2 static char copyright[] = "Copyright 1992 The University of Adelaide";
8 * Author: Mark R. Prior
9 * Communications and Systems Branch
10 * Information Technology Division
11 * The University of Adelaide
12 * E-mail: mrp@itd.adelaide.edu.au
18 * Redistribution and use in source and binary forms are permitted
19 * provided that the above copyright notice and this paragraph are
20 * duplicated in all such forms and that any documentation,
21 * advertising materials, and other materials related to such
22 * distribution and use acknowledge that the software was developed
23 * by the University of Adelaide. The name of the University may not
24 * be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
28 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
34 extern char *index(), *rindex();
36 static displayEntry();
37 static printAttribute();
39 static char *selectObjectClass( ld, entry )
44 static char *objectClass[] = { "objectClass", NULL };
51 dn = strdup( ldap_get_dn( ld, entry ) );
52 ldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectclass=*", objectClass,
54 if ( ld->ld_errno != LDAP_SUCCESS ) {
55 printFormatted( lineLength, TRUE, stdout,
56 "Read on object \"%s\" failed, %s",
57 dn, ldap_err2string( ld->ld_errno ) );
62 if ( ( val = ldap_get_values( ld, result, "objectClass" ) ) == NULL )
64 for ( i = 0 ; val[i] != NULL ; i++ )
65 if ( specifyAttributes( lowerCase( val[i] ) ) != NULL ) {
66 template = strdup( val[i] );
69 ldap_value_free( val );
73 int displayResult( ld, result, outputFormat )
79 int i, matches, number = 0;
83 char **attributes, **objectClassTable;
85 matches = ldap_count_entries( ld, result );
87 syslog( LOG_INFO, "%d match(es) to query", matches );
89 printFormatted( lineLength, TRUE, stdout, "No matches found." );
92 if ( outputFormat == NULL ) {
95 else if ( matches <= ABRIDGED_LIMIT )
96 outputFormat = HANDLE;
98 outputFormat = SUMMARY;
100 switch (outputFormat) {
102 printFormatted( lineLength, FALSE, stdout,
103 "#FULL %d", matches );
104 for ( e = ldap_first_entry( ld, result ); e != NULL;
105 e = ldap_next_entry( ld, e ) ) {
106 objectClass = selectObjectClass( ld, e );
107 dn = ldap_get_dn( ld, e );
108 printFormatted( lineLength, FALSE, stdout,
110 objectClassToTemplate( objectClass ), dn );
111 displayEntry( ld, dn,
112 specifyAttributes( objectClass ) );
113 if ( objectClass != NULL )
116 printFormatted( lineLength, FALSE, stdout, "#END" );
121 * As the DN contains most of the information wanted in
122 * ABRIDGED format we use HANDLE format even if the client
123 * really specified ABRIDGED.
125 printFormatted( lineLength, TRUE, stdout,
126 "Abridged format is not really supported, the handle \
127 supplies most of the information specified in the abridged format description \
128 so we use the handle format instead." );
131 printFormatted( lineLength, FALSE, stdout,
132 "#HANDLE %d", matches );
133 for ( e = ldap_first_entry( ld, result ); e != NULL;
134 e = ldap_next_entry( ld, e ) ) {
135 objectClass = selectObjectClass( ld, e );
136 printFormatted( lineLength, FALSE, stdout, " \"%s\" %s",
137 ldap_get_dn( ld, e ),
138 objectClassToTemplate( objectClass ) );
139 if ( objectClass != NULL )
142 printFormatted( lineLength, FALSE, stdout, "#END" );
146 printFormatted( lineLength, FALSE, stdout, "#SUMMARY" );
147 printFormatted( lineLength, FALSE, stdout, " matches: %d",
149 e = ldap_first_entry( ld, result );
150 objectClass = selectObjectClass( ld, e );
151 if ( ( objectClassTable = (char **)malloc(sizeof(char **)*matches) ) == NULL ) {
152 printFormatted( lineLength, TRUE, stdout,
156 objectClassTable[number++] = objectClass;
157 printFormatted( lineLength, FALSE, stdout, " templates: %s",
158 objectClassToTemplate( objectClass ) );
159 while ( ( e = ldap_next_entry( ld, e ) ) != NULL ) {
160 objectClass = selectObjectClass( ld, e );
161 /* have we printed this before? If not do it now */
162 for ( i = 0; i < number; i++ )
163 if ( EQ( objectClass, objectClassTable[i] ) )
166 if ( objectClass != NULL )
169 objectClassTable[number++] = objectClass;
170 printFormatted( lineLength, FALSE, stdout,
172 objectClassToTemplate( objectClass ) );
175 printFormatted( lineLength, FALSE, stdout, "#END" );
176 for ( i = 0; i < number; i++ )
177 if ( objectClassTable[i] != NULL )
178 free( objectClassTable[i] );
179 free( objectClassTable );
186 static displayEntry( ld, dn, attributes )
188 char *dn, *attributes[];
192 char *s, *department;
193 LDAPMessage *result, *entry;
195 ldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectclass=*", attributes,
197 if ( ld->ld_errno != LDAP_SUCCESS ) {
198 printFormatted( lineLength, TRUE, stdout,
199 "Read on object \"%s\" failed, %s", dn,
200 ldap_err2string( ld->ld_errno ) );
204 entry = ldap_first_entry( ld, result );
206 if ( entry == NULL ) {
207 /* something very weird has happened */
208 printFormatted( lineLength, TRUE, stdout,
209 "Possible conflict with ACLs for \"%s\"", dn );
214 * Get the UFN version of the DN and then cut it up into
215 * name and department.
217 ufn = ldap_dn2ufn( dn );
218 if ( ( s = index( ufn, ',' ) ) != NULL ) {
220 while ( *s != '\0' && isspace( (unsigned char) *s ) )
223 while ( s != NULL && *s != '\0' && !EQ( s, organisation ) )
224 if ( ( s = index( s, ',' ) ) != NULL ) {
226 while ( *s && isspace( (unsigned char) *s ) )
230 if ( s != department ) {
231 while ( isspace( (unsigned char) *--s ) )
240 * Name, Organization, Department, Organization-Type, and Handle
241 * should be read in from language dictionary rather than hard coded.
243 printFormatted( lineLength, FALSE, stdout, " %-19s %s", "Name", ufn );
244 if ( department != NULL && *department != '\0' )
245 printFormatted( lineLength, FALSE, stdout,
246 " %-19s %s", "Department", department );
247 printFormatted( lineLength, FALSE, stdout, " %-19s %s",
248 "Organization", organisation );
249 if ( category != NULL )
250 for ( i = 0; category[i] != NULL; i++ )
251 printFormatted( lineLength, FALSE, stdout, " %-19s %s",
252 "Organization-type", category[i] );
253 for ( i = 0; attributes != NULL && attributes[i] != NULL; i++ ) {
254 printAttribute( ld, attributes[i], entry );
256 printFormatted( lineLength, FALSE, stdout, " %-19s \"%s\"",
262 char *attributeLabel( attribute )
266 /**/ /* need to get printable string from language dictionary */
270 static printAttribute( ld, attribute, entry )
280 * We really should determine whether the attribute value needs line
281 * processing or not rather than just hard coding in a couple of cases
282 * but for the moment we will ignore the problem.
284 if ( ( val = ldap_get_values( ld, entry, attribute )) == NULL )
287 tag = attributeLabel( attribute );
288 for ( i = 0; val[i] != NULL; i++ )
289 if ( EQ( attribute, "lastModifiedTime" ) )
290 printFormatted( lineLength, FALSE, stdout, " %-19s %s",
291 tag, convertTime( val[i], locale ) );
292 else if ( EQ( attribute, "postalAddress" )
293 || EQ( attribute, "homePostalAddress" ) ) {
294 printFormatted( lineLength, FALSE, stdout, " %-19s %s",
295 tag, strtok( val[i], "$" ) );
296 while ( ( ptr = strtok( NULL, "$" ) ) != NULL )
297 printFormatted( lineLength, FALSE, stdout,
298 " %-19s%s", "", ptr );
300 printFormatted( lineLength, FALSE, stdout, " %-19s %s",
303 ldap_value_free( val );
306 printFormatted( lineLength, systemMessage, output, format, va_alist )
307 int lineLength, systemMessage;
319 if ( systemMessage ) {
325 vsprintf( buffer, format, ap );
327 if ( strlen( buffer ) < lineLength )
328 fprintf( output, "%s%s\r\n", tag, buffer );
332 count = strlen( tag );
333 for ( q = head; *q && *q != ' '; q++ )
336 fprintf( output, "%s%s\r\n", tag, head );
338 } else if ( count > lineLength ) {
340 fprintf( output, "%s%s\r\n", tag, head );
346 for (; *q && *q != ' '; q++ )
348 } while ( *p != '\0' && count <= lineLength );
351 fprintf( output, "%s%s\r\n", tag, head );
354 if ( !systemMessage )
356 } while ( *head != NULL );