X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fcreate.c;h=4cd5980856b580620f0d039d84f6deadb94ee596;hb=ab3b31cfef3e33696596f459da5130256b5ec60f;hp=b7b41c425086c38eb39cb289a3db06d0ec29f6a0;hpb=c50565d9655329deb983c3df5b151d1fe2032953;p=chaz%2Ftar diff --git a/src/create.c b/src/create.c index b7b41c4..4cd5980 100644 --- a/src/create.c +++ b/src/create.c @@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "system.h" +#include #if HAVE_UTIME_H # include @@ -922,6 +922,47 @@ dump_regular_finish (int fd, struct tar_stat_info *st, time_t original_ctime) } } +/* Look in directory DIRNAME for a cache directory tag file + with the magic name "CACHEDIR.TAG" and a standard header, + as described at: + http://www.brynosaurus.com/cachedir + Applications can write this file into directories they create + for use as caches containing purely regenerable, non-precious data, + allowing us to avoid archiving them if --exclude-caches is specified. */ + +#define CACHEDIR_SIGNATURE "Signature: 8a477f597d28d172789f06886806bc55" +#define CACHEDIR_SIGNATURE_SIZE (sizeof CACHEDIR_SIGNATURE - 1) + +static bool +check_cache_directory (char *dirname) +{ + static char tagname[] = "CACHEDIR.TAG"; + char *tagpath; + int fd; + int tag_present = false; + + tagpath = xmalloc (strlen (dirname) + strlen (tagname) + 1); + strcpy (tagpath, dirname); + strcat (tagpath, tagname); + + fd = open (tagpath, O_RDONLY); + if (fd >= 0) + { + static char tagbuf[CACHEDIR_SIGNATURE_SIZE]; + + if (read (fd, tagbuf, CACHEDIR_SIGNATURE_SIZE) + == CACHEDIR_SIGNATURE_SIZE + && memcmp (tagbuf, CACHEDIR_SIGNATURE, CACHEDIR_SIGNATURE_SIZE) == 0) + tag_present = true; + + close (fd); + } + + free (tagpath); + + return tag_present; +} + static void dump_dir0 (char *directory, struct tar_stat_info *st, int top_level, dev_t parent_device) @@ -1012,6 +1053,16 @@ dump_dir0 (char *directory, return; } + if (exclude_caches_option + && check_cache_directory(st->orig_file_name)) + { + if (verbose_option) + WARN ((0, 0, + _("%s: contains a cache directory tag; not dumped"), + quotearg_colon (st->orig_file_name))); + return; + } + { char const *entry; size_t entry_len; @@ -1322,16 +1373,19 @@ dump_file0 (struct tar_stat_info *st, char *p, #endif /* See if we want only new files, and check if this one is too old to - put in the archive. */ + put in the archive. - if (!S_ISDIR (st->stat.st_mode) + This check is omitted if incremental_option is set *and* the + requested file is not explicitely listed in the command line. */ + + if (!(incremental_option && !is_individual_file (p)) + && !S_ISDIR (st->stat.st_mode) && OLDER_STAT_TIME (st->stat, m) && (!after_date_option || OLDER_STAT_TIME (st->stat, c))) { - if (0 < top_level) /* equivalent to !incremental_option */ + if (!incremental_option) WARN ((0, 0, _("%s: file is unchanged; not dumped"), quotearg_colon (p))); - /* FIXME: recheck this return. */ return; }