+ if( ldif < 2 ) {
+ printf("# search reference\n");
+ }
+
+ rc = ldap_parse_reference( ld, reference, &refs, &ctrls, 0 );
+
+ if( rc != LDAP_SUCCESS ) {
+ ldap_perror(ld, "ldap_parse_reference");
+ exit( EXIT_FAILURE );
+ }
+
+ if( refs ) {
+ int i;
+ for( i=0; refs[i] != NULL; i++ ) {
+ write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
+ "ref", refs[i], strlen(refs[i]) );
+ }
+ ber_memvfree( (void **) refs );
+ }
+
+ if( ctrls ) {
+ print_ctrls( ctrls );
+ ldap_controls_free( ctrls );
+ }
+}
+
+static void print_extended(
+ LDAP *ld,
+ LDAPMessage *extended )
+{
+ int rc;
+ char *retoid = NULL;
+ struct berval *retdata = NULL;
+
+ if( ldif < 2 ) {
+ printf("# extended result response\n");
+ }
+
+ rc = ldap_parse_extended_result( ld, extended,
+ &retoid, &retdata, 0 );
+
+ if( rc != LDAP_SUCCESS ) {
+ ldap_perror(ld, "ldap_parse_extended_result");
+ exit( EXIT_FAILURE );
+ }
+
+ write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
+ "extended", retoid, retoid ? strlen(retoid) : 0 );
+ ber_memfree( retoid );
+
+ if(retdata) {
+ write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
+ "data", retdata->bv_val, retdata->bv_len );
+ ber_bvfree( retdata );
+ }
+
+ print_result( ld, extended, 0 );
+}
+
+static void print_partial(
+ LDAP *ld,
+ LDAPMessage *partial )
+{
+ int rc;
+ char *retoid = NULL;
+ struct berval *retdata = NULL;
+ LDAPControl **ctrls = NULL;
+
+ if( ldif < 2 ) {
+ printf("# extended partial response\n");
+ }
+
+ rc = ldap_parse_extended_partial( ld, partial,
+ &retoid, &retdata, &ctrls, 0 );
+
+ if( rc != LDAP_SUCCESS ) {
+ ldap_perror(ld, "ldap_parse_extended_partial");
+ exit( EXIT_FAILURE );
+ }
+
+ write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
+ "partial", retoid, retoid ? strlen(retoid) : 0 );
+
+ ber_memfree( retoid );
+
+ if( retdata ) {
+ write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_BINARY,
+ "data",
+ retdata->bv_val, retdata->bv_len );
+
+ ber_bvfree( retdata );
+ }
+
+ if( ctrls ) {
+ print_ctrls( ctrls );
+ ldap_controls_free( ctrls );
+ }
+}
+
+static int print_result(
+ LDAP *ld,
+ LDAPMessage *result, int search )
+{
+ char rst[BUFSIZ];
+ int rc;
+ int err;
+ char *matcheddn = NULL;
+ char *text = NULL;
+ char **refs = NULL;
+ LDAPControl **ctrls = NULL;
+
+ if( search ) {
+ if ( ldif < 2 ) {
+ printf("# search result\n");
+ }
+ if ( ldif < 1 ) {
+ printf("%s: %d\n", "search", ldap_msgid(result) );
+ }
+ }
+
+ rc = ldap_parse_result( ld, result,
+ &err, &matcheddn, &text, &refs, &ctrls, 0 );
+
+ if( rc != LDAP_SUCCESS ) {
+ ldap_perror(ld, "ldap_parse_result");
+ exit( EXIT_FAILURE );
+ }
+
+
+ if( !ldif ) {
+ printf( "result: %d %s\n", err, ldap_err2string(err) );
+
+ } else if ( err != LDAP_SUCCESS ) {
+ fprintf( stderr, "%s (%d)\n", ldap_err2string(err), err );
+ }
+
+ if( matcheddn && *matcheddn ) {
+ if( !ldif ) {
+ write_ldif( LDIF_PUT_VALUE,
+ "matchedDN", matcheddn, strlen(matcheddn) );
+ } else {
+ fprintf( stderr, "Matched DN: %s\n", matcheddn );
+ }
+
+ ber_memfree( matcheddn );
+ }
+
+ if( text && *text ) {
+ if( !ldif ) {
+ write_ldif( LDIF_PUT_TEXT, "text",
+ text, strlen(text) );
+ } else {
+ fprintf( stderr, "Additional information: %s\n", text );
+ }
+
+ ber_memfree( text );
+ }
+
+ if( refs ) {
+ int i;
+ for( i=0; refs[i] != NULL; i++ ) {
+ if( !ldif ) {
+ write_ldif( LDIF_PUT_VALUE, "ref", refs[i], strlen(refs[i]) );
+ } else {
+ fprintf( stderr, "Referral: %s\n", refs[i] );
+ }
+ }
+
+ ber_memvfree( (void **) refs );
+ }
+
+ if( ctrls ) {
+ print_ctrls( ctrls );
+ ldap_controls_free( ctrls );
+ }
+
+ return err;
+}
+
+void print_ctrls( LDAPControl **ctrls ) {
+ int i;
+ for(i=0; ctrls[i] != NULL; i++ ) {
+ /* control: OID criticality base64value */
+ struct berval *b64 = NULL;
+ ber_len_t len;
+ char *str;
+
+ len = strlen( ctrls[i]->ldctl_oid );
+
+ /* add enough for space after OID and the critical value itself */
+ len += ctrls[i]->ldctl_iscritical
+ ? sizeof("true") : sizeof("false");
+
+ /* convert to base64 */
+ if( ctrls[i]->ldctl_value.bv_len ) {
+ b64 = ber_memalloc( sizeof(struct berval) );
+
+ b64->bv_len = LUTIL_BASE64_ENCODE_LEN(
+ ctrls[i]->ldctl_value.bv_len ) + 1;
+ b64->bv_val = ber_memalloc( b64->bv_len + 1 );
+
+ b64->bv_len = lutil_b64_ntop(
+ ctrls[i]->ldctl_value.bv_val, ctrls[i]->ldctl_value.bv_len,
+ b64->bv_val, b64->bv_len );
+ }
+
+ if( b64 ) {
+ len += 1 + b64->bv_len;
+ }
+
+ str = malloc( len + 1 );
+ strcpy( str, ctrls[i]->ldctl_oid );
+ strcat( str, ctrls[i]->ldctl_iscritical
+ ? " true" : " false" );
+
+ if( b64 ) {
+ strcat(str, " ");
+ strcat(str, b64->bv_val );
+ }
+
+ write_ldif( ldif ? LDIF_PUT_COMMENT : LDIF_PUT_VALUE,
+ "control", str, len );
+
+ free( str );
+ ber_bvfree( b64 );
+ }
+}
+
+static int
+write_ldif( int type, char *name, char *value, ber_len_t vallen )