size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags) { size_t writtenbytes =0; my_off_t seekptr; #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) uint errors; #endif DBUG_ENTER("my_fwrite"); DBUG_PRINT("my",("stream: 0x%lx Buffer: 0x%lx Count: %u MyFlags: %d", (long) stream, (long) Buffer, (uint) Count, MyFlags)); #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) errors=0; #endif seekptr= ftell(stream); for (;;) { size_t written; if ((written = (size_t) fwrite((char*) Buffer,sizeof(char), Count, stream)) != Count) { DBUG_PRINT("error",("Write only %d bytes", (int) writtenbytes)); my_errno=errno; if (written != (size_t) -1) { seekptr+=written; Buffer+=written; writtenbytes+=written; Count-=written; } #ifdef EINTR if (errno == EINTR) { (void) my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0)); continue; } #endif #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM) if (my_thread_var->abort) MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */ if ((errno == ENOSPC || errno == EDQUOT) && (MyFlags & MY_WAIT_IF_FULL)) { wait_for_free_space("[stream]", errors); errors++; (void) my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0)); continue; } #endif if (ferror(stream) || (MyFlags & (MY_NABP | MY_FNABP))) { if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG), my_filename(my_fileno(stream)),errno); } writtenbytes= (size_t) -1; /* Return that we got error */ break; } } if (MyFlags & (MY_NABP | MY_FNABP)) writtenbytes= 0; /* Everything OK */ else writtenbytes+= written; break; } DBUG_RETURN(writtenbytes); } /* my_fwrite */
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 + 2], *tmp_file; char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1]; DBUG_ENTER("my_dir"); DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags)); #if !defined(HAVE_READDIR_R) mysql_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(buffer); 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); dp= (struct dirent*) dirent_tmp; 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; memset(finfo.mystat, 0, 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(HAVE_READDIR_R) mysql_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(HAVE_READDIR_R) mysql_mutex_unlock(&THR_LOCK_open); #endif my_errno=errno; if (dirp) (void) closedir(dirp); my_dirend(result); if (MyFlags & (MY_FAE | MY_WME)) { char errbuf[MYSYS_STRERROR_SIZE]; my_error(EE_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno)); } DBUG_RETURN((MY_DIR *) NULL); } /* my_dir */
int mrn_add_index_param(MRN_SHARE *share, KEY *key_info, int i) { int error; char *param_string = NULL; #if MYSQL_VERSION_ID >= 50500 int title_length; char *sprit_ptr[2]; char *tmp_ptr, *start_ptr; #endif THD *thd = current_thd; MRN_DBUG_ENTER_FUNCTION(); #if MYSQL_VERSION_ID >= 50500 if (key_info->comment.length == 0) { if (share->key_tokenizer[i]) { my_free(share->key_tokenizer[i]); } share->key_tokenizer[i] = mrn_my_strdup(mrn_default_tokenizer, MYF(MY_WME)); if (!share->key_tokenizer[i]) { error = HA_ERR_OUT_OF_MEM; goto error; } share->key_tokenizer_length[i] = strlen(share->key_tokenizer[i]); DBUG_RETURN(0); } DBUG_PRINT("info", ("mroonga create comment string")); if ( !(param_string = mrn_my_strndup(key_info->comment.str, key_info->comment.length, MYF(MY_WME))) ) { error = HA_ERR_OUT_OF_MEM; goto error_alloc_param_string; } DBUG_PRINT("info", ("mroonga comment string=%s", param_string)); sprit_ptr[0] = param_string; while (sprit_ptr[0]) { if ((sprit_ptr[1] = strchr(sprit_ptr[0], ','))) { *sprit_ptr[1] = '\0'; sprit_ptr[1]++; } tmp_ptr = sprit_ptr[0]; sprit_ptr[0] = sprit_ptr[1]; while (*tmp_ptr == ' ' || *tmp_ptr == '\r' || *tmp_ptr == '\n' || *tmp_ptr == '\t') tmp_ptr++; if (*tmp_ptr == '\0') continue; title_length = 0; start_ptr = tmp_ptr; while (*start_ptr != ' ' && *start_ptr != '\'' && *start_ptr != '"' && *start_ptr != '\0' && *start_ptr != '\r' && *start_ptr != '\n' && *start_ptr != '\t') { title_length++; start_ptr++; } switch (title_length) { case 5: MRN_PARAM_STR_LIST("table", index_table, i); break; case 6: push_warning_printf(thd, MRN_SEVERITY_WARNING, ER_WARN_DEPRECATED_SYNTAX, ER(ER_WARN_DEPRECATED_SYNTAX), "parser", "tokenizer"); MRN_PARAM_STR_LIST("parser", key_tokenizer, i); break; case 9: MRN_PARAM_STR_LIST("tokenizer", key_tokenizer, i); break; default: break; } } #endif if (!share->key_tokenizer[i]) { share->key_tokenizer[i] = mrn_my_strdup(mrn_default_tokenizer, MYF(MY_WME)); if (!share->key_tokenizer[i]) { error = HA_ERR_OUT_OF_MEM; goto error; } share->key_tokenizer_length[i] = strlen(share->key_tokenizer[i]); } if (param_string) my_free(param_string); DBUG_RETURN(0); error: if (param_string) my_free(param_string); #if MYSQL_VERSION_ID >= 50500 error_alloc_param_string: #endif DBUG_RETURN(error); }
/* TODO: Add option --verify to mysqld to be able to change verification mode */ struct st_VioSSLAcceptorFd* new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, const char *cipher) { int verify = (SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE); struct st_VioSSLAcceptorFd* ptr; int result; DH *dh=NULL; DBUG_ENTER("new_VioSSLAcceptorFd"); DBUG_PRINT("enter", ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s", key_file, cert_file, ca_path, ca_file, cipher)); ptr= ((struct st_VioSSLAcceptorFd*) my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0))); ptr->ssl_context=0; ptr->ssl_method=0; /* FIXME: constants! */ ptr->session_id_context= ptr; if (!ssl_algorithms_added) { DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()")); ssl_algorithms_added = TRUE; OpenSSL_add_all_algorithms(); } if (!ssl_error_strings_loaded) { DBUG_PRINT("info", ("todo: SSL_load_error_strings()")); ssl_error_strings_loaded = TRUE; SSL_load_error_strings(); } ptr->ssl_method= TLSv1_server_method(); ptr->ssl_context= SSL_CTX_new(ptr->ssl_method); if (ptr->ssl_context == 0) { DBUG_PRINT("error", ("SSL_CTX_new failed")); report_errors(); goto ctor_failure; } if (cipher) { result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher); DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result)); } /* SSL_CTX_set_quiet_shutdown(ctx,1); */ SSL_CTX_sess_set_cache_size(ptr->ssl_context,128); /* DH? */ SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback); SSL_CTX_set_session_id_context(ptr->ssl_context, (const uchar*) &(ptr->session_id_context), sizeof(ptr->session_id_context)); /* SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); */ if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1) { DBUG_PRINT("error", ("vio_set_cert_stuff failed")); report_errors(); goto ctor_failure; } if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file, ca_path) == 0) { DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); if (SSL_CTX_set_default_verify_paths(ptr->ssl_context)==0) { DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed")); report_errors(); goto ctor_failure; } } /* DH stuff */ dh=get_dh512(); SSL_CTX_set_tmp_dh(ptr->ssl_context,dh); DH_free(dh); DBUG_RETURN(ptr); ctor_failure: DBUG_PRINT("exit", ("there was an error")); my_free((gptr) ptr,MYF(0)); DBUG_RETURN(0); }
#include "my_static.h" #include "mysys_err.h" /* Remove an open tempfile so that it doesn't survive if we crash; If the operating system doesn't support this, just remember the file name for later removal */ static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)), const char *name) { #if O_TEMPORARY == 0 #if !defined(CANT_DELETE_OPEN_FILES) /* The following should always succeed */ (void) my_delete(name,MYF(MY_WME | ME_NOINPUT)); #else int length; if (!(cache->file_name= (char*) my_malloc((length=strlen(name)+1),MYF(MY_WME)))) { my_close(cache->file,MYF(0)); cache->file = -1; errno=my_errno=ENOMEM; return 1; } memcpy(cache->file_name,name,length); #endif #endif /* O_TEMPORARY == 0 */ return 0; }
int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length, int flag) { uint read_length,in_buff_length; my_off_t offset; uchar *in_buff_pos; DBUG_ENTER("_mi_read_cache"); DBUG_ASSERT(!(info->myflags & MY_ENCRYPT)); 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 (!_my_b_read(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 == -1 || my_errno == HA_ERR_FILE_TOO_SHORT) my_errno= HA_ERR_WRONG_IN_RECORD; DBUG_RETURN(1); } bzero(buff+read_length,MI_BLOCK_INFO_HEADER_LENGTH - in_buff_length - read_length); DBUG_RETURN(0); } /* _mi_read_cache */
MRN_API my_bool mroonga_normalize_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { st_mrn_normalize_info *info = NULL; String *result_str = NULL; initid->ptr = NULL; if (!(1 <= args->arg_count && args->arg_count <= 2)) { sprintf(message, "mroonga_normalize(): Incorrect number of arguments: %u for 1..2", args->arg_count); goto error; } if (args->arg_type[0] != STRING_RESULT) { strcpy(message, "mroonga_normalize(): The 1st argument must be query as string"); goto error; } if (args->arg_count == 2) { if (args->arg_type[1] != STRING_RESULT) { strcpy(message, "mroonga_normalize(): " "The 2st argument must be normalizer name as string"); goto error; } } initid->maybe_null = 1; initid->const_item = 0; info = (st_mrn_normalize_info *)mrn_my_malloc(sizeof(st_mrn_normalize_info), MYF(MY_WME | MY_ZEROFILL)); if (!info) { strcpy(message, "mroonga_normalize(): out of memory"); goto error; } info->ctx = mrn_context_pool->pull(); { const char *current_db_path = MRN_THD_DB_PATH(current_thd); const char *action; if (current_db_path) { action = "open database"; mrn::Database *db; int error = mrn_db_manager->open(current_db_path, &db); if (error == 0) { info->db = db->get(); grn_ctx_use(info->ctx, info->db); info->use_shared_db = true; } } else { action = "create anonymous database"; info->db = grn_db_create(info->ctx, NULL, NULL); info->use_shared_db = false; } if (!info->db) { sprintf(message, "mroonga_normalize(): failed to %s: %s", action, info->ctx->errbuf); goto error; } } if (args->arg_count == 1) { info->normalizer = grn_ctx_get(info->ctx, DEFAULT_NORMALIZER_NAME, -1); } else { info->normalizer = grn_ctx_get(info->ctx, args->args[1], args->lengths[1]); } if (!info->normalizer) { sprintf(message, "mroonga_normalize(): nonexistent normalizer %.*s", (int)args->lengths[1], args->args[1]); goto error; } info->flags = 0; result_str = &(info->result_str); mrn::encoding::set_raw(info->ctx, system_charset_info); result_str->set_charset(system_charset_info); initid->ptr = (char *)info; return FALSE; error: if (info) { if (!info->use_shared_db) { grn_obj_close(info->ctx, info->db); } mrn_context_pool->release(info->ctx); my_free(info); } return TRUE; }
int main(int argc, char **argv) { gcry_error_t gcry_error; File filein = 0; File fileout = 0; MY_INIT(argv[0]); if (get_options(&argc, &argv)) { goto err; } /* Acording to gcrypt docs (and my testing), setting up the threading callbacks must be done first, so, lets give it a shot */ gcry_error = gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); if (gcry_error) { msg("%s: unable to set libgcrypt thread cbs - " "%s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); return 1; } /* Version check should be the very first call because it makes sure that important subsystems are intialized. */ if (!gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) { const char *gcrypt_version; gcrypt_version = gcry_check_version(NULL); /* No other library has already initialized libgcrypt. */ if (!gcrypt_version) { msg("%s: failed to initialize libgcrypt\n", my_progname); return 1; } else if (opt_verbose) { msg("%s: using gcrypt %s\n", my_progname, gcrypt_version); } } gcry_control(GCRYCTL_DISABLE_SECMEM, 0); gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); /* Determine the algorithm */ encrypt_algo = encrypt_algos[opt_encrypt_algo]; /* Set up the iv length */ encrypt_iv_len = gcry_cipher_get_algo_blklen(encrypt_algo); /* Now set up the key */ if (opt_encrypt_key == NULL && opt_encrypt_key_file == NULL) { msg("%s: no encryption key or key file specified.\n", my_progname); return 1; } else if (opt_encrypt_key && opt_encrypt_key_file) { msg("%s: both encryption key and key file specified.\n", my_progname); return 1; } else if (opt_encrypt_key_file) { if (!xb_crypt_read_key_file(opt_encrypt_key_file, &opt_encrypt_key, &encrypt_key_len)) { msg("%s: unable to read encryption key file \"%s\".\n", opt_encrypt_key_file, my_progname); return 1; } } else { encrypt_key_len = strlen(opt_encrypt_key); } if (opt_input_file) { MY_STAT mystat; if (opt_verbose) msg("%s: input file \"%s\".\n", my_progname, opt_input_file); if (my_stat(opt_input_file, &mystat, MYF(MY_WME)) == NULL) { goto err; } if (!MY_S_ISREG(mystat.st_mode)) { msg("%s: \"%s\" is not a regular file, exiting.\n", my_progname, opt_input_file); goto err; } if ((filein = my_open(opt_input_file, O_RDONLY, MYF(MY_WME))) < 0) { msg("%s: failed to open \"%s\".\n", my_progname, opt_input_file); goto err; } } else { if (opt_verbose) msg("%s: input from standard input.\n", my_progname); filein = fileno(stdin); } if (opt_output_file) { if (opt_verbose) msg("%s: output file \"%s\".\n", my_progname, opt_output_file); if ((fileout = my_create(opt_output_file, 0, O_WRONLY|O_BINARY|O_EXCL|O_NOFOLLOW, MYF(MY_WME))) < 0) { msg("%s: failed to create output file \"%s\".\n", my_progname, opt_output_file); goto err; } } else { if (opt_verbose) msg("%s: output to standard output.\n", my_progname); fileout = fileno(stdout); } if (opt_run_mode == RUN_MODE_DECRYPT && mode_decrypt(filein, fileout)) { goto err; } else if (opt_run_mode == RUN_MODE_ENCRYPT && mode_encrypt(filein, fileout)) { goto err; } if (opt_input_file && filein) { my_close(filein, MYF(MY_WME)); } if (opt_output_file && fileout) { my_close(fileout, MYF(MY_WME)); } my_cleanup_options(my_long_options); my_end(0); return EXIT_SUCCESS; err: if (opt_input_file && filein) { my_close(filein, MYF(MY_WME)); } if (opt_output_file && fileout) { my_close(fileout, MYF(MY_WME)); } my_cleanup_options(my_long_options); my_end(0); exit(EXIT_FAILURE); }
static int mode_decrypt(File filein, File fileout) { xb_rcrypt_t *xbcrypt_file = NULL; void *chunkbuf = NULL; size_t chunksize; size_t originalsize; void *ivbuf = NULL; size_t ivsize; void *decryptbuf = NULL; size_t decryptbufsize = 0; ulonglong ttlchunksread = 0; ulonglong ttlbytesread = 0; xb_rcrypt_result_t result; gcry_cipher_hd_t cipher_handle; gcry_error_t gcry_error; if (encrypt_algo != GCRY_CIPHER_NONE) { gcry_error = gcry_cipher_open(&cipher_handle, encrypt_algo, encrypt_mode, 0); if (gcry_error) { msg("%s:decrypt: unable to open libgcrypt" " cipher - %s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); return 1; } gcry_error = gcry_cipher_setkey(cipher_handle, opt_encrypt_key, encrypt_key_len); if (gcry_error) { msg("%s:decrypt: unable to set libgcrypt cipher" "key - %s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); goto err; } } /* Initialize the xb_crypt format reader */ xbcrypt_file = xb_crypt_read_open(&filein, my_xb_crypt_read_callback); if (xbcrypt_file == NULL) { msg("%s:decrypt: xb_crypt_read_open() failed.\n", my_progname); goto err; } /* Walk the encrypted chunks, decrypting them and writing out */ while ((result = xb_crypt_read_chunk(xbcrypt_file, &chunkbuf, &originalsize, &chunksize, &ivbuf, &ivsize)) == XB_CRYPT_READ_CHUNK) { if (encrypt_algo != GCRY_CIPHER_NONE) { gcry_error = gcry_cipher_reset(cipher_handle); if (gcry_error) { msg("%s:decrypt: unable to reset libgcrypt" " cipher - %s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); goto err; } if (ivsize) { gcry_error = gcry_cipher_setiv(cipher_handle, ivbuf, ivsize); } else { gcry_error = gcry_cipher_setiv(cipher_handle, v1_encrypt_iv, encrypt_iv_len); } if (gcry_error) { msg("%s:decrypt: unable to set cipher iv - " "%s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); continue; } if (decryptbufsize < originalsize) { if (decryptbufsize) { decryptbuf = my_realloc(decryptbuf, originalsize, MYF(MY_WME)); decryptbufsize = originalsize; } else { decryptbuf = my_malloc(originalsize, MYF(MY_WME)); decryptbufsize = originalsize; } } /* Try to decrypt it */ gcry_error = gcry_cipher_decrypt(cipher_handle, decryptbuf, originalsize, chunkbuf, chunksize); if (gcry_error) { msg("%s:decrypt: unable to decrypt chunk - " "%s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); gcry_cipher_close(cipher_handle); goto err; } } else { decryptbuf = chunkbuf; } /* Write it out */ if (my_write(fileout, decryptbuf, originalsize, MYF(MY_WME | MY_NABP))) { msg("%s:decrypt: unable to write output chunk.\n", my_progname); goto err; } ttlchunksread++; ttlbytesread += chunksize; if (opt_verbose) msg("%s:decrypt: %llu chunks read, %llu bytes read\n.", my_progname, ttlchunksread, ttlbytesread); } xb_crypt_read_close(xbcrypt_file); if (encrypt_algo != GCRY_CIPHER_NONE) gcry_cipher_close(cipher_handle); if (decryptbuf && decryptbufsize) my_free(decryptbuf); if (opt_verbose) msg("\n%s:decrypt: done\n", my_progname); return 0; err: if (xbcrypt_file) xb_crypt_read_close(xbcrypt_file); if (encrypt_algo != GCRY_CIPHER_NONE) gcry_cipher_close(cipher_handle); if (decryptbuf && decryptbufsize) my_free(decryptbuf); return 1; }
void reset_tree(TREE* tree) { /* do not free mem_root, just mark blocks as free */ free_tree(tree, MYF(MY_MARK_BLOCKS_FREE)); }
TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size, void* custom_arg) { int cmp; TREE_ELEMENT *element,***parent; parent= tree->parents; *parent = &tree->root; element= tree->root; for (;;) { if (element == &tree->null_element || (cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree,element), key)) == 0) break; if (cmp < 0) { *++parent= &element->right; element= element->right; } else { *++parent = &element->left; element= element->left; } } if (element == &tree->null_element) { uint alloc_size=sizeof(TREE_ELEMENT)+key_size+tree->size_of_element; tree->allocated+=alloc_size; if (tree->memory_limit && tree->elements_in_tree && tree->allocated > tree->memory_limit) { reset_tree(tree); return tree_insert(tree, key, key_size, custom_arg); } key_size+=tree->size_of_element; if (tree->with_delete) element=(TREE_ELEMENT *) my_malloc(alloc_size, MYF(MY_WME)); else element=(TREE_ELEMENT *) alloc_root(&tree->mem_root,alloc_size); if (!element) return(NULL); **parent=element; element->left=element->right= &tree->null_element; if (!tree->offset_to_key) { if (key_size == sizeof(void*)) /* no length, save pointer */ *((void**) (element+1))=key; else { *((void**) (element+1))= (void*) ((void **) (element+1)+1); memcpy((uchar*) *((void **) (element+1)),key, (size_t) (key_size-sizeof(void*))); } } else memcpy((uchar*) element+tree->offset_to_key,key,(size_t) key_size); element->count=1; /* May give warning in purify */ tree->elements_in_tree++; rb_insert(tree,parent,element); /* rebalance tree */ } else { if (tree->flag & TREE_NO_DUPS) return(NULL); element->count++; /* Avoid a wrap over of the count. */ if (! element->count) element->count--; } DBUG_EXECUTE("check_tree", test_rb_tree(tree->root););
void delete_tree(TREE* tree) { free_tree(tree, MYF(0)); /* my_free() mem_root if applicable */ }
int my_copy(const char *from, const char *to, myf MyFlags) { size_t Count; my_bool new_file_stat= 0; /* 1 if we could stat "to" */ int create_flag; File from_file,to_file; uchar buff[IO_SIZE]; MY_STAT stat_buff,new_stat_buff; DBUG_ENTER("my_copy"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); from_file=to_file= -1; DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */ if (MyFlags & MY_HOLD_ORIGINAL_MODES) /* Copy stat if possible */ new_file_stat= test(my_stat((char*) to, &new_stat_buff, MYF(0))); if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0) { if (!my_stat(from, &stat_buff, MyFlags)) { my_errno=errno; goto err; } if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat) stat_buff=new_stat_buff; create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC; if ((to_file= my_create(to,(int) stat_buff.st_mode, O_WRONLY | create_flag | O_BINARY | O_SHARE, MyFlags)) < 0) goto err; while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0) { if (Count == (uint) -1 || my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP))) goto err; } /* sync the destination file */ if (MyFlags & MY_SYNC) { if (my_sync(to_file, MyFlags)) goto err; } if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags)) DBUG_RETURN(-1); /* Error on close */ /* Copy modes if possible */ if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat) DBUG_RETURN(0); /* File copyed but not stat */ /* Copy modes */ if (chmod(to, stat_buff.st_mode & 07777)) { my_errno= errno; if (MyFlags & (MY_FAE+MY_WME)) my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno); goto err; } #if !defined(__WIN__) /* Copy ownership */ if (chown(to, stat_buff.st_uid, stat_buff.st_gid)) { my_errno= errno; if (MyFlags & (MY_FAE+MY_WME)) my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno); goto err; } #endif if (MyFlags & MY_COPYTIME) { struct utimbuf timep; timep.actime = stat_buff.st_atime; timep.modtime = stat_buff.st_mtime; (void) utime((char*) to, &timep); /* last accessed and modified times */ } DBUG_RETURN(0); } err: if (from_file >= 0) (void) my_close(from_file,MyFlags); if (to_file >= 0) { (void) my_close(to_file, MyFlags); /* attempt to delete the to-file we've partially written */ (void) my_delete(to, MyFlags); } DBUG_RETURN(-1); } /* my_copy */
File create_temp_file(char *to, const char *dir, const char *prefix, int mode, myf MyFlags) { File file= -1; #ifdef _WIN32 TCHAR path_buf[MAX_PATH-14]; #endif DBUG_ENTER("create_temp_file"); DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir, prefix)); #if defined(_WIN32) /* Use GetTempPath to determine path for temporary files. This is because the documentation for GetTempFileName has the following to say about this parameter: "If this parameter is NULL, the function fails." */ if (!dir) { if(GetTempPath(sizeof(path_buf), path_buf) > 0) dir = path_buf; } /* Use GetTempFileName to generate a unique filename, create the file and release it's handle - uses up to the first three letters from prefix */ if (GetTempFileName(dir, prefix, 0, to) == 0) DBUG_RETURN(-1); DBUG_PRINT("info", ("name: %s", to)); /* Open the file without the "open only if file doesn't already exist" since the file has already been created by GetTempFileName */ if ((file= my_open(to, (mode & ~O_EXCL), MyFlags)) < 0) { /* Open failed, remove the file created by GetTempFileName */ int tmp= my_errno(); (void) my_delete(to, MYF(0)); set_my_errno(tmp); } #else /* mkstemp() is available on all non-Windows supported platforms. */ { char prefix_buff[30]; uint pfx_len; File org_file; pfx_len= (uint) (my_stpcpy(my_stpnmov(prefix_buff, prefix ? prefix : "tmp.", sizeof(prefix_buff)-7),"XXXXXX") - prefix_buff); if (!dir && ! (dir =getenv("TMPDIR"))) dir= DEFAULT_TMPDIR; if (strlen(dir)+ pfx_len > FN_REFLEN-2) { errno=ENAMETOOLONG; set_my_errno(ENAMETOOLONG); DBUG_RETURN(file); } my_stpcpy(convert_dirname(to,dir,NullS),prefix_buff); org_file=mkstemp(to); if (mode & O_TEMPORARY) (void) my_delete(to, MYF(MY_WME)); file=my_register_filename(org_file, to, FILE_BY_MKSTEMP, EE_CANTCREATEFILE, MyFlags); /* If we didn't manage to register the name, remove the temp file */ if (org_file >= 0 && file < 0) { int tmp=my_errno(); close(org_file); (void) my_delete(to, MYF(MY_WME)); set_my_errno(tmp); } } #endif if (file >= 0) { mysql_mutex_lock(&THR_LOCK_open); my_tmp_file_created++; mysql_mutex_unlock(&THR_LOCK_open); } DBUG_RETURN(file); }
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"); bzero((char*) &file,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; 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; 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); }
static int mode_encrypt(File filein, File fileout) { size_t bytesread; size_t chunkbuflen; void *chunkbuf = NULL; void *ivbuf = NULL; size_t encryptbuflen = 0; size_t encryptedlen = 0; void *encryptbuf = NULL; ulonglong ttlchunkswritten = 0; ulonglong ttlbyteswritten = 0; xb_wcrypt_t *xbcrypt_file = NULL; gcry_cipher_hd_t cipher_handle; gcry_error_t gcry_error; if (encrypt_algo != GCRY_CIPHER_NONE) { gcry_error = gcry_cipher_open(&cipher_handle, encrypt_algo, encrypt_mode, 0); if (gcry_error) { msg("%s:encrypt: unable to open libgcrypt cipher - " "%s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); return 1; } gcry_error = gcry_cipher_setkey(cipher_handle, opt_encrypt_key, encrypt_key_len); if (gcry_error) { msg("%s:encrypt: unable to set libgcrypt cipher key - " "%s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); goto err; } } posix_fadvise(filein, 0, 0, POSIX_FADV_SEQUENTIAL); xbcrypt_file = xb_crypt_write_open(&fileout, my_xb_crypt_write_callback); if (xbcrypt_file == NULL) { msg("%s:encrypt: xb_crypt_write_open() failed.\n", my_progname); goto err; } ivbuf = my_malloc(encrypt_iv_len, MYF(MY_FAE)); /* now read in data in chunk size, encrypt and write out */ chunkbuflen = opt_encrypt_chunk_size; chunkbuf = my_malloc(chunkbuflen, MYF(MY_FAE)); while ((bytesread = my_read(filein, chunkbuf, chunkbuflen, MYF(MY_WME))) > 0) { if (encrypt_algo != GCRY_CIPHER_NONE) { gcry_error = gcry_cipher_reset(cipher_handle); if (gcry_error) { msg("%s:encrypt: unable to reset cipher - " "%s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); goto err; } xb_crypt_create_iv(ivbuf, encrypt_iv_len); gcry_error = gcry_cipher_setiv(cipher_handle, ivbuf, encrypt_iv_len); if (gcry_error) { msg("%s:encrypt: unable to set cipher iv - " "%s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); continue; } if (encryptbuflen < bytesread) { if (encryptbuflen) { encryptbuf = my_realloc(encryptbuf, bytesread, MYF(MY_WME)); encryptbuflen = bytesread; } else { encryptbuf = my_malloc(bytesread, MYF(MY_WME)); encryptbuflen = bytesread; } } gcry_error = gcry_cipher_encrypt(cipher_handle, encryptbuf, encryptbuflen, chunkbuf, bytesread); encryptedlen = bytesread; if (gcry_error) { msg("%s:encrypt: unable to encrypt chunk - " "%s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); gcry_cipher_close(cipher_handle); goto err; } } else { encryptedlen = bytesread; encryptbuf = chunkbuf; } if (xb_crypt_write_chunk(xbcrypt_file, encryptbuf, bytesread, encryptedlen, ivbuf, encrypt_iv_len)) { msg("%s:encrypt: abcrypt_write_chunk() failed.\n", my_progname); goto err; } ttlchunkswritten++; ttlbyteswritten += encryptedlen; if (opt_verbose) msg("%s:encrypt: %llu chunks written, %llu bytes " "written\n.", my_progname, ttlchunkswritten, ttlbyteswritten); } my_free(ivbuf); my_free(chunkbuf); if (encryptbuf && encryptbuflen) my_free(encryptbuf); xb_crypt_write_close(xbcrypt_file); if (encrypt_algo != GCRY_CIPHER_NONE) gcry_cipher_close(cipher_handle); if (opt_verbose) msg("\n%s:encrypt: done\n", my_progname); return 0; err: if (chunkbuf) my_free(chunkbuf); if (encryptbuf && encryptbuflen) my_free(encryptbuf); if (xbcrypt_file) xb_crypt_write_close(xbcrypt_file); if (encrypt_algo != GCRY_CIPHER_NONE) gcry_cipher_close(cipher_handle); return 1; }
int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, MI_INFO *(*callback)(void*), void *callback_param, my_bool *need_compat_check) { ulonglong file_offset; MI_INFO *myisam; int errpos; int save_errno; uint idx; uint child_nr; uint UNINIT_VAR(key_parts); uint min_keys; my_bool bad_children= FALSE; my_bool first_child= TRUE; DBUG_ENTER("myrg_attach_children"); DBUG_PRINT("myrg", ("handle_locking: %d", handle_locking)); /* This function can be called while another thread is trying to abort locks of this MERGE table. If the processor reorders instructions or write to memory, 'children_attached' could be set before 'open_tables' has all the pointers to the children. Use of a mutex here and in ha_myisammrg::store_lock() forces consistent data. */ mysql_mutex_lock(&m_info->mutex); errpos= 0; file_offset= 0; min_keys= 0; for (child_nr= 0; child_nr < m_info->tables; child_nr++) { if (! (myisam= (*callback)(callback_param))) { if (handle_locking & HA_OPEN_FOR_REPAIR) { /* An appropriate error should've been already pushed by callback. */ bad_children= TRUE; continue; } goto bad_children; } DBUG_PRINT("myrg", ("child_nr: %u table: '%s'", child_nr, myisam->filename)); /* Special handling when the first child is attached. */ if (first_child) { first_child= FALSE; m_info->reclength= myisam->s->base.reclength; min_keys= myisam->s->base.keys; key_parts= myisam->s->base.key_parts; if (*need_compat_check && m_info->rec_per_key_part) { my_free(m_info->rec_per_key_part); m_info->rec_per_key_part= NULL; } if (!m_info->rec_per_key_part) { if(!(m_info->rec_per_key_part= (ulong*) my_malloc(key_parts * sizeof(long), MYF(MY_WME)))) goto err; /* purecov: inspected */ errpos= 1; } bzero((char*) m_info->rec_per_key_part, key_parts * sizeof(long)); } /* Add MyISAM table info. */ m_info->open_tables[child_nr].table= myisam; m_info->open_tables[child_nr].file_offset= (my_off_t) file_offset; file_offset+= myisam->state->data_file_length; /* Check table definition match. */ if (m_info->reclength != myisam->s->base.reclength) { DBUG_PRINT("error", ("definition mismatch table: '%s' repair: %d", myisam->filename, (handle_locking & HA_OPEN_FOR_REPAIR))); if (handle_locking & HA_OPEN_FOR_REPAIR) { myrg_print_wrong_table(myisam->filename); bad_children= TRUE; continue; } goto bad_children; } m_info->options|= myisam->s->options; m_info->records+= myisam->state->records; m_info->del+= myisam->state->del; m_info->data_file_length+= myisam->state->data_file_length; if (min_keys > myisam->s->base.keys) min_keys= myisam->s->base.keys; /* purecov: inspected */ for (idx= 0; idx < key_parts; idx++) m_info->rec_per_key_part[idx]+= (myisam->s->state.rec_per_key_part[idx] / m_info->tables); } if (bad_children) goto bad_children; if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L) { my_errno= HA_ERR_RECORD_FILE_FULL; 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->keys= min_keys; m_info->last_used_table= m_info->open_tables; m_info->children_attached= TRUE; mysql_mutex_unlock(&m_info->mutex); DBUG_RETURN(0); bad_children: my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; err: save_errno= my_errno; switch (errpos) { case 1: my_free(m_info->rec_per_key_part); m_info->rec_per_key_part= NULL; } mysql_mutex_unlock(&m_info->mutex); my_errno= save_errno; DBUG_RETURN(1); }
/* Change size of file. SYNOPSIS my_chsize() fd File descriptor new_length New file size filler If we don't have truncate, fill up all bytes after new_length with this character MyFlags Flags DESCRIPTION my_chsize() truncates file if shorter else fill with the filler character. The function also changes the file pointer. Usually it points to the end of the file after execution. RETURN VALUE 0 Ok 1 Error */ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) { my_off_t oldsize; uchar buff[IO_SIZE]; DBUG_ENTER("my_chsize"); DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength, MyFlags)); if ((oldsize= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength) DBUG_RETURN(0); DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize)); if (oldsize > newlength) { #ifdef _WIN32 if (my_win_chsize(fd, newlength)) { my_errno= errno; goto err; } DBUG_RETURN(0); #elif defined(HAVE_FTRUNCATE) if (ftruncate(fd, (off_t) newlength)) { my_errno= errno; goto err; } DBUG_RETURN(0); #elif defined(HAVE_CHSIZE) if (chsize(fd, (off_t) newlength)) { my_errno=errno; goto err; } DBUG_RETURN(0); #else /* Fill space between requested length and true length with 'filler' We should never come here on any modern machine */ if (my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE)) == MY_FILEPOS_ERROR) { goto err; } swap_variables(my_off_t, newlength, oldsize); #endif } /* Full file with 'filler' until it's as big as requested */ bfill(buff, IO_SIZE, filler); while (newlength-oldsize > IO_SIZE) { if (my_write(fd, buff, IO_SIZE, MYF(MY_NABP))) goto err; oldsize+= IO_SIZE; } if (my_write(fd,buff,(size_t) (newlength-oldsize), MYF(MY_NABP))) goto err; DBUG_RETURN(0); err: DBUG_PRINT("error", ("errno: %d", errno)); if (MyFlags & MY_WME) my_error(EE_CANT_CHSIZE, MYF(ME_BELL+ME_WAITTANG), my_errno); DBUG_RETURN(1); } /* my_chsize */
int main(int argc, char **argv) { int error; my_bool first_argument_uses_wildcards=0; char *wild; MYSQL mysql; MY_INIT(argv[0]); load_defaults("my",load_default_groups,&argc,&argv); get_options(&argc,&argv); wild=0; if (argc) { char *pos= argv[argc-1], *to; for (to= pos ; *pos ; pos++, to++) { switch (*pos) { case '*': *pos= '%'; first_argument_uses_wildcards= 1; break; case '?': *pos= '_'; first_argument_uses_wildcards= 1; break; case '%': case '_': first_argument_uses_wildcards= 1; break; case '\\': pos++; default: break; } *to= *pos; } *to= *pos; /* just to copy a '\0' if '\\' was used */ } if (first_argument_uses_wildcards) wild= argv[--argc]; else if (argc == 3) /* We only want one field */ wild= argv[--argc]; if (argc > 2) { fprintf(stderr,"%s: Too many arguments\n",my_progname); exit(1); } mysql_init(&mysql); if (opt_compress) mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); #ifdef HAVE_OPENSSL if (opt_use_ssl) mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (char*)&opt_ssl_verify_server_cert); #endif if (opt_protocol) mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); #ifdef HAVE_SMEM if (shared_memory_base_name) mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); #endif mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); if (!(mysql_real_connect(&mysql,host,user,opt_password, (first_argument_uses_wildcards) ? "" : argv[0],opt_mysql_port,opt_mysql_unix_port, 0))) { fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql)); exit(1); } mysql.reconnect= 1; switch (argc) { case 0: error=list_dbs(&mysql,wild); break; case 1: if (opt_status) error=list_table_status(&mysql,argv[0],wild); else error=list_tables(&mysql,argv[0],wild); break; default: if (opt_status && ! wild) error=list_table_status(&mysql,argv[0],argv[1]); else error=list_fields(&mysql,argv[0],argv[1],wild); break; } mysql_close(&mysql); /* Close & free connection */ if (opt_password) my_free(opt_password,MYF(0)); #ifdef HAVE_SMEM my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); #endif my_end(0); exit(error ? 1 : 0); return 0; /* No compiler warnings */ }
/* {{{ MADB_SetIrdRecord */ my_bool MADB_SetIrdRecord(MADB_Stmt *Stmt, MADB_DescRecord *Record, MYSQL_FIELD *Field) { if (Record == NULL) { return 1; } Record->CatalogName= Field->catalog ? my_strdup(Field->catalog, MYF(0)) : NULL; Record->TableName= Field->table ? my_strdup(Field->table, MYF(0)) : NULL; Record->ColumnName= Field->name ? my_strdup(Field->name, MYF(0)) : NULL; Record->BaseTableName= Field->org_table ? my_strdup(Field->org_table, MYF(0)) : NULL; Record->BaseColumnName= Field->org_name ? my_strdup(Field->org_name, MYF(0)) : NULL; Record->AutoUniqueValue= (Field->flags & AUTO_INCREMENT_FLAG) ? SQL_TRUE : SQL_FALSE; Record->CaseSensitive= (Field->flags & BINARY_FLAG) ? SQL_TRUE : SQL_FALSE; Record->Nullable= ( (Field->flags & NOT_NULL_FLAG) && !Record->AutoUniqueValue && Field->type != MYSQL_TYPE_TIMESTAMP) ? SQL_NO_NULLS : SQL_NULLABLE; Record->Unsigned= (Field->flags & UNSIGNED_FLAG) ? SQL_TRUE : SQL_FALSE; /* We assume it might be updatable if tablename exists */ Record->Updateable= (Field->table && Field->table[0]) ? SQL_ATTR_READWRITE_UNKNOWN : SQL_ATTR_READONLY; /* RADIX: If the data type in the SQL_DESC_TYPE field is an approximate numeric data type, this SQLINTEGER field contains a value of 2 because the SQL_DESC_PRECISION field contains the number of bits. If the data type in the SQL_DESC_TYPE field is an exact numeric data type, this field contains a value of 10 because the SQL_DESC_PRECISION field contains the number of decimal digits. This field is set to 0 for all non-numeric data types. */ switch (Field->type) { case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: Record->FixedPrecScale= SQL_FALSE; Record->NumPrecRadix= 10; Record->Precision= (SQLSMALLINT)Field->length - 2; Record->Scale= Field->decimals; break; case MYSQL_TYPE_FLOAT: Record->FixedPrecScale= SQL_FALSE; Record->NumPrecRadix= 2; Record->Precision= (SQLSMALLINT)Field->length - 2; //Record->Scale= Field->decimals; break; case MYSQL_TYPE_BIT: if (Field->length > 1) Record->Type= SQL_BINARY; break; case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_INT24: case MYSQL_TYPE_YEAR: case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: Record->NumPrecRadix= 10; break; default: Record->NumPrecRadix= 0; break; } Record->ConciseType= MADB_GetODBCType(Field); /* TYPE: For the datetime and interval data types, this field returns the verbose data type: SQL_DATETIME or SQL_INTERVAL. */ Record->Type= (Record->ConciseType == SQL_TYPE_DATE || Record->ConciseType == SQL_DATE || Record->ConciseType == SQL_TYPE_TIME || Record->ConciseType == SQL_TIME || Record->ConciseType == SQL_TYPE_TIMESTAMP || Record->ConciseType == SQL_TIMESTAMP) ? SQL_DATETIME : Record->ConciseType; switch(Record->ConciseType) { case SQL_TYPE_DATE: Record->DateTimeIntervalCode= SQL_CODE_DATE; break; case SQL_TYPE_TIME: Record->DateTimeIntervalCode= SQL_CODE_TIME; break; case SQL_TYPE_TIMESTAMP: Record->DateTimeIntervalCode= SQL_CODE_TIMESTAMP; break; } /* SEARCHABLE: Columns of type SQL_LONGVARCHAR and SQL_LONGVARBINARY usually return SQL_PRED_CHAR. */ Record->Searchable= (Record->ConciseType == SQL_LONGVARCHAR || Record->ConciseType == SQL_WLONGVARCHAR || Record->ConciseType == SQL_LONGVARBINARY) ? SQL_PRED_CHAR : SQL_SEARCHABLE; Record->DisplaySize= MADB_GetDisplaySize(*Field, mysql_get_charset_by_nr(Field->charsetnr)); Record->OctetLength= MADB_GetOctetLength(*Field, Stmt->Connection->mariadb->charset->char_maxlen); Record->Length= MADB_GetDataSize(Record, *Field, mysql_get_charset_by_nr(Field->charsetnr)); Record->TypeName= my_strdup(MADB_GetTypeName(*Field), MYF(0)); switch(Field->type) { case MYSQL_TYPE_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_STRING: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_VAR_STRING: if (Field->flags & BINARY_FLAG) { Record->LiteralPrefix= "0x"; Record->LiteralSuffix= ""; break; } /* else default */ case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_NEWDATE: case MYSQL_TYPE_TIME: case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_YEAR: Record->LiteralPrefix="'"; Record->LiteralSuffix= "'"; break; default: Record->LiteralPrefix= ""; Record->LiteralSuffix= ""; break; } return 0; }
struct st_VioSSLConnectorFd * new_VioSSLConnectorFd(const char* key_file, const char* cert_file, const char* ca_file, const char* ca_path, const char* cipher) { int verify = SSL_VERIFY_NONE; struct st_VioSSLConnectorFd* ptr; int result; DH *dh=NULL; DBUG_ENTER("new_VioSSLConnectorFd"); DBUG_PRINT("enter", ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s", key_file, cert_file, ca_path, ca_file, cipher)); if (!(ptr=((struct st_VioSSLConnectorFd*) my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0))))) DBUG_RETURN(0); ptr->ssl_context= 0; ptr->ssl_method= 0; /* FIXME: constants! */ if (!ssl_algorithms_added) { DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()")); ssl_algorithms_added = TRUE; OpenSSL_add_all_algorithms(); } if (!ssl_error_strings_loaded) { DBUG_PRINT("info", ("todo:SSL_load_error_strings()")); ssl_error_strings_loaded = TRUE; SSL_load_error_strings(); } ptr->ssl_method = TLSv1_client_method(); ptr->ssl_context = SSL_CTX_new(ptr->ssl_method); DBUG_PRINT("info", ("ssl_context: %p",ptr->ssl_context)); if (ptr->ssl_context == 0) { DBUG_PRINT("error", ("SSL_CTX_new failed")); report_errors(); goto ctor_failure; } /* SSL_CTX_set_options SSL_CTX_set_info_callback */ if (cipher) { result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher); DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result)); } SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback); if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1) { DBUG_PRINT("error", ("vio_set_cert_stuff failed")); report_errors(); goto ctor_failure; } if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file,ca_path) == 0) { DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); if (SSL_CTX_set_default_verify_paths(ptr->ssl_context) == 0) { DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed")); report_errors(); goto ctor_failure; } } /* DH stuff */ dh=get_dh512(); SSL_CTX_set_tmp_dh(ptr->ssl_context,dh); DH_free(dh); DBUG_RETURN(ptr); ctor_failure: DBUG_PRINT("exit", ("there was an error")); my_free((gptr)ptr,MYF(0)); DBUG_RETURN(0); }
static int add_collation(CHARSET_INFO *cs) { if (cs->name && (cs->number || (cs->number=get_collation_number_internal(cs->name))) && cs->number < array_elements(all_charsets)) { if (!all_charsets[cs->number]) { if (!(all_charsets[cs->number]= (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),MYF(0)))) return MY_XML_ERROR; memset(all_charsets[cs->number], 0, sizeof(CHARSET_INFO)); } if (cs->primary_number == cs->number) cs->state |= MY_CS_PRIMARY; if (cs->binary_number == cs->number) cs->state |= MY_CS_BINSORT; all_charsets[cs->number]->state|= cs->state; if (!(all_charsets[cs->number]->state & MY_CS_COMPILED)) { CHARSET_INFO *newcs= all_charsets[cs->number]; if (cs_copy_data(all_charsets[cs->number],cs)) return MY_XML_ERROR; newcs->caseup_multiply= newcs->casedn_multiply= 1; newcs->levels_for_compare= 1; newcs->levels_for_order= 1; if (!strcmp(cs->csname,"ucs2") ) { #if defined(HAVE_CHARSET_ucs2) && defined(HAVE_UCA_COLLATIONS) copy_uca_collation(newcs, &my_charset_ucs2_unicode_ci); newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII; #endif } else if (!strcmp(cs->csname, "utf8") || !strcmp(cs->csname, "utf8mb3")) { #if defined (HAVE_CHARSET_utf8) && defined(HAVE_UCA_COLLATIONS) copy_uca_collation(newcs, &my_charset_utf8_unicode_ci); newcs->ctype= my_charset_utf8_unicode_ci.ctype; if (init_state_maps(newcs)) return MY_XML_ERROR; #endif } else if (!strcmp(cs->csname, "utf8mb4")) { #if defined (HAVE_CHARSET_utf8mb4) && defined(HAVE_UCA_COLLATIONS) copy_uca_collation(newcs, &my_charset_utf8mb4_unicode_ci); newcs->ctype= my_charset_utf8mb4_unicode_ci.ctype; newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED; #endif } else if (!strcmp(cs->csname, "utf16")) { #if defined (HAVE_CHARSET_utf16) && defined(HAVE_UCA_COLLATIONS) copy_uca_collation(newcs, &my_charset_utf16_unicode_ci); newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII; #endif } else if (!strcmp(cs->csname, "utf32")) { #if defined (HAVE_CHARSET_utf32) && defined(HAVE_UCA_COLLATIONS) copy_uca_collation(newcs, &my_charset_utf32_unicode_ci); newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII; #endif } else { const uchar *sort_order= all_charsets[cs->number]->sort_order; simple_cs_init_functions(all_charsets[cs->number]); newcs->mbminlen= 1; newcs->mbmaxlen= 1; if (simple_cs_is_full(all_charsets[cs->number])) { all_charsets[cs->number]->state |= MY_CS_LOADED; } all_charsets[cs->number]->state|= MY_CS_AVAILABLE; /* Check if case sensitive sort order: A < a < B. We need MY_CS_FLAG for regex library, and for case sensitivity flag for 5.0 client protocol, to support isCaseSensitive() method in JDBC driver */ if (sort_order && sort_order['A'] < sort_order['a'] && sort_order['a'] < sort_order['B']) all_charsets[cs->number]->state|= MY_CS_CSSORT; if (my_charset_is_8bit_pure_ascii(all_charsets[cs->number])) all_charsets[cs->number]->state|= MY_CS_PUREASCII; if (!my_charset_is_ascii_compatible(cs)) all_charsets[cs->number]->state|= MY_CS_NONASCII; } } else { /* We need the below to make get_charset_name() and get_charset_number() working even if a character set has not been really incompiled. The above functions are used for example in error message compiler extra/comp_err.c. If a character set was compiled, this information will get lost and overwritten in add_compiled_collation(). */ CHARSET_INFO *dst= all_charsets[cs->number]; dst->number= cs->number; if (cs->comment) if (!(dst->comment= my_once_strdup(cs->comment,MYF(MY_WME)))) return MY_XML_ERROR; if (cs->csname) if (!(dst->csname= my_once_strdup(cs->csname,MYF(MY_WME)))) return MY_XML_ERROR; if (cs->name) if (!(dst->name= my_once_strdup(cs->name,MYF(MY_WME)))) return MY_XML_ERROR; } cs->number= 0; cs->primary_number= 0; cs->binary_number= 0; cs->name= NULL; cs->state= 0; cs->sort_order= NULL; cs->state= 0; } return MY_XML_OK; }
/* system msync() only syncs mmap'ed area to fs cache. fsync() is required to really sync to disc */ int my_msync(int fd, void *addr, size_t len, int flags) { msync(addr, len, flags); return my_sync(fd, MYF(0)); }
/** Wrappers for memory functions my_malloc (and friends) with C-compatbile API without extra "myf" argument. */ static void * my_once_alloc_c(size_t size) { return my_once_alloc(size, MYF(MY_WME)); }
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(buffer); 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; memset(finfo.mystat, 0, 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) { char errbuf[MYSYS_STRERROR_SIZE]; my_error(EE_DIR, MYF(ME_BELL+ME_WAITTANG), path, errno, my_strerror(errbuf, sizeof(errbuf), errno)); } DBUG_RETURN((MY_DIR *) NULL); } /* my_dir */
static void * my_realloc_c(void *old, size_t size) { return my_realloc(key_memory_charset_loader, old, size, MYF(MY_WME)); }
int mrn_parse_table_param(MRN_SHARE *share, TABLE *table) { int i, error = 0; int title_length; const char *sprit_ptr[2]; const char *tmp_ptr, *start_ptr; char *params_string = NULL; #ifdef WITH_PARTITION_STORAGE_ENGINE partition_element *part_elem; partition_element *sub_elem; #endif MRN_DBUG_ENTER_FUNCTION(); #ifdef WITH_PARTITION_STORAGE_ENGINE mrn_get_partition_info(share->table_name, share->table_name_length, table, &part_elem, &sub_elem); #endif #ifdef WITH_PARTITION_STORAGE_ENGINE for (i = 4; i > 0; i--) #else for (i = 2; i > 0; i--) #endif { const char *params_string_value = NULL; uint params_string_length = 0; switch (i) { #ifdef WITH_PARTITION_STORAGE_ENGINE case 4: if (!sub_elem || !sub_elem->part_comment) continue; DBUG_PRINT("info", ("mroonga create sub comment string")); params_string_value = sub_elem->part_comment; params_string_length = strlen(params_string_value); DBUG_PRINT("info", ("mroonga sub comment string=%s", params_string_value)); break; case 3: if (!part_elem || !part_elem->part_comment) continue; DBUG_PRINT("info", ("mroonga create part comment string")); params_string_value = part_elem->part_comment; params_string_length = strlen(params_string_value); DBUG_PRINT("info", ("mroonga part comment string=%s", params_string_value)); break; #endif case 2: if (LEX_STRING_IS_EMPTY(table->s->comment)) continue; DBUG_PRINT("info", ("mroonga create comment string")); params_string_value = table->s->comment.str; params_string_length = table->s->comment.length; DBUG_PRINT("info", ("mroonga comment string=%.*s", params_string_length, params_string_value)); break; default: if (LEX_STRING_IS_EMPTY(table->s->connect_string)) continue; DBUG_PRINT("info", ("mroonga create connect_string string")); params_string_value = table->s->connect_string.str; params_string_length = table->s->connect_string.length; DBUG_PRINT("info", ("mroonga connect_string=%.*s", params_string_length, params_string_value)); break; } if (!params_string_value) { continue; } { params_string = mrn_my_strndup(params_string_value, params_string_length, MYF(MY_WME)); if (!params_string) { error = HA_ERR_OUT_OF_MEM; goto error; } sprit_ptr[0] = params_string; while (sprit_ptr[0]) { if ((sprit_ptr[1] = strchr(sprit_ptr[0], ','))) { sprit_ptr[1]++; } tmp_ptr = sprit_ptr[0]; sprit_ptr[0] = sprit_ptr[1]; while (*tmp_ptr == ' ' || *tmp_ptr == '\r' || *tmp_ptr == '\n' || *tmp_ptr == '\t') tmp_ptr++; if (*tmp_ptr == '\0') continue; DBUG_PRINT("info", ("mroonga title_str=%s", tmp_ptr)); title_length = 0; start_ptr = tmp_ptr; while (*start_ptr != ' ' && *start_ptr != '\'' && *start_ptr != '"' && *start_ptr != '\0' && *start_ptr != '\r' && *start_ptr != '\n' && *start_ptr != '\t' && *start_ptr != ',') { title_length++; start_ptr++; } DBUG_PRINT("info", ("mroonga title_length=%u", title_length)); switch (title_length) { case 6: MRN_PARAM_STR("engine", engine); break; case 10: MRN_PARAM_STR("normalizer", normalizer); break; case 13: MRN_PARAM_STR("token_filters", token_filters); break; case 17: MRN_PARAM_STR("default_tokenizer", default_tokenizer); break; default: break; } } my_free(params_string); params_string = NULL; } } if (!share->engine && mrn_default_wrapper_engine) { share->engine_length = strlen(mrn_default_wrapper_engine); if ( !(share->engine = mrn_my_strndup(mrn_default_wrapper_engine, share->engine_length, MYF(MY_WME))) ) { error = HA_ERR_OUT_OF_MEM; goto error; } } if (share->engine) { LEX_STRING engine_name; if ( ( share->engine_length == MRN_DEFAULT_LEN && !strncasecmp(share->engine, MRN_DEFAULT_STR, MRN_DEFAULT_LEN) ) || ( share->engine_length == MRN_GROONGA_LEN && !strncasecmp(share->engine, MRN_GROONGA_STR, MRN_GROONGA_LEN) ) ) { my_free(share->engine); share->engine = NULL; share->engine_length = 0; } else { engine_name.str = share->engine; engine_name.length = share->engine_length; if (!(share->plugin = MRN_HA_RESOLVE_BY_NAME(&engine_name))) { my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), share->engine); error = ER_UNKNOWN_STORAGE_ENGINE; goto error; } share->hton = MRN_PLUGIN_DATA(share->plugin, handlerton *); share->wrapper_mode = TRUE; } }
MYRG_INFO *myrg_parent_open(const char *parent_name, int (*callback)(void*, const char*), void *callback_param) { MYRG_INFO *UNINIT_VAR(m_info); int rc; int errpos; int save_errno; int insert_method; uint length; uint child_count; 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= mysql_file_open(rg_key_file_MRG, 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, FIND_TYPE_BASIC); } 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. */ 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; 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) mysql_file_close(fd, MYF(0)); 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); /* purecov: begin inspected */ err: save_errno= my_errno; switch (errpos) { case 3: my_free(m_info); /* Fall through */ case 2: end_io_cache(&file_cache); /* Fall through */ case 1: (void) mysql_file_close(fd, MYF(0)); } my_errno= save_errno; DBUG_RETURN (NULL); /* purecov: end */ }
int mrn_add_column_param(MRN_SHARE *share, Field *field, int i) { int error; char *param_string = NULL; int title_length; char *sprit_ptr[2]; char *tmp_ptr, *start_ptr; MRN_DBUG_ENTER_FUNCTION(); if (share->wrapper_mode) { DBUG_RETURN(0); } DBUG_PRINT("info", ("mroonga create comment string")); if ( !(param_string = mrn_my_strndup(field->comment.str, field->comment.length, MYF(MY_WME))) ) { error = HA_ERR_OUT_OF_MEM; goto error_alloc_param_string; } DBUG_PRINT("info", ("mroonga comment string=%s", param_string)); sprit_ptr[0] = param_string; while (sprit_ptr[0]) { if ((sprit_ptr[1] = strchr(sprit_ptr[0], ','))) { *sprit_ptr[1] = '\0'; sprit_ptr[1]++; } tmp_ptr = sprit_ptr[0]; sprit_ptr[0] = sprit_ptr[1]; while (*tmp_ptr == ' ' || *tmp_ptr == '\r' || *tmp_ptr == '\n' || *tmp_ptr == '\t') tmp_ptr++; if (*tmp_ptr == '\0') continue; title_length = 0; start_ptr = tmp_ptr; while (*start_ptr != ' ' && *start_ptr != '\'' && *start_ptr != '"' && *start_ptr != '\0' && *start_ptr != '\r' && *start_ptr != '\n' && *start_ptr != '\t') { title_length++; start_ptr++; } switch (title_length) { case 4: MRN_PARAM_STR_LIST("type", col_type, i); break; case 5: MRN_PARAM_STR_LIST("flags", col_flags, i); break; case 12: MRN_PARAM_STR_LIST("groonga_type", col_type, i); break; default: break; } } if (param_string) my_free(param_string); DBUG_RETURN(0); error: if (param_string) my_free(param_string); error_alloc_param_string: DBUG_RETURN(error); }
int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, uint columns, MI_COLUMNDEF *recinfo, uint uniques, MI_UNIQUEDEF *uniquedefs, MI_CREATE_INFO *ci,uint flags) { register uint i,j; File UNINIT_VAR(dfile), UNINIT_VAR(file); int errpos,save_errno, create_mode= O_RDWR | O_TRUNC; myf create_flag; uint fields,length,max_key_length,packed,pointer,real_length_diff, key_length,info_length,key_segs,options,min_key_length_skip, base_pos,long_varchar_count,varchar_length, max_key_block_length,unique_key_parts,fulltext_keys,offset; uint aligned_key_start, block_length; ulong reclength, real_reclength,min_pack_length; char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr; ulong pack_reclength; ulonglong tot_length,max_rows, tmp; enum en_fieldtype type; MYISAM_SHARE share; MI_KEYDEF *keydef,tmp_keydef; MI_UNIQUEDEF *uniquedef; HA_KEYSEG *keyseg,tmp_keyseg; MI_COLUMNDEF *rec; ulong *rec_per_key_part; my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE]; MI_CREATE_INFO tmp_create_info; DBUG_ENTER("mi_create"); DBUG_PRINT("enter", ("keys: %u columns: %u uniques: %u flags: %u", keys, columns, uniques, flags)); if (!ci) { bzero((char*) &tmp_create_info,sizeof(tmp_create_info)); ci=&tmp_create_info; } if (keys + uniques > MI_MAX_KEY || columns == 0) { DBUG_RETURN(my_errno=HA_WRONG_CREATE_OPTION); } errpos=0; options=0; bzero((uchar*) &share,sizeof(share)); if (flags & HA_DONT_TOUCH_DATA) { if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD)) options=ci->old_options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD | HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE); else options=ci->old_options & (HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE); } if (ci->reloc_rows > ci->max_rows) ci->reloc_rows=ci->max_rows; /* Check if wrong parameter */ if (!(rec_per_key_part= (ulong*) my_malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long), MYF(MY_WME | MY_ZEROFILL)))) DBUG_RETURN(my_errno); /* Start by checking fields and field-types used */ reclength=varchar_length=long_varchar_count=packed= min_pack_length=pack_reclength=0; for (rec=recinfo, fields=0 ; fields != columns ; rec++,fields++) { reclength+=rec->length; if ((type=(enum en_fieldtype) rec->type) != FIELD_NORMAL && type != FIELD_CHECK) { packed++; if (type == FIELD_BLOB) { share.base.blobs++; if (pack_reclength != INT_MAX32) { if (rec->length == 4+portable_sizeof_char_ptr) pack_reclength= INT_MAX32; else pack_reclength+=(1 << ((rec->length-portable_sizeof_char_ptr)*8)); /* Max blob length */ } } else if (type == FIELD_SKIP_PRESPACE || type == FIELD_SKIP_ENDSPACE) { if (pack_reclength != INT_MAX32) pack_reclength+= rec->length > 255 ? 2 : 1; min_pack_length++; } else if (type == FIELD_VARCHAR) { varchar_length+= rec->length-1; /* Used for min_pack_length */ packed--; pack_reclength++; min_pack_length++; /* We must test for 257 as length includes pack-length */ if (test(rec->length >= 257)) { long_varchar_count++; pack_reclength+= 2; /* May be packed on 3 bytes */ } } else if (type != FIELD_SKIP_ZERO) { min_pack_length+=rec->length; packed--; /* Not a pack record type */ } } else /* FIELD_NORMAL */ min_pack_length+=rec->length; } if ((packed & 7) == 1) { /* Bad packing, try to remove a zero-field */ while (rec != recinfo) { rec--; if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1) { /* NOTE1: here we change a field type FIELD_SKIP_ZERO -> FIELD_NORMAL */ rec->type=(int) FIELD_NORMAL; packed--; min_pack_length++; break; } } } if (packed || (flags & HA_PACK_RECORD)) options|=HA_OPTION_PACK_RECORD; /* Must use packed records */ /* We can't use checksum with static length rows */ if (!(options & HA_OPTION_PACK_RECORD)) options&= ~HA_OPTION_CHECKSUM; if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))) min_pack_length+= varchar_length; if (flags & HA_CREATE_TMP_TABLE) { options|= HA_OPTION_TMP_TABLE; create_mode|= O_EXCL | O_NOFOLLOW; } if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM)) { options|= HA_OPTION_CHECKSUM; min_pack_length++; } if (flags & HA_CREATE_DELAY_KEY_WRITE) options|= HA_OPTION_DELAY_KEY_WRITE; if (flags & HA_CREATE_RELIES_ON_SQL_LAYER) options|= HA_OPTION_RELIES_ON_SQL_LAYER; packed=(packed+7)/8; if (pack_reclength != INT_MAX32) pack_reclength+= reclength+packed + test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_OPTION_PACK_RECORD)); min_pack_length+=packed; if (!ci->data_file_length && ci->max_rows) { if (pack_reclength == INT_MAX32 || (~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength) ci->data_file_length= ~(ulonglong) 0; else ci->data_file_length=(ulonglong) ci->max_rows*pack_reclength; } else if (!ci->max_rows) ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length + ((options & HA_OPTION_PACK_RECORD) ? 3 : 0))); if (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD)) pointer=mi_get_pointer_length(ci->data_file_length,myisam_data_pointer_size); else pointer=mi_get_pointer_length(ci->max_rows,myisam_data_pointer_size); if (!(max_rows=(ulonglong) ci->max_rows)) max_rows= ((((ulonglong) 1 << (pointer*8)) -1) / min_pack_length); real_reclength=reclength; if (!(options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))) { if (reclength <= pointer) reclength=pointer+1; /* reserve place for delete link */ } else reclength+= long_varchar_count; /* We need space for varchar! */ max_key_length=0; tot_length=0 ; key_segs=0; fulltext_keys=0; max_key_block_length=0; share.state.rec_per_key_part=rec_per_key_part; share.state.key_root=key_root; share.state.key_del=key_del; if (uniques) { max_key_block_length= myisam_block_size; max_key_length= MI_UNIQUE_HASH_LENGTH + pointer; } for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++) { share.state.key_root[i]= HA_OFFSET_ERROR; min_key_length_skip=length=real_length_diff=0; key_length=pointer; if (keydef->flag & HA_SPATIAL) { #ifdef HAVE_SPATIAL /* BAR TODO to support 3D and more dimensions in the future */ uint sp_segs=SPDIMS*2; keydef->flag=HA_SPATIAL; if (flags & HA_DONT_TOUCH_DATA) { /* called by myisamchk - i.e. table structure was taken from MYI file and SPATIAL key *does have* additional sp_segs keysegs. keydef->seg here points right at the GEOMETRY segment, so we only need to decrease keydef->keysegs. (see recreate_table() in mi_check.c) */ keydef->keysegs-=sp_segs-1; } for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ; j++, keyseg++) { if (keyseg->type != HA_KEYTYPE_BINARY && keyseg->type != HA_KEYTYPE_VARBINARY1 && keyseg->type != HA_KEYTYPE_VARBINARY2) { my_errno=HA_WRONG_CREATE_OPTION; goto err; } } keydef->keysegs+=sp_segs; key_length+=SPLEN*sp_segs; length++; /* At least one length byte */ min_key_length_skip+=SPLEN*2*SPDIMS; #else my_errno= HA_ERR_UNSUPPORTED; goto err; #endif /*HAVE_SPATIAL*/ } else if (keydef->flag & HA_FULLTEXT) { keydef->flag=HA_FULLTEXT | HA_PACK_KEY | HA_VAR_LENGTH_KEY; options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ; j++, keyseg++) { if (keyseg->type != HA_KEYTYPE_TEXT && keyseg->type != HA_KEYTYPE_VARTEXT1 && keyseg->type != HA_KEYTYPE_VARTEXT2) { my_errno=HA_WRONG_CREATE_OPTION; goto err; } if (!(keyseg->flag & HA_BLOB_PART) && (keyseg->type == HA_KEYTYPE_VARTEXT1 || keyseg->type == HA_KEYTYPE_VARTEXT2)) { /* Make a flag that this is a VARCHAR */ keyseg->flag|= HA_VAR_LENGTH_PART; /* Store in bit_start number of bytes used to pack the length */ keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1)? 1 : 2); } } fulltext_keys++; key_length+= HA_FT_MAXBYTELEN+HA_FT_WLEN; length++; /* At least one length byte */ min_key_length_skip+=HA_FT_MAXBYTELEN; real_length_diff=HA_FT_MAXBYTELEN-FT_MAX_WORD_LEN_FOR_SORT; } else { /* Test if prefix compression */ if (keydef->flag & HA_PACK_KEY) { /* Can't use space_compression on number keys */ if ((keydef->seg[0].flag & HA_SPACE_PACK) && keydef->seg[0].type == (int) HA_KEYTYPE_NUM) keydef->seg[0].flag&= ~HA_SPACE_PACK; /* Only use HA_PACK_KEY when first segment is a variable length key */ if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART | HA_VAR_LENGTH_PART))) { /* pack relative to previous key */ keydef->flag&= ~HA_PACK_KEY; keydef->flag|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY; } else { keydef->seg[0].flag|=HA_PACK_KEY; /* for easyer intern test */ keydef->flag|=HA_VAR_LENGTH_KEY; options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ } } if (keydef->flag & HA_BINARY_PACK_KEY) options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ if (keydef->flag & HA_AUTO_KEY && ci->with_auto_increment) share.base.auto_key=i+1; for (j=0, keyseg=keydef->seg ; j < keydef->keysegs ; j++, keyseg++) { /* numbers are stored with high by first to make compression easier */ switch (keyseg->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: keyseg->flag|= HA_SWAP_KEY; break; case HA_KEYTYPE_VARTEXT1: case HA_KEYTYPE_VARTEXT2: case HA_KEYTYPE_VARBINARY1: case HA_KEYTYPE_VARBINARY2: if (!(keyseg->flag & HA_BLOB_PART)) { /* Make a flag that this is a VARCHAR */ keyseg->flag|= HA_VAR_LENGTH_PART; /* Store in bit_start number of bytes used to pack the length */ keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 || keyseg->type == HA_KEYTYPE_VARBINARY1) ? 1 : 2); } break; default: break; } if (keyseg->flag & HA_SPACE_PACK) { DBUG_ASSERT(!(keyseg->flag & HA_VAR_LENGTH_PART)); keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY; options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ length++; /* At least one length byte */ min_key_length_skip+=keyseg->length; if (keyseg->length >= 255) { /* prefix may be 3 bytes */ min_key_length_skip+=2; length+=2; } } if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART)) { DBUG_ASSERT(!test_all_bits(keyseg->flag, (HA_VAR_LENGTH_PART | HA_BLOB_PART))); keydef->flag|=HA_VAR_LENGTH_KEY; length++; /* At least one length byte */ options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ min_key_length_skip+=keyseg->length; if (keyseg->length >= 255) { /* prefix may be 3 bytes */ min_key_length_skip+=2; length+=2; } } key_length+= keyseg->length; if (keyseg->null_bit) { key_length++; options|=HA_OPTION_PACK_KEYS; keyseg->flag|=HA_NULL_PART; keydef->flag|=HA_VAR_LENGTH_KEY | HA_NULL_PART_KEY; } } } /* if HA_FULLTEXT */ key_segs+=keydef->keysegs; if (keydef->keysegs > MI_MAX_KEY_SEG) { my_errno=HA_WRONG_CREATE_OPTION; goto err; } /* key_segs may be 0 in the case when we only want to be able to add on row into the table. This can happen with some DISTINCT queries in MySQL */ if ((keydef->flag & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME && key_segs) share.state.rec_per_key_part[key_segs-1]=1L; length+=key_length; /* Get block length for key, if defined by user */ block_length= (keydef->block_length ? my_round_up_to_next_power(keydef->block_length) : myisam_block_size); block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH); block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH); keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff, pointer,MI_MAX_KEYPTR_SIZE, block_length); if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH || length >= MI_MAX_KEY_BUFF) { my_errno=HA_WRONG_CREATE_OPTION; goto err; } set_if_bigger(max_key_block_length,keydef->block_length); keydef->keylength= (uint16) key_length; keydef->minlength= (uint16) (length-min_key_length_skip); keydef->maxlength= (uint16) length; if (length > max_key_length) max_key_length= length; tot_length+= (max_rows/(ulong) (((uint) keydef->block_length-5)/ (length*2)))* (ulong) keydef->block_length; } for (i=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; ) key_del[i]=HA_OFFSET_ERROR; unique_key_parts=0; offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH; for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++) { uniquedef->key=keys+i; unique_key_parts+=uniquedef->keysegs; share.state.key_root[keys+i]= HA_OFFSET_ERROR; tot_length+= (max_rows/(ulong) (((uint) myisam_block_size-5)/ ((MI_UNIQUE_HASH_LENGTH + pointer)*2)))* (ulong) myisam_block_size; } keys+=uniques; /* Each unique has 1 key */ key_segs+=uniques; /* Each unique has 1 key seg */ base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE + max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH* MI_STATE_KEYBLOCK_SIZE+ key_segs*MI_STATE_KEYSEG_SIZE); info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+ keys * MI_KEYDEF_SIZE+ uniques * MI_UNIQUEDEF_SIZE + (key_segs + unique_key_parts)*HA_KEYSEG_SIZE+ columns*MI_COLUMNDEF_SIZE); DBUG_PRINT("info", ("info_length: %u", info_length)); /* There are only 16 bits for the total header length. */ if (info_length > 65535) { my_printf_error(0, "MyISAM table '%s' has too many columns and/or " "indexes and/or unique constraints.", MYF(0), name + dirname_length(name)); my_errno= HA_WRONG_CREATE_OPTION; goto err; } bmove(share.state.header.file_version,(uchar*) myisam_file_magic,4); ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ? HA_OPTION_COMPRESS_RECORD | HA_OPTION_TEMP_COMPRESS_RECORD: 0); mi_int2store(share.state.header.options,ci->old_options); mi_int2store(share.state.header.header_length,info_length); mi_int2store(share.state.header.state_info_length,MI_STATE_INFO_SIZE); mi_int2store(share.state.header.base_info_length,MI_BASE_INFO_SIZE); mi_int2store(share.state.header.base_pos,base_pos); share.state.header.language= (ci->language ? ci->language : default_charset_info->number); share.state.header.max_block_size_index= max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH; share.state.dellink = HA_OFFSET_ERROR; share.state.process= (ulong) getpid(); share.state.unique= (ulong) 0; share.state.update_count=(ulong) 0; share.state.version= (ulong) time((time_t*) 0); share.state.sortkey= (ushort) ~0; share.state.auto_increment=ci->auto_increment; share.options=options; share.base.rec_reflength=pointer; /* Get estimate for index file length (this may be wrong for FT keys) */ tmp= (tot_length + max_key_block_length * keys * MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH; /* use maximum of key_file_length we calculated and key_file_length value we got from MYI file header (see also myisampack.c:save_state) */ share.base.key_reflength= mi_get_pointer_length(max(ci->key_file_length,tmp),3); share.base.keys= share.state.header.keys= keys; share.state.header.uniques= uniques; share.state.header.fulltext_keys= fulltext_keys; mi_int2store(share.state.header.key_parts,key_segs); mi_int2store(share.state.header.unique_key_parts,unique_key_parts); mi_set_all_keys_active(share.state.key_map, keys); aligned_key_start= my_round_up_to_next_power(max_key_block_length ? max_key_block_length : myisam_block_size); share.base.keystart= share.state.state.key_file_length= MY_ALIGN(info_length, aligned_key_start); share.base.max_key_block_length=max_key_block_length; share.base.max_key_length=ALIGN_SIZE(max_key_length+4); share.base.records=ci->max_rows; share.base.reloc= ci->reloc_rows; share.base.reclength=real_reclength; share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM); share.base.max_pack_length=pack_reclength; share.base.min_pack_length=min_pack_length; share.base.pack_bits=packed; share.base.fields=fields; share.base.pack_fields=packed; /* max_data_file_length and max_key_file_length are recalculated on open */ if (options & HA_OPTION_TMP_TABLE) share.base.max_data_file_length=(my_off_t) ci->data_file_length; share.base.min_block_length= (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH && ! share.base.blobs) ? max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) : MI_EXTEND_BLOCK_LENGTH; if (! (flags & HA_DONT_TOUCH_DATA)) share.state.create_time= (long) time((time_t*) 0); mysql_mutex_lock(&THR_LOCK_myisam); /* NOTE: For test_if_reopen() we need a real path name. Hence we need MY_RETURN_REAL_PATH for every fn_format(filename, ...). */ if (ci->index_file_name) { char *iext= strrchr(ci->index_file_name, '.'); int have_iext= iext && !strcmp(iext, MI_NAME_IEXT); if (options & HA_OPTION_TMP_TABLE) { char *path; /* chop off the table name, tempory tables use generated name */ if ((path= strrchr(ci->index_file_name, FN_LIBCHAR))) *path= '\0'; fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT, MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH | MY_APPEND_EXT); } else { fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH | (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT)); } fn_format(linkname, name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME|MY_APPEND_EXT); linkname_ptr=linkname; /* Don't create the table if the link or file exists to ensure that one doesn't accidently destroy another table. */ create_flag=0; } else { char *iext= strrchr(name, '.'); int have_iext= iext && !strcmp(iext, MI_NAME_IEXT); fn_format(filename, name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH | (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT)); linkname_ptr=0; /* Replace the current file */ create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD; } /* If a MRG_MyISAM table is in use, the mapped MyISAM tables are open, but no entry is made in the table cache for them. A TRUNCATE command checks for the table in the cache only and could be fooled to believe, the table is not open. Pull the emergency brake in this situation. (Bug #8306) NOTE: The filename is compared against unique_file_name of every open table. Hence we need a real path here. */ if (test_if_reopen(filename)) { my_printf_error(0, "MyISAM table '%s' is in use " "(most likely by a MERGE table). Try FLUSH TABLES.", MYF(0), name + dirname_length(name)); my_errno= HA_ERR_TABLE_EXIST; goto err; } if ((file= mysql_file_create_with_symlink(mi_key_file_kfile, linkname_ptr, filename, 0, create_mode, MYF(MY_WME | create_flag))) < 0) goto err; errpos=1; if (!(flags & HA_DONT_TOUCH_DATA)) { { if (ci->data_file_name) { char *dext= strrchr(ci->data_file_name, '.'); int have_dext= dext && !strcmp(dext, MI_NAME_DEXT); if (options & HA_OPTION_TMP_TABLE) { char *path; /* chop off the table name, tempory tables use generated name */ if ((path= strrchr(ci->data_file_name, FN_LIBCHAR))) *path= '\0'; fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT, MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT); } else { fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT, MY_UNPACK_FILENAME | (have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT)); } fn_format(linkname, name, "",MI_NAME_DEXT, MY_UNPACK_FILENAME | MY_APPEND_EXT); linkname_ptr=linkname; create_flag=0; } else { fn_format(filename,name,"", MI_NAME_DEXT, MY_UNPACK_FILENAME | MY_APPEND_EXT); linkname_ptr=0; create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD; } if ((dfile= mysql_file_create_with_symlink(mi_key_file_dfile, linkname_ptr, filename, 0, create_mode, MYF(MY_WME | create_flag))) < 0) goto err; } errpos=3; } DBUG_PRINT("info", ("write state info and base info")); if (mi_state_info_write(file, &share.state, 2) || mi_base_info_write(file, &share.base)) goto err; #ifndef DBUG_OFF if ((uint) mysql_file_tell(file, MYF(0)) != base_pos + MI_BASE_INFO_SIZE) { uint pos=(uint) mysql_file_tell(file, MYF(0)); DBUG_PRINT("warning",("base_length: %d != used_length: %d", base_pos+ MI_BASE_INFO_SIZE, pos)); } #endif /* Write key and keyseg definitions */ DBUG_PRINT("info", ("write key and keyseg definitions")); for (i=0 ; i < share.base.keys - uniques; i++) { uint sp_segs=(keydefs[i].flag & HA_SPATIAL) ? 2*SPDIMS : 0; if (mi_keydef_write(file, &keydefs[i])) goto err; for (j=0 ; j < keydefs[i].keysegs-sp_segs ; j++) if (mi_keyseg_write(file, &keydefs[i].seg[j])) goto err; #ifdef HAVE_SPATIAL for (j=0 ; j < sp_segs ; j++) { HA_KEYSEG sseg; sseg.type=SPTYPE; sseg.language= 7; /* Binary */ sseg.null_bit=0; sseg.bit_start=0; sseg.bit_end=0; sseg.bit_length= 0; sseg.bit_pos= 0; sseg.length=SPLEN; sseg.null_pos=0; sseg.start=j*SPLEN; sseg.flag= HA_SWAP_KEY; if (mi_keyseg_write(file, &sseg)) goto err; } #endif } /* Create extra keys for unique definitions */ offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH; bzero((char*) &tmp_keydef,sizeof(tmp_keydef)); bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg)); for (i=0; i < uniques ; i++) { tmp_keydef.keysegs=1; tmp_keydef.flag= HA_UNIQUE_CHECK; tmp_keydef.block_length= (uint16)myisam_block_size; tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer; tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength; tmp_keyseg.type= MI_UNIQUE_HASH_TYPE; tmp_keyseg.length= MI_UNIQUE_HASH_LENGTH; tmp_keyseg.start= offset; offset+= MI_UNIQUE_HASH_LENGTH; if (mi_keydef_write(file,&tmp_keydef) || mi_keyseg_write(file,(&tmp_keyseg))) goto err; } /* Save unique definition */ DBUG_PRINT("info", ("write unique definitions")); for (i=0 ; i < share.state.header.uniques ; i++) { HA_KEYSEG *keyseg_end; keyseg= uniquedefs[i].seg; if (mi_uniquedef_write(file, &uniquedefs[i])) goto err; for (keyseg= uniquedefs[i].seg, keyseg_end= keyseg+ uniquedefs[i].keysegs; keyseg < keyseg_end; keyseg++) { switch (keyseg->type) { case HA_KEYTYPE_VARTEXT1: case HA_KEYTYPE_VARTEXT2: case HA_KEYTYPE_VARBINARY1: case HA_KEYTYPE_VARBINARY2: if (!(keyseg->flag & HA_BLOB_PART)) { keyseg->flag|= HA_VAR_LENGTH_PART; keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 || keyseg->type == HA_KEYTYPE_VARBINARY1) ? 1 : 2); } break; default: break; } if (mi_keyseg_write(file, keyseg)) goto err; } } DBUG_PRINT("info", ("write field definitions")); for (i=0 ; i < share.base.fields ; i++) if (mi_recinfo_write(file, &recinfo[i])) goto err; #ifndef DBUG_OFF if ((uint) mysql_file_tell(file, MYF(0)) != info_length) { uint pos= (uint) mysql_file_tell(file, MYF(0)); DBUG_PRINT("warning",("info_length: %d != used_length: %d", info_length, pos)); } #endif /* Enlarge files */ DBUG_PRINT("info", ("enlarge to keystart: %lu", (ulong) share.base.keystart)); if (mysql_file_chsize(file, (ulong) share.base.keystart, 0, MYF(0))) goto err; if (! (flags & HA_DONT_TOUCH_DATA)) { #ifdef USE_RELOC if (mysql_file_chsize(dfile, share.base.min_pack_length*ci->reloc_rows, 0, MYF(0))) goto err; #endif errpos=2; if (mysql_file_close(dfile, MYF(0))) goto err; } errpos=0; mysql_mutex_unlock(&THR_LOCK_myisam); if (mysql_file_close(file, MYF(0))) goto err; my_free(rec_per_key_part); DBUG_RETURN(0); err: mysql_mutex_unlock(&THR_LOCK_myisam); save_errno=my_errno; switch (errpos) { case 3: (void) mysql_file_close(dfile, MYF(0)); /* fall through */ case 2: if (! (flags & HA_DONT_TOUCH_DATA)) mysql_file_delete_with_symlink(mi_key_file_dfile, fn_format(filename, name, "", MI_NAME_DEXT, MY_UNPACK_FILENAME | MY_APPEND_EXT), MYF(0)); /* fall through */ case 1: (void) mysql_file_close(file, MYF(0)); if (! (flags & HA_DONT_TOUCH_DATA)) mysql_file_delete_with_symlink(mi_key_file_kfile, fn_format(filename, name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME | MY_APPEND_EXT), MYF(0)); } my_free(rec_per_key_part); DBUG_RETURN(my_errno=save_errno); /* return the fatal errno */ }