X-Git-Url: https://git.cameronkatri.com/pw-darwin.git/blobdiff_plain/a7bda97c1f46bcacc464f9f1c5fa8c697f9574a8..f233ff62a96a2d0c369be8dcd504c169cbd60ffa:/pw/cpdir.c diff --git a/pw/cpdir.c b/pw/cpdir.c index d8fa42b..0fd671b 100644 --- a/pw/cpdir.c +++ b/pw/cpdir.c @@ -41,14 +41,16 @@ static const char rcsid[] = #include #include +#include "pw.h" #include "pwupd.h" void copymkdir(char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid) { - int rc = 0; char src[MAXPATHLEN]; char dst[MAXPATHLEN]; + char lnk[MAXPATHLEN]; + int len; if (mkdir(dir, mode) != 0 && errno != EEXIST) { warn("mkdir(%s)", dir); @@ -61,9 +63,7 @@ copymkdir(char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid ++counter; chown(dir, uid, gid); - if (skel == NULL || *skel == '\0') - rc = 1; - else { + if (skel != NULL && *skel != '\0') { DIR *d = opendir(skel); if (d != NULL) { @@ -74,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)) @@ -82,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) { @@ -104,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);