dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libldap5 / sources / ldap / common / disptmpl.c
blob7e97b33deee85e868808f8e5fc8eeb549f2db6af
1 /*
2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
6 #pragma ident "%Z%%M% %I% %E% SMI"
9 /*
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
21 * March 31, 1998.
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
26 * Rights Reserved.
28 * Contributor(s):
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
45 #include "ldap-int.h"
46 #include "disptmpl.h"
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[] = {
53 "addable", "modrdn",
54 "altview",
55 NULL
59 static unsigned long tmploptvals[] = {
60 LDAP_DTMPL_OPT_ADDABLE, LDAP_DTMPL_OPT_ALLOWMODRDN,
61 LDAP_DTMPL_OPT_ALTVIEW,
65 static char *itemtypes[] = {
66 "cis", "mls", "dn",
67 "bool", "jpeg", "jpegbtn",
68 "fax", "faxbtn", "audiobtn",
69 "time", "date", "url",
70 "searchact", "linkact", "adddnact",
71 "addact", "verifyact", "mail",
72 NULL
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[] = {
86 "ro", "sort",
87 "1val", "hide",
88 "required", "hideiffalse",
89 NULL
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"
105 LDAP_CALL
106 ldap_init_templates( char *file, struct ldap_disptmpl **tmpllistp )
108 FILE *fp;
109 char *buf;
110 long rlen, len;
111 int rc, eof;
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 */
120 fclose( fp );
121 return( LDAP_TMPL_ERR_FILE );
124 len = ftell( fp );
126 if ( fseek( fp, 0L, SEEK_SET ) != 0 ) { /* back to start of file */
127 fclose( fp );
128 return( LDAP_TMPL_ERR_FILE );
131 if (( buf = NSLDAPI_MALLOC( (size_t)len )) == NULL ) {
132 fclose( fp );
133 return( LDAP_TMPL_ERR_MEM );
136 rlen = fread( buf, 1, (size_t)len, fp );
137 eof = feof( fp );
138 fclose( fp );
140 if ( rlen != len && !eof ) { /* error: didn't get the whole file */
141 NSLDAPI_FREE( buf );
142 return( LDAP_TMPL_ERR_FILE );
145 rc = ldap_init_templates_buf( buf, rlen, tmpllistp );
146 NSLDAPI_FREE( buf );
148 return( rc );
153 LDAP_CALL
154 ldap_init_templates_buf( char *buf, long buflen,
155 struct ldap_disptmpl **tmpllistp )
157 int rc = 0, version;
158 char **toks;
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 ) {
177 *tmpllistp = tmpl;
178 } else {
179 prevtmpl->dt_next = tmpl;
181 prevtmpl = tmpl;
184 if ( rc != 0 ) {
185 ldap_free_templates( *tmpllistp );
188 return( rc );
193 void
194 LDAP_CALL
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;
202 free_disptmpl( tp );
208 static void
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 );
242 NSLDAPI_FREE( ocp );
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 );
257 NSLDAPI_FREE( adp );
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 *
288 LDAP_CALL
289 ldap_first_disptmpl( struct ldap_disptmpl *tmpllist )
291 return( tmpllist );
295 struct ldap_disptmpl *
296 LDAP_CALL
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 *
305 LDAP_CALL
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 ) {
313 return( dtp );
317 return( NULLDISPTMPL );
321 struct ldap_disptmpl *
322 LDAP_CALL
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 ] )
341 == 0 ) {
342 ++matchcnt;
345 ++needcnt;
348 if ( matchcnt == needcnt ) {
349 return( dtp );
354 return( NULLDISPTMPL );
358 struct ldap_tmplitem *
359 LDAP_CALL
360 ldap_first_tmplrow( struct ldap_disptmpl *tmpl )
362 return( tmpl->dt_items );
366 struct ldap_tmplitem *
367 LDAP_CALL
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 *
375 LDAP_CALL
376 ldap_first_tmplcol( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row )
378 return( row );
382 struct ldap_tmplitem *
383 LDAP_CALL
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 );
391 char **
392 LDAP_CALL
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;
401 char **attrs;
403 attrcnt = 0;
404 memerr = 0;
406 if (( attrs = (char **)NSLDAPI_MALLOC( sizeof( char * ))) == NULL ) {
407 return( 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 ) {
415 memerr = 1;
416 } else {
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 ) {
430 if (( exclude &&
431 ( syntaxmask & ticolp->ti_syntaxid ) != 0 ) ||
432 ( !exclude &&
433 ( syntaxmask & ticolp->ti_syntaxid ) == 0 )) {
434 continue;
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 ) {
442 memerr = 1;
443 } else {
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 );
458 return( NULL );
461 return( attrs );
465 static int
466 read_next_tmpl( char **bufp, long *blenp, struct ldap_disptmpl **tmplp,
467 int dtversion )
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;
544 } else {
545 prevocp->oc_next = ocp;
547 prevocp = ocp;
549 if ( tokcnt < 0 ) {
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 ];
564 } else {
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 ];
590 } else {
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;
603 } else {
604 adsource = 0;
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;
630 } else {
631 prevadp->ad_next = adp;
633 prevadp = adp;
637 * item list is next
639 samerow = 0;
640 while (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
641 if ( strcasecmp( toks[ 0 ], "item" ) == 0 ) {
642 if ( tokcnt < 4 ) {
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 ) {
659 *itemopts++ = '\0';
660 for ( i = 0; itemoptions[ i ] != NULL; ++i ) {
661 if ( strcasecmp( itemopts, itemoptions[ i ] ) == 0 ) {
662 break;
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 ) {
675 break;
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 ] );
691 } else {
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;
713 } else {
714 rowp->ti_next_in_col = ip;
715 rowp = ip;
717 previp = ip;
718 samerow = 0;
719 } else if ( strcasecmp( toks[ 0 ], "samerow" ) == 0 ) {
720 ldap_free_strarray( toks );
721 samerow = 1;
722 } else {
723 ldap_free_strarray( toks );
724 free_disptmpl( tmpl );
725 return( LDAP_TMPL_ERR_SYNTAX );
728 if ( tokcnt < 0 ) {
729 free_disptmpl( tmpl );
730 return( LDAP_TMPL_ERR_SYNTAX );
733 *tmplp = tmpl;
734 return( 0 );
738 struct tmplerror {
739 int e_code;
740 char *e_reason;
743 #ifdef SUN
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},
749 { -1, 0 }
751 #else
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" },
757 { -1, 0 }
759 #endif
761 char *
762 LDAP_CALL
763 ldap_tmplerr2string( int err )
765 static int init_flag = 0;
766 int i;
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");
778 init_flag = 1;
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") );