From 5ee00a8df72dc7d9896e5030b26ce12e2efcd4bd Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 28 May 2014 11:36:07 +0200 Subject: [PATCH] CSync: Simplify csync_owncloud stat/resource handling --- csync/src/csync_owncloud.c | 100 +++++------------- csync/src/csync_owncloud.h | 4 +- csync/src/csync_owncloud_recursive_propfind.c | 29 +---- csync/src/csync_owncloud_util.c | 52 ++++++--- csync/src/csync_update.c | 4 +- csync/src/csync_util.c | 53 ---------- csync/src/csync_util.h | 3 - csync/src/vio/csync_vio_file_stat.c | 16 +-- csync/src/vio/csync_vio_file_stat.h | 29 ++--- csync/src/vio/csync_vio_local.c | 11 -- src/mirall/syncengine.cpp | 1 - 11 files changed, 80 insertions(+), 222 deletions(-) diff --git a/csync/src/csync_owncloud.c b/csync/src/csync_owncloud.c index bfe1a63b9..cba173733 100644 --- a/csync/src/csync_owncloud.c +++ b/csync/src/csync_owncloud.c @@ -70,7 +70,7 @@ struct listdir_context *propfind_cache = 0; bool is_first_propfind = true; -csync_vio_file_stat_t _stat_cache; +struct resource* _stat_cache = 0; /* id cache, cache the ETag: header of a GET request */ struct { char *uri; char *id; } _id_cache = { NULL, NULL }; @@ -80,9 +80,8 @@ static void clean_caches() { free_fetchCtx(propfind_cache); propfind_cache = NULL; - SAFE_FREE(_stat_cache.name); - SAFE_FREE(_stat_cache.etag ); - memset( _stat_cache.file_id, 0, FILE_ID_BUF_SIZE+1 ); + resource_free(_stat_cache); + _stat_cache = NULL; SAFE_FREE(_id_cache.uri); SAFE_FREE(_id_cache.id); @@ -764,26 +763,6 @@ static struct listdir_context *fetch_resource_list_attempts(const char *uri, int return fetchCtx; } -static void fill_stat_cache( csync_vio_file_stat_t *lfs ) { - - if( _stat_cache.name ) SAFE_FREE(_stat_cache.name); - if( _stat_cache.etag ) SAFE_FREE(_stat_cache.etag ); - - if( !lfs) return; - - _stat_cache.name = c_strdup(lfs->name); - _stat_cache.mtime = lfs->mtime; - _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->etag ) { - _stat_cache.etag = c_strdup(lfs->etag); - } -} - - /* * file functions @@ -794,38 +773,24 @@ int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf) { * creattime * size */ - csync_vio_file_stat_t *lfs = NULL; struct listdir_context *fetchCtx = NULL; char *decodedUri = NULL; int len = 0; errno = 0; + ne_uri uri_parsed; + if (ne_uri_parse(uri, &uri_parsed) != NE_OK) { + return 1; + } + buf->name = c_basename(uri); - if (buf->name == NULL) { - errno = ENOMEM; - return -1; - } - - if( _stat_cache.name && strcmp( buf->name, _stat_cache.name ) == 0 ) { - buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; - 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->etag = NULL; - if( _stat_cache.etag ) { - buf->etag = c_strdup( _stat_cache.etag ); - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG; - } - csync_vio_file_stat_set_file_id( buf, _stat_cache.file_id ); + if( _stat_cache && _stat_cache->uri && strcmp( uri_parsed.path, _stat_cache->uri ) == 0 ) { + ne_uri_free(&uri_parsed); + resourceToFileStat(buf, _stat_cache ); return 0; } + ne_uri_free(&uri_parsed); DEBUG_WEBDAV("owncloud_stat => Could not find in stat cache %s", uri); /* fetch data via a propfind call. */ @@ -859,29 +824,8 @@ int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf) { DEBUG_WEBDAV("ERROR: Result struct not valid!"); } - lfs = resourceToFileStat( res ); - if( lfs ) { - buf->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; - 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 |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG; - - buf->fields = lfs->fields; - buf->type = lfs->type; - buf->mtime = lfs->mtime; - buf->size = lfs->size; - buf->mode = _stat_perms( lfs->type ); - buf->etag = NULL; - if( lfs->etag ) { - buf->etag = c_strdup( lfs->etag ); - } - 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 ); - } + // Fill user-provided buffer + resourceToFileStat(buf, res ); free_fetchCtx( fetchCtx ); } @@ -971,8 +915,20 @@ csync_vio_file_stat_t *owncloud_readdir(csync_vio_handle_t *dhandle) { */ escaped_path = ne_path_escape( currResource->uri ); if (ne_path_compare(fetchCtx->target, escaped_path) != 0) { - csync_vio_file_stat_t* lfs = resourceToFileStat(currResource); - fill_stat_cache(lfs); + // Convert the resource for the caller + csync_vio_file_stat_t* lfs = csync_vio_file_stat_new(); + resourceToFileStat(lfs, currResource); + + // Save the current readdir result into our single item stat cache too so a call to stat() + // will return that item + if (_stat_cache) { + resource_free(_stat_cache); + _stat_cache = NULL; + } + _stat_cache = resource_dup(currResource); + _stat_cache->next = 0; + + SAFE_FREE( escaped_path ); return lfs; } diff --git a/csync/src/csync_owncloud.h b/csync/src/csync_owncloud.h index fece58077..d6bce755a 100644 --- a/csync/src/csync_owncloud.h +++ b/csync/src/csync_owncloud.h @@ -164,7 +164,9 @@ time_t oc_httpdate_parse( const char *date ); char *_cleanPath( const char* uri ); int _stat_perms( int type ); -csync_vio_file_stat_t *resourceToFileStat( struct resource *res ); +void resourceToFileStat( csync_vio_file_stat_t *lfs, struct resource *res ); +void resource_free(struct resource* o); +struct resource* resource_dup(struct resource* o); // Public API from vio csync_vio_handle_t *owncloud_opendir(const char *uri); diff --git a/csync/src/csync_owncloud_recursive_propfind.c b/csync/src/csync_owncloud_recursive_propfind.c index 29abd199f..4b8c424d9 100644 --- a/csync/src/csync_owncloud_recursive_propfind.c +++ b/csync/src/csync_owncloud_recursive_propfind.c @@ -27,35 +27,7 @@ int propfind_recursive_cache_file_count = 0; int propfind_recursive_cache_folder_count = 0; -static struct resource* resource_dup(struct resource* o) { - struct resource *r = c_malloc (sizeof( struct resource )); - ZERO_STRUCTP(r); - r->uri = c_strdup(o->uri); - r->name = c_strdup(o->name); - r->type = o->type; - r->size = o->size; - r->modtime = o->modtime; - if( o->md5 ) { - 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) { - struct resource* old = NULL; - while (o) - { - old = o; - o = o->next; - SAFE_FREE(old->uri); - SAFE_FREE(old->name); - SAFE_FREE(old->md5); - SAFE_FREE(old); - } -} static void _tree_destructor(void *data) { propfind_recursive_element_t *element = data; @@ -202,6 +174,7 @@ static void propfind_results_recursive(void *userdata, if (!element) { element = c_malloc(sizeof(propfind_recursive_element_t)); element->self = resource_dup(newres); + element->self->next = 0; element->children = NULL; element->parent = NULL; c_rbtree_insert(propfind_recursive_cache, element); diff --git a/csync/src/csync_owncloud_util.c b/csync/src/csync_owncloud_util.c index ef57f77f3..0c5d7d41d 100644 --- a/csync/src/csync_owncloud_util.c +++ b/csync/src/csync_owncloud_util.c @@ -279,19 +279,9 @@ time_t oc_httpdate_parse( const char *date ) { /* * helper: convert a resource struct to file_stat struct. */ -csync_vio_file_stat_t *resourceToFileStat( struct resource *res ) +void resourceToFileStat(csync_vio_file_stat_t *lfs, struct resource *res ) { - csync_vio_file_stat_t *lfs = NULL; - - if( ! res ) { - return NULL; - } - - lfs = c_malloc(sizeof(csync_vio_file_stat_t)); - if (lfs == NULL) { - errno = ENOMEM; - return NULL; - } + ZERO_STRUCTP(lfs); lfs->name = c_strdup( res->name ); @@ -306,17 +296,20 @@ csync_vio_file_stat_t *resourceToFileStat( struct resource *res ) DEBUG_WEBDAV("ERROR: Unknown resource type %d", res->type); } + // FIXME Those are defaults, we'll have to use the real ownCloud WebDAV permissions soon + lfs->mode = _stat_perms( lfs->type ); + lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_PERMISSIONS; + lfs->mtime = res->modtime; lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; lfs->size = res->size; lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; if( res->md5 ) { lfs->etag = c_strdup(res->md5); + lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG; } - lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ETAG; - csync_vio_file_stat_set_file_id(lfs, res->file_id); - return lfs; + csync_vio_file_stat_set_file_id(lfs, res->file_id); } /* WebDAV does not deliver permissions. Set a default here. */ @@ -339,3 +332,32 @@ int _stat_perms( int type ) { return ret; } +struct resource* resource_dup(struct resource* o) { + struct resource *r = c_malloc (sizeof( struct resource )); + ZERO_STRUCTP(r); + + r->uri = c_strdup(o->uri); + r->name = c_strdup(o->name); + r->type = o->type; + r->size = o->size; + r->modtime = o->modtime; + if( o->md5 ) { + r->md5 = c_strdup(o->md5); + } + r->next = o->next; + csync_vio_set_file_id(r->file_id, o->file_id); + + return r; +} +void resource_free(struct resource* o) { + struct resource* old = NULL; + while (o) + { + old = o; + o = o->next; + SAFE_FREE(old->uri); + SAFE_FREE(old->name); + SAFE_FREE(old->md5); + SAFE_FREE(old); + } +} diff --git a/csync/src/csync_update.c b/csync/src/csync_update.c index 3ec6b194d..44d1a03f6 100644 --- a/csync/src/csync_update.c +++ b/csync/src/csync_update.c @@ -361,8 +361,6 @@ out: st->mode = fs->mode; st->size = fs->size; st->modtime = fs->mtime; - st->uid = fs->uid; - st->gid = fs->gid; st->nlink = fs->nlink; st->type = type; st->etag = NULL; @@ -587,6 +585,8 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn, } /* == see if really stat has to be called. */ + /* FIXME: No, this stat() is actually useless. This is the only place where we call it + and we get all info already thanks to csync_vio_readdir */ fs = csync_vio_file_stat_new(); res = csync_vio_stat(ctx, filename, fs); diff --git a/csync/src/csync_util.c b/csync/src/csync_util.c index ffcdafbe5..64f2ccfaf 100644 --- a/csync/src/csync_util.c +++ b/csync/src/csync_util.c @@ -128,59 +128,6 @@ void csync_win32_set_file_hidden( const char *file, bool h ) { #endif } -csync_vio_file_stat_t *csync_vio_convert_file_stat(csync_file_stat_t *st) { - csync_vio_file_stat_t *vfs = NULL; - - if (st == NULL) { - return NULL; - } - - vfs = csync_vio_file_stat_new(); - if (vfs == NULL) { - return NULL; - } - vfs->acl = NULL; - if (st->pathlen > 0) { - vfs->name = c_strdup(st->path); - } - vfs->uid = st->uid; - vfs->gid = st->gid; - - vfs->atime = 0; - vfs->mtime = st->modtime; - vfs->ctime = 0; - - vfs->size = st->size; - vfs->blksize = 0; /* Depricated. */ - vfs->blkcount = 0; - - vfs->mode = st->mode; - vfs->device = 0; - vfs->inode = st->inode; - vfs->nlink = st->nlink; - - /* fields. */ - vfs->fields = CSYNC_VIO_FILE_STAT_FIELDS_TYPE - + CSYNC_VIO_FILE_STAT_FIELDS_PERMISSIONS - + CSYNC_VIO_FILE_STAT_FIELDS_INODE - + CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT - + CSYNC_VIO_FILE_STAT_FIELDS_SIZE - + CSYNC_VIO_FILE_STAT_FIELDS_MTIME - + CSYNC_VIO_FILE_STAT_FIELDS_UID - + CSYNC_VIO_FILE_STAT_FIELDS_GID; - - if (st->type == CSYNC_FTW_TYPE_DIR) - vfs->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; - else if (st->type == CSYNC_FTW_TYPE_FILE) - vfs->type = CSYNC_VIO_FILE_TYPE_REGULAR; - else if (st->type == CSYNC_FTW_TYPE_SLINK) - vfs->type = CSYNC_VIO_FILE_TYPE_SYMBOLIC_LINK; - else - vfs->type = CSYNC_VIO_FILE_TYPE_UNKNOWN; - - return vfs; -} - bool (*csync_file_locked_or_open_ext) (const char*) = 0; // filled in by library user void set_csync_file_locked_or_open_ext(bool (*f) (const char*)); void set_csync_file_locked_or_open_ext(bool (*f) (const char*)) { diff --git a/csync/src/csync_util.h b/csync/src/csync_util.h index 20fe6940d..50ee03f14 100644 --- a/csync/src/csync_util.h +++ b/csync/src/csync_util.h @@ -32,8 +32,5 @@ void csync_memstat_check(void); void csync_win32_set_file_hidden( const char *file, bool hidden ); -/* Convert a csync_file_stat_t to csync_vio_file_stat_t */ -csync_vio_file_stat_t *csync_vio_convert_file_stat(csync_file_stat_t *st); - bool csync_file_locked_or_open( const char *dir, const char *fname); #endif /* _CSYNC_UTIL_H */ diff --git a/csync/src/vio/csync_vio_file_stat.c b/csync/src/vio/csync_vio_file_stat.c index 010e851db..46b2d450e 100644 --- a/csync/src/vio/csync_vio_file_stat.c +++ b/csync/src/vio/csync_vio_file_stat.c @@ -22,14 +22,8 @@ #include "vio/csync_vio_file_stat.h" csync_vio_file_stat_t *csync_vio_file_stat_new(void) { - csync_vio_file_stat_t *file_stat = NULL; - - file_stat = (csync_vio_file_stat_t *) c_malloc(sizeof(csync_vio_file_stat_t)); - if (file_stat == NULL) { - return NULL; - } - file_stat->etag = NULL; - memset(file_stat->file_id, 0, FILE_ID_BUF_SIZE+1); + csync_vio_file_stat_t *file_stat = (csync_vio_file_stat_t *) c_malloc(sizeof(csync_vio_file_stat_t)); + ZERO_STRUCTP(file_stat); return file_stat; } @@ -39,12 +33,6 @@ void csync_vio_file_stat_destroy(csync_vio_file_stat_t *file_stat) { return; } - if (file_stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_SYMLINK_NAME) { - SAFE_FREE(file_stat->u.symlink_name); - } - if (file_stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_CHECKSUM) { - SAFE_FREE(file_stat->u.checksum); - } if (file_stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_ETAG) { SAFE_FREE(file_stat->etag); } diff --git a/csync/src/vio/csync_vio_file_stat.h b/csync/src/vio/csync_vio_file_stat.h index 849e532a0..198c83afa 100644 --- a/csync/src/vio/csync_vio_file_stat.h +++ b/csync/src/vio/csync_vio_file_stat.h @@ -62,42 +62,31 @@ enum csync_vio_file_stat_fields_e { CSYNC_VIO_FILE_STAT_FIELDS_INODE = 1 << 4, CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT = 1 << 5, CSYNC_VIO_FILE_STAT_FIELDS_SIZE = 1 << 6, - CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_COUNT = 1 << 7, /* will be removed */ - CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_SIZE = 1 << 8, /* will be removed */ +// CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_COUNT = 1 << 7, /* will be removed */ +// CSYNC_VIO_FILE_STAT_FIELDS_BLOCK_SIZE = 1 << 8, /* will be removed */ CSYNC_VIO_FILE_STAT_FIELDS_ATIME = 1 << 9, CSYNC_VIO_FILE_STAT_FIELDS_MTIME = 1 << 10, CSYNC_VIO_FILE_STAT_FIELDS_CTIME = 1 << 11, - CSYNC_VIO_FILE_STAT_FIELDS_SYMLINK_NAME = 1 << 12, - CSYNC_VIO_FILE_STAT_FIELDS_CHECKSUM = 1 << 13, - CSYNC_VIO_FILE_STAT_FIELDS_ACL = 1 << 14, - CSYNC_VIO_FILE_STAT_FIELDS_UID = 1 << 15, - CSYNC_VIO_FILE_STAT_FIELDS_GID = 1 << 16, +// CSYNC_VIO_FILE_STAT_FIELDS_SYMLINK_NAME = 1 << 12, +// CSYNC_VIO_FILE_STAT_FIELDS_CHECKSUM = 1 << 13, +// CSYNC_VIO_FILE_STAT_FIELDS_ACL = 1 << 14, +// CSYNC_VIO_FILE_STAT_FIELDS_UID = 1 << 15, +// CSYNC_VIO_FILE_STAT_FIELDS_GID = 1 << 16, CSYNC_VIO_FILE_STAT_FIELDS_ETAG = 1 << 17, CSYNC_VIO_FILE_STAT_FIELDS_FILE_ID = 1 << 18 }; struct csync_vio_file_stat_s { - union { - char *symlink_name; - char *checksum; - } u; - - void *acl; char *name; char *etag; char file_id[FILE_ID_BUF_SIZE+1]; - uid_t uid; - gid_t gid; - time_t atime; time_t mtime; time_t ctime; int64_t size; - int64_t blksize; /* will be removed in future, not used in csync */ - unsigned long blkcount; /* will be removed in future, not used in csync */ mode_t mode; @@ -109,10 +98,6 @@ struct csync_vio_file_stat_s { enum csync_vio_file_type_e type; enum csync_vio_file_flags_e flags; - - void *reserved1; - void *reserved2; - void *reserved3; }; csync_vio_file_stat_t *csync_vio_file_stat_new(void); diff --git a/csync/src/vio/csync_vio_local.c b/csync/src/vio/csync_vio_local.c index ce2b257d0..fdea8ae9c 100644 --- a/csync/src/vio/csync_vio_local.c +++ b/csync/src/vio/csync_vio_local.c @@ -331,11 +331,6 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) { buf->inode = sb.st_ino; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_INODE; - /* Both values are only initialized to zero as they are not used in csync */ - /* They are deprecated and will be rmemoved later. */ - buf->blksize = 0; - buf->blkcount = 0; - buf->atime = sb.st_atime; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_ATIME; @@ -348,12 +343,6 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) { buf->nlink = sb.st_nlink; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_LINK_COUNT; - buf->uid = sb.st_uid; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_UID; - - buf->gid = sb.st_gid; - buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_GID; - buf->size = sb.st_size; buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; diff --git a/src/mirall/syncengine.cpp b/src/mirall/syncengine.cpp index 3e5c6c9c7..c2b64ea27 100644 --- a/src/mirall/syncengine.cpp +++ b/src/mirall/syncengine.cpp @@ -287,7 +287,6 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote ) Q_ASSERT("Non handled error-status"); /* No error string */ } - item._isDirectory = file->type == CSYNC_FTW_TYPE_DIR; item._modtime = file->modtime; item._etag = file->etag;