2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
10 * The contents of this file are subject to the Netscape Public
11 * License Version 1.1 (the "License"); you may not use this file
12 * except in compliance with the License. You may obtain a copy of
13 * the License at http://www.mozilla.org/NPL/
15 * Software distributed under the License is distributed on an "AS
16 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17 * implied. See the License for the specific language governing
18 * rights and limitations under the License.
20 * The Original Code is Mozilla Communicator client code, released
23 * The Initial Developer of the Original Code is Netscape
24 * Communications Corporation. Portions created by Netscape are
25 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
31 * Copyright (c) 1993, 1994 Regents of the University of Michigan.
32 * All rights reserved.
34 * Redistribution and use in source and binary forms are permitted
35 * provided that this notice is preserved and that due credit is given
36 * to the University of Michigan at Ann Arbor. The name of the University
37 * may not be used to endorse or promote products derived from this
38 * software without specific prior written permission. This software
39 * is provided ``as is'' without express or implied warranty.
42 * disptmpl.c: display template library routines for LDAP clients
48 static void free_disptmpl( struct ldap_disptmpl
*tmpl
);
49 static int read_next_tmpl( char **bufp
, long *blenp
,
50 struct ldap_disptmpl
**tmplp
, int dtversion
);
52 static char *tmploptions
[] = {
59 static unsigned long tmploptvals
[] = {
60 LDAP_DTMPL_OPT_ADDABLE
, LDAP_DTMPL_OPT_ALLOWMODRDN
,
61 LDAP_DTMPL_OPT_ALTVIEW
,
65 static char *itemtypes
[] = {
67 "bool", "jpeg", "jpegbtn",
68 "fax", "faxbtn", "audiobtn",
69 "time", "date", "url",
70 "searchact", "linkact", "adddnact",
71 "addact", "verifyact", "mail",
75 static unsigned long itemsynids
[] = {
76 LDAP_SYN_CASEIGNORESTR
, LDAP_SYN_MULTILINESTR
, LDAP_SYN_DN
,
77 LDAP_SYN_BOOLEAN
, LDAP_SYN_JPEGIMAGE
, LDAP_SYN_JPEGBUTTON
,
78 LDAP_SYN_FAXIMAGE
, LDAP_SYN_FAXBUTTON
, LDAP_SYN_AUDIOBUTTON
,
79 LDAP_SYN_TIME
, LDAP_SYN_DATE
, LDAP_SYN_LABELEDURL
,
80 LDAP_SYN_SEARCHACTION
, LDAP_SYN_LINKACTION
, LDAP_SYN_ADDDNACTION
,
81 LDAP_SYN_ADDDNACTION
, LDAP_SYN_VERIFYDNACTION
,LDAP_SYN_RFC822ADDR
,
85 static char *itemoptions
[] = {
88 "required", "hideiffalse",
93 static unsigned long itemoptvals
[] = {
94 LDAP_DITEM_OPT_READONLY
, LDAP_DITEM_OPT_SORTVALUES
,
95 LDAP_DITEM_OPT_SINGLEVALUED
, LDAP_DITEM_OPT_HIDEIFEMPTY
,
96 LDAP_DITEM_OPT_VALUEREQUIRED
, LDAP_DITEM_OPT_HIDEIFFALSE
,
100 #define ADDEF_CONSTANT "constant"
101 #define ADDEF_ADDERSDN "addersdn"
106 ldap_init_templates( char *file
, struct ldap_disptmpl
**tmpllistp
)
113 *tmpllistp
= NULLDISPTMPL
;
115 if (( fp
= fopen( file
, "rF" )) == NULL
) {
116 return( LDAP_TMPL_ERR_FILE
);
119 if ( fseek( fp
, 0L, SEEK_END
) != 0 ) { /* move to end to get len */
121 return( LDAP_TMPL_ERR_FILE
);
126 if ( fseek( fp
, 0L, SEEK_SET
) != 0 ) { /* back to start of file */
128 return( LDAP_TMPL_ERR_FILE
);
131 if (( buf
= NSLDAPI_MALLOC( (size_t)len
)) == NULL
) {
133 return( LDAP_TMPL_ERR_MEM
);
136 rlen
= fread( buf
, 1, (size_t)len
, fp
);
140 if ( rlen
!= len
&& !eof
) { /* error: didn't get the whole file */
142 return( LDAP_TMPL_ERR_FILE
);
145 rc
= ldap_init_templates_buf( buf
, rlen
, tmpllistp
);
154 ldap_init_templates_buf( char *buf
, long buflen
,
155 struct ldap_disptmpl
**tmpllistp
)
159 struct ldap_disptmpl
*prevtmpl
, *tmpl
;
161 *tmpllistp
= prevtmpl
= NULLDISPTMPL
;
163 if ( ldap_next_line_tokens( &buf
, &buflen
, &toks
) != 2 ||
164 strcasecmp( toks
[ 0 ], "version" ) != 0 ) {
165 ldap_free_strarray( toks
);
166 return( LDAP_TMPL_ERR_SYNTAX
);
168 version
= atoi( toks
[ 1 ] );
169 ldap_free_strarray( toks
);
170 if ( version
!= LDAP_TEMPLATE_VERSION
) {
171 return( LDAP_TMPL_ERR_VERSION
);
174 while ( buflen
> 0 && ( rc
= read_next_tmpl( &buf
, &buflen
, &tmpl
,
175 version
)) == 0 && tmpl
!= NULLDISPTMPL
) {
176 if ( prevtmpl
== NULLDISPTMPL
) {
179 prevtmpl
->dt_next
= tmpl
;
185 ldap_free_templates( *tmpllistp
);
195 ldap_free_templates( struct ldap_disptmpl
*tmpllist
)
197 struct ldap_disptmpl
*tp
, *nexttp
;
199 if ( tmpllist
!= NULL
) {
200 for ( tp
= tmpllist
; tp
!= NULL
; tp
= nexttp
) {
201 nexttp
= tp
->dt_next
;
209 free_disptmpl( struct ldap_disptmpl
*tmpl
)
211 if ( tmpl
!= NULL
) {
212 if ( tmpl
->dt_name
!= NULL
) {
213 NSLDAPI_FREE( tmpl
->dt_name
);
216 if ( tmpl
->dt_pluralname
!= NULL
) {
217 NSLDAPI_FREE( tmpl
->dt_pluralname
);
220 if ( tmpl
->dt_iconname
!= NULL
) {
221 NSLDAPI_FREE( tmpl
->dt_iconname
);
224 if ( tmpl
->dt_authattrname
!= NULL
) {
225 NSLDAPI_FREE( tmpl
->dt_authattrname
);
228 if ( tmpl
->dt_defrdnattrname
!= NULL
) {
229 NSLDAPI_FREE( tmpl
->dt_defrdnattrname
);
232 if ( tmpl
->dt_defaddlocation
!= NULL
) {
233 NSLDAPI_FREE( tmpl
->dt_defaddlocation
);
236 if ( tmpl
->dt_oclist
!= NULL
) {
237 struct ldap_oclist
*ocp
, *nextocp
;
239 for ( ocp
= tmpl
->dt_oclist
; ocp
!= NULL
; ocp
= nextocp
) {
240 nextocp
= ocp
->oc_next
;
241 ldap_free_strarray( ocp
->oc_objclasses
);
246 if ( tmpl
->dt_adddeflist
!= NULL
) {
247 struct ldap_adddeflist
*adp
, *nextadp
;
249 for ( adp
= tmpl
->dt_adddeflist
; adp
!= NULL
; adp
= nextadp
) {
250 nextadp
= adp
->ad_next
;
251 if( adp
->ad_attrname
!= NULL
) {
252 NSLDAPI_FREE( adp
->ad_attrname
);
254 if( adp
->ad_value
!= NULL
) {
255 NSLDAPI_FREE( adp
->ad_value
);
261 if ( tmpl
->dt_items
!= NULL
) {
262 struct ldap_tmplitem
*rowp
, *nextrowp
, *colp
, *nextcolp
;
264 for ( rowp
= tmpl
->dt_items
; rowp
!= NULL
; rowp
= nextrowp
) {
265 nextrowp
= rowp
->ti_next_in_col
;
266 for ( colp
= rowp
; colp
!= NULL
; colp
= nextcolp
) {
267 nextcolp
= colp
->ti_next_in_row
;
268 if ( colp
->ti_attrname
!= NULL
) {
269 NSLDAPI_FREE( colp
->ti_attrname
);
271 if ( colp
->ti_label
!= NULL
) {
272 NSLDAPI_FREE( colp
->ti_label
);
274 if ( colp
->ti_args
!= NULL
) {
275 ldap_free_strarray( colp
->ti_args
);
277 NSLDAPI_FREE( colp
);
282 NSLDAPI_FREE( tmpl
);
287 struct ldap_disptmpl
*
289 ldap_first_disptmpl( struct ldap_disptmpl
*tmpllist
)
295 struct ldap_disptmpl
*
297 ldap_next_disptmpl( struct ldap_disptmpl
*tmpllist
,
298 struct ldap_disptmpl
*tmpl
)
300 return( tmpl
== NULLDISPTMPL
? tmpl
: tmpl
->dt_next
);
304 struct ldap_disptmpl
*
306 ldap_name2template( char *name
, struct ldap_disptmpl
*tmpllist
)
308 struct ldap_disptmpl
*dtp
;
310 for ( dtp
= ldap_first_disptmpl( tmpllist
); dtp
!= NULLDISPTMPL
;
311 dtp
= ldap_next_disptmpl( tmpllist
, dtp
)) {
312 if ( strcasecmp( name
, dtp
->dt_name
) == 0 ) {
317 return( NULLDISPTMPL
);
321 struct ldap_disptmpl
*
323 ldap_oc2template( char **oclist
, struct ldap_disptmpl
*tmpllist
)
325 struct ldap_disptmpl
*dtp
;
326 struct ldap_oclist
*oclp
;
327 int i
, j
, needcnt
, matchcnt
;
329 if ( tmpllist
== NULL
|| oclist
== NULL
|| oclist
[ 0 ] == NULL
) {
330 return( NULLDISPTMPL
);
333 for ( dtp
= ldap_first_disptmpl( tmpllist
); dtp
!= NULLDISPTMPL
;
334 dtp
= ldap_next_disptmpl( tmpllist
, dtp
)) {
335 for ( oclp
= dtp
->dt_oclist
; oclp
!= NULLOCLIST
;
336 oclp
= oclp
->oc_next
) {
337 needcnt
= matchcnt
= 0;
338 for ( i
= 0; oclp
->oc_objclasses
[ i
] != NULL
; ++i
) {
339 for ( j
= 0; oclist
[ j
] != NULL
; ++j
) {
340 if ( strcasecmp( oclist
[ j
], oclp
->oc_objclasses
[ i
] )
348 if ( matchcnt
== needcnt
) {
354 return( NULLDISPTMPL
);
358 struct ldap_tmplitem
*
360 ldap_first_tmplrow( struct ldap_disptmpl
*tmpl
)
362 return( tmpl
->dt_items
);
366 struct ldap_tmplitem
*
368 ldap_next_tmplrow( struct ldap_disptmpl
*tmpl
, struct ldap_tmplitem
*row
)
370 return( row
== NULLTMPLITEM
? row
: row
->ti_next_in_col
);
374 struct ldap_tmplitem
*
376 ldap_first_tmplcol( struct ldap_disptmpl
*tmpl
, struct ldap_tmplitem
*row
)
382 struct ldap_tmplitem
*
384 ldap_next_tmplcol( struct ldap_disptmpl
*tmpl
, struct ldap_tmplitem
*row
,
385 struct ldap_tmplitem
*col
)
387 return( col
== NULLTMPLITEM
? col
: col
->ti_next_in_row
);
393 ldap_tmplattrs( struct ldap_disptmpl
*tmpl
, char **includeattrs
,
394 int exclude
, unsigned long syntaxmask
)
397 * this routine should filter out duplicate attributes...
399 struct ldap_tmplitem
*tirowp
, *ticolp
;
400 int i
, attrcnt
, memerr
;
406 if (( attrs
= (char **)NSLDAPI_MALLOC( sizeof( char * ))) == NULL
) {
410 if ( includeattrs
!= NULL
) {
411 for ( i
= 0; !memerr
&& includeattrs
[ i
] != NULL
; ++i
) {
412 if (( attrs
= (char **)NSLDAPI_REALLOC( attrs
, ( attrcnt
+ 2 ) *
413 sizeof( char * ))) == NULL
|| ( attrs
[ attrcnt
++ ] =
414 nsldapi_strdup( includeattrs
[ i
] )) == NULL
) {
417 attrs
[ attrcnt
] = NULL
;
422 for ( tirowp
= ldap_first_tmplrow( tmpl
);
423 !memerr
&& tirowp
!= NULLTMPLITEM
;
424 tirowp
= ldap_next_tmplrow( tmpl
, tirowp
)) {
425 for ( ticolp
= ldap_first_tmplcol( tmpl
, tirowp
);
426 ticolp
!= NULLTMPLITEM
;
427 ticolp
= ldap_next_tmplcol( tmpl
, tirowp
, ticolp
)) {
429 if ( syntaxmask
!= 0 ) {
431 ( syntaxmask
& ticolp
->ti_syntaxid
) != 0 ) ||
433 ( syntaxmask
& ticolp
->ti_syntaxid
) == 0 )) {
438 if ( ticolp
->ti_attrname
!= NULL
) {
439 if (( attrs
= (char **)NSLDAPI_REALLOC( attrs
, ( attrcnt
+ 2 )
440 * sizeof( char * ))) == NULL
|| ( attrs
[ attrcnt
++ ] =
441 nsldapi_strdup( ticolp
->ti_attrname
)) == NULL
) {
444 attrs
[ attrcnt
] = NULL
;
450 if ( memerr
|| attrcnt
== 0 ) {
451 for ( i
= 0; i
< attrcnt
; ++i
) {
452 if ( attrs
[ i
] != NULL
) {
453 NSLDAPI_FREE( attrs
[ i
] );
457 NSLDAPI_FREE( (char *)attrs
);
466 read_next_tmpl( char **bufp
, long *blenp
, struct ldap_disptmpl
**tmplp
,
469 int i
, j
, tokcnt
, samerow
, adsource
;
470 char **toks
, *itemopts
;
471 struct ldap_disptmpl
*tmpl
= NULL
;
472 struct ldap_oclist
*ocp
= NULL
, *prevocp
= NULL
;
473 struct ldap_adddeflist
*adp
= NULL
, *prevadp
= NULL
;
474 struct ldap_tmplitem
*rowp
= NULL
, *ip
= NULL
, *previp
= NULL
;
477 * template name comes first
479 if (( tokcnt
= ldap_next_line_tokens( bufp
, blenp
, &toks
)) != 1 ) {
480 ldap_free_strarray( toks
);
481 return( tokcnt
== 0 ? 0 : LDAP_TMPL_ERR_SYNTAX
);
484 if (( tmpl
= (struct ldap_disptmpl
*)NSLDAPI_CALLOC( 1,
485 sizeof( struct ldap_disptmpl
))) == NULL
) {
486 ldap_free_strarray( toks
);
487 return( LDAP_TMPL_ERR_MEM
);
489 tmpl
->dt_name
= toks
[ 0 ];
490 NSLDAPI_FREE( (char *)toks
);
493 * template plural name comes next
495 if (( tokcnt
= ldap_next_line_tokens( bufp
, blenp
, &toks
)) != 1 ) {
496 ldap_free_strarray( toks
);
497 free_disptmpl( tmpl
);
498 return( LDAP_TMPL_ERR_SYNTAX
);
500 tmpl
->dt_pluralname
= toks
[ 0 ];
501 NSLDAPI_FREE( (char *)toks
);
504 * template icon name is next
506 if (( tokcnt
= ldap_next_line_tokens( bufp
, blenp
, &toks
)) != 1 ) {
507 ldap_free_strarray( toks
);
508 free_disptmpl( tmpl
);
509 return( LDAP_TMPL_ERR_SYNTAX
);
511 tmpl
->dt_iconname
= toks
[ 0 ];
512 NSLDAPI_FREE( (char *)toks
);
515 * template options come next
517 if (( tokcnt
= ldap_next_line_tokens( bufp
, blenp
, &toks
)) < 1 ) {
518 ldap_free_strarray( toks
);
519 free_disptmpl( tmpl
);
520 return( LDAP_TMPL_ERR_SYNTAX
);
522 for ( i
= 0; toks
[ i
] != NULL
; ++i
) {
523 for ( j
= 0; tmploptions
[ j
] != NULL
; ++j
) {
524 if ( strcasecmp( toks
[ i
], tmploptions
[ j
] ) == 0 ) {
525 tmpl
->dt_options
|= tmploptvals
[ j
];
529 ldap_free_strarray( toks
);
532 * object class list is next
534 while (( tokcnt
= ldap_next_line_tokens( bufp
, blenp
, &toks
)) > 0 ) {
535 if (( ocp
= (struct ldap_oclist
*)NSLDAPI_CALLOC( 1,
536 sizeof( struct ldap_oclist
))) == NULL
) {
537 ldap_free_strarray( toks
);
538 free_disptmpl( tmpl
);
539 return( LDAP_TMPL_ERR_MEM
);
541 ocp
->oc_objclasses
= toks
;
542 if ( tmpl
->dt_oclist
== NULL
) {
543 tmpl
->dt_oclist
= ocp
;
545 prevocp
->oc_next
= ocp
;
550 free_disptmpl( tmpl
);
551 return( LDAP_TMPL_ERR_SYNTAX
);
555 * read name of attribute to authenticate as
557 if (( tokcnt
= ldap_next_line_tokens( bufp
, blenp
, &toks
)) != 1 ) {
558 ldap_free_strarray( toks
);
559 free_disptmpl( tmpl
);
560 return( LDAP_TMPL_ERR_SYNTAX
);
562 if ( toks
[ 0 ][ 0 ] != '\0' ) {
563 tmpl
->dt_authattrname
= toks
[ 0 ];
565 NSLDAPI_FREE( toks
[ 0 ] );
567 NSLDAPI_FREE( (char *)toks
);
570 * read default attribute to use for RDN
572 if (( tokcnt
= ldap_next_line_tokens( bufp
, blenp
, &toks
)) != 1 ) {
573 ldap_free_strarray( toks
);
574 free_disptmpl( tmpl
);
575 return( LDAP_TMPL_ERR_SYNTAX
);
577 tmpl
->dt_defrdnattrname
= toks
[ 0 ];
578 NSLDAPI_FREE( (char *)toks
);
581 * read default location for new entries
583 if (( tokcnt
= ldap_next_line_tokens( bufp
, blenp
, &toks
)) != 1 ) {
584 ldap_free_strarray( toks
);
585 free_disptmpl( tmpl
);
586 return( LDAP_TMPL_ERR_SYNTAX
);
588 if ( toks
[ 0 ][ 0 ] != '\0' ) {
589 tmpl
->dt_defaddlocation
= toks
[ 0 ];
591 NSLDAPI_FREE( toks
[ 0 ] );
593 NSLDAPI_FREE( (char *)toks
);
596 * read list of rules used to define default values for new entries
598 while (( tokcnt
= ldap_next_line_tokens( bufp
, blenp
, &toks
)) > 0 ) {
599 if ( strcasecmp( ADDEF_CONSTANT
, toks
[ 0 ] ) == 0 ) {
600 adsource
= LDAP_ADSRC_CONSTANTVALUE
;
601 } else if ( strcasecmp( ADDEF_ADDERSDN
, toks
[ 0 ] ) == 0 ) {
602 adsource
= LDAP_ADSRC_ADDERSDN
;
606 if ( adsource
== 0 || tokcnt
< 2 ||
607 ( adsource
== LDAP_ADSRC_CONSTANTVALUE
&& tokcnt
!= 3 ) ||
608 ( adsource
== LDAP_ADSRC_ADDERSDN
&& tokcnt
!= 2 )) {
609 ldap_free_strarray( toks
);
610 free_disptmpl( tmpl
);
611 return( LDAP_TMPL_ERR_SYNTAX
);
614 if (( adp
= (struct ldap_adddeflist
*)NSLDAPI_CALLOC( 1,
615 sizeof( struct ldap_adddeflist
))) == NULL
) {
616 ldap_free_strarray( toks
);
617 free_disptmpl( tmpl
);
618 return( LDAP_TMPL_ERR_MEM
);
620 adp
->ad_source
= adsource
;
621 adp
->ad_attrname
= toks
[ 1 ];
622 if ( adsource
== LDAP_ADSRC_CONSTANTVALUE
) {
623 adp
->ad_value
= toks
[ 2 ];
625 NSLDAPI_FREE( toks
[ 0 ] );
626 NSLDAPI_FREE( (char *)toks
);
628 if ( tmpl
->dt_adddeflist
== NULL
) {
629 tmpl
->dt_adddeflist
= adp
;
631 prevadp
->ad_next
= adp
;
640 while (( tokcnt
= ldap_next_line_tokens( bufp
, blenp
, &toks
)) > 0 ) {
641 if ( strcasecmp( toks
[ 0 ], "item" ) == 0 ) {
643 ldap_free_strarray( toks
);
644 free_disptmpl( tmpl
);
645 return( LDAP_TMPL_ERR_SYNTAX
);
648 if (( ip
= (struct ldap_tmplitem
*)NSLDAPI_CALLOC( 1,
649 sizeof( struct ldap_tmplitem
))) == NULL
) {
650 ldap_free_strarray( toks
);
651 free_disptmpl( tmpl
);
652 return( LDAP_TMPL_ERR_MEM
);
656 * find syntaxid from config file string
658 while (( itemopts
= strrchr( toks
[ 1 ], ',' )) != NULL
) {
660 for ( i
= 0; itemoptions
[ i
] != NULL
; ++i
) {
661 if ( strcasecmp( itemopts
, itemoptions
[ i
] ) == 0 ) {
665 if ( itemoptions
[ i
] == NULL
) {
666 ldap_free_strarray( toks
);
667 free_disptmpl( tmpl
);
668 return( LDAP_TMPL_ERR_SYNTAX
);
670 ip
->ti_options
|= itemoptvals
[ i
];
673 for ( i
= 0; itemtypes
[ i
] != NULL
; ++i
) {
674 if ( strcasecmp( toks
[ 1 ], itemtypes
[ i
] ) == 0 ) {
678 if ( itemtypes
[ i
] == NULL
) {
679 ldap_free_strarray( toks
);
680 free_disptmpl( tmpl
);
681 return( LDAP_TMPL_ERR_SYNTAX
);
684 NSLDAPI_FREE( toks
[ 0 ] );
685 NSLDAPI_FREE( toks
[ 1 ] );
686 ip
->ti_syntaxid
= itemsynids
[ i
];
687 ip
->ti_label
= toks
[ 2 ];
688 if ( toks
[ 3 ][ 0 ] == '\0' ) {
689 ip
->ti_attrname
= NULL
;
690 NSLDAPI_FREE( toks
[ 3 ] );
692 ip
->ti_attrname
= toks
[ 3 ];
694 if ( toks
[ 4 ] != NULL
) { /* extra args. */
695 for ( i
= 0; toks
[ i
+ 4 ] != NULL
; ++i
) {
698 if (( ip
->ti_args
= (char **)NSLDAPI_CALLOC( i
+ 1,
699 sizeof( char * ))) == NULL
) {
700 free_disptmpl( tmpl
);
701 return( LDAP_TMPL_ERR_MEM
);
703 for ( i
= 0; toks
[ i
+ 4 ] != NULL
; ++i
) {
704 ip
->ti_args
[ i
] = toks
[ i
+ 4 ];
707 NSLDAPI_FREE( (char *)toks
);
709 if ( tmpl
->dt_items
== NULL
) {
710 tmpl
->dt_items
= rowp
= ip
;
711 } else if ( samerow
) {
712 previp
->ti_next_in_row
= ip
;
714 rowp
->ti_next_in_col
= ip
;
719 } else if ( strcasecmp( toks
[ 0 ], "samerow" ) == 0 ) {
720 ldap_free_strarray( toks
);
723 ldap_free_strarray( toks
);
724 free_disptmpl( tmpl
);
725 return( LDAP_TMPL_ERR_SYNTAX
);
729 free_disptmpl( tmpl
);
730 return( LDAP_TMPL_ERR_SYNTAX
);
744 static struct tmplerror ldap_tmplerrlist
[] = {
745 { LDAP_TMPL_ERR_VERSION
, 0},
746 { LDAP_TMPL_ERR_MEM
, 0},
747 { LDAP_TMPL_ERR_SYNTAX
, 0},
748 { LDAP_TMPL_ERR_FILE
, 0},
752 static struct tmplerror ldap_tmplerrlist
[] = {
753 { LDAP_TMPL_ERR_VERSION
, "Bad template version" },
754 { LDAP_TMPL_ERR_MEM
, "Out of memory" },
755 { LDAP_TMPL_ERR_SYNTAX
, "Bad template syntax" },
756 { LDAP_TMPL_ERR_FILE
, "File error reading template" },
763 ldap_tmplerr2string( int err
)
765 static int init_flag
= 0;
768 /* Multiple threads should be ok since they assign same strings */
769 if (init_flag
== 0) {
770 ldap_tmplerrlist
[0].e_reason
=
771 dgettext(TEXT_DOMAIN
, "Bad template version");
772 ldap_tmplerrlist
[1].e_reason
=
773 dgettext(TEXT_DOMAIN
, "Out of memory");
774 ldap_tmplerrlist
[2].e_reason
=
775 dgettext(TEXT_DOMAIN
, "Bad template syntax");
776 ldap_tmplerrlist
[3].e_reason
=
777 dgettext(TEXT_DOMAIN
, "File error reading template");
781 for ( i
= 0; ldap_tmplerrlist
[i
].e_code
!= -1; i
++ ) {
782 if ( err
== ldap_tmplerrlist
[i
].e_code
)
783 return( ldap_tmplerrlist
[i
].e_reason
);
786 return(dgettext(TEXT_DOMAIN
, "Unknown error") );