mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-04-14 00:58:38 +02:00
lavf/file: implement directory listing callbacks
Signed-off-by: Lukasz Marek <lukasz.m.luki2 at gmail.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
060102389e
commit
d39a9b01e2
@ -23,6 +23,7 @@
|
|||||||
#include "libavutil/internal.h"
|
#include "libavutil/internal.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "avformat.h"
|
#include "avformat.h"
|
||||||
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#if HAVE_IO_H
|
#if HAVE_IO_H
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
@ -51,6 +52,7 @@ typedef struct FileContext {
|
|||||||
int fd;
|
int fd;
|
||||||
int trunc;
|
int trunc;
|
||||||
int blocksize;
|
int blocksize;
|
||||||
|
DIR *dir;
|
||||||
} FileContext;
|
} FileContext;
|
||||||
|
|
||||||
static const AVOption file_options[] = {
|
static const AVOption file_options[] = {
|
||||||
@ -225,6 +227,88 @@ static int file_close(URLContext *h)
|
|||||||
return close(c->fd);
|
return close(c->fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int file_open_dir(URLContext *h)
|
||||||
|
{
|
||||||
|
FileContext *c = h->priv_data;
|
||||||
|
|
||||||
|
c->dir = opendir(h->filename);
|
||||||
|
if (!c->dir)
|
||||||
|
return AVERROR(errno);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int file_read_dir(URLContext *h, AVIODirEntry **next)
|
||||||
|
{
|
||||||
|
FileContext *c = h->priv_data;
|
||||||
|
struct dirent *dir;
|
||||||
|
char *fullpath = NULL;
|
||||||
|
|
||||||
|
*next = ff_alloc_dir_entry();
|
||||||
|
if (!*next)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
do {
|
||||||
|
errno = 0;
|
||||||
|
dir = readdir(c->dir);
|
||||||
|
if (!dir) {
|
||||||
|
av_freep(next);
|
||||||
|
return AVERROR(errno);
|
||||||
|
}
|
||||||
|
} while (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."));
|
||||||
|
|
||||||
|
fullpath = av_append_path_component(h->filename, dir->d_name);
|
||||||
|
if (fullpath) {
|
||||||
|
struct stat st;
|
||||||
|
if (!stat(fullpath, &st)) {
|
||||||
|
(*next)->group_id = st.st_gid;
|
||||||
|
(*next)->user_id = st.st_uid;
|
||||||
|
(*next)->size = st.st_size;
|
||||||
|
(*next)->filemode = st.st_mode & 0777;
|
||||||
|
(*next)->modification_timestamp = INT64_C(1000000) * st.st_mtime;
|
||||||
|
(*next)->access_timestamp = INT64_C(1000000) * st.st_atime;
|
||||||
|
(*next)->status_change_timestamp = INT64_C(1000000) * st.st_ctime;
|
||||||
|
}
|
||||||
|
av_free(fullpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*next)->name = av_strdup(dir->d_name);
|
||||||
|
switch (dir->d_type) {
|
||||||
|
case DT_FIFO:
|
||||||
|
(*next)->type = AVIO_ENTRY_NAMED_PIPE;
|
||||||
|
break;
|
||||||
|
case DT_CHR:
|
||||||
|
(*next)->type = AVIO_ENTRY_CHARACTER_DEVICE;
|
||||||
|
break;
|
||||||
|
case DT_DIR:
|
||||||
|
(*next)->type = AVIO_ENTRY_DIRECTORY;
|
||||||
|
break;
|
||||||
|
case DT_BLK:
|
||||||
|
(*next)->type = AVIO_ENTRY_BLOCK_DEVICE;
|
||||||
|
break;
|
||||||
|
case DT_REG:
|
||||||
|
(*next)->type = AVIO_ENTRY_FILE;
|
||||||
|
break;
|
||||||
|
case DT_LNK:
|
||||||
|
(*next)->type = AVIO_ENTRY_SYMBOLIC_LINK;
|
||||||
|
break;
|
||||||
|
case DT_SOCK:
|
||||||
|
(*next)->type = AVIO_ENTRY_SOCKET;
|
||||||
|
break;
|
||||||
|
case DT_UNKNOWN:
|
||||||
|
default:
|
||||||
|
(*next)->type = AVIO_ENTRY_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int file_close_dir(URLContext *h)
|
||||||
|
{
|
||||||
|
FileContext *c = h->priv_data;
|
||||||
|
closedir(c->dir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
URLProtocol ff_file_protocol = {
|
URLProtocol ff_file_protocol = {
|
||||||
.name = "file",
|
.name = "file",
|
||||||
.url_open = file_open,
|
.url_open = file_open,
|
||||||
@ -238,6 +322,9 @@ URLProtocol ff_file_protocol = {
|
|||||||
.url_move = file_move,
|
.url_move = file_move,
|
||||||
.priv_data_size = sizeof(FileContext),
|
.priv_data_size = sizeof(FileContext),
|
||||||
.priv_data_class = &file_class,
|
.priv_data_class = &file_class,
|
||||||
|
.url_open_dir = file_open_dir,
|
||||||
|
.url_read_dir = file_read_dir,
|
||||||
|
.url_close_dir = file_close_dir,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CONFIG_FILE_PROTOCOL */
|
#endif /* CONFIG_FILE_PROTOCOL */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user