Esempio n. 1
0
/*
 * directory functions
 */
static csync_vio_method_handle_t *owncloud_opendir(const char *uri) {
    int rc;
    struct listdir_context *fetchCtx = NULL;
    struct resource *reslist = NULL;
    char *curi = _cleanPath( uri );

    DEBUG_WEBDAV("opendir method called on %s", uri );

    dav_connect( uri );

    fetchCtx = c_malloc( sizeof( struct listdir_context ));

    fetchCtx->list = reslist;
    fetchCtx->target = curi;
    fetchCtx->include_target = 0;
    fetchCtx->currResource = NULL;

    rc = fetch_resource_list( curi, NE_DEPTH_ONE, fetchCtx );
    if( rc != NE_OK ) {
        set_errno_from_session();
        return NULL;
    } else {
        fetchCtx->currResource = fetchCtx->list;
        DEBUG_WEBDAV("opendir returning handle %p", (void*) fetchCtx );
        return fetchCtx;
    }
    /* no freeing of curi because its part of the fetchCtx and gets freed later */
}
Esempio n. 2
0
static void fetch_a_context(void **state) {
    struct listdir_context  *fetchCtx = NULL;
    char *curi = _cleanPath(_credentials.oc_server);
    int rc = 0;
    unsigned int i;

    (void) state;

    fetchCtx = c_malloc( sizeof( struct listdir_context ));
    fetchCtx->target = curi;
    fetchCtx->include_target = 1;
    
    rc = fetch_resource_list( curi, NE_DEPTH_ONE, fetchCtx );
    assert_int_equal( rc, 0 );
    printf("Results: %d\n", fetchCtx->result_count);
    
    fetchCtx->currResource = fetchCtx->list;
    for( i = 0; i < fetchCtx->result_count; i++ ) {
	assert_true( fetchCtx->currResource != NULL );
	assert_true( fetchCtx->currResource->uri != NULL );
	assert_true( fetchCtx->currResource->name != NULL );
	
	printf( "   %s -> %s\n", fetchCtx->currResource->uri, fetchCtx->currResource->name );
	fetchCtx->currResource = fetchCtx->currResource->next;
    } 
}
Esempio n. 3
0
static struct listdir_context *fetch_resource_list_attempts(const char *uri, int depth)
{
    int i;

    struct listdir_context *fetchCtx = NULL;
    for(i = 0; i < 10; ++i) {
        fetchCtx = fetch_resource_list(uri, depth);
        if(fetchCtx) break;
        /* only loop in case the content is not XML formatted. Otherwise for every
         * non successful stat (for non existing directories) its tried 10 times. */
        if( errno != ERRNO_WRONG_CONTENT ) break;

        DEBUG_WEBDAV("=> Errno after fetch resource list for %s: %d", uri, errno);
        DEBUG_WEBDAV("   New attempt %i", i);
    }
    return fetchCtx;
}
Esempio n. 4
0
/*
 * 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;
}
Esempio n. 5
0
static char *remote_completion(const char *text, int state)
{
    static struct resource *reslist, *current;
    static int len;
    static time_t last_fetch;
    static char *last_path;

    char *name;
    
    if (state == 0) {
	/* Check to see if we should refresh the dumb cache.
	 * or, initialize the local cache of remote filenames
	 * The remote resource list persists until a completion
	 * in a new context is requested or the cache expires.
	 */

	/* TODO get cache expire time from config, currently from cadaver.h
	 * TODO cache and fetch on deep/absolute paths: (path: /a/b/, text: c/d)
	 */
	if (last_fetch < (time(NULL) - COMPLETION_CACHE_EXPIRE) 
	    || !last_path 
	    || strcmp(session.uri.path, last_path) != 0) {

	    if (last_path != NULL) {
		free(last_path);
	    }

	    if (reslist != NULL) { 
		free_resource_list(reslist); 
	    }

	    /* Hide the connection status */
	    ne_set_notifier(session.sess, NULL, NULL);
	    if (fetch_resource_list(session.sess, session.uri.path, 1, 0, 
                                    &reslist) != NE_OK) {
		reslist = NULL;
	    }
	    /* Restore the session connection printing */
	    ne_set_notifier(session.sess, notifier, NULL);

	    last_path = ne_strdup(session.uri.path);
	}

	current = reslist;
	len = strlen(text);
	time(&last_fetch);
    }

    while (current) {
	/* Massage the absolute URI to a URI relative to our path */
	/* Copy & paste & search & replace from ls.c */
	if (ne_path_has_trailing_slash(current->uri)) {
	    current->uri[strlen(current->uri)-1] = '\0';
	}

	name = strrchr(current->uri, '/');
	if (name != NULL && strlen(name+1) > 0) {
	    name++;
	} else {
	    name = current->uri;
	}
	name = ne_path_unescape(name);

	if (strncmp(text, name, len) == 0) {
	    current = current->next;
	    /* FIXME: readline docs say readline will free() this when
	     * it's finished with, although 'memprof' shows that it
	     * leaks. */
	    return name;
	}

	current = current->next;
    }
    
    return NULL;
}