winemenubuilder: Make initial directories for fd.o MIME type handling.
[wine] / dlls / wldap32 / ber.c
1 /*
2  * WLDAP32 - LDAP support for Wine
3  *
4  * Copyright 2005 Hans Leidekker
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winldap.h"
27 #include "wine/debug.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
30
31 #ifndef LBER_ERROR
32 # define LBER_ERROR (~0U)
33 #endif
34
35 /***********************************************************************
36  *      ber_alloc_t     (WLDAP32.@)
37  *
38  * Allocate a berelement structure.
39  *
40  * PARAMS
41  *  options [I] Must be LBER_USE_DER.
42  *
43  * RETURNS
44  *  Success: Pointer to an allocated berelement structure.
45  *  Failure: NULL
46  *
47  * NOTES
48  *  Free the berelement structure with ber_free.
49  */
50 BerElement * CDECL WLDAP32_ber_alloc_t( INT options )
51 {
52 #ifdef HAVE_LDAP
53     return ber_alloc_t( options );
54 #else
55     return NULL;
56 #endif
57 }
58
59
60 /***********************************************************************
61  *      ber_bvdup     (WLDAP32.@)
62  *
63  * Copy a berval structure.
64  *
65  * PARAMS
66  *  berval [I] Pointer to the berval structure to be copied.
67  *
68  * RETURNS
69  *  Success: Pointer to a copy of the berval structure.
70  *  Failure: NULL
71  *
72  * NOTES
73  *  Free the copy with ber_bvfree.
74  */
75 BERVAL * CDECL WLDAP32_ber_bvdup( BERVAL *berval )
76 {
77 #ifdef HAVE_LDAP
78     return ber_bvdup( berval );
79 #else
80     return NULL;
81 #endif
82 }
83
84
85 /***********************************************************************
86  *      ber_bvecfree     (WLDAP32.@)
87  *
88  * Free an array of berval structures.
89  *
90  * PARAMS
91  *  berval [I] Pointer to an array of berval structures.
92  *
93  * RETURNS
94  *  Nothing.
95  *
96  * NOTES
97  *  Use this function only to free an array of berval structures
98  *  returned by a call to ber_scanf with a 'V' in the format string.
99  */
100 void CDECL WLDAP32_ber_bvecfree( PBERVAL *berval )
101 {
102 #ifdef HAVE_LDAP
103     ber_bvecfree( berval );
104 #endif
105 }
106
107
108 /***********************************************************************
109  *      ber_bvfree     (WLDAP32.@)
110  *
111  * Free a berval structure.
112  *
113  * PARAMS
114  *  berval [I] Pointer to a berval structure.
115  *
116  * RETURNS
117  *  Nothing.
118  *
119  * NOTES
120  *  Use this function only to free berval structures allocated by
121  *  an LDAP API.
122  */
123 void CDECL WLDAP32_ber_bvfree( BERVAL *berval )
124 {
125 #ifdef HAVE_LDAP
126     ber_bvfree( berval );
127 #endif
128 }
129
130
131 /***********************************************************************
132  *      ber_first_element     (WLDAP32.@)
133  *
134  * Return the tag of the first element in a set or sequence.
135  *
136  * PARAMS
137  *  berelement [I] Pointer to a berelement structure.
138  *  len        [O] Receives the length of the first element.
139  *  opaque     [O] Receives a pointer to a cookie.
140  *
141  * RETURNS
142  *  Success: Tag of the first element.
143  *  Failure: LBER_DEFAULT (no more data).
144  *
145  * NOTES
146  *  len and cookie should be passed to ber_next_element.
147  */
148 ULONG CDECL WLDAP32_ber_first_element( BerElement *berelement, ULONG *len, CHAR **opaque )
149 {
150 #ifdef HAVE_LDAP
151     return ber_first_element( berelement, len, opaque );
152 #else
153     return LBER_ERROR;
154 #endif
155 }
156
157
158 /***********************************************************************
159  *      ber_flatten     (WLDAP32.@)
160  *
161  * Flatten a berelement structure into a berval structure.
162  *
163  * PARAMS
164  *  berelement [I] Pointer to a berelement structure.
165  *  berval    [O] Pointer to a berval structure.
166  *
167  * RETURNS
168  *  Success: 0
169  *  Failure: LBER_ERROR
170  *
171  * NOTES
172  *  Free the berval structure with ber_bvfree.
173  */
174 INT CDECL WLDAP32_ber_flatten( BerElement *berelement, PBERVAL *berval )
175 {
176 #ifdef HAVE_LDAP
177     return ber_flatten( berelement, berval );
178 #else
179     return LBER_ERROR;
180 #endif
181 }
182
183
184 /***********************************************************************
185  *      ber_free     (WLDAP32.@)
186  *
187  * Free a berelement structure.
188  *
189  * PARAMS
190  *  berelement [I] Pointer to the berelement structure to be freed.
191  *  buf       [I] Flag.
192  *
193  * RETURNS
194  *  Nothing.
195  *
196  * NOTES
197  *  Set buf to 0 if the berelement was allocated with ldap_first_attribute
198  *  or ldap_next_attribute, otherwise set it to 1.
199  */
200 void CDECL WLDAP32_ber_free( BerElement *berelement, INT buf )
201 {
202 #ifdef HAVE_LDAP
203     ber_free( berelement, buf );
204 #endif
205 }
206
207
208 /***********************************************************************
209  *      ber_init     (WLDAP32.@)
210  *
211  * Initialise a berelement structure from a berval structure.
212  *
213  * PARAMS
214  *  berval [I] Pointer to a berval structure.
215  *
216  * RETURNS
217  *  Success: Pointer to a berelement structure.
218  *  Failure: NULL
219  *
220  * NOTES
221  *  Call ber_free to free the returned berelement structure.
222  */
223 BerElement * CDECL WLDAP32_ber_init( BERVAL *berval )
224 {
225 #ifdef HAVE_LDAP
226     return ber_init( berval );
227 #else
228     return NULL;
229 #endif
230 }
231
232
233 /***********************************************************************
234  *      ber_next_element     (WLDAP32.@)
235  *
236  * Return the tag of the next element in a set or sequence.
237  *
238  * PARAMS
239  *  berelement [I]   Pointer to a berelement structure.
240  *  len        [I/O] Receives the length of the next element.
241  *  opaque     [I/O] Pointer to a cookie.
242  *
243  * RETURNS
244  *  Success: Tag of the next element.
245  *  Failure: LBER_DEFAULT (no more data).
246  *
247  * NOTES
248  *  len and cookie are initialized by ber_first_element and should
249  *  be passed on in subsequent calls to ber_next_element.
250  */
251 ULONG CDECL WLDAP32_ber_next_element( BerElement *berelement, ULONG *len, CHAR *opaque )
252 {
253 #ifdef HAVE_LDAP
254     return ber_next_element( berelement, len, opaque );
255 #else
256     return LBER_ERROR;
257 #endif
258 }
259
260
261 /***********************************************************************
262  *      ber_peek_tag     (WLDAP32.@)
263  *
264  * Return the tag of the next element.
265  *
266  * PARAMS
267  *  berelement [I] Pointer to a berelement structure.
268  *  len        [O] Receives the length of the next element.
269  *
270  * RETURNS
271  *  Success: Tag of the next element.
272  *  Failure: LBER_DEFAULT (no more data).
273  */
274 ULONG CDECL WLDAP32_ber_peek_tag( BerElement *berelement, ULONG *len )
275 {
276 #ifdef HAVE_LDAP
277     return ber_peek_tag( berelement, len );
278 #else
279     return LBER_ERROR;
280 #endif
281 }
282
283
284 /***********************************************************************
285  *      ber_skip_tag     (WLDAP32.@)
286  *
287  * Skip the current tag and return the tag of the next element.
288  *
289  * PARAMS
290  *  berelement [I] Pointer to a berelement structure.
291  *  len        [O] Receives the length of the skipped element.
292  *
293  * RETURNS
294  *  Success: Tag of the next element.
295  *  Failure: LBER_DEFAULT (no more data).
296  */
297 ULONG CDECL WLDAP32_ber_skip_tag( BerElement *berelement, ULONG *len )
298 {
299 #ifdef HAVE_LDAP
300     return ber_skip_tag( berelement, len );
301 #else
302     return LBER_ERROR;
303 #endif
304 }
305
306
307 /***********************************************************************
308  *      ber_printf     (WLDAP32.@)
309  *
310  * Encode a berelement structure.
311  *
312  * PARAMS
313  *  berelement [I/O] Pointer to a berelement structure.
314  *  fmt        [I]   Format string.
315  *  ...        [I]   Values to encode.
316  *
317  * RETURNS
318  *  Success: Non-negative number. 
319  *  Failure: LBER_ERROR
320  *
321  * NOTES
322  *  berelement must have been allocated with ber_alloc_t. This function
323  *  can be called multiple times to append data.
324  */
325 INT CDECL WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... )
326 {
327 #ifdef HAVE_LDAP
328     __ms_va_list list;
329     int ret = 0;
330     char new_fmt[2];
331
332     new_fmt[1] = 0;
333     __ms_va_start( list, fmt );
334     while (*fmt)
335     {
336         new_fmt[0] = *fmt++;
337         switch(new_fmt[0])
338         {
339         case 'b':
340         case 'e':
341         case 'i':
342             {
343                 int i = va_arg( list, int );
344                 ret = ber_printf( berelement, new_fmt, i );
345                 break;
346             }
347         case 'o':
348         case 's':
349             {
350                 char *str = va_arg( list, char * );
351                 ret = ber_printf( berelement, new_fmt, str );
352                 break;
353             }
354         case 't':
355             {
356                 unsigned int tag = va_arg( list, unsigned int );
357                 ret = ber_printf( berelement, new_fmt, tag );
358                 break;
359             }
360         case 'v':
361             {
362                 char **array = va_arg( list, char ** );
363                 ret = ber_printf( berelement, new_fmt, array );
364                 break;
365             }
366         case 'V':
367             {
368                 struct berval **array = va_arg( list, struct berval ** );
369                 ret = ber_printf( berelement, new_fmt, array );
370                 break;
371             }
372         case 'X':
373             {
374                 char *str = va_arg( list, char * );
375                 int len = va_arg( list, int );
376                 new_fmt[0] = 'B';  /* 'X' is deprecated */
377                 ret = ber_printf( berelement, new_fmt, str, len );
378                 break;
379             }
380         case 'n':
381         case '{':
382         case '}':
383         case '[':
384         case ']':
385             ret = ber_printf( berelement, new_fmt );
386             break;
387         default:
388             FIXME( "Unknown format '%c'\n", new_fmt[0] );
389             ret = -1;
390             break;
391         }
392         if (ret == -1) break;
393     }
394     __ms_va_end( list );
395     return ret;
396 #else
397     return LBER_ERROR;
398 #endif
399 }
400
401
402 /***********************************************************************
403  *      ber_scanf     (WLDAP32.@)
404  *
405  * Decode a berelement structure.
406  *
407  * PARAMS
408  *  berelement [I/O] Pointer to a berelement structure.
409  *  fmt        [I]   Format string.
410  *  ...        [I]   Pointers to values to be decoded.
411  *
412  * RETURNS
413  *  Success: Non-negative number. 
414  *  Failure: LBER_ERROR
415  *
416  * NOTES
417  *  berelement must have been allocated with ber_init. This function
418  *  can be called multiple times to decode data.
419  */
420 INT CDECL WLDAP32_ber_scanf( BerElement *berelement, PCHAR fmt, ... )
421 {
422 #ifdef HAVE_LDAP
423     __ms_va_list list;
424     int ret = 0;
425     char new_fmt[2];
426
427     new_fmt[1] = 0;
428     __ms_va_start( list, fmt );
429     while (*fmt)
430     {
431         new_fmt[0] = *fmt++;
432         switch(new_fmt[0])
433         {
434         case 'a':
435             {
436                 char **ptr = va_arg( list, char ** );
437                 ret = ber_scanf( berelement, new_fmt, ptr );
438                 break;
439             }
440         case 'b':
441         case 'e':
442         case 'i':
443             {
444                 int *i = va_arg( list, int * );
445                 ret = ber_scanf( berelement, new_fmt, i );
446                 break;
447             }
448         case 't':
449             {
450                 unsigned int *tag = va_arg( list, unsigned int * );
451                 ret = ber_scanf( berelement, new_fmt, tag );
452                 break;
453             }
454         case 'v':
455             {
456                 char ***array = va_arg( list, char *** );
457                 ret = ber_scanf( berelement, new_fmt, array );
458                 break;
459             }
460         case 'B':
461             {
462                 char **str = va_arg( list, char ** );
463                 int *len = va_arg( list, int * );
464                 ret = ber_scanf( berelement, new_fmt, str, len );
465                 break;
466             }
467         case 'O':
468             {
469                 struct berval **ptr = va_arg( list, struct berval ** );
470                 ret = ber_scanf( berelement, new_fmt, ptr );
471                 break;
472             }
473         case 'V':
474             {
475                 struct berval ***array = va_arg( list, struct berval *** );
476                 ret = ber_scanf( berelement, new_fmt, array );
477                 break;
478             }
479         case 'n':
480         case 'x':
481         case '{':
482         case '}':
483         case '[':
484         case ']':
485             ret = ber_scanf( berelement, new_fmt );
486             break;
487         default:
488             FIXME( "Unknown format '%c'\n", new_fmt[0] );
489             ret = -1;
490             break;
491         }
492         if (ret == -1) break;
493     }
494     __ms_va_end( list );
495     return ret;
496 #else
497     return LBER_ERROR;
498 #endif
499 }