diff --git a/modules/csync_owncloud.c b/modules/csync_owncloud.c index d3cbde4810..eb3b328811 100644 --- a/modules/csync_owncloud.c +++ b/modules/csync_owncloud.c @@ -42,6 +42,7 @@ static void free_fetchCtx( struct listdir_context *ctx ) SAFE_FREE(res->uri); SAFE_FREE(res->name); SAFE_FREE(res->md5); + memset( res->file_id, 0, FILE_ID_BUF_SIZE+1 ); newres = res->next; SAFE_FREE(res); @@ -80,6 +81,7 @@ static void clean_caches() { SAFE_FREE(_stat_cache.name); SAFE_FREE(_stat_cache.md5 ); + memset( _stat_cache.file_id, 0, FILE_ID_BUF_SIZE+1 ); SAFE_FREE(_id_cache.uri); SAFE_FREE(_id_cache.id); @@ -627,6 +629,7 @@ static void results(void *userdata, const char *clength, *modtime = NULL; const char *resourcetype = NULL; const char *md5sum = NULL; + const char *file_id = NULL; const ne_status *status = NULL; char *path = ne_path_unescape( uri->path ); @@ -650,6 +653,7 @@ static void results(void *userdata, clength = ne_propset_value( set, &ls_props[1] ); resourcetype = ne_propset_value( set, &ls_props[2] ); md5sum = ne_propset_value( set, &ls_props[3] ); + file_id = ne_propset_value( set, &ls_props[4] ); newres->type = resr_normal; if( clength == NULL && resourcetype && strncmp( resourcetype, "", 16 ) == 0) { @@ -677,6 +681,8 @@ static void results(void *userdata, } } + csync_vio_set_file_id(newres->file_id, file_id); + /* prepend the new resource to the result list */ newres->next = fetchCtx->list; fetchCtx->list = newres; @@ -821,6 +827,8 @@ static void fill_stat_cache( csync_vio_file_stat_t *lfs ) { _stat_cache.fields = lfs->fields; _stat_cache.type = lfs->type; _stat_cache.size = lfs->size; + csync_vio_file_stat_set_file_id(&_stat_cache, lfs->file_id); + if( lfs->md5 ) { _stat_cache.md5 = c_strdup(lfs->md5); } @@ -858,17 +866,17 @@ static int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf) { buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_PERMISSIONS; - - buf->fields = _stat_cache.fields; - buf->type = _stat_cache.type; - buf->mtime = _stat_cache.mtime; - buf->size = _stat_cache.size; - buf->mode = _stat_perms( _stat_cache.type ); - buf->md5 = NULL; + buf->fields = _stat_cache.fields; + buf->type = _stat_cache.type; + buf->mtime = _stat_cache.mtime; + buf->size = _stat_cache.size; + buf->mode = _stat_perms( _stat_cache.type ); + buf->md5 = NULL; if( _stat_cache.md5 ) { buf->md5 = c_strdup( _stat_cache.md5 ); buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MD5; } + csync_vio_file_stat_set_file_id( buf, _stat_cache.file_id ); return 0; } DEBUG_WEBDAV("owncloud_stat => Could not find in stat cache %s", uri); @@ -922,6 +930,7 @@ static int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf) { if( lfs->md5 ) { buf->md5 = c_strdup( lfs->md5 ); } + csync_vio_file_stat_set_file_id( buf, lfs->file_id ); /* fill the static stat buf as input for the stat function */ csync_vio_file_stat_destroy( lfs ); @@ -1058,7 +1067,7 @@ static const char* owncloud_get_etag( const char *path ) /* ... and do a stat call. */ fs = csync_vio_file_stat_new(); if(fs == NULL) { - DEBUG_WEBDAV( "owncloud_file_id: memory fault."); + DEBUG_WEBDAV( "owncloud_get_etag: memory fault."); errno = ENOMEM; return NULL; } @@ -1761,8 +1770,6 @@ static int owncloud_commit() { return 0; } - - static int owncloud_utimes(const char *uri, const struct timeval *times) { ne_proppatch_operation ops[2]; diff --git a/modules/csync_owncloud.h b/modules/csync_owncloud.h index 0d1d24b2a9..428f642e0e 100644 --- a/modules/csync_owncloud.h +++ b/modules/csync_owncloud.h @@ -84,6 +84,7 @@ typedef struct resource { int64_t size; time_t modtime; char* md5; + char file_id[FILE_ID_BUF_SIZE+1]; struct resource *next; } resource; @@ -177,6 +178,7 @@ static const ne_propname ls_props[] = { { "DAV:", "getcontentlength" }, { "DAV:", "resourcetype" }, { "DAV:", "getetag"}, + { "http://owncloud.org/ns", "id"}, { NULL, NULL } }; diff --git a/modules/csync_owncloud_recursive_propfind.c b/modules/csync_owncloud_recursive_propfind.c index fceb38d1e4..9f1aa90c53 100644 --- a/modules/csync_owncloud_recursive_propfind.c +++ b/modules/csync_owncloud_recursive_propfind.c @@ -36,6 +36,8 @@ static struct resource* resource_dup(struct resource* o) { r->modtime = o->modtime; r->md5 = c_strdup(o->md5); r->next = o->next; + csync_vio_set_file_id(r->file_id, o->file_id); + return r; } static void resource_free(struct resource* o) { @@ -126,7 +128,7 @@ static void propfind_results_recursive(void *userdata, const ne_prop_result_set *set) { struct resource *newres = 0; - const char *clength, *modtime = NULL; + const char *clength, *modtime, *file_id = NULL; const char *resourcetype = NULL; const char *md5sum = NULL; const ne_status *status = NULL; @@ -153,6 +155,7 @@ static void propfind_results_recursive(void *userdata, clength = ne_propset_value( set, &ls_props[1] ); resourcetype = ne_propset_value( set, &ls_props[2] ); md5sum = ne_propset_value( set, &ls_props[3] ); + file_id = ne_propset_value( set, &ls_props[4] ); newres->type = resr_normal; if( resourcetype && strncmp( resourcetype, "", 16 ) == 0) { @@ -184,6 +187,7 @@ static void propfind_results_recursive(void *userdata, } } + csync_vio_set_file_id(newres->file_id, file_id); /* DEBUG_WEBDAV("propfind_results_recursive %s [%s] %s", newres->uri, newres->type == resr_collection ? "collection" : "file", newres->md5); */ diff --git a/modules/csync_owncloud_util.c b/modules/csync_owncloud_util.c index eec8afef5c..b4a44c04ab 100644 --- a/modules/csync_owncloud_util.c +++ b/modules/csync_owncloud_util.c @@ -312,6 +312,8 @@ csync_vio_file_stat_t *resourceToFileStat( struct resource *res ) lfs->md5 = c_strdup(res->md5); } lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MD5; + csync_vio_file_stat_set_file_id(lfs, res->file_id); + return lfs; } diff --git a/src/csync_private.h b/src/csync_private.h index 0e6c0fa379..e9f67e14a4 100644 --- a/src/csync_private.h +++ b/src/csync_private.h @@ -41,6 +41,7 @@ #include "c_private.h" #include "csync.h" #include "csync_misc.h" +#include "vio/csync_vio_file_stat.h" #ifdef WITH_ICONV #include @@ -195,6 +196,7 @@ struct csync_file_stat_s { char *destpath; /* for renames */ const char *md5; + char file_id[FILE_ID_BUF_SIZE+1]; /* the ownCloud file id is fixed width of 21 byte. */ const char *error_string; enum csync_instructions_e instruction; /* u32 */ diff --git a/src/vio/csync_vio_file_stat.c b/src/vio/csync_vio_file_stat.c index e21e06fe2f..162567dac3 100644 --- a/src/vio/csync_vio_file_stat.c +++ b/src/vio/csync_vio_file_stat.c @@ -29,6 +29,7 @@ csync_vio_file_stat_t *csync_vio_file_stat_new(void) { return NULL; } file_stat->md5 = NULL; + memset(file_stat->file_id, 0, FILE_ID_BUF_SIZE+1); return file_stat; } @@ -51,3 +52,21 @@ void csync_vio_file_stat_destroy(csync_vio_file_stat_t *file_stat) { SAFE_FREE(file_stat); } +void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t *dst, const char* src ) { + + csync_vio_set_file_id( dst->file_id, src ); + if( c_streq( dst->file_id, INVALID_FILE_ID )) { + return; + } + dst->fields |= CSYNC_VIO_FILE_STAT_FIELDS_FILE_ID; +} + +void csync_vio_set_file_id( char* dst, const char *src ) { + if( src && dst ) { + if( strlen(src) > FILE_ID_BUF_SIZE ) { + strcpy(dst, INVALID_FILE_ID); + } else { + strcpy(dst, src); + } + } +} diff --git a/src/vio/csync_vio_file_stat.h b/src/vio/csync_vio_file_stat.h index f3abcc8bd2..e0d4419e57 100644 --- a/src/vio/csync_vio_file_stat.h +++ b/src/vio/csync_vio_file_stat.h @@ -26,12 +26,15 @@ * that would cause circular inclusion */ #include "c_private.h" - +#include "csync.h" #include #include #include #include +#define FILE_ID_BUF_SIZE 21 +#define INVALID_FILE_ID "-invalid_fileid-" + typedef struct csync_vio_file_stat_s csync_vio_file_stat_t; enum csync_vio_file_flags_e { @@ -71,6 +74,7 @@ enum csync_vio_file_stat_fields_e { CSYNC_VIO_FILE_STAT_FIELDS_UID = 1 << 15, CSYNC_VIO_FILE_STAT_FIELDS_GID = 1 << 16, CSYNC_VIO_FILE_STAT_FIELDS_MD5 = 1 << 17, + CSYNC_VIO_FILE_STAT_FIELDS_FILE_ID = 1 << 18 }; @@ -83,6 +87,7 @@ struct csync_vio_file_stat_s { void *acl; char *name; char *md5; + char file_id[FILE_ID_BUF_SIZE+1]; uid_t uid; gid_t gid; @@ -115,4 +120,8 @@ csync_vio_file_stat_t *csync_vio_file_stat_new(void); void csync_vio_file_stat_destroy(csync_vio_file_stat_t *fstat); +void csync_vio_file_stat_set_file_id( csync_vio_file_stat_t* dst, const char* src ); + +void csync_vio_set_file_id(char* dst, const char *src ); + #endif /* _CSYNC_VIO_METHOD_H */