#include #include #include #include #include #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] = '/'; } }