ldns_rr2buffer_str_fmt(ldns_buffer *output, 
		const ldns_output_format *fmt, const ldns_rr *rr)
{
	uint16_t i, flags;
	ldns_status status = LDNS_STATUS_OK;

	if (fmt == NULL) {
		fmt = ldns_output_format_default;
	}
	if (!rr) {
		if (LDNS_COMMENT_NULLS & fmt->flags) {
			ldns_buffer_printf(output, "; (null)\n");
		}
		return ldns_buffer_status(output);
	}
	if (ldns_rr_owner(rr)) {
		status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
	}
	if (status != LDNS_STATUS_OK) {
		return status;
	}

	/* TTL should NOT be printed if it is a question */
	if (!ldns_rr_is_question(rr)) {
		ldns_buffer_printf(output, "\t%d", ldns_rr_ttl(rr));
	}

	ldns_buffer_printf(output, "\t");
	status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
	if (status != LDNS_STATUS_OK) {
		return status;
	}
	ldns_buffer_printf(output, "\t");

	status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
	if (status != LDNS_STATUS_OK) {
		return status;
	}

	if (ldns_rr_rd_count(rr) > 0) {
		ldns_buffer_printf(output, "\t");
	} else if (!ldns_rr_is_question(rr)) {
		ldns_buffer_printf(output, "\t\\# 0");
	}

	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
		/* ldns_rdf2buffer_str handles NULL input fine! */
		if ((fmt->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
				((/* inception  */ i == 4 &&
				  ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) == 
							LDNS_RDF_TYPE_TIME) ||
				  (/* expiration */ i == 5 &&
				   ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
				   			LDNS_RDF_TYPE_TIME) ||
				  (/* signature  */ i == 8 &&
				   ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
				   			LDNS_RDF_TYPE_B64))) {

			ldns_buffer_printf(output, "(null)");
			status = ldns_buffer_status(output);
		} else if ((fmt->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
				/* serial */ i == 2 &&
			 	ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
			 				LDNS_RDF_TYPE_INT32) {
			ldns_buffer_printf(output, "%10lu",
				(unsigned long) ldns_read_uint32(
					ldns_rdf_data(ldns_rr_rdf(rr, 2))));
			status = ldns_buffer_status(output);
		} else {
			status = ldns_rdf2buffer_str(output,
					ldns_rr_rdf(rr, i));
		}
		if(status != LDNS_STATUS_OK)
			return status;
		if (i < ldns_rr_rd_count(rr) - 1) {
			ldns_buffer_printf(output, " ");
		}
	}
	/* per RR special comments - handy for DNSSEC types */
	/* check to prevent question sec. rr from
	 * getting here */
	if (ldns_rr_rd_count(rr) > 0) {
		switch (ldns_rr_get_type(rr)) {
			case LDNS_RR_TYPE_DNSKEY:
				/* if ldns_rr_rd_count(rr) > 0
				   then ldns_rr_rdf(rr, 0) exists! */
				if (! (fmt->flags & LDNS_COMMENT_KEY)) {
					break;
				}
				flags = ldns_rdf2native_int16(
						ldns_rr_rdf(rr, 0));
				ldns_buffer_printf(output, " ;{");
				if (fmt->flags & LDNS_COMMENT_KEY_ID) {
					ldns_buffer_printf(output, "id = %u",
							(unsigned int)
							ldns_calc_keytag(rr));
				}
				if ((fmt->flags & LDNS_COMMENT_KEY_TYPE)
						&& (flags & LDNS_KEY_ZONE_KEY)){
					if (flags & LDNS_KEY_SEP_KEY) {
						ldns_buffer_printf(
							output, " (ksk)");
					}
					else {
						ldns_buffer_printf(
							output, " (zsk)");
					}
					if (fmt->flags & LDNS_COMMENT_KEY_SIZE){
						ldns_buffer_printf(
							output, ", ");
					}
				} else if (fmt->flags
						& (LDNS_COMMENT_KEY_ID
						  |LDNS_COMMENT_KEY_SIZE)) {
					ldns_buffer_printf( output, ", ");
				}
				if (fmt->flags & LDNS_COMMENT_KEY_SIZE) {
					ldns_buffer_printf(output, "size = %db",
						ldns_rr_dnskey_key_size(rr));
				}
				ldns_buffer_printf(output, "}");
				break;
			case LDNS_RR_TYPE_RRSIG:
				if ((fmt->flags & LDNS_COMMENT_KEY)
						&& (fmt->flags 
							& LDNS_COMMENT_RRSIGS)
						&& ldns_rr_rdf(rr, 6) != NULL) {
					ldns_buffer_printf(output
						, " ;{id = %d}"
						, ldns_rdf2native_int16(
							ldns_rr_rdf(rr, 6)));
				}
				break;
			case LDNS_RR_TYPE_DS:
				if ((fmt->flags & LDNS_COMMENT_BUBBLEBABBLE)
						&& ldns_rr_rdf(rr, 3) != NULL) {
					uint8_t *data = ldns_rdf_data(
							ldns_rr_rdf(rr, 3));
					size_t len = ldns_rdf_size(
							ldns_rr_rdf(rr, 3));
					char *babble = ldns_bubblebabble(
							data, len);
					if(babble) {
						ldns_buffer_printf(output
							, " ;{%s}", babble);
					}
					LDNS_FREE(babble);
				}
				break;
			case LDNS_RR_TYPE_NSEC3:
				if (! (fmt->flags & LDNS_COMMENT_FLAGS) &&
				    ! (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
					break;
				}
				ldns_buffer_printf(output, " ;{");
				if ((fmt->flags & LDNS_COMMENT_FLAGS)) {
					if (ldns_nsec3_optout(rr)) {
						ldns_buffer_printf(output,
							" flags: optout");
					} else {
						ldns_buffer_printf(output,
							" flags: -");
					}
					if (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN
							&& fmt->data != NULL) {
						ldns_buffer_printf(output, ", ");
					}
				}
				if (fmt->flags & LDNS_COMMENT_NSEC3_CHAIN
						&& fmt->data != NULL) {
					ldns_rbnode_t *node;
					ldns_rdf *key = ldns_dname_label(
							ldns_rr_owner(rr), 0);
					if (key) {
				       		node = ldns_rbtree_search(
							(ldns_rbtree_t *)
								fmt->data,
							(void *) key);
						if (node->data) {
							ldns_buffer_printf(
								output,
							       	"from: ");
							(void)
							ldns_rdf2buffer_str(
								output, 
								(ldns_rdf *)
								node->data);
						}
						ldns_rdf_free(key);
					}
					key = ldns_b32_ext2dname(
						ldns_nsec3_next_owner(rr));
					if (key) {
						node = ldns_rbtree_search(
							(ldns_rbtree_t *)
								fmt->data,
							(void *) key);
						if (node->data) {
							ldns_buffer_printf(
								output,
								" to: ");
							(void)
							ldns_rdf2buffer_str(
								output, 
								(ldns_rdf *)
								node->data);
						}
						ldns_rdf_free(key);
					}
				}
				ldns_buffer_printf(output, "}");
				break;
			default:
				break;

		}
	}
	/* last */
	ldns_buffer_printf(output, "\n");
	return ldns_buffer_status(output);
}