From a8253449d68877fc25bccd69e8d87ae7cf632317 Mon Sep 17 00:00:00 2001 From: kesslern Date: Thu, 22 Mar 2018 22:18:59 -0400 Subject: [PATCH] Preserve permissions when copying files --- Makefile | 6 +++++- README.md | 5 ++--- dottemplater.c | 1 + test/dotfiles/binary_file | Bin test/expected/binary_file | Bin util.c | 11 +++++++++++ util.h | 3 +++ 7 files changed, 22 insertions(+), 4 deletions(-) mode change 100644 => 100755 test/dotfiles/binary_file mode change 100644 => 100755 test/expected/binary_file diff --git a/Makefile b/Makefile index 6d1cc1b..dadcf12 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,11 @@ test: ./$(EXECFILE) $(TEST_RULES) $(TEST_DOTFILES) $(TEST_DEST_DIR); \ fi diff $(DIFF_FLAGS) $(TEST_DEST_DIR) $(TEST_EXPECTED_DIR) - + if [ ! -x "$(TEST_DEST_DIR)/binary_file" ]; then \ + @echo "Expected binary_file to be executable."; \ + exit 1; \ + fi + @echo "*** All tests successfully passed. ***" clean: rm -f $(OBJS) diff --git a/README.md b/README.md index 275b9f5..e9bcd17 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,10 @@ Many developers store their dotfiles in git repositories, allowing them to share * Make string substitutions in files according to configuration files. * Include or exclude chunks of files according to configuration file feature flags. * Binary files are copied without templating. +* File permissions are preserved -- executable scripts will remain executable. ## Known Bugs -* File permissions are not preserved. This mostly affects executable scripts. After templating they must manually be set executable. - -Please report any bugs, difficulties, or suggestions in the issue tracker. +I fixed all I could find. Please report any bugs, difficulties, or suggestions in the issue tracker. ### Planned Features You tell me! diff --git a/dottemplater.c b/dottemplater.c index 7f67fb8..7444fd5 100644 --- a/dottemplater.c +++ b/dottemplater.c @@ -77,6 +77,7 @@ int walker(const char *fpath, const struct stat *sb, } else { copy_file(fpath, dest_file); } + copy_permission(fpath, dest_file); } free(dest_file); diff --git a/test/dotfiles/binary_file b/test/dotfiles/binary_file old mode 100644 new mode 100755 diff --git a/test/expected/binary_file b/test/expected/binary_file old mode 100644 new mode 100755 diff --git a/util.c b/util.c index 5f24e76..bdfa0f0 100644 --- a/util.c +++ b/util.c @@ -150,3 +150,14 @@ void copy_file(const char *src, const char *dest) close(input_file); close(output_file); } + +void copy_permission(const char *src, const char *dest) +{ + struct stat s; + stat(src, &s); + + if (chmod(dest, s.st_mode) < 0) { + perror("chmod"); + exit(1); + } +} diff --git a/util.h b/util.h index a1aa4e0..f055fd2 100644 --- a/util.h +++ b/util.h @@ -21,3 +21,6 @@ bool is_binary_file(const char *fpath); /** Copies a src file to a destination file.*/ void copy_file(const char *src, const char *dest); + +/** Duplicates permissions on src to dest. */ +void copy_permission(const char *src, const char *dest);