static bool print_admin_msg(THD* thd, uint len,
                            const char* msg_type,
                            const char* db_name, String &table_name,
                            const char* op_name, const char *fmt, ...)
{
  va_list args;
  Protocol *protocol= thd->protocol;
  uint length;
  uint msg_length;
  char name[SAFE_NAME_LEN*2+2];
  char *msgbuf;
  bool error= true;

  if (!(msgbuf= (char*) my_malloc(len, MYF(0))))
    return true;
  va_start(args, fmt);
  msg_length= my_vsnprintf(msgbuf, len, fmt, args);
  va_end(args);
  if (msg_length >= (len - 1))
    goto err;
  msgbuf[len - 1] = 0; // healthy paranoia


  if (!thd->vio_ok())
  {
    sql_print_error("%s", msgbuf);
    goto err;
  }

  length=(uint) (strxmov(name, db_name, ".", table_name.c_ptr_safe(), NullS) - name);
  /*
     TODO: switch from protocol to push_warning here. The main reason we didn't
     it yet is parallel repair. Due to following trace:
     mi_check_print_msg/push_warning/sql_alloc/my_pthread_getspecific_ptr.

     Also we likely need to lock mutex here (in both cases with protocol and
     push_warning).
  */
  DBUG_PRINT("info",("print_admin_msg:  %s, %s, %s, %s", name, op_name,
                     msg_type, msgbuf));
  protocol->prepare_for_resend();
  protocol->store(name, length, system_charset_info);
  protocol->store(op_name, system_charset_info);
  protocol->store(msg_type, system_charset_info);
  protocol->store(msgbuf, msg_length, system_charset_info);
  if (protocol->write())
  {
    sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
                    msgbuf);
    goto err;
  }
  error= false;
err:
  my_free(msgbuf);
  return error;
}
static bool print_admin_msg(THD* thd, uint len,
                            const char* msg_type,
                            const char* db_name, String &table_name,
                            const char* op_name, const char *fmt, ...)
{
  va_list args;
  Protocol *protocol= thd->protocol;
  uint length;
  uint msg_length;
  char name[SAFE_NAME_LEN*2+2];
  char *msgbuf;
  bool error= true;

  if (!(msgbuf= (char*) my_malloc(len, MYF(0))))
    return true;
  va_start(args, fmt);
  msg_length= my_vsnprintf(msgbuf, len, fmt, args);
  va_end(args);
  if (msg_length >= (len - 1))
    goto err;
  msgbuf[len - 1] = 0;  


  if (!thd->vio_ok())
  {
    sql_print_error("%s", msgbuf);
    goto err;
  }

  length=(uint) (strxmov(name, db_name, ".", table_name.c_ptr_safe(), NullS) - name);
   
  DBUG_PRINT("info",("print_admin_msg:  %s, %s, %s, %s", name, op_name,
                     msg_type, msgbuf));
  protocol->prepare_for_resend();
  protocol->store(name, length, system_charset_info);
  protocol->store(op_name, system_charset_info);
  protocol->store(msg_type, system_charset_info);
  protocol->store(msgbuf, msg_length, system_charset_info);
  if (protocol->write())
  {
    sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
                    msgbuf);
    goto err;
  }
  error= false;
err:
  my_free(msgbuf);
  return error;
}