int my_setwd(const char *dir, myf MyFlags) { int res; size_t length; char *start, *pos; DBUG_ENTER("my_setwd"); DBUG_PRINT("my",("dir: '%s' MyFlags %lu", dir, MyFlags)); start=(char *) dir; if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0)) dir=FN_ROOTDIR; if ((res=chdir((char*) dir)) != 0) { my_errno=errno; if (MyFlags & MY_WME) my_error(EE_SETWD,MYF(ME_BELL+ME_WAITTANG),start,errno); } else { if (test_if_hard_path(start)) { /* Hard pathname */ pos= strmake(&curr_dir[0],start,(size_t) FN_REFLEN-1); if (pos[-1] != FN_LIBCHAR) { length=(uint) (pos-(char*) curr_dir); curr_dir[length]=FN_LIBCHAR; /* must end with '/' */ curr_dir[length+1]='\0'; } } else curr_dir[0]='\0'; /* Don't save name */ } DBUG_RETURN(res); } /* my_setwd */
char * my_load_path(char * to, const char *path, const char *own_path_prefix) { char buff[FN_REFLEN]; int is_cur; DBUG_ENTER("my_load_path"); DBUG_PRINT("enter",("path: %s prefix: %s",path, own_path_prefix ? own_path_prefix : "")); if ((path[0] == FN_HOMELIB && path[1] == FN_LIBCHAR) || test_if_hard_path(path)) (void) strnmov(buff, path, FN_REFLEN); else if ((is_cur=(path[0] == FN_CURLIB && path[1] == FN_LIBCHAR)) || (is_prefix(path,FN_PARENTDIR)) || ! own_path_prefix) { if (is_cur) is_cur=2; /* Remove current dir */ if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0))) (void) strncat(buff, path+is_cur, FN_REFLEN-1); else (void) strnmov(buff, path, FN_REFLEN); /* Return org file name */ } else (void) strxnmov(buff, FN_REFLEN, own_path_prefix, path, NullS); strnmov(to, buff, FN_REFLEN); to[FN_REFLEN-1]= '\0'; DBUG_PRINT("exit",("to: %s",to)); DBUG_RETURN(to); } /* my_load_path */
int test_if_hard_path(register const char *dir_name) { if (dir_name[0] == FN_HOMELIB && dir_name[1] == FN_LIBCHAR) return (home_dir != NullS && test_if_hard_path(home_dir)); if (dir_name[0] == FN_LIBCHAR) return (TRUE); #ifdef FN_DEVCHAR return (strchr(dir_name,FN_DEVCHAR) != 0); #else return FALSE; #endif } /* test_if_hard_path */
int my_setwd(const char *dir, myf MyFlags) { int res; size_t length; char *start, *pos; #if defined(VMS) char buff[FN_REFLEN]; #endif DBUG_ENTER("my_setwd"); DBUG_PRINT("my",("dir: '%s' MyFlags %d", dir, MyFlags)); start=(char *) dir; if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0)) dir=FN_ROOTDIR; #ifdef VMS { pos=strmov(buff,dir); if (pos[-1] != FN_LIBCHAR) { pos[0]=FN_LIBCHAR; /* Mark as directory */ pos[1]=0; } system_filename(buff,buff); /* Change to VMS format */ dir=buff; } #endif /* VMS */ if ((res=chdir((char*) dir)) != 0) { my_errno=errno; if (MyFlags & MY_WME) my_error(EE_SETWD,MYF(ME_BELL+ME_WAITTANG),start,errno); } else { if (test_if_hard_path(start)) { /* Hard pathname */ pos= strmake(&curr_dir[0],start,(size_t) FN_REFLEN-1); if (pos[-1] != FN_LIBCHAR) { length=(uint) (pos-(char*) curr_dir); curr_dir[length]=FN_LIBCHAR; /* must end with '/' */ curr_dir[length+1]='\0'; } } else curr_dir[0]='\0'; /* Don't save name */ } DBUG_RETURN(res); } /* my_setwd */
char *get_charsets_dir(char *buf) { const char *sharedir= SHAREDIR; char *res; DBUG_ENTER("get_charsets_dir"); if (charsets_dir != NULL) strmake(buf, charsets_dir, FN_REFLEN-1); else { if (test_if_hard_path(sharedir) || is_prefix(sharedir, DEFAULT_CHARSET_HOME)) strxmov(buf, sharedir, "/", CHARSET_DIR, NullS); else strxmov(buf, DEFAULT_CHARSET_HOME, "/", sharedir, "/", CHARSET_DIR, NullS); } res= convert_dirname(buf,buf,NullS); DBUG_PRINT("info",("charsets dir: '%s'", buf)); DBUG_RETURN(res); }
char * my_path(char * to, const char *progname, const char *own_pathname_part) { char *start, *end, *prog; size_t to_length; DBUG_ENTER("my_path"); start=to; /* Return this */ if (progname && (dirname_part(to, progname, &to_length) || find_file_in_path(to,progname) || ((prog=getenv("_")) != 0 && dirname_part(to, prog, &to_length)))) { (void) intern_filename(to,to); if (!test_if_hard_path(to)) { if (!my_getwd(curr_dir,FN_REFLEN,MYF(0))) bchange((uchar*) to, 0, (uchar*) curr_dir, strlen(curr_dir), strlen(to)+1); } } else { if ((end = getenv("MY_BASEDIR_VERSION")) == 0 && (end = getenv("MY_BASEDIR")) == 0) { #ifdef DEFAULT_BASEDIR end= (char*) DEFAULT_BASEDIR; #else end= (char*) "/my/"; #endif } (void) intern_filename(to,end); to=strend(to); if (to != start && to[-1] != FN_LIBCHAR) *to++ = FN_LIBCHAR; (void) strmov(to,own_pathname_part); } DBUG_PRINT("exit",("to: '%s'",start)); DBUG_RETURN(start); } /* my_path */
char * fn_format(char * to, const char *name, const char *dir, const char *extension, uint flag) { char dev[FN_REFLEN], buff[FN_REFLEN], *pos, *startpos; const char *ext; reg1 size_t length; size_t dev_length; my_bool not_used; DBUG_ENTER("fn_format"); DBUG_ASSERT(name != NULL); DBUG_ASSERT(extension != NULL); DBUG_PRINT("enter",("name: %s dir: %s extension: %s flag: %d", name,dir,extension,flag)); /* Copy and skip directory */ name+=(length=dirname_part(dev, (startpos=(char *) name), &dev_length)); if (length == 0 || (flag & MY_REPLACE_DIR)) { DBUG_ASSERT(dir != NULL); /* Use given directory */ convert_dirname(dev,dir,NullS); /* Fix to this OS */ } else if ((flag & MY_RELATIVE_PATH) && !test_if_hard_path(dev)) { DBUG_ASSERT(dir != NULL); /* Put 'dir' before the given path */ strmake(buff,dev,sizeof(buff)-1); pos=convert_dirname(dev,dir,NullS); strmake(pos,buff,sizeof(buff)-1- (int) (pos-dev)); } if (flag & MY_PACK_FILENAME) pack_dirname(dev,dev); /* Put in ./.. and ~/.. */ if (flag & MY_UNPACK_FILENAME) (void) unpack_dirname(dev, dev, ¬_used); /* Replace ~/.. with dir */ if (!(flag & MY_APPEND_EXT) && (pos= (char*) strchr(name,FN_EXTCHAR)) != NullS) { if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */ { length=strlength(name); /* Use old extension */ ext = ""; } else { length= (size_t) (pos-(char*) name); /* Change extension */ ext= extension; } } else { length=strlength(name); /* No ext, use the now one */ ext=extension; } if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN ) { /* To long path, return original or NULL */ size_t tmp_length; if (flag & MY_SAFE_PATH) DBUG_RETURN(NullS); tmp_length= strlength(startpos); DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext, (uint) length)); (void) strmake(to, startpos, MY_MIN(tmp_length, FN_REFLEN-1)); } else { if (to == startpos) { bmove(buff,(uchar*) name,length); /* Save name for last copy */ name=buff; } pos=strmake(strmov(to,dev),name,length); (void) strmov(pos,ext); /* Don't convert extension */ } /* If MY_RETURN_REAL_PATH and MY_RESOLVE_SYMLINK is given, only do realpath if the file is a symbolic link */ if (flag & MY_RETURN_REAL_PATH) (void) my_realpath(to, to, MYF(flag & MY_RESOLVE_SYMLINKS ? MY_RESOLVE_LINK: 0)); else if (flag & MY_RESOLVE_SYMLINKS) { strmov(buff,to); (void) my_readlink(to, buff, MYF(0)); } DBUG_RETURN(to); } /* fn_format */
int my_setwd(const char *dir, myf MyFlags) { int res; size_s length; my_string start,pos; #if defined(VMS) || defined(MSDOS) || defined(OS2) char buff[FN_REFLEN]; #endif DBUG_ENTER("my_setwd"); DBUG_PRINT("my",("dir: '%s' MyFlags %d", dir, MyFlags)); start=(my_string) dir; #if defined(MSDOS) || defined(OS2) /* OS2/MSDOS chdir can't change drive */ #if !defined(_DDL) && !defined(WIN32) if ((pos=(char*) strchr(dir,FN_DEVCHAR)) != 0) { uint drive,drives; pos++; /* Skip FN_DEVCHAR */ drive=(uint) (my_toupper(&my_charset_latin1,dir[0])-'A'+1); drives= (uint) -1; if ((pos-(byte*) dir) == 2 && drive > 0 && drive < 32) { #ifdef OS2 _chdrive(drive); drives = _getdrive(); #else _dos_setdrive(drive,&drives); _dos_getdrive(&drives); #endif } if (drive != drives) { *pos='\0'; /* Dir is now only drive */ my_errno=errno; my_error(EE_SETWD,MYF(ME_BELL+ME_WAITTANG),dir,ENOENT); DBUG_RETURN(-1); } dir=pos; /* drive changed, change now path */ } #endif if (*((pos=strend(dir)-1)) == FN_LIBCHAR && pos != dir) { strmov(buff,dir)[-1]=0; /* Remove last '/' */ dir=buff; } #endif /* MSDOS*/ if (! dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0)) dir=FN_ROOTDIR; #ifdef VMS { pos=strmov(buff,dir); if (pos[-1] != FN_LIBCHAR) { pos[0]=FN_LIBCHAR; /* Mark as directory */ pos[1]=0; } system_filename(buff,buff); /* Change to VMS format */ dir=buff; } #endif /* VMS */ if ((res=chdir((char*) dir)) != 0) { my_errno=errno; if (MyFlags & MY_WME) my_error(EE_SETWD,MYF(ME_BELL+ME_WAITTANG),start,errno); } else { if (test_if_hard_path(start)) { /* Hard pathname */ pos=strmake(&curr_dir[0],start,(size_s) FN_REFLEN-1); if (pos[-1] != FN_LIBCHAR) { length=(uint) (pos-(char*) curr_dir); curr_dir[length]=FN_LIBCHAR; /* must end with '/' */ curr_dir[length+1]='\0'; } } else curr_dir[0]='\0'; /* Don't save name */ } DBUG_RETURN(res); } /* my_setwd */
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { int save_errno,i,errpos; uint files,dir_length,length,key_parts; ulonglong file_offset; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; MYRG_INFO info,*m_info; File fd; IO_CACHE file; MI_INFO *isam,*last_isam; DBUG_ENTER("myrg_open"); LINT_INIT(last_isam); LINT_INIT(m_info); isam=0; errpos=files=0; bzero((gptr) &info,sizeof(info)); bzero((char*) &file,sizeof(file)); if ((fd=my_open(fn_format(name_buff,name,"",MYRG_NAME_EXT,4), O_RDONLY | O_SHARE,MYF(0))) < 0 || init_io_cache(&file, fd, IO_SIZE, READ_CACHE, 0, 0, MYF(MY_WME | MY_NABP))) goto err; errpos=1; dir_length=dirname_part(name_buff,name); info.reclength=0; while ((length=my_b_gets(&file,buff,FN_REFLEN-1))) { if ((end=buff+length)[-1] == '\n') end[-1]='\0'; if (!buff[0]) continue; /* Skip empty lines */ if (buff[0] == '#') { if( !strncmp(buff+1,"INSERT_METHOD=",14)) { /* Lookup insert method */ int tmp=find_type(buff+15,&merge_insert_method,2); info.merge_insert_method = (uint) (tmp >= 0 ? tmp : 0); } continue; /* Skip comments */ } if (!test_if_hard_path(buff)) { VOID(strmake(name_buff+dir_length,buff, sizeof(name_buff)-1-dir_length)); VOID(cleanup_dirname(buff,name_buff)); } if (!(isam=mi_open(buff,mode,(handle_locking?HA_OPEN_WAIT_IF_LOCKED:0)))) goto err; files++; last_isam=isam; if (info.reclength && info.reclength != isam->s->base.reclength) { my_errno=HA_ERR_WRONG_MRG_TABLE_DEF; goto err; } info.reclength=isam->s->base.reclength; } key_parts=(isam ? isam->s->base.key_parts : 0); if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO)+ files*sizeof(MYRG_TABLE)+ sizeof(long)*key_parts, MYF(MY_WME)))) goto err; *m_info=info; m_info->tables=files; if (files) { m_info->open_tables=(MYRG_TABLE *) (m_info+1); m_info->rec_per_key_part=(ulong *) (m_info->open_tables+files); bzero((char*) m_info->rec_per_key_part,sizeof(long)*key_parts); } else { m_info->open_tables=0; m_info->rec_per_key_part=0; } errpos=2; for (i=files ; i-- > 0 ; ) { uint j; m_info->open_tables[i].table=isam; m_info->options|=isam->s->options; m_info->records+=isam->state->records; m_info->del+=isam->state->del; m_info->data_file_length+=isam->state->data_file_length; for (j=0; j < key_parts; j++) m_info->rec_per_key_part[j]+=isam->s->state.rec_per_key_part[j] / files; if (i) isam=(MI_INFO*) (isam->open_list.next->data); } /* Don't mark table readonly, for ALTER TABLE ... UNION=(...) to work */ m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA); /* Fix fileinfo for easyer debugging (actually set by rrnd) */ file_offset=0; for (i=0 ; (uint) i < files ; i++) { m_info->open_tables[i].file_offset=(my_off_t) file_offset; file_offset+=m_info->open_tables[i].table->state->data_file_length; } if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L) { my_errno=HA_ERR_RECORD_FILE_FULL; goto err; } m_info->keys=(files) ? m_info->open_tables->table->s->base.keys : 0; bzero((char*) &m_info->by_key,sizeof(m_info->by_key)); /* this works ok if the table list is empty */ m_info->end_table=m_info->open_tables+files; m_info->last_used_table=m_info->open_tables; VOID(my_close(fd,MYF(0))); end_io_cache(&file); m_info->open_list.data=(void*) m_info; pthread_mutex_lock(&THR_LOCK_open); myrg_open_list=list_add(myrg_open_list,&m_info->open_list); pthread_mutex_unlock(&THR_LOCK_open); DBUG_RETURN(m_info); err: save_errno=my_errno; switch (errpos) { case 2: my_free((char*) m_info,MYF(0)); /* Fall through */ case 1: VOID(my_close(fd,MYF(0))); end_io_cache(&file); for (i=files ; i-- > 0 ; ) { isam=last_isam; if (i) last_isam=(MI_INFO*) (isam->open_list.next->data); mi_close(isam); } } my_errno=save_errno; DBUG_RETURN (NULL); }