src/streamfer*: Fix timestamps.
authorJan Kratochvil <jan@jankratochvil.net>
Wed, 27 Dec 2023 01:26:06 +0000 (09:26 +0800)
committerJan Kratochvil <jan@jankratochvil.net>
Wed, 27 Dec 2023 01:26:06 +0000 (09:26 +0800)
src/streamfer-client.C
src/streamfer-server.C

index e998ffd..ce4e923 100644 (file)
@@ -18,11 +18,25 @@ static string get_string(FILE *f,const char *fn,const char *what) {
   return buf;
 }
 
-// https://stackoverflow.com/a/8615450/2995591
-#include <glob.h> // glob(), globfree()
-#include <cstring> // memset()
-#include <vector>
-#include <string>
+static void last_stored_write(const char *last_stored_fn,const string &filename,uint64_t offset) {
+  int last_stored_fd(open(last_stored_fn,O_WRONLY|O_CREAT|O_TRUNC,0644));
+  if (last_stored_fd==-1)
+    fatal("Error storing filename to %s: %m",last_stored_fn);
+  write_safe(last_stored_fd,filename.c_str(),filename.length());
+  write_safe(last_stored_fd,'\n');
+  string offsetstr(stringf("%zu",(size_t)offset));
+  write_safe(last_stored_fd,offsetstr.c_str(),offsetstr.length());
+  write_safe(last_stored_fd,'\n');
+  if (close(last_stored_fd))
+    fatal("Error closing %s: %m",last_stored_fn);
+}
+
+static string my_basename(const string &path) {
+  size_t slash(path.find_last_of('/'));
+  if (slash!=string::npos)
+    return path.substr(slash+1);
+  return path;
+}
 
 int main(int argc,char **argv) {
   if (argc!=1+3)
@@ -54,8 +68,20 @@ int main(int argc,char **argv) {
   }
   write_safe(server_fd,last_found);
   write_safe(server_fd,offset);
+  { struct stat statbuf;
+    string last_found_basename(my_basename(last_found));
+    if (stat(last_found_basename.c_str(),&statbuf)) {
+      static const struct timespec mtim_zero{};
+      write_safe(server_fd,mtim_zero);
+    } else
+      write_safe(server_fd,statbuf.st_mtim);
+  }
   string last_got;
-  read_safe(server_fd,last_got);
+  try {
+    read_safe(server_fd,last_got);
+  } catch (SafeIOError) {
+    fatal("SafeIOError reading from the server %s",argv[1]);
+  }
   if (last_got.empty()) {
     warning("No more files to transfer");
     exit(EXIT_SUCCESS);
@@ -63,12 +89,7 @@ int main(int argc,char **argv) {
   struct timespec mtim;
   read_safe(server_fd,mtim);
   int file_fd;
-  string file_name;
-  size_t slash(last_got.find_last_of('/'));
-  if (slash!=string::npos)
-    file_name=last_got.substr(slash+1);
-  else
-    file_name=last_got;
+  string file_name(my_basename(last_got));;
   if (last_found==last_got) {
     file_fd=open(file_name.c_str(),O_WRONLY);
     if (file_fd==-1)
@@ -82,9 +103,15 @@ int main(int argc,char **argv) {
     if (file_fd==-1)
       fatal("Error creating %s: %m",file_name.c_str());
   }
+  last_stored_write(last_stored_fn,last_got,offset);
   uint64_t transferred(transfer(server_fd,"server fd",file_fd,file_name.c_str()));
-  if (!transferred)
-    return EXIT_FAILURE;
+  if (!transferred) {
+    struct stat statbuf;
+    int err(fstat(file_fd,&statbuf));
+    assert(!err);
+    if (memcmp(&mtim,&statbuf.st_mtim,sizeof(mtim))==0)
+      return EXIT_FAILURE;
+  }
   offset+=transferred;
   struct timespec mtim2[2];
   mtim2[0]=mtim; // atime
@@ -93,15 +120,6 @@ int main(int argc,char **argv) {
     fatal("Error setting timestamp of %s: %m",file_name.c_str());
   if (close(file_fd))
     fatal("Error closing %s: %m",file_name.c_str());
-  int last_stored_fd(open(last_stored_fn,O_WRONLY|O_CREAT|O_TRUNC,0644));
-  if (last_stored_fd==-1)
-    fatal("Error storing filename to %s: %m",last_stored_fn);
-  write_safe(last_stored_fd,last_got.c_str(),last_got.length());
-  write_safe(last_stored_fd,'\n');
-  string offsetstr(stringf("%zu",(size_t)offset));
-  write_safe(last_stored_fd,offsetstr.c_str(),offsetstr.length());
-  write_safe(last_stored_fd,'\n');
-  if (close(last_stored_fd))
-    fatal("Error closing %s: %m",last_stored_fn);
+  last_stored_write(last_stored_fn,last_got,offset);
   return EXIT_SUCCESS;
 }
index dedb9f3..5a0bd8a 100644 (file)
@@ -145,6 +145,8 @@ int main(int argc,char **argv) {
     fatal("Requested too new file");
   uint64_t offset;
   read_safe(client_fd,offset);
+  struct timespec mtim;
+  read_safe(client_fd,mtim);
   const string *fnp;
   int file_fd=-1;
   struct stat statbuf;
@@ -161,6 +163,9 @@ int main(int argc,char **argv) {
     assert(!err);
     if (offset<(uint64_t)statbuf.st_size)
       break;
+    static const struct timespec mtim_zero{};
+    if (memcmp(&mtim,&mtim_zero,sizeof(mtim))!=0&&memcmp(&mtim,&statbuf.st_mtim,sizeof(mtim))!=0)
+      break;
     if (offset>(uint64_t)statbuf.st_size)
       warning("File %s has transferred %zu < %zu which is its size",fn.c_str(),(size_t)offset,(size_t)statbuf.st_size);
     if (lastix==matched.size()-1&&execname)