Back to index

openldap  2.4.31
test.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1998-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 
00016 #include "portable.h"
00017 
00018 #include <stdio.h>
00019 
00020 #include <ac/stdlib.h>
00021 
00022 #include <ac/ctype.h>
00023 #include <ac/socket.h>
00024 #include <ac/string.h>
00025 #include <ac/time.h>
00026 #include <ac/unistd.h>
00027 
00028 #include <sys/stat.h>
00029 
00030 #ifdef HAVE_SYS_FILE_H
00031 #include <sys/file.h>
00032 #endif
00033 #ifdef HAVE_IO_H
00034 #include <io.h>
00035 #endif
00036 
00037 #include <fcntl.h>
00038 
00039 /* including the "internal" defs is legit and nec. since this test routine has 
00040  * a-priori knowledge of libldap internal workings.
00041  * hodges@stanford.edu 5-Feb-96
00042  */
00043 #include "ldap-int.h"
00044 
00045 /* local functions */
00046 static char *get_line LDAP_P(( char *line, int len, FILE *fp, const char *prompt ));
00047 static char **get_list LDAP_P(( const char *prompt ));
00048 static int file_read LDAP_P(( const char *path, struct berval *bv ));
00049 static LDAPMod **get_modlist LDAP_P(( const char *prompt1,
00050        const char *prompt2, const char *prompt3 ));
00051 static void handle_result LDAP_P(( LDAP *ld, LDAPMessage *lm ));
00052 static void print_ldap_result LDAP_P(( LDAP *ld, LDAPMessage *lm,
00053        const char *s ));
00054 static void print_search_entry LDAP_P(( LDAP *ld, LDAPMessage *res ));
00055 static void free_list LDAP_P(( char **list ));
00056 
00057 static char *dnsuffix;
00058 
00059 static char *
00060 get_line( char *line, int len, FILE *fp, const char *prompt )
00061 {
00062        fputs(prompt, stdout);
00063 
00064        if ( fgets( line, len, fp ) == NULL )
00065               return( NULL );
00066 
00067        line[ strlen( line ) - 1 ] = '\0';
00068 
00069        return( line );
00070 }
00071 
00072 static char **
00073 get_list( const char *prompt )
00074 {
00075        static char   buf[256];
00076        int           num;
00077        char          **result;
00078 
00079        num = 0;
00080        result = (char **) 0;
00081        while ( 1 ) {
00082               get_line( buf, sizeof(buf), stdin, prompt );
00083 
00084               if ( *buf == '\0' )
00085                      break;
00086 
00087               if ( result == (char **) 0 )
00088                      result = (char **) malloc( sizeof(char *) );
00089               else
00090                      result = (char **) realloc( result,
00091                          sizeof(char *) * (num + 1) );
00092 
00093               result[num++] = (char *) strdup( buf );
00094        }
00095        if ( result == (char **) 0 )
00096               return( NULL );
00097        result = (char **) realloc( result, sizeof(char *) * (num + 1) );
00098        result[num] = NULL;
00099 
00100        return( result );
00101 }
00102 
00103 
00104 static void
00105 free_list( char **list )
00106 {
00107        int    i;
00108 
00109        if ( list != NULL ) {
00110               for ( i = 0; list[ i ] != NULL; ++i ) {
00111                      free( list[ i ] );
00112               }
00113               free( (char *)list );
00114        }
00115 }
00116 
00117 
00118 static int
00119 file_read( const char *path, struct berval *bv )
00120 {
00121        FILE          *fp;
00122        ber_slen_t    rlen;
00123        int           eof;
00124 
00125        if (( fp = fopen( path, "r" )) == NULL ) {
00126               perror( path );
00127               return( -1 );
00128        }
00129 
00130        if ( fseek( fp, 0L, SEEK_END ) != 0 ) {
00131               perror( path );
00132               fclose( fp );
00133               return( -1 );
00134        }
00135 
00136        bv->bv_len = ftell( fp );
00137 
00138        if (( bv->bv_val = (char *)malloc( bv->bv_len )) == NULL ) {
00139               perror( "malloc" );
00140               fclose( fp );
00141               return( -1 );
00142        }
00143 
00144        if ( fseek( fp, 0L, SEEK_SET ) != 0 ) {
00145               perror( path );
00146               fclose( fp );
00147               return( -1 );
00148        }
00149 
00150        rlen = fread( bv->bv_val, 1, bv->bv_len, fp );
00151        eof = feof( fp );
00152        fclose( fp );
00153 
00154        if ( (ber_len_t) rlen != bv->bv_len ) {
00155               perror( path );
00156               free( bv->bv_val );
00157               return( -1 );
00158        }
00159 
00160        return( bv->bv_len );
00161 }
00162 
00163 
00164 static LDAPMod **
00165 get_modlist(
00166        const char *prompt1,
00167        const char *prompt2,
00168        const char *prompt3 )
00169 {
00170        static char   buf[256];
00171        int           num;
00172        LDAPMod              tmp = { 0 };
00173        LDAPMod              **result;
00174        struct berval **bvals;
00175 
00176        num = 0;
00177        result = NULL;
00178        while ( 1 ) {
00179               if ( prompt1 ) {
00180                      get_line( buf, sizeof(buf), stdin, prompt1 );
00181                      tmp.mod_op = atoi( buf );
00182 
00183                      if ( tmp.mod_op == -1 || buf[0] == '\0' )
00184                             break;
00185               }
00186 
00187               get_line( buf, sizeof(buf), stdin, prompt2 );
00188               if ( buf[0] == '\0' )
00189                      break;
00190               tmp.mod_type = strdup( buf );
00191 
00192               tmp.mod_values = get_list( prompt3 );
00193 
00194               if ( tmp.mod_values != NULL ) {
00195                      int    i;
00196 
00197                      for ( i = 0; tmp.mod_values[i] != NULL; ++i )
00198                             ;
00199                      bvals = (struct berval **)calloc( i + 1,
00200                          sizeof( struct berval *));
00201                      for ( i = 0; tmp.mod_values[i] != NULL; ++i ) {
00202                             bvals[i] = (struct berval *)malloc(
00203                                 sizeof( struct berval ));
00204                             if ( strncmp( tmp.mod_values[i], "{FILE}",
00205                                 6 ) == 0 ) {
00206                                    if ( file_read( tmp.mod_values[i] + 6,
00207                                        bvals[i] ) < 0 ) {
00208                                           free( bvals );
00209                                           for ( i = 0; i<num; i++ )
00210                                                  free( result[ i ] );
00211                                           free( result );
00212                                           return( NULL );
00213                                    }
00214                             } else {
00215                                    bvals[i]->bv_val = tmp.mod_values[i];
00216                                    bvals[i]->bv_len =
00217                                        strlen( tmp.mod_values[i] );
00218                             }
00219                      }
00220                      tmp.mod_bvalues = bvals;
00221                      tmp.mod_op |= LDAP_MOD_BVALUES;
00222               }
00223 
00224               if ( result == NULL )
00225                      result = (LDAPMod **) malloc( sizeof(LDAPMod *) );
00226               else
00227                      result = (LDAPMod **) realloc( result,
00228                          sizeof(LDAPMod *) * (num + 1) );
00229 
00230               result[num] = (LDAPMod *) malloc( sizeof(LDAPMod) );
00231               *(result[num]) = tmp;       /* struct copy */
00232               num++;
00233        }
00234        if ( result == NULL )
00235               return( NULL );
00236        result = (LDAPMod **) realloc( result, sizeof(LDAPMod *) * (num + 1) );
00237        result[num] = NULL;
00238 
00239        return( result );
00240 }
00241 
00242 
00243 static int
00244 bind_prompt( LDAP *ld,
00245        LDAP_CONST char *url,
00246        ber_tag_t request, ber_int_t msgid,
00247        void *params )
00248 {
00249        static char   dn[256], passwd[256];
00250        int    authmethod;
00251 
00252        printf("rebind for request=%ld msgid=%ld url=%s\n",
00253               request, (long) msgid, url );
00254 
00255        authmethod = LDAP_AUTH_SIMPLE;
00256 
00257               get_line( dn, sizeof(dn), stdin, "re-bind dn? " );
00258               strcat( dn, dnsuffix );
00259 
00260        if ( authmethod == LDAP_AUTH_SIMPLE && dn[0] != '\0' ) {
00261                      get_line( passwd, sizeof(passwd), stdin,
00262                          "re-bind password? " );
00263               } else {
00264                      passwd[0] = '\0';
00265               }
00266 
00267        return ldap_bind_s( ld, dn, passwd, authmethod);
00268 }
00269 
00270 
00271 int
00272 main( int argc, char **argv )
00273 {
00274        LDAP          *ld = NULL;
00275        int           i, c, port, errflg, method, id, msgtype;
00276        char          line[256], command1, command2, command3;
00277        char          passwd[64], dn[256], rdn[64], attr[64], value[256];
00278        char          filter[256], *host, **types;
00279        char          **exdn;
00280        static const char usage[] =
00281               "usage: %s [-u] [-h host] [-d level] [-s dnsuffix] [-p port] [-t file] [-T file]\n";
00282        int           bound, all, scope, attrsonly;
00283        LDAPMessage   *res;
00284        LDAPMod              **mods, **attrs;
00285        struct timeval       timeout;
00286        char          *copyfname = NULL;
00287        int           copyoptions = 0;
00288        LDAPURLDesc   *ludp;
00289 
00290        host = NULL;
00291        port = LDAP_PORT;
00292        dnsuffix = "";
00293        errflg = 0;
00294 
00295        while (( c = getopt( argc, argv, "h:d:s:p:t:T:" )) != -1 ) {
00296               switch( c ) {
00297               case 'd':
00298 #ifdef LDAP_DEBUG
00299                      ldap_debug = atoi( optarg );
00300 #ifdef LBER_DEBUG
00301                      if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
00302                             ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &ldap_debug );
00303                      }
00304 #endif
00305 #else
00306                      printf( "Compile with -DLDAP_DEBUG for debugging\n" );
00307 #endif
00308                      break;
00309 
00310               case 'h':
00311                      host = optarg;
00312                      break;
00313 
00314               case 's':
00315                      dnsuffix = optarg;
00316                      break;
00317 
00318               case 'p':
00319                      port = atoi( optarg );
00320                      break;
00321 
00322               case 't':     /* copy ber's to given file */
00323                      copyfname = strdup( optarg );
00324 /*                   copyoptions = LBER_TO_FILE; */
00325                      break;
00326 
00327               case 'T':     /* only output ber's to given file */
00328                      copyfname = strdup( optarg );
00329 /*                   copyoptions = (LBER_TO_FILE | LBER_TO_FILE_ONLY); */
00330                      break;
00331 
00332               default:
00333                   ++errflg;
00334               }
00335        }
00336 
00337        if ( host == NULL && optind == argc - 1 ) {
00338               host = argv[ optind ];
00339               ++optind;
00340        }
00341 
00342        if ( errflg || optind < argc - 1 ) {
00343               fprintf( stderr, usage, argv[ 0 ] );
00344               exit( EXIT_FAILURE );
00345        }
00346        
00347        printf( "ldap_init( %s, %d )\n",
00348               host == NULL ? "(null)" : host, port );
00349 
00350        ld = ldap_init( host, port );
00351 
00352        if ( ld == NULL ) {
00353               perror( "ldap_init" );
00354               exit( EXIT_FAILURE );
00355        }
00356 
00357        if ( copyfname != NULL ) {
00358               if ( ( ld->ld_sb->sb_fd = open( copyfname, O_WRONLY|O_CREAT|O_EXCL,
00359                   0600 ))  == -1 ) {
00360                      perror( copyfname );
00361                      exit ( EXIT_FAILURE );
00362               }
00363               ld->ld_sb->sb_options = copyoptions;
00364        }
00365 
00366        bound = 0;
00367        timeout.tv_sec = 0;
00368        timeout.tv_usec = 0;
00369 
00370        (void) memset( line, '\0', sizeof(line) );
00371        while ( get_line( line, sizeof(line), stdin, "\ncommand? " ) != NULL ) {
00372               command1 = line[0];
00373               command2 = line[1];
00374               command3 = line[2];
00375 
00376               switch ( command1 ) {
00377               case 'a':     /* add or abandon */
00378                      switch ( command2 ) {
00379                      case 'd':     /* add */
00380                             get_line( dn, sizeof(dn), stdin, "dn? " );
00381                             strcat( dn, dnsuffix );
00382                             if ( (attrs = get_modlist( NULL, "attr? ",
00383                                 "value? " )) == NULL )
00384                                    break;
00385                             if ( (id = ldap_add( ld, dn, attrs )) == -1 )
00386                                    ldap_perror( ld, "ldap_add" );
00387                             else
00388                                    printf( "Add initiated with id %d\n",
00389                                        id );
00390                             break;
00391 
00392                      case 'b':     /* abandon */
00393                             get_line( line, sizeof(line), stdin, "msgid? " );
00394                             id = atoi( line );
00395                             if ( ldap_abandon( ld, id ) != 0 )
00396                                    ldap_perror( ld, "ldap_abandon" );
00397                             else
00398                                    printf( "Abandon successful\n" );
00399                             break;
00400                      default:
00401                             printf( "Possibilities: [ad]d, [ab]ort\n" );
00402                      }
00403                      break;
00404 
00405               case 'b':     /* asynch bind */
00406                      method = LDAP_AUTH_SIMPLE;
00407                      get_line( dn, sizeof(dn), stdin, "dn? " );
00408                      strcat( dn, dnsuffix );
00409 
00410                      if ( method == LDAP_AUTH_SIMPLE && dn[0] != '\0' )
00411                             get_line( passwd, sizeof(passwd), stdin,
00412                                 "password? " );
00413                      else
00414                             passwd[0] = '\0';
00415 
00416                      if ( ldap_bind( ld, dn, passwd, method ) == -1 ) {
00417                             fprintf( stderr, "ldap_bind failed\n" );
00418                             ldap_perror( ld, "ldap_bind" );
00419                      } else {
00420                             printf( "Bind initiated\n" );
00421                             bound = 1;
00422                      }
00423                      break;
00424 
00425               case 'B':     /* synch bind */
00426                      method = LDAP_AUTH_SIMPLE;
00427                      get_line( dn, sizeof(dn), stdin, "dn? " );
00428                      strcat( dn, dnsuffix );
00429 
00430                      if ( dn[0] != '\0' )
00431                             get_line( passwd, sizeof(passwd), stdin,
00432                                 "password? " );
00433                      else
00434                             passwd[0] = '\0';
00435 
00436                      if ( ldap_bind_s( ld, dn, passwd, method ) !=
00437                          LDAP_SUCCESS ) {
00438                             fprintf( stderr, "ldap_bind_s failed\n" );
00439                             ldap_perror( ld, "ldap_bind_s" );
00440                      } else {
00441                             printf( "Bind successful\n" );
00442                             bound = 1;
00443                      }
00444                      break;
00445 
00446               case 'c':     /* compare */
00447                      get_line( dn, sizeof(dn), stdin, "dn? " );
00448                      strcat( dn, dnsuffix );
00449                      get_line( attr, sizeof(attr), stdin, "attr? " );
00450                      get_line( value, sizeof(value), stdin, "value? " );
00451 
00452                      if ( (id = ldap_compare( ld, dn, attr, value )) == -1 )
00453                             ldap_perror( ld, "ldap_compare" );
00454                      else
00455                             printf( "Compare initiated with id %d\n", id );
00456                      break;
00457 
00458               case 'd':     /* turn on debugging */
00459 #ifdef LDAP_DEBUG
00460                      get_line( line, sizeof(line), stdin, "debug level? " );
00461                      ldap_debug = atoi( line );
00462 #ifdef LBER_DEBUG
00463                      if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
00464                             ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &ldap_debug );
00465                      }
00466 #endif
00467 #else
00468                      printf( "Compile with -DLDAP_DEBUG for debugging\n" );
00469 #endif
00470                      break;
00471 
00472               case 'E':     /* explode a dn */
00473                      get_line( line, sizeof(line), stdin, "dn? " );
00474                      exdn = ldap_explode_dn( line, 0 );
00475                      for ( i = 0; exdn != NULL && exdn[i] != NULL; i++ ) {
00476                             printf( "\t%s\n", exdn[i] );
00477                      }
00478                      break;
00479 
00480               case 'g':     /* set next msgid */
00481                      get_line( line, sizeof(line), stdin, "msgid? " );
00482                      ld->ld_msgid = atoi( line );
00483                      break;
00484 
00485               case 'v':     /* set version number */
00486                      get_line( line, sizeof(line), stdin, "version? " );
00487                      ld->ld_version = atoi( line );
00488                      break;
00489 
00490               case 'm':     /* modify or modifyrdn */
00491                      if ( strncmp( line, "modify", 4 ) == 0 ) {
00492                             get_line( dn, sizeof(dn), stdin, "dn? " );
00493                             strcat( dn, dnsuffix );
00494                             if ( (mods = get_modlist(
00495                                 "mod (0=>add, 1=>delete, 2=>replace -1=>done)? ",
00496                                 "attribute type? ", "attribute value? " ))
00497                                 == NULL )
00498                                    break;
00499                             if ( (id = ldap_modify( ld, dn, mods )) == -1 )
00500                                    ldap_perror( ld, "ldap_modify" );
00501                             else
00502                                    printf( "Modify initiated with id %d\n",
00503                                        id );
00504                      } else if ( strncmp( line, "modrdn", 4 ) == 0 ) {
00505                             get_line( dn, sizeof(dn), stdin, "dn? " );
00506                             strcat( dn, dnsuffix );
00507                             get_line( rdn, sizeof(rdn), stdin, "newrdn? " );
00508                             if ( (id = ldap_modrdn( ld, dn, rdn )) == -1 )
00509                                    ldap_perror( ld, "ldap_modrdn" );
00510                             else
00511                                    printf( "Modrdn initiated with id %d\n",
00512                                        id );
00513                      } else {
00514                             printf( "Possibilities: [modi]fy, [modr]dn\n" );
00515                      }
00516                      break;
00517 
00518               case 'q':     /* quit */
00519                      ldap_unbind( ld );
00520                      exit( EXIT_SUCCESS );
00521                      break;
00522 
00523               case 'r':     /* result or remove */
00524                      switch ( command3 ) {
00525                      case 's':     /* result */
00526                             get_line( line, sizeof(line), stdin,
00527                                 "msgid (-1=>any)? " );
00528                             if ( line[0] == '\0' )
00529                                    id = -1;
00530                             else
00531                                    id = atoi( line );
00532                             get_line( line, sizeof(line), stdin,
00533                                 "all (0=>any, 1=>all)? " );
00534                             if ( line[0] == '\0' )
00535                                    all = 1;
00536                             else
00537                                    all = atoi( line );
00538                             if (( msgtype = ldap_result( ld, id, all,
00539                                 &timeout, &res )) < 1 ) {
00540                                    ldap_perror( ld, "ldap_result" );
00541                                    break;
00542                             }
00543                             printf( "\nresult: msgtype %d msgid %d\n",
00544                                 msgtype, res->lm_msgid );
00545                             handle_result( ld, res );
00546                             res = NULL;
00547                             break;
00548 
00549                      case 'm':     /* remove */
00550                             get_line( dn, sizeof(dn), stdin, "dn? " );
00551                             strcat( dn, dnsuffix );
00552                             if ( (id = ldap_delete( ld, dn )) == -1 )
00553                                    ldap_perror( ld, "ldap_delete" );
00554                             else
00555                                    printf( "Remove initiated with id %d\n",
00556                                        id );
00557                             break;
00558 
00559                      default:
00560                             printf( "Possibilities: [rem]ove, [res]ult\n" );
00561                             break;
00562                      }
00563                      break;
00564 
00565               case 's':     /* search */
00566                      get_line( dn, sizeof(dn), stdin, "searchbase? " );
00567                      strcat( dn, dnsuffix );
00568                      get_line( line, sizeof(line), stdin,
00569                          "scope (0=baseObject, 1=oneLevel, 2=subtree, 3=children)? " );
00570                      scope = atoi( line );
00571                      get_line( filter, sizeof(filter), stdin,
00572                          "search filter (e.g. sn=jones)? " );
00573                      types = get_list( "attrs to return? " );
00574                      get_line( line, sizeof(line), stdin,
00575                          "attrsonly (0=attrs&values, 1=attrs only)? " );
00576                      attrsonly = atoi( line );
00577 
00578                          if (( id = ldap_search( ld, dn, scope, filter,
00579                                 types, attrsonly  )) == -1 ) {
00580                             ldap_perror( ld, "ldap_search" );
00581                          } else {
00582                             printf( "Search initiated with id %d\n", id );
00583                          }
00584                      free_list( types );
00585                      break;
00586 
00587               case 't':     /* set timeout value */
00588                      get_line( line, sizeof(line), stdin, "timeout? " );
00589                      timeout.tv_sec = atoi( line );
00590                      break;
00591 
00592               case 'p':     /* parse LDAP URL */
00593                      get_line( line, sizeof(line), stdin, "LDAP URL? " );
00594                      if (( i = ldap_url_parse( line, &ludp )) != 0 ) {
00595                          fprintf( stderr, "ldap_url_parse: error %d\n", i );
00596                      } else {
00597                          printf( "\t  host: " );
00598                          if ( ludp->lud_host == NULL ) {
00599                             printf( "DEFAULT\n" );
00600                          } else {
00601                             printf( "<%s>\n", ludp->lud_host );
00602                          }
00603                          printf( "\t  port: " );
00604                          if ( ludp->lud_port == 0 ) {
00605                             printf( "DEFAULT\n" );
00606                          } else {
00607                             printf( "%d\n", ludp->lud_port );
00608                          }
00609                          printf( "\t    dn: <%s>\n", ludp->lud_dn );
00610                          printf( "\t attrs:" );
00611                          if ( ludp->lud_attrs == NULL ) {
00612                             printf( " ALL" );
00613                          } else {
00614                             for ( i = 0; ludp->lud_attrs[ i ] != NULL; ++i ) {
00615                                 printf( " <%s>", ludp->lud_attrs[ i ] );
00616                             }
00617                          }
00618                          printf( "\n\t scope: %s\n",
00619                                    ludp->lud_scope == LDAP_SCOPE_BASE ? "baseObject"
00620                                    : ludp->lud_scope == LDAP_SCOPE_ONELEVEL ? "oneLevel"
00621                                    : ludp->lud_scope == LDAP_SCOPE_SUBTREE ? "subtree"
00622 #ifdef LDAP_SCOPE_SUBORDINATE
00623                                    : ludp->lud_scope == LDAP_SCOPE_SUBORDINATE ? "children"
00624 #endif
00625                                    : "**invalid**" );
00626                          printf( "\tfilter: <%s>\n", ludp->lud_filter );
00627                          ldap_free_urldesc( ludp );
00628                      }
00629                          break;
00630 
00631               case 'n':     /* set dn suffix, for convenience */
00632                      get_line( line, sizeof(line), stdin, "DN suffix? " );
00633                      strcpy( dnsuffix, line );
00634                      break;
00635 
00636               case 'o':     /* set ldap options */
00637                      get_line( line, sizeof(line), stdin, "alias deref (0=never, 1=searching, 2=finding, 3=always)?" );
00638                      ld->ld_deref = atoi( line );
00639                      get_line( line, sizeof(line), stdin, "timelimit?" );
00640                      ld->ld_timelimit = atoi( line );
00641                      get_line( line, sizeof(line), stdin, "sizelimit?" );
00642                      ld->ld_sizelimit = atoi( line );
00643 
00644                      LDAP_BOOL_ZERO(&ld->ld_options);
00645 
00646                      get_line( line, sizeof(line), stdin,
00647                             "Recognize and chase referrals (0=no, 1=yes)?" );
00648                      if ( atoi( line ) != 0 ) {
00649                             LDAP_BOOL_SET(&ld->ld_options, LDAP_BOOL_REFERRALS);
00650                             get_line( line, sizeof(line), stdin,
00651                                    "Prompt for bind credentials when chasing referrals (0=no, 1=yes)?" );
00652                             if ( atoi( line ) != 0 ) {
00653                                    ldap_set_rebind_proc( ld, bind_prompt, NULL );
00654                             }
00655                      }
00656                      break;
00657 
00658               case '?':     /* help */
00659                      printf(
00660 "Commands: [ad]d         [ab]andon         [b]ind\n"
00661 "          [B]ind async  [c]ompare\n"
00662 "          [modi]fy      [modr]dn          [rem]ove\n"
00663 "          [res]ult      [s]earch          [q]uit/unbind\n\n"
00664 "          [d]ebug       set ms[g]id\n"
00665 "          d[n]suffix    [t]imeout         [v]ersion\n"
00666 "          [?]help       [o]ptions"
00667 "          [E]xplode dn  [p]arse LDAP URL\n" );
00668                      break;
00669 
00670               default:
00671                      printf( "Invalid command.  Type ? for help.\n" );
00672                      break;
00673               }
00674 
00675               (void) memset( line, '\0', sizeof(line) );
00676        }
00677 
00678        return( 0 );
00679 }
00680 
00681 static void
00682 handle_result( LDAP *ld, LDAPMessage *lm )
00683 {
00684        switch ( lm->lm_msgtype ) {
00685        case LDAP_RES_COMPARE:
00686               printf( "Compare result\n" );
00687               print_ldap_result( ld, lm, "compare" );
00688               break;
00689 
00690        case LDAP_RES_SEARCH_RESULT:
00691               printf( "Search result\n" );
00692               print_ldap_result( ld, lm, "search" );
00693               break;
00694 
00695        case LDAP_RES_SEARCH_ENTRY:
00696               printf( "Search entry\n" );
00697               print_search_entry( ld, lm );
00698               break;
00699 
00700        case LDAP_RES_ADD:
00701               printf( "Add result\n" );
00702               print_ldap_result( ld, lm, "add" );
00703               break;
00704 
00705        case LDAP_RES_DELETE:
00706               printf( "Delete result\n" );
00707               print_ldap_result( ld, lm, "delete" );
00708               break;
00709 
00710        case LDAP_RES_MODRDN:
00711               printf( "ModRDN result\n" );
00712               print_ldap_result( ld, lm, "modrdn" );
00713               break;
00714 
00715        case LDAP_RES_BIND:
00716               printf( "Bind result\n" );
00717               print_ldap_result( ld, lm, "bind" );
00718               break;
00719 
00720        default:
00721               printf( "Unknown result type 0x%lx\n",
00722                       (unsigned long) lm->lm_msgtype );
00723               print_ldap_result( ld, lm, "unknown" );
00724        }
00725 }
00726 
00727 static void
00728 print_ldap_result( LDAP *ld, LDAPMessage *lm, const char *s )
00729 {
00730        ldap_result2error( ld, lm, 1 );
00731        ldap_perror( ld, s );
00732 /*
00733        if ( ld->ld_error != NULL && *ld->ld_error != '\0' )
00734               fprintf( stderr, "Additional info: %s\n", ld->ld_error );
00735        if ( LDAP_NAME_ERROR( ld->ld_errno ) && ld->ld_matched != NULL )
00736               fprintf( stderr, "Matched DN: %s\n", ld->ld_matched );
00737 */
00738 }
00739 
00740 static void
00741 print_search_entry( LDAP *ld, LDAPMessage *res )
00742 {
00743        LDAPMessage   *e;
00744 
00745        for ( e = ldap_first_entry( ld, res ); e != NULL;
00746            e = ldap_next_entry( ld, e ) )
00747        {
00748               BerElement    *ber = NULL;
00749               char *a, *dn, *ufn;
00750 
00751               if ( e->lm_msgtype == LDAP_RES_SEARCH_RESULT )
00752                      break;
00753 
00754               dn = ldap_get_dn( ld, e );
00755               printf( "\tDN: %s\n", dn );
00756 
00757               ufn = ldap_dn2ufn( dn );
00758               printf( "\tUFN: %s\n", ufn );
00759 
00760               free( dn );
00761               free( ufn );
00762 
00763               for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL;
00764                   a = ldap_next_attribute( ld, e, ber ) )
00765               {
00766                      struct berval **vals;
00767 
00768                      printf( "\t\tATTR: %s\n", a );
00769                      if ( (vals = ldap_get_values_len( ld, e, a ))
00770                          == NULL ) {
00771                             printf( "\t\t\t(no values)\n" );
00772                      } else {
00773                             int i;
00774                             for ( i = 0; vals[i] != NULL; i++ ) {
00775                                    int    j, nonascii;
00776 
00777                                    nonascii = 0;
00778                                    for ( j = 0; (ber_len_t) j < vals[i]->bv_len; j++ )
00779                                           if ( !isascii( vals[i]->bv_val[j] ) ) {
00780                                                  nonascii = 1;
00781                                                  break;
00782                                           }
00783 
00784                                    if ( nonascii ) {
00785                                           printf( "\t\t\tlength (%ld) (not ascii)\n", vals[i]->bv_len );
00786 #ifdef BPRINT_NONASCII
00787                                           ber_bprint( vals[i]->bv_val,
00788                                               vals[i]->bv_len );
00789 #endif /* BPRINT_NONASCII */
00790                                           continue;
00791                                    }
00792                                    printf( "\t\t\tlength (%ld) %s\n",
00793                                        vals[i]->bv_len, vals[i]->bv_val );
00794                             }
00795                             ber_bvecfree( vals );
00796                      }
00797               }
00798 
00799               if(ber != NULL) {
00800                      ber_free( ber, 0 );
00801               }
00802        }
00803 
00804        if ( res->lm_msgtype == LDAP_RES_SEARCH_RESULT
00805            || res->lm_chain != NULL )
00806               print_ldap_result( ld, res, "search" );
00807 }