summaryrefslogtreecommitdiff
path: root/src/fileops.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fileops.c')
-rw-r--r--src/fileops.c73
1 files changed, 29 insertions, 44 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 5a5041cc3..be2e53ca8 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -398,8 +398,11 @@ typedef struct {
size_t baselen;
uint32_t flags;
int error;
+ int depth;
} futils__rmdir_data;
+#define FUTILS_MAX_DEPTH 100
+
static int futils__error_cannot_rmdir(const char *path, const char *filemsg)
{
if (filemsg)
@@ -441,7 +444,12 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
struct stat st;
futils__rmdir_data *data = opaque;
- if ((data->error = p_lstat_posixly(path->ptr, &st)) < 0) {
+ if (data->depth > FUTILS_MAX_DEPTH) {
+ data->error =
+ futils__error_cannot_rmdir(path->ptr, "directory nesting too deep");
+ }
+
+ else if ((data->error = p_lstat_posixly(path->ptr, &st)) < 0) {
if (errno == ENOENT)
data->error = 0;
else if (errno == ENOTDIR) {
@@ -457,9 +465,19 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
}
else if (S_ISDIR(st.st_mode)) {
- int error = git_path_direach(path, futils__rmdir_recurs_foreach, data);
- if (error < 0)
- return (error == GIT_EUSER) ? data->error : error;
+ data->depth++;
+
+ {
+ int error =
+ git_path_direach(path, 0, futils__rmdir_recurs_foreach, data);
+ if (error < 0)
+ return (error == GIT_EUSER) ? data->error : error;
+ }
+
+ data->depth--;
+
+ if (data->depth == 0 && (data->flags & GIT_RMDIR_SKIP_ROOT) != 0)
+ return data->error;
data->error = p_rmdir(path->ptr);
@@ -517,7 +535,7 @@ int git_futils_rmdir_r(
{
int error;
git_buf fullpath = GIT_BUF_INIT;
- futils__rmdir_data data;
+ futils__rmdir_data data = { 0 };
/* build path and find "root" where we should start calling mkdir */
if (git_path_join_unrooted(&fullpath, path, base, NULL) < 0)
@@ -526,7 +544,6 @@ int git_futils_rmdir_r(
data.base = base ? base : "";
data.baselen = base ? strlen(base) : 0;
data.flags = flags;
- data.error = 0;
error = futils__rmdir_recurs_foreach(&data, &fullpath);
@@ -544,41 +561,6 @@ int git_futils_rmdir_r(
return error;
}
-int git_futils_cleanupdir_r(const char *path)
-{
- int error;
- git_buf fullpath = GIT_BUF_INIT;
- futils__rmdir_data data;
-
- if ((error = git_buf_put(&fullpath, path, strlen(path))) < 0)
- goto clean_up;
-
- data.base = "";
- data.baselen = 0;
- data.flags = GIT_RMDIR_REMOVE_FILES;
- data.error = 0;
-
- if (!git_path_exists(path)) {
- giterr_set(GITERR_OS, "Path does not exist: %s" , path);
- error = GIT_ERROR;
- goto clean_up;
- }
-
- if (!git_path_isdir(path)) {
- giterr_set(GITERR_OS, "Path is not a directory: %s" , path);
- error = GIT_ERROR;
- goto clean_up;
- }
-
- error = git_path_direach(&fullpath, futils__rmdir_recurs_foreach, &data);
- if (error == GIT_EUSER)
- error = data.error;
-
-clean_up:
- git_buf_free(&fullpath);
- return error;
-}
-
static int git_futils_guess_system_dirs(git_buf *out)
{
@@ -948,9 +930,12 @@ static int _cp_r_callback(void *ref, git_buf *from)
error = _cp_r_mkdir(info, from);
/* recurse onto target directory */
- if (!error && (!exists || S_ISDIR(to_st.st_mode)) &&
- ((error = git_path_direach(from, _cp_r_callback, info)) == GIT_EUSER))
- error = info->error;
+ if (!error && (!exists || S_ISDIR(to_st.st_mode))) {
+ error = git_path_direach(from, 0, _cp_r_callback, info);
+
+ if (error == GIT_EUSER)
+ error = info->error;
+ }
if (oldmode != 0)
info->dirmode = oldmode;