diff options
Diffstat (limited to '')
-rw-r--r-- | mysys/my_redel.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/mysys/my_redel.c b/mysys/my_redel.c new file mode 100644 index 00000000..1a69eaa2 --- /dev/null +++ b/mysys/my_redel.c @@ -0,0 +1,155 @@ +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates + Copyright (c) 2009, 2016, MariaDB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +#include "mysys_priv.h" +#include "mysys_err.h" +#include <my_dir.h> +#include <m_string.h> +#include "mysys_err.h" +#if defined(HAVE_UTIME_H) +#include <utime.h> +#elif defined(HAVE_SYS_UTIME_H) +#include <sys/utime.h> +#elif !defined(HPUX10) +struct utimbuf { + time_t actime; + time_t modtime; +}; +#endif + + /* + Rename with copy stat form old file + Copy stats from old file to new file, deletes original and + changes new file name to old file name + + if MY_REDEL_MAKE_COPY is given, then the original file + is renamed to org_name-'current_time'.BAK + */ + +#define REDEL_EXT ".BAK" + +int my_redel(const char *org_name, const char *tmp_name, + time_t backup_time_stamp, myf MyFlags) +{ + int error=1; + DBUG_ENTER("my_redel"); + DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %lu", + org_name,tmp_name,MyFlags)); + + if (!my_disable_copystat_in_redel && + my_copystat(org_name,tmp_name,MyFlags) < 0) + goto end; + if (MyFlags & MY_REDEL_MAKE_BACKUP) + { + char name_buff[FN_REFLEN + MY_BACKUP_NAME_EXTRA_LENGTH]; + my_create_backup_name(name_buff, org_name, backup_time_stamp); + if (my_rename(org_name, name_buff, MyFlags)) + goto end; + } + else if (my_delete(org_name, MyFlags)) + goto end; + if (my_rename(tmp_name,org_name,MyFlags)) + goto end; + + error=0; +end: + DBUG_RETURN(error); +} /* my_redel */ + + +/** + Copy stat from one file to another + @fn my_copystat() + @param from Copy stat from this file + @param to Copy stat to this file + @param MyFlags Flags: + MY_WME Give error if something goes wrong + MY_FAE Abort operation if something goes wrong + If MY_FAE is not given, we don't return -1 for + errors from chown (which normally require root + privilege) + + @return 0 ok + -1 if can't get stat, + 1 if wrong type of file +*/ + +int my_copystat(const char *from, const char *to, int MyFlags) +{ + MY_STAT statbuf; + + if (my_stat(from, &statbuf, MyFlags) == NULL) + return -1; /* Can't get stat on input file */ + + if ((statbuf.st_mode & S_IFMT) != S_IFREG) + return 1; + + /* Copy modes */ + if (chmod(to, statbuf.st_mode & 07777)) + { + my_errno= errno; + if (MyFlags & (MY_FAE+MY_WME)) + my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL), from, errno); + return -1; + } + +#if !defined(__WIN__) + if (statbuf.st_nlink > 1 && MyFlags & MY_LINK_WARNING) + { + if (MyFlags & MY_LINK_WARNING) + my_error(EE_LINK_WARNING,MYF(ME_BELL),from,statbuf.st_nlink); + } + /* Copy ownership */ + if (chown(to, statbuf.st_uid, statbuf.st_gid)) + { + my_errno= errno; + if (MyFlags & MY_WME) + my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL), from, errno); + if (MyFlags & MY_FAE) + return -1; + } +#endif /* !__WIN__ */ + + if (MyFlags & MY_COPYTIME) + { + struct utimbuf timep; + timep.actime = statbuf.st_atime; + timep.modtime = statbuf.st_mtime; + (void) utime((char*) to, &timep);/* Update last accessed and modified times */ + } + + return 0; +} /* my_copystat */ + + +/** + Create a backup file name. + @fn my_create_backup_name() + @param to Store new file name here + @param from Original name + + @info + The backup name is made by adding -YYMMDDHHMMSS.BAK to the file name +*/ + +void my_create_backup_name(char *to, const char *from, time_t backup_start) +{ + char ext[MY_BACKUP_NAME_EXTRA_LENGTH+1]; + ext[0]='-'; + get_date(ext+1, GETDATE_SHORT_DATE | GETDATE_HHMMSSTIME, backup_start); + strmov(strend(ext),REDEL_EXT); + strmov(strmov(to, from), ext); +} |