Merge "file.c/__ast_file_read_dirs: Fix issues on filesystems without d_type" into certified/13.8

changes/14/4814/2
George Joseph 8 years ago committed by Gerrit Code Review
commit 4574a24429

@ -1095,27 +1095,27 @@ int ast_filecopy(const char *filename, const char *filename2, const char *fmt)
return filehelper(filename, filename2, fmt, ACTION_COPY);
}
static int __ast_file_read_dirs(struct ast_str **path, ast_file_on_file on_file,
static int __ast_file_read_dirs(const char *path, ast_file_on_file on_file,
void *obj, int max_depth)
{
DIR *dir;
struct dirent *entry;
size_t size;
int res;
if (!(dir = opendir(ast_str_buffer(*path)))) {
if (!(dir = opendir(path))) {
ast_log(LOG_ERROR, "Error opening directory - %s: %s\n",
ast_str_buffer(*path), strerror(errno));
path, strerror(errno));
return -1;
}
size = ast_str_strlen(*path);
--max_depth;
res = 0;
while ((entry = readdir(dir)) != NULL && !errno) {
int is_file, is_dir, used_stat = 0;
int is_file = 0;
int is_dir = 0;
RAII_VAR(char *, full_path, NULL, ast_free);
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
continue;
@ -1136,16 +1136,18 @@ static int __ast_file_read_dirs(struct ast_str **path, ast_file_on_file on_file,
struct stat statbuf;
/*
* If using the stat function the file needs to be appended to the
* path so it can be found. However, before appending make sure the
* path contains only the directory for this depth level.
* Don't use alloca or we risk blowing out the stack if recursing
* into subdirectories.
*/
ast_str_truncate(*path, size);
ast_str_append(path, 0, "/%s", entry->d_name);
full_path = ast_malloc(strlen(path) + strlen(entry->d_name) + 2);
if (!full_path) {
return -1;
}
sprintf(full_path, "%s/%s", path, entry->d_name);
if (stat(ast_str_buffer(*path), &statbuf)) {
if (stat(full_path, &statbuf)) {
ast_log(LOG_ERROR, "Error reading path stats - %s: %s\n",
ast_str_buffer(*path), strerror(errno));
full_path, strerror(errno));
/*
* Output an error, but keep going. It could just be
* a broken link and other files could be fine.
@ -1155,12 +1157,11 @@ static int __ast_file_read_dirs(struct ast_str **path, ast_file_on_file on_file,
is_file = S_ISREG(statbuf.st_mode);
is_dir = S_ISDIR(statbuf.st_mode);
used_stat = 1;
}
if (is_file) {
/* If the handler returns non-zero then stop */
if ((res = on_file(ast_str_buffer(*path), entry->d_name, obj))) {
if ((res = on_file(path, entry->d_name, obj))) {
break;
}
/* Otherwise move on to next item in directory */
@ -1168,23 +1169,22 @@ static int __ast_file_read_dirs(struct ast_str **path, ast_file_on_file on_file,
}
if (!is_dir) {
ast_debug(5, "Skipping %s: not a regular file or directory\n",
ast_str_buffer(*path));
ast_debug(5, "Skipping %s: not a regular file or directory\n", full_path);
continue;
}
/* Only re-curse into sub-directories if not at the max depth */
if (max_depth != 0) {
/*
* If the stat function was used then the sub-directory has
* already been appended, otherwise append it.
*/
if (!used_stat) {
ast_str_truncate(*path, size);
ast_str_append(path, 0, "/%s", entry->d_name);
if (!full_path) {
/* Don't use alloca. See note above. */
full_path = ast_malloc(strlen(path) + strlen(entry->d_name) + 2);
if (!full_path) {
return -1;
}
sprintf(full_path, "%s/%s", path, entry->d_name);
}
if ((res = __ast_file_read_dirs(path, on_file, obj, max_depth))) {
if ((res = __ast_file_read_dirs(full_path, on_file, obj, max_depth))) {
break;
}
}
@ -1194,7 +1194,7 @@ static int __ast_file_read_dirs(struct ast_str **path, ast_file_on_file on_file,
if (!res && errno) {
ast_log(LOG_ERROR, "Error while reading directories - %s: %s\n",
ast_str_buffer(*path), strerror(errno));
path, strerror(errno));
res = -1;
}
@ -1215,27 +1215,20 @@ AST_MUTEX_DEFINE_STATIC(read_dirs_lock);
int ast_file_read_dirs(const char *dir_name, ast_file_on_file on_file, void *obj, int max_depth)
{
struct ast_str *path;
int res;
if (!(path = ast_str_create(256))) {
return -1;
}
ast_str_set(&path, 0, "%s", dir_name);
errno = 0;
#if !defined(__GLIBC__)
ast_mutex_lock(&read_dirs_lock);
#endif
res = __ast_file_read_dirs(&path, on_file, obj, max_depth);
res = __ast_file_read_dirs(dir_name, on_file, obj, max_depth);
#if !defined(__GLIBC__)
ast_mutex_unlock(&read_dirs_lock);
#endif
ast_free(path);
return res;
}

@ -21,7 +21,10 @@
<support_level>core</support_level>
***/
#include "asterisk.h"
#include <sys/stat.h>
#include <stdio.h>
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
@ -117,6 +120,17 @@ static char *test_files_get_one(struct _filenames *filenames, int num)
static int handle_find_file(const char *dir_name, const char *filename, void *obj)
{
struct stat statbuf;
char *full_path = ast_alloca(strlen(dir_name) + strlen(filename) + 2);
sprintf(full_path, "%s/%s", dir_name, filename);
errno = 0;
if (stat(full_path, &statbuf)) {
ast_log(LOG_ERROR, "Error reading path stats - %s: %s\n",
full_path, strerror(errno));
return 0;
}
/* obj contains the name of the file we are looking for */
return strcmp(obj, filename) ? 0 : FOUND;
}

Loading…
Cancel
Save