Preserve symbolic links permissions and ownership

This commit is contained in:
Pierre Pronchery 2018-01-28 20:03:59 +01:00
parent c6db72305a
commit 2e96450547

View File

@ -262,20 +262,26 @@ static int _cp_single_regular(char const * src, char const * dst, mode_t mode)
static int _cp_single_p(char const * dst, struct stat * st) static int _cp_single_p(char const * dst, struct stat * st)
{ {
struct timeval tv[2]; struct timeval tv[2];
int (*_chown)(const char * path, uid_t uid, gid_t git);
int (*_chmod)(const char * path, mode_t mode);
int (*_utimes)(const char * path, const struct timeval times[2]);
if(chown(dst, st->st_uid, st->st_gid) != 0) _chown = S_ISLNK(st->st_mode) ? lchown : chown;
_chmod = S_ISLNK(st->st_mode) ? lchmod : chmod;
_utimes = S_ISLNK(st->st_mode) ? lutimes : utimes;
if(_chown(dst, st->st_uid, st->st_gid) != 0)
{ {
_cp_error(dst, 0); _cp_error(dst, 0);
if(chmod(dst, st->st_mode & ~(S_ISUID | S_ISGID)) != 0) if(_chmod(dst, st->st_mode & ~(S_ISUID | S_ISGID)) != 0)
_cp_error(dst, 0); _cp_error(dst, 0);
} }
else if(chmod(dst, st->st_mode) != 0) else if(_chmod(dst, st->st_mode) != 0)
_cp_error(dst, 0); _cp_error(dst, 0);
tv[0].tv_sec = st->st_atime; tv[0].tv_sec = st->st_atime;
tv[0].tv_usec = 0; tv[0].tv_usec = 0;
tv[1].tv_sec = st->st_mtime; tv[1].tv_sec = st->st_mtime;
tv[1].tv_usec = 0; tv[1].tv_usec = 0;
if(utimes(dst, tv) != 0) if(_utimes(dst, tv) != 0)
_cp_error(dst, 0); _cp_error(dst, 0);
return 0; return 0;
} }