Ejemplo n.º 1
0
size_t unpack_dirname(char * to, const char *from)
{
  size_t length, h_length;
  char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion;
  DBUG_ENTER("unpack_dirname");

  length= normalize_dirname(buff, from);

  if (buff[0] == FN_HOMELIB)
  {
    suffix=buff+1; tilde_expansion=expand_tilde(&suffix);
    if (tilde_expansion)
    {
      length-= (size_t) (suffix-buff)-1;
      if (length+(h_length= strlen(tilde_expansion)) <= FN_REFLEN)
      {
	if ((h_length > 0) && (tilde_expansion[h_length-1] == FN_LIBCHAR))
	  h_length--;
	if (buff+h_length < suffix)
	  bmove(buff+h_length,suffix,length);
	else
	  bmove_upp((uchar*) buff+h_length+length, (uchar*) suffix+length, length);
	bmove(buff,tilde_expansion,h_length);
      }
    }
  }
#ifdef USE_SYMDIR
  if (my_use_symdir)
    symdirget(buff);
#endif
  DBUG_RETURN(system_filename(to,buff));	/* Fix for open */
} /* unpack_dirname */
Ejemplo n.º 2
0
void bchange(register char *dst, uint old_length, register const char *src, uint new_length, uint tot_length)
{
  uint rest=tot_length-old_length;
  if (old_length < new_length)
    bmove_upp(dst+rest+new_length,dst+tot_length,rest);
  else
    bmove(dst+new_length,dst+old_length,rest);
  memcpy(dst,src,new_length);
}
Ejemplo n.º 3
0
void bchange(register uchar *dst, size_t old_length, register const uchar *src,
	     size_t new_length, size_t tot_length)
{
  size_t rest=tot_length-old_length;
  if (old_length < new_length)
    bmove_upp(dst+rest+new_length,dst+tot_length,rest);
  else
    bmove(dst+new_length,dst+old_length,rest);
  memcpy(dst,src,new_length);
}
Ejemplo n.º 4
0
uint unpack_dirname(my_string to, const char *from)
{
  uint length,h_length;
  char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion;
  DBUG_ENTER("unpack_dirname");

  (void) intern_filename(buff,from);		/* Change to intern name */
  length= (uint) strlen(buff);			/* Fix that '/' is last */
  if (length &&
#ifdef FN_DEVCHAR
      buff[length-1] != FN_DEVCHAR &&
#endif
      buff[length-1] != FN_LIBCHAR && buff[length-1] != '/')
  {
    buff[length]=FN_LIBCHAR;
    buff[length+1]= '\0';
  }

  length=cleanup_dirname(buff,buff);
  if (buff[0] == FN_HOMELIB)
  {
    suffix=buff+1; tilde_expansion=expand_tilde(&suffix);
    if (tilde_expansion)
    {
      length-=(uint) (suffix-buff)-1;
      if (length+(h_length= (uint) strlen(tilde_expansion)) <= FN_REFLEN)
      {
	if (tilde_expansion[h_length-1] == FN_LIBCHAR)
	  h_length--;
	if (buff+h_length < suffix)
	  bmove(buff+h_length,suffix,length);
	else
	  bmove_upp(buff+h_length+length,suffix+length,length);
	bmove(buff,tilde_expansion,h_length);
      }
    }
  }
#ifdef USE_SYMDIR
  if (my_use_symdir)
    symdirget(buff);
#endif
  DBUG_RETURN(system_filename(to,buff));	/* Fix for open */
} /* unpack_dirname */
Ejemplo n.º 5
0
my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
                    int *warning)
{
  ulong date[5];
  ulonglong value;
  const char *end=str+length, *end_of_days;
  my_bool found_days,found_hours;
  uint state;

  l_time->neg=0;
  *warning= 0;
  for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++)
    length--;
  if (str != end && *str == '-')
  {
    l_time->neg=1;
    str++;
    length--;
  }
  if (str == end)
    return 1;

  /* Check first if this is a full TIMESTAMP */
  if (length >= 12)
  {                                             /* Probably full timestamp */
    int was_cut;
    enum enum_mysql_timestamp_type
      res= str_to_datetime(str, length, l_time,
                           (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), &was_cut);
    if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR)
    {
      if (was_cut)
        *warning|= MYSQL_TIME_WARN_TRUNCATED;
      return res == MYSQL_TIMESTAMP_ERROR;
    }
  }

  /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */
  for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
    value=value*10L + (long) (*str - '0');

  /* Skip all space after 'days' */
  end_of_days= str;
  for (; str != end && my_isspace(&my_charset_latin1, str[0]) ; str++)
    ;

  LINT_INIT(state);
  found_days=found_hours=0;
  if ((uint) (end-str) > 1 && str != end_of_days &&
      my_isdigit(&my_charset_latin1, *str))
  {                                             /* Found days part */
    date[0]= (ulong) value;
    state= 1;                                   /* Assume next is hours */
    found_days= 1;
  }
  else if ((end-str) > 1 &&  *str == time_separator &&
           my_isdigit(&my_charset_latin1, str[1]))
  {
    date[0]= 0;                                 /* Assume we found hours */
    date[1]= (ulong) value;
    state=2;
    found_hours=1;
    str++;                                      /* skip ':' */
  }
  else
  {
    /* String given as one number; assume HHMMSS format */
    date[0]= 0;
    date[1]= (ulong) (value/10000);
    date[2]= (ulong) (value/100 % 100);
    date[3]= (ulong) (value % 100);
    state=4;
    goto fractional;
  }

  /* Read hours, minutes and seconds */
  for (;;)
  {
    for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
      value=value*10L + (long) (*str - '0');
    date[state++]= (ulong) value;
    if (state == 4 || (end-str) < 2 || *str != time_separator ||
        !my_isdigit(&my_charset_latin1,str[1]))
      break;
    str++;                                      /* Skip time_separator (':') */
  }

  if (state != 4)
  {                                             /* Not HH:MM:SS */
    /* Fix the date to assume that seconds was given */
    if (!found_hours && !found_days)
    {
      bmove_upp((uchar*) (date+4), (uchar*) (date+state),
                sizeof(long)*(state-1));
      bzero((uchar*) date, sizeof(long)*(4-state));
    }
    else
      bzero((uchar*) (date+state), sizeof(long)*(4-state));
  }

fractional:
  /* Get fractional second part */
  if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1]))
  {
    int field_length= 5;
    str++; value=(uint) (uchar) (*str - '0');
    while (++str != end && my_isdigit(&my_charset_latin1, *str))
    {
      if (field_length-- > 0)
        value= value*10 + (uint) (uchar) (*str - '0');
    }
    if (field_length > 0)
      value*= (long) log_10_int[field_length];
    else if (field_length < 0)
      *warning|= MYSQL_TIME_WARN_TRUNCATED;
    date[4]= (ulong) value;
  }
  else
    date[4]=0;
    
  /* Check for exponent part: E<gigit> | E<sign><digit> */
  /* (may occur as result of %g formatting of time value) */
  if ((end - str) > 1 &&
      (*str == 'e' || *str == 'E') &&
      (my_isdigit(&my_charset_latin1, str[1]) ||
       ((str[1] == '-' || str[1] == '+') &&
        (end - str) > 2 &&
        my_isdigit(&my_charset_latin1, str[2]))))
    return 1;

  if (internal_format_positions[7] != 255)
  {
    /* Read a possible AM/PM */
    while (str != end && my_isspace(&my_charset_latin1, *str))
      str++;
    if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
    {
      if (str[0] == 'p' || str[0] == 'P')
      {
        str+= 2;
        date[1]= date[1]%12 + 12;
      }
      else if (str[0] == 'a' || str[0] == 'A')
        str+=2;
    }
  }

  /* Integer overflow checks */
  if (date[0] > UINT_MAX || date[1] > UINT_MAX ||
      date[2] > UINT_MAX || date[3] > UINT_MAX ||
      date[4] > UINT_MAX)
    return 1;
  
  l_time->year=         0;                      /* For protocol::store_time */
  l_time->month=        0;
  l_time->day=          date[0];
  l_time->hour=         date[1];
  l_time->minute=       date[2];
  l_time->second=       date[3];
  l_time->second_part=  date[4];
  l_time->time_type= MYSQL_TIMESTAMP_TIME;

  /* Check if the value is valid and fits into MYSQL_TIME range */
  if (check_time_range(l_time, warning))
    return 1;
  
  /* Check if there is garbage at end of the MYSQL_TIME specification */
  if (str != end)
  {
    do
    {
      if (!my_isspace(&my_charset_latin1,*str))
      {
        *warning|= MYSQL_TIME_WARN_TRUNCATED;
        break;
      }
    } while (++str != end);
  }
  return 0;
}
Ejemplo n.º 6
0
MY_DIR	*my_dir(const char *path, myf MyFlags)
{
  DIR		*dirp;
  struct dirent *dp;
  struct fileinfo *fnames;
  char	       *buffer, *obuffer, *tempptr;
  uint		fcnt,i,size,firstfcnt, maxfcnt,length;
  char		tmp_path[FN_REFLEN+1],*tmp_file;
  my_ptrdiff_t	diff;
  bool		eof;
#ifdef THREAD
  char	dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
#endif
  DBUG_ENTER("my_dir");
  DBUG_PRINT("my",("path: '%s' stat: %d  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,(my_string) path));
  size = STARTSIZE;
  if (dirp == NULL || ! (buffer = (char *) my_malloc(size, MyFlags)))
    goto error;

  fcnt = 0;
  tmp_file=strend(tmp_path);
  firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) /
    (sizeof(struct fileinfo) + FN_LEN);
  fnames=   (struct fileinfo *) (buffer + sizeof(MY_DIR));
  tempptr = (char *) (fnames + maxfcnt);

#ifdef THREAD
  dp= (struct dirent*) dirent_tmp;
#else
  dp=0;
#endif
  eof=0;
  for (;;)
  {
    while (fcnt < maxfcnt &&
	   !(eof= READDIR(dirp,(struct dirent*) dirent_tmp,dp)))
    {
      bzero((gptr) (fnames+fcnt),sizeof(fnames[0])); /* for purify */
      fnames[fcnt].name = tempptr;
      tempptr = strmov(tempptr,dp->d_name) + 1;
      if (MyFlags & MY_WANT_STAT)
      {
	VOID(strmov(tmp_file,dp->d_name));
	VOID(my_stat(tmp_path, &fnames[fcnt].mystat, MyFlags));
      }
      ++fcnt;
    }
    if (eof)
      break;
    size += STARTSIZE; obuffer = buffer;
    if (!(buffer = (char *) my_realloc((gptr) buffer, size,
				       MyFlags | MY_FREE_ON_ERROR)))
      goto error;			/* No memory */
    length= (uint) (sizeof(struct fileinfo ) * firstfcnt);
    diff=    PTR_BYTE_DIFF(buffer , obuffer) + (int) length;
    fnames=  (struct fileinfo *) (buffer + sizeof(MY_DIR));
    tempptr= ADD_TO_PTR(tempptr,diff,char*);
    for (i = 0; i < maxfcnt; i++)
      fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*);

    /* move filenames upp a bit */
    maxfcnt += firstfcnt;
    bmove_upp(tempptr,tempptr-length,
	      (uint) (tempptr- (char*) (fnames+maxfcnt)));
  }

  (void) closedir(dirp);
  {
    MY_DIR * s = (MY_DIR *) buffer;
    s->number_off_files = (uint) fcnt;
    s->dir_entry = fnames;
  }
  if (!(MyFlags & MY_DONT_SORT))
    qsort((void *) fnames, (size_s) fcnt, sizeof(struct fileinfo),
	  (qsort_cmp) comp_names);
#if defined(THREAD) && !defined(HAVE_READDIR_R)
  pthread_mutex_unlock(&THR_LOCK_open);
#endif
  DBUG_RETURN((MY_DIR *) buffer);

 error:
#if defined(THREAD) && !defined(HAVE_READDIR_R)
  pthread_mutex_unlock(&THR_LOCK_open);
#endif
  my_errno=errno;
  if (dirp)
    (void) closedir(dirp);
  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 */
Ejemplo n.º 7
0
my_bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time,
                    ulonglong fuzzydate, MYSQL_TIME_STATUS *status)
{
  ulong date[5];
  ulonglong value;
  const char *end=str+length, *end_of_days;
  my_bool found_days,found_hours, neg= 0;
  uint UNINIT_VAR(state);

  my_time_status_init(status);
  for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++)
    length--;
  if (str != end && *str == '-')
  {
    neg=1;
    str++;
    length--;
  }
  if (str == end)
  {
    status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
    goto err;
  }

  /* Check first if this is a full TIMESTAMP */
  if (length >= 12)
  {                                             /* Probably full timestamp */
    (void) str_to_datetime(str, length, l_time,
                           (fuzzydate & ~TIME_TIME_ONLY) | TIME_DATETIME_ONLY,
                            status);
    if (l_time->time_type >= MYSQL_TIMESTAMP_ERROR)
      return l_time->time_type == MYSQL_TIMESTAMP_ERROR;
    my_time_status_init(status);
  }

  l_time->neg= neg;
  /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */
  for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
    value=value*10L + (long) (*str - '0');

  /* Skip all space after 'days' */
  end_of_days= str;
  for (; str != end && my_isspace(&my_charset_latin1, str[0]) ; str++)
    ;

  found_days=found_hours=0;
  if ((uint) (end-str) > 1 && str != end_of_days &&
      my_isdigit(&my_charset_latin1, *str))
  {                                             /* Found days part */
    date[0]= (ulong) value;
    state= 1;                                   /* Assume next is hours */
    found_days= 1;
  }
  else if ((end-str) > 1 &&  *str == time_separator &&
           my_isdigit(&my_charset_latin1, str[1]))
  {
    date[0]= 0;                                 /* Assume we found hours */
    date[1]= (ulong) value;
    state=2;
    found_hours=1;
    str++;                                      /* skip ':' */
  }
  else
  {
    /* String given as one number; assume HHMMSS format */
    date[0]= 0;
    date[1]= (ulong) (value/10000);
    date[2]= (ulong) (value/100 % 100);
    date[3]= (ulong) (value % 100);
    state=4;
    goto fractional;
  }

  /* Read hours, minutes and seconds */
  for (;;)
  {
    for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
      value=value*10L + (long) (*str - '0');
    date[state++]= (ulong) value;
    if (state == 4 || (end-str) < 2 || *str != time_separator ||
        !my_isdigit(&my_charset_latin1,str[1]))
      break;
    str++;                                      /* Skip time_separator (':') */
  }

  if (state != 4)
  {                                             /* Not HH:MM:SS */
    /* Fix the date to assume that seconds was given */
    if (!found_hours && !found_days)
    {
      bmove_upp((uchar*) (date+4), (uchar*) (date+state),
                sizeof(long)*(state-1));
      bzero((uchar*) date, sizeof(long)*(4-state));
    }
    else
      bzero((uchar*) (date+state), sizeof(long)*(4-state));
  }

fractional:
  /* Get fractional second part */
  if (!status->warnings && str < end && *str == '.')
  {
    uint number_of_fields= 0;
    str++;
    get_microseconds(&date[4], status, &number_of_fields, &str, end);
  }
  else
    date[4]= 0;

  /* Check for exponent part: E<gigit> | E<sign><digit> */
  /* (may occur as result of %g formatting of time value) */
  if ((end - str) > 1 &&
      (*str == 'e' || *str == 'E') &&
      (my_isdigit(&my_charset_latin1, str[1]) ||
       ((str[1] == '-' || str[1] == '+') &&
        (end - str) > 2 &&
        my_isdigit(&my_charset_latin1, str[2]))))
  {
    status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
    goto err;
  }

  if (internal_format_positions[7] != 255)
  {
    /* Read a possible AM/PM */
    while (str != end && my_isspace(&my_charset_latin1, *str))
      str++;
    if (str+2 <= end && (str[1] == 'M' || str[1] == 'm'))
    {
      if (str[0] == 'p' || str[0] == 'P')
      {
        str+= 2;
        date[1]= date[1]%12 + 12;
      }
      else if (str[0] == 'a' || str[0] == 'A')
        str+=2;
    }
  }

  /* Integer overflow checks */
  if (date[0] > UINT_MAX || date[1] > UINT_MAX ||
      date[2] > UINT_MAX || date[3] > UINT_MAX ||
      date[4] > UINT_MAX)
  {
    status->warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
    goto err;
  }  

  l_time->year=         0;                      /* For protocol::store_time */
  l_time->month=        0;
  l_time->day=          0;
  l_time->hour=         date[1] + date[0] * 24; /* Mix days and hours */
  l_time->minute=       date[2];
  l_time->second=       date[3];
  l_time->second_part=  date[4];
  l_time->time_type= MYSQL_TIMESTAMP_TIME;

  /* Check if the value is valid and fits into MYSQL_TIME range */
  if (check_time_range(l_time, 6, &status->warnings))
    return TRUE;

  /* Check if there is garbage at end of the MYSQL_TIME specification */
  if (str != end)
  {
    do
    {
      if (!my_isspace(&my_charset_latin1,*str))
      {
        status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
        break;
      }
    } while (++str != end);
  }
  return FALSE;

err:
  bzero((char*) l_time, sizeof(*l_time));
  l_time->time_type= MYSQL_TIMESTAMP_ERROR;
  return TRUE;
}
Ejemplo n.º 8
0
static void convert_from_float(MYSQL_BIND *r_param, const MYSQL_FIELD *field, double val, int size)
{
  double check_trunc_val= (val > 0) ? floor(val) : -floor(-val);
  char *buf= (char *)r_param->buffer;
  switch (r_param->buffer_type)
  {
    case MYSQL_TYPE_TINY:
      *buf= (r_param->is_unsigned) ? (uint8)val : (int8)val;
      *r_param->error= check_trunc_val != (r_param->is_unsigned ? (double)((uint8)*buf) :
                                          (double)((int8)*buf));
      r_param->buffer_length= 1;
    break;
    case MYSQL_TYPE_SHORT:
    case MYSQL_TYPE_YEAR:
    {
      if (r_param->is_unsigned)
      {
        ushort sval= (ushort)val;
        shortstore(buf, sval);
        *r_param->error= check_trunc_val != (double)sval;
      } else { 
        short sval= (short)val;
        shortstore(buf, sval);
        *r_param->error= check_trunc_val != (double)sval;
      } 
      r_param->buffer_length= 2;
    }
    break; 
    case MYSQL_TYPE_LONG:
    {
      if (r_param->is_unsigned)
      {
        uint32 lval= (uint32)val;
        longstore(buf, lval);
        *r_param->error= (check_trunc_val != (double)lval);
      } else {
        int32 lval= (int32)val;
        longstore(buf, lval);
        *r_param->error= (check_trunc_val != (double)lval);
      }
      r_param->buffer_length= 4;
    }
    break; 
    case MYSQL_TYPE_LONGLONG:
    {
      if (r_param->is_unsigned)
      {
        ulonglong llval= (ulonglong)val;
        longlongstore(buf, llval);
        *r_param->error= (check_trunc_val != (double)llval);
      } else {
        longlong llval= (longlong)val;
        longlongstore(buf, llval);
        *r_param->error= (check_trunc_val != (double)llval);
      }
      r_param->buffer_length= 8;
    }
    break; 
    case MYSQL_TYPE_FLOAT:
    {
      float fval= (float)val;
      memcpy(buf, &fval, sizeof(float));
      *r_param->error= (*(float*)buf != fval);
      r_param->buffer_length= 4;
    }
    break;
    case MYSQL_TYPE_DOUBLE:
    {
      memcpy(buf, &val, sizeof(double));
      r_param->buffer_length= 8;
    }
    break;
    default:
    {
 #define MAX_DOUBLE_STRING_REP_LENGTH 300
     char buff[MAX_DOUBLE_STRING_REP_LENGTH];
     char *end;
     size_t length;

     length= MIN(MAX_DOUBLE_STRING_REP_LENGTH - 1, r_param->buffer_length);

     if (field->decimals >= NOT_FIXED_DEC)
     {
       sprintf(buff, "%-*.*g", (int) length-1, DBL_DIG, val);
       length= strlen(buff);
     }
     else
     {
       sprintf(buff, "%.*f", field->decimals, val);
       length= strlen(buff);
     }

     /* remove possible trailing blanks */
     if ((end= strcend(buff, ' ')))
       *end= 0;

     /* check if ZEROFILL flag is active */
     if (field->flags & ZEROFILL_FLAG)
     {
       /* enough space available ? */
       if (field->length < length || field->length > MAX_DOUBLE_STRING_REP_LENGTH - 1)
         break;
       bmove_upp(buff + field->length, buff + length, length);
       bfill((char*) buff, field->length - length, '0');
     }
     convert_from_string(r_param, buff, strlen(buff));
    }  
    break;
  } 
}