From 40b127591fe49bdb7dcf52e879a2cf1929af4a7c Mon Sep 17 00:00:00 2001
From: Yorhel <git@yorhel.nl>
Date: Tue, 23 Jan 2018 14:11:40 +0100
Subject: [PATCH] Import/export extended information

And stick to the more portable second resolution timestamps for mtime.
---
 src/dir_export.c | 18 +++++++++++++++---
 src/dir_import.c | 16 ++++++++++++++++
 src/dir_scan.c   |  2 +-
 src/global.h     |  2 +-
 4 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/dir_export.c b/src/dir_export.c
index c739197..eadccf7 100644
--- a/src/dir_export.c
+++ b/src/dir_export.c
@@ -75,6 +75,9 @@ static void output_int(uint64_t n) {
 
 
 static void output_info(struct dir *d, const char *name, struct dir_ext *e) {
+  if(!extended_info || !(d->flags & FF_EXT))
+    e = NULL;
+
   fputs("{\"name\":\"", stream);
   output_string(name);
   fputc('"', stream);
@@ -96,6 +99,17 @@ static void output_info(struct dir *d, const char *name, struct dir_ext *e) {
   fputs(",\"ino\":", stream);
   output_int(d->ino);
 
+  if(e) {
+    fputs(",\"uid\":", stream);
+    output_int(e->uid);
+    fputs(",\"gid\":", stream);
+    output_int(e->gid);
+    fputs(",\"mode\":", stream);
+    output_int(e->mode);
+    fputs(",\"mtime\":", stream);
+    output_int(e->mtime);
+  }
+
   /* TODO: Including the actual number of links would be nicer. */
   if(d->flags & FF_HLNKC)
     fputs(",\"hlnkc\":true", stream);
@@ -109,8 +123,6 @@ static void output_info(struct dir *d, const char *name, struct dir_ext *e) {
   else if(d->flags & FF_OTHFS)
     fputs(",\"excluded\":\"othfs\"", stream);
 
-  /* TODO: Output extended info if -e is given */
-
   fputc('}', stream);
 }
 
@@ -136,7 +148,7 @@ static int item(struct dir *item, const char *name, struct dir_ext *ext) {
   /* File header.
    * TODO: Add scan options? */
   if(!stack.top) {
-    fputs("[1,0,{\"progname\":\""PACKAGE"\",\"progver\":\""PACKAGE_VERSION"\",\"timestamp\":", stream);
+    fputs("[1,1,{\"progname\":\""PACKAGE"\",\"progver\":\""PACKAGE_VERSION"\",\"timestamp\":", stream);
     output_int((uint64_t)time(NULL));
     fputc('}', stream);
   }
diff --git a/src/dir_import.c b/src/dir_import.c
index 53b31f6..31e9613 100644
--- a/src/dir_import.c
+++ b/src/dir_import.c
@@ -448,6 +448,22 @@ static int iteminfo() {
     } else if(strcmp(ctx->val, "ino") == 0) {        /* ino */
       C(rint64(&iv, UINT64_MAX));
       ctx->buf_dir->ino = iv;
+    } else if(strcmp(ctx->val, "uid") == 0) {        /* uid */
+      C(rint64(&iv, INT32_MAX));
+      ctx->buf_dir->flags |= FF_EXT;
+      ctx->buf_ext->uid = iv;
+    } else if(strcmp(ctx->val, "gid") == 0) {        /* gid */
+      C(rint64(&iv, INT32_MAX));
+      ctx->buf_dir->flags |= FF_EXT;
+      ctx->buf_ext->gid = iv;
+    } else if(strcmp(ctx->val, "mode") == 0) {       /* mode */
+      C(rint64(&iv, UINT16_MAX));
+      ctx->buf_dir->flags |= FF_EXT;
+      ctx->buf_ext->mode = iv;
+    } else if(strcmp(ctx->val, "mtime") == 0) {      /* mtime */
+      C(rint64(&iv, UINT64_MAX));
+      ctx->buf_dir->flags |= FF_EXT;
+      ctx->buf_ext->mtime = iv;
     } else if(strcmp(ctx->val, "hlnkc") == 0) {      /* hlnkc */
       if(*ctx->buf == 't') {
         C(rlit("true", 4));
diff --git a/src/dir_scan.c b/src/dir_scan.c
index b0f0b1d..4b7b174 100644
--- a/src/dir_scan.c
+++ b/src/dir_scan.c
@@ -75,7 +75,7 @@ static void stat_to_dir(struct stat *fs) {
   }
 
   buf_ext->mode  = fs->st_mode;
-  buf_ext->mtime = fs->st_mtim;
+  buf_ext->mtime = fs->st_mtime;
   buf_ext->uid   = (int)fs->st_uid;
   buf_ext->gid   = (int)fs->st_gid;
 }
diff --git a/src/global.h b/src/global.h
index b998ef4..92b6eb7 100644
--- a/src/global.h
+++ b/src/global.h
@@ -85,7 +85,7 @@ struct dir {
  * memory region as struct dir, placed after the name field. See util.h for
  * macros to help manage this. */
 struct dir_ext {
-  struct timespec mtime;
+  uint64_t mtime;
   int uid, gid;
   unsigned short mode;
 };
-- 
GitLab