]> git.sur5r.net Git - openldap/blob - libraries/libldap/util-int.c
Improved ldap_int_strtok. If strtok_r does not exists, it will be worked
[openldap] / libraries / libldap / util-int.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 /*
6  * util-int.c   Various functions to replace missing threadsafe ones.
7  *                                Without the real *_r funcs, things will work, but won't be
8  *                                threadsafe. 
9  * 
10  * Written by Bart Hartgers.
11  *
12  * Copyright 1998, A. Hartgers, All rights reserved.
13  * This software is not subject to any license of Eindhoven University of
14  * Technology, since it was written in my spare time.
15  *                      
16  * Redistribution and use in source and binary forms are permitted only
17  * as authorized by the OpenLDAP Public License.  A copy of this
18  * license is available at http://www.OpenLDAP.org/license.html or
19  * in file LICENSE in the top-level directory of the distribution.
20  */ 
21
22 #include "portable.h"
23
24 #include <stdlib.h>
25
26 #include <ac/errno.h>
27 #include <ac/socket.h>
28 #include <ac/string.h>
29 #include <ac/time.h>
30
31 #include "ldap-int.h"
32
33 static int int_strspn( const char *str, const char *delim )
34 {
35 #if defined( HAVE_STRSPN )
36         return strspn( str, delim );
37 #else
38         int pos;
39         const char *p=delim;
40         for( pos=0; (*str) ; pos++,str++) {
41                 if (*str!=*p)
42                         for( p=delim; (*p) ; p++ ) {
43                                 if (*str==*p)
44                                         break;
45                         }
46                 if (*p=='\0')
47                         return pos;
48         }
49         return pos;
50 #endif  
51 }
52
53 static char *int_strpbrk( const char *str, const char *accept )
54 {
55 #if defined( HAVE_STRPBRK )
56         return strpbrk( str, accept );
57 #else
58         const char *p;
59         for( ; (*str) ; str++ ) {
60                 for( p=accept; (*p) ; p++) {
61                         if (*str==*p)
62                                 return str;
63                 }
64         }
65         return NULL;
66 #endif
67 }
68
69 char *ldap_int_strtok( char *str, const char *delim, char **pos )
70 {
71 #ifdef HAVE_STRTOK_R
72         return strtok_r(str, delim, pos);
73 #else
74         char *p;
75
76         if (pos==NULL)
77                 return NULL;
78         if (str==NULL) {
79                 if (*pos==NULL)
80                         return NULL;
81                 str=*pos;
82         }
83         /* skip any initial delimiters */
84         str += int_strspn( str, delim );
85         if (*str == '\0')
86                 return NULL;
87         p = int_strpbrk( str, delim );
88         if (p==NULL) {
89                 *pos = NULL;
90         } else {
91                 *p ='\0';
92                 *pos = p+1;
93         }
94         return str;
95 #endif
96 }
97
98 char *ldap_int_ctime( const time_t *tp, char *buf )
99 {
100 #if defined( HAVE_CTIME_R ) && defined( CTIME_R_NARGS )
101 # if (CTIME_R_NARGS > 3) || (CTIME_R_NARGS < 2)
102         choke me!  nargs should have 2 or 3
103 # elif CTIME_R_NARGS > 2
104         return ctime_r(tp,buf,26);
105 # else
106         return ctime_r(tp,buf);
107 # endif   
108 #else
109         memcpy( buf, ctime(tp), 26 );
110         return buf;
111 #endif  
112 }
113
114 #define BUFSTART 1024
115 #define BUFMAX (32*1024)
116
117 static char *safe_realloc( char **buf, int len )
118 {
119         char *tmpbuf;
120         tmpbuf = realloc( *buf, len );
121         if (tmpbuf) {
122                 *buf=tmpbuf;
123         } 
124         return tmpbuf;
125 }
126
127 int ldap_int_gethostbyname_a(
128         const char *name, 
129         struct hostent *resbuf,
130         char **buf,
131         struct hostent **result,
132         int *herrno_ptr )
133 {
134 #ifdef HAVE_GETHOSTBYNAME_R
135         int r=-1;
136         int buflen=BUFSTART;
137         *buf = NULL;
138         for(;buflen<BUFMAX;) {
139                 if (safe_realloc( buf, buflen )==NULL)
140                         return r;
141                 r = gethostbyname_r( name, resbuf, *buf,
142                         buflen, result, herrno_ptr );
143 #ifdef NETDB_INTERNAL
144                 if ((r<0) &&
145                         (*herrno_ptr==NETDB_INTERNAL) &&
146                         (errno==ERANGE))
147                 {
148                         buflen*=2;
149                         continue;
150                 }
151 #endif
152                 return r;
153         }
154         return -1;
155 #else   
156         *result = gethostbyname( name );
157
158         if (*result!=NULL) {
159                 return 0;
160         }
161
162         *herrno_ptr = h_errno;
163         
164         return -1;
165 #endif  
166 }
167          
168 int ldap_int_gethostbyaddr_a(
169         const char *addr,
170         int len,
171         int type,
172         struct hostent *resbuf,
173         char **buf,
174         struct hostent **result,
175         int *herrno_ptr )
176 {
177 #ifdef HAVE_GETHOSTBYADDR_R
178         int r=-1;
179         int buflen=BUFSTART;
180         *buf = NULL;   
181         for(;buflen<BUFMAX;) {
182                 if (safe_realloc( buf, buflen )==NULL)
183                         return r;
184                 r = gethostbyaddr_r( addr, len, type,
185                         resbuf, *buf, buflen, 
186                         result, herrno_ptr );
187 #ifdef NETDB_INTERNAL
188                 if ((r<0) &&
189                         (*herrno_ptr==NETDB_INTERNAL) &&
190                         (errno==ERANGE))
191                 {
192                         buflen*=2;
193                         continue;
194                 }
195 #endif
196                 return r;
197         }
198         return -1;
199 #else /* gethostbyaddr() */
200         *result = gethostbyaddr( addr, len, type );
201
202         if (*result!=NULL) {
203                 return 0;
204         }
205         return -1;
206 #endif  
207 }