1/* Copyright (c) 2000, 2010, Oracle and/or its affiliates
2 Copyright (c) 2009, 2016, MariaDB
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
17#include "mysys_priv.h"
18#include "mysys_err.h"
19#include <my_dir.h>
20#include <m_string.h>
21#include "mysys_err.h"
22#if defined(HAVE_UTIME_H)
23#include <utime.h>
24#elif defined(HAVE_SYS_UTIME_H)
25#include <sys/utime.h>
26#elif !defined(HPUX10)
27struct utimbuf {
28 time_t actime;
29 time_t modtime;
30};
31#endif
32
33 /*
34 Rename with copy stat form old file
35 Copy stats from old file to new file, deletes original and
36 changes new file name to old file name
37
38 if MY_REDEL_MAKE_COPY is given, then the original file
39 is renamed to org_name-'current_time'.BAK
40 */
41
42#define REDEL_EXT ".BAK"
43
44int my_redel(const char *org_name, const char *tmp_name,
45 time_t backup_time_stamp, myf MyFlags)
46{
47 int error=1;
48 DBUG_ENTER("my_redel");
49 DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %lu",
50 org_name,tmp_name,MyFlags));
51
52 if (!my_disable_copystat_in_redel &&
53 my_copystat(org_name,tmp_name,MyFlags) < 0)
54 goto end;
55 if (MyFlags & MY_REDEL_MAKE_BACKUP)
56 {
57 char name_buff[FN_REFLEN + MY_BACKUP_NAME_EXTRA_LENGTH];
58 my_create_backup_name(name_buff, org_name, backup_time_stamp);
59 if (my_rename(org_name, name_buff, MyFlags))
60 goto end;
61 }
62 else if (my_delete(org_name, MyFlags))
63 goto end;
64 if (my_rename(tmp_name,org_name,MyFlags))
65 goto end;
66
67 error=0;
68end:
69 DBUG_RETURN(error);
70} /* my_redel */
71
72
73/**
74 Copy stat from one file to another
75 @fn my_copystat()
76 @param from Copy stat from this file
77 @param to Copy stat to this file
78 @param MyFlags Flags:
79 MY_WME Give error if something goes wrong
80 MY_FAE Abort operation if something goes wrong
81 If MY_FAE is not given, we don't return -1 for
82 errors from chown (which normally require root
83 privilege)
84
85 @return 0 ok
86 -1 if can't get stat,
87 1 if wrong type of file
88*/
89
90int my_copystat(const char *from, const char *to, int MyFlags)
91{
92 MY_STAT statbuf;
93
94 if (my_stat(from, &statbuf, MyFlags) == NULL)
95 return -1; /* Can't get stat on input file */
96
97 if ((statbuf.st_mode & S_IFMT) != S_IFREG)
98 return 1;
99
100 /* Copy modes */
101 if (chmod(to, statbuf.st_mode & 07777))
102 {
103 my_errno= errno;
104 if (MyFlags & (MY_FAE+MY_WME))
105 my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno);
106 return -1;
107 }
108
109#if !defined(__WIN__)
110 if (statbuf.st_nlink > 1 && MyFlags & MY_LINK_WARNING)
111 {
112 if (MyFlags & MY_LINK_WARNING)
113 my_error(EE_LINK_WARNING,MYF(ME_BELL+ME_WAITTANG),from,statbuf.st_nlink);
114 }
115 /* Copy ownership */
116 if (chown(to, statbuf.st_uid, statbuf.st_gid))
117 {
118 my_errno= errno;
119 if (MyFlags & MY_WME)
120 my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno);
121 if (MyFlags & MY_FAE)
122 return -1;
123 }
124#endif /* !__WIN__ */
125
126 if (MyFlags & MY_COPYTIME)
127 {
128 struct utimbuf timep;
129 timep.actime = statbuf.st_atime;
130 timep.modtime = statbuf.st_mtime;
131 (void) utime((char*) to, &timep);/* Update last accessed and modified times */
132 }
133
134 return 0;
135} /* my_copystat */
136
137
138/**
139 Create a backup file name.
140 @fn my_create_backup_name()
141 @param to Store new file name here
142 @param from Original name
143
144 @info
145 The backup name is made by adding -YYMMDDHHMMSS.BAK to the file name
146*/
147
148void my_create_backup_name(char *to, const char *from, time_t backup_start)
149{
150 char ext[MY_BACKUP_NAME_EXTRA_LENGTH+1];
151 ext[0]='-';
152 get_date(ext+1, GETDATE_SHORT_DATE | GETDATE_HHMMSSTIME, backup_start);
153 strmov(strend(ext),REDEL_EXT);
154 strmov(strmov(to, from), ext);
155}
156