int my_readlink(char *to, const char *filename, myf MyFlags) { #ifndef HAVE_READLINK my_stpcpy(to,filename); return 1; #else int result=0; int length; DBUG_ENTER("my_readlink"); if ((length=readlink(filename, to, FN_REFLEN-1)) < 0) { /* Don't give an error if this wasn't a symlink */ if ((my_errno=errno) == EINVAL) { result= 1; my_stpcpy(to,filename); } else { if (MyFlags & MY_WME) { char errbuf[MYSYS_STRERROR_SIZE]; my_error(EE_CANT_READLINK, MYF(0), filename, errno, my_strerror(errbuf, sizeof(errbuf), errno)); } result= -1; } } else to[length]=0; DBUG_PRINT("exit" ,("result: %d", result)); DBUG_RETURN(result); #endif /* HAVE_READLINK */ }
int my_redel(const char *org_name, const char *tmp_name, myf MyFlags) { int error=1; DBUG_ENTER("my_redel"); DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %d", org_name,tmp_name,MyFlags)); if (my_copystat(org_name,tmp_name,MyFlags) < 0) goto end; if (MyFlags & MY_REDEL_MAKE_BACKUP) { char name_buff[FN_REFLEN+20]; char ext[20]; ext[0]='-'; get_date(ext+1,2+4,(time_t) 0); my_stpcpy(strend(ext),REDEL_EXT); if (my_rename(org_name, fn_format(name_buff, org_name, "", ext, 2), MyFlags)) goto end; } else if (my_delete_allow_opened(org_name, MyFlags)) goto end; if (my_rename(tmp_name,org_name,MyFlags)) goto end; error=0; end: DBUG_RETURN(error); } /* my_redel */
CHARSET_INFO *get_charset(uint cs_number, myf flags) { CHARSET_INFO *cs; MY_CHARSET_LOADER loader; if (cs_number == default_charset_info->number) return default_charset_info; my_pthread_once(&charsets_initialized, init_available_charsets); if (cs_number >= array_elements(all_charsets)) return NULL; my_charset_loader_init_mysys(&loader); cs= get_internal_charset(&loader, cs_number, flags); if (!cs && (flags & MY_WME)) { char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)], cs_string[23]; my_stpcpy(get_charsets_dir(index_file),MY_CHARSET_INDEX); cs_string[0]='#'; int10_to_str(cs_number, cs_string+1, 10); my_error(EE_UNKNOWN_CHARSET, MYF(ME_BELL), cs_string, index_file); } return cs; }
static void init_available_charsets(void) { char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)]; CHARSET_INFO **cs; MY_CHARSET_LOADER loader; memset(&all_charsets, 0, sizeof(all_charsets)); init_compiled_charsets(MYF(0)); /* Copy compiled charsets */ for (cs=all_charsets; cs < all_charsets+array_elements(all_charsets)-1 ; cs++) { if (*cs) { if (cs[0]->ctype) if (init_state_maps(*cs)) *cs= NULL; } } my_charset_loader_init_mysys(&loader); my_stpcpy(get_charsets_dir(fname), MY_CHARSET_INDEX); my_read_charset_file(&loader, fname, MYF(0)); }
void scan_directory(const char *dir) { DIR *pd; struct dirent *pe; char canonical_path[PATH_MAX+1] = { 0 }; char *end; struct stat sb; if (!(pd = opendir(dir))) { perror_str("[!] Unable to open dir \"%s\"", dir); return; } while ((pe = readdir(pd))) { if (pe->d_name[0] == '.') { if (pe->d_name[1] == '\0') continue; if (pe->d_name[1] == '.' && pe->d_name[2] == '\0') continue; } end = my_stpcpy(canonical_path, dir); if (end - canonical_path >= PATH_MAX - 1 - strlen(pe->d_name)) { fprintf(stderr, "[!] name too long \"%s/%s\"\n", dir, pe->d_name); continue; } if (end > canonical_path && *(end - 1) != '/') *end++ = '/'; strcpy(end, pe->d_name); #ifdef DEBUG printf("[*] checking: 0x%x 0x%x 0x%x 0x%x %s ...\n", (unsigned int)pe->d_ino, (unsigned int)pe->d_off, pe->d_reclen, pe->d_type, canonical_path); #endif /* decide where to put this one */ if (lstat(canonical_path, &sb) == -1) { perror_str("[!] Unable to lstat \"%s\"", canonical_path); continue; } /* skip symlinks.. */ if (S_ISLNK(sb.st_mode)) continue; record_access_level(canonical_path, &sb); /* can the child directory too */ if (S_ISDIR(sb.st_mode) && is_executable(&sb)) scan_directory(canonical_path); } closedir(pd); }
check (char *dest, char *src, size_t len) { char *result; result = my_stpcpy (dest, src); if (result != dest + len) __builtin_abort (); if (__builtin_memcmp (src, dest, len) != 0) __builtin_abort (); }
void make_type(char * to, uint nr, TYPELIB *typelib) { DBUG_ENTER("make_type"); if (!nr) to[0]=0; else (void) my_stpcpy(to,get_type(typelib,nr-1)); DBUG_VOID_RETURN; } /* make_type */
int myrg_create(const char *name, const char **table_names, uint insert_method, my_bool fix_names) { int save_errno; uint errpos; File file; char buff[FN_REFLEN],*end; DBUG_ENTER("myrg_create"); errpos=0; if ((file= mysql_file_create(rg_key_file_MRG, fn_format(buff, name, "", MYRG_NAME_EXT, MY_UNPACK_FILENAME|MY_APPEND_EXT), 0, O_RDWR | O_EXCL | O_NOFOLLOW, MYF(MY_WME))) < 0) goto err; errpos=1; if (table_names) { for ( ; *table_names ; table_names++) { my_stpcpy(buff,*table_names); if (fix_names) fn_same(buff,name,4); *(end=strend(buff))='\n'; end[1]=0; if (mysql_file_write(file, (uchar*) buff, (uint) (end-buff+1), MYF(MY_WME | MY_NABP))) goto err; } } if (insert_method != MERGE_INSERT_DISABLED) { end=strxmov(buff,"#INSERT_METHOD=", get_type(&merge_insert_method,insert_method-1),"\n",NullS); if (mysql_file_write(file, (uchar*) buff, (uint) (end-buff), MYF(MY_WME | MY_NABP))) goto err; } if (mysql_file_close(file, MYF(0))) goto err; DBUG_RETURN(0); err: save_errno=my_errno() ? my_errno() : -1; switch (errpos) { case 1: (void) mysql_file_close(file, MYF(0)); } set_my_errno(save_errno); DBUG_RETURN(save_errno); } /* myrg_create */
static void init_available_charsets(void) { char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)]; MY_CHARSET_LOADER loader; memset(&all_charsets, 0, sizeof(all_charsets)); init_compiled_charsets(MYF(0)); /* Copy compiled charsets */ my_charset_loader_init_mysys(&loader); my_stpcpy(get_charsets_dir(fname), MY_CHARSET_INDEX); my_read_charset_file(&loader, fname, MYF(0)); }
CHARSET_INFO * my_collation_get_by_name(MY_CHARSET_LOADER *loader, const char *name, myf flags) { uint cs_number; CHARSET_INFO *cs; my_pthread_once(&charsets_initialized, init_available_charsets); cs_number= get_collation_number(name); my_charset_loader_init_mysys(loader); cs= cs_number ? get_internal_charset(loader, cs_number, flags) : NULL; if (!cs && (flags & MY_WME)) { char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)]; my_stpcpy(get_charsets_dir(index_file),MY_CHARSET_INDEX); my_error(EE_UNKNOWN_COLLATION, MYF(ME_BELL), name, index_file); } return cs; }
/** Find character set by name: extended version of get_charset_by_csname() to return error messages to the caller. @param loader Character set loader @param name Collation name @param cs_flags Character set flags (e.g. default or binary collation) @param flags Flags @return NULL on error, pointer to collation on success */ CHARSET_INFO * my_charset_get_by_name(MY_CHARSET_LOADER *loader, const char *cs_name, uint cs_flags, myf flags) { uint cs_number; CHARSET_INFO *cs; DBUG_ENTER("get_charset_by_csname"); DBUG_PRINT("enter",("name: '%s'", cs_name)); my_pthread_once(&charsets_initialized, init_available_charsets); cs_number= get_charset_number(cs_name, cs_flags); cs= cs_number ? get_internal_charset(loader, cs_number, flags) : NULL; if (!cs && (flags & MY_WME)) { char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)]; my_stpcpy(get_charsets_dir(index_file),MY_CHARSET_INDEX); my_error(EE_UNKNOWN_CHARSET, MYF(ME_BELL), cs_name, index_file); } DBUG_RETURN(cs); }
int my_rename_with_symlink(const char *from, const char *to, myf MyFlags) { #ifndef HAVE_READLINK return my_rename(from, to, MyFlags); #else char link_name[FN_REFLEN], tmp_name[FN_REFLEN]; int was_symlink= (my_enable_symlinks && !my_readlink(link_name, from, MYF(0))); int result=0; int name_is_different; DBUG_ENTER("my_rename_with_symlink"); if (!was_symlink) DBUG_RETURN(my_rename(from, to, MyFlags)); /* Change filename that symlink pointed to */ my_stpcpy(tmp_name, to); fn_same(tmp_name,link_name,1); /* Copy dir */ name_is_different= strcmp(link_name, tmp_name); if (name_is_different && !access(tmp_name, F_OK)) { my_errno= EEXIST; if (MyFlags & MY_WME) { char errbuf[MYSYS_STRERROR_SIZE]; my_error(EE_CANTCREATEFILE, MYF(0), tmp_name, EEXIST, my_strerror(errbuf, sizeof(errbuf), EEXIST)); } DBUG_RETURN(1); } /* Create new symlink */ if (my_symlink(tmp_name, to, MyFlags)) DBUG_RETURN(1); /* Rename symlinked file if the base name didn't change. This can happen if you use this function where 'from' and 'to' has the same basename and different directories. */ if (name_is_different && my_rename(link_name, tmp_name, MyFlags)) { int save_errno=my_errno; my_delete(to, MyFlags); /* Remove created symlink */ my_errno=save_errno; DBUG_RETURN(1); } /* Remove original symlink */ if (my_delete(from, MyFlags)) { int save_errno=my_errno; /* Remove created link */ my_delete(to, MyFlags); /* Rename file back */ if (strcmp(link_name, tmp_name)) (void) my_rename(tmp_name, link_name, MyFlags); my_errno=save_errno; result= 1; } DBUG_RETURN(result); #endif /* HAVE_READLINK */ }
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); }
int main(int argc,char *argv[]) { int error=0, subkeys; uint keylen, keylen2=0, inx, doc_cnt=0; float weight= 1.0; double gws, min_gws=0, avg_gws=0; MI_INFO *info; char buf[MAX_LEN], buf2[MAX_LEN], buf_maxlen[MAX_LEN], buf_min_gws[MAX_LEN]; ulong total=0, maxlen=0, uniq=0, max_doc_cnt=0; struct { MI_INFO *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */ MY_INIT(argv[0]); memset(&main_thread_keycache_var, 0, sizeof(st_keycache_thread_var)); mysql_cond_init(PSI_NOT_INSTRUMENTED, &main_thread_keycache_var.suspend); if ((error= handle_options(&argc, &argv, my_long_options, get_one_option))) exit(error); if (count || dump) verbose=0; if (!count && !dump && !lstats && !query) stats=1; if (verbose) setbuf(stdout,NULL); if (argc < 2) usage(); { char *end; inx= (uint) my_strtoll(argv[1], &end, 10); if (*end) usage(); } init_key_cache(dflt_key_cache,MI_KEY_BLOCK_LENGTH,USE_BUFFER_INIT, 0, 0); if (!(info=mi_open(argv[0], O_RDONLY, HA_OPEN_ABORT_IF_LOCKED|HA_OPEN_FROM_SQL_LAYER))) { error=my_errno(); goto err; } *buf2=0; aio->info=info; if ((inx >= info->s->base.keys) || !(info->s->keyinfo[inx].flag & HA_FULLTEXT)) { printf("Key %d in table %s is not a FULLTEXT key\n", inx, info->filename); goto err; } mi_lock_database(info, F_EXTRA_LCK); info->lastpos= HA_OFFSET_ERROR; info->update|= HA_STATE_PREV_FOUND; while (!(error=mi_rnext(info,NULL,inx))) { keylen=*(info->lastkey); subkeys=ft_sintXkorr(info->lastkey+keylen+1); if (subkeys >= 0) ft_floatXget(weight, info->lastkey+keylen+1); my_snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey+1); my_casedn_str(default_charset_info,buf); total++; lengths[keylen]++; if (count || stats) { if (strcmp(buf, buf2)) { if (*buf2) { uniq++; avg_gws+=gws=GWS_IN_USE; if (count) printf("%9u %20.7f %s\n",doc_cnt,gws,buf2); if (maxlen<keylen2) { maxlen=keylen2; my_stpcpy(buf_maxlen, buf2); } if (max_doc_cnt < doc_cnt) { max_doc_cnt=doc_cnt; my_stpcpy(buf_min_gws, buf2); min_gws=gws; } } my_stpcpy(buf2, buf); keylen2=keylen; doc_cnt=0; } doc_cnt+= (subkeys >= 0 ? 1 : -subkeys); } if (dump) { if (subkeys>=0) printf("%9lx %20.7f %s\n", (long) info->lastpos,weight,buf); else printf("%9lx => %17d %s\n",(long) info->lastpos,-subkeys,buf); } if (verbose && (total%HOW_OFTEN_TO_WRITE)==0) printf("%10ld\r",total); } mi_lock_database(info, F_UNLCK); if (count || stats) { if (*buf2) { uniq++; avg_gws+=gws=GWS_IN_USE; if (count) printf("%9u %20.7f %s\n",doc_cnt,gws,buf2); if (maxlen<keylen2) { maxlen=keylen2; my_stpcpy(buf_maxlen, buf2); } if (max_doc_cnt < doc_cnt) { max_doc_cnt=doc_cnt; my_stpcpy(buf_min_gws, buf2); min_gws=gws; } } } if (stats) { count=0; for (inx=0;inx<256;inx++) { count+=lengths[inx]; if ((ulong) count >= total/2) break; } printf("Total rows: %lu\nTotal words: %lu\n" "Unique words: %lu\nLongest word: %lu chars (%s)\n" "Median length: %u\n" "Average global weight: %f\n" "Most common word: %lu times, weight: %f (%s)\n", (long) info->state->records, total, uniq, maxlen, buf_maxlen, inx, avg_gws/uniq, max_doc_cnt, min_gws, buf_min_gws); } if (lstats) { count=0; for (inx=0; inx<256; inx++) { count+=lengths[inx]; if (count && lengths[inx]) printf("%3u: %10lu %5.2f%% %20lu %4.1f%%\n", inx, (ulong) lengths[inx],100.0*lengths[inx]/total,(ulong) count, 100.0*count/total); } } err: if (error && error != HA_ERR_END_OF_FILE) printf("got error %d\n",my_errno()); if (info) mi_close(info); mysql_cond_destroy(&main_thread_keycache_var.suspend); return 0; }
MY_DIR *my_dir(const char *path, myf MyFlags) { char *buffer; MY_DIR *result= 0; FILEINFO finfo; DYNAMIC_ARRAY *dir_entries_storage; MEM_ROOT *names_storage; DIR *dirp; struct dirent *dp; char tmp_path[FN_REFLEN + 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 (dirp == NULL || ! (buffer= my_malloc(key_memory_MY_DIR, 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), NULL, /* init_buffer */ ENTRIES_START_SIZE, ENTRIES_INCREMENT)) { my_free(buffer); goto error; } init_alloc_root(key_memory_MY_DIR, 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) my_stpcpy(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 (insert_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(0), path, my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno)); } DBUG_RETURN((MY_DIR *) NULL); } /* my_dir */
int main(int argc, char **argv) { int i,j,error,deleted; HP_INFO *file; uchar record[128],key[32]; const char *filename; HP_KEYDEF keyinfo[10]; HA_KEYSEG keyseg[4]; HP_CREATE_INFO hp_create_info; HP_SHARE *tmp_share; my_bool unused; MY_INIT(argv[0]); filename= "test1"; get_options(argc,argv); memset(&hp_create_info, 0, sizeof(hp_create_info)); hp_create_info.max_table_size= 1024L*1024L; hp_create_info.keys= 1; hp_create_info.keydef= keyinfo; hp_create_info.reclength= 30; hp_create_info.max_records= (ulong) flag*100000L; hp_create_info.min_records= 10UL; keyinfo[0].keysegs=1; keyinfo[0].seg=keyseg; keyinfo[0].algorithm= HA_KEY_ALG_HASH; keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY; keyinfo[0].seg[0].start=1; keyinfo[0].seg[0].length=6; keyinfo[0].seg[0].charset= &my_charset_latin1; keyinfo[0].seg[0].null_bit= 0; keyinfo[0].flag = HA_NOSAME; deleted=0; memset(flags, 0, sizeof(flags)); printf("- Creating heap-file\n"); if (heap_create(filename, &hp_create_info, &tmp_share, &unused) || !(file= heap_open(filename, 2))) goto err; printf("- Writing records:s\n"); my_stpcpy((char*) record," ..... key "); for (i=49 ; i>=1 ; i-=2 ) { j=i%25 +1; sprintf((char*) key,"%6d",j); memmove(record + 1, key, 6); error=heap_write(file,record); if (heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } flags[j]=1; if (verbose || error) printf("J= %2d heap_write: %d my_errno: %d\n", j,error,my_errno); } if (heap_close(file)) goto err; printf("- Reopening file\n"); if (!(file=heap_open(filename, 2))) goto err; printf("- Removing records\n"); for (i=1 ; i<=10 ; i++) { if (i == remove_ant) { (void) heap_close(file); return (0) ; } sprintf((char*) key,"%6d",(j=(int) ((rand() & 32767)/32767.*25))); if ((error = heap_rkey(file,record,0,key,6,HA_READ_KEY_EXACT))) { if (verbose || (flags[j] == 1 || (error && my_errno != HA_ERR_KEY_NOT_FOUND))) printf("key: %s rkey: %3d my_errno: %3d\n",(char*) key,error,my_errno); } else { error=heap_delete(file,record); if (error || verbose) printf("key: %s delete: %d my_errno: %d\n",(char*) key,error,my_errno); flags[j]=0; if (! error) deleted++; } if (heap_check_heap(file,0)) { puts("Heap keys crashed"); goto err; } } printf("- Reading records with key\n"); for (i=1 ; i<=25 ; i++) { sprintf((char*) key,"%6d",i); memmove(record + 1, key, 6); my_errno=0; error=heap_rkey(file,record,0,key,6,HA_READ_KEY_EXACT); if (verbose || (error == 0 && flags[i] != 1) || (error && (flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND))) { printf("key: %s rkey: %3d my_errno: %3d record: %s\n", (char*) key,error,my_errno,record+1); } } if (heap_close(file) || hp_panic(HA_PANIC_CLOSE)) goto err; my_end(MY_GIVE_INFO); return(0); err: printf("got error: %d when using heap-database\n",my_errno); return(1); } /* main */
static int examine_log(char * file_name, char **table_names) { uint command,result,files_open; ulong access_time,length; my_off_t filepos; int lock_command,mi_result; char isam_file_name[FN_REFLEN],llbuff[21],llbuff2[21]; uchar head[20]; uchar* buff; struct test_if_open_param open_param; IO_CACHE cache; File file; FILE *write_file; enum ha_extra_function extra_command; TREE tree; struct file_info file_info,*curr_file_info; DBUG_ENTER("examine_log"); if ((file=my_open(file_name,O_RDONLY,MYF(MY_WME))) < 0) DBUG_RETURN(1); write_file=0; if (write_filename) { if (!(write_file=my_fopen(write_filename,O_WRONLY,MYF(MY_WME)))) { my_close(file,MYF(0)); DBUG_RETURN(1); } } init_io_cache(&cache,file,0,READ_CACHE,start_offset,0,MYF(0)); memset(com_count, 0, sizeof(com_count)); init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1, (tree_element_free) file_info_free, NULL); (void) init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE, 0, 0); files_open=0; access_time=0; while (access_time++ != number_of_commands && !my_b_read(&cache,(uchar*) head,9)) { isamlog_filepos=my_b_tell(&cache)-9L; file_info.filenr= mi_uint2korr(head+1); isamlog_process=file_info.process=(long) mi_uint4korr(head+3); if (!opt_processes) file_info.process=0; result= mi_uint2korr(head+7); if ((curr_file_info=(struct file_info*) tree_search(&tree, &file_info, tree.custom_arg))) { curr_file_info->accessed=access_time; if (update && curr_file_info->used && curr_file_info->closed) { if (reopen_closed_file(&tree,curr_file_info)) { command=sizeof(com_count)/sizeof(com_count[0][0])/3; result=0; goto com_err; } } } command=(uint) head[0]; if (command < sizeof(com_count)/sizeof(com_count[0][0])/3 && (!table_names[0] || (curr_file_info && curr_file_info->used))) { com_count[command][0]++; if (result) com_count[command][1]++; } switch ((enum myisam_log_commands) command) { case MI_LOG_OPEN: if (!table_names[0]) { com_count[command][0]--; /* Must be counted explicite */ if (result) com_count[command][1]--; } if (curr_file_info) printf("\nWarning: %s is opened with same process and filenumber\n" "Maybe you should use the -P option ?\n", curr_file_info->show_name); if (my_b_read(&cache,(uchar*) head,2)) goto err; buff= 0; file_info.name=0; file_info.show_name=0; file_info.record=0; if (read_string(&cache, &buff, (uint) mi_uint2korr(head))) goto err; { uint i; char *pos,*to; /* Fix if old DOS files to new format */ for (pos=file_info.name=(char*)buff; (pos=strchr(pos,'\\')) ; pos++) *pos= '/'; pos=file_info.name; for (i=0 ; i < prefix_remove ; i++) { char *next; if (!(next=strchr(pos,'/'))) break; pos=next+1; } to=isam_file_name; if (filepath) to=convert_dirname(isam_file_name,filepath,NullS); my_stpcpy(to,pos); fn_ext(isam_file_name)[0]=0; /* Remove extension */ } open_param.name=file_info.name; open_param.max_id=0; (void) tree_walk(&tree,(tree_walk_action) test_if_open,(void*) &open_param, left_root_right); file_info.id=open_param.max_id+1; /* * In the line below +10 is added to accomodate '<' and '>' chars * plus '\0' at the end, so that there is place for 7 digits. * It is improbable that same table can have that many entries in * the table cache. * The additional space is needed for the sprintf commands two lines * below. */ file_info.show_name=my_memdup(PSI_NOT_INSTRUMENTED, isam_file_name, (uint) strlen(isam_file_name)+10, MYF(MY_WME)); if (file_info.id > 1) sprintf(strend(file_info.show_name),"<%d>",file_info.id); file_info.closed=1; file_info.accessed=access_time; file_info.used=1; if (table_names[0]) { char **name; file_info.used=0; for (name=table_names ; *name ; name++) { if (!strcmp(*name,isam_file_name)) file_info.used=1; /* Update/log only this */ } } if (update && file_info.used) { if (files_open >= max_files) { if (close_some_file(&tree)) goto com_err; files_open--; } if (!(file_info.isam= mi_open(isam_file_name,O_RDWR, HA_OPEN_WAIT_IF_LOCKED))) goto com_err; if (!(file_info.record=my_malloc(PSI_NOT_INSTRUMENTED, file_info.isam->s->base.reclength, MYF(MY_WME)))) goto end; files_open++; file_info.closed=0; } (void) tree_insert(&tree, (uchar*) &file_info, 0, tree.custom_arg); if (file_info.used) { if (verbose && !record_pos_file) printf_log("%s: open -> %d",file_info.show_name, file_info.filenr); com_count[command][0]++; if (result) com_count[command][1]++; } break; case MI_LOG_CLOSE: if (verbose && !record_pos_file && (!table_names[0] || (curr_file_info && curr_file_info->used))) printf_log("%s: %s -> %d",FILENAME(curr_file_info), command_name[command],result); if (curr_file_info) { if (!curr_file_info->closed) files_open--; (void) tree_delete(&tree, (uchar*) curr_file_info, 0, tree.custom_arg); } break; case MI_LOG_EXTRA: if (my_b_read(&cache,(uchar*) head,1)) goto err; extra_command=(enum ha_extra_function) head[0]; if (verbose && !record_pos_file && (!table_names[0] || (curr_file_info && curr_file_info->used))) printf_log("%s: %s(%d) -> %d",FILENAME(curr_file_info), command_name[command], (int) extra_command,result); if (update && curr_file_info && !curr_file_info->closed) { if (mi_extra(curr_file_info->isam, extra_command, 0) != (int) result) { fflush(stdout); (void) fprintf(stderr, "Warning: error %d, expected %d on command %s at %s\n", my_errno(),result,command_name[command], llstr(isamlog_filepos,llbuff)); fflush(stderr); } } break; case MI_LOG_DELETE: if (my_b_read(&cache,(uchar*) head,8)) goto err; filepos=mi_sizekorr(head); if (verbose && (!record_pos_file || ((record_pos == filepos || record_pos == NO_FILEPOS) && !cmp_filename(curr_file_info,record_pos_file))) && (!table_names[0] || (curr_file_info && curr_file_info->used))) printf_log("%s: %s at %ld -> %d",FILENAME(curr_file_info), command_name[command],(long) filepos,result); if (update && curr_file_info && !curr_file_info->closed) { if (mi_rrnd(curr_file_info->isam,curr_file_info->record,filepos)) { if (!recover) goto com_err; if (verbose) printf_log("error: Didn't find row to delete with mi_rrnd"); com_count[command][2]++; /* Mark error */ } mi_result=mi_delete(curr_file_info->isam,curr_file_info->record); if ((mi_result == 0 && result) || (mi_result && (uint) my_errno() != result)) { if (!recover) goto com_err; if (mi_result) com_count[command][2]++; /* Mark error */ if (verbose) printf_log("error: Got result %d from mi_delete instead of %d", mi_result, result); } } break; case MI_LOG_WRITE: case MI_LOG_UPDATE: if (my_b_read(&cache,(uchar*) head,12)) goto err; filepos=mi_sizekorr(head); length=mi_uint4korr(head+8); buff=0; if (read_string(&cache,&buff,(uint) length)) goto err; if ((!record_pos_file || ((record_pos == filepos || record_pos == NO_FILEPOS) && !cmp_filename(curr_file_info,record_pos_file))) && (!table_names[0] || (curr_file_info && curr_file_info->used))) { if (write_file && (my_fwrite(write_file,buff,length,MYF(MY_WAIT_IF_FULL | MY_NABP)))) goto end; if (verbose) printf_log("%s: %s at %ld, length=%ld -> %d", FILENAME(curr_file_info), command_name[command], filepos,length,result); } if (update && curr_file_info && !curr_file_info->closed) { if (curr_file_info->isam->s->base.blobs) fix_blob_pointers(curr_file_info->isam,buff); if ((enum myisam_log_commands) command == MI_LOG_UPDATE) { if (mi_rrnd(curr_file_info->isam,curr_file_info->record,filepos)) { if (!recover) { result=0; goto com_err; } if (verbose) printf_log("error: Didn't find row to update with mi_rrnd"); if (recover == 1 || result || find_record_with_key(curr_file_info,buff)) { com_count[command][2]++; /* Mark error */ break; } } mi_result=mi_update(curr_file_info->isam,curr_file_info->record, buff); if ((mi_result == 0 && result) || (mi_result && (uint) my_errno() != result)) { if (!recover) goto com_err; if (verbose) printf_log("error: Got result %d from mi_update instead of %d", mi_result, result); if (mi_result) com_count[command][2]++; /* Mark error */ } } else { mi_result=mi_write(curr_file_info->isam,buff); if ((mi_result == 0 && result) || (mi_result && (uint) my_errno() != result)) { if (!recover) goto com_err; if (verbose) printf_log("error: Got result %d from mi_write instead of %d", mi_result, result); if (mi_result) com_count[command][2]++; /* Mark error */ } if (!recover && filepos != curr_file_info->isam->lastpos) { printf("error: Wrote at position: %s, should have been %s", llstr(curr_file_info->isam->lastpos,llbuff), llstr(filepos,llbuff2)); goto end; } } } my_free(buff); break; case MI_LOG_LOCK: if (my_b_read(&cache,(uchar*) head,sizeof(lock_command))) goto err; memcpy(&lock_command, head, sizeof(lock_command)); if (verbose && !record_pos_file && (!table_names[0] || (curr_file_info && curr_file_info->used))) printf_log("%s: %s(%d) -> %d\n",FILENAME(curr_file_info), command_name[command],lock_command,result); if (update && curr_file_info && !curr_file_info->closed) { if (mi_lock_database(curr_file_info->isam,lock_command) != (int) result) goto com_err; } break; case MI_LOG_DELETE_ALL: if (verbose && !record_pos_file && (!table_names[0] || (curr_file_info && curr_file_info->used))) printf_log("%s: %s -> %d\n",FILENAME(curr_file_info), command_name[command],result); break; default: fflush(stdout); (void) fprintf(stderr, "Error: found unknown command %d in logfile, aborted\n", command); fflush(stderr); goto end; } } end_key_cache(dflt_key_cache,1); delete_tree(&tree); (void) end_io_cache(&cache); (void) my_close(file,MYF(0)); if (write_file && my_fclose(write_file,MYF(MY_WME))) DBUG_RETURN(1); DBUG_RETURN(0); err: fflush(stdout); (void) fprintf(stderr,"Got error %d when reading from logfile\n",my_errno()); fflush(stderr); goto end; com_err: fflush(stdout); (void) fprintf(stderr,"Got error %d, expected %d on command %s at %s\n", my_errno(),result,command_name[command], llstr(isamlog_filepos,llbuff)); fflush(stderr); end: end_key_cache(dflt_key_cache, 1); delete_tree(&tree); (void) end_io_cache(&cache); (void) my_close(file,MYF(0)); if (write_file) (void) my_fclose(write_file,MYF(MY_WME)); DBUG_RETURN(1); }