/** * copy a directory between branches (includes all contents of the directory) */ int copy_directory(const char *path, int branch_ro, int branch_rw) { DBG("%s\n", path); /* create the directory on the destination branch */ int res = path_create(path, branch_ro, branch_rw); if (res != 0) { RETURN(res); } /* determine path to source directory on read-only branch */ char from[PATHLEN_MAX]; if (BUILD_PATH(from, uopt.branches[branch_ro].path, path)) RETURN(1); DIR *dp = opendir(from); if (dp == NULL) RETURN(1); struct dirent *de; while ((de = readdir(dp)) != NULL) { if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; char member[PATHLEN_MAX]; if (BUILD_PATH(member, path, "/", de->d_name)) { res = 1; break; } res = cow_cp(member, branch_ro, branch_rw, true); if (res != 0) break; } closedir(dp); struct stat buf; lstat(from, &buf); setfile(from, &buf); RETURN(res); }
/** * copy a directory between branches (includes all contents of the directory) */ int copy_directory(const char *path, int branch_ro, int branch_rw) { DBG_IN(); /* create the directory on the destination branch */ int res = path_create(path, branch_ro, branch_rw); if (res != 0) { return res; } /* determine path to source directory on read-only branch */ char from[PATHLEN_MAX]; if (BUILD_PATH(from, uopt.branches[branch_ro].path, path)) return 1; DIR *dp = opendir(from); if (dp == NULL) return 1; struct dirent *de; while ((de = readdir(dp)) != NULL) { if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; char member[PATHLEN_MAX]; if (BUILD_PATH(member, path, de->d_name)) return 1; res = cow_cp(member, branch_ro, branch_rw); if (res != 0) return res; } closedir(dp); return 0; }
/** * copy-one-write * Find path in a union branch and if this branch is read-only, * copy the file to a read-write branch. */ int find_rw_root_cow(const char *path) { int root_rorw = find_rorw_root(path); // not found anywhere if (root_rorw < 0) return -1; // the found root is writable, good! if (uopt.roots[root_rorw].rw) return root_rorw; // cow is disabled, return whatever was found if (!uopt.cow_enabled) return root_rorw; int root_rw = find_lowest_rw_root(root_rorw); if (root_rw < 0) { // no writable root found errno = EACCES; return -1; } if (cow_cp(path, root_rorw, root_rw)) return -1; // remove a file that might hide the copied file remove_hidden(path, root_rw); return root_rw; }