1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright (c) 2001 by Sun Microsystems, Inc. 3*7c478bd9Sstevel@tonic-gate * All rights reserved. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*7c478bd9Sstevel@tonic-gate 8*7c478bd9Sstevel@tonic-gate /* 9*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public 10*7c478bd9Sstevel@tonic-gate * License Version 1.1 (the "License"); you may not use this file 11*7c478bd9Sstevel@tonic-gate * except in compliance with the License. You may obtain a copy of 12*7c478bd9Sstevel@tonic-gate * the License at http://www.mozilla.org/NPL/ 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * Software distributed under the License is distributed on an "AS 15*7c478bd9Sstevel@tonic-gate * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 16*7c478bd9Sstevel@tonic-gate * implied. See the License for the specific language governing 17*7c478bd9Sstevel@tonic-gate * rights and limitations under the License. 18*7c478bd9Sstevel@tonic-gate * 19*7c478bd9Sstevel@tonic-gate * The Original Code is Mozilla Communicator client code, released 20*7c478bd9Sstevel@tonic-gate * March 31, 1998. 21*7c478bd9Sstevel@tonic-gate * 22*7c478bd9Sstevel@tonic-gate * The Initial Developer of the Original Code is Netscape 23*7c478bd9Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are 24*7c478bd9Sstevel@tonic-gate * Copyright (C) 1998-1999 Netscape Communications Corporation. All 25*7c478bd9Sstevel@tonic-gate * Rights Reserved. 26*7c478bd9Sstevel@tonic-gate * 27*7c478bd9Sstevel@tonic-gate * Contributor(s): 28*7c478bd9Sstevel@tonic-gate */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * tmplout.c: display template library output routines for LDAP clients 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include "ldap-int.h" 36*7c478bd9Sstevel@tonic-gate #include "disptmpl.h" 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #if defined(_WINDOWS) || defined(aix) || defined(SCOOS) || defined(OSF1) || defined(SOLARIS) 39*7c478bd9Sstevel@tonic-gate #include <time.h> /* for struct tm and ctime */ 40*7c478bd9Sstevel@tonic-gate #endif 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate /* This is totally lame, since it should be coming from time.h, but isn't. */ 44*7c478bd9Sstevel@tonic-gate #if defined(SOLARIS) 45*7c478bd9Sstevel@tonic-gate char *ctime_r(const time_t *, char *, int); 46*7c478bd9Sstevel@tonic-gate #endif 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate static int do_entry2text( LDAP *ld, char *buf, char *base, LDAPMessage *entry, 49*7c478bd9Sstevel@tonic-gate struct ldap_disptmpl *tmpl, char **defattrs, char ***defvals, 50*7c478bd9Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, int rdncount, 51*7c478bd9Sstevel@tonic-gate unsigned long opts, char *urlprefix ); 52*7c478bd9Sstevel@tonic-gate static int do_entry2text_search( LDAP *ld, char *dn, char *base, 53*7c478bd9Sstevel@tonic-gate LDAPMessage *entry, struct ldap_disptmpl *tmpllist, char **defattrs, 54*7c478bd9Sstevel@tonic-gate char ***defvals, writeptype writeproc, void *writeparm, char *eol, 55*7c478bd9Sstevel@tonic-gate int rdncount, unsigned long opts, char *urlprefix ); 56*7c478bd9Sstevel@tonic-gate static int do_vals2text( LDAP *ld, char *buf, char **vals, char *label, 57*7c478bd9Sstevel@tonic-gate int labelwidth, unsigned long syntaxid, writeptype writeproc, 58*7c478bd9Sstevel@tonic-gate void *writeparm, char *eol, int rdncount, char *urlprefix ); 59*7c478bd9Sstevel@tonic-gate static int max_label_len( struct ldap_disptmpl *tmpl ); 60*7c478bd9Sstevel@tonic-gate static int output_label( char *buf, char *label, int width, 61*7c478bd9Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, int html ); 62*7c478bd9Sstevel@tonic-gate static int output_dn( char *buf, char *dn, int width, int rdncount, 63*7c478bd9Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, char *urlprefix ); 64*7c478bd9Sstevel@tonic-gate static void strcat_escaped( char *s1, char *s2 ); 65*7c478bd9Sstevel@tonic-gate static char *time2text( char *ldtimestr, int dateonly ); 66*7c478bd9Sstevel@tonic-gate static long gtime( struct tm *tm ); 67*7c478bd9Sstevel@tonic-gate static int searchaction( LDAP *ld, char *buf, char *base, LDAPMessage *entry, 68*7c478bd9Sstevel@tonic-gate char *dn, struct ldap_tmplitem *tip, int labelwidth, int rdncount, 69*7c478bd9Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, char *urlprefix ); 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate #define DEF_LABEL_WIDTH 15 72*7c478bd9Sstevel@tonic-gate #define SEARCH_TIMEOUT_SECS 120 73*7c478bd9Sstevel@tonic-gate #define OCATTRNAME "objectClass" 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate #define NONFATAL_LDAP_ERR( err ) ( err == LDAP_SUCCESS || \ 77*7c478bd9Sstevel@tonic-gate err == LDAP_TIMELIMIT_EXCEEDED || err == LDAP_SIZELIMIT_EXCEEDED ) 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate #define DEF_LDAP_URL_PREFIX "ldap:///" 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate int 83*7c478bd9Sstevel@tonic-gate LDAP_CALL 84*7c478bd9Sstevel@tonic-gate ldap_entry2text( 85*7c478bd9Sstevel@tonic-gate LDAP *ld, 86*7c478bd9Sstevel@tonic-gate char *buf, /* NULL for "use internal" */ 87*7c478bd9Sstevel@tonic-gate LDAPMessage *entry, 88*7c478bd9Sstevel@tonic-gate struct ldap_disptmpl *tmpl, 89*7c478bd9Sstevel@tonic-gate char **defattrs, 90*7c478bd9Sstevel@tonic-gate char ***defvals, 91*7c478bd9Sstevel@tonic-gate writeptype writeproc, 92*7c478bd9Sstevel@tonic-gate void *writeparm, 93*7c478bd9Sstevel@tonic-gate char *eol, 94*7c478bd9Sstevel@tonic-gate int rdncount, 95*7c478bd9Sstevel@tonic-gate unsigned long opts 96*7c478bd9Sstevel@tonic-gate ) 97*7c478bd9Sstevel@tonic-gate { 98*7c478bd9Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_entry2text\n", 0, 0, 0 ); 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate return( do_entry2text( ld, buf, NULL, entry, tmpl, defattrs, defvals, 101*7c478bd9Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, opts, NULL )); 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate int 108*7c478bd9Sstevel@tonic-gate LDAP_CALL 109*7c478bd9Sstevel@tonic-gate ldap_entry2html( 110*7c478bd9Sstevel@tonic-gate LDAP *ld, 111*7c478bd9Sstevel@tonic-gate char *buf, /* NULL for "use internal" */ 112*7c478bd9Sstevel@tonic-gate LDAPMessage *entry, 113*7c478bd9Sstevel@tonic-gate struct ldap_disptmpl *tmpl, 114*7c478bd9Sstevel@tonic-gate char **defattrs, 115*7c478bd9Sstevel@tonic-gate char ***defvals, 116*7c478bd9Sstevel@tonic-gate writeptype writeproc, 117*7c478bd9Sstevel@tonic-gate void *writeparm, 118*7c478bd9Sstevel@tonic-gate char *eol, 119*7c478bd9Sstevel@tonic-gate int rdncount, 120*7c478bd9Sstevel@tonic-gate unsigned long opts, 121*7c478bd9Sstevel@tonic-gate char *base, 122*7c478bd9Sstevel@tonic-gate char *urlprefix 123*7c478bd9Sstevel@tonic-gate ) 124*7c478bd9Sstevel@tonic-gate { 125*7c478bd9Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_entry2html\n", 0, 0, 0 ); 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate if ( urlprefix == NULL ) { 128*7c478bd9Sstevel@tonic-gate urlprefix = DEF_LDAP_URL_PREFIX; 129*7c478bd9Sstevel@tonic-gate } 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate return( do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals, 132*7c478bd9Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, opts, urlprefix )); 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate static int 137*7c478bd9Sstevel@tonic-gate do_entry2text( 138*7c478bd9Sstevel@tonic-gate LDAP *ld, 139*7c478bd9Sstevel@tonic-gate char *buf, /* NULL for use-internal */ 140*7c478bd9Sstevel@tonic-gate char *base, /* used for search actions */ 141*7c478bd9Sstevel@tonic-gate LDAPMessage *entry, 142*7c478bd9Sstevel@tonic-gate struct ldap_disptmpl *tmpl, 143*7c478bd9Sstevel@tonic-gate char **defattrs, 144*7c478bd9Sstevel@tonic-gate char ***defvals, 145*7c478bd9Sstevel@tonic-gate writeptype writeproc, 146*7c478bd9Sstevel@tonic-gate void *writeparm, 147*7c478bd9Sstevel@tonic-gate char *eol, 148*7c478bd9Sstevel@tonic-gate int rdncount, 149*7c478bd9Sstevel@tonic-gate unsigned long opts, 150*7c478bd9Sstevel@tonic-gate char *urlprefix /* if non-NULL, do HTML */ 151*7c478bd9Sstevel@tonic-gate ) 152*7c478bd9Sstevel@tonic-gate { 153*7c478bd9Sstevel@tonic-gate int i, err, html, show, labelwidth; 154*7c478bd9Sstevel@tonic-gate int freebuf, freevals; 155*7c478bd9Sstevel@tonic-gate char *dn, **vals; 156*7c478bd9Sstevel@tonic-gate struct ldap_tmplitem *rowp, *colp; 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { 159*7c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate if ( writeproc == NULL || 163*7c478bd9Sstevel@tonic-gate !NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry )) { 164*7c478bd9Sstevel@tonic-gate err = LDAP_PARAM_ERROR; 165*7c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, err, NULL, NULL ); 166*7c478bd9Sstevel@tonic-gate return( err ); 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate if (( dn = ldap_get_dn( ld, entry )) == NULL ) { 170*7c478bd9Sstevel@tonic-gate return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate if ( buf == NULL ) { 174*7c478bd9Sstevel@tonic-gate if (( buf = NSLDAPI_MALLOC( LDAP_DTMPL_BUFSIZ )) == NULL ) { 175*7c478bd9Sstevel@tonic-gate err = LDAP_NO_MEMORY; 176*7c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, err, NULL, NULL ); 177*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( dn ); 178*7c478bd9Sstevel@tonic-gate return( err ); 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate freebuf = 1; 181*7c478bd9Sstevel@tonic-gate } else { 182*7c478bd9Sstevel@tonic-gate freebuf = 0; 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate html = ( urlprefix != NULL ); 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate if ( html ) { 188*7c478bd9Sstevel@tonic-gate /* 189*7c478bd9Sstevel@tonic-gate * add HTML intro. and title 190*7c478bd9Sstevel@tonic-gate */ 191*7c478bd9Sstevel@tonic-gate if (!(( opts & LDAP_DISP_OPT_HTMLBODYONLY ) != 0 )) { 192*7c478bd9Sstevel@tonic-gate sprintf( buf, "<HTML>%s<HEAD>%s<TITLE>%s%s - ", eol, eol, eol, 193*7c478bd9Sstevel@tonic-gate ( tmpl == NULL ) ? "Entry" : tmpl->dt_name ); 194*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 195*7c478bd9Sstevel@tonic-gate output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL ); 196*7c478bd9Sstevel@tonic-gate sprintf( buf, "%s</TITLE>%s</HEAD>%s<BODY>%s<H3>%s - ", eol, eol, 197*7c478bd9Sstevel@tonic-gate eol, eol, ( tmpl == NULL ) ? "Entry" : tmpl->dt_name ); 198*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 199*7c478bd9Sstevel@tonic-gate output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL ); 200*7c478bd9Sstevel@tonic-gate sprintf( buf, "</H3>%s", eol ); 201*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 202*7c478bd9Sstevel@tonic-gate } 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate if (( opts & LDAP_DISP_OPT_NONLEAF ) != 0 && 205*7c478bd9Sstevel@tonic-gate ( vals = ldap_explode_dn( dn, 0 )) != NULL ) { 206*7c478bd9Sstevel@tonic-gate char *untagged; 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate /* 209*7c478bd9Sstevel@tonic-gate * add "Move Up" link 210*7c478bd9Sstevel@tonic-gate */ 211*7c478bd9Sstevel@tonic-gate sprintf( buf, "<A HREF=\"%s", urlprefix ); 212*7c478bd9Sstevel@tonic-gate for ( i = 1; vals[ i ] != NULL; ++i ) { 213*7c478bd9Sstevel@tonic-gate if ( i > 1 ) { 214*7c478bd9Sstevel@tonic-gate strcat_escaped( buf, ", " ); 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate strcat_escaped( buf, vals[ i ] ); 217*7c478bd9Sstevel@tonic-gate } 218*7c478bd9Sstevel@tonic-gate if ( vals[ 1 ] != NULL ) { 219*7c478bd9Sstevel@tonic-gate untagged = strchr( vals[ 1 ], '=' ); 220*7c478bd9Sstevel@tonic-gate } else { 221*7c478bd9Sstevel@tonic-gate untagged = "=The World"; 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate sprintf( buf + strlen( buf ), 224*7c478bd9Sstevel@tonic-gate "%s\">Move Up To <EM>%s</EM></A>%s<BR>", 225*7c478bd9Sstevel@tonic-gate ( vals[ 1 ] == NULL ) ? "??one" : "", 226*7c478bd9Sstevel@tonic-gate ( untagged != NULL ) ? untagged + 1 : vals[ 1 ], eol ); 227*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate /* 230*7c478bd9Sstevel@tonic-gate * add "Browse" link 231*7c478bd9Sstevel@tonic-gate */ 232*7c478bd9Sstevel@tonic-gate untagged = strchr( vals[ 0 ], '=' ); 233*7c478bd9Sstevel@tonic-gate sprintf( buf, "<A HREF=\"%s", urlprefix ); 234*7c478bd9Sstevel@tonic-gate strcat_escaped( buf, dn ); 235*7c478bd9Sstevel@tonic-gate sprintf( buf + strlen( buf ), "??one?(!(objectClass=dsa))\">Browse Below <EM>%s</EM></A>%s%s", 236*7c478bd9Sstevel@tonic-gate ( untagged != NULL ) ? untagged + 1 : vals[ 0 ], eol, eol ); 237*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate ldap_value_free( vals ); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, "<HR>", 4 ); /* horizontal rule */ 243*7c478bd9Sstevel@tonic-gate } else { 244*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, "\"", 1 ); 245*7c478bd9Sstevel@tonic-gate output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL ); 246*7c478bd9Sstevel@tonic-gate sprintf( buf, "\"%s", eol ); 247*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate if ( tmpl != NULL && ( opts & LDAP_DISP_OPT_AUTOLABELWIDTH ) != 0 ) { 251*7c478bd9Sstevel@tonic-gate labelwidth = max_label_len( tmpl ) + 3; 252*7c478bd9Sstevel@tonic-gate } else { 253*7c478bd9Sstevel@tonic-gate labelwidth = DEF_LABEL_WIDTH;; 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate err = LDAP_SUCCESS; 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate if ( tmpl == NULL ) { 259*7c478bd9Sstevel@tonic-gate BerElement *ber; 260*7c478bd9Sstevel@tonic-gate char *attr; 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate ber = NULL; 263*7c478bd9Sstevel@tonic-gate for ( attr = ldap_first_attribute( ld, entry, &ber ); 264*7c478bd9Sstevel@tonic-gate NONFATAL_LDAP_ERR( err ) && attr != NULL; 265*7c478bd9Sstevel@tonic-gate attr = ldap_next_attribute( ld, entry, ber )) { 266*7c478bd9Sstevel@tonic-gate if (( vals = ldap_get_values( ld, entry, attr )) == NULL ) { 267*7c478bd9Sstevel@tonic-gate freevals = 0; 268*7c478bd9Sstevel@tonic-gate if ( defattrs != NULL ) { 269*7c478bd9Sstevel@tonic-gate for ( i = 0; defattrs[ i ] != NULL; ++i ) { 270*7c478bd9Sstevel@tonic-gate if ( strcasecmp( attr, defattrs[ i ] ) == 0 ) { 271*7c478bd9Sstevel@tonic-gate break; 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate if ( defattrs[ i ] != NULL ) { 275*7c478bd9Sstevel@tonic-gate vals = defvals[ i ]; 276*7c478bd9Sstevel@tonic-gate } 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate } else { 279*7c478bd9Sstevel@tonic-gate freevals = 1; 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate if ( islower( *attr )) { /* cosmetic -- upcase attr. name */ 283*7c478bd9Sstevel@tonic-gate *attr = toupper( *attr ); 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate err = do_vals2text( ld, buf, vals, attr, labelwidth, 287*7c478bd9Sstevel@tonic-gate LDAP_SYN_CASEIGNORESTR, writeproc, writeparm, eol, 288*7c478bd9Sstevel@tonic-gate rdncount, urlprefix ); 289*7c478bd9Sstevel@tonic-gate if ( freevals ) { 290*7c478bd9Sstevel@tonic-gate ldap_value_free( vals ); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate if ( ber == NULL ) { 294*7c478bd9Sstevel@tonic-gate ber_free( ber, 0 ); 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate /* 297*7c478bd9Sstevel@tonic-gate * XXX check for errors in ldap_first_attribute/ldap_next_attribute 298*7c478bd9Sstevel@tonic-gate * here (but what should we do if there was one?) 299*7c478bd9Sstevel@tonic-gate */ 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate } else { 302*7c478bd9Sstevel@tonic-gate for ( rowp = ldap_first_tmplrow( tmpl ); 303*7c478bd9Sstevel@tonic-gate NONFATAL_LDAP_ERR( err ) && rowp != NULLTMPLITEM; 304*7c478bd9Sstevel@tonic-gate rowp = ldap_next_tmplrow( tmpl, rowp )) { 305*7c478bd9Sstevel@tonic-gate for ( colp = ldap_first_tmplcol( tmpl, rowp ); colp != NULLTMPLITEM; 306*7c478bd9Sstevel@tonic-gate colp = ldap_next_tmplcol( tmpl, rowp, colp )) { 307*7c478bd9Sstevel@tonic-gate vals = NULL; 308*7c478bd9Sstevel@tonic-gate if ( colp->ti_attrname == NULL || ( vals = ldap_get_values( ld, 309*7c478bd9Sstevel@tonic-gate entry, colp->ti_attrname )) == NULL ) { 310*7c478bd9Sstevel@tonic-gate freevals = 0; 311*7c478bd9Sstevel@tonic-gate if ( !LDAP_IS_TMPLITEM_OPTION_SET( colp, 312*7c478bd9Sstevel@tonic-gate LDAP_DITEM_OPT_HIDEIFEMPTY ) && defattrs != NULL 313*7c478bd9Sstevel@tonic-gate && colp->ti_attrname != NULL ) { 314*7c478bd9Sstevel@tonic-gate for ( i = 0; defattrs[ i ] != NULL; ++i ) { 315*7c478bd9Sstevel@tonic-gate if ( strcasecmp( colp->ti_attrname, defattrs[ i ] ) 316*7c478bd9Sstevel@tonic-gate == 0 ) { 317*7c478bd9Sstevel@tonic-gate break; 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate if ( defattrs[ i ] != NULL ) { 321*7c478bd9Sstevel@tonic-gate vals = defvals[ i ]; 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate } else { 325*7c478bd9Sstevel@tonic-gate freevals = 1; 326*7c478bd9Sstevel@tonic-gate if ( LDAP_IS_TMPLITEM_OPTION_SET( colp, 327*7c478bd9Sstevel@tonic-gate LDAP_DITEM_OPT_SORTVALUES ) && vals[ 0 ] != NULL 328*7c478bd9Sstevel@tonic-gate && vals[ 1 ] != NULL ) { 329*7c478bd9Sstevel@tonic-gate ldap_sort_values(ld, vals, ldap_sort_strcasecmp); 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate /* 334*7c478bd9Sstevel@tonic-gate * don't bother even calling do_vals2text() if no values 335*7c478bd9Sstevel@tonic-gate * or boolean with value false and "hide if false" option set 336*7c478bd9Sstevel@tonic-gate */ 337*7c478bd9Sstevel@tonic-gate show = ( vals != NULL && vals[ 0 ] != NULL ); 338*7c478bd9Sstevel@tonic-gate if ( show && LDAP_GET_SYN_TYPE( colp->ti_syntaxid ) 339*7c478bd9Sstevel@tonic-gate == LDAP_SYN_TYPE_BOOLEAN && LDAP_IS_TMPLITEM_OPTION_SET( 340*7c478bd9Sstevel@tonic-gate colp, LDAP_DITEM_OPT_HIDEIFFALSE ) && 341*7c478bd9Sstevel@tonic-gate toupper( vals[ 0 ][ 0 ] ) != 'T' ) { 342*7c478bd9Sstevel@tonic-gate show = 0; 343*7c478bd9Sstevel@tonic-gate } 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate if ( colp->ti_syntaxid == LDAP_SYN_SEARCHACTION ) { 346*7c478bd9Sstevel@tonic-gate if (( opts & LDAP_DISP_OPT_DOSEARCHACTIONS ) != 0 ) { 347*7c478bd9Sstevel@tonic-gate if ( colp->ti_attrname == NULL || ( show && 348*7c478bd9Sstevel@tonic-gate toupper( vals[ 0 ][ 0 ] ) == 'T' )) { 349*7c478bd9Sstevel@tonic-gate err = searchaction( ld, buf, base, entry, dn, colp, 350*7c478bd9Sstevel@tonic-gate labelwidth, rdncount, writeproc, 351*7c478bd9Sstevel@tonic-gate writeparm, eol, urlprefix ); 352*7c478bd9Sstevel@tonic-gate } 353*7c478bd9Sstevel@tonic-gate } 354*7c478bd9Sstevel@tonic-gate show = 0; 355*7c478bd9Sstevel@tonic-gate } 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate if ( show ) { 358*7c478bd9Sstevel@tonic-gate err = do_vals2text( ld, buf, vals, colp->ti_label, 359*7c478bd9Sstevel@tonic-gate labelwidth, colp->ti_syntaxid, writeproc, writeparm, 360*7c478bd9Sstevel@tonic-gate eol, rdncount, urlprefix ); 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate if ( freevals ) { 364*7c478bd9Sstevel@tonic-gate ldap_value_free( vals ); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate if ( html && !(( opts & LDAP_DISP_OPT_HTMLBODYONLY ) != 0 )) { 371*7c478bd9Sstevel@tonic-gate sprintf( buf, "</BODY>%s</HTML>%s", eol, eol ); 372*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( dn ); 376*7c478bd9Sstevel@tonic-gate if ( freebuf ) { 377*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( buf ); 378*7c478bd9Sstevel@tonic-gate } 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate return( err ); 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate int 385*7c478bd9Sstevel@tonic-gate LDAP_CALL 386*7c478bd9Sstevel@tonic-gate ldap_entry2text_search( 387*7c478bd9Sstevel@tonic-gate LDAP *ld, 388*7c478bd9Sstevel@tonic-gate char *dn, /* if NULL, use entry */ 389*7c478bd9Sstevel@tonic-gate char *base, /* if NULL, no search actions */ 390*7c478bd9Sstevel@tonic-gate LDAPMessage *entry, /* if NULL, use dn */ 391*7c478bd9Sstevel@tonic-gate struct ldap_disptmpl* tmpllist, /* if NULL, load default file */ 392*7c478bd9Sstevel@tonic-gate char **defattrs, 393*7c478bd9Sstevel@tonic-gate char ***defvals, 394*7c478bd9Sstevel@tonic-gate writeptype writeproc, 395*7c478bd9Sstevel@tonic-gate void *writeparm, 396*7c478bd9Sstevel@tonic-gate char *eol, 397*7c478bd9Sstevel@tonic-gate int rdncount, /* if 0, display full DN */ 398*7c478bd9Sstevel@tonic-gate unsigned long opts 399*7c478bd9Sstevel@tonic-gate ) 400*7c478bd9Sstevel@tonic-gate { 401*7c478bd9Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_entry2text_search\n", 0, 0, 0 ); 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate return( do_entry2text_search( ld, dn, base, entry, tmpllist, defattrs, 404*7c478bd9Sstevel@tonic-gate defvals, writeproc, writeparm, eol, rdncount, opts, NULL )); 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate int 410*7c478bd9Sstevel@tonic-gate LDAP_CALL 411*7c478bd9Sstevel@tonic-gate ldap_entry2html_search( 412*7c478bd9Sstevel@tonic-gate LDAP *ld, 413*7c478bd9Sstevel@tonic-gate char *dn, /* if NULL, use entry */ 414*7c478bd9Sstevel@tonic-gate char *base, /* if NULL, no search actions */ 415*7c478bd9Sstevel@tonic-gate LDAPMessage *entry, /* if NULL, use dn */ 416*7c478bd9Sstevel@tonic-gate struct ldap_disptmpl* tmpllist, /* if NULL, load default file */ 417*7c478bd9Sstevel@tonic-gate char **defattrs, 418*7c478bd9Sstevel@tonic-gate char ***defvals, 419*7c478bd9Sstevel@tonic-gate writeptype writeproc, 420*7c478bd9Sstevel@tonic-gate void *writeparm, 421*7c478bd9Sstevel@tonic-gate char *eol, 422*7c478bd9Sstevel@tonic-gate int rdncount, /* if 0, display full DN */ 423*7c478bd9Sstevel@tonic-gate unsigned long opts, 424*7c478bd9Sstevel@tonic-gate char *urlprefix 425*7c478bd9Sstevel@tonic-gate ) 426*7c478bd9Sstevel@tonic-gate { 427*7c478bd9Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_entry2html_search\n", 0, 0, 0 ); 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate return( do_entry2text_search( ld, dn, base, entry, tmpllist, defattrs, 430*7c478bd9Sstevel@tonic-gate defvals, writeproc, writeparm, eol, rdncount, opts, urlprefix )); 431*7c478bd9Sstevel@tonic-gate } 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate 434*7c478bd9Sstevel@tonic-gate static int 435*7c478bd9Sstevel@tonic-gate do_entry2text_search( 436*7c478bd9Sstevel@tonic-gate LDAP *ld, 437*7c478bd9Sstevel@tonic-gate char *dn, /* if NULL, use entry */ 438*7c478bd9Sstevel@tonic-gate char *base, /* if NULL, no search actions */ 439*7c478bd9Sstevel@tonic-gate LDAPMessage *entry, /* if NULL, use dn */ 440*7c478bd9Sstevel@tonic-gate struct ldap_disptmpl* tmpllist, /* if NULL, no template used */ 441*7c478bd9Sstevel@tonic-gate char **defattrs, 442*7c478bd9Sstevel@tonic-gate char ***defvals, 443*7c478bd9Sstevel@tonic-gate writeptype writeproc, 444*7c478bd9Sstevel@tonic-gate void *writeparm, 445*7c478bd9Sstevel@tonic-gate char *eol, 446*7c478bd9Sstevel@tonic-gate int rdncount, /* if 0, display full DN */ 447*7c478bd9Sstevel@tonic-gate unsigned long opts, 448*7c478bd9Sstevel@tonic-gate char *urlprefix 449*7c478bd9Sstevel@tonic-gate ) 450*7c478bd9Sstevel@tonic-gate { 451*7c478bd9Sstevel@tonic-gate int err, freedn, html; 452*7c478bd9Sstevel@tonic-gate char *buf, **fetchattrs, **vals; 453*7c478bd9Sstevel@tonic-gate LDAPMessage *ldmp; 454*7c478bd9Sstevel@tonic-gate struct ldap_disptmpl *tmpl; 455*7c478bd9Sstevel@tonic-gate struct timeval timeout; 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { 458*7c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate if ( dn == NULL && entry == NULLMSG ) { 462*7c478bd9Sstevel@tonic-gate err = LDAP_PARAM_ERROR; 463*7c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, err, NULL, NULL ); 464*7c478bd9Sstevel@tonic-gate return( err ); 465*7c478bd9Sstevel@tonic-gate } 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate html = ( urlprefix != NULL ); 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate timeout.tv_sec = SEARCH_TIMEOUT_SECS; 470*7c478bd9Sstevel@tonic-gate timeout.tv_usec = 0; 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate if (( buf = NSLDAPI_MALLOC( LDAP_DTMPL_BUFSIZ )) == NULL ) { 473*7c478bd9Sstevel@tonic-gate err = LDAP_NO_MEMORY; 474*7c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, err, NULL, NULL ); 475*7c478bd9Sstevel@tonic-gate return( err ); 476*7c478bd9Sstevel@tonic-gate } 477*7c478bd9Sstevel@tonic-gate 478*7c478bd9Sstevel@tonic-gate freedn = 0; 479*7c478bd9Sstevel@tonic-gate tmpl = NULL; 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate if ( dn == NULL ) { 482*7c478bd9Sstevel@tonic-gate if (( dn = ldap_get_dn( ld, entry )) == NULL ) { 483*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( buf ); 484*7c478bd9Sstevel@tonic-gate return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); 485*7c478bd9Sstevel@tonic-gate } 486*7c478bd9Sstevel@tonic-gate freedn = 1; 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate if ( tmpllist != NULL ) { 491*7c478bd9Sstevel@tonic-gate ldmp = NULLMSG; 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate if ( entry == NULL ) { 494*7c478bd9Sstevel@tonic-gate char *ocattrs[2]; 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate ocattrs[0] = OCATTRNAME; 497*7c478bd9Sstevel@tonic-gate ocattrs[1] = NULL; 498*7c478bd9Sstevel@tonic-gate #ifdef CLDAP 499*7c478bd9Sstevel@tonic-gate if ( LDAP_IS_CLDAP( ld )) 500*7c478bd9Sstevel@tonic-gate err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, 501*7c478bd9Sstevel@tonic-gate "objectClass=*", ocattrs, 0, &ldmp, NULL ); 502*7c478bd9Sstevel@tonic-gate else 503*7c478bd9Sstevel@tonic-gate #endif /* CLDAP */ 504*7c478bd9Sstevel@tonic-gate err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, 505*7c478bd9Sstevel@tonic-gate "objectClass=*", ocattrs, 0, &timeout, &ldmp ); 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate if ( err == LDAP_SUCCESS ) { 508*7c478bd9Sstevel@tonic-gate entry = ldap_first_entry( ld, ldmp ); 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate } 511*7c478bd9Sstevel@tonic-gate 512*7c478bd9Sstevel@tonic-gate if ( entry != NULL ) { 513*7c478bd9Sstevel@tonic-gate vals = ldap_get_values( ld, entry, OCATTRNAME ); 514*7c478bd9Sstevel@tonic-gate tmpl = ldap_oc2template( vals, tmpllist ); 515*7c478bd9Sstevel@tonic-gate if ( vals != NULL ) { 516*7c478bd9Sstevel@tonic-gate ldap_value_free( vals ); 517*7c478bd9Sstevel@tonic-gate } 518*7c478bd9Sstevel@tonic-gate } 519*7c478bd9Sstevel@tonic-gate if ( ldmp != NULL ) { 520*7c478bd9Sstevel@tonic-gate ldap_msgfree( ldmp ); 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate } 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate entry = NULL; 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate if ( tmpl == NULL ) { 527*7c478bd9Sstevel@tonic-gate fetchattrs = NULL; 528*7c478bd9Sstevel@tonic-gate } else { 529*7c478bd9Sstevel@tonic-gate fetchattrs = ldap_tmplattrs( tmpl, NULL, 1, LDAP_SYN_OPT_DEFER ); 530*7c478bd9Sstevel@tonic-gate } 531*7c478bd9Sstevel@tonic-gate 532*7c478bd9Sstevel@tonic-gate #ifdef CLDAP 533*7c478bd9Sstevel@tonic-gate if ( LDAP_IS_CLDAP( ld )) 534*7c478bd9Sstevel@tonic-gate err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectClass=*", 535*7c478bd9Sstevel@tonic-gate fetchattrs, 0, &ldmp, NULL ); 536*7c478bd9Sstevel@tonic-gate else 537*7c478bd9Sstevel@tonic-gate #endif /* CLDAP */ 538*7c478bd9Sstevel@tonic-gate err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*", 539*7c478bd9Sstevel@tonic-gate fetchattrs, 0, &timeout, &ldmp ); 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate if ( freedn ) { 542*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( dn ); 543*7c478bd9Sstevel@tonic-gate } 544*7c478bd9Sstevel@tonic-gate if ( fetchattrs != NULL ) { 545*7c478bd9Sstevel@tonic-gate ldap_value_free( fetchattrs ); 546*7c478bd9Sstevel@tonic-gate } 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate if ( err != LDAP_SUCCESS || 549*7c478bd9Sstevel@tonic-gate ( entry = ldap_first_entry( ld, ldmp )) == NULL ) { 550*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( buf ); 551*7c478bd9Sstevel@tonic-gate return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate err = do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals, 555*7c478bd9Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, opts, urlprefix ); 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( buf ); 558*7c478bd9Sstevel@tonic-gate ldap_msgfree( ldmp ); 559*7c478bd9Sstevel@tonic-gate return( err ); 560*7c478bd9Sstevel@tonic-gate } 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate int 564*7c478bd9Sstevel@tonic-gate LDAP_CALL 565*7c478bd9Sstevel@tonic-gate ldap_vals2text( 566*7c478bd9Sstevel@tonic-gate LDAP *ld, 567*7c478bd9Sstevel@tonic-gate char *buf, /* NULL for "use internal" */ 568*7c478bd9Sstevel@tonic-gate char **vals, 569*7c478bd9Sstevel@tonic-gate char *label, 570*7c478bd9Sstevel@tonic-gate int labelwidth, /* 0 means use default */ 571*7c478bd9Sstevel@tonic-gate unsigned long syntaxid, 572*7c478bd9Sstevel@tonic-gate writeptype writeproc, 573*7c478bd9Sstevel@tonic-gate void *writeparm, 574*7c478bd9Sstevel@tonic-gate char *eol, 575*7c478bd9Sstevel@tonic-gate int rdncount 576*7c478bd9Sstevel@tonic-gate ) 577*7c478bd9Sstevel@tonic-gate { 578*7c478bd9Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_vals2text\n", 0, 0, 0 ); 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate return( do_vals2text( ld, buf, vals, label, labelwidth, syntaxid, 581*7c478bd9Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, NULL )); 582*7c478bd9Sstevel@tonic-gate } 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate int 586*7c478bd9Sstevel@tonic-gate LDAP_CALL 587*7c478bd9Sstevel@tonic-gate ldap_vals2html( 588*7c478bd9Sstevel@tonic-gate LDAP *ld, 589*7c478bd9Sstevel@tonic-gate char *buf, /* NULL for "use internal" */ 590*7c478bd9Sstevel@tonic-gate char **vals, 591*7c478bd9Sstevel@tonic-gate char *label, 592*7c478bd9Sstevel@tonic-gate int labelwidth, /* 0 means use default */ 593*7c478bd9Sstevel@tonic-gate unsigned long syntaxid, 594*7c478bd9Sstevel@tonic-gate writeptype writeproc, 595*7c478bd9Sstevel@tonic-gate void *writeparm, 596*7c478bd9Sstevel@tonic-gate char *eol, 597*7c478bd9Sstevel@tonic-gate int rdncount, 598*7c478bd9Sstevel@tonic-gate char *urlprefix 599*7c478bd9Sstevel@tonic-gate ) 600*7c478bd9Sstevel@tonic-gate { 601*7c478bd9Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_vals2html\n", 0, 0, 0 ); 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate if ( urlprefix == NULL ) { 604*7c478bd9Sstevel@tonic-gate urlprefix = DEF_LDAP_URL_PREFIX; 605*7c478bd9Sstevel@tonic-gate } 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate return( do_vals2text( ld, buf, vals, label, labelwidth, syntaxid, 608*7c478bd9Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, urlprefix )); 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate static int 613*7c478bd9Sstevel@tonic-gate do_vals2text( 614*7c478bd9Sstevel@tonic-gate LDAP *ld, 615*7c478bd9Sstevel@tonic-gate char *buf, /* NULL for "use internal" */ 616*7c478bd9Sstevel@tonic-gate char **vals, 617*7c478bd9Sstevel@tonic-gate char *label, 618*7c478bd9Sstevel@tonic-gate int labelwidth, /* 0 means use default */ 619*7c478bd9Sstevel@tonic-gate unsigned long syntaxid, 620*7c478bd9Sstevel@tonic-gate writeptype writeproc, 621*7c478bd9Sstevel@tonic-gate void *writeparm, 622*7c478bd9Sstevel@tonic-gate char *eol, 623*7c478bd9Sstevel@tonic-gate int rdncount, 624*7c478bd9Sstevel@tonic-gate char *urlprefix 625*7c478bd9Sstevel@tonic-gate ) 626*7c478bd9Sstevel@tonic-gate { 627*7c478bd9Sstevel@tonic-gate int err, i, html, writeoutval, freebuf, notascii; 628*7c478bd9Sstevel@tonic-gate char *p, *s, *outval; 629*7c478bd9Sstevel@tonic-gate 630*7c478bd9Sstevel@tonic-gate if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || writeproc == NULL ) { 631*7c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 632*7c478bd9Sstevel@tonic-gate } 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate if ( vals == NULL ) { 635*7c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 636*7c478bd9Sstevel@tonic-gate } 637*7c478bd9Sstevel@tonic-gate 638*7c478bd9Sstevel@tonic-gate html = ( urlprefix != NULL ); 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate switch( LDAP_GET_SYN_TYPE( syntaxid )) { 641*7c478bd9Sstevel@tonic-gate case LDAP_SYN_TYPE_TEXT: 642*7c478bd9Sstevel@tonic-gate case LDAP_SYN_TYPE_BOOLEAN: 643*7c478bd9Sstevel@tonic-gate break; /* we only bother with these two types... */ 644*7c478bd9Sstevel@tonic-gate default: 645*7c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate if ( labelwidth == 0 || labelwidth < 0 ) { 649*7c478bd9Sstevel@tonic-gate labelwidth = DEF_LABEL_WIDTH; 650*7c478bd9Sstevel@tonic-gate } 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate if ( buf == NULL ) { 653*7c478bd9Sstevel@tonic-gate if (( buf = NSLDAPI_MALLOC( LDAP_DTMPL_BUFSIZ )) == NULL ) { 654*7c478bd9Sstevel@tonic-gate err = LDAP_NO_MEMORY; 655*7c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, err, NULL, NULL ); 656*7c478bd9Sstevel@tonic-gate return( err ); 657*7c478bd9Sstevel@tonic-gate } 658*7c478bd9Sstevel@tonic-gate freebuf = 1; 659*7c478bd9Sstevel@tonic-gate } else { 660*7c478bd9Sstevel@tonic-gate freebuf = 0; 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate output_label( buf, label, labelwidth, writeproc, writeparm, eol, html ); 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate for ( i = 0; vals[ i ] != NULL; ++i ) { 666*7c478bd9Sstevel@tonic-gate for ( p = vals[ i ]; *p != '\0'; ++p ) { 667*7c478bd9Sstevel@tonic-gate if ( !isascii( *p )) { 668*7c478bd9Sstevel@tonic-gate break; 669*7c478bd9Sstevel@tonic-gate } 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate notascii = ( *p != '\0' ); 672*7c478bd9Sstevel@tonic-gate outval = notascii ? dgettext(TEXT_DOMAIN, 673*7c478bd9Sstevel@tonic-gate "(unable to display non-ASCII text value)") 674*7c478bd9Sstevel@tonic-gate : vals[ i ]; 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate writeoutval = 0; /* if non-zero, write outval after switch */ 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate switch( syntaxid ) { 679*7c478bd9Sstevel@tonic-gate case LDAP_SYN_CASEIGNORESTR: 680*7c478bd9Sstevel@tonic-gate ++writeoutval; 681*7c478bd9Sstevel@tonic-gate break; 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate case LDAP_SYN_RFC822ADDR: 684*7c478bd9Sstevel@tonic-gate if ( html ) { 685*7c478bd9Sstevel@tonic-gate strcpy( buf, "<DD><A HREF=\"mailto:" ); 686*7c478bd9Sstevel@tonic-gate strcat_escaped( buf, outval ); 687*7c478bd9Sstevel@tonic-gate sprintf( buf + strlen( buf ), "\">%s</A><BR>%s", outval, eol ); 688*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 689*7c478bd9Sstevel@tonic-gate } else { 690*7c478bd9Sstevel@tonic-gate ++writeoutval; 691*7c478bd9Sstevel@tonic-gate } 692*7c478bd9Sstevel@tonic-gate break; 693*7c478bd9Sstevel@tonic-gate 694*7c478bd9Sstevel@tonic-gate case LDAP_SYN_DN: /* for now */ 695*7c478bd9Sstevel@tonic-gate output_dn( buf, outval, labelwidth, rdncount, writeproc, 696*7c478bd9Sstevel@tonic-gate writeparm, eol, urlprefix ); 697*7c478bd9Sstevel@tonic-gate break; 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate case LDAP_SYN_MULTILINESTR: 700*7c478bd9Sstevel@tonic-gate if ( i > 0 && !html ) { 701*7c478bd9Sstevel@tonic-gate output_label( buf, label, labelwidth, writeproc, 702*7c478bd9Sstevel@tonic-gate writeparm, eol, html ); 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate p = s = outval; 706*7c478bd9Sstevel@tonic-gate while (( s = strchr( s, '$' )) != NULL ) { 707*7c478bd9Sstevel@tonic-gate *s++ = '\0'; 708*7c478bd9Sstevel@tonic-gate while ( ldap_utf8isspace( s )) { 709*7c478bd9Sstevel@tonic-gate ++s; 710*7c478bd9Sstevel@tonic-gate } 711*7c478bd9Sstevel@tonic-gate if ( html ) { 712*7c478bd9Sstevel@tonic-gate sprintf( buf, "<DD>%s<BR>%s", p, eol ); 713*7c478bd9Sstevel@tonic-gate } else { 714*7c478bd9Sstevel@tonic-gate sprintf( buf, "%-*s%s%s", labelwidth, " ", p, eol ); 715*7c478bd9Sstevel@tonic-gate } 716*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 717*7c478bd9Sstevel@tonic-gate p = s; 718*7c478bd9Sstevel@tonic-gate } 719*7c478bd9Sstevel@tonic-gate outval = p; 720*7c478bd9Sstevel@tonic-gate ++writeoutval; 721*7c478bd9Sstevel@tonic-gate break; 722*7c478bd9Sstevel@tonic-gate 723*7c478bd9Sstevel@tonic-gate case LDAP_SYN_BOOLEAN: 724*7c478bd9Sstevel@tonic-gate outval = toupper( outval[ 0 ] ) == 'T' ? 725*7c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "TRUE") : dgettext(TEXT_DOMAIN, "FALSE"); 726*7c478bd9Sstevel@tonic-gate ++writeoutval; 727*7c478bd9Sstevel@tonic-gate break; 728*7c478bd9Sstevel@tonic-gate 729*7c478bd9Sstevel@tonic-gate case LDAP_SYN_TIME: 730*7c478bd9Sstevel@tonic-gate case LDAP_SYN_DATE: 731*7c478bd9Sstevel@tonic-gate outval = time2text( outval, syntaxid == LDAP_SYN_DATE ); 732*7c478bd9Sstevel@tonic-gate ++writeoutval; 733*7c478bd9Sstevel@tonic-gate break; 734*7c478bd9Sstevel@tonic-gate 735*7c478bd9Sstevel@tonic-gate case LDAP_SYN_LABELEDURL: 736*7c478bd9Sstevel@tonic-gate if ( !notascii && ( p = strchr( outval, '$' )) != NULL ) { 737*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 738*7c478bd9Sstevel@tonic-gate while ( ldap_utf8isspace( p )) { 739*7c478bd9Sstevel@tonic-gate ++p; 740*7c478bd9Sstevel@tonic-gate } 741*7c478bd9Sstevel@tonic-gate s = outval; 742*7c478bd9Sstevel@tonic-gate } else if ( !notascii && ( s = strchr( outval, ' ' )) != NULL ) { 743*7c478bd9Sstevel@tonic-gate *s++ = '\0'; 744*7c478bd9Sstevel@tonic-gate while ( ldap_utf8isspace( s )) { 745*7c478bd9Sstevel@tonic-gate ++s; 746*7c478bd9Sstevel@tonic-gate } 747*7c478bd9Sstevel@tonic-gate p = outval; 748*7c478bd9Sstevel@tonic-gate } else { 749*7c478bd9Sstevel@tonic-gate s = "URL"; 750*7c478bd9Sstevel@tonic-gate p = outval; 751*7c478bd9Sstevel@tonic-gate } 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate /* 754*7c478bd9Sstevel@tonic-gate * at this point `s' points to the label & `p' to the URL 755*7c478bd9Sstevel@tonic-gate */ 756*7c478bd9Sstevel@tonic-gate if ( html ) { 757*7c478bd9Sstevel@tonic-gate sprintf( buf, "<DD><A HREF=\"%s\">%s</A><BR>%s", p, s, eol ); 758*7c478bd9Sstevel@tonic-gate } else { 759*7c478bd9Sstevel@tonic-gate sprintf( buf, "%-*s%s%s%-*s%s%s", labelwidth, " ", 760*7c478bd9Sstevel@tonic-gate s, eol, labelwidth + 2, " ",p , eol ); 761*7c478bd9Sstevel@tonic-gate } 762*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 763*7c478bd9Sstevel@tonic-gate break; 764*7c478bd9Sstevel@tonic-gate 765*7c478bd9Sstevel@tonic-gate default: 766*7c478bd9Sstevel@tonic-gate sprintf( buf, dgettext(TEXT_DOMAIN, 767*7c478bd9Sstevel@tonic-gate " Can't display item type %ld%s"), 768*7c478bd9Sstevel@tonic-gate syntaxid, eol ); 769*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 770*7c478bd9Sstevel@tonic-gate } 771*7c478bd9Sstevel@tonic-gate 772*7c478bd9Sstevel@tonic-gate if ( writeoutval ) { 773*7c478bd9Sstevel@tonic-gate if ( html ) { 774*7c478bd9Sstevel@tonic-gate sprintf( buf, "<DD>%s<BR>%s", outval, eol ); 775*7c478bd9Sstevel@tonic-gate } else { 776*7c478bd9Sstevel@tonic-gate sprintf( buf, "%-*s%s%s", labelwidth, " ", outval, eol ); 777*7c478bd9Sstevel@tonic-gate } 778*7c478bd9Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate } 781*7c478bd9Sstevel@tonic-gate 782*7c478bd9Sstevel@tonic-gate if ( freebuf ) { 783*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( buf ); 784*7c478bd9Sstevel@tonic-gate } 785*7c478bd9Sstevel@tonic-gate 786*7c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate 790*7c478bd9Sstevel@tonic-gate static int 791*7c478bd9Sstevel@tonic-gate max_label_len( struct ldap_disptmpl *tmpl ) 792*7c478bd9Sstevel@tonic-gate { 793*7c478bd9Sstevel@tonic-gate struct ldap_tmplitem *rowp, *colp; 794*7c478bd9Sstevel@tonic-gate int len, maxlen; 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate maxlen = 0; 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate for ( rowp = ldap_first_tmplrow( tmpl ); rowp != NULLTMPLITEM; 799*7c478bd9Sstevel@tonic-gate rowp = ldap_next_tmplrow( tmpl, rowp )) { 800*7c478bd9Sstevel@tonic-gate for ( colp = ldap_first_tmplcol( tmpl, rowp ); colp != NULLTMPLITEM; 801*7c478bd9Sstevel@tonic-gate colp = ldap_next_tmplcol( tmpl, rowp, colp )) { 802*7c478bd9Sstevel@tonic-gate if (( len = strlen( colp->ti_label )) > maxlen ) { 803*7c478bd9Sstevel@tonic-gate maxlen = len; 804*7c478bd9Sstevel@tonic-gate } 805*7c478bd9Sstevel@tonic-gate } 806*7c478bd9Sstevel@tonic-gate } 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate return( maxlen ); 809*7c478bd9Sstevel@tonic-gate } 810*7c478bd9Sstevel@tonic-gate 811*7c478bd9Sstevel@tonic-gate 812*7c478bd9Sstevel@tonic-gate static int 813*7c478bd9Sstevel@tonic-gate output_label( char *buf, char *label, int width, writeptype writeproc, 814*7c478bd9Sstevel@tonic-gate void *writeparm, char *eol, int html ) 815*7c478bd9Sstevel@tonic-gate { 816*7c478bd9Sstevel@tonic-gate char *p; 817*7c478bd9Sstevel@tonic-gate 818*7c478bd9Sstevel@tonic-gate if ( html ) { 819*7c478bd9Sstevel@tonic-gate sprintf( buf, "<DT><B>%s</B>", label ); 820*7c478bd9Sstevel@tonic-gate } else { 821*7c478bd9Sstevel@tonic-gate auto size_t w; 822*7c478bd9Sstevel@tonic-gate sprintf( buf, " %s:", label ); 823*7c478bd9Sstevel@tonic-gate p = buf + strlen( buf ); 824*7c478bd9Sstevel@tonic-gate 825*7c478bd9Sstevel@tonic-gate for (w = ldap_utf8characters(buf); w < (size_t)width; ++w) { 826*7c478bd9Sstevel@tonic-gate *p++ = ' '; 827*7c478bd9Sstevel@tonic-gate } 828*7c478bd9Sstevel@tonic-gate 829*7c478bd9Sstevel@tonic-gate *p = '\0'; 830*7c478bd9Sstevel@tonic-gate strcat( buf, eol ); 831*7c478bd9Sstevel@tonic-gate } 832*7c478bd9Sstevel@tonic-gate 833*7c478bd9Sstevel@tonic-gate return ((*writeproc)( writeparm, buf, strlen( buf ))); 834*7c478bd9Sstevel@tonic-gate } 835*7c478bd9Sstevel@tonic-gate 836*7c478bd9Sstevel@tonic-gate 837*7c478bd9Sstevel@tonic-gate static int 838*7c478bd9Sstevel@tonic-gate output_dn( char *buf, char *dn, int width, int rdncount, 839*7c478bd9Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, char *urlprefix ) 840*7c478bd9Sstevel@tonic-gate { 841*7c478bd9Sstevel@tonic-gate char **dnrdns; 842*7c478bd9Sstevel@tonic-gate int i; 843*7c478bd9Sstevel@tonic-gate 844*7c478bd9Sstevel@tonic-gate if (( dnrdns = ldap_explode_dn( dn, 1 )) == NULL ) { 845*7c478bd9Sstevel@tonic-gate return( -1 ); 846*7c478bd9Sstevel@tonic-gate } 847*7c478bd9Sstevel@tonic-gate 848*7c478bd9Sstevel@tonic-gate if ( urlprefix != NULL ) { 849*7c478bd9Sstevel@tonic-gate sprintf( buf, "<DD><A HREF=\"%s", urlprefix ); 850*7c478bd9Sstevel@tonic-gate strcat_escaped( buf, dn ); 851*7c478bd9Sstevel@tonic-gate strcat( buf, "\">" ); 852*7c478bd9Sstevel@tonic-gate } else if ( width > 0 ) { 853*7c478bd9Sstevel@tonic-gate sprintf( buf, "%-*s", width, " " ); 854*7c478bd9Sstevel@tonic-gate } else { 855*7c478bd9Sstevel@tonic-gate *buf = '\0'; 856*7c478bd9Sstevel@tonic-gate } 857*7c478bd9Sstevel@tonic-gate 858*7c478bd9Sstevel@tonic-gate for ( i = 0; dnrdns[ i ] != NULL && ( rdncount == 0 || i < rdncount ); 859*7c478bd9Sstevel@tonic-gate ++i ) { 860*7c478bd9Sstevel@tonic-gate if ( i > 0 ) { 861*7c478bd9Sstevel@tonic-gate strcat( buf, ", " ); 862*7c478bd9Sstevel@tonic-gate } 863*7c478bd9Sstevel@tonic-gate strcat( buf, dnrdns[ i ] ); 864*7c478bd9Sstevel@tonic-gate } 865*7c478bd9Sstevel@tonic-gate 866*7c478bd9Sstevel@tonic-gate if ( urlprefix != NULL ) { 867*7c478bd9Sstevel@tonic-gate strcat( buf, "</A><BR>" ); 868*7c478bd9Sstevel@tonic-gate } 869*7c478bd9Sstevel@tonic-gate 870*7c478bd9Sstevel@tonic-gate ldap_value_free( dnrdns ); 871*7c478bd9Sstevel@tonic-gate 872*7c478bd9Sstevel@tonic-gate strcat( buf, eol ); 873*7c478bd9Sstevel@tonic-gate 874*7c478bd9Sstevel@tonic-gate return ((*writeproc)( writeparm, buf, strlen( buf ))); 875*7c478bd9Sstevel@tonic-gate } 876*7c478bd9Sstevel@tonic-gate 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate 879*7c478bd9Sstevel@tonic-gate #define HREF_CHAR_ACCEPTABLE( c ) (( c >= '-' && c <= '9' ) || \ 880*7c478bd9Sstevel@tonic-gate ( c >= '@' && c <= 'Z' ) || \ 881*7c478bd9Sstevel@tonic-gate ( c == '_' ) || \ 882*7c478bd9Sstevel@tonic-gate ( c >= 'a' && c <= 'z' )) 883*7c478bd9Sstevel@tonic-gate 884*7c478bd9Sstevel@tonic-gate static void 885*7c478bd9Sstevel@tonic-gate strcat_escaped( char *s1, char *s2 ) 886*7c478bd9Sstevel@tonic-gate { 887*7c478bd9Sstevel@tonic-gate char *p, *q; 888*7c478bd9Sstevel@tonic-gate char *hexdig = "0123456789ABCDEF"; 889*7c478bd9Sstevel@tonic-gate 890*7c478bd9Sstevel@tonic-gate p = s1 + strlen( s1 ); 891*7c478bd9Sstevel@tonic-gate for ( q = s2; *q != '\0'; ++q ) { 892*7c478bd9Sstevel@tonic-gate if ( HREF_CHAR_ACCEPTABLE( *q )) { 893*7c478bd9Sstevel@tonic-gate *p++ = *q; 894*7c478bd9Sstevel@tonic-gate } else { 895*7c478bd9Sstevel@tonic-gate *p++ = '%'; 896*7c478bd9Sstevel@tonic-gate *p++ = hexdig[ 0x0F & ((*(unsigned char*)q) >> 4) ]; 897*7c478bd9Sstevel@tonic-gate *p++ = hexdig[ 0x0F & *q ]; 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate } 900*7c478bd9Sstevel@tonic-gate 901*7c478bd9Sstevel@tonic-gate *p = '\0'; 902*7c478bd9Sstevel@tonic-gate } 903*7c478bd9Sstevel@tonic-gate 904*7c478bd9Sstevel@tonic-gate 905*7c478bd9Sstevel@tonic-gate #define GET2BYTENUM( p ) (( *p - '0' ) * 10 + ( *(p+1) - '0' )) 906*7c478bd9Sstevel@tonic-gate 907*7c478bd9Sstevel@tonic-gate static char * 908*7c478bd9Sstevel@tonic-gate time2text( char *ldtimestr, int dateonly ) 909*7c478bd9Sstevel@tonic-gate { 910*7c478bd9Sstevel@tonic-gate int len; 911*7c478bd9Sstevel@tonic-gate struct tm t; 912*7c478bd9Sstevel@tonic-gate char *p, *timestr, zone, *fmterr = 913*7c478bd9Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "badly formatted time"); 914*7c478bd9Sstevel@tonic-gate time_t gmttime; 915*7c478bd9Sstevel@tonic-gate /* CTIME for this platform doesn't use this. */ 916*7c478bd9Sstevel@tonic-gate #if !defined(SUNOS4) && !defined(BSDI) && !defined(LINUX1_2) && \ 917*7c478bd9Sstevel@tonic-gate !defined(SNI) && !defined(_WIN32) && !defined(macintosh) && !defined(LINUX) 918*7c478bd9Sstevel@tonic-gate char buf[26]; 919*7c478bd9Sstevel@tonic-gate #endif 920*7c478bd9Sstevel@tonic-gate 921*7c478bd9Sstevel@tonic-gate memset( (char *)&t, 0, sizeof( struct tm )); 922*7c478bd9Sstevel@tonic-gate if (( len = (int)strlen( ldtimestr )) < 13 ) { 923*7c478bd9Sstevel@tonic-gate return( fmterr ); 924*7c478bd9Sstevel@tonic-gate } 925*7c478bd9Sstevel@tonic-gate if ( len > 15 ) { /* throw away excess from 4-digit year time string */ 926*7c478bd9Sstevel@tonic-gate len = 15; 927*7c478bd9Sstevel@tonic-gate } else if ( len == 14 ) { 928*7c478bd9Sstevel@tonic-gate len = 13; /* assume we have a time w/2-digit year (len=13) */ 929*7c478bd9Sstevel@tonic-gate } 930*7c478bd9Sstevel@tonic-gate 931*7c478bd9Sstevel@tonic-gate for ( p = ldtimestr; p - ldtimestr + 1 < len; ++p ) { 932*7c478bd9Sstevel@tonic-gate if ( !isdigit( *p )) { 933*7c478bd9Sstevel@tonic-gate return( fmterr ); 934*7c478bd9Sstevel@tonic-gate } 935*7c478bd9Sstevel@tonic-gate } 936*7c478bd9Sstevel@tonic-gate 937*7c478bd9Sstevel@tonic-gate p = ldtimestr; 938*7c478bd9Sstevel@tonic-gate t.tm_year = GET2BYTENUM( p ); p += 2; 939*7c478bd9Sstevel@tonic-gate if ( len == 15 ) { 940*7c478bd9Sstevel@tonic-gate t.tm_year = 100 * (t.tm_year - 19); 941*7c478bd9Sstevel@tonic-gate t.tm_year += GET2BYTENUM( p ); p += 2; 942*7c478bd9Sstevel@tonic-gate } 943*7c478bd9Sstevel@tonic-gate else { 944*7c478bd9Sstevel@tonic-gate /* 2 digit years...assumed to be in the range (19)70 through 945*7c478bd9Sstevel@tonic-gate (20)69 ...less than 70 (for now, 38) means 20xx */ 946*7c478bd9Sstevel@tonic-gate if(t.tm_year < 70) { 947*7c478bd9Sstevel@tonic-gate t.tm_year += 100; 948*7c478bd9Sstevel@tonic-gate } 949*7c478bd9Sstevel@tonic-gate } 950*7c478bd9Sstevel@tonic-gate t.tm_mon = GET2BYTENUM( p ) - 1; p += 2; 951*7c478bd9Sstevel@tonic-gate t.tm_mday = GET2BYTENUM( p ); p += 2; 952*7c478bd9Sstevel@tonic-gate t.tm_hour = GET2BYTENUM( p ); p += 2; 953*7c478bd9Sstevel@tonic-gate t.tm_min = GET2BYTENUM( p ); p += 2; 954*7c478bd9Sstevel@tonic-gate t.tm_sec = GET2BYTENUM( p ); p += 2; 955*7c478bd9Sstevel@tonic-gate 956*7c478bd9Sstevel@tonic-gate if (( zone = *p ) == 'Z' ) { /* GMT */ 957*7c478bd9Sstevel@tonic-gate zone = '\0'; /* no need to indicate on screen, so we make it null */ 958*7c478bd9Sstevel@tonic-gate } 959*7c478bd9Sstevel@tonic-gate 960*7c478bd9Sstevel@tonic-gate gmttime = gtime( &t ); 961*7c478bd9Sstevel@tonic-gate timestr = NSLDAPI_CTIME( &gmttime, buf, sizeof(buf) ); 962*7c478bd9Sstevel@tonic-gate 963*7c478bd9Sstevel@tonic-gate timestr[ strlen( timestr ) - 1 ] = zone; /* replace trailing newline */ 964*7c478bd9Sstevel@tonic-gate if ( dateonly ) { 965*7c478bd9Sstevel@tonic-gate strcpy( timestr + 11, timestr + 20 ); 966*7c478bd9Sstevel@tonic-gate } 967*7c478bd9Sstevel@tonic-gate 968*7c478bd9Sstevel@tonic-gate return( timestr ); 969*7c478bd9Sstevel@tonic-gate } 970*7c478bd9Sstevel@tonic-gate 971*7c478bd9Sstevel@tonic-gate 972*7c478bd9Sstevel@tonic-gate 973*7c478bd9Sstevel@tonic-gate /* gtime.c - inverse gmtime */ 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate #if !defined( macintosh ) && !defined( _WINDOWS ) && !defined( DOS ) && !defined(XP_OS2) 976*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 977*7c478bd9Sstevel@tonic-gate #endif /* !macintosh */ 978*7c478bd9Sstevel@tonic-gate 979*7c478bd9Sstevel@tonic-gate /* gtime(): the inverse of localtime(). 980*7c478bd9Sstevel@tonic-gate This routine was supplied by Mike Accetta at CMU many years ago. 981*7c478bd9Sstevel@tonic-gate */ 982*7c478bd9Sstevel@tonic-gate 983*7c478bd9Sstevel@tonic-gate static int dmsize[] = { 984*7c478bd9Sstevel@tonic-gate 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 985*7c478bd9Sstevel@tonic-gate }; 986*7c478bd9Sstevel@tonic-gate 987*7c478bd9Sstevel@tonic-gate #define dysize(y) \ 988*7c478bd9Sstevel@tonic-gate (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366))) 989*7c478bd9Sstevel@tonic-gate 990*7c478bd9Sstevel@tonic-gate /* 991*7c478bd9Sstevel@tonic-gate #define YEAR(y) ((y) >= 100 ? (y) : (y) + 1900) 992*7c478bd9Sstevel@tonic-gate */ 993*7c478bd9Sstevel@tonic-gate #define YEAR(y) (((y) < 1900) ? ((y) + 1900) : (y)) 994*7c478bd9Sstevel@tonic-gate 995*7c478bd9Sstevel@tonic-gate /* */ 996*7c478bd9Sstevel@tonic-gate 997*7c478bd9Sstevel@tonic-gate static long gtime ( struct tm *tm ) 998*7c478bd9Sstevel@tonic-gate { 999*7c478bd9Sstevel@tonic-gate register int i, 1000*7c478bd9Sstevel@tonic-gate sec, 1001*7c478bd9Sstevel@tonic-gate mins, 1002*7c478bd9Sstevel@tonic-gate hour, 1003*7c478bd9Sstevel@tonic-gate mday, 1004*7c478bd9Sstevel@tonic-gate mon, 1005*7c478bd9Sstevel@tonic-gate year; 1006*7c478bd9Sstevel@tonic-gate register long result; 1007*7c478bd9Sstevel@tonic-gate 1008*7c478bd9Sstevel@tonic-gate if ((sec = tm -> tm_sec) < 0 || sec > 59 1009*7c478bd9Sstevel@tonic-gate || (mins = tm -> tm_min) < 0 || mins > 59 1010*7c478bd9Sstevel@tonic-gate || (hour = tm -> tm_hour) < 0 || hour > 24 1011*7c478bd9Sstevel@tonic-gate || (mday = tm -> tm_mday) < 1 || mday > 31 1012*7c478bd9Sstevel@tonic-gate || (mon = tm -> tm_mon + 1) < 1 || mon > 12) 1013*7c478bd9Sstevel@tonic-gate return ((long) -1); 1014*7c478bd9Sstevel@tonic-gate if (hour == 24) { 1015*7c478bd9Sstevel@tonic-gate hour = 0; 1016*7c478bd9Sstevel@tonic-gate mday++; 1017*7c478bd9Sstevel@tonic-gate } 1018*7c478bd9Sstevel@tonic-gate year = YEAR (tm -> tm_year); 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate result = 0L; 1021*7c478bd9Sstevel@tonic-gate for (i = 1970; i < year; i++) 1022*7c478bd9Sstevel@tonic-gate result += dysize (i); 1023*7c478bd9Sstevel@tonic-gate if (dysize (year) == 366 && mon >= 3) 1024*7c478bd9Sstevel@tonic-gate result++; 1025*7c478bd9Sstevel@tonic-gate while (--mon) 1026*7c478bd9Sstevel@tonic-gate result += dmsize[mon - 1]; 1027*7c478bd9Sstevel@tonic-gate result += mday - 1; 1028*7c478bd9Sstevel@tonic-gate result = 24 * result + hour; 1029*7c478bd9Sstevel@tonic-gate result = 60 * result + mins; 1030*7c478bd9Sstevel@tonic-gate result = 60 * result + sec; 1031*7c478bd9Sstevel@tonic-gate 1032*7c478bd9Sstevel@tonic-gate return result; 1033*7c478bd9Sstevel@tonic-gate } 1034*7c478bd9Sstevel@tonic-gate 1035*7c478bd9Sstevel@tonic-gate static int 1036*7c478bd9Sstevel@tonic-gate searchaction( LDAP *ld, char *buf, char *base, LDAPMessage *entry, char *dn, 1037*7c478bd9Sstevel@tonic-gate struct ldap_tmplitem *tip, int labelwidth, int rdncount, 1038*7c478bd9Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, char *urlprefix ) 1039*7c478bd9Sstevel@tonic-gate { 1040*7c478bd9Sstevel@tonic-gate int err = LDAP_SUCCESS, lderr, i, count, html; 1041*7c478bd9Sstevel@tonic-gate char **vals, **members; 1042*7c478bd9Sstevel@tonic-gate char *value, *filtpattern, *attr, *selectname; 1043*7c478bd9Sstevel@tonic-gate char *retattrs[2], filter[ 256 ]; 1044*7c478bd9Sstevel@tonic-gate LDAPMessage *ldmp; 1045*7c478bd9Sstevel@tonic-gate struct timeval timeout; 1046*7c478bd9Sstevel@tonic-gate 1047*7c478bd9Sstevel@tonic-gate html = ( urlprefix != NULL ); 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gate for ( i = 0; tip->ti_args != NULL && tip->ti_args[ i ] != NULL; ++i ) { 1050*7c478bd9Sstevel@tonic-gate ; 1051*7c478bd9Sstevel@tonic-gate } 1052*7c478bd9Sstevel@tonic-gate if ( i < 3 ) { 1053*7c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 1054*7c478bd9Sstevel@tonic-gate } 1055*7c478bd9Sstevel@tonic-gate attr = tip->ti_args[ 0 ]; 1056*7c478bd9Sstevel@tonic-gate filtpattern = tip->ti_args[ 1 ]; 1057*7c478bd9Sstevel@tonic-gate retattrs[ 0 ] = tip->ti_args[ 2 ]; 1058*7c478bd9Sstevel@tonic-gate retattrs[ 1 ] = NULL; 1059*7c478bd9Sstevel@tonic-gate selectname = tip->ti_args[ 3 ]; 1060*7c478bd9Sstevel@tonic-gate 1061*7c478bd9Sstevel@tonic-gate vals = NULL; 1062*7c478bd9Sstevel@tonic-gate if ( attr == NULL ) { 1063*7c478bd9Sstevel@tonic-gate value = NULL; 1064*7c478bd9Sstevel@tonic-gate } else if ( strcasecmp( attr, "-dnb" ) == 0 ) { 1065*7c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 1066*7c478bd9Sstevel@tonic-gate } else if ( strcasecmp( attr, "-dnt" ) == 0 ) { 1067*7c478bd9Sstevel@tonic-gate value = dn; 1068*7c478bd9Sstevel@tonic-gate } else if (( vals = ldap_get_values( ld, entry, attr )) != NULL ) { 1069*7c478bd9Sstevel@tonic-gate value = vals[ 0 ]; 1070*7c478bd9Sstevel@tonic-gate } else { 1071*7c478bd9Sstevel@tonic-gate value = NULL; 1072*7c478bd9Sstevel@tonic-gate } 1073*7c478bd9Sstevel@tonic-gate 1074*7c478bd9Sstevel@tonic-gate ldap_build_filter( filter, sizeof( filter ), filtpattern, NULL, NULL, NULL, 1075*7c478bd9Sstevel@tonic-gate value, NULL ); 1076*7c478bd9Sstevel@tonic-gate 1077*7c478bd9Sstevel@tonic-gate if ( html ) { 1078*7c478bd9Sstevel@tonic-gate /* 1079*7c478bd9Sstevel@tonic-gate * if we are generating HTML, we add an HREF link that embodies this 1080*7c478bd9Sstevel@tonic-gate * search action as an LDAP URL, instead of actually doing the search 1081*7c478bd9Sstevel@tonic-gate * now. 1082*7c478bd9Sstevel@tonic-gate */ 1083*7c478bd9Sstevel@tonic-gate sprintf( buf, "<DT><A HREF=\"%s", urlprefix ); 1084*7c478bd9Sstevel@tonic-gate if ( base != NULL ) { 1085*7c478bd9Sstevel@tonic-gate strcat_escaped( buf, base ); 1086*7c478bd9Sstevel@tonic-gate } 1087*7c478bd9Sstevel@tonic-gate strcat( buf, "??sub?" ); 1088*7c478bd9Sstevel@tonic-gate strcat_escaped( buf, filter ); 1089*7c478bd9Sstevel@tonic-gate sprintf( buf + strlen( buf ), "\"><B>%s</B></A><DD><BR>%s", 1090*7c478bd9Sstevel@tonic-gate tip->ti_label, eol ); 1091*7c478bd9Sstevel@tonic-gate if ((*writeproc)( writeparm, buf, strlen( buf )) < 0 ) { 1092*7c478bd9Sstevel@tonic-gate return( LDAP_LOCAL_ERROR ); 1093*7c478bd9Sstevel@tonic-gate } 1094*7c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 1095*7c478bd9Sstevel@tonic-gate } 1096*7c478bd9Sstevel@tonic-gate 1097*7c478bd9Sstevel@tonic-gate timeout.tv_sec = SEARCH_TIMEOUT_SECS; 1098*7c478bd9Sstevel@tonic-gate timeout.tv_usec = 0; 1099*7c478bd9Sstevel@tonic-gate 1100*7c478bd9Sstevel@tonic-gate #ifdef CLDAP 1101*7c478bd9Sstevel@tonic-gate if ( LDAP_IS_CLDAP( ld )) 1102*7c478bd9Sstevel@tonic-gate lderr = cldap_search_s( ld, base, LDAP_SCOPE_SUBTREE, filter, retattrs, 1103*7c478bd9Sstevel@tonic-gate 0, &ldmp, NULL ); 1104*7c478bd9Sstevel@tonic-gate else 1105*7c478bd9Sstevel@tonic-gate #endif /* CLDAP */ 1106*7c478bd9Sstevel@tonic-gate lderr = ldap_search_st( ld, base, LDAP_SCOPE_SUBTREE, filter, 1107*7c478bd9Sstevel@tonic-gate retattrs, 0, &timeout, &ldmp ); 1108*7c478bd9Sstevel@tonic-gate 1109*7c478bd9Sstevel@tonic-gate if ( lderr == LDAP_SUCCESS || NONFATAL_LDAP_ERR( lderr )) { 1110*7c478bd9Sstevel@tonic-gate if (( count = ldap_count_entries( ld, ldmp )) > 0 ) { 1111*7c478bd9Sstevel@tonic-gate if (( members = (char **)NSLDAPI_MALLOC( (count + 1) 1112*7c478bd9Sstevel@tonic-gate * sizeof(char *))) == NULL ) { 1113*7c478bd9Sstevel@tonic-gate err = LDAP_NO_MEMORY; 1114*7c478bd9Sstevel@tonic-gate } else { 1115*7c478bd9Sstevel@tonic-gate for ( i = 0, entry = ldap_first_entry( ld, ldmp ); 1116*7c478bd9Sstevel@tonic-gate entry != NULL; 1117*7c478bd9Sstevel@tonic-gate entry = ldap_next_entry( ld, entry ), ++i ) { 1118*7c478bd9Sstevel@tonic-gate members[ i ] = ldap_get_dn( ld, entry ); 1119*7c478bd9Sstevel@tonic-gate } 1120*7c478bd9Sstevel@tonic-gate members[ i ] = NULL; 1121*7c478bd9Sstevel@tonic-gate 1122*7c478bd9Sstevel@tonic-gate ldap_sort_values(ld,members, ldap_sort_strcasecmp); 1123*7c478bd9Sstevel@tonic-gate 1124*7c478bd9Sstevel@tonic-gate err = do_vals2text( ld, NULL, members, tip->ti_label, 1125*7c478bd9Sstevel@tonic-gate html ? -1 : 0, LDAP_SYN_DN, writeproc, writeparm, 1126*7c478bd9Sstevel@tonic-gate eol, rdncount, urlprefix ); 1127*7c478bd9Sstevel@tonic-gate 1128*7c478bd9Sstevel@tonic-gate ldap_value_free( members ); 1129*7c478bd9Sstevel@tonic-gate } 1130*7c478bd9Sstevel@tonic-gate } 1131*7c478bd9Sstevel@tonic-gate ldap_msgfree( ldmp ); 1132*7c478bd9Sstevel@tonic-gate } 1133*7c478bd9Sstevel@tonic-gate 1134*7c478bd9Sstevel@tonic-gate 1135*7c478bd9Sstevel@tonic-gate if ( vals != NULL ) { 1136*7c478bd9Sstevel@tonic-gate ldap_value_free( vals ); 1137*7c478bd9Sstevel@tonic-gate } 1138*7c478bd9Sstevel@tonic-gate 1139*7c478bd9Sstevel@tonic-gate return(( err == LDAP_SUCCESS ) ? lderr : err ); 1140*7c478bd9Sstevel@tonic-gate } 1141