cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
		     const uchar *header, ulong header_length,
		     const uchar *arg, ulong arg_length, my_bool skip_check,
                     MYSQL_STMT *stmt)
{
  NET *net= &mysql->net;
  my_bool result= 1;
  my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE;
  DBUG_ENTER("cli_advanced_command");

  if (mysql->net.vio == 0)
  {						/* Do reconnect if possible */
    if (mysql_reconnect(mysql) || stmt_skip)
      DBUG_RETURN(1);
  }
  if (mysql->status != MYSQL_STATUS_READY ||
      mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
  {
    DBUG_PRINT("error",("state: %d", mysql->status));
    set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
    DBUG_RETURN(1);
  }

  net_clear_error(net);
  mysql->info=0;
  mysql->affected_rows= ~(my_ulonglong) 0;
  /*
    Do not check the socket/protocol buffer on COM_QUIT as the
    result of a previous command might not have been read. This
    can happen if a client sends a query but does not reap the
    result before attempting to close the connection.
  */
  net_clear(&mysql->net, (command != COM_QUIT));

  MYSQL_TRACE_STAGE(mysql, READY_FOR_COMMAND);
  MYSQL_TRACE(SEND_COMMAND, mysql, (command, header_length, arg_length, header, arg));

  if (net_write_command(net,(uchar) command, header, header_length,
			arg, arg_length))
  {
    DBUG_PRINT("error",("Can't send command to server. Error: %d",
			socket_errno));
    if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
    {
      set_mysql_error(mysql, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
      goto end;
    }
    end_server(mysql);
    if (mysql_reconnect(mysql) || stmt_skip)
      goto end;
    
    MYSQL_TRACE(SEND_COMMAND, mysql, (command, header_length, arg_length, header, arg));
    if (net_write_command(net,(uchar) command, header, header_length,
			  arg, arg_length))
    {
      set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
      goto end;
    }
  }

  MYSQL_TRACE(PACKET_SENT, mysql, (header_length + arg_length)); 

#if defined(CLIENT_PROTOCOL_TRACING)
  switch (command)
  {
  case COM_STMT_PREPARE:
    MYSQL_TRACE_STAGE(mysql, WAIT_FOR_PS_DESCRIPTION);
    break;

  case COM_STMT_FETCH:
    MYSQL_TRACE_STAGE(mysql, WAIT_FOR_ROW);
    break;

  /* 
    No server reply is expected after these commands so we reamin ready
    for the next command.
 */
  case COM_STMT_SEND_LONG_DATA: 
  case COM_STMT_CLOSE:
  case COM_REGISTER_SLAVE:
  case COM_QUIT:
    break;

  /*
    These replication commands are not supported and we bail out
    by pretending that connection has been closed.
  */
  case COM_BINLOG_DUMP:
  case COM_BINLOG_DUMP_GTID:
  case COM_TABLE_DUMP:
    MYSQL_TRACE(DISCONNECTED, mysql, ());
    break;

  /*
    After COM_CHANGE_USER a regular authentication exchange
    is performed.
  */
  case COM_CHANGE_USER:
    MYSQL_TRACE_STAGE(mysql, AUTHENTICATE);
    break;

  /*
    Server replies to COM_STATISTICS with a single packet 
    containing a string with statistics information.
  */
  /* Server replies to COM_RESET_CONNECTION with OK or
     Error Packet.
  */
  case COM_STATISTICS:
  case COM_RESET_CONNECTION:
    MYSQL_TRACE_STAGE(mysql, WAIT_FOR_PACKET);
    break;

  default: MYSQL_TRACE_STAGE(mysql, WAIT_FOR_RESULT); break;
  }
#endif

  result=0;
  if (!skip_check)
  {
    result= ((mysql->packet_length=cli_safe_read(mysql)) == packet_error ?
	     1 : 0);

#if defined(CLIENT_PROTOCOL_TRACING)
    /*
      Return to READY_FOR_COMMAND protocol stage in case server reports error 
      or sends OK packet.
    */
    if (!result || mysql->net.read_pos[0] == 0x00)
      MYSQL_TRACE_STAGE(mysql, READY_FOR_COMMAND);
#endif
  }

end:
  DBUG_PRINT("exit",("result: %d", result));
  DBUG_RETURN(result);
}