Skip to content
Snippets Groups Projects
Commit 89e79a48 authored by George Joseph's avatar George Joseph Committed by Gerrit Code Review
Browse files

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

parents 1c26117d 3017f09f
No related branches found
No related tags found
No related merge requests found
......@@ -1093,27 +1093,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;
......@@ -1128,23 +1128,24 @@ static int __ast_file_read_dirs(struct ast_str **path, ast_file_on_file on_file,
if (entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK) {
is_file = entry->d_type == DT_REG;
is_dir = entry->d_type == DT_DIR;
ast_log(LOG_VERBOSE, "!###### d_name=%s, path=%s, NO USE STAT used_stat=%d\n", entry->d_name, ast_str_buffer(*path), used_stat);
} else
#endif
{
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.
......@@ -1154,13 +1155,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;
ast_log(LOG_VERBOSE, "!###### d_name=%s, path=%s, WE USED IT YO used_stat=%d\n", entry->d_name, ast_str_buffer(*path), used_stat);
}
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,25 +1167,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.
*/
ast_log(LOG_VERBOSE, "!###### do dir d_name=%s, path=%s, used_stat=%d\n", entry->d_name, ast_str_buffer(*path), used_stat);
if (!used_stat) {
ast_str_truncate(*path, size);
ast_str_append(path, 0, "/%s", entry->d_name);
ast_log(LOG_VERBOSE, "!###### d_name=%s, path=%s\n", entry->d_name, ast_str_buffer(*path));
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;
}
}
......@@ -1196,7 +1192,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;
}
......@@ -1217,27 +1213,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>
#include "asterisk/file.h"
#include "asterisk/paths.h"
......@@ -115,6 +118,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;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment