diff options
Diffstat (limited to 'src/backup_streamer.c')
| -rw-r--r-- | src/backup_streamer.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/backup_streamer.c b/src/backup_streamer.c new file mode 100644 index 0000000..3b5929b --- /dev/null +++ b/src/backup_streamer.c @@ -0,0 +1,54 @@ +#include <unistd.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <assert.h> +#include <string.h> + +#include "lib.h" + +struct backup_streamer backup_streamer_init(char *cwd) { + struct backup_streamer output; + output.cwd_length = strnlen(cwd, PATH_MAX); + char *end = stpncpy(output.to_prefix, cwd, PATH_MAX - 3); + *(end++) = '.'; + *(end++) = 'b'; + *(end++) = 'k'; + *(end++) = 0; + return output; +} + +void get_backup_destination(struct backup_streamer *streamer, char* from) { + char *cursor = stpncpy(streamer->cursor, streamer->to_prefix, PATH_MAX); + from += streamer->cwd_length; + int n = (cursor - streamer->cursor) - 2; + strncpy(cursor, from, PATH_MAX - n); +} + +int is_dir(char *path) { + struct stat info; + if (stat(path, &info) != 0) return -1; + return S_ISDIR(info.st_mode); +} + +void backup_file(char *from, char *to) { + ensure_parents_exist(to); + pid_t pid; + if ((pid = fork()) == 0) { + char *argv[] = {"/usr/bin/cp", from, to, NULL}; + execv(argv[0], argv); + } + assert(waitpid(pid, NULL, 0) != -1); +} + +void ensure_parents_exist(char *path) { + int n = strnlen(path, PATH_MAX); + for (int i = 1; i < n; i++) { + if (path[i] != '/') continue; + path[i] = 0; + if (is_dir(path) == -1) { + debugf("mkdir %s\n", path); + assert(mkdir(path, 0755) != -1); + } + path[i] = '/'; + } +} |
