8 static string get_string(FILE *f,const char *fn,const char *what) {
10 char *got=fgets(buf,sizeof(buf),f);
12 fatal("Error reading %s from %s: %m",what,fn);
13 char *s(strchr(buf,'\n'));
15 fatal("Stored %s in %s is not newline-terminated",what,fn);
21 // https://stackoverflow.com/a/8615450/2995591
22 #include <glob.h> // glob(), globfree()
23 #include <cstring> // memset()
27 int main(int argc,char **argv) {
29 fatal("streamfer-client <host>:<port> <pattern> <last storage file>");
30 int server_fd(socket_connect(string(argv[1]),0/*retries*/));
31 string pattern(argv[2]);
32 write_safe(server_fd,pattern);
34 const char *last_stored_fn(argv[3]);
35 FILE *last_stored_f(fopen(last_stored_fn,"r"));
39 fatal("Error opening filename from %s: %m",last_stored_fn);
41 last_found= get_string(last_stored_f,last_stored_fn,"filename") ;
42 string offsetstr(get_string(last_stored_f,last_stored_fn,"offset" ));
45 unsigned long ul(strtoul(offsetstr.c_str(),&end,0));
46 if (errno||(end&&*end))
47 fatal("Error converting offset from %s: %s",last_stored_fn,offsetstr.c_str());
49 int gotint(fgetc(last_stored_f));
51 fatal("Stored filename in %s has excessive data after filename %s and offset %s",last_stored_fn,last_found.c_str(),offsetstr.c_str());
52 int err(fclose(last_stored_f));
55 write_safe(server_fd,last_found);
56 write_safe(server_fd,offset);
58 read_safe(server_fd,last_got);
59 if (last_got.empty()) {
60 warning("No more files to transfer");
64 read_safe(server_fd,mtim);
67 size_t slash(last_got.find_last_of('/'));
68 if (slash!=string::npos)
69 file_name=last_got.substr(slash+1);
72 if (last_found==last_got) {
73 file_fd=open(file_name.c_str(),O_WRONLY);
75 fatal("Error opening for write %s: %m",file_name.c_str());
76 off_t got(lseek(file_fd,offset,SEEK_SET));
77 if ((uint64_t)got!=offset)
78 fatal("Error seeking in %s to %zu, got: %zu",file_name.c_str(),(size_t)offset,(size_t)got);
81 file_fd=open(file_name.c_str(),O_WRONLY|O_CREAT,0644);
83 fatal("Error creating %s: %m",file_name.c_str());
85 uint64_t transferred(transfer(server_fd,"server fd",file_fd,file_name.c_str()));
89 struct timespec mtim2[2];
90 mtim2[0]=mtim; // atime
91 mtim2[1]=mtim; // mtime
92 if (futimens(file_fd,mtim2))
93 fatal("Error setting timestamp of %s: %m",file_name.c_str());
95 fatal("Error closing %s: %m",file_name.c_str());
96 int last_stored_fd(open(last_stored_fn,O_WRONLY|O_CREAT|O_TRUNC,0644));
97 if (last_stored_fd==-1)
98 fatal("Error storing filename to %s: %m",last_stored_fn);
99 write_safe(last_stored_fd,last_got.c_str(),last_got.length());
100 write_safe(last_stored_fd,'\n');
101 string offsetstr(stringf("%zu",(size_t)offset));
102 write_safe(last_stored_fd,offsetstr.c_str(),offsetstr.length());
103 write_safe(last_stored_fd,'\n');
104 if (close(last_stored_fd))
105 fatal("Error closing %s: %m",last_stored_fn);