Beispiel #1
0
int my_ssl_verify_server_cert(SSL *ssl)
{
  X509 *cert;
  MYSQL *mysql;
  X509_NAME *x509sn;
  int cn_pos;
  X509_NAME_ENTRY *cn_entry;
  ASN1_STRING *cn_asn1;
  const char *cn_str;

  DBUG_ENTER("my_ssl_verify_server_cert");

  mysql= (MYSQL *)SSL_get_app_data(ssl);

  if (!mysql->host)
  {
    my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
                        ER(CR_SSL_CONNECTION_ERROR), 
                        "Invalid (empty) hostname");
    DBUG_RETURN(1);
  }

  if (!(cert= SSL_get_peer_certificate(ssl)))
  {
    my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
                        ER(CR_SSL_CONNECTION_ERROR), 
                        "Unable to get server certificate");
    DBUG_RETURN(1);
  }

  x509sn= X509_get_subject_name(cert);

  if ((cn_pos= X509_NAME_get_index_by_NID(x509sn, NID_commonName, -1)) < 0)
    goto error;

  if (!(cn_entry= X509_NAME_get_entry(x509sn, cn_pos)))
    goto error;

  if (!(cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry)))
    goto error;

  cn_str = (char *)ASN1_STRING_data(cn_asn1);

  /* Make sure there is no embedded \0 in the CN */
  if ((size_t)ASN1_STRING_length(cn_asn1) != strlen(cn_str))
    goto error;

  if (strcmp(cn_str, mysql->host))
    goto error;

  X509_free(cert);

  DBUG_RETURN(0);

error:
  X509_free(cert);

  my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
                      ER(CR_SSL_CONNECTION_ERROR), 
                      "Validation of SSL server certificate failed");
  DBUG_RETURN(1);
}
my_bool _ma_read_cache(MARIA_HA *handler, IO_CACHE *info, uchar *buff,
                       my_off_t pos, size_t length, uint flag)
{
  size_t read_length,in_buff_length;
  my_off_t offset;
  uchar *in_buff_pos;
  DBUG_ENTER("_ma_read_cache");

  if (pos < info->pos_in_file)
  {
    read_length=length;
    if ((my_off_t) read_length > (my_off_t) (info->pos_in_file-pos))
      read_length=(uint) (info->pos_in_file-pos);
    info->seek_not_done=1;
    if (mysql_file_pread(info->file,buff,read_length,pos,MYF(MY_NABP)))
      DBUG_RETURN(1);
    if (!(length-=read_length))
      DBUG_RETURN(0);
    pos+=read_length;
    buff+=read_length;
  }
  if (pos >= info->pos_in_file &&
      (offset= (my_off_t) (pos - info->pos_in_file)) <
      (my_off_t) (info->read_end - info->request_pos))
  {
    in_buff_pos=info->request_pos+(uint) offset;
    in_buff_length= MY_MIN(length,(size_t) (info->read_end-in_buff_pos));
    memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
    if (!(length-=in_buff_length))
      DBUG_RETURN(0);
    pos+=in_buff_length;
    buff+=in_buff_length;
  }
  else
    in_buff_length=0;
  if (flag & READING_NEXT)
  {
    if (pos != (info->pos_in_file +
		(uint) (info->read_end - info->request_pos)))
    {
      info->pos_in_file=pos;				/* Force start here */
      info->read_pos=info->read_end=info->request_pos;	/* Everything used */
      info->seek_not_done=1;
    }
    else
      info->read_pos=info->read_end;			/* All block used */
    if (!(*info->read_function)(info,buff,length))
      DBUG_RETURN(0);
    read_length=info->error;
  }
  else
  {
    info->seek_not_done=1;
    if ((read_length=mysql_file_pread(info->file,buff,length,pos,MYF(0))) == length)
      DBUG_RETURN(0);
  }
  if (!(flag & READING_HEADER) || (int) read_length == -1 ||
      read_length+in_buff_length < 3)
  {
    DBUG_PRINT("error",
               ("Error %d reading next-multi-part block (Got %d bytes)",
                my_errno, (int) read_length));
    if (!my_errno || my_errno == HA_ERR_FILE_TOO_SHORT)
    {
      if (!handler->in_check_table)
        _ma_set_fatal_error(handler->s, HA_ERR_WRONG_IN_RECORD);
      else
        my_errno= HA_ERR_WRONG_IN_RECORD;
    }
    DBUG_RETURN(1);
  }
  bzero(buff+read_length,MARIA_BLOCK_INFO_HEADER_LENGTH - in_buff_length -
        read_length);
  DBUG_RETURN(0);
} /* _ma_read_cache */
Beispiel #3
0
static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key, 
                             uint key_length, int ins_level)
{
  my_off_t old_root;
  MI_KEYDEF *keyinfo = info->s->keyinfo + keynr;
  int res;
  my_off_t new_page;
  DBUG_ENTER("rtree_insert_level");

  if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
  {
    if ((old_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
      DBUG_RETURN(-1);
    info->buff_used = 1;
    mi_putint(info->buff, 2, 0);
    res = rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL);
    if (_mi_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff))
      DBUG_RETURN(1);
    info->s->state.key_root[keynr] = old_root;
    DBUG_RETURN(res);
  }

  switch ((res = rtree_insert_req(info, keyinfo, key, key_length, 
                                  old_root, &new_page, ins_level, 0)))
  {
    case 0: /* root was not split */
    {
      break;
    }
    case 1: /* root was split, grow a new root */
    { 
      uchar *new_root_buf;
      my_off_t new_root;
      uchar *new_key;
      uint nod_flag = info->s->base.key_reflength;

      DBUG_PRINT("rtree", ("root was split, grow a new root"));
      if (!(new_root_buf = (uchar*)my_alloca((uint)keyinfo->block_length + 
                                             MI_MAX_KEY_BUFF)))
      {
        my_errno = HA_ERR_OUT_OF_MEM;
        DBUG_RETURN(-1); /* purecov: inspected */
      }

      mi_putint(new_root_buf, 2, nod_flag);
      if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
	  HA_OFFSET_ERROR)
        goto err1;

      new_key = new_root_buf + keyinfo->block_length + nod_flag;

      _mi_kpointer(info, new_key - nod_flag, old_root);
      if (rtree_set_key_mbr(info, keyinfo, new_key, key_length, old_root))
        goto err1;
      if (rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf, NULL) 
          == -1)
        goto err1;
      _mi_kpointer(info, new_key - nod_flag, new_page);
      if (rtree_set_key_mbr(info, keyinfo, new_key, key_length, new_page))
        goto err1;
      if (rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf, NULL) 
          == -1)
        goto err1;
      if (_mi_write_keypage(info, keyinfo, new_root,
                            DFLT_INIT_HITS, new_root_buf))
        goto err1;
      info->s->state.key_root[keynr] = new_root;
      DBUG_PRINT("rtree", ("new root page: %lu  level: %d  nod_flag: %u",
                           (ulong) new_root, 0, mi_test_if_nod(new_root_buf)));

      my_afree((uchar*)new_root_buf);
      break;
err1:
      my_afree((uchar*)new_root_buf);
      DBUG_RETURN(-1); /* purecov: inspected */
    }
    default:
    case -1: /* error */
    {
      break;
    }
  }
  DBUG_RETURN(res);
}
Beispiel #4
0
int my_search_option_files(const char *conf_file, int *argc, char ***argv,
                           uint *args_used, Process_option_func func,
                           void *func_ctx, const char **default_directories)
{
  const char **dirs, *forced_default_file, *forced_extra_defaults;
  int error= 0;
  DBUG_ENTER("my_search_option_files");

  /* Check if we want to force the use a specific default file */
  *args_used+= get_defaults_options(*argc - *args_used, *argv + *args_used,
                                    (char **) &forced_default_file,
                                    (char **) &forced_extra_defaults,
                                    (char **) &my_defaults_group_suffix);

  if (! my_defaults_group_suffix)
    my_defaults_group_suffix= getenv(STRINGIFY_ARG(DEFAULT_GROUP_SUFFIX_ENV));

  if (forced_extra_defaults && !defaults_already_read)
  {
    int error= fn_expand(forced_extra_defaults, my_defaults_extra_file_buffer);
    if (error)
      DBUG_RETURN(error);
    my_defaults_extra_file= my_defaults_extra_file_buffer;
  }

  if (forced_default_file && !defaults_already_read)
  {
    int error= fn_expand(forced_default_file, my_defaults_file_buffer);
    if (error)
      DBUG_RETURN(error);
    my_defaults_file= my_defaults_file_buffer;
  }

  defaults_already_read= TRUE;

  /*
    We can only handle 'defaults-group-suffix' if we are called from
    load_defaults() as otherwise we can't know the type of 'func_ctx'
  */

  if (my_defaults_group_suffix && func == handle_default_option)
  {
    /* Handle --defaults-group-suffix= */
    uint i;
    const char **extra_groups;
    const size_t instance_len= strlen(my_defaults_group_suffix); 
    struct handle_option_ctx *ctx= (struct handle_option_ctx*) func_ctx;
    char *ptr;
    TYPELIB *group= ctx->group;
    
    if (!(extra_groups= 
	  (const char**)alloc_root(ctx->alloc,
                                   (2*group->count+1)*sizeof(char*))))
      DBUG_RETURN(2);
    
    for (i= 0; i < group->count; i++)
    {
      size_t len;
      extra_groups[i]= group->type_names[i]; /** copy group */
      
      len= strlen(extra_groups[i]);
      if (!(ptr= alloc_root(ctx->alloc, (uint) (len+instance_len+1))))
       DBUG_RETURN(2);
      
      extra_groups[i+group->count]= ptr;
      
      /** Construct new group */
      memcpy(ptr, extra_groups[i], len);
      memcpy(ptr+len, my_defaults_group_suffix, instance_len+1);
    }
    
    group->count*= 2;
    group->type_names= extra_groups;
    group->type_names[group->count]= 0;
  }
  
  if (my_defaults_file)
  {
    if ((error= search_default_file_with_ext(func, func_ctx, "", "",
                                             my_defaults_file, 0)) < 0)
      goto err;
    if (error > 0)
    {
      fprintf(stderr, "Could not open required defaults file: %s\n",
              my_defaults_file);
      goto err;
    }
  }
  else if (dirname_length(conf_file))
  {
    if ((error= search_default_file(func, func_ctx, NullS, conf_file)) < 0)
      goto err;
  }
  else
  {
    for (dirs= default_directories ; *dirs; dirs++)
    {
      if (**dirs)
      {
	if (search_default_file(func, func_ctx, *dirs, conf_file) < 0)
	  goto err;
      }
      else if (my_defaults_extra_file)
      {
        if ((error= search_default_file_with_ext(func, func_ctx, "", "",
                                                my_defaults_extra_file, 0)) < 0)
	  goto err;				/* Fatal error */
        if (error > 0)
        {
          fprintf(stderr, "Could not open required defaults file: %s\n",
                  my_defaults_extra_file);
          goto err;
        }
      }
    }
  }

  DBUG_RETURN(0);

err:
  fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
  DBUG_RETURN(1);
}
my_bool fetch_n(const char **query_list, unsigned query_count,
enum fetch_type fetch_type)
{
 unsigned open_statements= query_count;
 int rc, error_count= 0;
 Stmt_fetch *fetch_array= (Stmt_fetch*) calloc(1, sizeof(Stmt_fetch) *
 query_count);
 Stmt_fetch *fetch;
 DBUG_ENTER("fetch_n");

 for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
 {
   /* Init will exit(1) in case of error */
   stmt_fetch_init(fetch, fetch - fetch_array,
   query_list[fetch - fetch_array]);
 }

 if (fetch_type == USE_STORE_RESULT)
 {
   for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
   {
     rc= mysql_stmt_store_result(fetch->handle);
     check_execute(fetch->handle, rc);
   }
 }

 while (open_statements)
 {
   for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
   {
     if (fetch->is_open && (rc= stmt_fetch_fetch_row(fetch)))
     {
       open_statements--;
       /*
       We try to fetch from the rest of the statements in case of
       error
       */
       if (rc != MYSQL_NO_DATA)
       {
	 fprintf(stderr,
	 "Got error reading rows from statement %d,\n"
	 "query is: %s,\n"
	 "error message: %s", (int) (fetch - fetch_array),
	 fetch->query,
	 mysql_stmt_error(fetch->handle));
	 error_count++;
       }
     }
   }
 }
 if (error_count)
 fprintf(stderr, "Fetch FAILED");
 else
 {
   unsigned total_row_count= 0;
   for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
   total_row_count+= fetch->row_count;
   if (!opt_silent)
   printf("Success, total rows fetched: %d\n", total_row_count);
 }
 for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch)
 stmt_fetch_close(fetch);
 free(fetch_array);
 DBUG_RETURN(error_count != 0);
}
Beispiel #6
0
my_string fn_format(my_string to, const char *name, const char *dir,
                    const char *extension, uint flag)
{
    reg1 uint length;
    char dev[FN_REFLEN], buff[FN_REFLEN], *pos, *startpos;
    const char *ext;
    DBUG_ENTER("fn_format");
    DBUG_PRINT("enter",("name: %s  dir: %s  extension: %s  flag: %d",
                        name,dir,extension,flag));

    /* Copy and skip directory */
    name+=(length=dirname_part(dev,(startpos=(my_string) name)));
    if (length == 0 || (flag & MY_REPLACE_DIR))
    {
        /* Use given directory */
        convert_dirname(dev,dir,NullS);		/* Fix to this OS */
    }
    else if ((flag & MY_RELATIVE_PATH) && !test_if_hard_path(dev))
    {
        /* Put 'dir' before the given path */
        strmake(buff,dev,sizeof(buff)-1);
        pos=convert_dirname(dev,dir,NullS);
        strmake(pos,buff,sizeof(buff)-1- (int) (pos-dev));
    }

    if (flag & MY_PACK_FILENAME)
        pack_dirname(dev,dev);			/* Put in ./.. and ~/.. */
    if (flag & MY_UNPACK_FILENAME)
        (void) unpack_dirname(dev,dev);		/* Replace ~/.. with dir */

    if ((pos= (char*) strchr(name,FN_EXTCHAR)) != NullS)
    {
        if ((flag & MY_REPLACE_EXT) == 0)		/* If we should keep old ext */
        {
            length=strlength(name);			/* Use old extension */
            ext = "";
        }
        else
        {
            length=(uint) (pos-(char*) name);		/* Change extension */
            ext= extension;
        }
    }
    else
    {
        length=strlength(name);			/* No ext, use the now one */
        ext=extension;
    }

    if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN )
    {
        /* To long path, return original or NULL */
        uint tmp_length;
        if (flag & MY_SAFE_PATH)
            return NullS;
        tmp_length=strlength(startpos);
        DBUG_PRINT("error",("dev: '%s'  ext: '%s'  length: %d",dev,ext,length));
        (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
    }
    else
    {
        if (to == startpos)
        {
            bmove(buff,(char*) name,length);		/* Save name for last copy */
            name=buff;
        }
        pos=strmake(strmov(to,dev),name,length);
        (void) strmov(pos,ext);			/* Don't convert extension */
    }
    /*
      If MY_RETURN_REAL_PATH and MY_RESOLVE_SYMLINK is given, only do
      realpath if the file is a symbolic link
    */
    if (flag & MY_RETURN_REAL_PATH)
        (void) my_realpath(to, to, MYF(flag & MY_RESOLVE_SYMLINKS ?
                                       MY_RESOLVE_LINK: 0));
    else if (flag & MY_RESOLVE_SYMLINKS)
    {
        strmov(buff,to);
        (void) my_readlink(to, buff, MYF(0));
    }
    DBUG_RETURN(to);
} /* fn_format */
Beispiel #7
0
static void end_server(MYSQL *mysql)
{
  DBUG_ENTER("end_server");
  free_old_query(mysql);
  DBUG_VOID_RETURN;
}
Ndb_cluster_connection_impl::~Ndb_cluster_connection_impl()
{
  DBUG_ENTER("~Ndb_cluster_connection");
  if (m_transporter_facade != 0)
  {
    m_transporter_facade->stop_instance();
  }
  if (m_connect_thread)
  {
    void *status;
    m_run_connect_thread= 0;
    NdbThread_WaitFor(m_connect_thread, &status);
    NdbThread_Destroy(&m_connect_thread);
    m_connect_thread= 0;
  }
  if (m_transporter_facade != 0)
  {
    delete m_transporter_facade;
    m_transporter_facade = 0;
  }
  if (m_config_retriever)
  {
    delete m_config_retriever;
    m_config_retriever= NULL;
  }
#ifdef VM_TRACE
  if (ndb_print_state_mutex != NULL)
  {
    NdbMutex_Destroy(ndb_print_state_mutex);
    ndb_print_state_mutex= NULL;
  }
#endif
  if (m_name)
    free(m_name);

  NdbMutex_Lock(g_ndb_connection_mutex);
  if(--g_ndb_connection_count == 0){
    delete NdbDictionary::Column::FRAGMENT; 
    delete NdbDictionary::Column::FRAGMENT_FIXED_MEMORY;
    delete NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY;
    delete NdbDictionary::Column::ROW_COUNT;
    delete NdbDictionary::Column::COMMIT_COUNT;
    delete NdbDictionary::Column::ROW_SIZE;
    delete NdbDictionary::Column::RANGE_NO;
    delete NdbDictionary::Column::DISK_REF;
    delete NdbDictionary::Column::RECORDS_IN_RANGE;
    delete NdbDictionary::Column::ROWID;
    delete NdbDictionary::Column::ROW_GCI;
    delete NdbDictionary::Column::ANY_VALUE;
    NdbDictionary::Column::FRAGMENT= 0;
    NdbDictionary::Column::FRAGMENT_FIXED_MEMORY= 0;
    NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY= 0;
    NdbDictionary::Column::ROW_COUNT= 0;
    NdbDictionary::Column::COMMIT_COUNT= 0;
    NdbDictionary::Column::ROW_SIZE= 0;
    NdbDictionary::Column::RANGE_NO= 0;
    NdbDictionary::Column::DISK_REF= 0;
    NdbDictionary::Column::RECORDS_IN_RANGE= 0;
    NdbDictionary::Column::ROWID= 0;
    NdbDictionary::Column::ROW_GCI= 0;
    NdbDictionary::Column::ANY_VALUE= 0;

    delete NdbDictionary::Column::COPY_ROWID;
    NdbDictionary::Column::COPY_ROWID = 0;
  }
  NdbMutex_Unlock(g_ndb_connection_mutex);

  if (m_event_add_drop_mutex)
    NdbMutex_Destroy(m_event_add_drop_mutex);

  DBUG_VOID_RETURN;
}
int
Ndb_cluster_connection_impl::init_nodes_vector(Uint32 nodeid,
					       const ndb_mgm_configuration 
					       &config)
{
  DBUG_ENTER("Ndb_cluster_connection_impl::init_nodes_vector");
  ndb_mgm_configuration_iterator iter(config, CFG_SECTION_CONNECTION);
  
  for(iter.first(); iter.valid(); iter.next())
  {
    Uint32 nodeid1, nodeid2, remoteNodeId, group= 5;
    const char * remoteHostName= 0, * localHostName= 0;
    if(iter.get(CFG_CONNECTION_NODE_1, &nodeid1)) continue;
    if(iter.get(CFG_CONNECTION_NODE_2, &nodeid2)) continue;

    if(nodeid1 != nodeid && nodeid2 != nodeid) continue;
    remoteNodeId = (nodeid == nodeid1 ? nodeid2 : nodeid1);

    iter.get(CFG_CONNECTION_GROUP, &group);

    {
      const char * host1= 0, * host2= 0;
      iter.get(CFG_CONNECTION_HOSTNAME_1, &host1);
      iter.get(CFG_CONNECTION_HOSTNAME_2, &host2);
      localHostName  = (nodeid == nodeid1 ? host1 : host2);
      remoteHostName = (nodeid == nodeid1 ? host2 : host1);
    }

    Uint32 type = ~0;
    if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue;

    switch(type){
    case CONNECTION_TYPE_SHM:{
      break;
    }
    case CONNECTION_TYPE_SCI:{
      break;
    }
    case CONNECTION_TYPE_TCP:{
      // connecting through localhost
      // check if config_hostname is local
      if (SocketServer::tryBind(0,remoteHostName))
	group--; // upgrade group value
      break;
    }
    }
    if (m_impl.m_all_nodes.push_back(Node(group,remoteNodeId)))
    {
      DBUG_RETURN(-1);
    }
    DBUG_PRINT("info",("saved %d %d", group,remoteNodeId));
    for (int i= m_impl.m_all_nodes.size()-2;
	 i >= 0 && m_impl.m_all_nodes[i].group > m_impl.m_all_nodes[i+1].group;
	 i--)
    {
      Node tmp= m_impl.m_all_nodes[i];
      m_impl.m_all_nodes[i]= m_impl.m_all_nodes[i+1];
      m_impl.m_all_nodes[i+1]= tmp;
    }
  }

  int i;
  Uint32 cur_group, i_group= 0;
  cur_group= ~0;
  for (i= (int)m_impl.m_all_nodes.size()-1; i >= 0; i--)
  {
    if (m_impl.m_all_nodes[i].group != cur_group)
    {
      cur_group= m_impl.m_all_nodes[i].group;
      i_group= i+1;
    }
    m_impl.m_all_nodes[i].next_group= i_group;
  }
  cur_group= ~0;
  for (i= 0; i < (int)m_impl.m_all_nodes.size(); i++)
  {
    if (m_impl.m_all_nodes[i].group != cur_group)
    {
      cur_group= m_impl.m_all_nodes[i].group;
      i_group= i;
    }
    m_impl.m_all_nodes[i].this_group= i_group;
  }
#if 0
  for (i= 0; i < (int)m_impl.m_all_nodes.size(); i++)
  {
    fprintf(stderr, "[%d] %d %d %d %d\n",
	   i,
	   m_impl.m_all_nodes[i].id,
	   m_impl.m_all_nodes[i].group,
	   m_impl.m_all_nodes[i].this_group,
	   m_impl.m_all_nodes[i].next_group);
  }

  do_test();
#endif
  DBUG_RETURN(0);
}
int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, 
                     uint key_length, my_off_t *new_page_offs)
{
  int n1, n2; /* Number of items in groups */

  SplitStruct *task;
  SplitStruct *cur;
  SplitStruct *stop;
  double *coord_buf;
  double *next_coord;
  int n_dim;
  uchar *source_cur, *cur1, *cur2;
  uchar *new_page= info->buff;
  int err_code= 0;
  uint nod_flag= mi_test_if_nod(page);
  uint full_length= key_length + (nod_flag ? nod_flag : 
                                  info->s->base.rec_reflength);
  int max_keys= (mi_getint(page)-2) / (full_length);
  DBUG_ENTER("rtree_split_page");
  DBUG_PRINT("rtree", ("splitting block"));

  n_dim = keyinfo->keysegs / 2;
  
  if (!(coord_buf= (double*) my_alloca(n_dim * 2 * sizeof(double) *
                                       (max_keys + 1 + 4) +
                                       sizeof(SplitStruct) * (max_keys + 1))))
    DBUG_RETURN(-1); /* purecov: inspected */

  task= (SplitStruct *)(coord_buf + n_dim * 2 * (max_keys + 1 + 4));

  next_coord = coord_buf;
 
  stop = task + max_keys;
  source_cur = rt_PAGE_FIRST_KEY(page, nod_flag);

  for (cur = task; cur < stop; ++cur, source_cur = rt_PAGE_NEXT_KEY(source_cur, 
       key_length, nod_flag))
  {
    cur->coords = reserve_coords(&next_coord, n_dim);
    cur->key = source_cur;
    rtree_d_mbr(keyinfo->seg, source_cur, key_length, cur->coords);
  }

  cur->coords = reserve_coords(&next_coord, n_dim);
  rtree_d_mbr(keyinfo->seg, key, key_length, cur->coords);
  cur->key = key;

  if (split_rtree_node(task, max_keys + 1,
       mi_getint(page) + full_length + 2, full_length, 
       rt_PAGE_MIN_SIZE(keyinfo->block_length),
       2, 2, &next_coord, n_dim))
  {
    err_code = 1;
    goto split_err;
  }

  info->buff_used= 1;
  stop = task + (max_keys + 1);
  cur1 = rt_PAGE_FIRST_KEY(page, nod_flag);
  cur2 = rt_PAGE_FIRST_KEY(new_page, nod_flag);

  n1= n2 = 0;
  for (cur = task; cur < stop; ++cur)
  {
    uchar *to;
    if (cur->n_node == 1)
    {
      to = cur1;
      cur1 = rt_PAGE_NEXT_KEY(cur1, key_length, nod_flag);
      ++n1;
    }
    else
    {
      to = cur2;
      cur2 = rt_PAGE_NEXT_KEY(cur2, key_length, nod_flag);
      ++n2;
    }
    if (to != cur->key)
      memcpy(to - nod_flag, cur->key - nod_flag, full_length);
  }
 
  mi_putint(page, 2 + n1 * full_length, nod_flag);
  mi_putint(new_page, 2 + n2 * full_length, nod_flag);

  if ((*new_page_offs= _mi_new(info, keyinfo, DFLT_INIT_HITS)) == 
                                                               HA_OFFSET_ERROR)
    err_code= -1;
  else
    err_code= _mi_write_keypage(info, keyinfo, *new_page_offs,
                                DFLT_INIT_HITS, new_page);
  DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs));

split_err:
  my_afree((uchar*) coord_buf);
  DBUG_RETURN(err_code);
}
Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char *
							 connect_string)
  : Ndb_cluster_connection(*this),
    m_optimized_node_selection(1),
    m_name(0),
    m_run_connect_thread(0),
    m_event_add_drop_mutex(0),
    m_latest_trans_gci(0)
{
  DBUG_ENTER("Ndb_cluster_connection");
  DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%lx", (long) this));

  if (!m_event_add_drop_mutex)
    m_event_add_drop_mutex= NdbMutex_Create();

  g_eventLogger.createConsoleHandler();
  g_eventLogger.setCategory("NdbApi");
  g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR);

  m_connect_thread= 0;
  m_connect_callback= 0;

#ifdef VM_TRACE
  if (ndb_print_state_mutex == NULL)
    ndb_print_state_mutex= NdbMutex_Create();
#endif
  m_config_retriever=
    new ConfigRetriever(connect_string, NDB_VERSION, NODE_TYPE_API);
  if (m_config_retriever->hasError())
  {
    printf("Could not initialize handle to management server: %s\n",
	   m_config_retriever->getErrorString());
    delete m_config_retriever;
    m_config_retriever= 0;
  }
  if (m_name)
  {
    NdbMgmHandle h= m_config_retriever->get_mgmHandle();
    ndb_mgm_set_name(h, m_name);
  }
  m_transporter_facade= new TransporterFacade();
  
  NdbMutex_Lock(g_ndb_connection_mutex);
  if(g_ndb_connection_count++ == 0){
    NdbDictionary::Column::FRAGMENT= 
      NdbColumnImpl::create_pseudo("NDB$FRAGMENT");
    NdbDictionary::Column::FRAGMENT_FIXED_MEMORY= 
      NdbColumnImpl::create_pseudo("NDB$FRAGMENT_FIXED_MEMORY");
    NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY= 
      NdbColumnImpl::create_pseudo("NDB$FRAGMENT_VARSIZED_MEMORY");
    NdbDictionary::Column::ROW_COUNT= 
      NdbColumnImpl::create_pseudo("NDB$ROW_COUNT");
    NdbDictionary::Column::COMMIT_COUNT= 
      NdbColumnImpl::create_pseudo("NDB$COMMIT_COUNT");
    NdbDictionary::Column::ROW_SIZE=
      NdbColumnImpl::create_pseudo("NDB$ROW_SIZE");
    NdbDictionary::Column::RANGE_NO= 
      NdbColumnImpl::create_pseudo("NDB$RANGE_NO");
    NdbDictionary::Column::DISK_REF= 
      NdbColumnImpl::create_pseudo("NDB$DISK_REF");
    NdbDictionary::Column::RECORDS_IN_RANGE= 
      NdbColumnImpl::create_pseudo("NDB$RECORDS_IN_RANGE");
    NdbDictionary::Column::ROWID= 
      NdbColumnImpl::create_pseudo("NDB$ROWID");
    NdbDictionary::Column::ROW_GCI= 
      NdbColumnImpl::create_pseudo("NDB$ROW_GCI");
    NdbDictionary::Column::ANY_VALUE= 
      NdbColumnImpl::create_pseudo("NDB$ANY_VALUE");
    NdbDictionary::Column::COPY_ROWID= 
      NdbColumnImpl::create_pseudo("NDB$COPY_ROWID");
  }
  NdbMutex_Unlock(g_ndb_connection_mutex);

  DBUG_VOID_RETURN;
}
int main(int argc, char **argv)
{
  SHAPEFILE *sha;
  SHAPEFILE_RECORD *rec;
  PROJECTION *proj;

  int rc;
  int i, max;

  DBUG_ENTER("main");
  DBUG_PROCESS(argv[0]);
  DBUG_PUSH("d:t");

  if(argc != 2)
  {
    printf("usage %s <shapefile>\n", argv[0]);
    DBUG_RETURN(-1);
  }

  if(!(sha = shapefile_init(0)))
  {
    printf("Couldn't init\n");
    DBUG_RETURN(-2);
  }

  if((rc= shapefile_open(sha, argv[1], 'r')) < 0)
  {
    printf("Couldn't open\n");
    DBUG_RETURN(-3);
  }

  proj = projection_init();

  if(sha->flags & SHAPEFILE_HAS_PRJ)
  {
    projection_set(proj, sha->prj->proj4_def, "+proj=latlong");
    shapefile_set_projection(sha, proj);
  }

  shapefile_dump(sha);

  max = sha->dbf->numrecords < 100 ? sha->dbf->numrecords : 100;

  for(i=1; i<max; i+=10)
  {
    shapefile_seek_record(sha, i);
    if((rec = shapefile_read_next(sha)))
    {
      shapefile_record_dump(rec);
      shapefile_record_free(rec);
    } else {
      printf("Error reading record\n");
      return 4;
    }
    printf("\n\n\n");
  }

  shapefile_close(sha);
  shapefile_free(sha);

  DBUG_RETURN(0);
}
Beispiel #13
0
int runEventApplier(NDBT_Context* ctx, NDBT_Step* step)
{
  DBUG_ENTER("runEventApplier");

  int records = ctx->getNumRecords();
  int loops = ctx->getNumLoops();
  const NdbDictionary::Table * table= ctx->getTab();
  char buf[1024];

  sprintf(buf, "%s_SHADOW", table->getName());
  const NdbDictionary::Table * table_shadow;
  if ((table_shadow = GETNDB(step)->getDictionary()->getTable(buf)) == 0)
  {
    g_err << "Unable to get table " << buf << endl;
    DBUG_RETURN(NDBT_FAILED);
  }

  sprintf(buf, "%s_EVENT", table->getName());
  NdbEventOperation    *pOp;
  pOp = GETNDB(step)->createEventOperation(buf, 10*records);
  if ( pOp == NULL ) {
    g_err << "Event operation creation failed on %s" << buf << endl;
    DBUG_RETURN(NDBT_FAILED);
  }

  int i;
  int n_columns= table->getNoOfColumns();
  NdbRecAttr* recAttr[1024];
  NdbRecAttr* recAttrPre[1024];
  for (i = 0; i < n_columns; i++) {
    recAttr[i]    = pOp->getValue(table->getColumn(i)->getName());
    recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
  }

  if (pOp->execute()) { // This starts changes to "start flowing"
    g_err << "execute operation execution failed: \n";
    g_err << pOp->getNdbError().code << " "
	  << pOp->getNdbError().message << endl;
    DBUG_RETURN(NDBT_FAILED);
  }

  int r= 0;
  int res;
  while (r < 10*records){
    //printf("now waiting for event...\n");
    res= GETNDB(step)->pollEvents(1000); // wait for event or 1000 ms
    if (res <= 0)
    {
      ndbout_c("********************");
      continue;
    }

    //printf("got data! %d\n", r);
    int overrun= 0;
    while (pOp->next(&overrun) > 0)
    {
      if (overrun)
      {
	g_err << "buffer overrun\n";
	DBUG_RETURN(NDBT_FAILED);
      }
      r++;

      Uint32 gci= pOp->getGCI();

      if (!pOp->isConsistent()) {
	g_err << "A node failure has occured and events might be missing\n";
	DBUG_RETURN(NDBT_FAILED);
      }

      int noRetries= 0;
      do
      {
	NdbTransaction *trans= GETNDB(step)->startTransaction();
	if (trans == 0)
	{
	  g_err << "startTransaction failed "
		<< GETNDB(step)->getNdbError().code << " "
		<< GETNDB(step)->getNdbError().message << endl;
	  DBUG_RETURN(NDBT_FAILED);
	}
	
	NdbOperation *op= trans->getNdbOperation(table_shadow);
	if (op == 0)
	{
	  g_err << "getNdbOperation failed "
		<< trans->getNdbError().code << " "
		<< trans->getNdbError().message << endl;
	  DBUG_RETURN(NDBT_FAILED);
	}
	
	switch (pOp->getEventType()) {
	case NdbDictionary::Event::TE_INSERT:
	  if (op->insertTuple())
	  {
	    g_err << "insertTuple "
		  << op->getNdbError().code << " "
		  << op->getNdbError().message << endl;
	    DBUG_RETURN(NDBT_FAILED);
	  }
	  break;
	case NdbDictionary::Event::TE_DELETE:
	  if (op->deleteTuple())
	  {
	    g_err << "deleteTuple "
		  << op->getNdbError().code << " "
		  << op->getNdbError().message << endl;
	    DBUG_RETURN(NDBT_FAILED);
	  }
	  break;
	case NdbDictionary::Event::TE_UPDATE:
	  if (op->updateTuple())
	  {
	    g_err << "updateTuple "
		  << op->getNdbError().code << " "
		  << op->getNdbError().message << endl;
	    DBUG_RETURN(NDBT_FAILED);
	  }
	  break;
	default:
	  abort();
	}

	for (i= 0; i < n_columns; i++)
	{
	  if (recAttr[i]->isNULL())
	  {
	    if (table->getColumn(i)->getPrimaryKey())
	    {
	      g_err << "internal error: primary key isNull()="
		    << recAttr[i]->isNULL() << endl;
	      DBUG_RETURN(NDBT_FAILED);
	    }
	    switch (pOp->getEventType()) {
	    case NdbDictionary::Event::TE_INSERT:
	      if (recAttr[i]->isNULL() < 0)
	      {
		g_err << "internal error: missing value for insert\n";
		DBUG_RETURN(NDBT_FAILED);
	      }
	      break;
	    case NdbDictionary::Event::TE_DELETE:
	      break;
	    case NdbDictionary::Event::TE_UPDATE:
	      break;
	    default:
	      abort();
	    }
	  }
	  if (table->getColumn(i)->getPrimaryKey() &&
	      op->equal(i,recAttr[i]->aRef()))
	  {
	    g_err << "equal " << i << " "
		  << op->getNdbError().code << " "
		  << op->getNdbError().message << endl;
	    DBUG_RETURN(NDBT_FAILED);
	  }
	}
	
	switch (pOp->getEventType()) {
	case NdbDictionary::Event::TE_INSERT:
	  for (i= 0; i < n_columns; i++)
	  {
	    if (!table->getColumn(i)->getPrimaryKey() &&
		op->setValue(i,recAttr[i]->isNULL() ? 0:recAttr[i]->aRef()))
	    {
	      g_err << "setValue(insert) " << i << " "
		    << op->getNdbError().code << " "
		    << op->getNdbError().message << endl;
	      DBUG_RETURN(NDBT_FAILED);
	    }
	  }
	  break;
	case NdbDictionary::Event::TE_DELETE:
	  break;
	case NdbDictionary::Event::TE_UPDATE:
	  for (i= 0; i < n_columns; i++)
	  {
	    if (!table->getColumn(i)->getPrimaryKey() &&
		recAttr[i]->isNULL() >= 0 &&
		op->setValue(i,recAttr[i]->isNULL() ? 0:recAttr[i]->aRef()))
	    {
	      g_err << "setValue(update) " << i << " "
		    << op->getNdbError().code << " "
		    << op->getNdbError().message << endl;
	      DBUG_RETURN(NDBT_FAILED);
	    }
	  }
	  break;
	case NdbDictionary::Event::TE_ALL:
	  abort();
	}
	if (trans->execute(Commit) == 0)
	{
	  trans->close();
	  // everything ok
	  break;
	}
	if (noRetries++ == 10 ||
	    trans->getNdbError().status != NdbError::TemporaryError)
	{
	  g_err << "execute " << r << " failed "
		<< trans->getNdbError().code << " "
		<< trans->getNdbError().message << endl;
	  trans->close();
	  DBUG_RETURN(NDBT_FAILED);
	}
	trans->close();
	NdbSleep_MilliSleep(100); // sleep before retying
      } while(1);
    }
  }

  if (GETNDB(step)->dropEventOperation(pOp)) {
    g_err << "dropEventOperation execution failed "
	  << GETNDB(step)->getNdbError().code << " "
	  << GETNDB(step)->getNdbError().message << endl;
    DBUG_RETURN(NDBT_FAILED);
  }
  
  DBUG_RETURN(NDBT_OK);
}
Beispiel #14
0
static void my_win_init(void)
{
  DBUG_ENTER("my_win_init");

#if defined(_MSC_VER)
#if _MSC_VER < 1300
  /* 
    Clear the OS system variable TZ and avoid the 100% CPU usage
    Only for old versions of Visual C++
  */
  _putenv( "TZ=" ); 
#endif 
#if _MSC_VER >= 1400
  /* this is required to make crt functions return -1 appropriately */
  _set_invalid_parameter_handler(my_parameter_handler);
#endif
#endif  
#ifdef __MSVC_RUNTIME_CHECKS
  /*
    Install handler to send RTC (Runtime Error Check) warnings
    to log file
  */
  _RTC_SetErrorFunc(handle_rtc_failure);
#endif

  _tzset();

               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
               
  /* The following is used by time functions */
#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
#define MS 10000000
  {
    FILETIME ft;
    LARGE_INTEGER li, t_cnt;
    DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency));
    if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency) == 0)
      query_performance_frequency= 0;
    else
    {
      GetSystemTimeAsFileTime(&ft);
      li.LowPart=  ft.dwLowDateTime;
      li.HighPart= ft.dwHighDateTime;
      query_performance_offset= li.QuadPart-OFFSET_TO_EPOC;
      QueryPerformanceCounter(&t_cnt);
      query_performance_offset-= (t_cnt.QuadPart /
                                  query_performance_frequency * MS +
                                  t_cnt.QuadPart %
                                  query_performance_frequency * MS /
                                  query_performance_frequency);
    }
  }

  {
    /*
      Open HKEY_LOCAL_MACHINE\SOFTWARE\MySQL and set any strings found
      there as environment variables
    */
    HKEY key_handle;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)"SOFTWARE\\MySQL",
                     0, KEY_READ, &key_handle) == ERROR_SUCCESS)
    {
      LONG ret;
      DWORD index= 0;
      DWORD type;
      char key_name[256], key_data[1024];
      DWORD key_name_len= sizeof(key_name) - 1;
      DWORD key_data_len= sizeof(key_data) - 1;

      while ((ret= RegEnumValue(key_handle, index++,
                                key_name, &key_name_len,
                                NULL, &type, (LPBYTE)&key_data,
                                &key_data_len)) != ERROR_NO_MORE_ITEMS)
      {
        char env_string[sizeof(key_name) + sizeof(key_data) + 2];

        if (ret == ERROR_MORE_DATA)
        {
          /* Registry value larger than 'key_data', skip it */
          DBUG_PRINT("error", ("Skipped registry value that was too large"));
        }
        else if (ret == ERROR_SUCCESS)
        {
          if (type == REG_SZ)
          {
            strxmov(env_string, key_name, "=", key_data, NullS);

            /* variable for putenv must be allocated ! */
            putenv(strdup(env_string)) ;
          }
        }
        else
        {
          /* Unhandled error, break out of loop */
          break;
        }

        key_name_len= sizeof(key_name) - 1;
        key_data_len= sizeof(key_data) - 1;
      }

      RegCloseKey(key_handle) ;
    }
  }
  DBUG_VOID_RETURN ;
}
Beispiel #15
0
MY_DIR	*my_dir(const char *path, myf MyFlags)
{
  char          *buffer;
  MY_DIR        *result= 0;
  FILEINFO      finfo;
  DYNAMIC_ARRAY *dir_entries_storage;
  MEM_ROOT      *names_storage;
  DIR		*dirp;
  struct dirent *dp;
  char		tmp_path[FN_REFLEN+1],*tmp_file;
#ifdef THREAD
  char	dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
#endif
  DBUG_ENTER("my_dir");
  DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags));

#if defined(THREAD) && !defined(HAVE_READDIR_R)
  pthread_mutex_lock(&THR_LOCK_open);
#endif

  dirp = opendir(directory_file_name(tmp_path,(char *) path));
#if defined(__amiga__)
  if ((dirp->dd_fd) < 0)			/* Directory doesn't exists */
    goto error;
#endif
  if (dirp == NULL || 
      ! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + 
                           ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
                           sizeof(MEM_ROOT), MyFlags)))
    goto error;

  dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); 
  names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
                             ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
  
  if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
                            ENTRIES_START_SIZE, ENTRIES_INCREMENT))
  {
    my_free((uchar*) buffer,MYF(0));
    goto error;
  }
  init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
  
  /* MY_DIR structure is allocated and completly initialized at this point */
  result= (MY_DIR*)buffer;

  tmp_file=strend(tmp_path);

#ifdef THREAD
  dp= (struct dirent*) dirent_tmp;
#else
  dp=0;
#endif
  
  while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
  {
    if (!(finfo.name= strdup_root(names_storage, dp->d_name)))
      goto error;
    
    if (MyFlags & MY_WANT_STAT)
    {
      if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, 
                                               sizeof(MY_STAT))))
        goto error;
      
      bzero(finfo.mystat, sizeof(MY_STAT));
      VOID(strmov(tmp_file,dp->d_name));
      VOID(my_stat(tmp_path, finfo.mystat, MyFlags));
      if (!(finfo.mystat->st_mode & MY_S_IREAD))
        continue;
    }
    else
      finfo.mystat= NULL;

    if (push_dynamic(dir_entries_storage, (uchar*)&finfo))
      goto error;
  }

  (void) closedir(dirp);
#if defined(THREAD) && !defined(HAVE_READDIR_R)
  pthread_mutex_unlock(&THR_LOCK_open);
#endif
  result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
  result->number_off_files= dir_entries_storage->elements;
  
  if (!(MyFlags & MY_DONT_SORT))
    my_qsort((void *) result->dir_entry, result->number_off_files,
          sizeof(FILEINFO), (qsort_cmp) comp_names);
  DBUG_RETURN(result);

 error:
#if defined(THREAD) && !defined(HAVE_READDIR_R)
  pthread_mutex_unlock(&THR_LOCK_open);
#endif
  my_errno=errno;
  if (dirp)
    (void) closedir(dirp);
  my_dirend(result);
  if (MyFlags & (MY_FAE | MY_WME))
    my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno);
  DBUG_RETURN((MY_DIR *) NULL);
} /* my_dir */
Beispiel #16
0
static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
                  int (*connect_accept_func)(SSL*), unsigned long *errptr)
{
  int r;
  SSL *ssl;
  my_bool unused;
  my_bool was_blocking;

  DBUG_ENTER("ssl_do");
  DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d  ctx: 0x%lx",
                       (long) ptr, vio->sd, (long) ptr->ssl_context));

  /* Set socket to blocking if not already set */
  vio_blocking(vio, 1, &was_blocking);

  if (!(ssl= SSL_new(ptr->ssl_context)))
  {
    DBUG_PRINT("error", ("SSL_new failure"));
    *errptr= ERR_get_error();
    vio_blocking(vio, was_blocking, &unused);
    DBUG_RETURN(1);
  }
  DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout));
  SSL_clear(ssl);
  SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
  SSL_set_fd(ssl, vio->sd);

  if ((r= connect_accept_func(ssl)) < 1)
  {
    DBUG_PRINT("error", ("SSL_connect/accept failure"));
    *errptr= SSL_get_error(ssl, r);
    SSL_free(ssl);
    vio_blocking(vio, was_blocking, &unused);
    DBUG_RETURN(1);
  }

  /*
    Connection succeeded. Install new function handlers,
    change type, set sd to the fd used when connecting
    and set pointer to the SSL structure
  */
  vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), 0, 0);
  vio->ssl_arg= (void*)ssl;

#ifndef DBUG_OFF
  {
    /* Print some info about the peer */
    X509 *cert;
    char buf[512];

    DBUG_PRINT("info",("SSL connection succeeded"));
    DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl)));

    if ((cert= SSL_get_peer_certificate (ssl)))
    {
      DBUG_PRINT("info",("Peer certificate:"));
      X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
      DBUG_PRINT("info",("\t subject: '%s'", buf));
      X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
      DBUG_PRINT("info",("\t issuer: '%s'", buf));
      X509_free(cert);
    }
    else
      DBUG_PRINT("info",("Peer does not have certificate."));

    if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
    {
      DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
    }
    else
      DBUG_PRINT("info",("no shared ciphers!"));
  }
#endif

  DBUG_RETURN(0);
}
Beispiel #17
0
int heap_create(const char *name, HP_CREATE_INFO *create_info,
                HP_SHARE **res, my_bool *created_new_share)
{
  uint i, j, key_segs, max_length, length;
  HP_SHARE *share= 0;
  HA_KEYSEG *keyseg;
  HP_KEYDEF *keydef= create_info->keydef;
  uint reclength= create_info->reclength;
  uint keys= create_info->keys;
  ulong min_records= create_info->min_records;
  ulong max_records= create_info->max_records;
  ulong max_rows_for_stated_memory;
  DBUG_ENTER("heap_create");

  if (!create_info->internal_table)
  {
    mysql_mutex_lock(&THR_LOCK_heap);
    share= hp_find_named_heap(name);
    if (share && share->open_count == 0)
    {
      hp_free(share);
      share= 0;
    }
  }
  *created_new_share= (share == NULL);

  if (!share)
  {
    uint chunk_dataspace_length, chunk_length, is_variable_size;
    uint fixed_data_length, fixed_column_count;
    HP_KEYDEF *keyinfo;
    DBUG_PRINT("info",("Initializing new table"));

    if (create_info->max_chunk_size)
    {
      uint configured_chunk_size= create_info->max_chunk_size;

      /* User requested variable-size records, let's see if they're possible */

      if (configured_chunk_size < create_info->fixed_data_size)
      {
        /*
          The resulting chunk_size cannot be smaller than fixed data part
          at the start of the first chunk which allows faster copying
          with a single memcpy().
        */
        my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "key_block_size");
        goto err;
      }

      if (reclength > configured_chunk_size + VARIABLE_REC_OVERHEAD ||
	  create_info->blobs > 0)
      {
        /*
          Allow variable size only if we're saving some space, i.e.
          if a fixed-size record would take more space than variable-size
          one plus the variable-size overhead.
          There has to be at least one field after indexed fields.
          Note that NULL bits are already included in key_part_size.
        */
        is_variable_size= 1;
        chunk_dataspace_length= configured_chunk_size;
      }
      else
      {
        /* max_chunk_size is near the full reclength, let's use fixed size */
        is_variable_size= 0;
        chunk_dataspace_length= reclength;
      }
    }
    else if ((create_info->is_dynamic && reclength >
              256 + VARIABLE_REC_OVERHEAD)
             || create_info->blobs > 0)
    {
      /*
        User asked for dynamic records - use 256 as the chunk size, if that
        will may save some memory. Otherwise revert to fixed size format.
      */
      if ((create_info->fixed_data_size + VARIABLE_REC_OVERHEAD) > 256)
        chunk_dataspace_length= create_info->fixed_data_size;
      else
        chunk_dataspace_length= 256 - VARIABLE_REC_OVERHEAD;

      is_variable_size= 1;
    }
    else
    {
      /*
        If max_chunk_size is not specified, put the whole record in one chunk
      */
      is_variable_size= 0;
      chunk_dataspace_length= reclength;
    }

    if (is_variable_size)
    {
      /* Check whether we have any variable size records past key data */
      uint has_variable_fields= 0;

      fixed_data_length= create_info->fixed_data_size;
      fixed_column_count= create_info->fixed_key_fieldnr;

      for (i= create_info->fixed_key_fieldnr; i < create_info->columns; i++)
      {
        HP_COLUMNDEF *column= create_info->columndef + i;
	if ((column->type == MYSQL_TYPE_VARCHAR &&
	     (column->length - column->length_bytes) >= 32) ||
	    column->type == MYSQL_TYPE_BLOB)
        {
            /*
              The field has to be either blob or >= 5.0.3 true VARCHAR
              and have substantial length.
              TODO: do we want to calculate minimum length?
            */
            has_variable_fields= 1;
            break;
        }

        if (has_variable_fields)
        {
          break;
        }

        if ((column->offset + column->length) <= chunk_dataspace_length)
        {
          /* Still no variable-size columns, add one fixed-length */
          fixed_column_count= i + 1;
          fixed_data_length= column->offset + column->length;
        }
      }

      if (!has_variable_fields && create_info->blobs == 0)
      {
        /*
          There is no need to use variable-size records without variable-size
          columns.
          Reset sizes if it's not variable size anymore.
        */
        is_variable_size= 0;
        chunk_dataspace_length= reclength;
        fixed_data_length= reclength;
        fixed_column_count= create_info->columns;
      }
    }
    else
    {
      fixed_data_length= reclength;
      fixed_column_count= create_info->columns;
    }

    /*
      We store uchar* del_link inside the data area of deleted records,
      so the data length should be at least sizeof(uchar*)
    */
    set_if_bigger(chunk_dataspace_length, sizeof (uchar **));

    if (is_variable_size)
    {
      chunk_length= chunk_dataspace_length + VARIABLE_REC_OVERHEAD;
    }
    else
    {
      chunk_length= chunk_dataspace_length + FIXED_REC_OVERHEAD;
    }

    /* Align chunk length to the next pointer */
    chunk_length= (uint) (chunk_length + sizeof(uchar **) - 1) &
      ~(sizeof(uchar **) - 1);

    for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
    {
      memset(&keyinfo->block, 0, sizeof(keyinfo->block));
      memset(&keyinfo->rb_tree, 0, sizeof(keyinfo->rb_tree));
      for (j= length= 0; j < keyinfo->keysegs; j++)
      {
	length+= keyinfo->seg[j].length;
	if (keyinfo->seg[j].null_bit)
	{
	  length++;
	  if (!(keyinfo->flag & HA_NULL_ARE_EQUAL))
	    keyinfo->flag|= HA_NULL_PART_KEY;
	  if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
	    keyinfo->rb_tree.size_of_element++;
	}
	switch (keyinfo->seg[j].type) {
        case HA_KEYTYPE_VARBINARY1:
        case HA_KEYTYPE_VARTEXT1:
        case HA_KEYTYPE_VARBINARY2:
        case HA_KEYTYPE_VARTEXT2:
          length+= 2;
          break;
	default:
	  break;
	}
      }
      keyinfo->length= length;
      length+= keyinfo->rb_tree.size_of_element + 
	       ((keyinfo->algorithm == HA_KEY_ALG_BTREE) ? sizeof(uchar*) : 0);
      if (length > max_length)
	max_length= length;
      key_segs+= keyinfo->keysegs;
      if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
      {
        key_segs++; /* additional HA_KEYTYPE_END segment */
        if (keyinfo->flag & HA_VAR_LENGTH_KEY)
          keyinfo->get_key_length= hp_rb_var_key_length;
        else if (keyinfo->flag & HA_NULL_PART_KEY)
          keyinfo->get_key_length= hp_rb_null_key_length;
        else
          keyinfo->get_key_length= hp_rb_key_length;
      }
    }
    if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
				       keys*sizeof(HP_KEYDEF)+
                                       (create_info->columns *
                                        sizeof(HP_COLUMNDEF)) +
				       key_segs*sizeof(HA_KEYSEG),
				       MYF(MY_ZEROFILL))))
      goto err;

    /*
      Max_records is used for estimating block sizes and for enforcement.
      Calculate the very maximum number of rows (if everything was one chunk)
      and then take either that value or configured max_records (pick smallest
      one).
    */
    max_rows_for_stated_memory= (ha_rows) (create_info->max_table_size /
                                           (create_info->keys_memory_size +
                                            chunk_length));
    max_records = ((max_records && max_records < max_rows_for_stated_memory) ?
                   max_records : max_rows_for_stated_memory);

    share->column_defs= (HP_COLUMNDEF*) (share + 1);
    memcpy(share->column_defs, create_info->columndef,
           (size_t) (sizeof(create_info->columndef[0]) *
                     create_info->columns));

    share->keydef= (HP_KEYDEF*) (share->column_defs + create_info->columns);
    share->key_stat_version= 1;
    keyseg= (HA_KEYSEG*) (share->keydef + keys);
    init_block(&share->recordspace.block, chunk_length, min_records,
               max_records);
	/* Fix keys */
    memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
    for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
    {
      keyinfo->seg= keyseg;
      memcpy(keyseg, keydef[i].seg,
	     (size_t) (sizeof(keyseg[0]) * keydef[i].keysegs));
      keyseg+= keydef[i].keysegs;

      if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
      {
	/* additional HA_KEYTYPE_END keyseg */
	keyseg->type=     HA_KEYTYPE_END;
	keyseg->length=   sizeof(uchar*);
	keyseg->flag=     0;
	keyseg->null_bit= 0;
	keyseg++;

	init_tree(&keyinfo->rb_tree, 0, 0, sizeof(uchar*),
		  (qsort_cmp2)keys_compare, 1, NULL, NULL);
	keyinfo->delete_key= hp_rb_delete_key;
	keyinfo->write_key= hp_rb_write_key;
      }
      else
      {
	init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
		   max_records);
	keyinfo->delete_key= hp_delete_key;
	keyinfo->write_key= hp_write_key;
        keyinfo->hash_buckets= 0;
      }
      if ((keyinfo->flag & HA_AUTO_KEY) && create_info->with_auto_increment)
        share->auto_key= i + 1;
    }
    share->min_records= min_records;
    share->max_records= max_records;
    share->max_table_size= create_info->max_table_size;
    share->index_length= 0;
    share->blength= 1;
    share->keys= keys;
    share->max_key_length= max_length;
    share->column_count= create_info->columns;
    share->changed= 0;
    share->auto_key= create_info->auto_key;
    share->auto_key_type= create_info->auto_key_type;
    share->auto_increment= create_info->auto_increment;
    share->create_time= (long) time((time_t*) 0);

    share->fixed_data_length= fixed_data_length;
    share->fixed_column_count= fixed_column_count;
    share->blobs= create_info->blobs;

    share->recordspace.chunk_length= chunk_length;
    share->recordspace.chunk_dataspace_length= chunk_dataspace_length;
    share->recordspace.is_variable_size= is_variable_size;
    share->recordspace.total_data_length= 0;

    if (is_variable_size) {
      share->recordspace.offset_link= chunk_dataspace_length;
      share->recordspace.offset_status= share->recordspace.offset_link +
        sizeof(uchar **);
    } else {
      /* Make it likely to fail if anyone uses this offset */
      share->recordspace.offset_link= 1 << 22;
      share->recordspace.offset_status= chunk_dataspace_length;
    }

    /* Must be allocated separately for rename to work */
    if (!(share->name= my_strdup(name,MYF(0))))
    {
      my_free(share);
      goto err;
    }
    thr_lock_init(&share->lock);
    mysql_mutex_init(hp_key_mutex_HP_SHARE_intern_lock,
                     &share->intern_lock, MY_MUTEX_INIT_FAST);
    if (!create_info->internal_table)
    {
      share->open_list.data= (void*) share;
      heap_share_list= list_add(heap_share_list,&share->open_list);
    }
    else
      share->delete_on_close= 1;
  }
  if (!create_info->internal_table)
  {
    if (create_info->pin_share)
      ++share->open_count;
    mysql_mutex_unlock(&THR_LOCK_heap);
  }

  *res= share;
  DBUG_RETURN(0);

err:
  if (!create_info->internal_table)
    mysql_mutex_unlock(&THR_LOCK_heap);
  DBUG_RETURN(1);
} /* heap_create */
Beispiel #18
0
int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout, unsigned long *errptr)
{
  DBUG_ENTER("sslconnect");
  DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect, errptr));
}
Beispiel #19
0
int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
{
  int error=0;
  ulong cache_size;
  MYISAM_SHARE *share=info->s;
  DBUG_ENTER("mi_extra");
  DBUG_PRINT("enter",("function: %d",(int) function));

  switch (function) {
  case HA_EXTRA_RESET:
    /*
      Free buffers and reset the following flags:
      EXTRA_CACHE, EXTRA_WRITE_CACHE, EXTRA_KEYREAD, EXTRA_QUICK

      If the row buffer cache is large (for dynamic tables), reduce it
      to save memory.
    */
    if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
    {
      info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
      error=end_io_cache(&info->rec_cache);
    }
    if (share->base.blobs)
      mi_alloc_rec_buff(info, -1, &info->rec_buff);
#if defined(HAVE_MMAP) && defined(HAVE_MADVISE)
    if (info->opt_flag & MEMMAP_USED)
      madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM);
#endif
    info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
    info->quick_mode=0;
    /* Fall through */

  case HA_EXTRA_RESET_STATE:		/* Reset state (don't free buffers) */
    info->lastinx= 0;			/* Use first index as def */
    info->last_search_keypage=info->lastpos= HA_OFFSET_ERROR;
    info->page_changed=1;
					/* Next/prev gives first/last */
    if (info->opt_flag & READ_CACHE_USED)
    {
      reinit_io_cache(&info->rec_cache,READ_CACHE,0,
		      (pbool) (info->lock_type != F_UNLCK),
		      (pbool) test(info->update & HA_STATE_ROW_CHANGED)
		      );
    }
    info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND |
		   HA_STATE_PREV_FOUND);
    break;
  case HA_EXTRA_CACHE:
    if (info->lock_type == F_UNLCK &&
	(share->options & HA_OPTION_PACK_RECORD))
    {
      error=1;			/* Not possibly if not locked */
      my_errno=EACCES;
      break;
    }
#if defined(HAVE_MMAP) && defined(HAVE_MADVISE)
    if ((share->options & HA_OPTION_COMPRESS_RECORD))
    {
      pthread_mutex_lock(&share->intern_lock);
      if (_mi_memmap_file(info))
      {
	/* We don't nead MADV_SEQUENTIAL if small file */
	madvise(share->file_map,share->state.state.data_file_length,
		share->state.state.data_file_length <= RECORD_CACHE_SIZE*16 ?
		MADV_RANDOM : MADV_SEQUENTIAL);
	pthread_mutex_unlock(&share->intern_lock);
	break;
      }
      pthread_mutex_unlock(&share->intern_lock);
    }
#endif
    if (info->opt_flag & WRITE_CACHE_USED)
    {
      info->opt_flag&= ~WRITE_CACHE_USED;
      if ((error=end_io_cache(&info->rec_cache)))
	break;
    }
    if (!(info->opt_flag &
	  (READ_CACHE_USED | WRITE_CACHE_USED | MEMMAP_USED)))
    {
      cache_size= (extra_arg ? *(ulong*) extra_arg :
		   my_default_record_cache_size);
      if (!(init_io_cache(&info->rec_cache,info->dfile,
			 (uint) min(info->state->data_file_length+1,
				    cache_size),
			  READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
			  MYF(share->write_flag & MY_WAIT_IF_FULL))))
      {
	info->opt_flag|=READ_CACHE_USED;
	info->update&= ~HA_STATE_ROW_CHANGED;
      }
      if (share->concurrent_insert)
	info->rec_cache.end_of_file=info->state->data_file_length;
    }
    break;
  case HA_EXTRA_REINIT_CACHE:
    if (info->opt_flag & READ_CACHE_USED)
    {
      reinit_io_cache(&info->rec_cache,READ_CACHE,info->nextpos,
		      (pbool) (info->lock_type != F_UNLCK),
		      (pbool) test(info->update & HA_STATE_ROW_CHANGED));
      info->update&= ~HA_STATE_ROW_CHANGED;
      if (share->concurrent_insert)
	info->rec_cache.end_of_file=info->state->data_file_length;
    }
    break;
  case HA_EXTRA_WRITE_CACHE:
    if (info->lock_type == F_UNLCK)
    {
      error=1;			/* Not possibly if not locked */
      break;
    }
    cache_size= (extra_arg ? *(ulong*) extra_arg :
		 my_default_record_cache_size);
    if (!(info->opt_flag &
	  (READ_CACHE_USED | WRITE_CACHE_USED | OPT_NO_ROWS)) &&
	!share->state.header.uniques)
      if (!(init_io_cache(&info->rec_cache,info->dfile, cache_size,
			 WRITE_CACHE,info->state->data_file_length,
			  (pbool) (info->lock_type != F_UNLCK),
			  MYF(share->write_flag & MY_WAIT_IF_FULL))))
      {
	info->opt_flag|=WRITE_CACHE_USED;
	info->update&= ~(HA_STATE_ROW_CHANGED |
			 HA_STATE_WRITE_AT_END |
			 HA_STATE_EXTEND_BLOCK);
      }
    break;
  case HA_EXTRA_PREPARE_FOR_UPDATE:
    if (info->s->data_file_type != DYNAMIC_RECORD)
      break;
    /* Remove read/write cache if dynamic rows */
  case HA_EXTRA_NO_CACHE:
    if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
    {
      info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
      error=end_io_cache(&info->rec_cache);
      /* Sergei will insert full text index caching here */
    }
#if defined(HAVE_MMAP) && defined(HAVE_MADVISE)
    if (info->opt_flag & MEMMAP_USED)
      madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM);
#endif
    break;
  case HA_EXTRA_FLUSH_CACHE:
    if (info->opt_flag & WRITE_CACHE_USED)
    {
      if ((error=flush_io_cache(&info->rec_cache)))
      {
        mi_print_error(info->s, HA_ERR_CRASHED);
	mi_mark_crashed(info);			/* Fatal error found */
      }
    }
    break;
  case HA_EXTRA_NO_READCHECK:
    info->opt_flag&= ~READ_CHECK_USED;		/* No readcheck */
    break;
  case HA_EXTRA_READCHECK:
    info->opt_flag|= READ_CHECK_USED;
    break;
  case HA_EXTRA_KEYREAD:			/* Read only keys to record */
  case HA_EXTRA_REMEMBER_POS:
    info->opt_flag |= REMEMBER_OLD_POS;
    bmove((byte*) info->lastkey+share->base.max_key_length*2,
	  (byte*) info->lastkey,info->lastkey_length);
    info->save_update=	info->update;
    info->save_lastinx= info->lastinx;
    info->save_lastpos= info->lastpos;
    info->save_lastkey_length=info->lastkey_length;
    if (function == HA_EXTRA_REMEMBER_POS)
      break;
    /* fall through */
  case HA_EXTRA_KEYREAD_CHANGE_POS:
    info->opt_flag |= KEY_READ_USED;
    info->read_record=_mi_read_key_record;
    break;
  case HA_EXTRA_NO_KEYREAD:
  case HA_EXTRA_RESTORE_POS:
    if (info->opt_flag & REMEMBER_OLD_POS)
    {
      bmove((byte*) info->lastkey,
	    (byte*) info->lastkey+share->base.max_key_length*2,
	    info->save_lastkey_length);
      info->update=	info->save_update | HA_STATE_WRITTEN;
      info->lastinx=	info->save_lastinx;
      info->lastpos=	info->save_lastpos;
      info->lastkey_length=info->save_lastkey_length;
    }
    info->read_record=	share->read_record;
    info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
    break;
  case HA_EXTRA_NO_USER_CHANGE: /* Database is somehow locked agains changes */
    info->lock_type= F_EXTRA_LCK; /* Simulate as locked */
    break;
  case HA_EXTRA_WAIT_LOCK:
    info->lock_wait=0;
    break;
  case HA_EXTRA_NO_WAIT_LOCK:
    info->lock_wait=MY_DONT_WAIT;
    break;
  case HA_EXTRA_NO_KEYS:
    if (info->lock_type == F_UNLCK)
    {
      error=1;					/* Not possibly if not lock */
      break;
    }
    if (mi_is_any_key_active(share->state.key_map))
    {
      MI_KEYDEF *key=share->keyinfo;
      uint i;
      for (i=0 ; i < share->base.keys ; i++,key++)
      {
        if (!(key->flag & HA_NOSAME) && info->s->base.auto_key != i+1)
        {
          mi_clear_key_active(share->state.key_map, i);
          info->update|= HA_STATE_CHANGED;
        }
      }

      if (!share->changed)
      {
	share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
	share->changed=1;			/* Update on close */
	if (!share->global_changed)
	{
	  share->global_changed=1;
	  share->state.open_count++;
	}
      }
      share->state.state= *info->state;
      error=mi_state_info_write(share->kfile,&share->state,1 | 2);
    }
    break;
  case HA_EXTRA_FORCE_REOPEN:
    pthread_mutex_lock(&THR_LOCK_myisam);
    share->last_version= 0L;			/* Impossible version */
    pthread_mutex_unlock(&THR_LOCK_myisam);
    break;
  case HA_EXTRA_PREPARE_FOR_DELETE:
    pthread_mutex_lock(&THR_LOCK_myisam);
    share->last_version= 0L;			/* Impossible version */
#ifdef __WIN__REMOVE_OBSOLETE_WORKAROUND
    /* Close the isam and data files as Win32 can't drop an open table */
    pthread_mutex_lock(&share->intern_lock);
    if (flush_key_blocks(share->key_cache, share->kfile,
			 (function == HA_EXTRA_FORCE_REOPEN ?
			  FLUSH_RELEASE : FLUSH_IGNORE_CHANGED)))
    {
      error=my_errno;
      share->changed=1;
      mi_print_error(info->s, HA_ERR_CRASHED);
      mi_mark_crashed(info);			/* Fatal error found */
    }
    if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
    {
      info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
      error=end_io_cache(&info->rec_cache);
    }
    if (info->lock_type != F_UNLCK && ! info->was_locked)
    {
      info->was_locked=info->lock_type;
      if (mi_lock_database(info,F_UNLCK))
	error=my_errno;
      info->lock_type = F_UNLCK;
    }
    if (share->kfile >= 0)
      _mi_decrement_open_count(info);
    if (share->kfile >= 0 && my_close(share->kfile,MYF(0)))
      error=my_errno;
    {
      LIST *list_element ;
      for (list_element=myisam_open_list ;
	   list_element ;
	   list_element=list_element->next)
      {
	MI_INFO *tmpinfo=(MI_INFO*) list_element->data;
	if (tmpinfo->s == info->s)
	{
	  if (tmpinfo->dfile >= 0 && my_close(tmpinfo->dfile,MYF(0)))
	    error = my_errno;
	  tmpinfo->dfile= -1;
	}
      }
    }
    share->kfile= -1;				/* Files aren't open anymore */
    pthread_mutex_unlock(&share->intern_lock);
#endif
    pthread_mutex_unlock(&THR_LOCK_myisam);
    break;
  case HA_EXTRA_FLUSH:
    if (!share->temporary)
      flush_key_blocks(share->key_cache, share->kfile, FLUSH_KEEP);
#ifdef HAVE_PWRITE
    _mi_decrement_open_count(info);
#endif
    if (share->not_flushed)
    {
      share->not_flushed=0;
      if (my_sync(share->kfile, MYF(0)))
	error= my_errno;
      if (my_sync(info->dfile, MYF(0)))
	error= my_errno;
      if (error)
      {
	share->changed=1;
        mi_print_error(info->s, HA_ERR_CRASHED);
	mi_mark_crashed(info);			/* Fatal error found */
      }
    }
    if (share->base.blobs)
      mi_alloc_rec_buff(info, -1, &info->rec_buff);
    break;
  case HA_EXTRA_NORMAL:				/* Theese isn't in use */
    info->quick_mode=0;
    break;
  case HA_EXTRA_QUICK:
    info->quick_mode=1;
    break;
  case HA_EXTRA_NO_ROWS:
    if (!share->state.header.uniques)
      info->opt_flag|= OPT_NO_ROWS;
    break;
  case HA_EXTRA_PRELOAD_BUFFER_SIZE:
    info->preload_buff_size= *((ulong *) extra_arg); 
    break;
  case HA_EXTRA_CHANGE_KEY_TO_UNIQUE:
  case HA_EXTRA_CHANGE_KEY_TO_DUP:
    mi_extra_keyflag(info, function);
    break;
  case HA_EXTRA_KEY_CACHE:
  case HA_EXTRA_NO_KEY_CACHE:
  default:
    break;
  }
  {
    char tmp[1];
    tmp[0]=function;
    myisam_log_command(MI_LOG_EXTRA,info,(byte*) tmp,1,error);
  }
  DBUG_RETURN(error);
} /* mi_extra */
int _mi_read_rnd_static_record(MI_INFO *info, uchar *buf,
			       my_off_t filepos,
			       my_bool skip_deleted_blocks)
{
  int locked,error,cache_read;
  uint cache_length;
  MYISAM_SHARE *share=info->s;
  DBUG_ENTER("_mi_read_rnd_static_record");

  cache_read=0;
  cache_length=0;
  if (info->opt_flag & WRITE_CACHE_USED &&
      (info->rec_cache.pos_in_file <= filepos || skip_deleted_blocks) &&
      flush_io_cache(&info->rec_cache))
    DBUG_RETURN(my_errno);
  if (info->opt_flag & READ_CACHE_USED)
  {						/* Cache in use */
    if (filepos == my_b_tell(&info->rec_cache) &&
	(skip_deleted_blocks || !filepos))
    {
      cache_read=1;				/* Read record using cache */
      cache_length=(uint) (info->rec_cache.read_end - info->rec_cache.read_pos);
    }
    else
      info->rec_cache.seek_not_done=1;		/* Filepos is changed */
  }
  locked=0;
  if (info->lock_type == F_UNLCK)
  {
    if (filepos >= info->state->data_file_length)
    {						/* Test if new records */
      if (_mi_readinfo(info,F_RDLCK,0))
	DBUG_RETURN(my_errno);
      locked=1;
    }
    else
    {						/* We don't nead new info */
      if ((! cache_read || share->base.reclength > cache_length) &&
	  share->tot_locks == 0)
      {						/* record not in cache */
	if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
		    MYF(MY_SEEK_NOT_DONE) | info->lock_wait))
	  DBUG_RETURN(my_errno);
	locked=1;
      }
    }
  }
  if (filepos >= info->state->data_file_length)
  {
    DBUG_PRINT("test",("filepos: %ld (%ld)  records: %ld  del: %ld",
		       (long) filepos/share->base.reclength, (long) filepos,
		       (long) info->state->records, (long) info->state->del));
    fast_mi_writeinfo(info);
    DBUG_RETURN(my_errno=HA_ERR_END_OF_FILE);
  }
  info->lastpos= filepos;
  info->nextpos= filepos+share->base.pack_reclength;

  if (! cache_read)			/* No cacheing */
  {
    if ((error=_mi_read_static_record(info,filepos,buf)))
    {
      if (error > 0)
	error=my_errno=HA_ERR_RECORD_DELETED;
      else
	error=my_errno;
    }
    DBUG_RETURN(error);
  }

  /*
    Read record with caching. If my_b_read() returns TRUE, less than the
    requested bytes have been read. In this case rec_cache.error is
    either -1 for a read error, or contains the number of bytes copied
    into the buffer.
  */
  error=my_b_read(&info->rec_cache,(uchar*) buf,share->base.reclength);
  if (info->s->base.pack_reclength != info->s->base.reclength && !error)
  {
    char tmp[8];				/* Skill fill bytes */
    error=my_b_read(&info->rec_cache,(uchar*) tmp,
		    info->s->base.pack_reclength - info->s->base.reclength);
  }
  if (locked)
    (void) _mi_writeinfo(info,0);		/* Unlock keyfile */
  if (!error)
  {
    if (!buf[0])
    {						/* Record is removed */
      DBUG_RETURN(my_errno=HA_ERR_RECORD_DELETED);
    }
						/* Found and may be updated */
    info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
    DBUG_RETURN(0);
  }
  /* error is TRUE. my_errno should be set if rec_cache.error == -1 */
  if (info->rec_cache.error != -1 || my_errno == 0)
  {
    /*
      If we could not get a full record, we either have a broken record,
      or are at end of file.
    */
    if (info->rec_cache.error == 0)
      my_errno= HA_ERR_END_OF_FILE;
    else
      my_errno= HA_ERR_WRONG_IN_RECORD;
  }
  DBUG_RETURN(my_errno);			/* Something wrong (EOF?) */
}
Beispiel #21
0
MYSQL * STDCALL
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
		   const char *passwd, const char *db,
		   uint port, const char *unix_socket,ulong client_flag)
{
  char name_buff[USERNAME_LENGTH];

  DBUG_ENTER("mysql_real_connect");
  DBUG_PRINT("enter",("host: %s  db: %s  user: %s",
		      host ? host : "(Null)",
		      db ? db : "(Null)",
		      user ? user : "******"));

  if (!host || !host[0])
    host= mysql->options.host;

  if (mysql->options.methods_to_use == MYSQL_OPT_USE_REMOTE_CONNECTION ||
      (mysql->options.methods_to_use == MYSQL_OPT_GUESS_CONNECTION &&
       host && *host && strcmp(host,LOCAL_HOST)))
    DBUG_RETURN(cli_mysql_real_connect(mysql, host, user, 
				       passwd, db, port, 
				       unix_socket, client_flag));

  mysql->methods= &embedded_methods;

  /* use default options */
  if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
  {
    mysql_read_default_options(&mysql->options,
			       (mysql->options.my_cnf_file ?
				mysql->options.my_cnf_file : "my"),
			       mysql->options.my_cnf_group);
    my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
    my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
    mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
  }

  if (!db || !db[0])
    db=mysql->options.db;

  if (!user || !user[0])
    user=mysql->options.user;

#ifndef NO_EMBEDDED_ACCESS_CHECKS
  if (!passwd)
  {
    passwd=mysql->options.password;
#if !defined(DONT_USE_MYSQL_PWD)
    if (!passwd)
      passwd=getenv("MYSQL_PWD");		/* get it from environment */
#endif
  }
  mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL;
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
  if (!user || !user[0])
  {
    read_user_name(name_buff);
    if (name_buff[0])
      user= name_buff;
  }

  if (!user)
    user= "";
   /* 
      We need to alloc some space for mysql->info but don't want to
      put extra 'my_free's in mysql_close.
      So we alloc it with the 'user' string to be freed at once
   */
  mysql->user= my_strdup(user, MYF(0));

  port=0;
  unix_socket=0;

  /* Send client information for access check */
  client_flag|=CLIENT_CAPABILITIES;
  if (client_flag & CLIENT_MULTI_STATEMENTS)
    client_flag|= CLIENT_MULTI_RESULTS;
  client_flag&= ~CLIENT_COMPRESS;
  if (db)
    client_flag|=CLIENT_CONNECT_WITH_DB;

  mysql->info_buffer= my_malloc(MYSQL_ERRMSG_SIZE, MYF(0));
  mysql->thd= create_embedded_thd(client_flag);

  init_embedded_mysql(mysql, client_flag);

  if (mysql_init_character_set(mysql))
    goto error;

  if (check_embedded_connection(mysql, db))
    goto error;

  mysql->server_status= SERVER_STATUS_AUTOCOMMIT;

  if (mysql->options.init_commands)
  {
    DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
    char **ptr= (char**)init_commands->buffer;
    char **end= ptr + init_commands->elements;

    for (; ptr<end; ptr++)
    {
      MYSQL_RES *res;
      if (mysql_query(mysql,*ptr))
	goto error;
      if (mysql->fields)
      {
	if (!(res= (*mysql->methods->use_result)(mysql)))
	  goto error;
	mysql_free_result(res);
      }
    }
  }

  DBUG_PRINT("exit",("Mysql handler: 0x%lx", (long) mysql));
  DBUG_RETURN(mysql);

error:
  DBUG_PRINT("error",("message: %u (%s)", mysql->net.last_errno,
		      mysql->net.last_error));
  {
    /* Free alloced memory */
    my_bool free_me=mysql->free_me;
    end_server(mysql);
    mysql->free_me=0;
    mysql_close(mysql);
    mysql->free_me=free_me;
  }
  DBUG_RETURN(0);
}
Beispiel #22
0
int heap_create(const char *name, HP_CREATE_INFO *create_info,
                HP_SHARE **res, my_bool *created_new_share)
{
    uint i, j, key_segs, max_length, length;
    HP_SHARE *share= 0;
    HA_KEYSEG *keyseg;
    HP_KEYDEF *keydef= create_info->keydef;
    uint reclength= create_info->reclength;
    uint keys= create_info->keys;
    ulong min_records= create_info->min_records;
    ulong max_records= create_info->max_records;
    DBUG_ENTER("heap_create");

    if (!create_info->internal_table)
    {
        mysql_mutex_lock(&THR_LOCK_heap);
        share= hp_find_named_heap(name);
        if (share && share->open_count == 0)
        {
            hp_free(share);
            share= 0;
        }
    }
    *created_new_share= (share == NULL);

    if (!share)
    {
        HP_KEYDEF *keyinfo;
        DBUG_PRINT("info",("Initializing new table"));

        /*
          We have to store sometimes uchar* del_link in records,
          so the record length should be at least sizeof(uchar*)
        */
        set_if_bigger(reclength, sizeof (uchar*));

        for (i= key_segs= max_length= 0, keyinfo= keydef; i < keys; i++, keyinfo++)
        {
            memset(&keyinfo->block, 0, sizeof(keyinfo->block));
            memset(&keyinfo->rb_tree, 0, sizeof(keyinfo->rb_tree));
            for (j= length= 0; j < keyinfo->keysegs; j++)
            {
                length+= keyinfo->seg[j].length;
                if (keyinfo->seg[j].null_bit)
                {
                    length++;
                    if (!(keyinfo->flag & HA_NULL_ARE_EQUAL))
                        keyinfo->flag|= HA_NULL_PART_KEY;
                    if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
                        keyinfo->rb_tree.size_of_element++;
                }
                switch (keyinfo->seg[j].type) {
                case HA_KEYTYPE_SHORT_INT:
                case HA_KEYTYPE_LONG_INT:
                case HA_KEYTYPE_FLOAT:
                case HA_KEYTYPE_DOUBLE:
                case HA_KEYTYPE_USHORT_INT:
                case HA_KEYTYPE_ULONG_INT:
                case HA_KEYTYPE_LONGLONG:
                case HA_KEYTYPE_ULONGLONG:
                case HA_KEYTYPE_INT24:
                case HA_KEYTYPE_UINT24:
                case HA_KEYTYPE_INT8:
                    keyinfo->seg[j].flag|= HA_SWAP_KEY;
                    break;
                case HA_KEYTYPE_VARBINARY1:
                    /* Case-insensitiveness is handled in coll->hash_sort */
                    keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
                /* fall_through */
                case HA_KEYTYPE_VARTEXT1:
                    keyinfo->flag|= HA_VAR_LENGTH_KEY;
                    length+= 2;
                    /* Save number of bytes used to store length */
                    keyinfo->seg[j].bit_start= 1;
                    break;
                case HA_KEYTYPE_VARBINARY2:
                /* Case-insensitiveness is handled in coll->hash_sort */
                /* fall_through */
                case HA_KEYTYPE_VARTEXT2:
                    keyinfo->flag|= HA_VAR_LENGTH_KEY;
                    length+= 2;
                    /* Save number of bytes used to store length */
                    keyinfo->seg[j].bit_start= 2;
                    /*
                      Make future comparison simpler by only having to check for
                      one type
                    */
                    keyinfo->seg[j].type= HA_KEYTYPE_VARTEXT1;
                    break;
                default:
                    break;
                }
            }
            keyinfo->length= length;
            length+= keyinfo->rb_tree.size_of_element +
                     ((keyinfo->algorithm == HA_KEY_ALG_BTREE) ? sizeof(uchar*) : 0);
            if (length > max_length)
                max_length= length;
            key_segs+= keyinfo->keysegs;
            if (keyinfo->algorithm == HA_KEY_ALG_BTREE)
            {
                key_segs++; /* additional HA_KEYTYPE_END segment */
                if (keyinfo->flag & HA_VAR_LENGTH_KEY)
                    keyinfo->get_key_length= hp_rb_var_key_length;
                else if (keyinfo->flag & HA_NULL_PART_KEY)
                    keyinfo->get_key_length= hp_rb_null_key_length;
                else
                    keyinfo->get_key_length= hp_rb_key_length;
            }
        }
        if (!(share= (HP_SHARE*) my_malloc(hp_key_memory_HP_SHARE,
                                           (uint) sizeof(HP_SHARE)+
                                           keys*sizeof(HP_KEYDEF)+
                                           key_segs*sizeof(HA_KEYSEG),
                                           MYF(MY_ZEROFILL))))
            goto err;
        share->keydef= (HP_KEYDEF*) (share + 1);
        share->key_stat_version= 1;
        keyseg= (HA_KEYSEG*) (share->keydef + keys);
        init_block(&share->block, reclength + 1, min_records, max_records);
        /* Fix keys */
        memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys));
        for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++)
        {
            keyinfo->seg= keyseg;
            memcpy(keyseg, keydef[i].seg,
                   (size_t) (sizeof(keyseg[0]) * keydef[i].keysegs));
            keyseg+= keydef[i].keysegs;

            if (keydef[i].algorithm == HA_KEY_ALG_BTREE)
            {
                /* additional HA_KEYTYPE_END keyseg */
                keyseg->type=     HA_KEYTYPE_END;
                keyseg->length=   sizeof(uchar*);
                keyseg->flag=     0;
                keyseg->null_bit= 0;
                keyseg++;

                init_tree(&keyinfo->rb_tree, 0, 0, sizeof(uchar*),
                          (qsort_cmp2)keys_compare, 1, NULL, NULL);
                keyinfo->delete_key= hp_rb_delete_key;
                keyinfo->write_key= hp_rb_write_key;
            }
            else
            {
                init_block(&keyinfo->block, sizeof(HASH_INFO), min_records,
                           max_records);
                keyinfo->delete_key= hp_delete_key;
                keyinfo->write_key= hp_write_key;
                keyinfo->hash_buckets= 0;
            }
            if ((keyinfo->flag & HA_AUTO_KEY) && create_info->with_auto_increment)
                share->auto_key= i + 1;
        }
        share->min_records= min_records;
        share->max_records= max_records;
        share->max_table_size= create_info->max_table_size;
        share->data_length= share->index_length= 0;
        share->reclength= reclength;
        share->blength= 1;
        share->keys= keys;
        share->max_key_length= max_length;
        share->changed= 0;
        share->auto_key= create_info->auto_key;
        share->auto_key_type= create_info->auto_key_type;
        share->auto_increment= create_info->auto_increment;
        share->create_time= (long) time((time_t*) 0);
        /* Must be allocated separately for rename to work */
        if (!(share->name= my_strdup(hp_key_memory_HP_SHARE,
                                     name, MYF(0))))
        {
            my_free(share);
            goto err;
        }
        if (!create_info->internal_table)
        {
            /*
              Do not initialize THR_LOCK object for internal temporary tables.
              It is not needed for such tables. Calling thr_lock_init() can
              cause scalability issues since it acquires global lock.
            */
            thr_lock_init(&share->lock);
            share->open_list.data= (void*) share;
            heap_share_list= list_add(heap_share_list,&share->open_list);
        }
        else
            share->delete_on_close= 1;
    }
    if (!create_info->internal_table)
    {
        if (create_info->pin_share)
            ++share->open_count;
        mysql_mutex_unlock(&THR_LOCK_heap);
    }

    *res= share;
    DBUG_RETURN(0);

err:
    if (!create_info->internal_table)
        mysql_mutex_unlock(&THR_LOCK_heap);
    DBUG_RETURN(1);
} /* heap_create */
Beispiel #23
0
int my_load_defaults(const char *conf_file, const char **groups,
                  int *argc, char ***argv, const char ***default_directories)
{
  DYNAMIC_ARRAY args;
  TYPELIB group;
  my_bool found_print_defaults= 0;
  uint args_used= 0;
  int error= 0;
  MEM_ROOT alloc;
  char *ptr,**res;
  struct handle_option_ctx ctx;
  const char **dirs;
  uint args_sep= my_getopt_use_args_separator ? 1 : 0;
  DBUG_ENTER("load_defaults");

  init_alloc_root(&alloc,512,0);
  if ((dirs= init_default_directories(&alloc)) == NULL)
    goto err;
  /*
    Check if the user doesn't want any default option processing
    --no-defaults is always the first option
  */
  if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
  {
    /* remove the --no-defaults argument and return only the other arguments */
    uint i, j;
    if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
				 (*argc + 1)*sizeof(char*))))
      goto err;
    res= (char**) (ptr+sizeof(alloc));
    res[0]= **argv;				/* Copy program name */
    j= 1;                 /* Start from 1 for the reset result args */
    if (my_getopt_use_args_separator)
    {
      /* set arguments separator */
      set_args_separator(&res[1]);
      j++;
    }
    for (i=2 ; i < (uint) *argc ; i++, j++)
      res[j]=argv[0][i];
    res[j]=0;					/* End pointer */
    /*
      Update the argc, if have not added args separator, then we have
      to decrease argc because we have removed the "--no-defaults".
    */
    if (!my_getopt_use_args_separator)
      (*argc)--;
    *argv=res;
    *(MEM_ROOT*) ptr= alloc;			/* Save alloc root for free */
    if (default_directories)
      *default_directories= dirs;
    DBUG_RETURN(0);
  }

  group.count=0;
  group.name= "defaults";
  group.type_names= groups;

  for (; *groups ; groups++)
    group.count++;

  if (my_init_dynamic_array(&args, sizeof(char*),*argc, 32))
    goto err;

  ctx.alloc= &alloc;
  ctx.args= &args;
  ctx.group= &group;

  if ((error= my_search_option_files(conf_file, argc, argv, &args_used,
                                     handle_default_option, (void *) &ctx,
                                     dirs)))
  {
    free_root(&alloc,MYF(0));
    DBUG_RETURN(error);
  }
  /*
    Here error contains <> 0 only if we have a fully specified conf_file
    or a forced default file
  */
  if (!(ptr=(char*) alloc_root(&alloc,sizeof(alloc)+
			       (args.elements + *argc + 1 + args_sep) *sizeof(char*))))
    goto err;
  res= (char**) (ptr+sizeof(alloc));

  /* copy name + found arguments + command line arguments to new array */
  res[0]= argv[0][0];  /* Name MUST be set, even by embedded library */
  memcpy((uchar*) (res+1), args.buffer, args.elements*sizeof(char*));
  /* Skip --defaults-xxx options */
  (*argc)-= args_used;
  (*argv)+= args_used;

  /*
    Check if we wan't to see the new argument list
    This options must always be the last of the default options
  */
  if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults"))
  {
    found_print_defaults=1;
    --*argc; ++*argv;				/* skip argument */
  }

  if (my_getopt_use_args_separator)
  {
    /* set arguments separator for arguments from config file and
       command line */
    set_args_separator(&res[args.elements+1]);
  }

  if (*argc)
    memcpy((uchar*) (res+1+args.elements+args_sep), (char*) ((*argv)+1),
	   (*argc-1)*sizeof(char*));
  res[args.elements+ *argc+args_sep]=0;                /* last null */

  (*argc)+=args.elements+args_sep;
  *argv= (char**) res;
  *(MEM_ROOT*) ptr= alloc;			/* Save alloc root for free */
  delete_dynamic(&args);
  if (found_print_defaults)
  {
    int i;
    printf("%s would have been started with the following arguments:\n",
	   **argv);
    for (i=1 ; i < *argc ; i++)
      if (!my_getopt_is_args_separator((*argv)[i])) /* skip arguments separator */
        printf("%s ", (*argv)[i]);
    puts("");
    exit(0);
  }

  if (default_directories)
    *default_directories= dirs;

  DBUG_RETURN(0);

 err:
  fprintf(stderr,"Fatal error in defaults handling. Program aborted\n");
  exit(1);
  return 0;					/* Keep compiler happy */
}
Beispiel #24
0
size_t my_pwrite(File Filedes, const uchar *Buffer, size_t Count,
                 my_off_t offset, myf MyFlags)
{
  size_t writtenbytes, written;
  uint errors;

  DBUG_ENTER("my_pwrite");
  DBUG_PRINT("my",("fd: %d  Seek: %llu  Buffer: %p  Count: %lu  MyFlags: %d",
             Filedes, offset, Buffer, (ulong)Count, MyFlags));
  errors= 0;
  written= 0;

  for (;;)
  {
#if !defined (HAVE_PREAD) && !defined (_WIN32)
    int error;
    writtenbytes= (size_t) -1;
    mysql_mutex_lock(&my_file_info[Filedes].mutex);
    error= (lseek(Filedes, offset, MY_SEEK_SET) != (my_off_t) -1 &&
            (writtenbytes= write(Filedes, Buffer, Count)) == Count);
    mysql_mutex_unlock(&my_file_info[Filedes].mutex);
    if (error)
      break;
#elif defined (_WIN32)
    writtenbytes= my_win_pwrite(Filedes, Buffer, Count, offset);
#else
    writtenbytes= pwrite(Filedes, Buffer, Count, offset);
#endif
    if(writtenbytes == Count)
      break;
    my_errno= errno;
    if (writtenbytes != (size_t) -1)
    {
      written+= writtenbytes;
      Buffer+= writtenbytes;
      Count-= writtenbytes;
      offset+= writtenbytes;
    }
    DBUG_PRINT("error",("Write only %u bytes", (uint) writtenbytes));
#ifndef NO_BACKGROUND

    if (my_thread_var->abort)
      MyFlags&= ~ MY_WAIT_IF_FULL;		/* End if aborted by user */

    if ((my_errno == ENOSPC || my_errno == EDQUOT) &&
        (MyFlags & MY_WAIT_IF_FULL))
    {
      wait_for_free_space(my_filename(Filedes), errors);
      errors++;
      continue;
    }
    if ((writtenbytes && writtenbytes != (size_t) -1) || my_errno == EINTR)
      continue;					/* Retry */
#endif
    if (MyFlags & (MY_NABP | MY_FNABP))
    {
      if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
      {
        char errbuf[MYSYS_STRERROR_SIZE];
        my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG), my_filename(Filedes),
                 my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno));
      }
      DBUG_RETURN(MY_FILE_ERROR);		/* Error on read */
    }
    else
      break;					/* Return bytes written */
  }
  DBUG_EXECUTE_IF("check", my_seek(Filedes, -1, SEEK_SET, MYF(0)););
void stmt_fetch_init(Stmt_fetch *fetch, unsigned stmt_no_arg,
const char *query_arg)
{
 unsigned long type= CURSOR_TYPE_READ_ONLY;
 int rc;
 unsigned i;
 MYSQL_RES *metadata;
 DBUG_ENTER("stmt_fetch_init");

 /* Save query and statement number for error messages */
 fetch->stmt_no= stmt_no_arg;
 fetch->query= query_arg;

 fetch->handle= mysql_stmt_init(mysql);

 rc= mysql_stmt_prepare(fetch->handle, fetch->query, (ulong)strlen(fetch->query));
 check_execute(fetch->handle, rc);

 /*
 The attribute is sent to server on execute and asks to open read-only
 for result set
 */
 mysql_stmt_attr_set(fetch->handle, STMT_ATTR_CURSOR_TYPE,
 (const void*) &type);

 rc= mysql_stmt_execute(fetch->handle);
 check_execute(fetch->handle, rc);

 /* Find out total number of columns in result set */
 metadata= mysql_stmt_result_metadata(fetch->handle);
 fetch->column_count= mysql_num_fields(metadata);
 mysql_free_result(metadata);

 /*
 Now allocate bind handles and buffers for output data:
 calloc memory to reduce number of MYSQL_BIND members we need to
 set up.
 */

 fetch->bind_array= (MYSQL_BIND *) calloc(1, sizeof(MYSQL_BIND) *
 fetch->column_count);
 fetch->out_data= (char**) calloc(1, sizeof(char*) * fetch->column_count);
 fetch->out_data_length= (ulong*) calloc(1, sizeof(ulong) *
                                         fetch->column_count);
 for (i= 0; i < fetch->column_count; ++i)
 {
   fetch->out_data[i]= (char*) calloc(1, MAX_COLUMN_LENGTH);
   fetch->bind_array[i].buffer_type= MYSQL_TYPE_STRING;
   fetch->bind_array[i].buffer= fetch->out_data[i];
   fetch->bind_array[i].buffer_length= MAX_COLUMN_LENGTH;
   fetch->bind_array[i].length= fetch->out_data_length + i;
 }

 mysql_stmt_bind_result(fetch->handle, fetch->bind_array);

 fetch->row_count= 0;
 fetch->is_open= TRUE;

 /* Ready for reading rows */
 DBUG_VOID_RETURN;
}
Beispiel #26
0
size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
                myf MyFlags)
{
  size_t readbytes;
  size_t total_readbytes= 0;
  int error= 0;
#if !defined (HAVE_PREAD) && !defined (_WIN32)
  int save_errno;
#endif
  DBUG_ENTER("my_pread");
  DBUG_PRINT("my",("fd: %d  Seek: %llu  Buffer: %p  Count: %lu  MyFlags: %d",
             Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags));
  for (;;)
  {
    errno= 0;    /* Linux, Windows don't reset this on EOF/success */
#if !defined (HAVE_PREAD) && !defined (_WIN32)
    mysql_mutex_lock(&my_file_info[Filedes].mutex);
    readbytes= (uint) -1;
    error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 ||
           (readbytes= read(Filedes, Buffer, Count)) != Count);
    save_errno= errno;
    mysql_mutex_unlock(&my_file_info[Filedes].mutex);
    if (error)
      errno= save_errno;
#else
#if defined(_WIN32)
    readbytes= my_win_pread(Filedes, Buffer, Count, offset);
#else 
    readbytes= pread(Filedes, Buffer, Count, offset);
#endif
    error= (readbytes != Count);
#endif
    if (readbytes > 0)
      total_readbytes+= readbytes;

    if(error)
    {
      if (readbytes > 0 && readbytes < Count && errno == 0)
      {
        /*
          pread() may return less bytes than requested even if enough bytes are
          available according to the Linux man page.
          This makes determining the end-of-file condition a bit harder.
          We just do another pread() call to see if more bytes can be read,
          since all my_pread() users expect it to always return all available
          bytes. For end-of-file 0 bytes is returned. This can never be the case
          for a partial read, since according to the man page, -1 is returned
          with errno set to EINTR if no data has been read.
        */
        Buffer+= readbytes;
        offset+= readbytes;
        Count-= readbytes;

        continue;
      }

      my_errno= errno ? errno : -1;
      if (errno == 0 || (readbytes != (size_t) -1 &&
                      (MyFlags & (MY_NABP | MY_FNABP))))
         my_errno= HA_ERR_FILE_TOO_SHORT;

      DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d",
                            (int) readbytes, (uint) Count,Filedes,my_errno));

      if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
      {
        DBUG_PRINT("debug", ("my_pread() was interrupted and returned %d",
                             (int) readbytes));
        continue;                              /* Interrupted */
      }

      if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
      {
        char errbuf[MYSYS_STRERROR_SIZE];
        if (readbytes == (size_t) -1)
          my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), my_filename(Filedes),
                   my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno));
        else if (MyFlags & (MY_NABP | MY_FNABP))
          my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), my_filename(Filedes),
                   my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno));
      }
      if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP)))
        DBUG_RETURN(MY_FILE_ERROR);         /* Return with error */
    }
    if (MyFlags & (MY_NABP | MY_FNABP))
      DBUG_RETURN(0);                      /* Read went ok; Return 0 */
    DBUG_RETURN(total_readbytes);                /* purecov: inspected */
  }
} /* my_pread */
Beispiel #27
0
static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, 
                            uint key_length, my_off_t page, my_off_t *new_page, 
                            int ins_level, int level)
{
  uchar *k;
  uint nod_flag;
  uchar *page_buf;
  int res;
  DBUG_ENTER("rtree_insert_req");

  if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length + 
                                     MI_MAX_KEY_BUFF)))
  {
    my_errno = HA_ERR_OUT_OF_MEM;
    DBUG_RETURN(-1); /* purecov: inspected */
  }
  if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
    goto err1;
  nod_flag = mi_test_if_nod(page_buf);
  DBUG_PRINT("rtree", ("page: %lu  level: %d  ins_level: %d  nod_flag: %u",
                       (ulong) page, level, ins_level, nod_flag));

  if ((ins_level == -1 && nod_flag) ||       /* key: go down to leaf */
      (ins_level > -1 && ins_level > level)) /* branch: go down to ins_level */
  { 
    if ((k = rtree_pick_key(info, keyinfo, key, key_length, page_buf, 
                             nod_flag)) == NULL)
      goto err1;
    switch ((res = rtree_insert_req(info, keyinfo, key, key_length, 
                     _mi_kpos(nod_flag, k), new_page, ins_level, level + 1)))
    {
      case 0: /* child was not split */
      {
        rtree_combine_rect(keyinfo->seg, k, key, k, key_length);
        if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
          goto err1;
        goto ok;
      }
      case 1: /* child was split */
      {
        uchar *new_key = page_buf + keyinfo->block_length + nod_flag;
        /* set proper MBR for key */
        if (rtree_set_key_mbr(info, keyinfo, k, key_length, 
                            _mi_kpos(nod_flag, k)))
          goto err1;
        /* add new key for new page */
        _mi_kpointer(info, new_key - nod_flag, *new_page);
        if (rtree_set_key_mbr(info, keyinfo, new_key, key_length, *new_page))
          goto err1;
        res = rtree_add_key(info, keyinfo, new_key, key_length, 
                           page_buf, new_page);
        if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
          goto err1;
        goto ok;
      }
      default:
      case -1: /* error */
      {
        goto err1;
      }
    }
  }
  else
  { 
    res = rtree_add_key(info, keyinfo, key, key_length, page_buf, new_page);
    if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
      goto err1;
    goto ok;
  }

ok:
  my_afree((uchar*)page_buf);
  DBUG_RETURN(res);

err1:
  my_afree((uchar*)page_buf);
  DBUG_RETURN(-1); /* purecov: inspected */
}
Beispiel #28
0
MY_DIR	*my_dir(const char *path, myf MyFlags)
{
  char          *buffer;
  MY_DIR        *result= 0;
  FILEINFO      finfo;
  DYNAMIC_ARRAY *dir_entries_storage;
  MEM_ROOT      *names_storage;
#ifdef __BORLANDC__
  struct ffblk       find;
#else
  struct _finddata_t find;
#endif
  ushort	mode;
  char		tmp_path[FN_REFLEN],*tmp_file,attrib;
#ifdef _WIN64
  __int64       handle;
#else
  long		handle;
#endif
  DBUG_ENTER("my_dir");
  DBUG_PRINT("my",("path: '%s' stat: %d  MyFlags: %d",path,MyFlags));

  /* Put LIB-CHAR as last path-character if not there */
  tmp_file=tmp_path;
  if (!*path)
    *tmp_file++ ='.';				/* From current dir */
  tmp_file= strnmov(tmp_file, path, FN_REFLEN-5);
  if (tmp_file[-1] == FN_DEVCHAR)
    *tmp_file++= '.';				/* From current dev-dir */
  if (tmp_file[-1] != FN_LIBCHAR)
    *tmp_file++ =FN_LIBCHAR;
  tmp_file[0]='*';				/* Windows needs this !??? */
  tmp_file[1]='.';
  tmp_file[2]='*';
  tmp_file[3]='\0';

  if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + 
                          ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) +
                          sizeof(MEM_ROOT), MyFlags)))
    goto error;

  dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); 
  names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) +
                             ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)));
  
  if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO),
                            ENTRIES_START_SIZE, ENTRIES_INCREMENT))
  {
    my_free((uchar*) buffer,MYF(0));
    goto error;
  }
  init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE);
  
  /* MY_DIR structure is allocated and completly initialized at this point */
  result= (MY_DIR*)buffer;

#ifdef __BORLANDC__
  if ((handle= findfirst(tmp_path,&find,0)) == -1L)
#else
  if ((handle=_findfirst(tmp_path,&find)) == -1L)
#endif
  {
    DBUG_PRINT("info", ("findfirst returned error, errno: %d", errno));
    if  (errno != EINVAL)
      goto error;
    /*
      Could not read the directory, no read access.
      Probably because by "chmod -r".
      continue and return zero files in dir
    */
  }
  else
  {

    do
    {
#ifdef __BORLANDC__
      attrib= find.ff_attrib;
#else
      attrib= find.attrib;
      /*
        Do not show hidden and system files which Windows sometimes create.
        Note. Because Borland's findfirst() is called with the third
        argument = 0 hidden/system files are excluded from the search.
      */
      if (attrib & (_A_HIDDEN | _A_SYSTEM))
        continue;
#endif
#ifdef __BORLANDC__
      if (!(finfo.name= strdup_root(names_storage, find.ff_name)))
        goto error;
#else
      if (!(finfo.name= strdup_root(names_storage, find.name)))
        goto error;
#endif
      if (MyFlags & MY_WANT_STAT)
      {
        if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage,
                                                 sizeof(MY_STAT))))
          goto error;

        bzero(finfo.mystat, sizeof(MY_STAT));
#ifdef __BORLANDC__
        finfo.mystat->st_size=find.ff_fsize;
#else
        finfo.mystat->st_size=find.size;
#endif
        mode= MY_S_IREAD;
        if (!(attrib & _A_RDONLY))
          mode|= MY_S_IWRITE;
        if (attrib & _A_SUBDIR)
          mode|= MY_S_IFDIR;
        finfo.mystat->st_mode= mode;
#ifdef __BORLANDC__
        finfo.mystat->st_mtime= ((uint32) find.ff_ftime);
#else
        finfo.mystat->st_mtime= ((uint32) find.time_write);
#endif
      }
      else
        finfo.mystat= NULL;

      if (push_dynamic(dir_entries_storage, (uchar*)&finfo))
        goto error;
    }
#ifdef __BORLANDC__
    while (findnext(&find) == 0);
#else
    while (_findnext(handle,&find) == 0);

    _findclose(handle);
#endif
  }

  result->dir_entry= (FILEINFO *)dir_entries_storage->buffer;
  result->number_off_files= dir_entries_storage->elements;

  if (!(MyFlags & MY_DONT_SORT))
    my_qsort((void *) result->dir_entry, result->number_off_files,
          sizeof(FILEINFO), (qsort_cmp) comp_names);
  DBUG_PRINT("exit", ("found %d files", result->number_off_files));
  DBUG_RETURN(result);
error:
  my_errno=errno;
#ifndef __BORLANDC__
  if (handle != -1)
      _findclose(handle);
#endif
  my_dirend(result);
  if (MyFlags & MY_FAE+MY_WME)
    my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno);
  DBUG_RETURN((MY_DIR *) NULL);
} /* my_dir */
Beispiel #29
0
static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, 
                           uint key_length, my_off_t page, uint *page_size, 
                           stPageList *ReinsertList, int level)
{
  uchar *k;
  uchar *last;
  ulong i;
  uint nod_flag;
  uchar *page_buf;
  int res;
  DBUG_ENTER("rtree_delete_req");

  if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
  {
    my_errno = HA_ERR_OUT_OF_MEM;
    DBUG_RETURN(-1); /* purecov: inspected */
  }
  if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
    goto err1;
  nod_flag = mi_test_if_nod(page_buf);
  DBUG_PRINT("rtree", ("page: %lu  level: %d  nod_flag: %u",
                       (ulong) page, level, nod_flag));

  k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
  last = rt_PAGE_END(page_buf);

  for (i = 0; k < last; k = rt_PAGE_NEXT_KEY(k, key_length, nod_flag), ++i)
  {
    if (nod_flag)
    { 
      /* not leaf */
      if (!rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_WITHIN))
      {
        switch ((res = rtree_delete_req(info, keyinfo, key, key_length, 
                  _mi_kpos(nod_flag, k), page_size, ReinsertList, level + 1)))
        {
          case 0: /* deleted */
          { 
            /* test page filling */
            if (*page_size + key_length >= rt_PAGE_MIN_SIZE(keyinfo->block_length)) 
            { 
              /* OK */
              /* Calculate a new key value (MBR) for the shrinked block. */
              if (rtree_set_key_mbr(info, keyinfo, k, key_length, 
                                  _mi_kpos(nod_flag, k)))
                goto err1;
              if (_mi_write_keypage(info, keyinfo, page,
                                    DFLT_INIT_HITS, page_buf))
                goto err1;
            }
            else
            { 
              /*
                Too small: delete key & add it descendant to reinsert list.
                Store position and level of the block so that it can be
                accessed later for inserting the remaining keys.
              */
              DBUG_PRINT("rtree", ("too small. move block to reinsert list"));
              if (rtree_fill_reinsert_list(ReinsertList, _mi_kpos(nod_flag, k),
                                           level + 1))
                goto err1;
              /*
                Delete the key that references the block. This makes the
                block disappear from the index. Hence we need to insert
                its remaining keys later. Note: if the block is a branch
                block, we do not only remove this block, but the whole
                subtree. So we need to re-insert its keys on the same
                level later to reintegrate the subtrees.
              */
              rtree_delete_key(info, page_buf, k, key_length, nod_flag);
              if (_mi_write_keypage(info, keyinfo, page,
                                    DFLT_INIT_HITS, page_buf))
                goto err1;
              *page_size = mi_getint(page_buf);
            }
            
            goto ok;
          }
          case 1: /* not found - continue searching */
          {
            break;
          }
          case 2: /* vacuous case: last key in the leaf */
          {
            rtree_delete_key(info, page_buf, k, key_length, nod_flag);
            if (_mi_write_keypage(info, keyinfo, page,
                                  DFLT_INIT_HITS, page_buf))
              goto err1;
            *page_size = mi_getint(page_buf);
            res = 0;
            goto ok;
          }
          default: /* error */
          case -1:
          {
            goto err1;
          }
        }
      }
    }
    else  
    {
      /* leaf */
      if (!rtree_key_cmp(keyinfo->seg, key, k, key_length, MBR_EQUAL | MBR_DATA))
      {
        rtree_delete_key(info, page_buf, k, key_length, nod_flag);
        *page_size = mi_getint(page_buf);
        if (*page_size == 2) 
        {
          /* last key in the leaf */
          res = 2;
          if (_mi_dispose(info, keyinfo, page, DFLT_INIT_HITS))
            goto err1;
        }
        else
        {
          res = 0;
          if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
            goto err1;
        }
        goto ok;
      }
    }
  }
  res = 1;

ok:
  my_afree((uchar*)page_buf);
  DBUG_RETURN(res);

err1:
  my_afree((uchar*)page_buf);
  DBUG_RETURN(-1); /* purecov: inspected */
}
Beispiel #30
0
int ma_ssl_verify_fingerprint(SSL *ssl)
{
  X509 *cert= SSL_get_peer_certificate(ssl);
  MYSQL *mysql= (MYSQL *)SSL_get_app_data(ssl);
  unsigned char fingerprint[EVP_MAX_MD_SIZE];
  EVP_MD *digest;
  unsigned int fp_length;

  DBUG_ENTER("ma_ssl_verify_fingerprint");

  if (!cert)
  {
    my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
                        ER(CR_SSL_CONNECTION_ERROR), 
                        "Unable to get server certificate");
    DBUG_RETURN(1);
  }

  digest= (EVP_MD *)EVP_sha1();
  fp_length= sizeof(fingerprint);

  if (!ma_get_cert_fingerprint(cert, digest, fingerprint, &fp_length))
  {
    my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
                        ER(CR_SSL_CONNECTION_ERROR), 
                        "Unable to get finger print of server certificate");
    DBUG_RETURN(1);
  }

  /* single finger print was specified */
  if (mysql->options.extension->ssl_fp)
  {
    if (ma_check_fingerprint(fingerprint, fp_length, mysql->options.extension->ssl_fp,
                             strlen(mysql->options.extension->ssl_fp)))
    {
      my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
                          ER(CR_SSL_CONNECTION_ERROR), 
                          "invalid finger print of server certificate");
      DBUG_RETURN(1);
    }
  }

  /* white list of finger prints was specified */
  if (mysql->options.extension->ssl_fp_list)
  {
    FILE *fp;
    char buff[255];

    if (!(fp = my_fopen(mysql->options.extension->ssl_fp_list ,O_RDONLY, MYF(0))))
    {
      my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
                          ER(CR_SSL_CONNECTION_ERROR), 
                          "Can't open finger print list");
      DBUG_RETURN(1);
    }

    while (fgets(buff, sizeof(buff)-1, fp))
    {
      /* remove trailing new line character */
      char *pos= strchr(buff, '\r');
      if (!pos)
        pos= strchr(buff, '\n');
      if (pos)
        *pos= '\0';
        
      if (!ma_check_fingerprint(fingerprint, fp_length, buff, strlen(buff)))
      {
        /* finger print is valid: close file and exit */
        my_fclose(fp, MYF(0));
        DBUG_RETURN(0);
      }
    }

    /* No finger print matched - close file and return error */
    my_fclose(fp, MYF(0));
    my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
                 ER(CR_SSL_CONNECTION_ERROR), 
                 "invalid finger print of server certificate");
    DBUG_RETURN(1);
  }
  DBUG_RETURN(0);
}