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 */
char *intern_filename(char *to, const char *from) { size_t length, to_length; char buff[FN_REFLEN]; if (from == to) { /* Dirname may destroy from */ (void) strnmov(buff, from, FN_REFLEN); from=buff; } length= dirname_part(to, from, &to_length); /* Copy dirname & fix chars */ (void) strnmov(to + to_length, from + length, FN_REFLEN - to_length); return (to); } /* intern_filename */
int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) { char *start=to, *end=to+n-1; for (; *fmt ; fmt++) { if (fmt[0] != '%') { if (to == end) /* End of buffer */ break; *to++= *fmt; /* Copy ordinary char */ continue; } /* Skip if max size is used (to be compatible with printf) */ fmt++; while (isdigit(*fmt) || *fmt == '.' || *fmt == '-') fmt++; if (*fmt == 'l') fmt++; if (*fmt == 's') /* String parameter */ { reg2 char *par = va_arg(ap, char *); uint plen,left_len = (uint)(end-to); if (!par) par = (char*)"(null)"; plen = (uint) strlen(par); if (left_len <= plen) plen = left_len - 1; to=strnmov(to,par,plen); continue; } else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
my_bool my_gethwaddr(uchar *to) { int fd, res= 1; struct ifreq ifr; char zero_array[ETHER_ADDR_LEN] = {0}; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) goto err; bzero(&ifr, sizeof(ifr)); strnmov(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1); do { if (ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0) { memcpy(to, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1; } } while (res && (errno == 0 || errno == ENODEV) && ifr.ifr_name[3]++ < '6'); close(fd); err: return res; }
char *get_tty_password(const char *opt_message) { #ifdef HAVE_GETPASS char *passbuff; #else /* ! HAVE_GETPASS */ TERMIO org,tmp; #endif /* HAVE_GETPASS */ char buff[80]; DBUG_ENTER("get_tty_password"); #ifdef HAVE_GETPASS passbuff = getpass(opt_message ? opt_message : "Enter password: "******"Enter password: ",stdout); fflush(stdout); } #if defined(HAVE_TERMIOS_H) tcgetattr(fileno(stdin), &org); tmp = org; tmp.c_lflag &= ~(ECHO | ISIG | ICANON); tmp.c_cc[VMIN] = 1; tmp.c_cc[VTIME] = 0; tcsetattr(fileno(stdin), TCSADRAIN, &tmp); get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stdout))); tcsetattr(fileno(stdin), TCSADRAIN, &org); #elif defined(HAVE_TERMIO_H) ioctl(fileno(stdin), (int) TCGETA, &org); tmp=org; tmp.c_lflag &= ~(ECHO | ISIG | ICANON); tmp.c_cc[VMIN] = 1; tmp.c_cc[VTIME]= 0; ioctl(fileno(stdin),(int) TCSETA, &tmp); get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout))); ioctl(fileno(stdin),(int) TCSETA, &org); #else gtty(fileno(stdin), &org); tmp=org; tmp.sg_flags &= ~ECHO; tmp.sg_flags |= RAW; stty(fileno(stdin), &tmp); get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout))); stty(fileno(stdin), &org); #endif if (isatty(fileno(stdout))) fputc('\n',stdout); #endif /* HAVE_GETPASS */ DBUG_RETURN(my_strdup(buff,MYF(MY_FAE))); }
static my_bool get_one_option(int optid, const struct my_option *opt, char *argument) { my_bool add_option= TRUE; switch (optid) { case '?': printf("MySQL utility for upgrading database to MySQL version %s\n", MYSQL_SERVER_VERSION); my_print_help(my_long_options); exit(0); break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); add_option= FALSE; break; case 'p': tty_password= 1; add_option= FALSE; if (argument) { /* Add password to ds_args before overwriting the arg with x's */ add_one_option(&ds_args, opt, argument); while (*argument) *argument++= 'x'; /* Destroy argument */ tty_password= 0; } break; case 't': strnmov(opt_tmpdir, argument, sizeof(opt_tmpdir)); add_option= FALSE; break; case 'b': /* --basedir */ case 'v': /* --verbose */ case 'd': /* --datadir */ case 'f': /* --force */ add_option= FALSE; break; } if (add_option) { /* This is an option that is accpted by mysql_upgrade just so it can be passed on to "mysql" and "mysqlcheck" Save it in the ds_args string */ add_one_option(&ds_args, opt, argument); } return 0; }
int test_write(MI_INFO *file,int id,int lock_type) { uint i,tries,count,lock; lock=0; if (rnd(2) == 0 || lock_type == F_RDLCK) { lock=1; if (mi_lock_database(file,F_WRLCK)) { if (lock_type == F_RDLCK && my_errno == EDEADLK) { printf("%2d: write: deadlock\n",id); fflush(stdout); return 0; } fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno); mi_close(file); return 1; } if (rnd(2) == 0) mi_extra(file,HA_EXTRA_WRITE_CACHE,0); } sprintf((char*) record.id,"%7d",getpid()); strnmov((char*) record.text,"Testing...", sizeof(record.text)); tries=(uint) rnd(100)+10; for (i=count=0 ; i < tries ; i++) { uint32 tmp=rnd(80000)+20000; int4store(record.nr,tmp); if (!mi_write(file,record.id)) count++; else { if (my_errno != HA_ERR_FOUND_DUPP_KEY) { fprintf(stderr,"%2d: Got error %d (errno %d) from write\n",id,my_errno, errno); return 1; } } } if (lock) { mi_extra(file,HA_EXTRA_NO_CACHE,0); if (mi_lock_database(file,F_UNLCK)) { fprintf(stderr,"%2d: Can't unlock table\n",id); exit(0); } } printf("%2d: write: %5d\n",id,count); fflush(stdout); return 0; }
char * directory_file_name (char * dst, const char *src) { /* Process as Unix format: just remove test the final slash. */ char *end; DBUG_ASSERT(strlen(src) < (FN_REFLEN + 1)); if (src[0] == 0) src= (char*) "."; /* Use empty as current */ end= strnmov(dst, src, FN_REFLEN + 1); if (end[-1] != FN_LIBCHAR) { end[0]=FN_LIBCHAR; /* Add last '/' */ end[1]='\0'; } return dst; }
static char *process_str_arg(CHARSET_INFO *cs, char *to, char *end, size_t width, char *par, uint print_type) { int well_formed_error; size_t plen, left_len= (size_t) (end - to) + 1; if (!par) par = (char*) "(null)"; plen= strnlen(par, width); if (left_len <= plen) plen = left_len - 1; plen= cs->cset->well_formed_len(cs, par, par + plen, width, &well_formed_error); if (print_type & ESCAPED_ARG) to= backtick_string(cs, to, end, par, plen, '`'); else to= strnmov(to,par,plen); return to; }
static char *backtick_string(CHARSET_INFO *cs, char *to, char *end, char *par, size_t par_len, char quote_char) { uint char_len; char *start= to; char *par_end= par + par_len; size_t buff_length= (size_t) (end - to); if (buff_length <= par_len) goto err; *start++= quote_char; for ( ; par < par_end; par+= char_len) { uchar c= *(uchar *) par; if (!(char_len= my_mbcharlen(cs, c))) char_len= 1; if (char_len == 1 && c == (uchar) quote_char ) { if (start + 1 >= end) goto err; *start++= quote_char; } if (start + char_len >= end) goto err; start= strnmov(start, par, char_len); } if (start + 1 >= end) goto err; *start++= quote_char; return start; err: *to='\0'; return to; }
static char *find_file_in_path(char *to, const char *name) { char *path,*pos,dir[2]; const char *ext=""; if (!(path=getenv("PATH"))) return NullS; dir[0]=FN_LIBCHAR; dir[1]=0; #ifdef PROGRAM_EXTENSION if (!fn_ext(name)[0]) ext=PROGRAM_EXTENSION; #endif for (pos=path ; (pos=strchr(pos,PATH_SEP)) ; path= ++pos) { if (path != pos) { strxmov(strnmov(to,path,(uint) (pos-path)),dir,name,ext,NullS); if (!access(to,F_OK)) { to[(uint) (pos-path)+1]=0; /* Return path only */ return to; } } } #ifdef __WIN__ to[0]=FN_CURLIB; strxmov(to+1,dir,name,ext,NullS); if (!access(to,F_OK)) /* Test in current dir */ { to[2]=0; /* Leave ".\" */ return to; } #endif return NullS; /* File not found */ }
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; bzero(finfo.mystat, 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) my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno); DBUG_RETURN((MY_DIR *) NULL); } /* my_dir */
static my_bool get_one_option(int optid, const struct my_option *opt, char *argument) { my_bool add_option= TRUE; switch (optid) { case '?': printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000")); puts("MariaDB utility for upgrading databases to new MariaDB versions."); print_defaults("my", load_default_groups); puts(""); my_print_help(my_long_options); my_print_variables(my_long_options); die(0); break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); add_option= FALSE; debug_check_flag= 1; break; case 'p': if (argument == disabled_my_option) argument= (char*) ""; /* Don't require password */ tty_password= 1; add_option= FALSE; if (argument) { /* Add password to ds_args before overwriting the arg with x's */ add_one_option(&ds_args, opt, argument); while (*argument) *argument++= 'x'; /* Destroy argument */ tty_password= 0; } break; case 't': strnmov(opt_tmpdir, argument, sizeof(opt_tmpdir)); add_option= FALSE; break; case 'b': /* --basedir */ case 'd': /* --datadir */ fprintf(stderr, "%s: the '--%s' option is always ignored\n", my_progname, optid == 'b' ? "basedir" : "datadir"); /* FALLTHROUGH */ case 'k': /* --version-check */ case 'v': /* --verbose */ opt_verbose++; if (argument == disabled_my_option) { opt_verbose= 0; opt_silent= 1; } add_option= 0; break; case 'V': printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); die(0); break; case OPT_SILENT: opt_verbose= 0; add_option= 0; break; case 'f': /* --force */ case 's': /* --upgrade-system-tables */ case OPT_WRITE_BINLOG: /* --write-binlog */ add_option= FALSE; break; case 'h': /* --host */ case 'W': /* --pipe */ case 'P': /* --port */ case 'S': /* --socket */ case OPT_MYSQL_PROTOCOL: /* --protocol */ case OPT_SHARED_MEMORY_BASE_NAME: /* --shared-memory-base-name */ case OPT_PLUGIN_DIR: /* --plugin-dir */ case OPT_DEFAULT_AUTH: /* --default-auth */ add_one_option(&conn_args, opt, argument); break; } if (add_option) { /* This is an option that is accpted by mysql_upgrade just so it can be passed on to "mysql" and "mysqlcheck" Save it in the ds_args string */ add_one_option(&ds_args, opt, argument); } return 0; }
my_string intern_filename(my_string to, const char *from) { #ifndef VMS { uint length; char buff[FN_REFLEN]; if (from == to) { /* Dirname may destroy from */ strmov(buff,from); from=buff; } length=dirname_part(to,from); /* Copy dirname & fix chars */ (void) strcat(to,from+length); return (to); } #else /* VMS */ /* change 'dev:[lib]xxx' to 'dev:lib/xxx' */ /* change 'dev:xxx' to 'dev:xxx' */ /* change 'dev:x/y/[.lib]' to 'dev:x/y/lib/ */ /* change '[.lib]' to './lib/' */ /* change '[x.y]' or '[x.][y]' or '[x][.y]' to '/x/y/' */ /* change '[000000.x] or [x.000000]' to '/x/' */ int par_length,root_length; my_string pos,from_pos,to_pos,end_pos; char buff[FN_REFLEN]; convert_dirname(buff,from,NullS); /* change '<>' to '[]' */ from_pos=buff; if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skipp device part */ { pos++; to_pos=strnmov(to,from_pos,(size_s) (pos-from_pos)); from_pos=pos; } else to_pos=to; root_length=strlen(FN_C_ROOT_DIR); if ((pos = strchr(from_pos,FN_C_BEFORE_DIR)) && (end_pos = strrchr(pos+1,FN_C_AFTER_DIR))) { to_pos=strnmov(to_pos,from_pos,(size_s) (pos-from_pos)); /* Copy all between ':' and '[' */ from_pos=pos+1; if (strinstr(from_pos,FN_C_ROOT_DIR) == 1 && (from_pos[root_length] == FN_C_DIR_SEP || from_pos[root_length] == FN_C_AFTER_DIR)) { from_pos+=root_length+1; } else if (*from_pos == FN_C_DIR_SEP) *(to_pos++) = FN_CURLIB; /* Set ./ first */ *(to_pos++) = FN_LIBCHAR; par_length=strlen(FN_C_PARENT_DIR); pos=to_pos; for (; from_pos <= end_pos ; from_pos++) { switch (*from_pos) { case FN_C_DIR_SEP: case FN_C_AFTER_DIR: if (pos != to_pos) { if ((int) (to_pos-pos) == root_length && is_suffix(pos,FN_C_ROOT_DIR)) to_pos=pos; /* remove root-pos */ else { *(to_pos++)=FN_LIBCHAR; /* Find lib */ pos=to_pos; } } break; case FN_C_BEFORE_DIR: break; case '-': /* *(FN_C_PARENT_DIR): */ if (to_pos[-1] == FN_LIBCHAR && strncmp(from_pos,FN_C_PARENT_DIR,par_length) == 0) { /* Change '-' to '..' */ to_pos=strmov(to_pos,FN_PARENTDIR); *(to_pos++)=FN_LIBCHAR; pos=to_pos; from_pos+=par_length-1; break; } /* Fall through */ default: *(to_pos++)= *from_pos; break; } } } (void) strmov(to_pos,from_pos); return (to); #endif /* VMS */ } /* intern_filename */
uint system_filename(my_string to, const char *from) { #ifndef FN_C_BEFORE_DIR return (uint) (strmake(to,from,FN_REFLEN-1)-to); #else /* VMS */ /* change 'dev:lib/xxx' to 'dev:[lib]xxx' */ /* change 'dev:xxx' to 'dev:xxx' */ /* change './xxx' to 'xxx' */ /* change './lib/' or lib/ to '[.lib]' */ /* change '/x/y/z to '[x.y]x' */ /* change 'dev:/x' to 'dev:[000000]x' */ int libchar_found,length; my_string to_pos,from_pos,pos; char buff[FN_REFLEN]; DBUG_ENTER("system_filename"); libchar_found=0; (void) strmov(buff,from); /* If to == from */ from_pos= buff; if ((pos=strrchr(from_pos,FN_DEVCHAR))) /* Skipp device part */ { pos++; to_pos=strnmov(to,from_pos,(size_s) (pos-from_pos)); from_pos=pos; } else to_pos=to; if (from_pos[0] == FN_CURLIB && from_pos[1] == FN_LIBCHAR) from_pos+=2; /* Skipp './' */ if (strchr(from_pos,FN_LIBCHAR)) { *(to_pos++) = FN_C_BEFORE_DIR; if (strinstr(from_pos,FN_ROOTDIR) == 1) { from_pos+=strlen(FN_ROOTDIR); /* Actually +1 but... */ if (! strchr(from_pos,FN_LIBCHAR)) { /* No dir, use [000000] */ to_pos=strmov(to_pos,FN_C_ROOT_DIR); libchar_found++; } } else *(to_pos++)=FN_C_DIR_SEP; /* '.' gives current dir */ while ((pos=strchr(from_pos,FN_LIBCHAR))) { if (libchar_found++) *(to_pos++)=FN_C_DIR_SEP; /* Add '.' between dirs */ if (strinstr(from_pos,FN_PARENTDIR) == 1 && from_pos+strlen(FN_PARENTDIR) == pos) to_pos=strmov(to_pos,FN_C_PARENT_DIR); /* Found '../' */ else to_pos=strnmov(to_pos,from_pos,(size_s) (pos-from_pos)); from_pos=pos+1; } *(to_pos++)=FN_C_AFTER_DIR; } length=(int) (strmov(to_pos,from_pos)-to); DBUG_PRINT("exit",("name: '%s'",to)); DBUG_RETURN((uint) length); #endif } /* system_filename */
uint cleanup_dirname(register my_string to, const char *from) /* to may be == from */ { reg5 uint length; reg2 my_string pos; reg3 my_string from_ptr; reg4 my_string start; char parent[5], /* for "FN_PARENTDIR" */ buff[FN_REFLEN+1],*end_parentdir; DBUG_ENTER("cleanup_dirname"); DBUG_PRINT("enter",("from: '%s'",from)); start=buff; from_ptr=(my_string) from; #ifdef FN_DEVCHAR if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0) { /* Skipp device part */ length=(uint) (pos-from_ptr)+1; start=strnmov(buff,from_ptr,length); from_ptr+=length; } #endif parent[0]=FN_LIBCHAR; length=(uint) (strmov(parent+1,FN_PARENTDIR)-parent); for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++) { if (*pos == '/') *pos = FN_LIBCHAR; if (*pos == FN_LIBCHAR) { if ((uint) (pos-start) > length && bcmp(pos-length,parent,length) == 0) { /* If .../../; skipp prev */ pos-=length; if (pos != start) { /* not /../ */ pos--; if (*pos == FN_HOMELIB && (pos == start || pos[-1] == FN_LIBCHAR)) { if (!home_dir) { pos+=length+1; /* Don't unpack ~/.. */ continue; } pos=strmov(buff,home_dir)-1; /* Unpacks ~/.. */ if (*pos == FN_LIBCHAR) pos--; /* home ended with '/' */ } if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR)) { if (my_getwd(curr_dir,FN_REFLEN,MYF(0))) { pos+=length+1; /* Don't unpack ./.. */ continue; } pos=strmov(buff,curr_dir)-1; /* Unpacks ./.. */ if (*pos == FN_LIBCHAR) pos--; /* home ended with '/' */ } end_parentdir=pos; while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */ pos--; if (pos[1] == FN_HOMELIB || bcmp(pos,parent,length) == 0) { /* Don't remove ~user/ */ pos=strmov(end_parentdir+1,parent); *pos=FN_LIBCHAR; continue; } } } else if ((uint) (pos-start) == length-1 && !bcmp(start,parent+1,length-1)) start=pos; /* Starts with "../" */ else if (pos-start > 0 && pos[-1] == FN_LIBCHAR) { #ifdef FN_NETWORK_DRIVES if (pos-start != 1) #endif pos--; /* Remove dupplicate '/' */ } else if (pos-start > 1 && pos[-1] == FN_CURLIB && pos[-2] == FN_LIBCHAR) pos-=2; /* Skipp /./ */ else if (pos > buff+1 && pos[-1] == FN_HOMELIB && pos[-2] == FN_LIBCHAR) { /* Found ..../~/ */ buff[0]=FN_HOMELIB; buff[1]=FN_LIBCHAR; start=buff; pos=buff+1; } } } (void) strmov(to,buff); DBUG_PRINT("exit",("to: '%s'",to)); DBUG_RETURN((uint) (pos-buff)); } /* cleanup_dirname */
size_t cleanup_dirname(register char *to, const char *from) { reg5 size_t length; reg2 char * pos; reg3 char * from_ptr; reg4 char * start; char parent[5], /* for "FN_PARENTDIR" */ buff[FN_REFLEN+1],*end_parentdir; #ifdef BACKSLASH_MBTAIL CHARSET_INFO *fs= fs_character_set(); #endif DBUG_ENTER("cleanup_dirname"); DBUG_PRINT("enter",("from: '%s'",from)); start=buff; from_ptr=(char *) from; #ifdef FN_DEVCHAR if ((pos=strrchr(from_ptr,FN_DEVCHAR)) != 0) { /* Skip device part */ length=(size_t) (pos-from_ptr)+1; start=strnmov(buff,from_ptr,length); from_ptr+=length; } #endif parent[0]=FN_LIBCHAR; length=(size_t) (strmov(parent+1,FN_PARENTDIR)-parent); for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++) { #ifdef BACKSLASH_MBTAIL uint l; if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2))) { for (l-- ; l ; *++pos= *from_ptr++, l--); start= pos + 1; /* Don't look inside multi-byte char */ continue; } #endif if (*pos == '/') *pos = FN_LIBCHAR; if (*pos == FN_LIBCHAR) { if ((size_t) (pos-start) > length && memcmp(pos-length,parent,length) == 0) { /* If .../../; skip prev */ pos-=length; if (pos != start) { /* not /../ */ pos--; if (*pos == FN_HOMELIB && (pos == start || pos[-1] == FN_LIBCHAR)) { if (!home_dir) { pos+=length+1; /* Don't unpack ~/.. */ continue; } pos=strmov(buff,home_dir)-1; /* Unpacks ~/.. */ if (*pos == FN_LIBCHAR) pos--; /* home ended with '/' */ } if (*pos == FN_CURLIB && (pos == start || pos[-1] == FN_LIBCHAR)) { if (my_getwd(curr_dir,FN_REFLEN,MYF(0))) { pos+=length+1; /* Don't unpack ./.. */ continue; } pos=strmov(buff,curr_dir)-1; /* Unpacks ./.. */ if (*pos == FN_LIBCHAR) pos--; /* home ended with '/' */ } end_parentdir=pos; while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */ pos--; if (pos[1] == FN_HOMELIB || (pos > start && memcmp(pos, parent, length) == 0)) { /* Don't remove ~user/ */ pos=strmov(end_parentdir+1,parent); *pos=FN_LIBCHAR; continue; } } } else if ((size_t) (pos-start) == length-1 && !memcmp(start,parent+1,length-1)) start=pos; /* Starts with "../" */ else if (pos-start > 0 && pos[-1] == FN_LIBCHAR) { #ifdef FN_NETWORK_DRIVES if (pos-start != 1) #endif pos--; /* Remove dupplicate '/' */ } else if (pos-start > 1 && pos[-1] == FN_CURLIB && pos[-2] == FN_LIBCHAR) pos-=2; /* Skip /./ */ else if (pos > buff+1 && pos[-1] == FN_HOMELIB && pos[-2] == FN_LIBCHAR) { /* Found ..../~/ */ buff[0]=FN_HOMELIB; buff[1]=FN_LIBCHAR; start=buff; pos=buff+1; } } } (void) strmov(to,buff); DBUG_PRINT("exit",("to: '%s'",to)); DBUG_RETURN((size_t) (pos-buff)); } /* cleanup_dirname */
static int search_default_file_with_ext(Process_option_func opt_handler, void *handler_ctx, const char *dir, const char *ext, const char *config_file, int recursion_level) { char name[FN_REFLEN + 10], buff[4096], curr_gr[4096], *ptr, *end, **tmp_ext; char *value, option[4096+2], tmp[FN_REFLEN]; static const char includedir_keyword[]= "includedir"; static const char include_keyword[]= "include"; const int max_recursion_level= 10; MYSQL_FILE *fp; uint line=0; my_bool found_group=0; uint i; MY_DIR *search_dir; FILEINFO *search_file; if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3) return 0; /* Ignore wrong paths */ if (dir) { end=convert_dirname(name, dir, NullS); if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */ *end++='.'; strxmov(end,config_file,ext,NullS); } else { strmov(name,config_file); } fn_format(name,name,"","",4); #if !defined(__WIN__) { MY_STAT stat_info; if (!my_stat(name,&stat_info,MYF(0))) return 1; /* Ignore world-writable regular files. This is mainly done to protect us to not read a file created by the mysqld server, but the check is still valid in most context. */ if ((stat_info.st_mode & S_IWOTH) && (stat_info.st_mode & S_IFMT) == S_IFREG) { fprintf(stderr, "Warning: World-writable config file '%s' is ignored\n", name); return 0; } } #endif if (!(fp= mysql_file_fopen(key_file_cnf, name, O_RDONLY, MYF(0)))) return 1; /* Ignore wrong files */ while (mysql_file_fgets(buff, sizeof(buff) - 1, fp)) { line++; /* Ignore comment and empty lines */ for (ptr= buff; my_isspace(&my_charset_latin1, *ptr); ptr++) {} if (*ptr == '#' || *ptr == ';' || !*ptr) continue; /* Configuration File Directives */ if (*ptr == '!') { if (recursion_level >= max_recursion_level) { for (end= ptr + strlen(ptr) - 1; my_isspace(&my_charset_latin1, *(end - 1)); end--) {} end[0]= 0; fprintf(stderr, "Warning: skipping '%s' directive as maximum include" "recursion level was reached in file %s at line %d\n", ptr, name, line); continue; } /* skip over `!' and following whitespace */ for (++ptr; my_isspace(&my_charset_latin1, ptr[0]); ptr++) {} if ((!strncmp(ptr, includedir_keyword, sizeof(includedir_keyword) - 1)) && my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1])) { if (!(ptr= get_argument(includedir_keyword, sizeof(includedir_keyword), ptr, name, line))) goto err; if (!(search_dir= my_dir(ptr, MYF(MY_WME)))) goto err; for (i= 0; i < (uint) search_dir->number_of_files; i++) { search_file= search_dir->dir_entry + i; ext= fn_ext(search_file->name); /* check extension */ for (tmp_ext= (char**) f_extensions; *tmp_ext; tmp_ext++) { if (!strcmp(ext, *tmp_ext)) break; } if (*tmp_ext) { fn_format(tmp, search_file->name, ptr, "", MY_UNPACK_FILENAME | MY_SAFE_PATH); search_default_file_with_ext(opt_handler, handler_ctx, "", "", tmp, recursion_level + 1); } } my_dirend(search_dir); } else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1)) && my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword)-1])) { if (!(ptr= get_argument(include_keyword, sizeof(include_keyword), ptr, name, line))) goto err; search_default_file_with_ext(opt_handler, handler_ctx, "", "", ptr, recursion_level + 1); } continue; } if (*ptr == '[') /* Group name */ { found_group=1; if (!(end=(char *) strchr(++ptr,']'))) { fprintf(stderr, "error: Wrong group definition in config file: %s at line %d\n", name,line); goto err; } /* Remove end space */ for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ; end[0]=0; strmake(curr_gr, ptr, MY_MIN((size_t) (end-ptr)+1, sizeof(curr_gr)-1)); /* signal that a new group is found */ opt_handler(handler_ctx, curr_gr, NULL); continue; } if (!found_group) { fprintf(stderr, "error: Found option without preceding group in config file: %s at line: %d\n", name,line); goto err; } end= remove_end_comment(ptr); if ((value= strchr(ptr, '='))) end= value; /* Option without argument */ for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ; if (!value) { strmake(strmov(option,"--"),ptr, (size_t) (end-ptr)); if (opt_handler(handler_ctx, curr_gr, option)) goto err; } else { /* Remove pre- and end space */ char *value_end; for (value++ ; my_isspace(&my_charset_latin1,*value); value++) ; value_end=strend(value); /* We don't have to test for value_end >= value as we know there is an '=' before */ for ( ; my_isspace(&my_charset_latin1,value_end[-1]) ; value_end--) ; if (value_end < value) /* Empty string */ value_end=value; /* remove quotes around argument */ if ((*value == '\"' || *value == '\'') && /* First char is quote */ (value + 1 < value_end ) && /* String is longer than 1 */ *value == value_end[-1] ) /* First char is equal to last char */ { value++; value_end--; } ptr=strnmov(strmov(option,"--"),ptr,(size_t) (end-ptr)); *ptr++= '='; for ( ; value != value_end; value++) { if (*value == '\\' && value != value_end-1) { switch(*++value) { case 'n': *ptr++='\n'; break; case 't': *ptr++= '\t'; break; case 'r': *ptr++ = '\r'; break; case 'b': *ptr++ = '\b'; break; case 's': *ptr++= ' '; /* space */ break; case '\"': *ptr++= '\"'; break; case '\'': *ptr++= '\''; break; case '\\': *ptr++= '\\'; break; default: /* Unknown; Keep '\' */ *ptr++= '\\'; *ptr++= *value; break; } } else *ptr++= *value; } *ptr=0; if (opt_handler(handler_ctx, curr_gr, option)) goto err; } } mysql_file_fclose(fp, MYF(0)); return(0); err: mysql_file_fclose(fp, MYF(0)); return -1; /* Fatal error */ }
File create_temp_file(char *to, const char *dir, const char *prefix, int mode __attribute__((unused)), myf MyFlags __attribute__((unused))) { File file= -1; #ifdef __WIN__ TCHAR path_buf[MAX_PATH-14]; #endif DBUG_ENTER("create_temp_file"); DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir, prefix)); #if defined (__WIN__) /* 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)); my_errno= tmp; } #elif defined(HAVE_MKSTEMP) { char prefix_buff[30]; uint pfx_len; File org_file; pfx_len= (uint) (strmov(strnmov(prefix_buff, prefix ? prefix : "tmp.", sizeof(prefix_buff)-7),"XXXXXX") - prefix_buff); if (!dir && ! (dir =getenv("TMPDIR"))) dir=P_tmpdir; if (strlen(dir)+ pfx_len > FN_REFLEN-2) { errno=my_errno= ENAMETOOLONG; DBUG_RETURN(file); } strmov(convert_dirname(to,dir,NullS),prefix_buff); org_file=mkstemp(to); if (mode & O_TEMPORARY) (void) my_delete(to, MYF(MY_WME | ME_NOINPUT)); 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 | ME_NOINPUT)); my_errno=tmp; } } #elif defined(HAVE_TEMPNAM) { extern char **environ; char *res,**old_env,*temp_env[1]; if (dir && !dir[0]) { /* Change empty string to current dir */ to[0]= FN_CURLIB; to[1]= 0; dir=to; } old_env= (char**) environ; if (dir) { /* Don't use TMPDIR if dir is given */ environ=(const char**) temp_env; temp_env[0]=0; } if ((res=tempnam((char*) dir, (char*) prefix))) { strmake(to,res,FN_REFLEN-1); (*free)(res); file=my_create(to,0, (int) (O_RDWR | O_BINARY | O_TRUNC | O_EXCL | O_NOFOLLOW | O_TEMPORARY | O_SHORT_LIVED), MYF(MY_WME)); } else { DBUG_PRINT("error",("Got error: %d from tempnam",errno)); } environ=(const char**) old_env; } #else #error No implementation found for create_temp_file #endif if (file >= 0) thread_safe_increment(my_tmp_file_created,&THR_LOCK_open); DBUG_RETURN(file); }
static my_bool get_one_option(int optid, const struct my_option *opt, char *argument) { my_bool add_option= TRUE; switch (optid) { case '?': printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); puts("MySQL utility for upgrading databases to new MySQL versions.\n"); my_print_help(my_long_options); exit(0); break; case '#': DBUG_PUSH(argument ? argument : default_dbug_option); add_option= FALSE; debug_check_flag= 1; break; case 'p': if (argument == disabled_my_option) argument= (char*) ""; /* Don't require password */ tty_password= 1; add_option= FALSE; if (argument) { /* Add password to ds_args before overwriting the arg with x's */ add_one_option(&ds_args, opt, argument); while (*argument) *argument++= 'x'; /* Destroy argument */ tty_password= 0; } break; case 't': strnmov(opt_tmpdir, argument, sizeof(opt_tmpdir)); add_option= FALSE; break; case 'b': /* --basedir */ case 'd': /* --datadir */ fprintf(stderr, "%s: the '--%s' option is always ignored\n", my_progname, optid == 'b' ? "basedir" : "datadir"); /* FALLTHROUGH */ case 'v': /* --verbose */ case 'f': /* --force */ add_option= FALSE; break; case 'h': /* --host */ case 'W': /* --pipe */ case 'P': /* --port */ case 'S': /* --socket */ case OPT_MYSQL_PROTOCOL: /* --protocol */ case OPT_SHARED_MEMORY_BASE_NAME: /* --shared-memory-base-name */ add_one_option(&conn_args, opt, argument); break; } if (add_option) { /* This is an option that is accpted by mysql_upgrade just so it can be passed on to "mysql" and "mysqlcheck" Save it in the ds_args string */ add_one_option(&ds_args, opt, argument); } return 0; }
File create_temp_file(char *to, const char *dir, const char *prefix, int mode __attribute__((unused)), myf MyFlags __attribute__((unused))) { File file= -1; DBUG_ENTER("create_temp_file"); #if defined(_MSC_VER) { char temp[FN_REFLEN],*end,*res,**old_env,*temp_env[1]; old_env=environ; if (dir) { end=strend(dir)-1; if (!dir[0]) { /* Change empty string to current dir */ to[0]= FN_CURLIB; to[1]= 0; dir=to; } else if (*end == FN_DEVCHAR) { /* Get current dir for drive */ _fullpath(temp,dir,FN_REFLEN); dir=to; } else if (*end == FN_LIBCHAR && dir < end && end[-1] != FN_DEVCHAR) { strmake(to,dir,(uint) (end-dir)); /* Copy and remove last '\' */ dir=to; } environ=temp_env; /* Force use of dir (dir not checked) */ temp_env[0]=0; } if ((res=tempnam((char*) dir,(char *) prefix))) { strmake(to,res,FN_REFLEN-1); (*free)(res); file=my_create(to,0, mode, MyFlags); } environ=old_env; } #elif defined(_ZTC__) if (!dir) dir=getenv("TMPDIR"); if ((res=tempnam((char*) dir,(char *) prefix))) { strmake(to,res,FN_REFLEN-1); (*free)(res); file=my_create(to, 0, mode, MyFlags); } #elif defined(HAVE_MKSTEMP) { char prefix_buff[30]; uint pfx_len; File org_file; pfx_len=(strmov(strnmov(prefix_buff, prefix ? prefix : "tmp.", sizeof(prefix_buff)-7),"XXXXXX") - prefix_buff); if (!dir && ! (dir =getenv("TMPDIR"))) dir=P_tmpdir; if (strlen(dir)+ pfx_len > FN_REFLEN-2) { errno=my_errno= ENAMETOOLONG; return 1; } strmov(to,dir); strmov(convert_dirname(to),prefix_buff); org_file=mkstemp(to); 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; (void) my_delete(to, MYF(MY_WME | ME_NOINPUT)); my_errno=tmp; } } #elif defined(HAVE_TEMPNAM) { char *res,**old_env,*temp_env[1]; if (dir && !dir[0]) { /* Change empty string to current dir */ to[0]= FN_CURLIB; to[1]= 0; dir=to; } #ifdef OS2 // changing environ variable doesn't work with VACPP char buffer[256]; sprintf( buffer, "TMP=%s", dir); // remove ending backslash if (buffer[strlen(buffer)-1] == '\\') buffer[strlen(buffer)-1] = '\0'; putenv( buffer); #else old_env= (char**) environ; if (dir) { /* Don't use TMPDIR if dir is given */ environ=(const char**) temp_env; temp_env[0]=0; } #endif if ((res=tempnam((char*) dir, (char*) prefix))) { strmake(to,res,FN_REFLEN-1); (*free)(res); file=my_create(to,0, (int) (O_RDWR | O_BINARY | O_TRUNC | O_TEMPORARY | O_SHORT_LIVED), MYF(MY_WME)); } else { DBUG_PRINT("error",("Got error: %d from tempnam",errno)); } #ifndef OS2 environ=(const char**) old_env; #endif } #else { register long uniq; register int length; my_string pos,end_pos; /* Make an unique number */ pthread_mutex_lock(&THR_LOCK_open); uniq= ((long) getpid() << 20) + (long) _my_tempnam_used++ ; pthread_mutex_unlock(&THR_LOCK_open); if (!dir && !(dir=getenv("TMPDIR"))) /* Use this if possibly */ dir=P_tmpdir; /* Use system default */ length=strlen(dir)+strlen(pfx)+1; DBUG_PRINT("test",("mallocing %d byte",length+8+sizeof(TMP_EXT)+1)); if (length+8+sizeof(TMP_EXT)+1 > FN_REFLENGTH) errno=my_errno= ENAMETOOLONG; else { end_pos=strmov(to,dir); if (end_pos != to && end_pos[-1] != FN_LIBCHAR) *end_pos++=FN_LIBCHAR; end_pos=strmov(end_pos,pfx); for (length=0 ; length < 8 && uniq ; length++) { *end_pos++= _dig_vec[(int) (uniq & 31)]; uniq >>= 5; } (void) strmov(end_pos,TMP_EXT); file=my_create(to,0, (int) (O_RDWR | O_BINARY | O_TRUNC | O_TEMPORARY | O_SHORT_LIVED), MYF(MY_WME)); } } #endif if (file >= 0) thread_safe_increment(my_tmp_file_created,&THR_LOCK_open); DBUG_RETURN(file); }
static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, const char *dir, const char *config_file, const char *ext, TYPELIB *group) { char name[FN_REFLEN+10],buff[4096],*ptr,*end,*value,*tmp; FILE *fp; uint line=0; my_bool read_values=0,found_group=0; if ((dir ? strlen(dir) : 0 )+strlen(config_file) >= FN_REFLEN-3) return 0; /* Ignore wrong paths */ if (dir) { strmov(name,dir); convert_dirname(name); if (dir[0] == FN_HOMELIB) /* Add . to filenames in home */ strcat(name,"."); strxmov(strend(name),config_file,ext,NullS); } else { strmov(name,config_file); } fn_format(name,name,"","",4); #if !defined(_WIN32) && !defined(OS2) { MY_STAT stat_info; if (!my_stat(name,&stat_info,MYF(0))) return 0; if (stat_info.st_mode & S_IWOTH) /* ignore world-writeable files */ { fprintf(stderr, "warning: World-writeable config file %s is ignored\n", name); return 0; } } #endif if (!(fp = my_fopen(fn_format(name,name,"","",4),O_RDONLY,MYF(0)))) return 0; /* Ignore wrong files */ while (fgets(buff,sizeof(buff)-1,fp)) { line++; /* Ignore comment and empty lines */ for (ptr=buff ; isspace(*ptr) ; ptr++ ) ; if (*ptr == '#' || *ptr == ';' || !*ptr) continue; if (*ptr == '[') /* Group name */ { found_group=1; if (!(end=(char *) strchr(++ptr,']'))) { fprintf(stderr, "error: Wrong group definition in config file: %s at line %d\n", name,line); goto err; } for ( ; isspace(end[-1]) ; end--) ; /* Remove end space */ end[0]=0; read_values=find_type(ptr,group,3) > 0; continue; } if (!found_group) { fprintf(stderr, "error: Found option without preceding group in config file: %s at line: %d\n", name,line); goto err; } if (!read_values) continue; if (!(end=value=strchr(ptr,'='))) end=strend(ptr); /* Option without argument */ for ( ; isspace(end[-1]) ; end--) ; if (!value) { if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3))) goto err; strmake(strmov(tmp,"--"),ptr,(uint) (end-ptr)); if (insert_dynamic(args,(gptr) &tmp)) goto err; } else { /* Remove pre- and end space */ char *value_end; for (value++ ; isspace(*value); value++) ; value_end=strend(value); for ( ; isspace(value_end[-1]) ; value_end--) ; if (value_end < value) /* Empty string */ value_end=value; if (!(tmp=alloc_root(alloc,(uint) (end-ptr)+3 + (uint) (value_end-value)+1))) goto err; if (insert_dynamic(args,(gptr) &tmp)) goto err; ptr=strnmov(strmov(tmp,"--"),ptr,(uint) (end-ptr)); *ptr++= '='; for ( ; value != value_end; value++) { if (*value == '\\' && value != value_end-1) { switch(*++value) { case 'n': *ptr++='\n'; break; case 't': *ptr++= '\t'; break; case 'r': *ptr++ = '\r'; break; case 'b': *ptr++ = '\b'; break; case 's': *ptr++= ' '; /* space */ break; case '\\': *ptr++= '\\'; break; default: /* Unknown; Keep '\' */ *ptr++= '\\'; *ptr++= *value; break; } } else *ptr++= *value; } *ptr=0; } } my_fclose(fp,MYF(0)); return(0); err: my_fclose(fp,MYF(0)); return 1; }