2 Commits

Author SHA1 Message Date
3d81b832e5 implement -o exit_after_connect
this is useful as a connectivity check
2024-08-06 05:19:09 +00:00
5c68307010 implement readdir 2024-08-06 04:09:49 +00:00
6 changed files with 32 additions and 12 deletions

View File

@@ -385,6 +385,7 @@ static void cache_unity_fill(struct fuse_cache_operations *oper,
cache_oper->listxattr = oper->oper.listxattr;
cache_oper->removexattr = oper->oper.removexattr;
cache_oper->create = oper->oper.create;
cache_oper->readdir = oper->oper.readdir;
}
struct fuse_operations *cache_init(struct fuse_cache_operations *oper)
@@ -409,6 +410,7 @@ struct fuse_operations *cache_init(struct fuse_cache_operations *oper)
cache_oper.utimens = oper->oper.utimens ? cache_utimens : NULL;
cache_oper.write = oper->oper.write ? cache_write : NULL;
cache_oper.create = oper->oper.create ? cache_create : NULL;
// TODO: cache `readdir`
pthread_mutex_init(&cache.lock, NULL);
cache.table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
free_node);

View File

@@ -23,7 +23,6 @@ typedef int (*fuse_cache_dirfil_t) (fuse_cache_dirh_t h, const char *name,
struct fuse_cache_operations {
struct fuse_operations oper;
int (*cache_getdir) (const char *, fuse_cache_dirh_t, fuse_cache_dirfil_t);
};
struct fuse_operations *cache_init(struct fuse_cache_operations *oper);

View File

@@ -190,7 +190,7 @@ static int parse_dir_netware(const char *line,
int parse_dir(const char* list, const char* dir,
const char* name, struct stat* sbuf,
char* linkbuf, int linklen,
fuse_cache_dirh_t h, fuse_cache_dirfil_t filler) {
void *dbuf, fuse_cache_dirfil_t filler) {
char *file;
char *link;
const char *start = list;
@@ -253,9 +253,9 @@ int parse_dir(const char* list, const char* dir,
free(reallink);
}
if (h && filler) {
if (dbuf && filler) {
DEBUG(1, "filler: %s\n", file);
filler(h, file, &stat_buf);
filler(dbuf, file, &stat_buf);
} else {
DEBUG(1, "cache_add_attr: %s\n", full_path);
cache_add_attr(full_path, &stat_buf);

View File

@@ -14,6 +14,6 @@
int parse_dir(const char* list, const char* dir,
const char* name, struct stat* sbuf,
char* linkbuf, int linklen,
fuse_cache_dirh_t h, fuse_cache_dirfil_t filler);
void *dbuf, fuse_cache_dirfil_t filler);
#endif /* __CURLFTPFS_FTPFS_LS_H__ */

32
ftpfs.c
View File

@@ -174,6 +174,7 @@ static struct fuse_opt ftpfs_opts[] = {
FTPFS_OPT("codepage=%s", codepage, 0),
FTPFS_OPT("iocharset=%s", iocharset, 0),
FTPFS_OPT("nomulticonn", multiconn, 0),
FTPFS_OPT("exit_after_connect", exit_after_connect, 1),
FUSE_OPT_KEY("-h", KEY_HELP),
FUSE_OPT_KEY("--help", KEY_HELP),
@@ -266,13 +267,17 @@ static size_t read_data(void *ptr, size_t size, size_t nmemb, void *data) {
}\
}while(0)
static int ftpfs_getdir(const char* path, fuse_cache_dirh_t h,
fuse_cache_dirfil_t filler) {
static int ftpfs_readdir(const char* path, void *dbuf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags flags) {
// N.B.: fuse.h tells us that we can ignore `offset` and pass 0 to the filler where it would expect an offset.
// fuse_cache_dirfil_t handle = (struct dir_handle*) fi->fh; //< set by us in `open`
int err = 0;
CURLcode curl_res;
char* dir_path = get_fulldir_path(path);
DEBUG(1, "ftpfs_getdir: %s\n", dir_path);
DEBUG(1, "ftpfs_readdir: %s\n", dir_path);
struct buffer buf;
buf_init(&buf);
@@ -289,12 +294,12 @@ static int ftpfs_getdir(const char* path, fuse_cache_dirh_t h,
} else {
buf_null_terminate(&buf);
parse_dir((char*)buf.p, dir_path + strlen(ftpfs.host) - 1,
NULL, NULL, NULL, 0, h, filler);
NULL, NULL, NULL, 0, dbuf, filler);
}
free(dir_path);
buf_free(&buf);
return op_return(err, "ftpfs_getdir");
return op_return(err, "ftpfs_readdir");
}
static int ftpfs_getattr(const char* path, struct stat* sbuf, struct fuse_file_info* fi) {
@@ -1361,6 +1366,15 @@ static int ftpfs_statfs(const char *path, struct statvfs *buf)
return op_return(0, "ftpfs_statfs");
}
// static void *ftpfs_init(struct fuse_conn_info *conn,
// struct fuse_config *cfg)
// {
// // alternatively, mount with `-o readdirplus=no`
// conn->want &= ~FUSE_CAP_READDIRPLUS;
// // alternatively, mount with `-o sync_read`
// conn->want &= ~FUSE_CAP_ASYNC_READ;
// }
static struct fuse_cache_operations ftpfs_oper = {
.oper = {
// .init = ftpfs_init,
@@ -1384,8 +1398,8 @@ static struct fuse_cache_operations ftpfs_oper = {
.write = ftpfs_write,
.statfs = ftpfs_statfs,
.create = ftpfs_create,
.readdir = ftpfs_readdir,
},
.cache_getdir = ftpfs_getdir,
};
static int curlftpfs_fuse_main(struct fuse_args *args)
@@ -1489,6 +1503,7 @@ static void usage(const char* progname) {
" utf8 try to transfer file list with utf-8 encoding\n"
" codepage=STR set the codepage the server uses\n"
" iocharset=STR set the charset used by the client\n"
" exit_after_connect after connecting to the FTP server, instead of passing control to FUSE, exit\n"
"\n"
"CurlFtpFS cache options: \n"
" cache=yes|no enable/disable cache (default: yes)\n"
@@ -1787,7 +1802,10 @@ int main(int argc, char** argv) {
fuse_opt_insert_arg(&args, 1, tmp);
g_free(tmp);
res = curlftpfs_fuse_main(&args);
if (!ftpfs.exit_after_connect) {
res = curlftpfs_fuse_main(&args);
}
cancel_previous_multi();
curl_multi_cleanup(ftpfs.multi);

View File

@@ -67,6 +67,7 @@ struct ftpfs {
char *codepage;
char *iocharset;
int multiconn;
int exit_after_connect;
};
extern struct ftpfs ftpfs;