X-Git-Url: https://git.cameronkatri.com/pw-darwin.git/blobdiff_plain/43d349d4f39e2a9578326e25d786523b1689c789..f233ff62a96a2d0c369be8dcd504c169cbd60ffa:/pw/cpdir.c diff --git a/pw/cpdir.c b/pw/cpdir.c index 1eba348..0fd671b 100644 --- a/pw/cpdir.c +++ b/pw/cpdir.c @@ -41,6 +41,7 @@ static const char rcsid[] = #include #include +#include "pw.h" #include "pwupd.h" void @@ -48,6 +49,8 @@ copymkdir(char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid { char src[MAXPATHLEN]; char dst[MAXPATHLEN]; + char lnk[MAXPATHLEN]; + int len; if (mkdir(dir, mode) != 0 && errno != EEXIST) { warn("mkdir(%s)", dir); @@ -71,7 +74,7 @@ copymkdir(char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid if (snprintf(src, sizeof(src), "%s/%s", skel, p) >= (int)sizeof(src)) warn("warning: pathname too long '%s/%s' (skel not copied)", skel, p); - else if (stat(src, &st) == 0) { + else if (lstat(src, &st) == 0) { if (strncmp(p, "dot.", 4) == 0) /* Conversion */ p += 3; if (snprintf(dst, sizeof(dst), "%s/%s", dir, p) >= (int)sizeof(dst)) @@ -79,11 +82,15 @@ copymkdir(char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid else { if (S_ISDIR(st.st_mode)) { /* Recurse for this */ if (strcmp(e->d_name, ".") != 0 && strcmp(e->d_name, "..") != 0) - copymkdir(dst, src, (st.st_mode & 0777), uid, gid); - chflags(dst, st.st_flags); /* propogate flags */ + copymkdir(dst, src, st.st_mode & _DEF_DIRMODE, uid, gid); + chflags(dst, st.st_flags); /* propagate flags */ + } else if (S_ISLNK(st.st_mode) && (len = readlink(src, lnk, sizeof(lnk) - 1)) != -1) { + lnk[len] = '\0'; + symlink(lnk, dst); + lchown(dst, uid, gid); /* - * Note: don't propogate special attributes - * but do propogate file flags + * Note: don't propagate special attributes + * but do propagate file flags */ } else if (S_ISREG(st.st_mode) && (outfd = open(dst, O_RDWR | O_CREAT | O_EXCL, st.st_mode)) != -1) { if ((infd = open(src, O_RDONLY)) == -1) { @@ -101,7 +108,7 @@ copymkdir(char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid write(outfd, copybuf, b); close(infd); /* - * Propogate special filesystem flags + * Propagate special filesystem flags */ fchown(outfd, uid, gid); fchflags(outfd, st.st_flags);