]> git.sur5r.net Git - openldap/blob - contrib/whois++/output.c
Update lutil_lockf (aka: ldap_lockf) to hide implementation in
[openldap] / contrib / whois++ / output.c
1 #if !defined(lint)
2 static char copyright[] = "Copyright 1992 The University of Adelaide";
3 #endif
4
5 /*
6  *                      O U T P U T
7  *
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
13  * Date:        October 1992
14  * Version:     1.7
15  * Description:
16  *              The Output routines
17  *
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.
29  */
30
31 #include <varargs.h>
32 #include "whois++.h"
33
34 extern char *index(), *rindex();
35
36 static displayEntry();
37 static printAttribute();
38
39 static char     *selectObjectClass( ld, entry )
40 LDAP            *ld;
41 LDAPMessage     *entry;
42
43 {
44         static char     *objectClass[] = { "objectClass", NULL };
45         LDAPMessage     *result;
46         char            *dn, *template;
47         char            **val;
48         int             i;
49
50         template = NULL;
51         dn = ldap_get_dn( ld, entry );
52         ldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectclass=*", objectClass,
53                 0, &result );
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 ) );
58                 ldap_memfree( dn );
59                 return NULL;
60         } else
61                 ldap_memfree( dn );
62         if ( ( val = ldap_get_values( ld, result, "objectClass" ) ) == NULL )
63                 return NULL;
64         for ( i = 0 ; val[i] != NULL ; i++ )
65                 if ( specifyAttributes( lowerCase( val[i] ) ) != NULL ) {
66                         template = strdup( val[i] );
67                         break;
68                 }
69         ldap_value_free( val );
70         return template;
71 }
72
73 int             displayResult( ld, result, outputFormat )
74 LDAP            *ld;
75 LDAPMessage     *result;
76 int             outputFormat;
77
78 {
79         int             i, matches, number = 0;
80         char            *dn;
81         LDAPMessage     *e;
82         char            *objectClass;
83         char            **attributes, **objectClassTable;
84
85         matches = ldap_count_entries( ld, result );
86         if ( log )
87                 syslog( LOG_INFO, "%d match(es) to query", matches );
88         if ( matches == 0 ) {
89                 printFormatted( lineLength, TRUE, stdout, "No matches found." );
90                 return FALSE;
91         }
92         if ( outputFormat == NULL ) {
93                 if ( matches == 1 )
94                         outputFormat = FULL;
95                 else if ( matches <= ABRIDGED_LIMIT )
96                         outputFormat = HANDLE;
97                 else
98                         outputFormat = SUMMARY;
99         }
100         switch (outputFormat) {
101         case FULL:
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,
109                                 "#%s \"%s\"",
110                                 objectClassToTemplate( objectClass ), dn );
111                         displayEntry( ld, dn,
112                                 specifyAttributes( objectClass ) );
113                         if ( objectClass != NULL )
114                                 free( objectClass );
115                 }
116                 printFormatted( lineLength, FALSE, stdout, "#END" );
117                 break;
118
119         case ABRIDGED:
120                 /*
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.
124                  */
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." );
129
130         case HANDLE:
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 )
140                                 free( objectClass );
141                 }
142                 printFormatted( lineLength, FALSE, stdout, "#END" );
143                 break;
144
145         case SUMMARY:
146                 printFormatted( lineLength, FALSE, stdout, "#SUMMARY" );
147                 printFormatted( lineLength, FALSE, stdout, " matches:   %d",
148                         matches );
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, 
153                                 "Malloc failed" );
154                         break;
155                 }
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] ) )
164                                         break;
165                         if ( i < number ) {
166                                 if ( objectClass != NULL )
167                                         free( objectClass );
168                         } else {
169                                 objectClassTable[number++] = objectClass;
170                                 printFormatted( lineLength, FALSE, stdout,
171                                         "            %s",
172                                         objectClassToTemplate( objectClass ) );
173                         }
174                 }
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 );
180                 break;
181
182         }
183         return TRUE;
184 }
185
186 static displayEntry( ld, dn, attributes )
187 LDAP    *ld;
188 char    *dn, *attributes[];
189 {
190         char            *ufn;
191         int             i;
192         char            *s, *department;
193         LDAPMessage     *result, *entry;
194
195         ldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectclass=*", attributes,
196                 0, &result );
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 ) );
201                 return;
202         }
203
204         entry = ldap_first_entry( ld, result );
205
206         if ( entry == NULL ) {
207                 /* something very weird has happened */
208                 printFormatted( lineLength, TRUE, stdout,
209                         "Possible conflict with ACLs for \"%s\"", dn );
210                 return;
211         }
212
213         /*
214          * Get the UFN version of the DN and then cut it up into
215          * name and department.
216          */
217         ufn = ldap_dn2ufn( dn );
218         if ( ( s = index( ufn, ',' ) ) != NULL ) {
219                 *s++ = '\0';
220                 while ( *s != '\0' && isspace( (unsigned char) *s ) )
221                         s++;
222                 department = s;
223                 while ( s != NULL && *s != '\0' && !EQ( s, organisation ) )
224                         if ( ( s = index( s, ',' ) ) != NULL ) {
225                                 s++;
226                                 while ( *s && isspace( (unsigned char) *s ) )
227                                         s++;
228                         }
229                 if ( s != NULL )
230                         if ( s != department ) {
231                                 while ( isspace( (unsigned char) *--s ) )
232                                         ;
233                                 *s = '\0';
234                         } else
235                                 department = NULL;
236         } else
237                 department = NULL;
238
239 /**/    /*
240          * Name, Organization, Department, Organization-Type, and Handle
241          * should be read in from language dictionary rather than hard coded.
242          */
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 );
255         }
256         printFormatted( lineLength, FALSE, stdout, " %-19s \"%s\"",
257                 "Handle", dn );
258
259         ldap_memfree( ufn );
260 }
261
262 char *attributeLabel( attribute )
263 char    *attribute;
264
265 {
266 /**/    /* need to get printable string from language dictionary */
267         return attribute;
268 }
269
270 static printAttribute( ld, attribute, entry )
271 LDAP            *ld;
272 char            *attribute;
273 LDAPMessage     *entry;
274 {
275         char    **val;
276         char    *tag, *ptr;
277         int     i;
278
279 /**/    /*
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.
283          */
284         if ( ( val = ldap_get_values( ld, entry, attribute )) == NULL )
285                 return;
286
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 );
299                 } else
300                         printFormatted( lineLength, FALSE, stdout, " %-19s %s",
301                                 tag, val[i] );
302
303         ldap_value_free( val );
304 }
305
306 printFormatted( va_alist )
307 va_dcl
308 {
309         int     lineLength, systemMessage;
310         FILE    *output;
311         char    *format;
312         va_list ap;
313
314         char    buffer[BUFSIZ];
315         char    *head, *p, *q;
316         char    *tag;
317         int     count;
318
319         va_start( ap );
320         lineLength =    va_arg( ap, int );
321         systemMessage = va_arg( ap, int );
322         output =        va_arg( ap, FILE * );
323         format =        va_arg( ap, char * );
324         if ( systemMessage ) {
325                 lineLength--;
326                 tag = "% ";
327         } else
328                 tag = "";
329         vsprintf( buffer, format, ap );
330         va_end( ap );
331
332         if ( strlen( buffer ) < lineLength )
333                 fprintf( output, "%s%s\r\n", tag, buffer );
334         else {
335                 head = buffer;
336                 do {
337                         count = strlen( tag );
338                         for ( q = head; *q && *q != ' '; q++ )
339                                 count++;
340                         if ( *q == NULL ) {
341                                 fprintf( output, "%s%s\r\n", tag, head );
342                                 break;
343                         } else if ( count > lineLength ) {
344                                 *q++ = '\0';
345                                 fprintf( output, "%s%s\r\n", tag, head );
346                                 head = q;
347                         } else {
348                                 do {
349                                         p = q++;
350                                         count++;
351                                         for (; *q && *q != ' '; q++ )
352                                                 count++;
353                                 } while ( *p != '\0' && count <= lineLength );
354                                 if ( *p != '\0' )
355                                         *p++ = '\0';
356                                 fprintf( output, "%s%s\r\n", tag, head );
357                                 head = p;
358                         }
359                         if ( !systemMessage )
360                                 tag = "+ ";
361                 } while ( *head != NULL );
362         }
363 }