2 * Copyright (c) 1995 Regents of the University of Michigan.
5 * macos-ip.c -- Macintosh platform-specific TCP & UDP related code
9 static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of Michigan.\nAll rights reserved.\n";
22 connect_to_host( Sockbuf *sb, char *host, unsigned long address,
25 * if host == NULL, connect using address
26 * "address" and "port" must be in network byte order
27 * zero is returned upon success, -1 if fatal error, -2 EINPROGRESS
28 * async is only used ifndef NO_REFERRALS (non-0 means don't wait for connect)
29 * XXX async is not used yet!
34 #ifdef SUPPORT_OPENTRANSPORT
36 #else /* SUPPORT_OPENTRANSPORT */
38 #endif /* SUPPORT_OPENTRANSPORT */
40 Debug( LDAP_DEBUG_TRACE, "connect_to_host: %s:%d\n",
41 ( host == NULL ) ? "(by address)" : host, ntohs( port ), 0 );
43 if ( host != NULL && gethostinfobyname( host, &hi ) != noErr ) {
47 if (( tcps = tcpopen( NULL, TCP_BUFSIZ )) == NULL ) {
48 Debug( LDAP_DEBUG_TRACE, "tcpopen failed\n", 0, 0, 0 );
52 #ifdef SUPPORT_OPENTRANSPORT
53 for ( i = 0; host == NULL || hi.addrs[ i ] != 0; ++i ) {
55 SAFEMEMCPY( (char *)&address, (char *)&hi.addrs[ i ], sizeof( long ));
57 #else /* SUPPORT_OPENTRANSPORT */
58 for ( i = 0; host == NULL || hi.addr[ i ] != 0; ++i ) {
60 SAFEMEMCPY( (char *)&address, (char *)&hi.addr[ i ], sizeof( long ));
62 #endif /* SUPPORT_OPENTRANSPORT */
64 if ( tcpconnect( tcps, address, port ) > 0 ) {
65 sb->sb_sd = (void *)tcps;
69 if ( host == NULL ) { /* using single address -- not hi.addrs array */
74 Debug( LDAP_DEBUG_TRACE, "tcpconnect failed\n", 0, 0, 0 );
81 close_connection( Sockbuf *sb )
83 tcpclose( (tcpstream *)sb->sb_sd );
89 host_connected_to( Sockbuf *sb )
93 #ifdef SUPPORT_OPENTRANSPORT
95 #else /* SUPPORT_OPENTRANSPORT */
97 #endif /* SUPPORT_OPENTRANSPORT */
99 if ( tcpgetpeername( (tcpstream *)sb->sb_sd, &addr, NULL ) != noErr ) {
103 #ifdef SUPPORT_OPENTRANSPORT
104 if ( gethostinfobyaddr( addr, &hi ) == noErr ) {
105 return( strdup( hi.name ));
107 #else /* SUPPORT_OPENTRANSPORT */
108 if ( gethostinfobyaddr( addr, &hi ) == noErr ) {
109 return( strdup( hi.cname ));
111 #endif /* SUPPORT_OPENTRANSPORT */
115 #endif /* KERBEROS */
118 #ifdef LDAP_REFERRALS
119 struct tcpstreaminfo {
120 struct tcpstream *tcpsi_stream;
121 Boolean tcpsi_check_read;
122 Boolean tcpsi_is_read_ready;
123 /* Boolean tcpsi_check_write; /* no write select support needed yet */
124 /* Boolean tcpsi_is_write_ready; /* ditto */
129 struct tcpstreaminfo *si_streaminfo;
134 mark_select_read( LDAP *ld, Sockbuf *sb )
136 struct selectinfo *sip;
137 struct tcpstreaminfo *tcpsip;
140 Debug( LDAP_DEBUG_TRACE, "mark_select_read: stream %x\n", (tcpstream *)sb->sb_sd, 0, 0 );
142 if (( sip = (struct selectinfo *)ld->ld_selectinfo ) == NULL ) {
146 for ( i = 0; i < sip->si_count; ++i ) { /* make sure stream is not already in the list... */
147 if ( sip->si_streaminfo[ i ].tcpsi_stream == (tcpstream *)sb->sb_sd ) {
148 sip->si_streaminfo[ i ].tcpsi_check_read = true;
149 sip->si_streaminfo[ i ].tcpsi_is_read_ready = false;
154 /* add a new stream element to our array... */
155 if ( sip->si_count <= 0 ) {
156 tcpsip = (struct tcpstreaminfo *)malloc( sizeof( struct tcpstreaminfo ));
158 tcpsip = (struct tcpstreaminfo *)realloc( sip->si_streaminfo,
159 ( sip->si_count + 1 ) * sizeof( struct tcpstreaminfo ));
162 if ( tcpsip != NULL ) {
163 tcpsip[ sip->si_count ].tcpsi_stream = (tcpstream *)sb->sb_sd;
164 tcpsip[ sip->si_count ].tcpsi_check_read = true;
165 tcpsip[ sip->si_count ].tcpsi_is_read_ready = false;
166 sip->si_streaminfo = tcpsip;
173 mark_select_clear( LDAP *ld, Sockbuf *sb )
175 struct selectinfo *sip;
178 Debug( LDAP_DEBUG_TRACE, "mark_select_clear: stream %x\n", (tcpstream *)sb->sb_sd, 0, 0 );
180 sip = (struct selectinfo *)ld->ld_selectinfo;
181 if ( sip != NULL && sip->si_count > 0 && sip->si_streaminfo != NULL ) {
182 for ( i = 0; i < sip->si_count; ++i ) {
183 if ( sip->si_streaminfo[ i ].tcpsi_stream == (tcpstream *)sb->sb_sd ) {
187 if ( i < sip->si_count ) {
189 for ( ; i < sip->si_count; ++i ) {
190 sip->si_streaminfo[ i ] = sip->si_streaminfo[ i + 1 ];
192 /* we don't bother to use realloc to make the si_streaminfo array smaller */
199 is_read_ready( LDAP *ld, Sockbuf *sb )
201 struct selectinfo *sip;
204 sip = (struct selectinfo *)ld->ld_selectinfo;
205 if ( sip != NULL && sip->si_count > 0 && sip->si_streaminfo != NULL ) {
206 for ( i = 0; i < sip->si_count; ++i ) {
207 if ( sip->si_streaminfo[ i ].tcpsi_stream == (tcpstream *)sb->sb_sd ) {
209 if ( sip->si_streaminfo[ i ].tcpsi_is_read_ready ) {
210 Debug( LDAP_DEBUG_TRACE, "is_read_ready: stream %x READY\n",
211 (tcpstream *)sb->sb_sd, 0, 0 );
213 Debug( LDAP_DEBUG_TRACE, "is_read_ready: stream %x Not Ready\n",
214 (tcpstream *)sb->sb_sd, 0, 0 );
216 #endif /* LDAP_DEBUG */
217 return( sip->si_streaminfo[ i ].tcpsi_is_read_ready ? 1 : 0 );
222 Debug( LDAP_DEBUG_TRACE, "is_read_ready: stream %x: NOT FOUND\n", (tcpstream *)sb->sb_sd, 0, 0 );
230 return( (void *)calloc( 1, sizeof( struct selectinfo )));
235 free_select_info( void *sip )
244 do_ldap_select( LDAP *ld, struct timeval *timeout )
246 struct selectinfo *sip;
247 Boolean ready, gotselecterr;
248 long ticks, endticks;
251 Debug( LDAP_DEBUG_TRACE, "do_ldap_select\n", 0, 0, 0 );
253 if (( sip = (struct selectinfo *)ld->ld_selectinfo ) == NULL ) {
257 if ( sip->si_count == 0 ) {
261 if ( timeout != NULL ) {
262 endticks = 60 * timeout->tv_sec + ( 60 * timeout->tv_usec ) / 1000000 + TickCount();
265 for ( i = 0; i < sip->si_count; ++i ) {
266 if ( sip->si_streaminfo[ i ].tcpsi_check_read ) {
267 sip->si_streaminfo[ i ].tcpsi_is_read_ready = false;
271 ready = gotselecterr = false;
273 for ( i = 0; i < sip->si_count; ++i ) {
274 if ( sip->si_streaminfo[ i ].tcpsi_check_read && !sip->si_streaminfo[ i ].tcpsi_is_read_ready ) {
275 if (( err = tcpreadready( sip->si_streaminfo[ i ].tcpsi_stream )) > 0 ) {
276 sip->si_streaminfo[ i ].tcpsi_is_read_ready = ready = true;
277 } else if ( err < 0 ) {
282 if ( !ready && !gotselecterr ) {
286 } while ( !ready && !gotselecterr && ( timeout == NULL || ticks < endticks ));
288 Debug( LDAP_DEBUG_TRACE, "do_ldap_select returns %d\n", ready ? 1 : ( gotselecterr ? -1 : 0 ), 0, 0 );
289 return( ready ? 1 : ( gotselecterr ? -1 : 0 ));
291 #endif /* LDAP_REFERRALS */