diff options
Diffstat (limited to 'src/fileops.c')
| -rw-r--r-- | src/fileops.c | 73 |
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; |
