int git_path_direach( git_buf *path, int (*fn)(void *, git_buf *), void *arg) { ssize_t wd_len; DIR *dir; struct dirent *de, *de_buf; if (git_path_to_dir(path) < 0) return -1; wd_len = git_buf_len(path); if ((dir = opendir(path->ptr)) == NULL) { giterr_set(GITERR_OS, "Failed to open directory '%s'", path->ptr); return -1; } #ifdef __sun de_buf = git__malloc(sizeof(struct dirent) + FILENAME_MAX + 1); #else de_buf = git__malloc(sizeof(struct dirent)); #endif while (p_readdir_r(dir, de_buf, &de) == 0 && de != NULL) { int result; if (is_dot_or_dotdot(de->d_name)) continue; if (git_buf_puts(path, de->d_name) < 0) { closedir(dir); git__free(de_buf); return -1; } result = fn(arg, path); git_buf_truncate(path, wd_len); /* restore path */ if (result < 0) { closedir(dir); git__free(de_buf); return -1; } } closedir(dir); git__free(de_buf); return 0; }
int git_path_direach( git_buf *path, uint32_t flags, int (*fn)(void *, git_buf *), void *arg) { int error = 0; ssize_t wd_len; DIR *dir; path_dirent_data de_data; struct dirent *de, *de_buf = (struct dirent *)&de_data; #ifdef GIT_USE_ICONV git_path_iconv_t ic = GIT_PATH_ICONV_INIT; #endif GIT_UNUSED(flags); if (git_path_to_dir(path) < 0) return -1; wd_len = git_buf_len(path); if ((dir = opendir(path->ptr)) == NULL) { giterr_set(GITERR_OS, "Failed to open directory '%s'", path->ptr); if (errno == ENOENT) return GIT_ENOTFOUND; return -1; } #ifdef GIT_USE_ICONV if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0) (void)git_path_iconv_init_precompose(&ic); #endif while (p_readdir_r(dir, de_buf, &de) == 0 && de != NULL) { char *de_path = de->d_name; size_t de_len = strlen(de_path); if (git_path_is_dot_or_dotdot(de_path)) continue; #ifdef GIT_USE_ICONV if ((error = git_path_iconv(&ic, &de_path, &de_len)) < 0) break; #endif if ((error = git_buf_put(path, de_path, de_len)) < 0) break; error = fn(arg, path); git_buf_truncate(path, wd_len); /* restore path */ if (error != 0) { giterr_set_after_callback(error); break; } } closedir(dir); #ifdef GIT_USE_ICONV git_path_iconv_clear(&ic); #endif return error; }
int git_path_dirload( const char *path, size_t prefix_len, size_t alloc_extra, unsigned int flags, git_vector *contents) { int error; DIR *dir; size_t path_len; path_dirent_data de_data; struct dirent *de, *de_buf = (struct dirent *)&de_data; #ifdef GIT_USE_ICONV git_path_iconv_t ic = GIT_PATH_ICONV_INIT; #endif GIT_UNUSED(flags); assert(path && contents); path_len = strlen(path); if (!path_len || path_len < prefix_len) { giterr_set(GITERR_INVALID, "Invalid directory path '%s'", path); return -1; } if ((dir = opendir(path)) == NULL) { giterr_set(GITERR_OS, "Failed to open directory '%s'", path); return -1; } #ifdef GIT_USE_ICONV if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0) (void)git_path_iconv_init_precompose(&ic); #endif path += prefix_len; path_len -= prefix_len; while ((error = p_readdir_r(dir, de_buf, &de)) == 0 && de != NULL) { char *entry_path, *de_path = de->d_name; size_t de_len = strlen(de_path); if (git_path_is_dot_or_dotdot(de_path)) continue; #ifdef GIT_USE_ICONV if ((error = git_path_iconv(&ic, &de_path, &de_len)) < 0) break; #endif if ((error = entry_path_alloc(&entry_path, path, path_len, de_path, de_len, alloc_extra)) < 0) break; if ((error = git_vector_insert(contents, entry_path)) < 0) { git__free(entry_path); break; } } closedir(dir); #ifdef GIT_USE_ICONV git_path_iconv_clear(&ic); #endif if (error != 0) giterr_set(GITERR_OS, "Failed to process directory entry in '%s'", path); return error; }
int git_path_dirload( const char *path, size_t prefix_len, size_t alloc_extra, git_vector *contents) { int error, need_slash; DIR *dir; struct dirent *de, *de_buf; size_t path_len; assert(path != NULL && contents != NULL); path_len = strlen(path); assert(path_len > 0 && path_len >= prefix_len); if ((dir = opendir(path)) == NULL) { giterr_set(GITERR_OS, "Failed to open directory '%s'", path); return -1; } #ifdef __sun de_buf = git__malloc(sizeof(struct dirent) + FILENAME_MAX + 1); #else de_buf = git__malloc(sizeof(struct dirent)); #endif path += prefix_len; path_len -= prefix_len; need_slash = (path_len > 0 && path[path_len-1] != '/') ? 1 : 0; while ((error = p_readdir_r(dir, de_buf, &de)) == 0 && de != NULL) { char *entry_path; size_t entry_len; if (is_dot_or_dotdot(de->d_name)) continue; entry_len = strlen(de->d_name); entry_path = git__malloc( path_len + need_slash + entry_len + 1 + alloc_extra); GITERR_CHECK_ALLOC(entry_path); if (path_len) memcpy(entry_path, path, path_len); if (need_slash) entry_path[path_len] = '/'; memcpy(&entry_path[path_len + need_slash], de->d_name, entry_len); entry_path[path_len + need_slash + entry_len] = '\0'; if (git_vector_insert(contents, entry_path) < 0) { closedir(dir); git__free(de_buf); return -1; } } closedir(dir); git__free(de_buf); if (error != 0) giterr_set(GITERR_OS, "Failed to process directory entry in '%s'", path); return error; }
int git_path_dirload( const char *path, size_t prefix_len, size_t alloc_extra, unsigned int flags, git_vector *contents) { int error, need_slash; DIR *dir; size_t path_len; path_dirent_data de_data; struct dirent *de, *de_buf = (struct dirent *)&de_data; (void)flags; #ifdef GIT_USE_ICONV git_path_iconv_t ic = GIT_PATH_ICONV_INIT; #endif assert(path && contents); path_len = strlen(path); if (!path_len || path_len < prefix_len) { giterr_set(GITERR_INVALID, "Invalid directory path '%s'", path); return -1; } if ((dir = opendir(path)) == NULL) { giterr_set(GITERR_OS, "Failed to open directory '%s'", path); return -1; } #ifdef GIT_USE_ICONV if ((flags & GIT_PATH_DIR_PRECOMPOSE_UNICODE) != 0) (void)git_path_iconv_init_precompose(&ic); #endif path += prefix_len; path_len -= prefix_len; need_slash = (path_len > 0 && path[path_len-1] != '/') ? 1 : 0; while ((error = p_readdir_r(dir, de_buf, &de)) == 0 && de != NULL) { char *entry_path, *de_path = de->d_name; size_t alloc_size, de_len = strlen(de_path); if (git_path_is_dot_or_dotdot(de_path)) continue; #ifdef GIT_USE_ICONV if ((error = git_path_iconv(&ic, &de_path, &de_len)) < 0) break; #endif alloc_size = path_len + need_slash + de_len + 1 + alloc_extra; if ((entry_path = git__calloc(alloc_size, 1)) == NULL) { error = -1; break; } if (path_len) memcpy(entry_path, path, path_len); if (need_slash) entry_path[path_len] = '/'; memcpy(&entry_path[path_len + need_slash], de_path, de_len); if ((error = git_vector_insert(contents, entry_path)) < 0) break; } closedir(dir); #ifdef GIT_USE_ICONV git_path_iconv_clear(&ic); #endif if (error != 0) giterr_set(GITERR_OS, "Failed to process directory entry in '%s'", path); return error; }