Ejemplo n.º 1
0
int my_rename(const char *from, const char *to, myf MyFlags)
{
  int error = 0;
  DBUG_ENTER("my_rename");
  DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));

#if defined(HAVE_FILE_VERSIONS)
  {				/* Check that there isn't a old file */
    int save_errno;
    MY_STAT my_stat_result;
    save_errno=my_errno;
    if (my_stat(to,&my_stat_result,MYF(0)))
    {
      my_errno=EEXIST;
      error= -1;
      if (MyFlags & MY_FAE+MY_WME)
      {
        char errbuf[MYSYS_STRERROR_SIZE];
        my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG), from, to,
                 my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno));
      }
      DBUG_RETURN(error);
    }
    my_errno=save_errno;
  }
#endif
#if defined(__WIN__)
  if(!MoveFileEx(from, to, MOVEFILE_COPY_ALLOWED|
                           MOVEFILE_REPLACE_EXISTING))
  {
    my_osmaperr(GetLastError());
#else
  if (rename(from,to))
  {
#endif
    my_errno=errno;
    error = -1;
    if (MyFlags & (MY_FAE+MY_WME))
    {
      char errbuf[MYSYS_STRERROR_SIZE];
      my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG), from, to,
               my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno));
    }
  }
  else if (MyFlags & MY_SYNC_DIR)
  {
#ifdef NEED_EXPLICIT_SYNC_DIR
    /* do only the needed amount of syncs: */
    char dir_from[FN_REFLEN], dir_to[FN_REFLEN];
    size_t dir_from_length, dir_to_length;
    dirname_part(dir_from, from, &dir_from_length);
    dirname_part(dir_to, to, &dir_to_length);
    if (my_sync_dir(dir_from, MyFlags) ||
        (strcmp(dir_from, dir_to) &&
         my_sync_dir(dir_to, MyFlags)))
      error= -1;
#endif
  }
  DBUG_RETURN(error);
} /* my_rename */
Ejemplo n.º 2
0
int my_rename(const char *from, const char *to, myf MyFlags)
{
  int error = 0;
  DBUG_ENTER("my_rename");
  DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));

#if defined(HAVE_FILE_VERSIONS)
  {				/* Check that there isn't a old file */
    int save_errno;
    MY_STAT my_stat_result;
    save_errno=my_errno;
    if (my_stat(to,&my_stat_result,MYF(0)))
    {
      my_errno=EEXIST;
      error= -1;
      if (MyFlags & MY_FAE+MY_WME)
	my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG),from,to,my_errno);
      DBUG_RETURN(error);
    }
    my_errno=save_errno;
  }
#endif
#if defined(HAVE_RENAME)
#if defined(__WIN__)
  /*
    On windows we can't rename over an existing file:
    Remove any conflicting files:
  */
  (void) my_delete(to, MYF(0));
#endif
  if (rename(from,to))
#else
  if (link(from, to) || unlink(from))
#endif
  {
    my_errno=errno;
    error = -1;
    if (MyFlags & (MY_FAE+MY_WME))
      my_error(EE_LINK, MYF(ME_BELL+ME_WAITTANG),from,to,my_errno);
  }
  else if (MyFlags & MY_SYNC_DIR)
  {
#ifdef NEED_EXPLICIT_SYNC_DIR
    /* do only the needed amount of syncs: */
    char dir_from[FN_REFLEN], dir_to[FN_REFLEN];
    size_t dir_from_length, dir_to_length;
    dirname_part(dir_from, from, &dir_from_length);
    dirname_part(dir_to, to, &dir_to_length);
    if (my_sync_dir(dir_from, MyFlags) ||
        (strcmp(dir_from, dir_to) &&
         my_sync_dir(dir_to, MyFlags)))
      error= -1;
#endif
  }
  DBUG_RETURN(error);
} /* my_rename */
Ejemplo n.º 3
0
my_string fn_same(char *to, const char *name, int flag)
{
  char dev[FN_REFLEN];
  const char *ext;
  DBUG_ENTER("fn_same");
  DBUG_PRINT("enter",("to: %s  name: %s  flag: %d",to,name,flag));

  if ((ext=strrchr(name+dirname_part(dev,name),FN_EXTCHAR)) == 0)
    ext="";

  DBUG_RETURN(fn_format(to,to,dev,ext,flag));
} /* fn_same */
Ejemplo n.º 4
0
char * my_path(char * to, const char *progname,
               const char *own_pathname_part)
{
  char *start, *end, *prog;
  size_t to_length;
  DBUG_ENTER("my_path");

  start=to;					/* Return this */
  if (progname && (dirname_part(to, progname, &to_length) ||
		   find_file_in_path(to,progname) ||
		   ((prog=getenv("_")) != 0 &&
                    dirname_part(to, prog, &to_length))))
  {
    (void) intern_filename(to,to);
    if (!test_if_hard_path(to))
    {
      if (!my_getwd(curr_dir,FN_REFLEN,MYF(0)))
	bchange((uchar*) to, 0, (uchar*) curr_dir, strlen(curr_dir), strlen(to)+1);
    }
  }
  else
  {
    if ((end = getenv("MY_BASEDIR_VERSION")) == 0 &&
	(end = getenv("MY_BASEDIR")) == 0)
    {
#ifdef DEFAULT_BASEDIR
      end= (char*) DEFAULT_BASEDIR;
#else
      end= (char*) "/my/";
#endif
    }
    (void) intern_filename(to,end);
    to=strend(to);
    if (to != start && to[-1] != FN_LIBCHAR)
      *to++ = FN_LIBCHAR;
    (void) strmov(to,own_pathname_part);
  }
  DBUG_PRINT("exit",("to: '%s'",start));
  DBUG_RETURN(start);
} /* my_path */
Ejemplo n.º 5
0
char *intern_filename(char *to, const char *from)
{
  size_t length, to_length;
  char buff[FN_REFLEN];
  if (from == to)
  {						/* Dirname may destroy from */
    strmov(buff,from);
    from=buff;
  }
  length= dirname_part(to, from, &to_length);	/* Copy dirname & fix chars */
  (void) strmov(to + to_length,from+length);
  return (to);
} /* intern_filename */
Ejemplo n.º 6
0
my_string unpack_filename(my_string to, const char *from)
{
  uint length,n_length;
  char buff[FN_REFLEN];
  DBUG_ENTER("unpack_filename");

  length=dirname_part(buff,from);		/* copy & convert dirname */
  n_length=unpack_dirname(buff,buff);
  if (n_length+strlen(from+length) < FN_REFLEN)
  {
    (void) strmov(buff+n_length,from+length);
    (void) system_filename(to,buff);		/* Fix to usably filename */
  }
  else
    (void) system_filename(to,from);		/* Fix to usably filename */
  DBUG_RETURN(to);
} /* unpack_filename */
Ejemplo n.º 7
0
size_t unpack_filename(char * to, const char *from)
{
  size_t length, n_length, buff_length;
  char buff[FN_REFLEN + 1];
  DBUG_ENTER("unpack_filename");

  length=dirname_part(buff, from, &buff_length);/* copy & convert dirname */
  n_length=unpack_dirname(buff,buff);
  if (n_length+strlen(from+length) < FN_REFLEN)
  {
    (void) strmov(buff+n_length,from+length);
    length= system_filename(to,buff);		/* Fix to usably filename */
  }
  else
    length= system_filename(to,from);		/* Fix to usably filename */
  DBUG_RETURN(length);
} /* unpack_filename */
Ejemplo n.º 8
0
my_string fn_ext(const char *name)
{
  register my_string pos,gpos;
  DBUG_ENTER("fn_ext");
  DBUG_PRINT("mfunkt",("name: '%s'",name));

#if defined(FN_DEVCHAR) || defined(FN_C_AFTER_DIR)
  {
    char buff[FN_REFLEN];
    gpos=(my_string) name+dirname_part(buff,(char*) name);
  }
#else
  if (!(gpos=strrchr(name,FNLIBCHAR)))
    gpos=name;
#endif
  pos=strchr(gpos,FN_EXTCHAR);
  DBUG_RETURN (pos ? pos : strend(gpos));
} /* fn_ext */
Ejemplo n.º 9
0
char *fn_ext(const char *name)
{
  register const char *pos, *gpos;
  DBUG_ENTER("fn_ext");
  DBUG_PRINT("mfunkt",("name: '%s'",name));

#if defined(FN_DEVCHAR) || defined(BASKSLASH_MBTAIL)
  {
    char buff[FN_REFLEN];
    size_t res_length;
    gpos= name+ dirname_part(buff,(char*) name, &res_length);
  }
#else
  if (!(gpos= strrchr(name, FN_LIBCHAR)))
    gpos= name;
#endif
  pos=strchr(gpos,FN_EXTCHAR);
  DBUG_RETURN((char*) (pos ? pos : strend(gpos)));
} /* fn_ext */
Ejemplo n.º 10
0
my_string intern_filename(my_string to, const char *from)
{
#ifndef VMS
  {
    uint length;
    char buff[FN_REFLEN];
    if (from == to)
    {						/* Dirname may destroy from */
      strmov(buff,from);
      from=buff;
    }
    length=dirname_part(to,from);			/* Copy dirname & fix chars */
    (void) strcat(to,from+length);
    return (to);
  }
#else	/* VMS */

	/* change 'dev:[lib]xxx' to 'dev:lib/xxx' */
	/* change 'dev:xxx' to 'dev:xxx' */
	/* change 'dev:x/y/[.lib]' to 'dev:x/y/lib/ */
	/* change '[.lib]' to './lib/' */
	/* change '[x.y]' or '[x.][y]' or '[x][.y]' to '/x/y/' */
	/* change '[000000.x] or [x.000000]' to '/x/' */

  int par_length,root_length;
  my_string pos,from_pos,to_pos,end_pos;
  char buff[FN_REFLEN];

  convert_dirname(buff,from,NullS);		/* change '<>' to '[]' */
  from_pos=buff;
  if ((pos=strrchr(from_pos,FN_DEVCHAR)))	/* Skipp device part */
  {
    pos++;
    to_pos=strnmov(to,from_pos,(size_s) (pos-from_pos));
    from_pos=pos;
  }
  else
    to_pos=to;

  root_length=strlen(FN_C_ROOT_DIR);
  if ((pos = strchr(from_pos,FN_C_BEFORE_DIR)) &&
      (end_pos = strrchr(pos+1,FN_C_AFTER_DIR)))
  {
    to_pos=strnmov(to_pos,from_pos,(size_s) (pos-from_pos));
				/* Copy all between ':' and '[' */
    from_pos=pos+1;
    if (strinstr(from_pos,FN_C_ROOT_DIR) == 1 &&
	(from_pos[root_length] == FN_C_DIR_SEP ||
	 from_pos[root_length] == FN_C_AFTER_DIR))
    {
      from_pos+=root_length+1;
    }
    else if (*from_pos == FN_C_DIR_SEP)
      *(to_pos++) = FN_CURLIB;			/* Set ./ first */
    *(to_pos++) = FN_LIBCHAR;

    par_length=strlen(FN_C_PARENT_DIR);
    pos=to_pos;
    for (; from_pos <= end_pos ; from_pos++)
    {
      switch (*from_pos) {
      case FN_C_DIR_SEP:
      case FN_C_AFTER_DIR:
	if (pos != to_pos)
	{
	  if ((int) (to_pos-pos) == root_length &&
	      is_suffix(pos,FN_C_ROOT_DIR))
	    to_pos=pos;				/* remove root-pos */
	  else
	  {
	    *(to_pos++)=FN_LIBCHAR;		/* Find lib */
	    pos=to_pos;
	  }
	}
	break;
      case FN_C_BEFORE_DIR:
	break;
      case '-':					/* *(FN_C_PARENT_DIR): */
	if (to_pos[-1] == FN_LIBCHAR &&
	    strncmp(from_pos,FN_C_PARENT_DIR,par_length) == 0)
	{					/* Change '-' to '..' */
	  to_pos=strmov(to_pos,FN_PARENTDIR);
	  *(to_pos++)=FN_LIBCHAR;
	  pos=to_pos;
	  from_pos+=par_length-1;
	  break;
	}
	/* Fall through */
      default:
	*(to_pos++)= *from_pos;
	break;
      }
    }
  }
  (void) strmov(to_pos,from_pos);
  return (to);
#endif /* VMS */
} /* intern_filename */
Ejemplo n.º 11
0
char * fn_format(char * to, const char *name, const char *dir,
		    const char *extension, uint flag)
{
  char dev[FN_REFLEN], buff[FN_REFLEN], *pos, *startpos;
  const char *ext;
  reg1 size_t length;
  size_t dev_length;
  my_bool not_used;
  DBUG_ENTER("fn_format");
  DBUG_ASSERT(name != NULL);
  DBUG_ASSERT(extension != NULL);
  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=(char *) name), &dev_length));
  if (length == 0 || (flag & MY_REPLACE_DIR))
  {
    DBUG_ASSERT(dir != NULL);
    /* Use given directory */
    convert_dirname(dev,dir,NullS);		/* Fix to this OS */
  }
  else if ((flag & MY_RELATIVE_PATH) && !test_if_hard_path(dev))
  {
    DBUG_ASSERT(dir != NULL);
    /* 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, &not_used);	/* Replace ~/.. with dir */

  if (!(flag & MY_APPEND_EXT) &&
      (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= (size_t) (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 */
    size_t tmp_length;
    if (flag & MY_SAFE_PATH)
      DBUG_RETURN(NullS);
    tmp_length= strlength(startpos);
    DBUG_PRINT("error",("dev: '%s'  ext: '%s'  length: %u",dev,ext,
                        (uint) length));
    (void) strmake(to, startpos, MY_MIN(tmp_length, FN_REFLEN-1));
  }
  else
  {
    if (to == startpos)
    {
      bmove(buff,(uchar*) 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 */
Ejemplo n.º 12
0
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{
  int save_errno,errpos=0;
  uint files= 0, i, dir_length, length, UNINIT_VAR(key_parts), min_keys= 0;
  ulonglong file_offset=0;
  char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
  MYRG_INFO *m_info=0;
  File fd;
  IO_CACHE file;
  MI_INFO *isam=0;
  uint found_merge_insert_method= 0;
  size_t name_buff_length;
  my_bool bad_children= FALSE;
  DBUG_ENTER("myrg_open");

  memset(&file, 0, sizeof(file));
  if ((fd= mysql_file_open(rg_key_file_MRG,
                           fn_format(name_buff, name, "", MYRG_NAME_EXT,
                                     MY_UNPACK_FILENAME|MY_APPEND_EXT),
                           O_RDONLY | O_SHARE, MYF(0))) < 0)
    goto err;
  errpos=1;
  if (init_io_cache(&file, fd, 4*IO_SIZE, READ_CACHE, 0, 0,
		    MYF(MY_WME | MY_NABP)))
    goto err;
  errpos=2;
  dir_length=dirname_part(name_buff, name, &name_buff_length);
  while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
  {
    if ((end=buff+length)[-1] == '\n')
      end[-1]='\0';
    if (buff[0] && buff[0] != '#')
      files++;
  }

  my_b_seek(&file, 0);
  while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
  {
    if ((end=buff+length)[-1] == '\n')
      *--end='\0';
    if (!buff[0])
      continue;		/* Skip empty lines */
    if (buff[0] == '#')
    {
      if (!strncmp(buff+1,"INSERT_METHOD=",14))
      {			/* Lookup insert method */
	int tmp= find_type(buff + 15, &merge_insert_method, FIND_TYPE_BASIC);
	found_merge_insert_method = (uint) (tmp >= 0 ? tmp : 0);
      }
      continue;		/* Skip comments */
    }

    if (!has_path(buff))
    {
      (void) strmake(name_buff+dir_length,buff,
                   sizeof(name_buff)-1-dir_length);
      (void) cleanup_dirname(buff,name_buff);
    }
    else
      fn_format(buff, buff, "", "", 0);
    if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0))))
    {
      if (handle_locking & HA_OPEN_FOR_REPAIR)
      {
        myrg_print_wrong_table(buff);
        bad_children= TRUE;
        continue;
      }
      goto bad_children;
    }
    if (!m_info)                                /* First file */
    {
      key_parts=isam->s->base.key_parts;
      if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO) +
                                           files*sizeof(MYRG_TABLE) +
                                           key_parts*sizeof(long),
                                           MYF(MY_WME|MY_ZEROFILL))))
        goto err;
      DBUG_ASSERT(files);
      m_info->open_tables=(MYRG_TABLE *) (m_info+1);
      m_info->rec_per_key_part=(ulong *) (m_info->open_tables+files);
      m_info->tables= files;
      files= 0;
      m_info->reclength=isam->s->base.reclength;
      min_keys= isam->s->base.keys;
      errpos=3;
    }
    m_info->open_tables[files].table= isam;
    m_info->open_tables[files].file_offset=(my_off_t) file_offset;
    file_offset+=isam->state->data_file_length;
    files++;
    if (m_info->reclength != isam->s->base.reclength)
    {
      if (handle_locking & HA_OPEN_FOR_REPAIR)
      {
        myrg_print_wrong_table(buff);
        bad_children= TRUE;
        continue;
      }
      goto bad_children;
    }
    m_info->options|= isam->s->options;
    m_info->records+= isam->state->records;
    m_info->del+= isam->state->del;
    m_info->data_file_length+= isam->state->data_file_length;
    if (min_keys > isam->s->base.keys)
      min_keys= isam->s->base.keys;
    for (i=0; i < key_parts; i++)
      m_info->rec_per_key_part[i]+= (isam->s->state.rec_per_key_part[i] /
                                     m_info->tables);
  }

  if (bad_children)
    goto bad_children;
  if (!m_info && !(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO),
                                                  MYF(MY_WME | MY_ZEROFILL))))
    goto err;
  /* Don't mark table readonly, for ALTER TABLE ... UNION=(...) to work */
  m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA);
  m_info->merge_insert_method= found_merge_insert_method;

  if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L)
  {
    my_errno=HA_ERR_RECORD_FILE_FULL;
    goto err;
  }
  m_info->keys= min_keys;
  memset(&m_info->by_key, 0, sizeof(m_info->by_key));

  /* this works ok if the table list is empty */
  m_info->end_table=m_info->open_tables+files;
  m_info->last_used_table=m_info->open_tables;
  m_info->children_attached= TRUE;

  (void) mysql_file_close(fd, MYF(0));
  end_io_cache(&file);
  mysql_mutex_init(rg_key_mutex_MYRG_INFO_mutex,
                   &m_info->mutex, MY_MUTEX_INIT_FAST);
  m_info->open_list.data=(void*) m_info;
  mysql_mutex_lock(&THR_LOCK_open);
  myrg_open_list=list_add(myrg_open_list,&m_info->open_list);
  mysql_mutex_unlock(&THR_LOCK_open);
  DBUG_RETURN(m_info);

bad_children:
  my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
err:
  save_errno=my_errno;
  switch (errpos) {
  case 3:
    while (files)
      (void) mi_close(m_info->open_tables[--files].table);
    my_free(m_info);
    /* Fall through */
  case 2:
    end_io_cache(&file);
    /* Fall through */
  case 1:
    (void) mysql_file_close(fd, MYF(0));
  }
  my_errno=save_errno;
  DBUG_RETURN (NULL);
}
Ejemplo n.º 13
0
MYRG_INFO *myrg_parent_open(const char *parent_name,
                            int (*callback)(void*, const char*),
                            void *callback_param)
{
  MYRG_INFO *m_info;
  int       rc;
  int       errpos;
  int       save_errno;
  int       insert_method;
  uint      length;
  uint      dir_length;
  uint      child_count;
  size_t    name_buff_length;
  File      fd;
  IO_CACHE  file_cache;
  char      parent_name_buff[FN_REFLEN * 2];
  char      child_name_buff[FN_REFLEN];
  DBUG_ENTER("myrg_parent_open");

  rc= 1;
  errpos= 0;
  bzero((char*) &file_cache, sizeof(file_cache));

  /* Open MERGE meta file. */
  if ((fd= my_open(fn_format(parent_name_buff, parent_name, "", MYRG_NAME_EXT,
                             MY_UNPACK_FILENAME|MY_APPEND_EXT),
                   O_RDONLY | O_SHARE, MYF(0))) < 0)
    goto err; /* purecov: inspected */
  errpos= 1;

  if (init_io_cache(&file_cache, fd, 4 * IO_SIZE, READ_CACHE, 0, 0,
                    MYF(MY_WME | MY_NABP)))
    goto err; /* purecov: inspected */
  errpos= 2;

  /* Count children. Determine insert method. */
  child_count= 0;
  insert_method= 0;
  while ((length= my_b_gets(&file_cache, child_name_buff, FN_REFLEN - 1)))
  {
    /* Remove line terminator. */
    if (child_name_buff[length - 1] == '\n')
      child_name_buff[--length]= '\0';

    /* Skip empty lines. */
    if (!child_name_buff[0])
      continue; /* purecov: inspected */

    /* Skip comments, but evaluate insert method. */
    if (child_name_buff[0] == '#')
    {
      if (!strncmp(child_name_buff + 1, "INSERT_METHOD=", 14))
      {
        /* Compare buffer with global methods list: merge_insert_method. */
        insert_method= find_type(child_name_buff + 15,
                                 &merge_insert_method, 2);
      }
      continue;
    }

    /* Count the child. */
    child_count++;
  }

  /* Allocate MERGE parent table structure. */
  if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO) +
                                       child_count * sizeof(MYRG_TABLE),
                                       MYF(MY_WME | MY_ZEROFILL))))
    goto err; /* purecov: inspected */
  errpos= 3;
  m_info->open_tables= (MYRG_TABLE*) (m_info + 1);
  m_info->tables= child_count;
  m_info->merge_insert_method= insert_method > 0 ? insert_method : 0;
  /* This works even if the table list is empty. */
  m_info->end_table= m_info->open_tables + child_count;
  if (!child_count)
  {
    /* Do not attach/detach an empty child list. */
    m_info->children_attached= TRUE;
  }

  /* Call callback for each child. */
  dir_length= dirname_part(parent_name_buff, parent_name, &name_buff_length);
  my_b_seek(&file_cache, 0);
  while ((length= my_b_gets(&file_cache, child_name_buff, FN_REFLEN - 1)))
  {
    /* Remove line terminator. */
    if (child_name_buff[length - 1] == '\n')
      child_name_buff[--length]= '\0';

    /* Skip empty lines and comments. */
    if (!child_name_buff[0] || (child_name_buff[0] == '#'))
      continue;

    if (!has_path(child_name_buff))
    {
      VOID(strmake(parent_name_buff + dir_length, child_name_buff,
                   sizeof(parent_name_buff) - 1 - dir_length));
      VOID(cleanup_dirname(child_name_buff, parent_name_buff));
    }
    else
      fn_format(child_name_buff, child_name_buff, "", "", 0);
    DBUG_PRINT("info", ("child: '%s'", child_name_buff));

    /* Callback registers child with handler table. */
    if ((rc= (*callback)(callback_param, child_name_buff)))
      goto err; /* purecov: inspected */
  }

  end_io_cache(&file_cache);
  VOID(my_close(fd, MYF(0)));
  VOID(pthread_mutex_init(&m_info->mutex, MY_MUTEX_INIT_FAST));

  m_info->open_list.data= (void*) m_info;
  pthread_mutex_lock(&THR_LOCK_open);
  myrg_open_list= list_add(myrg_open_list, &m_info->open_list);
  pthread_mutex_unlock(&THR_LOCK_open);

  DBUG_RETURN(m_info);

  /* purecov: begin inspected */
 err:
  save_errno= my_errno;
  switch (errpos) {
  case 3:
    my_free((char*) m_info, MYF(0));
    /* Fall through */
  case 2:
    end_io_cache(&file_cache);
    /* Fall through */
  case 1:
    VOID(my_close(fd, MYF(0)));
  }
  my_errno= save_errno;
  DBUG_RETURN (NULL);
  /* purecov: end */
}
Ejemplo n.º 14
0
my_string fn_format(my_string to, const char *name, const char *dsk,
		    const char *form, int flag)
{
  reg1 uint length;
  char dev[FN_REFLEN], buff[BUFF_LEN], *pos, *startpos;
  const char *ext;
  DBUG_ENTER("fn_format");
  DBUG_PRINT("enter",("name: %s  dsk: %s  form: %s  flag: %d",
		       name,dsk,form,flag));

	/* Kopiera & skippa enheten */
  name+=(length=dirname_part(dev,(startpos=(my_string) name)));
  if (length == 0 || flag & 1)
  {
    (void) strmake(dev,dsk, sizeof(dev) - 2);
      /* Use given directory */
    convert_dirname(dev);			/* Fix to this OS */
  }
  if (flag & 8)
    pack_dirname(dev,dev);			/* Put in ./.. and ~/.. */
  if (flag & 4)
    (void) unpack_dirname(dev,dev);		/* Replace ~/.. with dir */
  if ((pos=(char*)strchr(name,FN_EXTCHAR)) != NullS)
  {
    if ((flag & 2) == 0)			/* Skall vi byta extension ? */
    {
      length=strlength(name);			/* Old extension */
      ext = "";
    }
    else
    {
      length=(uint) (pos-(char*) name);		/* Change extension */
      ext= form;
    }
  }
  else
  {
    length=strlength(name);			/* Har ingen ext- tag nya */
    ext=form;
  }

  if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN )
  {				/* To long path, return original */
    uint tmp_length;
    if (flag & 64)
      return 0;
    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);
#ifdef FN_UPPER_CASE
    caseup_str(to);
#endif
#ifdef FN_LOWER_CASE
    casedn_str(to);
#endif
    (void) strmov(pos,ext);			/* Don't convert extension */
  }
  /* Purify gives a lot of UMR errors when using realpath */
#if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH)
  if (flag & 16)
  {
    struct stat stat_buff;
    if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
    {
      if (realpath(to,buff))
	strmake(to,buff,FN_REFLEN-1);
    }
  }
#endif
  DBUG_RETURN (to);
} /* fn_format */
Ejemplo n.º 15
0
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{
  int save_errno,i,errpos;
  uint files,dir_length,length,key_parts;
  ulonglong file_offset;
  char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
  MYRG_INFO info,*m_info;
  File fd;
  IO_CACHE file;
  MI_INFO *isam,*last_isam;
  DBUG_ENTER("myrg_open");

  LINT_INIT(last_isam);
  LINT_INIT(m_info);
  isam=0;
  errpos=files=0;
  bzero((gptr) &info,sizeof(info));
  bzero((char*) &file,sizeof(file));
  if ((fd=my_open(fn_format(name_buff,name,"",MYRG_NAME_EXT,4),
		  O_RDONLY | O_SHARE,MYF(0))) < 0 ||
      init_io_cache(&file, fd, IO_SIZE, READ_CACHE, 0, 0,
		    MYF(MY_WME | MY_NABP)))
    goto err;
  errpos=1;
  dir_length=dirname_part(name_buff,name);
  info.reclength=0;
  while ((length=my_b_gets(&file,buff,FN_REFLEN-1)))
  {
    if ((end=buff+length)[-1] == '\n')
      end[-1]='\0';
    if (!buff[0])
      continue;		/* Skip empty lines */
    if (buff[0] == '#')
    {
      if( !strncmp(buff+1,"INSERT_METHOD=",14))
      {			/* Lookup insert method */
	int tmp=find_type(buff+15,&merge_insert_method,2);
	info.merge_insert_method = (uint) (tmp >= 0 ? tmp : 0);
      }
      continue;		/* Skip comments */
    }

    if (!test_if_hard_path(buff))
    {
      VOID(strmake(name_buff+dir_length,buff,
                   sizeof(name_buff)-1-dir_length));
      VOID(cleanup_dirname(buff,name_buff));
    }
    if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0))))
	goto err;
    files++;
    last_isam=isam;
    if (info.reclength && info.reclength != isam->s->base.reclength)
    {
      my_errno=HA_ERR_WRONG_MRG_TABLE_DEF;
      goto err;
    }
    info.reclength=isam->s->base.reclength;
  }
  key_parts=(isam ? isam->s->base.key_parts : 0);
  if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO)+
                                       files*sizeof(MYRG_TABLE)+
                                       sizeof(long)*key_parts,
				       MYF(MY_WME))))
    goto err;
  *m_info=info;
  m_info->tables=files;
  if (files)
  {
    m_info->open_tables=(MYRG_TABLE *) (m_info+1);
    m_info->rec_per_key_part=(ulong *) (m_info->open_tables+files);
    bzero((char*) m_info->rec_per_key_part,sizeof(long)*key_parts);
  }
  else
  {
    m_info->open_tables=0;
    m_info->rec_per_key_part=0;
  }
  errpos=2;

  for (i=files ; i-- > 0 ; )
  {
    uint j;
    m_info->open_tables[i].table=isam;
    m_info->options|=isam->s->options;
    m_info->records+=isam->state->records;
    m_info->del+=isam->state->del;
    m_info->data_file_length+=isam->state->data_file_length;
    for (j=0; j < key_parts; j++)
      m_info->rec_per_key_part[j]+=isam->s->state.rec_per_key_part[j] / files;
    if (i)
      isam=(MI_INFO*) (isam->open_list.next->data);
  }
  /* Don't mark table readonly, for ALTER TABLE ... UNION=(...) to work */
  m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA);

  /* Fix fileinfo for easyer debugging (actually set by rrnd) */
  file_offset=0;
  for (i=0 ; (uint) i < files ; i++)
  {
    m_info->open_tables[i].file_offset=(my_off_t) file_offset;
    file_offset+=m_info->open_tables[i].table->state->data_file_length;
  }
  if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L)
  {
    my_errno=HA_ERR_RECORD_FILE_FULL;
    goto err;
  }
  m_info->keys=(files) ? m_info->open_tables->table->s->base.keys : 0;
  bzero((char*) &m_info->by_key,sizeof(m_info->by_key));

  /* this works ok if the table list is empty */
  m_info->end_table=m_info->open_tables+files;
  m_info->last_used_table=m_info->open_tables;

  VOID(my_close(fd,MYF(0)));
  end_io_cache(&file);
  m_info->open_list.data=(void*) m_info;
  pthread_mutex_lock(&THR_LOCK_open);
  myrg_open_list=list_add(myrg_open_list,&m_info->open_list);
  pthread_mutex_unlock(&THR_LOCK_open);
  DBUG_RETURN(m_info);

err:
  save_errno=my_errno;
  switch (errpos) {
  case 2:
    my_free((char*) m_info,MYF(0));
    /* Fall through */
  case 1:
    VOID(my_close(fd,MYF(0)));
    end_io_cache(&file);
    for (i=files ; i-- > 0 ; )
    {
      isam=last_isam;
      if (i)
	last_isam=(MI_INFO*) (isam->open_list.next->data);
      mi_close(isam);
    }
  }
  my_errno=save_errno;
  DBUG_RETURN (NULL);
}