+ return bytes;
+}
+
+static void
+send_ldap_response(
+ Connection *conn,
+ Operation *op,
+ ber_tag_t tag,
+ ber_int_t msgid,
+ ber_int_t err,
+ const char *matched,
+ const char *text,
+ BerVarray ref,
+ const char *resoid,
+ struct berval *resdata,
+ struct berval *sasldata,
+ LDAPControl **ctrls
+)
+{
+ char berbuf[256];
+ BerElement *ber = (BerElement *)berbuf;
+ int rc;
+ long bytes;
+
+ if (op->o_callback && op->o_callback->sc_response) {
+ op->o_callback->sc_response( conn, op, tag, msgid, err, matched,
+ text, ref, resoid, resdata, sasldata, ctrls );
+ return;
+ }
+
+ assert( ctrls == NULL ); /* ctrls not implemented */
+
+ ber_init_w_nullc( ber, LBER_USE_DER );
+
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY,
+ "send_ldap_response: conn %d msgid=%ld tag=%ld err=%ld\n",
+ conn ? conn->c_connid : 0, (long)msgid, (long)tag, (long)err ));
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "send_ldap_response: msgid=%ld tag=%ld err=%ld\n",
+ (long) msgid, (long) tag, (long) err );
+#endif
+
+ if( ref ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "operation", LDAP_LEVEL_ARGS,
+ "send_ldap_response: conn %d ref=\"%s\"\n",
+ conn ? conn->c_connid : 0,
+ ref[0].bv_val ? ref[0].bv_val : "NULL" ));
+#else
+ Debug( LDAP_DEBUG_ARGS, "send_ldap_response: ref=\"%s\"\n",
+ ref[0].bv_val ? ref[0].bv_val : "NULL",
+ NULL, NULL );
+#endif
+
+ }
+
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp) {
+ rc = ber_write(ber, (char *)&op->o_peeraddr, sizeof(struct sockaddr), 0);
+ if (rc != sizeof(struct sockaddr)) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
+ "send_ldap_response: conn %d ber_write failed\n",
+ conn ? conn->c_connid : 0 ));
+#else
+ Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
+#endif
+ ber_free_buf( ber );
+ return;
+ }
+ }
+ if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
+ rc = ber_printf( ber, "{is{t{ess",
+ msgid, "", tag, err,
+ matched == NULL ? "" : matched,
+ text == NULL ? "" : text );
+ } else
+#endif
+ {
+ rc = ber_printf( ber, "{it{ess",
+ msgid, tag, err,
+ matched == NULL ? "" : matched,
+ text == NULL ? "" : text );
+ }
+
+ if( rc != -1 ) {
+ if ( ref != NULL ) {
+ assert( err == LDAP_REFERRAL );
+ rc = ber_printf( ber, "t{W}",
+ LDAP_TAG_REFERRAL, ref );
+ } else {
+ assert( err != LDAP_REFERRAL );
+ }
+ }
+
+ if( rc != -1 && sasldata != NULL ) {
+ rc = ber_printf( ber, "tO",
+ LDAP_TAG_SASL_RES_CREDS, sasldata );
+ }
+
+ if( rc != -1 && resoid != NULL ) {
+ rc = ber_printf( ber, "ts",
+ LDAP_TAG_EXOP_RES_OID, resoid );
+ }
+
+ if( rc != -1 && resdata != NULL ) {
+ rc = ber_printf( ber, "tO",
+ LDAP_TAG_EXOP_RES_VALUE, resdata );
+ }
+
+ if( rc != -1 ) {
+ rc = ber_printf( ber, "N}N}" );
+ }
+#ifdef LDAP_CONNECTIONLESS
+ if( conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1 ) {
+ rc = ber_printf( ber, "N}" );
+ }
+#endif
+
+ if ( rc == -1 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
+ "send_ldap_response: conn %d ber_printf failed\n",
+ conn ? conn->c_connid : 0 ));
+#else
+ Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
+#endif
+
+ ber_free_buf( ber );
+ return;
+ }
+
+ /* send BER */
+ bytes = send_ldap_ber( conn, ber );
+ ber_free_buf( ber );
+
+ if ( bytes < 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
+ "send_ldap_response: conn %d ber write failed\n",
+ conn ? conn->c_connid : 0 ));
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "send_ldap_response: ber write failed\n",
+ 0, 0, 0 );
+#endif
+
+ return;
+ }
+