diff --git a/lib/webfuse/adapter/impl/session.c b/lib/webfuse/adapter/impl/session.c index 7e07b69..3a8be94 100644 --- a/lib/webfuse/adapter/impl/session.c +++ b/lib/webfuse/adapter/impl/session.c @@ -8,6 +8,8 @@ #include #include +#include +#include static bool wf_impl_session_send( json_t * request, @@ -33,67 +35,71 @@ static bool wf_impl_session_send( return result; } -void wf_impl_session_init_empty( - struct wf_impl_session * session) -{ - wf_message_queue_init(&session->queue); - session->is_authenticated = false; - session->wsi = NULL; - session->wsi_fuse = NULL; - session->authenticators = NULL; - session->server = NULL; -} - -bool wf_impl_session_init( - struct wf_impl_session * session, +struct wf_impl_session * wf_impl_session_create( struct lws * wsi, struct wf_impl_authenticators * authenticators, struct wf_impl_timeout_manager * timeout_manager, struct wf_impl_jsonrpc_server * server, char const * mount_point, char const * protocol_name) - { - session->wsi = wsi; - session->is_authenticated = false; - session->authenticators = authenticators; - session->server = server; - wf_impl_jsonrpc_proxy_init(&session->rpc, timeout_manager, &wf_impl_session_send, session); - wf_message_queue_init(&session->queue); +{ + static int session_id = 0; + char path[PATH_MAX]; + snprintf(path, PATH_MAX, "%s/%d", mount_point, session_id); + session_id++; + mkdir(path, 0755); - bool const success = wf_impl_filesystem_init(&session->filesystem, session, mount_point); - if (!success) + struct wf_impl_session * session = malloc(sizeof(struct wf_impl_session)); + if (NULL != session) { - wf_impl_jsonrpc_proxy_cleanup(&session->rpc); - wf_message_queue_cleanup(&session->queue); + wf_dlist_item_init(&session->item); + + session->wsi = wsi; + session->is_authenticated = false; + session->authenticators = authenticators; + session->server = server; + wf_impl_jsonrpc_proxy_init(&session->rpc, timeout_manager, &wf_impl_session_send, session); + wf_message_queue_init(&session->queue); + + bool success = wf_impl_filesystem_init(&session->filesystem, session, path); + if (success) + { + lws_sock_file_fd_type fd; + fd.filefd = wf_impl_filesystem_get_fd(&session->filesystem); + session->wsi_fuse = lws_adopt_descriptor_vhost(lws_get_vhost(wsi), LWS_ADOPT_RAW_FILE_DESC, fd, protocol_name, wsi); + if (NULL == session->wsi_fuse) + { + success = false; + fprintf(stderr, "error: unable to adopt fd"); + } + } + + if (!success) + { + wf_impl_jsonrpc_proxy_cleanup(&session->rpc); + wf_message_queue_cleanup(&session->queue); + free(session); + session = NULL; + } } - lws_sock_file_fd_type fd; - fd.filefd = wf_impl_filesystem_get_fd(&session->filesystem); - session->wsi_fuse = lws_adopt_descriptor_vhost(lws_get_vhost(wsi), LWS_ADOPT_RAW_FILE_DESC, fd, protocol_name, wsi); - if (NULL == session->wsi_fuse) - { - fprintf(stderr, "error: unable to adopt fd"); - } + return session; +} - return success; - } - -void wf_impl_session_cleanup( +void wf_impl_session_dispose( struct wf_impl_session * session) { - if (NULL != session->wsi) - { - wf_impl_filesystem_cleanup(&session->filesystem); + wf_impl_filesystem_cleanup(&session->filesystem); - wf_impl_jsonrpc_proxy_cleanup(&session->rpc); - wf_message_queue_cleanup(&session->queue); - session->is_authenticated = false; - session->wsi = NULL; - session->wsi_fuse = NULL; - session->authenticators = NULL; - session->server = NULL; - } -} + wf_impl_jsonrpc_proxy_cleanup(&session->rpc); + wf_message_queue_cleanup(&session->queue); + session->is_authenticated = false; + session->wsi = NULL; + session->wsi_fuse = NULL; + session->authenticators = NULL; + session->server = NULL; + free(session); +} bool wf_impl_session_authenticate( struct wf_impl_session * session, diff --git a/lib/webfuse/adapter/impl/session.h b/lib/webfuse/adapter/impl/session.h index 6e7ef7d..3944f36 100644 --- a/lib/webfuse/adapter/impl/session.h +++ b/lib/webfuse/adapter/impl/session.h @@ -13,6 +13,7 @@ using std::size_t; #include "webfuse/adapter/impl/jsonrpc/proxy.h" #include "webfuse/adapter/impl/jsonrpc/server.h" #include "webfuse/adapter/impl/filesystem.h" +#include "webfuse/core/dlist.h" #ifdef __cplusplus extern "C" @@ -27,6 +28,7 @@ struct wf_impl_timeout_manager; struct wf_impl_session { + struct wf_dlist_item item; struct lws * wsi; struct lws * wsi_fuse; bool is_authenticated; @@ -37,11 +39,7 @@ struct wf_impl_session struct wf_impl_jsonrpc_proxy rpc; }; -extern void wf_impl_session_init_empty( - struct wf_impl_session * session); - -extern bool wf_impl_session_init( - struct wf_impl_session * session, +extern struct wf_impl_session * wf_impl_session_create( struct lws * wsi, struct wf_impl_authenticators * authenticators, struct wf_impl_timeout_manager * timeout_manager, @@ -49,6 +47,9 @@ extern bool wf_impl_session_init( char const * mount_point, char const * protocol_name); +extern void wf_impl_session_dispose( + struct wf_impl_session * session); + extern bool wf_impl_session_authenticate( struct wf_impl_session * session, struct wf_credentials * creds); @@ -61,9 +62,6 @@ extern void wf_impl_session_receive( extern void wf_impl_session_onwritable( struct wf_impl_session * session); -extern void wf_impl_session_cleanup( - struct wf_impl_session * session); - #ifdef __cplusplus } #endif diff --git a/lib/webfuse/adapter/impl/session_manager.c b/lib/webfuse/adapter/impl/session_manager.c index 49fccf6..91300bd 100644 --- a/lib/webfuse/adapter/impl/session_manager.c +++ b/lib/webfuse/adapter/impl/session_manager.c @@ -1,17 +1,30 @@ #include "webfuse/adapter/impl/session_manager.h" #include "webfuse/core/util.h" +#include "webfuse/core/container_of.h" #include void wf_impl_session_manager_init( struct wf_impl_session_manager * manager) { - wf_impl_session_init_empty(&manager->session); + wf_dlist_init(&manager->sessions); } +static void wf_impl_session_manager_cleanup_session( + struct wf_dlist_item * item, + void * user_data) +{ + (void) user_data; + struct wf_impl_session * session = WF_CONTAINER_OF(item, struct wf_impl_session, item); + + wf_impl_session_dispose(session); +} + + + void wf_impl_session_manager_cleanup( struct wf_impl_session_manager * manager) { - wf_impl_session_cleanup(&manager->session); + wf_dlist_cleanup(&manager->sessions, &wf_impl_session_manager_cleanup_session, NULL); } struct wf_impl_session * wf_impl_session_manager_add( @@ -23,36 +36,62 @@ struct wf_impl_session * wf_impl_session_manager_add( char const * mount_point, char const * protocol_name) { - struct wf_impl_session * session = NULL; - if (NULL == manager->session.wsi) + struct wf_impl_session * session = wf_impl_session_create( + wsi, authenticators, timeout_manager, server, mount_point, protocol_name); + if (NULL != session) { - session = &manager->session; - wf_impl_session_init(&manager->session, wsi, authenticators, timeout_manager, server, mount_point, protocol_name); + wf_dlist_prepend(&manager->sessions, &session->item); } return session; } +static bool wf_impl_session_manager_get_predicate( + struct wf_dlist_item * item, + void * user_data) +{ + struct lws * wsi = user_data; + struct wf_impl_session * session = WF_CONTAINER_OF(item, struct wf_impl_session, item); + + return ((wsi == session->wsi) || (wsi == session->wsi_fuse)); +} + struct wf_impl_session * wf_impl_session_manager_get( struct wf_impl_session_manager * manager, struct lws * wsi) { struct wf_impl_session * session = NULL; - if ((wsi == manager->session.wsi) || (wsi == manager->session.wsi_fuse)) + struct wf_dlist_item * item = wf_dlist_find_first( + &manager->sessions, &wf_impl_session_manager_get_predicate, wsi); + if (NULL != item) { - session = &manager->session; + session = WF_CONTAINER_OF(item, struct wf_impl_session, item); } return session; } +static bool wf_impl_session_manager_remove_predicate( + struct wf_dlist_item * item, + void * user_data) +{ + struct lws * wsi = user_data; + struct wf_impl_session * session = WF_CONTAINER_OF(item, struct wf_impl_session, item); + + return (wsi == session->wsi); +} + void wf_impl_session_manager_remove( struct wf_impl_session_manager * manager, struct lws * wsi) { - if (wsi == manager->session.wsi) + struct wf_impl_session * session = NULL; + struct wf_dlist_item * item = wf_dlist_find_first( + &manager->sessions, &wf_impl_session_manager_remove_predicate, wsi); + if (NULL != item) { - wf_impl_session_cleanup(&manager->session); - manager->session.wsi = NULL; + wf_dlist_remove(&manager->sessions, item); + session = WF_CONTAINER_OF(item, struct wf_impl_session, item); + wf_impl_session_dispose(session); } } diff --git a/lib/webfuse/adapter/impl/session_manager.h b/lib/webfuse/adapter/impl/session_manager.h index fe60551..fa0badd 100644 --- a/lib/webfuse/adapter/impl/session_manager.h +++ b/lib/webfuse/adapter/impl/session_manager.h @@ -7,6 +7,7 @@ #include "webfuse/adapter/impl/session.h" #include "webfuse/adapter/impl/fuse_wrapper.h" +#include "webfuse/core/dlist.h" #ifdef __cplusplus extern "C" @@ -19,7 +20,7 @@ struct wf_impl_jsonrpc_server; struct wf_impl_session_manager { - struct wf_impl_session session; + struct wf_dlist sessions; }; extern void wf_impl_session_manager_init( diff --git a/lib/webfuse/core/dlist.c b/lib/webfuse/core/dlist.c index 74b9c31..edfd547 100644 --- a/lib/webfuse/core/dlist.c +++ b/lib/webfuse/core/dlist.c @@ -2,6 +2,20 @@ #include "webfuse/core/util.h" #include +void wf_dlist_item_init( + struct wf_dlist_item * item) +{ + item->next = NULL; + item->prev = NULL; +} + +void wf_dlist_item_cleanup( + struct wf_dlist_item * item) +{ + item->next = NULL; + item->prev = NULL; +} + void wf_dlist_init( struct wf_dlist * list) { diff --git a/lib/webfuse/core/dlist.h b/lib/webfuse/core/dlist.h index 8866bd8..864d882 100644 --- a/lib/webfuse/core/dlist.h +++ b/lib/webfuse/core/dlist.h @@ -21,6 +21,7 @@ struct wf_dlist struct wf_dlist_item * first; }; + typedef void wf_dlist_item_cleanup_fn( struct wf_dlist_item * item, void * user_data); @@ -29,6 +30,11 @@ typedef bool wf_dlist_item_predicate_fn( struct wf_dlist_item * item, void * user_data); +extern void wf_dlist_item_init( + struct wf_dlist_item * item); + +extern void wf_dlist_item_cleanup( + struct wf_dlist_item * item); extern void wf_dlist_init( struct wf_dlist * list);