diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 290c84d75..36932019e 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -64,7 +64,7 @@ endif (LIBSSH_FOUND) if (NEON_FOUND) include_directories( ${NEON_INCLUDE_DIRS} ) - macro_add_plugin(${OWNCLOUD_PLUGIN} csync_owncloud.c) + macro_add_plugin(${OWNCLOUD_PLUGIN} csync_owncloud.c csync_owncloud_recursive_propfind.c) target_link_libraries(${OWNCLOUD_PLUGIN} ${CSYNC_LIBRARY} ${NEON_LIBRARIES} ${HTTPBF_LIBRARY}) install( diff --git a/modules/csync_owncloud.c b/modules/csync_owncloud.c index 96e257499..991067ae4 100644 --- a/modules/csync_owncloud.c +++ b/modules/csync_owncloud.c @@ -18,87 +18,9 @@ * along with this program = NULL, if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include -#include -#include -#include -#include -#include -#include -#include +#include "csync_owncloud.h" -#include "config.h" -#ifdef NEON_WITH_LFS /* Switch on LFS in libneon. Never remove the NE_LFS! */ -#define NE_LFS -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "c_rbtree.h" - -#include "c_lib.h" -#include "csync.h" -#include "csync_misc.h" -#include "csync_macros.h" -#include "c_private.h" -#include "httpbf.h" - -#include "vio/csync_vio_module.h" -#include "vio/csync_vio_file_stat.h" -#include "vio/csync_vio.h" - -#include "csync_log.h" - -#define DEBUG_WEBDAV(...) csync_log( dav_session.csync_ctx, 9, "oc_module", __VA_ARGS__); - -#define OC_TIMEDELTA_FAIL (NE_REDIRECT +1) -#define OC_PROPFIND_FAIL (NE_REDIRECT +2) - - -enum resource_type { - resr_normal = 0, - resr_collection, - resr_reference, - resr_error -}; - -#define DAV_STRTOL strtoll - -/* Struct to store data for each resource found during an opendir operation. - * It represents a single file entry. - */ - -typedef struct resource { - char *uri; /* The complete uri */ - char *name; /* The filename only */ - - enum resource_type type; - off_t size; - time_t modtime; - char* md5; - - struct resource *next; -} resource; - -/* Struct to hold the context of a WebDAV PropFind operation to fetch - * a directory listing from the server. - */ -struct listdir_context { - struct resource *list; /* The list of result resources */ - struct resource *currResource; /* A pointer to the current resource */ - char *target; /* Request-URI of the PROPFIND */ - unsigned int result_count; /* number of elements stored in list */ - int ref; /* reference count, only destroy when it reaches 0 */ -}; /* * free the fetchCtx @@ -128,56 +50,6 @@ static void free_fetchCtx( struct listdir_context *ctx ) } -/* - * context to store info about a temp file for GET and PUT requests - * which store the data in a local file to save memory and secure the - * transmission. - */ -struct transfer_context { - ne_request *req; /* the neon request */ - int fd; /* file descriptor of the file to read or write from */ - const char *method; /* the HTTP method, either PUT or GET */ - ne_decompress *decompress; /* the decompress context */ - char *url; -}; - -/* Struct with the WebDAV session */ -struct dav_session_s { - ne_session *ctx; - char *user; - char *pwd; - - char *proxy_type; - char *proxy_host; - int proxy_port; - char *proxy_user; - char *proxy_pwd; - - char *session_key; - - char *error_string; - - int read_timeout; - - long int prev_delta; - long int time_delta; /* The time delta to use. */ - long int time_delta_sum; /* What is the time delta average? */ - long int time_delta_cnt; /* How often was the server time gathered? */ - - CSYNC *csync_ctx; - void *userdata; - - csync_hbf_info_t *chunk_info; -}; - -/* The list of properties that is fetched in PropFind on a collection */ -static const ne_propname ls_props[] = { - { "DAV:", "getlastmodified" }, - { "DAV:", "getcontentlength" }, - { "DAV:", "resourcetype" }, - { "DAV:", "getetag"}, - { NULL, NULL } -}; /* * local variables. @@ -195,7 +67,7 @@ long long chunked_done = 0; struct listdir_context *propfind_cache = 0; bool is_first_propfind = true; -static void clear_propfind_recursive_cache(); + csync_vio_file_stat_t _stat_cache; /* id cache, cache the ETag: header of a GET request */ @@ -222,14 +94,14 @@ static void clean_caches() { char _buffer[PUT_BUFFER_SIZE]; /* ***************************************************************************** */ -static void set_error_message( const char *msg ) +void set_error_message( const char *msg ) { SAFE_FREE(dav_session.error_string); if( msg ) dav_session.error_string = c_strdup(msg); } -static void set_errno_from_http_errcode( int err ) { +void set_errno_from_http_errcode( int err ) { int new_errno = 0; switch(err) { @@ -328,7 +200,7 @@ static void set_errno_from_session() { } } -static void set_errno_from_neon_errcode( int neon_code ) { +void set_errno_from_neon_errcode( int neon_code ) { if( neon_code != NE_OK ) { DEBUG_WEBDAV("Neon error code was %d", neon_code); @@ -386,10 +258,6 @@ static char *_cleanPath( const char* uri ) { SAFE_FREE( path ); return re; } -/* ***************************************************************************** */ -#include "csync_owncloud_recursive_propfind.c" -/* ***************************************************************************** */ - /* * helper method to build up a user text for SSL problems, called from the @@ -872,7 +740,7 @@ static const char short_months[12][4] = { * needed. * This one uses timegm instead, which returns UTC. */ -static time_t oc_httpdate_parse( const char *date ) { +time_t oc_httpdate_parse( const char *date ) { struct tm gmt; char wkday[4], mon[4]; int n; diff --git a/modules/csync_owncloud.h b/modules/csync_owncloud.h new file mode 100644 index 000000000..a9639ddf4 --- /dev/null +++ b/modules/csync_owncloud.h @@ -0,0 +1,180 @@ +/* + * libcsync -- a library to sync a directory with another + * + * Copyright (c) 2011 by Andreas Schneider + * Copyright (c) 2012 by Klaas Freitag + * + * This program is free software = NULL, you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation = NULL, either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY = NULL, without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program = NULL, if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef CSYNC_OWNCLOUD_H +#define CSYNC_OWNCLOUD_H + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "config.h" +#ifdef NEON_WITH_LFS /* Switch on LFS in libneon. Never remove the NE_LFS! */ +#define NE_LFS +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "c_rbtree.h" + +#include "c_lib.h" +#include "csync.h" +#include "csync_misc.h" +#include "csync_macros.h" +#include "c_private.h" +#include "httpbf.h" + +#include "vio/csync_vio_module.h" +#include "vio/csync_vio_file_stat.h" +#include "vio/csync_vio.h" + +#include "csync_log.h" + + +#define DEBUG_WEBDAV(...) csync_log( dav_session.csync_ctx, 9, "oc_module", __VA_ARGS__); + +#define OC_TIMEDELTA_FAIL (NE_REDIRECT +1) +#define OC_PROPFIND_FAIL (NE_REDIRECT +2) + + +enum resource_type { + resr_normal = 0, + resr_collection, + resr_reference, + resr_error +}; + +#define DAV_STRTOL strtoll + +/* Struct to store data for each resource found during an opendir operation. + * It represents a single file entry. + */ + +typedef struct resource { + char *uri; /* The complete uri */ + char *name; /* The filename only */ + + enum resource_type type; + off_t size; + time_t modtime; + char* md5; + + struct resource *next; +} resource; + +/* Struct to hold the context of a WebDAV PropFind operation to fetch + * a directory listing from the server. + */ +struct listdir_context { + struct resource *list; /* The list of result resources */ + struct resource *currResource; /* A pointer to the current resource */ + char *target; /* Request-URI of the PROPFIND */ + unsigned int result_count; /* number of elements stored in list */ + int ref; /* reference count, only destroy when it reaches 0 */ +}; + + +// Our cache, key is a char* +extern c_rbtree_t *propfind_recursive_cache; +// Values are propfind_recursive_element: +struct propfind_recursive_element { + struct resource *self; + struct resource *children; +}; +typedef struct propfind_recursive_element propfind_recursive_element_t; +void clear_propfind_recursive_cache(); +struct listdir_context *get_listdir_context_from_cache(const char *curi); +struct listdir_context *fetch_resource_list_recursive(const char *uri, const char *curi); + +time_t oc_httpdate_parse( const char *date ); + + +/* + * context to store info about a temp file for GET and PUT requests + * which store the data in a local file to save memory and secure the + * transmission. + */ +struct transfer_context { + ne_request *req; /* the neon request */ + int fd; /* file descriptor of the file to read or write from */ + const char *method; /* the HTTP method, either PUT or GET */ + ne_decompress *decompress; /* the decompress context */ + char *url; +}; + +/* Struct with the WebDAV session */ +struct dav_session_s { + ne_session *ctx; + char *user; + char *pwd; + + char *proxy_type; + char *proxy_host; + int proxy_port; + char *proxy_user; + char *proxy_pwd; + + char *session_key; + + char *error_string; + + int read_timeout; + + long int prev_delta; + long int time_delta; /* The time delta to use. */ + long int time_delta_sum; /* What is the time delta average? */ + long int time_delta_cnt; /* How often was the server time gathered? */ + + CSYNC *csync_ctx; + void *userdata; + + csync_hbf_info_t *chunk_info; +}; +extern struct dav_session_s dav_session; + +/* The list of properties that is fetched in PropFind on a collection */ +static const ne_propname ls_props[] = { + { "DAV:", "getlastmodified" }, + { "DAV:", "getcontentlength" }, + { "DAV:", "resourcetype" }, + { "DAV:", "getetag"}, + { NULL, NULL } +}; + +void set_errno_from_http_errcode( int err ); +void set_error_message( const char *msg ); +void set_errno_from_neon_errcode( int neon_code ); + +#endif // CSYNC_OWNCLOUD_H diff --git a/modules/csync_owncloud_recursive_propfind.c b/modules/csync_owncloud_recursive_propfind.c index 617e65784..ba15b0e10 100644 --- a/modules/csync_owncloud_recursive_propfind.c +++ b/modules/csync_owncloud_recursive_propfind.c @@ -1,13 +1,36 @@ -static time_t oc_httpdate_parse( const char *date ); +/* + * libcsync -- a library to sync a directory with another + * + * Copyright (c) 2011 by Andreas Schneider + * Copyright (c) 2012 by Klaas Freitag + * + * This program is free software = NULL, you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation = NULL, either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY = NULL, without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program = NULL, if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include "csync_owncloud.h" + + -// Our cache, key is a char* c_rbtree_t *propfind_recursive_cache = NULL; -// Values are propfind_recursive_element: -struct propfind_recursive_element { - struct resource *self; - struct resource *children; -}; -typedef struct propfind_recursive_element propfind_recursive_element_t; + static struct resource* resource_dup(struct resource* o) { struct resource *r = c_malloc (sizeof( struct resource )); @@ -39,13 +62,13 @@ static void _tree_destructor(void *data) { resource_free(element->children); SAFE_FREE(element); } -static void clear_propfind_recursive_cache() +void clear_propfind_recursive_cache() { c_rbtree_destroy(propfind_recursive_cache, _tree_destructor); propfind_recursive_cache = NULL; } -static struct listdir_context *get_listdir_context_from_cache(const char *curi) +struct listdir_context *get_listdir_context_from_cache(const char *curi) { if (!propfind_recursive_cache) { DEBUG_WEBDAV("get_listdir_context_from_cache No cache"); @@ -197,7 +220,8 @@ static void results_recursive(void *userdata, /* * fetches a resource list from the WebDAV server. This is equivalent to list dir. */ -static struct listdir_context *fetch_resource_list_recursive(const char *uri, const char *curi) +extern csync_progress_callback _progresscb; +struct listdir_context *fetch_resource_list_recursive(const char *uri, const char *curi) { int ret = 0; ne_propfind_handler *hdl = NULL;