summaryrefslogtreecommitdiff
path: root/src/archive.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/archive.c')
-rw-r--r--src/archive.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/src/archive.c b/src/archive.c
index 8ffb921..5c1eb91 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -14,6 +14,7 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <utime.h>
#include <malloc.h>
#include <string.h>
#include <unistd.h>
@@ -194,6 +195,7 @@ int apk_archive_entry_extract(const struct apk_file_info *ae,
const char *fn, apk_progress_cb cb,
void *cb_ctx)
{
+ struct utimbuf utb;
int r = -1, fd;
if (fn == NULL)
@@ -238,17 +240,34 @@ int apk_archive_entry_extract(const struct apk_file_info *ae,
r = chown(fn, ae->uid, ae->gid);
else
r = lchown(fn, ae->uid, ae->gid);
- if (r < 0)
- apk_error("Failed to set ownership on %s: %s", fn,
- strerror(errno));
+ if (r < 0) {
+ apk_error("Failed to set ownership on %s: %s",
+ fn, strerror(errno));
+ return -errno;
+ }
+
/* chown resets suid bit so we need set it again */
- if (ae->mode & 07000)
+ if (ae->mode & 07000) {
r = chmod(fn, ae->mode & 07777);
- if (r < 0)
- apk_error("Failed to set file permissions on %s: %s",
+ if (r < 0) {
+ apk_error("Failed to set file permissions "
+ "on %s: %s",
+ fn, strerror(errno));
+ return -errno;
+ }
+ }
+
+ /* preserve modification time */
+ utb.actime = utb.modtime = ae->mtime;
+ r = utime(fn, &utb);
+ if (r < 0) {
+ apk_error("Failed to preserve modification time on %s: %s",
fn, strerror(errno));
+ return -errno;
+ }
} else {
- apk_error("Failed to extract %s\n", ae->name);
+ apk_error("Failed to extract %s: %s", ae->name, strerror(errno));
+ return -errno;
}
- return r;
+ return 0;
}