]> git.sur5r.net Git - openldap/blob - libraries/libldap/test.c
More files that didn't get merged properly.
[openldap] / libraries / libldap / test.c
1 #include "portable.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 #include <ac/ctype.h>
7 #include <ac/socket.h>
8 #include <ac/string.h>
9 #include <ac/time.h>
10 #include <ac/unistd.h>
11
12 #include <sys/stat.h>
13
14 #ifdef HAVE_SYS_FILE_H
15 #include <sys/file.h>
16 #endif
17 #ifdef HAVE_IO_H
18 #include <io.h>
19 #endif
20
21 #include <fcntl.h>
22
23 #include "lber.h"
24 #include "ldap.h"
25
26 /* including the "internal" defs is legit and nec. since this test routine has 
27  * a-priori knowledge of libldap internal workings.
28  * hodges@stanford.edu 5-Feb-96
29  */
30 #include "ldap-int.h"
31
32 static void handle_result LDAP_P(( LDAP *ld, LDAPMessage *lm ));
33 static void print_ldap_result LDAP_P(( LDAP *ld, LDAPMessage *lm, char *s ));
34 static void print_search_entry LDAP_P(( LDAP *ld, LDAPMessage *res ));
35 static void free_list LDAP_P(( char **list ));
36
37 #define NOCACHEERRMSG   "don't compile with -DLDAP_NOCACHE if you desire local caching"
38
39 char *dnsuffix;
40
41 #ifndef HAVE_GETLINE
42 static char *
43 getline( char *line, int len, FILE *fp, char *prompt )
44 {
45         printf(prompt);
46
47         if ( fgets( line, len, fp ) == NULL )
48                 return( NULL );
49
50         line[ strlen( line ) - 1 ] = '\0';
51
52         return( line );
53 }
54 #endif
55
56 static char **
57 get_list( char *prompt )
58 {
59         static char     buf[256];
60         int             num;
61         char            **result;
62
63         num = 0;
64         result = (char **) 0;
65         while ( 1 ) {
66                 getline( buf, sizeof(buf), stdin, prompt );
67
68                 if ( *buf == '\0' )
69                         break;
70
71                 if ( result == (char **) 0 )
72                         result = (char **) malloc( sizeof(char *) );
73                 else
74                         result = (char **) realloc( result,
75                             sizeof(char *) * (num + 1) );
76
77                 result[num++] = (char *) strdup( buf );
78         }
79         if ( result == (char **) 0 )
80                 return( NULL );
81         result = (char **) realloc( result, sizeof(char *) * (num + 1) );
82         result[num] = NULL;
83
84         return( result );
85 }
86
87
88 static void
89 free_list( char **list )
90 {
91         int     i;
92
93         if ( list != NULL ) {
94                 for ( i = 0; list[ i ] != NULL; ++i ) {
95                         free( list[ i ] );
96                 }
97                 free( (char *)list );
98         }
99 }
100
101
102 static int
103 file_read( char *path, struct berval *bv )
104 {
105         FILE            *fp;
106         long            rlen;
107         int             eof;
108
109         if (( fp = fopen( path, "r" )) == NULL ) {
110                 perror( path );
111                 return( -1 );
112         }
113
114         if ( fseek( fp, 0L, SEEK_END ) != 0 ) {
115                 perror( path );
116                 fclose( fp );
117                 return( -1 );
118         }
119
120         bv->bv_len = ftell( fp );
121
122         if (( bv->bv_val = (char *)malloc( bv->bv_len )) == NULL ) {
123                 perror( "malloc" );
124                 fclose( fp );
125                 return( -1 );
126         }
127
128         if ( fseek( fp, 0L, SEEK_SET ) != 0 ) {
129                 perror( path );
130                 fclose( fp );
131                 return( -1 );
132         }
133
134         rlen = fread( bv->bv_val, 1, bv->bv_len, fp );
135         eof = feof( fp );
136         fclose( fp );
137
138         if ( (unsigned long) rlen != bv->bv_len ) {
139                 perror( path );
140                 free( bv->bv_val );
141                 return( -1 );
142         }
143
144         return( bv->bv_len );
145 }
146
147
148 static LDAPMod **
149 get_modlist( char *prompt1, char *prompt2, char *prompt3 )
150 {
151         static char     buf[256];
152         int             num;
153         LDAPMod         tmp;
154         LDAPMod         **result;
155         struct berval   **bvals;
156
157         num = 0;
158         result = NULL;
159         while ( 1 ) {
160                 if ( prompt1 ) {
161                         getline( buf, sizeof(buf), stdin, prompt1 );
162                         tmp.mod_op = atoi( buf );
163
164                         if ( tmp.mod_op == -1 || buf[0] == '\0' )
165                                 break;
166                 }
167
168                 getline( buf, sizeof(buf), stdin, prompt2 );
169                 if ( buf[0] == '\0' )
170                         break;
171                 tmp.mod_type = strdup( buf );
172
173                 tmp.mod_values = get_list( prompt3 );
174
175                 if ( tmp.mod_values != NULL ) {
176                         int     i;
177
178                         for ( i = 0; tmp.mod_values[i] != NULL; ++i )
179                                 ;
180                         bvals = (struct berval **)calloc( i + 1,
181                             sizeof( struct berval *));
182                         for ( i = 0; tmp.mod_values[i] != NULL; ++i ) {
183                                 bvals[i] = (struct berval *)malloc(
184                                     sizeof( struct berval ));
185                                 if ( strncmp( tmp.mod_values[i], "{FILE}",
186                                     6 ) == 0 ) {
187                                         if ( file_read( tmp.mod_values[i] + 6,
188                                             bvals[i] ) < 0 ) {
189                                                 return( NULL );
190                                         }
191                                 } else {
192                                         bvals[i]->bv_val = tmp.mod_values[i];
193                                         bvals[i]->bv_len =
194                                             strlen( tmp.mod_values[i] );
195                                 }
196                         }
197                         tmp.mod_bvalues = bvals;
198                         tmp.mod_op |= LDAP_MOD_BVALUES;
199                 }
200
201                 if ( result == NULL )
202                         result = (LDAPMod **) malloc( sizeof(LDAPMod *) );
203                 else
204                         result = (LDAPMod **) realloc( result,
205                             sizeof(LDAPMod *) * (num + 1) );
206
207                 result[num] = (LDAPMod *) malloc( sizeof(LDAPMod) );
208                 *(result[num]) = tmp;   /* struct copy */
209                 num++;
210         }
211         if ( result == NULL )
212                 return( NULL );
213         result = (LDAPMod **) realloc( result, sizeof(LDAPMod *) * (num + 1) );
214         result[num] = NULL;
215
216         return( result );
217 }
218
219
220 #ifdef LDAP_REFERRALS
221 int
222 bind_prompt( LDAP *ld, char **dnp, char **passwdp, int *authmethodp,
223         int freeit )
224 {
225         static char     dn[256], passwd[256];
226
227         if ( !freeit ) {
228 #ifdef HAVE_KERBEROS
229                 getline( dn, sizeof(dn), stdin,
230                     "re-bind method (0->simple, 1->krbv41, 2->krbv42, 3->krbv41&2)? " );
231                 if (( *authmethodp = atoi( dn )) == 3 ) {
232                         *authmethodp = LDAP_AUTH_KRBV4;
233                 } else {
234                         *authmethodp |= 0x80;
235                 }
236 #else /* HAVE_KERBEROS */
237                 *authmethodp = LDAP_AUTH_SIMPLE;
238 #endif /* HAVE_KERBEROS */
239
240                 getline( dn, sizeof(dn), stdin, "re-bind dn? " );
241                 strcat( dn, dnsuffix );
242                 *dnp = dn;
243
244                 if ( *authmethodp == LDAP_AUTH_SIMPLE && dn[0] != '\0' ) {
245                         getline( passwd, sizeof(passwd), stdin,
246                             "re-bind password? " );
247                 } else {
248                         passwd[0] = '\0';
249                 }
250                 *passwdp = passwd;
251         }
252
253         return( LDAP_SUCCESS );
254 }
255 #endif /* LDAP_REFERRALS */
256
257
258 int
259 main( int argc, char **argv )
260 {
261         LDAP            *ld = NULL;
262         int             i, c, port, cldapflg, errflg, method, id, msgtype;
263         char            line[256], command1, command2, command3;
264         char            passwd[64], dn[256], rdn[64], attr[64], value[256];
265         char            filter[256], *host, **types;
266         char            **exdn;
267         char            *usage = "usage: %s [-u] [-h host] [-d level] [-s dnsuffix] [-p port] [-t file] [-T file]\n";
268         int             bound, all, scope, attrsonly;
269         LDAPMessage     *res;
270         LDAPMod         **mods, **attrs;
271         struct timeval  timeout;
272         char            *copyfname = NULL;
273         int             copyoptions = 0;
274         LDAPURLDesc     *ludp;
275
276         extern char     *optarg;
277         extern int      optind;
278
279         host = NULL;
280         port = LDAP_PORT;
281         dnsuffix = "";
282         cldapflg = errflg = 0;
283
284         while (( c = getopt( argc, argv, "uh:d:s:p:t:T:" )) != -1 ) {
285                 switch( c ) {
286                 case 'u':
287 #ifdef LDAP_CONNECTIONLESS
288                         cldapflg++;
289 #else /* LDAP_CONNECTIONLESS */
290                         printf( "Compile with -DLDAP_CONNECTIONLESS for UDP support\n" );
291 #endif /* LDAP_CONNECTIONLESS */
292                         break;
293
294                 case 'd':
295 #ifdef LDAP_DEBUG
296                         ldap_debug = atoi( optarg );
297                         if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
298                                 lber_debug = ldap_debug;
299                         }
300 #else
301                         printf( "Compile with -DLDAP_DEBUG for debugging\n" );
302 #endif
303                         break;
304
305                 case 'h':
306                         host = optarg;
307                         break;
308
309                 case 's':
310                         dnsuffix = optarg;
311                         break;
312
313                 case 'p':
314                         port = atoi( optarg );
315                         break;
316
317                 case 't':       /* copy ber's to given file */
318                         copyfname = strdup( optarg );
319                         copyoptions = LBER_TO_FILE;
320                         break;
321
322                 case 'T':       /* only output ber's to given file */
323                         copyfname = strdup( optarg );
324                         copyoptions = (LBER_TO_FILE | LBER_TO_FILE_ONLY);
325                         break;
326
327                 default:
328                     ++errflg;
329                 }
330         }
331
332         if ( host == NULL && optind == argc - 1 ) {
333                 host = argv[ optind ];
334                 ++optind;
335         }
336
337         if ( errflg || optind < argc - 1 ) {
338                 fprintf( stderr, usage, argv[ 0 ] );
339                 exit( 1 );
340         }
341         
342         printf( "%sldap_open( %s, %d )\n", cldapflg ? "c" : "",
343                 host == NULL ? "(null)" : host, port );
344
345         if ( cldapflg ) {
346 #ifdef LDAP_CONNECTIONLESS
347                 ld = cldap_open( host, port );
348 #endif /* LDAP_CONNECTIONLESS */
349         } else {
350                 ld = ldap_open( host, port );
351         }
352
353         if ( ld == NULL ) {
354                 perror( "ldap_open" );
355                 exit(1);
356         }
357
358         if ( copyfname != NULL ) {
359                 if ( (ld->ld_sb.sb_fd = open( copyfname, O_WRONLY | O_CREAT,
360                     0600 ))  == -1 ) {
361                         perror( copyfname );
362                         exit ( 1 );
363                 }
364                 ld->ld_sb.sb_options = copyoptions;
365         }
366
367         bound = 0;
368         timeout.tv_sec = 0;
369         timeout.tv_usec = 0;
370
371         (void) memset( line, '\0', sizeof(line) );
372         while ( getline( line, sizeof(line), stdin, "\ncommand? " ) != NULL ) {
373                 command1 = line[0];
374                 command2 = line[1];
375                 command3 = line[2];
376
377                 switch ( command1 ) {
378                 case 'a':       /* add or abandon */
379                         switch ( command2 ) {
380                         case 'd':       /* add */
381                                 getline( dn, sizeof(dn), stdin, "dn? " );
382                                 strcat( dn, dnsuffix );
383                                 if ( (attrs = get_modlist( NULL, "attr? ",
384                                     "value? " )) == NULL )
385                                         break;
386                                 if ( (id = ldap_add( ld, dn, attrs )) == -1 )
387                                         ldap_perror( ld, "ldap_add" );
388                                 else
389                                         printf( "Add initiated with id %d\n",
390                                             id );
391                                 break;
392
393                         case 'b':       /* abandon */
394                                 getline( line, sizeof(line), stdin, "msgid? " );
395                                 id = atoi( line );
396                                 if ( ldap_abandon( ld, id ) != 0 )
397                                         ldap_perror( ld, "ldap_abandon" );
398                                 else
399                                         printf( "Abandon successful\n" );
400                                 break;
401                         default:
402                                 printf( "Possibilities: [ad]d, [ab]ort\n" );
403                         }
404                         break;
405
406                 case 'b':       /* asynch bind */
407 #ifdef HAVE_KERBEROS
408                         getline( line, sizeof(line), stdin,
409                             "method (0->simple, 1->krbv41, 2->krbv42)? " );
410                         method = atoi( line ) | 0x80;
411 #else /* HAVE_KERBEROS */
412                         method = LDAP_AUTH_SIMPLE;
413 #endif /* HAVE_KERBEROS */
414                         getline( dn, sizeof(dn), stdin, "dn? " );
415                         strcat( dn, dnsuffix );
416
417                         if ( method == LDAP_AUTH_SIMPLE && dn[0] != '\0' )
418                                 getline( passwd, sizeof(passwd), stdin,
419                                     "password? " );
420                         else
421                                 passwd[0] = '\0';
422
423                         if ( ldap_bind( ld, dn, passwd, method ) == -1 ) {
424                                 fprintf( stderr, "ldap_bind failed\n" );
425                                 ldap_perror( ld, "ldap_bind" );
426                         } else {
427                                 printf( "Bind initiated\n" );
428                                 bound = 1;
429                         }
430                         break;
431
432                 case 'B':       /* synch bind */
433 #ifdef HAVE_KERBEROS
434                         getline( line, sizeof(line), stdin,
435                             "method 0->simple 1->krbv41 2->krbv42 3->krb? " );
436                         method = atoi( line );
437                         if ( method == 3 )
438                                 method = LDAP_AUTH_KRBV4;
439                         else
440                                 method = method | 0x80;
441 #else /* HAVE_KERBEROS */
442                         method = LDAP_AUTH_SIMPLE;
443 #endif /* HAVE_KERBEROS */
444                         getline( dn, sizeof(dn), stdin, "dn? " );
445                         strcat( dn, dnsuffix );
446
447                         if ( dn[0] != '\0' )
448                                 getline( passwd, sizeof(passwd), stdin,
449                                     "password? " );
450                         else
451                                 passwd[0] = '\0';
452
453                         if ( ldap_bind_s( ld, dn, passwd, method ) !=
454                             LDAP_SUCCESS ) {
455                                 fprintf( stderr, "ldap_bind_s failed\n" );
456                                 ldap_perror( ld, "ldap_bind_s" );
457                         } else {
458                                 printf( "Bind successful\n" );
459                                 bound = 1;
460                         }
461                         break;
462
463                 case 'c':       /* compare */
464                         getline( dn, sizeof(dn), stdin, "dn? " );
465                         strcat( dn, dnsuffix );
466                         getline( attr, sizeof(attr), stdin, "attr? " );
467                         getline( value, sizeof(value), stdin, "value? " );
468
469                         if ( (id = ldap_compare( ld, dn, attr, value )) == -1 )
470                                 ldap_perror( ld, "ldap_compare" );
471                         else
472                                 printf( "Compare initiated with id %d\n", id );
473                         break;
474
475                 case 'd':       /* turn on debugging */
476 #ifdef LDAP_DEBUG
477                         getline( line, sizeof(line), stdin, "debug level? " );
478                         ldap_debug = atoi( line );
479                         if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
480                                 lber_debug = ldap_debug;
481                         }
482 #else
483                         printf( "Compile with -DLDAP_DEBUG for debugging\n" );
484 #endif
485                         break;
486
487                 case 'E':       /* explode a dn */
488                         getline( line, sizeof(line), stdin, "dn? " );
489                         exdn = ldap_explode_dn( line, 0 );
490                         for ( i = 0; exdn != NULL && exdn[i] != NULL; i++ ) {
491                                 printf( "\t%s\n", exdn[i] );
492                         }
493                         break;
494
495                 case 'g':       /* set next msgid */
496                         getline( line, sizeof(line), stdin, "msgid? " );
497                         ld->ld_msgid = atoi( line );
498                         break;
499
500                 case 'v':       /* set version number */
501                         getline( line, sizeof(line), stdin, "version? " );
502                         ld->ld_version = atoi( line );
503                         break;
504
505                 case 'm':       /* modify or modifyrdn */
506                         if ( strncmp( line, "modify", 4 ) == 0 ) {
507                                 getline( dn, sizeof(dn), stdin, "dn? " );
508                                 strcat( dn, dnsuffix );
509                                 if ( (mods = get_modlist(
510                                     "mod (0=>add, 1=>delete, 2=>replace -1=>done)? ",
511                                     "attribute type? ", "attribute value? " ))
512                                     == NULL )
513                                         break;
514                                 if ( (id = ldap_modify( ld, dn, mods )) == -1 )
515                                         ldap_perror( ld, "ldap_modify" );
516                                 else
517                                         printf( "Modify initiated with id %d\n",
518                                             id );
519                         } else if ( strncmp( line, "modrdn", 4 ) == 0 ) {
520                                 getline( dn, sizeof(dn), stdin, "dn? " );
521                                 strcat( dn, dnsuffix );
522                                 getline( rdn, sizeof(rdn), stdin, "newrdn? " );
523                                 if ( (id = ldap_modrdn( ld, dn, rdn )) == -1 )
524                                         ldap_perror( ld, "ldap_modrdn" );
525                                 else
526                                         printf( "Modrdn initiated with id %d\n",
527                                             id );
528                         } else {
529                                 printf( "Possibilities: [modi]fy, [modr]dn\n" );
530                         }
531                         break;
532
533                 case 'q':       /* quit */
534 #ifdef LDAP_CONNECTIONLESS
535                         if ( cldapflg )
536                                 cldap_close( ld );
537 #endif /* LDAP_CONNECTIONLESS */
538 #ifdef LDAP_REFERRALS
539                         if ( !cldapflg )
540 #else /* LDAP_REFERRALS */
541                         if ( !cldapflg && bound )
542 #endif /* LDAP_REFERRALS */
543                                 ldap_unbind( ld );
544                         exit( 0 );
545                         break;
546
547                 case 'r':       /* result or remove */
548                         switch ( command3 ) {
549                         case 's':       /* result */
550                                 getline( line, sizeof(line), stdin,
551                                     "msgid (-1=>any)? " );
552                                 if ( line[0] == '\0' )
553                                         id = -1;
554                                 else
555                                         id = atoi( line );
556                                 getline( line, sizeof(line), stdin,
557                                     "all (0=>any, 1=>all)? " );
558                                 if ( line[0] == '\0' )
559                                         all = 1;
560                                 else
561                                         all = atoi( line );
562                                 if (( msgtype = ldap_result( ld, id, all,
563                                     &timeout, &res )) < 1 ) {
564                                         ldap_perror( ld, "ldap_result" );
565                                         break;
566                                 }
567                                 printf( "\nresult: msgtype %d msgid %d\n",
568                                     msgtype, res->lm_msgid );
569                                 handle_result( ld, res );
570                                 res = NULLMSG;
571                                 break;
572
573                         case 'm':       /* remove */
574                                 getline( dn, sizeof(dn), stdin, "dn? " );
575                                 strcat( dn, dnsuffix );
576                                 if ( (id = ldap_delete( ld, dn )) == -1 )
577                                         ldap_perror( ld, "ldap_delete" );
578                                 else
579                                         printf( "Remove initiated with id %d\n",
580                                             id );
581                                 break;
582
583                         default:
584                                 printf( "Possibilities: [rem]ove, [res]ult\n" );
585                                 break;
586                         }
587                         break;
588
589                 case 's':       /* search */
590                         getline( dn, sizeof(dn), stdin, "searchbase? " );
591                         strcat( dn, dnsuffix );
592                         getline( line, sizeof(line), stdin,
593                             "scope (0=Base, 1=One Level, 2=Subtree)? " );
594                         scope = atoi( line );
595                         getline( filter, sizeof(filter), stdin,
596                             "search filter (e.g. sn=jones)? " );
597                         types = get_list( "attrs to return? " );
598                         getline( line, sizeof(line), stdin,
599                             "attrsonly (0=attrs&values, 1=attrs only)? " );
600                         attrsonly = atoi( line );
601
602                         if ( cldapflg ) {
603 #ifdef LDAP_CONNECTIONLESS
604                             getline( line, sizeof(line), stdin,
605                                 "Requestor DN (for logging)? " );
606                             if ( cldap_search_s( ld, dn, scope, filter, types,
607                                     attrsonly, &res, line ) != 0 ) {
608                                 ldap_perror( ld, "cldap_search_s" );
609                             } else {
610                                 printf( "\nresult: msgid %d\n",
611                                     res->lm_msgid );
612                                 handle_result( ld, res );
613                                 res = NULLMSG;
614                             }
615 #endif /* LDAP_CONNECTIONLESS */
616                         } else {
617                             if (( id = ldap_search( ld, dn, scope, filter,
618                                     types, attrsonly  )) == -1 ) {
619                                 ldap_perror( ld, "ldap_search" );
620                             } else {
621                                 printf( "Search initiated with id %d\n", id );
622                             }
623                         }
624                         free_list( types );
625                         break;
626
627                 case 't':       /* set timeout value */
628                         getline( line, sizeof(line), stdin, "timeout? " );
629                         timeout.tv_sec = atoi( line );
630                         break;
631
632                 case 'U':       /* set ufn search prefix */
633                         getline( line, sizeof(line), stdin, "ufn prefix? " );
634                         ldap_ufn_setprefix( ld, line );
635                         break;
636
637                 case 'u':       /* user friendly search w/optional timeout */
638                         getline( dn, sizeof(dn), stdin, "ufn? " );
639                         strcat( dn, dnsuffix );
640                         types = get_list( "attrs to return? " );
641                         getline( line, sizeof(line), stdin,
642                             "attrsonly (0=attrs&values, 1=attrs only)? " );
643                         attrsonly = atoi( line );
644
645                         if ( command2 == 't' ) {
646                                 id = ldap_ufn_search_c( ld, dn, types,
647                                     attrsonly, &res, ldap_ufn_timeout,
648                                     &timeout );
649                         } else {
650                                 id = ldap_ufn_search_s( ld, dn, types,
651                                     attrsonly, &res );
652                         }
653                         if ( res == NULL )
654                                 ldap_perror( ld, "ldap_ufn_search" );
655                         else {
656                                 printf( "\nresult: err %d\n", id );
657                                 handle_result( ld, res );
658                                 res = NULLMSG;
659                         }
660                         free_list( types );
661                         break;
662
663                 case 'l':       /* URL search */
664                         getline( line, sizeof(line), stdin,
665                             "attrsonly (0=attrs&values, 1=attrs only)? " );
666                         attrsonly = atoi( line );
667                         getline( line, sizeof(line), stdin, "LDAP URL? " );
668                         if (( id = ldap_url_search( ld, line, attrsonly  ))
669                                 == -1 ) {
670                             ldap_perror( ld, "ldap_url_search" );
671                         } else {
672                             printf( "URL search initiated with id %d\n", id );
673                         }
674                         break;
675
676                 case 'p':       /* parse LDAP URL */
677                         getline( line, sizeof(line), stdin, "LDAP URL? " );
678                         if (( i = ldap_url_parse( line, &ludp )) != 0 ) {
679                             fprintf( stderr, "ldap_url_parse: error %d\n", i );
680                         } else {
681                             printf( "\t  host: " );
682                             if ( ludp->lud_host == NULL ) {
683                                 printf( "DEFAULT\n" );
684                             } else {
685                                 printf( "<%s>\n", ludp->lud_host );
686                             }
687                             printf( "\t  port: " );
688                             if ( ludp->lud_port == 0 ) {
689                                 printf( "DEFAULT\n" );
690                             } else {
691                                 printf( "%d\n", ludp->lud_port );
692                             }
693                             printf( "\t    dn: <%s>\n", ludp->lud_dn );
694                             printf( "\t attrs:" );
695                             if ( ludp->lud_attrs == NULL ) {
696                                 printf( " ALL" );
697                             } else {
698                                 for ( i = 0; ludp->lud_attrs[ i ] != NULL; ++i ) {
699                                     printf( " <%s>", ludp->lud_attrs[ i ] );
700                                 }
701                             }
702                             printf( "\n\t scope: %s\n", ludp->lud_scope == LDAP_SCOPE_ONELEVEL ?
703                                 "ONE" : ludp->lud_scope == LDAP_SCOPE_BASE ? "BASE" :
704                                 ludp->lud_scope == LDAP_SCOPE_SUBTREE ? "SUB" : "**invalid**" );
705                             printf( "\tfilter: <%s>\n", ludp->lud_filter );
706                             ldap_free_urldesc( ludp );
707                         }
708                             break;
709
710                 case 'n':       /* set dn suffix, for convenience */
711                         getline( line, sizeof(line), stdin, "DN suffix? " );
712                         strcpy( dnsuffix, line );
713                         break;
714
715                 case 'e':       /* enable cache */
716 #ifdef LDAP_NOCACHE
717                         printf( NOCACHEERRMSG );
718 #else /* LDAP_NOCACHE */
719                         getline( line, sizeof(line), stdin, "Cache timeout (secs)? " );
720                         i = atoi( line );
721                         getline( line, sizeof(line), stdin, "Maximum memory to use (bytes)? " );
722                         if ( ldap_enable_cache( ld, i, atoi( line )) == 0 ) {
723                                 printf( "local cache is on\n" ); 
724                         } else {
725                                 printf( "ldap_enable_cache failed\n" ); 
726                         }
727 #endif /* LDAP_NOCACHE */
728                         break;
729
730                 case 'x':       /* uncache entry */
731 #ifdef LDAP_NOCACHE
732                         printf( NOCACHEERRMSG );
733 #else /* LDAP_NOCACHE */
734                         getline( line, sizeof(line), stdin, "DN? " );
735                         ldap_uncache_entry( ld, line );
736 #endif /* LDAP_NOCACHE */
737                         break;
738
739                 case 'X':       /* uncache request */
740 #ifdef LDAP_NOCACHE
741                         printf( NOCACHEERRMSG );
742 #else /* LDAP_NOCACHE */
743                         getline( line, sizeof(line), stdin, "request msgid? " );
744                         ldap_uncache_request( ld, atoi( line ));
745 #endif /* LDAP_NOCACHE */
746                         break;
747
748                 case 'o':       /* set ldap options */
749                         getline( line, sizeof(line), stdin, "alias deref (0=never, 1=searching, 2=finding, 3=always)?" );
750                         ld->ld_deref = atoi( line );
751                         getline( line, sizeof(line), stdin, "timelimit?" );
752                         ld->ld_timelimit = atoi( line );
753                         getline( line, sizeof(line), stdin, "sizelimit?" );
754                         ld->ld_sizelimit = atoi( line );
755
756                         ld->ld_options = 0;
757
758 #ifdef STR_TRANSLATION
759                         getline( line, sizeof(line), stdin,
760                                 "Automatic translation of T.61 strings (0=no, 1=yes)?" );
761                         if ( atoi( line ) == 0 ) {
762                                 ld->ld_lberoptions &= ~LBER_TRANSLATE_STRINGS;
763                         } else {
764                                 ld->ld_lberoptions |= LBER_TRANSLATE_STRINGS;
765 #ifdef LDAP_CHARSET_8859
766                                 getline( line, sizeof(line), stdin,
767                                         "Translate to/from ISO-8859 (0=no, 1=yes?" );
768                                 if ( atoi( line ) != 0 ) {
769                                         ldap_set_string_translators( ld,
770                                             ldap_8859_to_t61,
771                                             ldap_t61_to_8859 );
772                                 }
773 #endif /* LDAP_CHARSET_8859 */
774                         }
775 #endif /* STR_TRANSLATION */
776
777 #ifdef LDAP_DNS
778                         getline( line, sizeof(line), stdin,
779                                 "Use DN & DNS to determine where to send requests (0=no, 1=yes)?" );
780                         if ( atoi( line ) != 0 ) {
781                                 ld->ld_options |= LDAP_OPT_DNS;
782                         }
783 #endif /* LDAP_DNS */
784
785 #ifdef LDAP_REFERRALS
786                         getline( line, sizeof(line), stdin,
787                                 "Recognize and chase referrals (0=no, 1=yes)?" );
788                         if ( atoi( line ) != 0 ) {
789                                 ld->ld_options |= LDAP_OPT_REFERRALS;
790                                 getline( line, sizeof(line), stdin,
791                                         "Prompt for bind credentials when chasing referrals (0=no, 1=yes)?" );
792                                 if ( atoi( line ) != 0 ) {
793                                         ldap_set_rebind_proc( ld, bind_prompt );
794                                 }
795                         }
796 #endif /* LDAP_REFERRALS */
797                         break;
798
799                 case 'O':       /* set cache options */
800 #ifdef LDAP_NOCACHE
801                         printf( NOCACHEERRMSG );
802 #else /* LDAP_NOCACHE */
803                         getline( line, sizeof(line), stdin, "cache errors (0=smart, 1=never, 2=always)?" );
804                         switch( atoi( line )) {
805                         case 0:
806                                 ldap_set_cache_options( ld, 0 );
807                                 break;
808                         case 1:
809                                 ldap_set_cache_options( ld,
810                                         LDAP_CACHE_OPT_CACHENOERRS );
811                                 break;
812                         case 2:
813                                 ldap_set_cache_options( ld,
814                                         LDAP_CACHE_OPT_CACHEALLERRS );
815                                 break;
816                         default:
817                                 printf( "not a valid cache option\n" );
818                         }
819 #endif /* LDAP_NOCACHE */
820                         break;
821
822                 case '?':       /* help */
823     printf( "Commands: [ad]d         [ab]andon         [b]ind\n" );
824     printf( "          [B]ind async  [c]ompare         [l]URL search\n" );
825     printf( "          [modi]fy      [modr]dn          [rem]ove\n" );
826     printf( "          [res]ult      [s]earch          [q]uit/unbind\n\n" );
827     printf( "          [u]fn search  [ut]fn search with timeout\n" );
828     printf( "          [d]ebug       [e]nable cache    set ms[g]id\n" );
829     printf( "          d[n]suffix    [t]imeout         [v]ersion\n" );
830     printf( "          [U]fn prefix  [x]uncache entry  [X]uncache request\n" );
831     printf( "          [?]help       [o]ptions         [O]cache options\n" );
832     printf( "          [E]xplode dn  [p]arse LDAP URL\n" );
833                         break;
834
835                 default:
836                         printf( "Invalid command.  Type ? for help.\n" );
837                         break;
838                 }
839
840                 (void) memset( line, '\0', sizeof(line) );
841         }
842
843         return( 0 );
844 }
845
846 static void
847 handle_result( LDAP *ld, LDAPMessage *lm )
848 {
849         switch ( lm->lm_msgtype ) {
850         case LDAP_RES_COMPARE:
851                 printf( "Compare result\n" );
852                 print_ldap_result( ld, lm, "compare" );
853                 break;
854
855         case LDAP_RES_SEARCH_RESULT:
856                 printf( "Search result\n" );
857                 print_ldap_result( ld, lm, "search" );
858                 break;
859
860         case LDAP_RES_SEARCH_ENTRY:
861                 printf( "Search entry\n" );
862                 print_search_entry( ld, lm );
863                 break;
864
865         case LDAP_RES_ADD:
866                 printf( "Add result\n" );
867                 print_ldap_result( ld, lm, "add" );
868                 break;
869
870         case LDAP_RES_DELETE:
871                 printf( "Delete result\n" );
872                 print_ldap_result( ld, lm, "delete" );
873                 break;
874
875         case LDAP_RES_MODRDN:
876                 printf( "ModRDN result\n" );
877                 print_ldap_result( ld, lm, "modrdn" );
878                 break;
879
880         case LDAP_RES_BIND:
881                 printf( "Bind result\n" );
882                 print_ldap_result( ld, lm, "bind" );
883                 break;
884
885         default:
886                 printf( "Unknown result type 0x%x\n", lm->lm_msgtype );
887                 print_ldap_result( ld, lm, "unknown" );
888         }
889 }
890
891 static void
892 print_ldap_result( LDAP *ld, LDAPMessage *lm, char *s )
893 {
894         ldap_result2error( ld, lm, 1 );
895         ldap_perror( ld, s );
896 /*
897         if ( ld->ld_error != NULL && *ld->ld_error != '\0' )
898                 fprintf( stderr, "Additional info: %s\n", ld->ld_error );
899         if ( NAME_ERROR( ld->ld_errno ) && ld->ld_matched != NULL )
900                 fprintf( stderr, "Matched DN: %s\n", ld->ld_matched );
901 */
902 }
903
904 static void
905 print_search_entry( LDAP *ld, LDAPMessage *res )
906 {
907         BerElement      *ber;
908         char            *a, *dn, *ufn;
909         struct berval   **vals;
910         int             i;
911         LDAPMessage     *e;
912
913         for ( e = ldap_first_entry( ld, res ); e != NULLMSG;
914             e = ldap_next_entry( ld, e ) ) {
915                 if ( e->lm_msgtype == LDAP_RES_SEARCH_RESULT )
916                         break;
917
918                 dn = ldap_get_dn( ld, e );
919                 printf( "\tDN: %s\n", dn );
920
921                 ufn = ldap_dn2ufn( dn );
922                 printf( "\tUFN: %s\n", ufn );
923
924                 free( dn );
925                 free( ufn );
926
927                 for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL;
928                     a = ldap_next_attribute( ld, e, ber ) ) {
929                         printf( "\t\tATTR: %s\n", a );
930                         if ( (vals = ldap_get_values_len( ld, e, a ))
931                             == NULL ) {
932                                 printf( "\t\t\t(no values)\n" );
933                         } else {
934                                 for ( i = 0; vals[i] != NULL; i++ ) {
935                                         int     j, nonascii;
936
937                                         nonascii = 0;
938                                         for ( j = 0; (unsigned long) j < vals[i]->bv_len; j++ )
939                                                 if ( !isascii( vals[i]->bv_val[j] ) ) {
940                                                         nonascii = 1;
941                                                         break;
942                                                 }
943
944                                         if ( nonascii ) {
945                                                 printf( "\t\t\tlength (%ld) (not ascii)\n", vals[i]->bv_len );
946 #ifdef BPRINT_NONASCII
947                                                 lber_bprint( vals[i]->bv_val,
948                                                     vals[i]->bv_len );
949 #endif /* BPRINT_NONASCII */
950                                                 continue;
951                                         }
952                                         printf( "\t\t\tlength (%ld) %s\n",
953                                             vals[i]->bv_len, vals[i]->bv_val );
954                                 }
955                                 ber_bvecfree( vals );
956                         }
957                 }
958         }
959
960         if ( res->lm_msgtype == LDAP_RES_SEARCH_RESULT
961             || res->lm_chain != NULLMSG )
962                 print_ldap_result( ld, res, "search" );
963 }