|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|