From 2e964505479d9fdf037d0ae2776b22127c9a7de8 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sun, 28 Jan 2018 20:03:59 +0100 Subject: [PATCH] Preserve symbolic links permissions and ownership --- src/cp.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/cp.c b/src/cp.c index e240ee7..da6930f 100644 --- a/src/cp.c +++ b/src/cp.c @@ -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) { 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); - 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); } - else if(chmod(dst, st->st_mode) != 0) + else if(_chmod(dst, st->st_mode) != 0) _cp_error(dst, 0); tv[0].tv_sec = st->st_atime; tv[0].tv_usec = 0; tv[1].tv_sec = st->st_mtime; tv[1].tv_usec = 0; - if(utimes(dst, tv) != 0) + if(_utimes(dst, tv) != 0) _cp_error(dst, 0); return 0; }