예제 #1
0
파일: csync_owncloud.c 프로젝트: gco/csync
static csync_vio_file_stat_t *owncloud_readdir(csync_vio_method_handle_t *dhandle) {

    struct listdir_context *fetchCtx = dhandle;
    csync_vio_file_stat_t *lfs = NULL;

    if( fetchCtx == NULL) {
        /* DEBUG_WEBDAV("An empty dir or at end); */
        return NULL;
    }

    if( fetchCtx->currResource ) {
        /* FIXME: Who frees the allocated mem for lfs, allocated in the helper func? */
        lfs = resourceToFileStat( fetchCtx->currResource );

        /* set pointer to next element */
        fetchCtx->currResource = fetchCtx->currResource->next;

        /* fill the static stat buf as input for the stat function */
        _fs.name   = lfs->name;
        _fs.mtime  = lfs->mtime;
        _fs.fields = lfs->fields;
        _fs.type   = lfs->type;
        _fs.size   = lfs->size;
    }

    // DEBUG_WEBDAV("LFS fields: %s: %d, lfs->name, lfs->type );
    return lfs;
}
예제 #2
0
static csync_vio_file_stat_t *owncloud_readdir(csync_vio_method_handle_t *dhandle) {

    struct listdir_context *fetchCtx = dhandle;

    if( fetchCtx == NULL) {
        /* DEBUG_WEBDAV("An empty dir or at end"); */
        return NULL;
    }

    while( fetchCtx->currResource ) {
        resource* currResource = fetchCtx->currResource;
        char *escaped_path = NULL;

        /* set pointer to next element */
        fetchCtx->currResource = fetchCtx->currResource->next;

        /* It seems strange: first uri->path is unescaped to escape it in the next step again.
         * The reason is that uri->path is not completely escaped (ie. it seems only to have
         * spaces escaped), while the fetchCtx->target is fully escaped.
         * See http://bugs.owncloud.org/thebuggenie/owncloud/issues/oc-613
         */
        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);
            SAFE_FREE( escaped_path );
            return lfs;
        }

        /* This is the target URI */
        SAFE_FREE( escaped_path );
    }

    return NULL;
}
예제 #3
0
파일: csync_owncloud.c 프로젝트: gco/csync
/*
 * file functions
 */
static int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf) {
    /* get props:
     *   modtime
     *   creattime
     *   size
     */
    int rc = 0;
    csync_vio_file_stat_t *lfs = NULL;
    struct listdir_context  *fetchCtx = NULL;
    char *curi = NULL;
    char *decodedUri = NULL;
    char strbuf[PATH_MAX +1];
    int len = 0;

    DEBUG_WEBDAV("owncloud_stat %s called", uri );

    buf->name = c_basename(uri);

    if (buf->name == NULL) {
        csync_vio_file_stat_destroy(buf);
        errno = ENOMEM;
        return -1;
    }

    /* check if the data in the static 'cache' fs is for the same file.
     * The cache is filled by readdir which is often called directly before
     * stat. If the cache matches, a http call is saved.
     */
    if( _fs.name && strcmp( buf->name, _fs.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 = _fs.fields;
        buf->type   = _fs.type;
        buf->mtime  = _fs.mtime;
        buf->size   = _fs.size;
        buf->mode   = _stat_perms( _fs.type );
    } else {
        /* fetch data via a propfind call. */
        fetchCtx = c_malloc( sizeof( struct listdir_context ));
        if( ! fetchCtx ) {
            errno = ENOMEM;
            return -1;
        }

        curi = _cleanPath( uri );

        DEBUG_WEBDAV("I have no stat cache, call propfind for %s.", curi );
        fetchCtx->list = NULL;
        fetchCtx->target = curi;
        fetchCtx->include_target = 1;
        fetchCtx->currResource = NULL;

        rc = fetch_resource_list( curi, NE_DEPTH_ONE, fetchCtx );
        if( rc != NE_OK ) {
          if( errno != ENOENT ) {
            set_errno_from_session();
          }
          DEBUG_WEBDAV("stat fails with errno %d", errno );

          return -1;
        }

        if( fetchCtx ) {
            struct resource *res = fetchCtx->list;
            while( res ) {
                /* remove trailing slashes */
                len = strlen(res->uri);
                while( len > 0 && res->uri[len-1] == '/' ) --len;
                memset( strbuf, 0, PATH_MAX+1);
                strncpy( strbuf, res->uri, len < PATH_MAX ? len : PATH_MAX );
                decodedUri = ne_path_unescape( curi ); /* allocates memory */
                if( c_streq(strbuf, decodedUri )) {
                    SAFE_FREE( decodedUri );
                    break;
                }
                res = res->next;
                SAFE_FREE( decodedUri );
            }
            DEBUG_WEBDAV("Working on file %s", res ? res->name : "NULL");

            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 = lfs->fields;
                buf->type   = lfs->type;
                buf->mtime  = lfs->mtime;
                buf->size   = lfs->size;
                buf->mode   = _stat_perms( lfs->type );

                csync_vio_file_stat_destroy( lfs );
            }
            SAFE_FREE( fetchCtx );
        }
    }
    DEBUG_WEBDAV("STAT result: %s, type=%d", buf->name ? buf->name:"NULL",
                  buf->type );
    return 0;
}
예제 #4
0
/*
 * file functions
 */
int owncloud_stat(const char *uri, csync_vio_file_stat_t *buf) {
    /* get props:
     *   modtime
     *   creattime
     *   size
     */
    csync_vio_file_stat_t *lfs = NULL;
    struct listdir_context  *fetchCtx = NULL;
    char *decodedUri = NULL;
    int len = 0;
    errno = 0;

    DEBUG_WEBDAV("owncloud_stat %s called", uri );

    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 );
        return 0;
    }
    DEBUG_WEBDAV("owncloud_stat => Could not find in stat cache %s", uri);

    /* fetch data via a propfind call. */
    /* fetchCtx = fetch_resource_list( uri, NE_DEPTH_ONE); */
    fetchCtx = fetch_resource_list_attempts( uri, NE_DEPTH_ONE);
    DEBUG_WEBDAV("=> Errno after fetch resource list for %s: %d", uri, errno);
    if (!fetchCtx) {
        return -1;
    }

    if( fetchCtx ) {
        struct resource *res = fetchCtx->list;
        while( res ) {
            /* remove trailing slashes */
            len = strlen(res->uri);
            while( len > 0 && res->uri[len-1] == '/' ) --len;
            decodedUri = ne_path_unescape( fetchCtx->target ); /* allocates memory */

            /* Only do the comparaison of the part of the string without the trailing
               slashes, and make sure decodedUri is not too large */
            if( strncmp(res->uri, decodedUri, len ) == 0 && decodedUri[len] == '\0') {
                SAFE_FREE( decodedUri );
                break;
            }
            res = res->next;
            SAFE_FREE( decodedUri );
        }
        if( res ) {
            DEBUG_WEBDAV("Working on file %s", res->name );
        } else {
            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 );
        }

        free_fetchCtx( fetchCtx );
    }
    DEBUG_WEBDAV("STAT result from propfind: %s, mtime: %llu", buf->name ? buf->name:"NULL",
                    (unsigned long long) buf->mtime );

    return 0;
}