afh: Implement --preserve.
[paraslash.git] / afh.c
diff --git a/afh.c b/afh.c
index 4955b3cfea12e6e7abf93b672d4501cb1e46ca85..ffb4315b0d41e7087aa03ee7b353e7f690989126 100644 (file)
--- a/afh.c
+++ b/afh.c
@@ -1,8 +1,4 @@
-/*
- * Copyright (C) 2008 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 2008 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
 
 /** \file afh.c Paraslash's standalone audio format handler tool. */
 
@@ -20,7 +16,7 @@
 /** Array of error strings. */
 DEFINE_PARA_ERRLIST;
 
-struct lls_parse_result *lpr;
+static struct lls_parse_result *lpr;
 
 #define CMD_PTR (lls_cmd(0, afh_suite))
 #define OPT_RESULT(_name) (lls_opt_result(LSG_AFH_PARA_AFH_OPT_ ## _name, lpr))
@@ -117,6 +113,24 @@ static int rewrite_tags(const char *name, int input_fd, void *map,
                        goto out;
        }
        ret = xrename(tmp_name, name);
+       if (ret < 0)
+               goto out;
+       if (OPT_GIVEN(PRESERVE)) {
+               struct timespec times[2]; /* [0]: atime, [1]: mtime */
+               times[0].tv_nsec = UTIME_OMIT;
+               times[1] = sb.st_mtim;
+               /*
+                * We might well have written a file of identical size. If we
+                * keep the mtime as well, we might fool backup applications
+                * like rsync which skip files whose size and mtime haven't
+                * changed. So we change the mtime slightly.
+                */
+               times[1].tv_sec++;
+               if (futimens(output_fd, times) < 0) {
+                       ret = -ERRNO_TO_PARA_ERROR(errno);
+                       goto out;
+               }
+       }
 out:
        if (ret < 0 && output_fd >= 0)
                unlink(tmp_name); /* ignore errors */