2 * tmplout.c: display template library output routines for LDAP clients
3 * 12 April 1994 by Mark C Smith
11 #include <ac/socket.h>
12 #include <ac/string.h>
22 #include "ldapconfig.h"
24 static int do_entry2text LDAP_P((
25 LDAP *ld, char *buf, char *base, LDAPMessage *entry,
26 struct ldap_disptmpl *tmpl, char **defattrs, char ***defvals,
27 writeptype writeproc, void *writeparm, char *eol, int rdncount,
28 unsigned long opts, char *urlprefix ));
29 static int do_entry2text_search LDAP_P((
30 LDAP *ld, char *dn, char *base,
31 LDAPMessage *entry, struct ldap_disptmpl *tmpllist, char **defattrs,
32 char ***defvals, writeptype writeproc, void *writeparm, char *eol,
33 int rdncount, unsigned long opts, char *urlprefix ));
34 static int do_vals2text LDAP_P((
35 LDAP *ld, char *buf, char **vals, char *label,
36 int labelwidth, unsigned long syntaxid, writeptype writeproc,
37 void *writeparm, char *eol, int rdncount, char *urlprefix ));
38 static int max_label_len LDAP_P(( struct ldap_disptmpl *tmpl ));
39 static int output_label LDAP_P((
40 char *buf, char *label, int width,
41 writeptype writeproc, void *writeparm, char *eol, int html ));
42 static int output_dn LDAP_P((
43 char *buf, char *dn, int width, int rdncount,
44 writeptype writeproc, void *writeparm, char *eol, char *urlprefix ));
45 static void strcat_escaped LDAP_P(( char *s1, char *s2 ));
46 static char *time2text LDAP_P(( char *ldtimestr, int dateonly ));
47 static long gtime LDAP_P(( struct tm *tm ));
48 static int searchaction LDAP_P((
49 LDAP *ld, char *buf, char *base, LDAPMessage *entry,
50 char *dn, struct ldap_tmplitem *tip, int labelwidth, int rdncount,
51 writeptype writeproc, void *writeparm, char *eol, char *urlprefix ));
53 #define DEF_LABEL_WIDTH 15
54 #define SEARCH_TIMEOUT_SECS 120
55 #define OCATTRNAME "objectClass"
58 #define NONFATAL_LDAP_ERR( err ) ( err == LDAP_SUCCESS || \
59 err == LDAP_TIMELIMIT_EXCEEDED || err == LDAP_SIZELIMIT_EXCEEDED )
61 #define DEF_LDAP_URL_PREFIX "ldap:///"
67 char *buf, /* NULL for "use internal" */
69 struct ldap_disptmpl *tmpl,
79 Debug( LDAP_DEBUG_TRACE, "ldap_entry2text\n", 0, 0, 0 );
81 return( do_entry2text( ld, buf, NULL, entry, tmpl, defattrs, defvals,
82 writeproc, writeparm, eol, rdncount, opts, NULL ));
91 char *buf, /* NULL for "use internal" */
93 struct ldap_disptmpl *tmpl,
105 Debug( LDAP_DEBUG_TRACE, "ldap_entry2html\n", 0, 0, 0 );
107 if ( urlprefix == NULL ) {
108 urlprefix = DEF_LDAP_URL_PREFIX;
111 return( do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals,
112 writeproc, writeparm, eol, rdncount, opts, urlprefix ));
119 char *buf, /* NULL for use-internal */
120 char *base, /* used for search actions */
122 struct ldap_disptmpl *tmpl,
125 writeptype writeproc,
130 char *urlprefix /* if non-NULL, do HTML */
133 int i, err, html, show, labelwidth;
134 int freebuf, freevals;
136 struct ldap_tmplitem *rowp, *colp;
138 if (( dn = ldap_get_dn( ld, entry )) == NULL ) {
139 return( ld->ld_errno );
143 if (( buf = malloc( LDAP_DTMPL_BUFSIZ )) == NULL ) {
144 ld->ld_errno = LDAP_NO_MEMORY;
146 return( ld->ld_errno );
153 html = ( urlprefix != NULL );
157 * add HTML intro. and title
159 if (!(( opts & LDAP_DISP_OPT_HTMLBODYONLY ) != 0 )) {
160 sprintf( buf, "<HTML>%s<HEAD>%s<TITLE>%s%s - ", eol, eol, eol,
161 ( tmpl == NULL ) ? "Entry" : tmpl->dt_name );
162 (*writeproc)( writeparm, buf, strlen( buf ));
163 output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL );
164 sprintf( buf, "%s</TITLE>%s</HEAD>%s<BODY>%s<H3>%s - ", eol, eol,
165 eol, eol, ( tmpl == NULL ) ? "Entry" : tmpl->dt_name );
166 (*writeproc)( writeparm, buf, strlen( buf ));
167 output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL );
168 sprintf( buf, "</H3>%s", eol );
169 (*writeproc)( writeparm, buf, strlen( buf ));
172 if (( opts & LDAP_DISP_OPT_NONLEAF ) != 0 &&
173 ( vals = ldap_explode_dn( dn, 0 )) != NULL ) {
179 sprintf( buf, "<A HREF=\"%s", urlprefix );
180 for ( i = 1; vals[ i ] != NULL; ++i ) {
182 strcat_escaped( buf, ", " );
184 strcat_escaped( buf, vals[ i ] );
186 if ( vals[ 1 ] != NULL ) {
187 untagged = strchr( vals[ 1 ], '=' );
189 untagged = "=The World";
191 sprintf( buf + strlen( buf ),
192 "%s\">Move Up To <EM>%s</EM></A>%s<BR>",
193 ( vals[ 1 ] == NULL ) ? "??one" : "",
194 ( untagged != NULL ) ? untagged + 1 : vals[ 1 ], eol, eol );
195 (*writeproc)( writeparm, buf, strlen( buf ));
200 untagged = strchr( vals[ 0 ], '=' );
201 sprintf( buf, "<A HREF=\"%s", urlprefix );
202 strcat_escaped( buf, dn );
203 sprintf( buf + strlen( buf ), "??one?(!(objectClass=dsa))\">Browse Below <EM>%s</EM></A>%s%s",
204 ( untagged != NULL ) ? untagged + 1 : vals[ 0 ], eol, eol );
205 (*writeproc)( writeparm, buf, strlen( buf ));
207 ldap_value_free( vals );
210 (*writeproc)( writeparm, "<HR>", 4 ); /* horizontal rule */
212 (*writeproc)( writeparm, "\"", 1 );
213 output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL );
214 sprintf( buf, "\"%s", eol );
215 (*writeproc)( writeparm, buf, strlen( buf ));
218 if ( tmpl != NULL && ( opts & LDAP_DISP_OPT_AUTOLABELWIDTH ) != 0 ) {
219 labelwidth = max_label_len( tmpl ) + 3;
221 labelwidth = DEF_LABEL_WIDTH;;
226 if ( tmpl == NULL ) {
231 for ( attr = ldap_first_attribute( ld, entry, &ber );
232 NONFATAL_LDAP_ERR( err ) && attr != NULL;
233 attr = ldap_next_attribute( ld, entry, ber )) {
234 if (( vals = ldap_get_values( ld, entry, attr )) == NULL ) {
236 if ( defattrs != NULL ) {
237 for ( i = 0; defattrs[ i ] != NULL; ++i ) {
238 if ( strcasecmp( attr, defattrs[ i ] ) == 0 ) {
242 if ( defattrs[ i ] != NULL ) {
250 if ( islower( *attr )) { /* cosmetic -- upcase attr. name */
251 *attr = toupper( *attr );
254 err = do_vals2text( ld, buf, vals, attr, labelwidth,
255 LDAP_SYN_CASEIGNORESTR, writeproc, writeparm, eol,
256 rdncount, urlprefix );
258 ldap_value_free( vals );
262 for ( rowp = ldap_first_tmplrow( tmpl );
263 NONFATAL_LDAP_ERR( err ) && rowp != NULLTMPLITEM;
264 rowp = ldap_next_tmplrow( tmpl, rowp )) {
265 for ( colp = ldap_first_tmplcol( tmpl, rowp ); colp != NULLTMPLITEM;
266 colp = ldap_next_tmplcol( tmpl, rowp, colp )) {
268 if ( colp->ti_attrname == NULL || ( vals = ldap_get_values( ld,
269 entry, colp->ti_attrname )) == NULL ) {
271 if ( !LDAP_IS_TMPLITEM_OPTION_SET( colp,
272 LDAP_DITEM_OPT_HIDEIFEMPTY ) && defattrs != NULL
273 && colp->ti_attrname != NULL ) {
274 for ( i = 0; defattrs[ i ] != NULL; ++i ) {
275 if ( strcasecmp( colp->ti_attrname, defattrs[ i ] )
280 if ( defattrs[ i ] != NULL ) {
286 if ( LDAP_IS_TMPLITEM_OPTION_SET( colp,
287 LDAP_DITEM_OPT_SORTVALUES ) && vals[ 0 ] != NULL
288 && vals[ 1 ] != NULL ) {
289 ldap_sort_values( ld, vals, ldap_sort_strcasecmp );
294 * don't bother even calling do_vals2text() if no values
295 * or boolean with value false and "hide if false" option set
297 show = ( vals != NULL && vals[ 0 ] != NULL );
298 if ( show && LDAP_GET_SYN_TYPE( colp->ti_syntaxid )
299 == LDAP_SYN_TYPE_BOOLEAN && LDAP_IS_TMPLITEM_OPTION_SET(
300 colp, LDAP_DITEM_OPT_HIDEIFFALSE ) &&
301 toupper( vals[ 0 ][ 0 ] ) != 'T' ) {
305 if ( colp->ti_syntaxid == LDAP_SYN_SEARCHACTION ) {
306 if (( opts & LDAP_DISP_OPT_DOSEARCHACTIONS ) != 0 ) {
307 if ( colp->ti_attrname == NULL || ( show &&
308 toupper( vals[ 0 ][ 0 ] ) == 'T' )) {
309 err = searchaction( ld, buf, base, entry, dn, colp,
310 labelwidth, rdncount, writeproc,
311 writeparm, eol, urlprefix );
318 err = do_vals2text( ld, buf, vals, colp->ti_label,
319 labelwidth, colp->ti_syntaxid, writeproc, writeparm,
320 eol, rdncount, urlprefix );
324 ldap_value_free( vals );
330 if ( html && !(( opts & LDAP_DISP_OPT_HTMLBODYONLY ) != 0 )) {
331 sprintf( buf, "</BODY>%s</HTML>%s", eol, eol );
332 (*writeproc)( writeparm, buf, strlen( buf ));
345 ldap_entry2text_search(
347 char *dn, /* if NULL, use entry */
348 char *base, /* if NULL, no search actions */
349 LDAPMessage *entry, /* if NULL, use dn */
350 struct ldap_disptmpl* tmpllist, /* if NULL, load default file */
353 writeptype writeproc,
356 int rdncount, /* if 0, display full DN */
360 Debug( LDAP_DEBUG_TRACE, "ldap_entry2text_search\n", 0, 0, 0 );
362 return( do_entry2text_search( ld, dn, base, entry, tmpllist, defattrs,
363 defvals, writeproc, writeparm, eol, rdncount, opts, NULL ));
369 ldap_entry2html_search(
371 char *dn, /* if NULL, use entry */
372 char *base, /* if NULL, no search actions */
373 LDAPMessage *entry, /* if NULL, use dn */
374 struct ldap_disptmpl* tmpllist, /* if NULL, load default file */
377 writeptype writeproc,
380 int rdncount, /* if 0, display full DN */
385 Debug( LDAP_DEBUG_TRACE, "ldap_entry2html_search\n", 0, 0, 0 );
387 return( do_entry2text_search( ld, dn, base, entry, tmpllist, defattrs,
388 defvals, writeproc, writeparm, eol, rdncount, opts, urlprefix ));
393 do_entry2text_search(
395 char *dn, /* if NULL, use entry */
396 char *base, /* if NULL, no search actions */
397 LDAPMessage *entry, /* if NULL, use dn */
398 struct ldap_disptmpl* tmpllist, /* if NULL, load default file */
401 writeptype writeproc,
404 int rdncount, /* if 0, display full DN */
409 int err, freedn, freetmpls, html;
410 char *buf, **fetchattrs, **vals;
412 struct ldap_disptmpl *tmpl;
413 struct timeval timeout;
415 if ( dn == NULL && entry == NULLMSG ) {
416 ld->ld_errno = LDAP_PARAM_ERROR;
417 return( ld->ld_errno );
420 html = ( urlprefix != NULL );
422 timeout.tv_sec = SEARCH_TIMEOUT_SECS;
425 if (( buf = malloc( LDAP_DTMPL_BUFSIZ )) == NULL ) {
426 ld->ld_errno = LDAP_NO_MEMORY;
427 return( ld->ld_errno );
430 freedn = freetmpls = 0;
433 if ( tmpllist == NULL ) {
434 if (( err = ldap_init_templates( TEMPLATEFILE, &tmpllist )) != 0 ) {
435 sprintf( buf, "%sUnable to read template file %s (error %d)%s%s",
436 html ? "<!-- " : "", TEMPLATEFILE, err,
437 html ? "-->" : "", eol );
438 (*writeproc)( writeparm, buf, strlen( buf ));
444 if (( dn = ldap_get_dn( ld, entry )) == NULL ) {
447 ldap_free_templates( tmpllist );
449 return( ld->ld_errno );
455 if ( tmpllist != NULL ) {
458 if ( entry == NULL ) {
461 ocattrs[0] = OCATTRNAME;
463 #ifdef LDAP_CONNECTIONLESS
464 if ( LDAP_IS_CLDAP( ld ))
465 err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE,
466 "objectClass=*", ocattrs, 0, &ldmp, NULL );
468 #endif /* LDAP_CONNECTIONLESS */
469 err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE,
470 "objectClass=*", ocattrs, 0, &timeout, &ldmp );
472 if ( err == LDAP_SUCCESS ) {
473 entry = ldap_first_entry( ld, ldmp );
477 if ( entry != NULL ) {
478 vals = ldap_get_values( ld, entry, OCATTRNAME );
479 tmpl = ldap_oc2template( vals, tmpllist );
480 if ( vals != NULL ) {
481 ldap_value_free( vals );
484 if ( ldmp != NULL ) {
485 ldap_msgfree( ldmp );
491 if ( tmpl == NULL ) {
494 fetchattrs = ldap_tmplattrs( tmpl, NULL, 1, LDAP_SYN_OPT_DEFER );
497 #ifdef LDAP_CONNECTIONLESS
498 if ( LDAP_IS_CLDAP( ld ))
499 err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
500 fetchattrs, 0, &ldmp, NULL );
502 #endif /* LDAP_CONNECTIONLESS */
503 err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
504 fetchattrs, 0, &timeout, &ldmp );
509 if ( fetchattrs != NULL ) {
510 ldap_value_free( fetchattrs );
513 if ( err != LDAP_SUCCESS ||
514 ( entry = ldap_first_entry( ld, ldmp )) == NULL ) {
516 ldap_free_templates( tmpllist );
519 return( ld->ld_errno );
522 err = do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals,
523 writeproc, writeparm, eol, rdncount, opts, urlprefix );
527 ldap_free_templates( tmpllist );
529 ldap_msgfree( ldmp );
537 char *buf, /* NULL for "use internal" */
540 int labelwidth, /* 0 means use default */
541 unsigned long syntaxid,
542 writeptype writeproc,
548 Debug( LDAP_DEBUG_TRACE, "ldap_vals2text\n", 0, 0, 0 );
550 return( do_vals2text( ld, buf, vals, label, labelwidth, syntaxid,
551 writeproc, writeparm, eol, rdncount, NULL ));
558 char *buf, /* NULL for "use internal" */
561 int labelwidth, /* 0 means use default */
562 unsigned long syntaxid,
563 writeptype writeproc,
570 Debug( LDAP_DEBUG_TRACE, "ldap_vals2html\n", 0, 0, 0 );
572 if ( urlprefix == NULL ) {
573 urlprefix = DEF_LDAP_URL_PREFIX;
576 return( do_vals2text( ld, buf, vals, label, labelwidth, syntaxid,
577 writeproc, writeparm, eol, rdncount, urlprefix ));
584 char *buf, /* NULL for "use internal" */
587 int labelwidth, /* 0 means use default */
588 unsigned long syntaxid,
589 writeptype writeproc,
596 int i, html, writeoutval, freebuf, notascii;
597 char *p, *s, *outval;
600 if ( vals == NULL ) {
601 return( LDAP_SUCCESS );
604 html = ( urlprefix != NULL );
606 switch( LDAP_GET_SYN_TYPE( syntaxid )) {
607 case LDAP_SYN_TYPE_TEXT:
608 case LDAP_SYN_TYPE_BOOLEAN:
609 break; /* we only bother with these two types... */
611 return( LDAP_SUCCESS );
614 if ( labelwidth == 0 || labelwidth < 0 ) {
615 labelwidth = DEF_LABEL_WIDTH;
619 if (( buf = malloc( LDAP_DTMPL_BUFSIZ )) == NULL ) {
620 ld->ld_errno = LDAP_NO_MEMORY;
621 return( ld->ld_errno );
628 output_label( buf, label, labelwidth, writeproc, writeparm, eol, html );
630 for ( i = 0; vals[ i ] != NULL; ++i ) {
631 for ( p = vals[ i ]; *p != '\0'; ++p ) {
632 if ( !isascii( *p )) {
636 notascii = ( *p != '\0' );
637 outval = notascii ? "(unable to display non-ASCII text value)"
640 writeoutval = 0; /* if non-zero, write outval after switch */
643 case LDAP_SYN_CASEIGNORESTR:
647 case LDAP_SYN_RFC822ADDR:
649 strcpy( buf, "<DD><A HREF=\"mailto:" );
650 strcat_escaped( buf, outval );
651 sprintf( buf + strlen( buf ), "\">%s</A><BR>%s", outval, eol );
652 (*writeproc)( writeparm, buf, strlen( buf ));
658 case LDAP_SYN_DN: /* for now */
659 output_dn( buf, outval, labelwidth, rdncount, writeproc,
660 writeparm, eol, urlprefix );
663 case LDAP_SYN_MULTILINESTR:
664 if ( i > 0 && !html ) {
665 output_label( buf, label, labelwidth, writeproc,
666 writeparm, eol, html );
670 while (( s = strchr( s, '$' )) != NULL ) {
672 while ( isspace( *s )) {
676 sprintf( buf, "<DD>%s<BR>%s", p, eol );
678 sprintf( buf, "%-*s%s%s", labelwidth, " ", p, eol );
680 (*writeproc)( writeparm, buf, strlen( buf ));
687 case LDAP_SYN_BOOLEAN:
688 outval = toupper( outval[ 0 ] ) == 'T' ? "TRUE" : "FALSE";
694 outval = time2text( outval, syntaxid == LDAP_SYN_DATE );
698 case LDAP_SYN_LABELEDURL:
699 if ( !notascii && ( p = strchr( outval, '$' )) != NULL ) {
701 while ( isspace( *p )) {
705 } else if ( !notascii && ( s = strchr( outval, ' ' )) != NULL ) {
707 while ( isspace( *s )) {
717 * at this point `s' points to the label & `p' to the URL
720 sprintf( buf, "<DD><A HREF=\"%s\">%s</A><BR>%s", p, s, eol );
722 sprintf( buf, "%-*s%s%s%-*s%s%s", labelwidth, " ",
723 s, eol, labelwidth + 2, " ",p , eol );
725 (*writeproc)( writeparm, buf, strlen( buf ));
729 sprintf( buf, " Can't display item type %ld%s",
731 (*writeproc)( writeparm, buf, strlen( buf ));
736 sprintf( buf, "<DD>%s<BR>%s", outval, eol );
738 sprintf( buf, "%-*s%s%s", labelwidth, " ", outval, eol );
740 (*writeproc)( writeparm, buf, strlen( buf ));
748 return( LDAP_SUCCESS );
753 max_label_len( struct ldap_disptmpl *tmpl )
755 struct ldap_tmplitem *rowp, *colp;
760 for ( rowp = ldap_first_tmplrow( tmpl ); rowp != NULLTMPLITEM;
761 rowp = ldap_next_tmplrow( tmpl, rowp )) {
762 for ( colp = ldap_first_tmplcol( tmpl, rowp ); colp != NULLTMPLITEM;
763 colp = ldap_next_tmplcol( tmpl, rowp, colp )) {
764 if (( len = strlen( colp->ti_label )) > maxlen ) {
775 output_label( char *buf, char *label, int width, writeptype writeproc,
776 void *writeparm, char *eol, int html )
781 sprintf( buf, "<DT><B>%s</B>", label );
783 sprintf( buf, " %s:", label );
784 p = buf + strlen( buf );
786 while ( p - buf < width ) {
794 return ((*writeproc)( writeparm, buf, strlen( buf )));
799 output_dn( char *buf, char *dn, int width, int rdncount,
800 writeptype writeproc, void *writeparm, char *eol, char *urlprefix )
805 if (( dnrdns = ldap_explode_dn( dn, 1 )) == NULL ) {
809 if ( urlprefix != NULL ) {
810 sprintf( buf, "<DD><A HREF=\"%s", urlprefix );
811 strcat_escaped( buf, dn );
812 strcat( buf, "\">" );
813 } else if ( width > 0 ) {
814 sprintf( buf, "%-*s", width, " " );
819 for ( i = 0; dnrdns[ i ] != NULL && ( rdncount == 0 || i < rdncount );
824 strcat( buf, dnrdns[ i ] );
827 if ( urlprefix != NULL ) {
828 strcat( buf, "</A><BR>" );
831 ldap_value_free( dnrdns );
835 return ((*writeproc)( writeparm, buf, strlen( buf )));
840 #define HREF_CHAR_ACCEPTABLE( c ) (( c >= '-' && c <= '9' ) || \
841 ( c >= '@' && c <= 'Z' ) || \
843 ( c >= 'a' && c <= 'z' ))
846 strcat_escaped( char *s1, char *s2 )
849 char *hexdig = "0123456789ABCDEF";
851 p = s1 + strlen( s1 );
852 for ( q = s2; *q != '\0'; ++q ) {
853 if ( HREF_CHAR_ACCEPTABLE( *q )) {
857 *p++ = hexdig[ *q >> 4 ];
858 *p++ = hexdig[ *q & 0x0F ];
866 #define GET2BYTENUM( p ) (( *p - '0' ) * 10 + ( *(p+1) - '0' ))
869 time2text( char *ldtimestr, int dateonly )
872 char *p, *timestr, zone, *fmterr = "badly formatted time";
875 memset( (char *)&t, 0, sizeof( struct tm ));
876 if ( (int) strlen( ldtimestr ) < 13 ) {
880 for ( p = ldtimestr; p - ldtimestr < 12; ++p ) {
881 if ( !isdigit( *p )) {
887 t.tm_year = GET2BYTENUM( p ); p += 2;
888 t.tm_mon = GET2BYTENUM( p ) - 1; p += 2;
889 t.tm_mday = GET2BYTENUM( p ); p += 2;
890 t.tm_hour = GET2BYTENUM( p ); p += 2;
891 t.tm_min = GET2BYTENUM( p ); p += 2;
892 t.tm_sec = GET2BYTENUM( p ); p += 2;
894 if (( zone = *p ) == 'Z' ) { /* GMT */
895 zone = '\0'; /* no need to indicate on screen, so we make it null */
898 gmttime = gtime( &t );
899 timestr = ctime( &gmttime );
901 timestr[ strlen( timestr ) - 1 ] = zone; /* replace trailing newline */
903 strcpy( timestr + 11, timestr + 20 );
911 /* gtime.c - inverse gmtime */
913 #if !defined( MACOS ) && !defined( _WIN32 ) && !defined( DOS )
914 #include <sys/time.h>
917 /* gtime(): the inverse of localtime().
918 This routine was supplied by Mike Accetta at CMU many years ago.
921 static int dmsize[] = {
922 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
926 (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
928 #define YEAR(y) ((y) >= 100 ? (y) : (y) + 1900)
932 static long gtime ( struct tm *tm )
941 register long result;
943 if ((sec = tm -> tm_sec) < 0 || sec > 59
944 || (mins = tm -> tm_min) < 0 || mins > 59
945 || (hour = tm -> tm_hour) < 0 || hour > 24
946 || (mday = tm -> tm_mday) < 1 || mday > 31
947 || (mon = tm -> tm_mon + 1) < 1 || mon > 12)
953 year = YEAR (tm -> tm_year);
956 for (i = 1970; i < year; i++)
957 result += dysize (i);
958 if (dysize (year) == 366 && mon >= 3)
961 result += dmsize[mon - 1];
963 result = 24 * result + hour;
964 result = 60 * result + mins;
965 result = 60 * result + sec;
971 searchaction( LDAP *ld, char *buf, char *base, LDAPMessage *entry, char *dn,
972 struct ldap_tmplitem *tip, int labelwidth, int rdncount,
973 writeptype writeproc, void *writeparm, char *eol, char *urlprefix )
975 int err = 0, lderr, i, count, html;
976 char **vals, **members;
977 char *value, *filtpattern, *attr, *selectname;
978 char *retattrs[2], filter[ 256 ];
980 struct timeval timeout;
982 html = ( urlprefix != NULL );
984 for ( i = 0; tip->ti_args != NULL && tip->ti_args[ i ] != NULL; ++i ) {
988 return( LDAP_PARAM_ERROR );
990 attr = tip->ti_args[ 0 ];
991 filtpattern = tip->ti_args[ 1 ];
992 retattrs[ 0 ] = tip->ti_args[ 2 ];
993 retattrs[ 1 ] = NULL;
994 selectname = tip->ti_args[ 3 ];
997 if ( attr == NULL ) {
999 } else if ( strcasecmp( attr, "-dnb" ) == 0 ) {
1000 return( LDAP_PARAM_ERROR );
1001 } else if ( strcasecmp( attr, "-dnt" ) == 0 ) {
1003 } else if (( vals = ldap_get_values( ld, entry, attr )) != NULL ) {
1009 ldap_build_filter( filter, sizeof( filter ), filtpattern, NULL, NULL, NULL,
1014 * if we are generating HTML, we add an HREF link that embodies this
1015 * search action as an LDAP URL, instead of actually doing the search
1018 sprintf( buf, "<DT><A HREF=\"%s", urlprefix );
1019 if ( base != NULL ) {
1020 strcat_escaped( buf, base );
1022 strcat( buf, "??sub?" );
1023 strcat_escaped( buf, filter );
1024 sprintf( buf + strlen( buf ), "\"><B>%s</B></A><DD><BR>%s",
1025 tip->ti_label, eol );
1026 if ((*writeproc)( writeparm, buf, strlen( buf )) < 0 ) {
1027 return( LDAP_LOCAL_ERROR );
1029 return( LDAP_SUCCESS );
1032 timeout.tv_sec = SEARCH_TIMEOUT_SECS;
1033 timeout.tv_usec = 0;
1035 #ifdef LDAP_CONNECTIONLESS
1036 if ( LDAP_IS_CLDAP( ld ))
1037 lderr = cldap_search_s( ld, base, LDAP_SCOPE_SUBTREE, filter, retattrs,
1040 #endif /* LDAP_CONNECTIONLESS */
1041 lderr = ldap_search_st( ld, base, LDAP_SCOPE_SUBTREE, filter, retattrs,
1042 0, &timeout, &ldmp );
1044 if ( lderr == LDAP_SUCCESS || NONFATAL_LDAP_ERR( lderr )) {
1045 if (( count = ldap_count_entries( ld, ldmp )) > 0 ) {
1046 if (( members = (char **)malloc( (count + 1) * sizeof(char *)))
1048 err = LDAP_NO_MEMORY;
1050 for ( i = 0, entry = ldap_first_entry( ld, ldmp );
1052 entry = ldap_next_entry( ld, entry ), ++i ) {
1053 members[ i ] = ldap_get_dn( ld, entry );
1055 members[ i ] = NULL;
1057 ldap_sort_values( ld, members, ldap_sort_strcasecmp );
1059 err = do_vals2text( ld, NULL, members, tip->ti_label,
1060 html ? -1 : 0, LDAP_SYN_DN, writeproc, writeparm,
1061 eol, rdncount, urlprefix );
1063 ldap_value_free( members );
1066 ldap_msgfree( ldmp );
1070 if ( vals != NULL ) {
1071 ldap_value_free( vals );
1074 return(( err == LDAP_SUCCESS ) ? lderr : err );