]> git.sur5r.net Git - openldap/blob - libraries/macintosh/macos-ip.c
merged with autoconf branch
[openldap] / libraries / macintosh / macos-ip.c
1 /*
2  *  Copyright (c) 1995 Regents of the University of Michigan.
3  *  All rights reserved.
4  *
5  *  macos-ip.c -- Macintosh platform-specific TCP & UDP related code
6  */
7
8 #ifndef lint 
9 static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of Michigan.\nAll rights reserved.\n";
10 #endif
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <Memory.h>
16 #include "macos.h"
17 #include "lber.h"
18 #include "ldap.h"
19 #include "ldap-int.h"
20
21 int
22 ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
23         int port, int async )
24 /*
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!
30  */
31 {
32         void                    *tcps;
33         short                   i;
34 #ifdef SUPPORT_OPENTRANSPORT
35     InetHostInfo        hi;
36 #else /* SUPPORT_OPENTRANSPORT */
37     struct hostInfo     hi;
38 #endif /* SUPPORT_OPENTRANSPORT */
39
40         Debug( LDAP_DEBUG_TRACE, "ldap_connect_to_host: %s:%d\n",
41             ( host == NULL ) ? "(by address)" : host, ntohs( port ), 0 );
42
43         if ( host != NULL && gethostinfobyname( host, &hi ) != noErr ) {
44                 return( -1 );
45         }
46
47         if (( tcps = tcpopen( NULL, TCP_BUFSIZ )) == NULL ) {
48                 Debug( LDAP_DEBUG_TRACE, "tcpopen failed\n", 0, 0, 0 );
49                 return( -1 );
50         }
51
52 #ifdef SUPPORT_OPENTRANSPORT
53     for ( i = 0; host == NULL || hi.addrs[ i ] != 0; ++i ) {
54         if ( host != NULL ) {
55                         SAFEMEMCPY( (char *)&address, (char *)&hi.addrs[ i ], sizeof( long ));
56                 }
57 #else /* SUPPORT_OPENTRANSPORT */
58     for ( i = 0; host == NULL || hi.addr[ i ] != 0; ++i ) {
59         if ( host != NULL ) {
60                         SAFEMEMCPY( (char *)&address, (char *)&hi.addr[ i ], sizeof( long ));
61                 }
62 #endif /* SUPPORT_OPENTRANSPORT */
63
64                 if ( tcpconnect( tcps, address, port ) > 0 ) {
65                         sb->sb_sd = (void *)tcps;
66                         return( 0 );
67                 }
68
69                 if ( host == NULL ) {   /* using single address -- not hi.addrs array */
70                         break;
71                 }
72         }
73         
74         Debug( LDAP_DEBUG_TRACE, "tcpconnect failed\n", 0, 0, 0 );
75         tcpclose( tcps );
76         return( -1 );
77 }
78
79
80 void
81 ldap_close_connection( Sockbuf *sb )
82 {
83         tcpclose( (tcpstream *)sb->sb_sd );
84 }
85
86
87 #ifdef KERBEROS
88 char *
89 ldap_host_connected_to( Sockbuf *sb )
90 {
91         ip_addr addr;
92         
93 #ifdef SUPPORT_OPENTRANSPORT
94     InetHostInfo        hi;
95 #else /* SUPPORT_OPENTRANSPORT */
96     struct hostInfo     hi;
97 #endif /* SUPPORT_OPENTRANSPORT */
98
99         if ( tcpgetpeername( (tcpstream *)sb->sb_sd, &addr, NULL ) != noErr ) {
100                 return( NULL );
101         }
102
103 #ifdef SUPPORT_OPENTRANSPORT
104         if ( gethostinfobyaddr( addr, &hi ) == noErr ) {
105                 return( strdup( hi.name ));
106         }
107 #else /* SUPPORT_OPENTRANSPORT */
108         if ( gethostinfobyaddr( addr, &hi ) == noErr ) {
109                 return( strdup( hi.cname ));
110         }
111 #endif /* SUPPORT_OPENTRANSPORT */
112
113         return( NULL );
114 }
115 #endif /* KERBEROS */
116
117
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 */
125 };
126
127 struct selectinfo {
128         short                                   si_count;
129         struct tcpstreaminfo    *si_streaminfo;
130 };
131
132
133 void
134 ldap_mark_select_read( LDAP *ld, Sockbuf *sb )
135 {
136         struct selectinfo               *sip;
137         struct tcpstreaminfo    *tcpsip;
138         short                                   i;
139         
140         Debug( LDAP_DEBUG_TRACE, "ldap_mark_select_read: stream %x\n", (tcpstream *)sb->sb_sd, 0, 0 );
141
142         if (( sip = (struct selectinfo *)ld->ld_selectinfo ) == NULL ) {
143                 return;
144         }
145         
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;
150                         return;
151                 }
152         }
153
154         /* add a new stream element to our array... */
155         if ( sip->si_count <= 0 ) {
156                 tcpsip = (struct tcpstreaminfo *)malloc( sizeof( struct tcpstreaminfo ));
157         } else {
158                 tcpsip = (struct tcpstreaminfo *)realloc( sip->si_streaminfo,
159                                 ( sip->si_count + 1 ) * sizeof( struct tcpstreaminfo ));
160         }
161         
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;
167                 ++sip->si_count;
168         }
169 }
170
171
172 void
173 ldap_mark_select_clear( LDAP *ld, Sockbuf *sb )
174 {
175         struct selectinfo       *sip;
176         short                           i;
177
178         Debug( LDAP_DEBUG_TRACE, "ldap_mark_select_clear: stream %x\n", (tcpstream *)sb->sb_sd, 0, 0 );
179
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 ) {
184                                 break;
185                         }
186                 }
187                 if ( i < sip->si_count ) {
188                         --sip->si_count;
189                         for ( ; i < sip->si_count; ++i ) {
190                                 sip->si_streaminfo[ i ] = sip->si_streaminfo[ i + 1 ];
191                         }
192                         /* we don't bother to use realloc to make the si_streaminfo array smaller */
193                 }
194         }
195 }
196
197
198 int
199 ldap_is_read_ready( LDAP *ld, Sockbuf *sb )
200 {
201         struct selectinfo       *sip;
202         short                           i;
203         
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 ) {
208 #ifdef LDAP_DEBUG
209                                 if ( sip->si_streaminfo[ i ].tcpsi_is_read_ready ) {
210                                         Debug( LDAP_DEBUG_TRACE, "ldap_is_read_ready: stream %x READY\n",
211                                                         (tcpstream *)sb->sb_sd, 0, 0 );
212                                 } else {
213                                         Debug( LDAP_DEBUG_TRACE, "ldap_is_read_ready: stream %x Not Ready\n",
214                                                         (tcpstream *)sb->sb_sd, 0, 0 );
215                                 }
216 #endif /* LDAP_DEBUG */
217                                 return( sip->si_streaminfo[ i ].tcpsi_is_read_ready ? 1 : 0 );
218                         }
219                 }
220         }
221
222         Debug( LDAP_DEBUG_TRACE, "ldap_is_read_ready: stream %x: NOT FOUND\n", (tcpstream *)sb->sb_sd, 0, 0 );
223         return( 0 );
224 }
225
226
227 void *
228 ldap_new_select_info()
229 {
230         return( (void *)calloc( 1, sizeof( struct selectinfo )));
231 }
232
233
234 void
235 ldap_free_select_info( void *sip )
236 {
237         if ( sip != NULL ) {
238                 free( sip );
239         }
240 }
241
242
243 int
244 do_ldap_select( LDAP *ld, struct timeval *timeout )
245 {
246         struct selectinfo       *sip;
247         Boolean                         ready, gotselecterr;
248         long                            ticks, endticks;
249         short                           i, err;
250
251         Debug( LDAP_DEBUG_TRACE, "do_ldap_select\n", 0, 0, 0 );
252
253         if (( sip = (struct selectinfo *)ld->ld_selectinfo ) == NULL ) {
254                 return( -1 );
255         }
256
257         if ( sip->si_count == 0 ) {
258                 return( 1 );
259         }
260
261         if ( timeout != NULL ) {
262                 endticks = 60 * timeout->tv_sec + ( 60 * timeout->tv_usec ) / 1000000 + TickCount();
263         }
264
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;
268                 }
269         }
270
271         ready = gotselecterr = false;
272         do {
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 ) {
278                                         gotselecterr = true;
279                                 }
280                         }
281                 }
282                 if ( !ready && !gotselecterr ) {
283                         Delay( 2L, &ticks );
284                         SystemTask();
285                 }
286         } while ( !ready && !gotselecterr && ( timeout == NULL || ticks < endticks ));
287
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 ));
290 }
291 #endif /* LDAP_REFERRALS */