diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | bootstrap.conf | 1 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | m4/.gitignore | 116 | ||||
-rw-r--r-- | m4/xattr.m4 | 44 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/patch.c | 9 | ||||
-rw-r--r-- | src/util.c | 70 | ||||
-rw-r--r-- | src/util.h | 4 |
10 files changed, 251 insertions, 11 deletions
@@ -15,7 +15,6 @@ /config.status /configure /lib -/m4 /patch-*.tar.bz2 /patch-*.tar.bz2.sig /patch-*.tar.gz @@ -4,6 +4,18 @@ be set when FA_MODE is specified. (create_backup_copy): Update accordingly. + * src/patch.c (main): Set all file attributes of the temporary output + file before renaming it over the final output file (possibly replacing + the input file). Pass the input file name to set_file_attributes(). + * src/util.c (set_file_attributes): When enabled (USE_XATTR), also + copy extended attributes including attributes which define + permissions. + (copy_attr_error, copy_attr_quote, copy_attr_free, copy_attr_check, + copy_attr): Helper functions for copying extended attributes. + * m4/xattr.m4 (gl_FUNC_XATTR): Import from coreutils. + * src/Makefile.am (patch_LDADD): Add $(LIB_XATTR) here. + * bootstrap.conf: Use the gnulib verror module. + 2010-10-26 Andreas Gruenbacher <agruen@suse.de> * configure.ac: Remove obsolete checks for mktemp. diff --git a/bootstrap.conf b/bootstrap.conf index 260164d..688fde0 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -56,6 +56,7 @@ time unistd unlink utimens +verror xalloc " diff --git a/configure.ac b/configure.ac index 8912210..82e0a52 100644 --- a/configure.ac +++ b/configure.ac @@ -49,6 +49,8 @@ gl_INIT AC_TYPE_MODE_T AC_TYPE_OFF_T +gl_FUNC_XATTR + AC_CHECK_FUNCS(geteuid getuid raise sigaction sigprocmask sigsetmask) AC_FUNC_SETMODE_DOS diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 0000000..057a6a6 --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1,116 @@ +00gnulib.m4 +alloca.m4 +argmatch.m4 +backupfile.m4 +bison.m4 +canonicalize.m4 +clock_time.m4 +codeset.m4 +d-ino.m4 +dirent-safer.m4 +dirent_h.m4 +dirfd.m4 +dirname.m4 +dos.m4 +double-slash-root.m4 +dup2.m4 +eealloc.m4 +environ.m4 +errno_h.m4 +error.m4 +extensions.m4 +fcntl-o.m4 +fcntl.m4 +fcntl_h.m4 +float_h.m4 +fseek.m4 +fseeko.m4 +ftell.m4 +ftello.m4 +getdate.m4 +getdtablesize.m4 +getopt.m4 +gettime.m4 +gettimeofday.m4 +glibc21.m4 +gnulib-cache.m4 +gnulib-common.m4 +gnulib-comp.m4 +gnulib-tool.m4 +hash.m4 +include_next.m4 +inline.m4 +intmax_t.m4 +inttypes_h.m4 +lchmod.m4 +localcharset.m4 +locale-fr.m4 +locale-ja.m4 +locale-zh.m4 +longlong.m4 +lseek.m4 +lstat.m4 +malloc.m4 +malloca.m4 +mbrtowc.m4 +mbsinit.m4 +mbstate_t.m4 +memchr.m4 +minmax.m4 +mkdir.m4 +mktime.m4 +mmap-anon.m4 +multiarch.m4 +onceonly.m4 +pathmax.m4 +printf.m4 +quote.m4 +quotearg.m4 +readlink.m4 +realloc.m4 +rename.m4 +rmdir.m4 +safe-read.m4 +safe-write.m4 +setenv.m4 +size_max.m4 +ssize_t.m4 +stat-time.m4 +stat.m4 +stdarg.m4 +stdbool.m4 +stddef_h.m4 +stdint.m4 +stdint_h.m4 +stdio_h.m4 +stdlib_h.m4 +strerror.m4 +string_h.m4 +strndup.m4 +strnlen.m4 +symlink.m4 +sys_stat_h.m4 +sys_time_h.m4 +tempname.m4 +time_h.m4 +time_r.m4 +timespec.m4 +tm_gmtoff.m4 +unistd-safer.m4 +unistd_h.m4 +unlink.m4 +utimbuf.m4 +utimens.m4 +utimes.m4 +vasnprintf.m4 +vasprintf.m4 +warn-on-use.m4 +wchar_h.m4 +wchar_t.m4 +wctype_h.m4 +wint_t.m4 +write.m4 +xalloc.m4 +xsize.m4 +xstrndup.m4 +xvasprintf.m4 diff --git a/m4/xattr.m4 b/m4/xattr.m4 new file mode 100644 index 0000000..80fddbd --- /dev/null +++ b/m4/xattr.m4 @@ -0,0 +1,44 @@ +# xattr.m4 - check for Extended Attributes (Linux) +# serial 3 + +# Copyright (C) 2003, 2008-2010 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Originally written by Andreas Gruenbacher. +# http://www.suse.de/~agruen/coreutils/5.91/coreutils-xattr.diff + +AC_DEFUN([gl_FUNC_XATTR], +[ + AC_ARG_ENABLE([xattr], + AC_HELP_STRING([--disable-xattr], + [do not support extended attributes]), + [use_xattr=$enableval], [use_xattr=yes]) + + LIB_XATTR= + AC_SUBST([LIB_XATTR]) + + if test "$use_xattr" = "yes"; then + AC_CHECK_HEADERS([attr/error_context.h attr/libattr.h]) + use_xattr=no + if test $ac_cv_header_attr_libattr_h = yes \ + && test $ac_cv_header_attr_error_context_h = yes; then + xattr_saved_LIBS=$LIBS + AC_SEARCH_LIBS([attr_copy_file], [attr], + [test "$ac_cv_search_attr_copy_file" = "none required" || + LIB_XATTR=$ac_cv_search_attr_copy_file]) + AC_CHECK_FUNCS([attr_copy_file]) + LIBS=$xattr_saved_LIBS + if test $ac_cv_func_attr_copy_file = yes; then + use_xattr=yes + fi + fi + if test $use_xattr = no; then + AC_MSG_WARN([libattr development library was not found or not usable.]) + AC_MSG_WARN([AC_PACKAGE_NAME will be built without xattr support.]) + fi + fi + AC_DEFINE_UNQUOTED([USE_XATTR], [`test $use_xattr != yes; echo $?`], + [Define if you want extended attribute support.]) +]) diff --git a/src/Makefile.am b/src/Makefile.am index c1a1f9c..c119cfb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -31,7 +31,8 @@ patch_SOURCES = \ version.h AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib -patch_LDADD = $(LDADD) $(top_builddir)/lib/libpatch.a $(LIB_CLOCK_GETTIME) +patch_LDADD = $(LDADD) $(top_builddir)/lib/libpatch.a $(LIB_CLOCK_GETTIME) \ + $(LIB_XATTR) if ENABLE_MERGE patch_SOURCES += merge.c diff --git a/src/patch.c b/src/patch.c index 6d37581..77be499 100644 --- a/src/patch.c +++ b/src/patch.c @@ -476,9 +476,6 @@ main (int argc, char **argv) mode_t mode = file_type | ((new_mode ? new_mode : instat.st_mode) & S_IRWXUGO); - move_file (TMPOUTNAME, &TMPOUTNAME_needs_removal, &outst, - outname, mode, backup); - if ((set_time | set_utc) && new_time.tv_sec != -1) { struct timespec old_time = pch_timestamp (reverse); @@ -500,7 +497,11 @@ main (int argc, char **argv) } if (! inerrno) - set_file_attributes (outname, attr, &instat, mode, &new_time); + set_file_attributes (TMPOUTNAME, attr, inname, &instat, + mode, &new_time); + + move_file (TMPOUTNAME, &TMPOUTNAME_needs_removal, &outst, + outname, mode, backup); if (pch_rename ()) { @@ -42,6 +42,13 @@ #include <full-write.h> #include <tempname.h> +#ifdef USE_XATTR +# include <attr/error_context.h> +# include <attr/libattr.h> +# include <stdarg.h> +# include "verror.h" +#endif + static void makedirs (char const *); typedef struct @@ -123,9 +130,64 @@ contains_slash (const char *s) return false; } +#ifdef USE_XATTR + +static void +copy_attr_error (struct error_context *ctx, char const *fmt, ...) +{ + int err = errno; + va_list ap; + + /* use verror module to print error message */ + va_start (ap, fmt); + verror (0, err, fmt, ap); + va_end (ap); +} + +static char const * +copy_attr_quote (struct error_context *ctx, char const *str) +{ + return quotearg (str); +} + +static void +copy_attr_free (struct error_context *ctx, char const *str) +{ +} + +static int +copy_attr_check (const char *name, struct error_context *ctx) +{ + int action = attr_copy_action (name, ctx); + return action == 0 || action == ATTR_ACTION_PERMISSIONS; +} + +static int +copy_attr (char const *src_path, char const *dst_path) +{ + struct error_context ctx = + { + .error = copy_attr_error, + .quote = copy_attr_quote, + .quote_free = copy_attr_free + }; + return attr_copy_file (src_path, dst_path, copy_attr_check, &ctx); +} + +#else /* USE_XATTR */ + +static int +copy_attr (char const *src_path, char const *dst_path) +{ + return 0; +} + +#endif + void set_file_attributes (char const *to, enum file_attributes attr, - struct stat *st, mode_t mode, struct timespec *new_time) + char const *from, struct stat *st, mode_t mode, + struct timespec *new_time) { if (attr & FA_TIMES) { @@ -170,6 +232,9 @@ set_file_attributes (char const *to, enum file_attributes attr, S_ISLNK (st->st_mode) ? "symbolic link" : "file", quotearg (to)); } + if (copy_attr (from, to)) + fatal_exit (0); + /* FIXME: There may be other attributes to preserve. */ if (attr & FA_MODE) { #if 0 && defined HAVE_LCHMOD @@ -184,7 +249,6 @@ set_file_attributes (char const *to, enum file_attributes attr, S_ISLNK (st->st_mode) ? "symbolic link" : "file", quotearg (to)); } - /* FIXME: There may be other attributes to preserve. */ } static void @@ -196,7 +260,7 @@ create_backup_copy (char const *from, char const *to, struct stat *st, to_dir_known_to_exist); if (remember_backup) insert_file (&backup_st); - set_file_attributes (to, FA_TIMES | FA_IDS | FA_MODE, st, st->st_mode, NULL); + set_file_attributes (to, FA_TIMES | FA_IDS | FA_MODE, from, st, st->st_mode, NULL); } void @@ -70,8 +70,8 @@ enum file_attributes { FA_MODE = 4 }; -void set_file_attributes (char const *, enum file_attributes, struct stat *, - mode_t, struct timespec *); +void set_file_attributes (char const *, enum file_attributes, char const *, + struct stat *, mode_t, struct timespec *); static inline char const * skip_spaces (char const *str) |