/* * 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 */ }
/* * Authentication callback. Is set by ne_set_server_auth to be called * from the neon lib to authenticate a request. */ static int ne_auth( void *userdata, const char *realm, int attempt, char *username, char *password) { char buf[NE_ABUFSIZ] = {0}; (void) userdata; (void) realm; /* DEBUG_WEBDAV( "Authentication required %s, realm ); */ if( username && password ) { DEBUG_WEBDAV( "Authentication required %s", username ); if( dav_session.user ) { /* allow user without password */ snprintf(username, NE_ABUFSIZ, "%s", dav_session.user); if( dav_session.pwd ) { strncpy( password, dav_session.pwd, NE_ABUFSIZ ); } else { (*_authcb) ("Enter your password: "******"%s", buf ); } } else if( _authcb != NULL ){ /* call the csync callback */ DEBUG_WEBDAV("Call the csync callback for %s", realm ); (*_authcb) ("Enter your username: "******"%s", buf ); (*_authcb) ("Enter your password: "******"%s", buf ); } else { DEBUG_WEBDAV("I can not authenticate!"); } } return attempt; }
static void install_content_reader( ne_request *req, void *userdata, const ne_status *status ) { const char *enc = NULL; struct transfer_context *writeCtx = userdata; (void) status; if( !writeCtx ) { DEBUG_WEBDAV("Error: install_content_reader called without valid write context!"); return; } enc = ne_get_response_header( req, "Content-Encoding" ); if( status && status->code != 200 ) { DEBUG_WEBDAV("Content encoding ist <%s> with status %d", enc ? enc : "empty", status ? status->code : -1 ); } if( enc && c_streq( enc, "gzip" )) { writeCtx->decompress = ne_decompress_reader( req, ne_accept_2xx, compress_reader, /* reader callback */ (void*) writeCtx ); /* userdata */ } else { ne_add_response_body_reader( req, ne_accept_2xx, uncompress_reader, (void*) writeCtx ); writeCtx->decompress = NULL; } }
static int verify_sslcert(void *userdata, int failures, const ne_ssl_certificate *certificate) { char problem[LEN]; char buf[MAX(NE_SSL_DIGESTLEN, NE_ABUFSIZ)]; int ret = -1; const ne_ssl_certificate *cert = certificate; (void) userdata; memset( problem, 0, LEN ); while( cert ) { addSSLWarning( problem, "There are problems with the SSL certificate:\n", LEN ); if( failures & NE_SSL_NOTYETVALID ) { addSSLWarning( problem, " * The certificate is not yet valid.\n", LEN ); } if( failures & NE_SSL_EXPIRED ) { addSSLWarning( problem, " * The certificate has expired.\n", LEN ); } if( failures & NE_SSL_UNTRUSTED ) { addSSLWarning( problem, " * The certificate is not trusted!\n", LEN ); } if( failures & NE_SSL_IDMISMATCH ) { addSSLWarning( problem, " * The hostname for which the certificate was " "issued does not match the hostname of the server\n", LEN ); } if( failures & NE_SSL_BADCHAIN ) { addSSLWarning( problem, " * The certificate chain contained a certificate other than the server cert\n", LEN ); } if( failures & NE_SSL_REVOKED ) { addSSLWarning( problem, " * The server certificate has been revoked by the issuing authority.\n", LEN ); } if (ne_ssl_cert_digest(cert, buf) == 0) { addSSLWarning( problem, "Certificate fingerprint: ", LEN ); addSSLWarning( problem, buf, LEN ); addSSLWarning( problem, "\n", LEN ); } cert = ne_ssl_cert_signedby( cert ); } addSSLWarning( problem, "Do you want to accept the certificate chain anyway?\nAnswer yes to do so and take the risk: ", LEN ); if( _authcb ){ /* call the csync callback */ DEBUG_WEBDAV("Call the csync callback for SSL problems"); memset( buf, 0, NE_ABUFSIZ ); (*_authcb) ( problem, buf, NE_ABUFSIZ-1, 1, 0, NULL ); if( buf[0] == 'y' || buf[0] == 'Y') { ret = 0; } else { DEBUG_WEBDAV("Authentication callback replied %s", buf ); } } DEBUG_WEBDAV("## VERIFY_SSL CERT: %d", ret ); return ret; }
static ssize_t owncloud_write(csync_vio_method_handle_t *fhandle, const void *buf, size_t count) { struct transfer_context *writeCtx = NULL; size_t written = 0; size_t bufWritten = 0; if (fhandle == NULL) { return -1; } writeCtx = (struct transfer_context*) fhandle; /* check if there is space left in the mem buffer */ if( writeCtx->bytes_written + count > PUT_BUFFER_SIZE ) { if( writeCtx->fileWritten == 0 ) { DEBUG_WEBDAV(("Remaining Mem Buffer size to small, push to disk " "(current buf size %lu)\n", (unsigned long) writeCtx->bytes_written)); } /* write contents to disk */ if( writeCtx->fd > -1 ) { if( writeCtx->bytes_written > 0 ) { /* there is something in the buffer already. Store to disk */ written = write( writeCtx->fd, _buffer, writeCtx->bytes_written ); if( written != writeCtx->bytes_written ) { DEBUG_WEBDAV(("WRN: Written bytes from buffer not equal to count\n")); } /* reset the buffer counter */ writeCtx->bytes_written = 0; } /* also write the incoming memory buffer content to file */ if( count > 0 ) { bufWritten = write( writeCtx->fd, buf, count ); if( bufWritten != count ) { DEBUG_WEBDAV(("WRN: Written bytes not equal to count\n")); } } /* set a flag that file was used, needed in the close routine */ writeCtx->fileWritten = 1; } else { /* problem: the file descriptor is not valid. */ DEBUG_WEBDAV(("ERR: Not a valid file descriptor in write\n")); } } else { /* still space in the buffer */ memcpy( _buffer + writeCtx->bytes_written, buf, count ); writeCtx->bytes_written += count; bufWritten = count; } return bufWritten; }
static int owncloud_rename(const char *olduri, const char *newuri) { char *src = NULL; char *target = NULL; int rc = NE_OK; rc = dav_connect(olduri); if (rc < 0) { errno = EINVAL; } src = _cleanPath( olduri ); target = _cleanPath( newuri ); if( rc >= 0 ) { DEBUG_WEBDAV("MOVE: %s => %s: %d", src, target, rc ); rc = ne_move(dav_session.ctx, 1, src, target ); if (rc != NE_OK ) { set_errno_from_session(); } } SAFE_FREE( src ); SAFE_FREE( target ); if( rc != NE_OK ) return -1; return 0; }
/* * helper: convert a resource struct to file_stat struct. */ static csync_vio_file_stat_t *resourceToFileStat( 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) { return NULL; } lfs->name = c_strdup( res->name ); lfs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; if( res->type == resr_normal ) { lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; lfs->type = CSYNC_VIO_FILE_TYPE_REGULAR; } else if( res->type == resr_collection ) { lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; lfs->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; } else { DEBUG_WEBDAV("ERROR: Unknown resource type %d", res->type); } lfs->mtime = res->modtime; lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_MTIME; lfs->size = res->size; lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE; return lfs; }
void clear_propfind_recursive_cache(csync_owncloud_ctx_t *ctx) { if (ctx->propfind_recursive_cache) { DEBUG_WEBDAV("clear_propfind_recursive_cache Invalidating.."); c_rbtree_destroy(ctx->propfind_recursive_cache, _tree_destructor); ctx->propfind_recursive_cache = NULL; } }
void clear_propfind_recursive_cache(void) { if (propfind_recursive_cache) { DEBUG_WEBDAV("clear_propfind_recursive_cache Invalidating.."); c_rbtree_destroy(propfind_recursive_cache, _tree_destructor); propfind_recursive_cache = NULL; } }
static int verify_sslcert(void *userdata, int failures, const ne_ssl_certificate *cert) { char problem[LEN]; char buf[NE_ABUFSIZ]; int ret = -1; (void) cert; memset( problem, 0, LEN ); addSSLWarning( problem, "There are problems with the SSL certificate:\n", LEN ); if( failures & NE_SSL_NOTYETVALID ) { addSSLWarning( problem, " * The certificate is not yet valid.\n", LEN ); } if( failures & NE_SSL_EXPIRED ) { addSSLWarning( problem, " * The certificate has expired.\n", LEN ); } if( failures & NE_SSL_UNTRUSTED ) { addSSLWarning( problem, " * The certificate is not trusted!\n", LEN ); } if( failures & NE_SSL_IDMISMATCH ) { addSSLWarning( problem, " * The hostname for which the certificate was " "issued does not match the hostname of the server\n", LEN ); } if( failures & NE_SSL_BADCHAIN ) { addSSLWarning( problem, " * The certificate chain contained a certificate other than the server cert\n", LEN ); } if( failures & NE_SSL_REVOKED ) { addSSLWarning( problem, " * The server certificate has been revoked by the issuing authority.\n", LEN ); } addSSLWarning( problem, "Do you want to accept the certificate anyway?\nAnswer yes to do so and take the risk: ", LEN ); if( _authcb ){ /* call the csync callback */ DEBUG_WEBDAV("Call the csync callback for SSL problems"); memset( buf, 0, NE_ABUFSIZ ); (*_authcb) ( problem, buf, NE_ABUFSIZ-1, 1, 0, userdata ); if( strcmp( buf, "yes" ) == 0 ) { ret = 0; } } DEBUG_WEBDAV("## VERIFY_SSL CERT: %d", ret ); return ret; }
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; }
static ssize_t owncloud_read(csync_vio_method_handle_t *fhandle, void *buf, size_t count) { (void) fhandle; (void) buf; (void) count; DEBUG_WEBDAV("XXXXXXXXXXXXXXXXXXX We should not have come here - owncloud_read"); return 0; }
void fill_recursive_propfind_cache(const char *uri, const char *curi) { fetch_resource_list_recursive(uri, curi); if (propfind_recursive_cache_depth <= 2) { DEBUG_WEBDAV("fill_recursive_propfind_cache %s Server maybe did not give us an 'infinity' depth result", curi); /* transform the cache to the normal cache in propfind_cache */ propfind_cache = get_listdir_context_from_recursive_cache(curi); /* clear the cache, it is bogus since the server returned only results for Depth 1 */ clear_propfind_recursive_cache(); } else { DEBUG_WEBDAV("fill_recursive_propfind_cache %s We received %d elements deep for 'infinity' depth (%d folders, %d files)", curi, propfind_recursive_cache_depth, propfind_recursive_cache_folder_count, propfind_recursive_cache_file_count); } }
struct listdir_context *get_listdir_context_from_recursive_cache(const char *curi) { propfind_recursive_element_t *element = NULL; struct listdir_context *fetchCtx = NULL; struct resource *iterator, *r; if (!propfind_recursive_cache) { DEBUG_WEBDAV("get_listdir_context_from_recursive_cache No cache"); return NULL; } element = c_rbtree_node_data(c_rbtree_find(propfind_recursive_cache, curi)); if (!element) { DEBUG_WEBDAV("get_listdir_context_from_recursive_cache No element %s in cache found", curi); return NULL; } /* Out of the element, create a listdir_context.. if we could be sure that it is immutable, we could ref instead.. need to investigate */ fetchCtx = c_malloc( sizeof( struct listdir_context )); ZERO_STRUCTP(fetchCtx); fetchCtx->list = NULL; fetchCtx->target = c_strdup(curi); fetchCtx->currResource = NULL; fetchCtx->ref = 1; iterator = element->children; r = NULL; while (iterator) { r = resource_dup(iterator); r->next = fetchCtx->list; fetchCtx->list = r; iterator = iterator->next; fetchCtx->result_count++; /* DEBUG_WEBDAV("get_listdir_context_from_cache Returning cache for %s element %s", fetchCtx->target, fetchCtx->list->uri); */ } r = resource_dup(element->self); r->next = fetchCtx->list; fetchCtx->result_count++; fetchCtx->list = r; fetchCtx->currResource = fetchCtx->list; DEBUG_WEBDAV("get_listdir_context_from_cache Returning cache for %s (%d elements)", fetchCtx->target, fetchCtx->result_count); return fetchCtx; }
int owncloud_closedir(csync_vio_handle_t *dhandle) { struct listdir_context *fetchCtx = dhandle; DEBUG_WEBDAV("closedir method called %p!", dhandle); free_fetchCtx(fetchCtx); return 0; }
static ssize_t owncloud_read(csync_vio_method_handle_t *fhandle, void *buf, size_t count) { struct transfer_context *writeCtx; size_t len = 0; csync_stat_t st; writeCtx = (struct transfer_context*) fhandle; DEBUG_WEBDAV(( "read called on %s (fd=%d)!\n", writeCtx->tmpFileName, writeCtx->fd )); if( ! fhandle ) { errno = EBADF; return -1; } if( writeCtx->fd == -1 ) { /* open the downloaded file to read from */ #ifdef _WIN32 _fmode = _O_BINARY; #endif if (( writeCtx->fd = open( writeCtx->tmpFileName, O_RDONLY )) < 0) { DEBUG_WEBDAV(("Could not open local file %s\n", writeCtx->tmpFileName )); errno = EIO; return -1; } else { if (fstat( writeCtx->fd, &st ) < 0) { DEBUG_WEBDAV(("Could not stat file %s\n", writeCtx->tmpFileName )); errno = EIO; return -1; } DEBUG_WEBDAV(("local downlaod file size=%d\n", (int) st.st_size )); } } if( writeCtx->fd ) { len = read( writeCtx->fd, buf, count ); writeCtx->bytes_written = writeCtx->bytes_written + len; } /* DEBUG_WEBDAV(( "read len: %d %ul\n", len, count )); */ return len; }
static int owncloud_utimes(const char *uri, const struct timeval *times) { ne_proppatch_operation ops[2]; ne_propname pname; int rc = NE_OK; char val[255]; char *curi; curi = _cleanPath( uri ); if( ! uri ) { errno = ENOENT; return -1; } if( !times ) { errno = EACCES; return -1; /* FIXME: Find good errno */ } pname.nspace = "DAV:"; pname.name = "lastmodified"; snprintf( val, sizeof(val), "%ld", times->tv_sec ); DEBUG_WEBDAV("Setting LastModified of %s to %s", curi, val ); ops[0].name = &pname; ops[0].type = ne_propset; ops[0].value = val; ops[1].name = NULL; rc = ne_proppatch( dav_session.ctx, curi, ops ); SAFE_FREE(curi); if( rc != NE_OK ) { errno = EPERM; DEBUG_WEBDAV("Error in propatch: %d", rc); return -1; } return 0; }
/* Configure the proxy depending on the variables */ static int configureProxy( ne_session *session ) { int port = 8080; int re = -1; if( ! session ) return -1; if( ! dav_session.proxy_type ) return 0; /* Go by NoProxy per default */ if( dav_session.proxy_port > 0 ) { port = dav_session.proxy_port; } if( c_streq(dav_session.proxy_type, "NoProxy" )) { DEBUG_WEBDAV("No proxy configured."); re = 0; } else if( c_streq(dav_session.proxy_type, "DefaultProxy") || c_streq(dav_session.proxy_type, "HttpProxy") || c_streq(dav_session.proxy_type, "HttpCachingProxy") || c_streq(dav_session.proxy_type, "Socks5Proxy")) { if( dav_session.proxy_host ) { DEBUG_WEBDAV("%s at %s:%d", dav_session.proxy_type, dav_session.proxy_host, port ); if (c_streq(dav_session.proxy_type, "Socks5Proxy")) { ne_session_socks_proxy(session, NE_SOCK_SOCKSV5, dav_session.proxy_host, port, dav_session.proxy_user, dav_session.proxy_pwd); } else { ne_session_proxy(session, dav_session.proxy_host, port ); } re = 2; } else { DEBUG_WEBDAV("%s requested but no proxy host defined.", dav_session.proxy_type ); /* we used to try ne_system_session_proxy here, but we should rather err out to behave exactly like the caller. */ } } else { DEBUG_WEBDAV( "Unsupported Proxy: %s", dav_session.proxy_type ); } return re; }
/* Normally, this module uses get and put. But for creation of new files * with owncloud_creat, write is still needed. */ static ssize_t owncloud_write(csync_vio_method_handle_t *fhandle, const void *buf, size_t count) { struct transfer_context *writeCtx; int rc = 0; int neon_stat; const ne_status *status; writeCtx = (struct transfer_context*) fhandle; if (fhandle == NULL) { errno = EBADF; rc = -1; } ne_set_request_body_buffer(writeCtx->req, buf, count ); /* Start the request. */ neon_stat = ne_request_dispatch( writeCtx->req ); set_errno_from_neon_errcode( neon_stat ); status = ne_get_status( writeCtx->req ); if( status->klass != 2 ) { DEBUG_WEBDAV("sendfile request failed with http status %d!", status->code); set_errno_from_http_errcode( status->code ); /* decide if soft error or hard error that stops the whole sync. */ /* Currently all problems concerning one file are soft errors */ if( status->klass == 4 /* Forbidden and stuff, soft error */ ) { rc = 1; } else if( status->klass == 5 /* Server errors and such */ ) { rc = 1; /* No Abort on individual file errors. */ } else { rc = 1; } } else { DEBUG_WEBDAV("write request all ok, result code %d", status->code); } return rc; }
/* * directory functions */ csync_vio_handle_t *owncloud_opendir(const char *uri) { struct listdir_context *fetchCtx = NULL; char *curi = NULL; DEBUG_WEBDAV("opendir method called on %s", uri ); dav_connect( uri ); curi = _cleanPath( uri ); if (is_first_propfind && !dav_session.no_recursive_propfind) { is_first_propfind = false; // Try to fill it fill_recursive_propfind_cache(uri, curi); } if (propfind_recursive_cache) { // Try to fetch from recursive cache (if we have one) fetchCtx = get_listdir_context_from_recursive_cache(curi); } SAFE_FREE(curi); is_first_propfind = false; if (fetchCtx) { return fetchCtx; } /* fetchCtx = fetch_resource_list( uri, NE_DEPTH_ONE ); */ fetchCtx = fetch_resource_list_attempts( uri, NE_DEPTH_ONE); if( !fetchCtx ) { /* errno is set properly in fetch_resource_list */ DEBUG_WEBDAV("Errno set to %d", errno); return NULL; } else { fetchCtx->currResource = fetchCtx->list; DEBUG_WEBDAV("opendir returning handle %p (count=%d)", (void*) fetchCtx, fetchCtx->result_count ); return fetchCtx; } /* no freeing of curi because its part of the fetchCtx and gets freed later */ }
static int compress_reader(void *userdata, const char *buf, size_t len) { struct transfer_context *writeCtx = userdata; size_t written = 0; if( buf && writeCtx->fd ) { /* DEBUG_WEBDAV("Writing compressed %d bytes, len); */ written = write(writeCtx->fd, buf, len); if( written != len ) { DEBUG_WEBDAV("WRN: compress reader wrote wrong len"); } return NE_OK; } return NE_ERROR; }
static int fetch_resource_list( const char *curi, int depth, struct listdir_context *fetchCtx ) { int ret = 0; /* do a propfind request and parse the results in the results function, set as callback */ ret = ne_simple_propfind( dav_session.ctx, curi, depth, ls_props, results, fetchCtx ); if( ret == NE_OK ) { DEBUG_WEBDAV(("Simple propfind OK.\n" )); fetchCtx->currResource = fetchCtx->list; } return ret; }
/* cleanPath to return an escaped path of an uri */ static char *_cleanPath( const char* uri ) { int rc = 0; char *path; char *re = NULL; rc = c_parse_uri( uri, NULL, NULL, NULL, NULL, NULL, &path ); if( rc < 0 ) { DEBUG_WEBDAV(("Unable to cleanPath %s\n", uri ? uri: "" )); re = NULL; } else { re = ne_path_escape( path ); } SAFE_FREE( path ); return re; }
static int uncompress_reader(void *userdata, const char *buf, size_t len) { struct transfer_context *writeCtx = userdata; size_t written = 0; if( buf && writeCtx->fd ) { /* DEBUG_WEBDAV(("Writing NON compressed %d bytes\n", len)); */ len = write(writeCtx->fd, buf, len); if( len != written ) { DEBUG_WEBDAV(("WRN: uncompress_reader wrote wrong num of bytes\n")); } return NE_OK; } return NE_ERROR; }
/* cleanPath to return an escaped path of an uri */ char *_cleanPath( const char* uri ) { int rc = 0; char *path = NULL; char *re = NULL; rc = c_parse_uri( uri, NULL, NULL, NULL, NULL, NULL, &path ); if( rc < 0 ) { DEBUG_WEBDAV("Unable to cleanPath %s", uri ? uri: "<zero>" ); re = NULL; } else { if(path) { re = ne_path_escape( path ); } } SAFE_FREE( path ); return re; }
static int owncloud_closedir(csync_vio_method_handle_t *dhandle) { struct listdir_context *fetchCtx = dhandle; struct resource *r = fetchCtx->list; struct resource *rnext = NULL; DEBUG_WEBDAV("closedir method called %p!", dhandle); while( r ) { rnext = r->next; SAFE_FREE(r->uri); SAFE_FREE(r->name); SAFE_FREE(r); r = rnext; } SAFE_FREE( fetchCtx->target ); SAFE_FREE( dhandle ); return 0; }
/* * helper: convert a resource struct to file_stat struct. */ void resourceToFileStat(csync_vio_file_stat_t *lfs, struct resource *res ) { ZERO_STRUCTP(lfs); lfs->name = c_strdup( res->name ); lfs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; if( res->type == resr_normal ) { lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; lfs->type = CSYNC_VIO_FILE_TYPE_REGULAR; } else if( res->type == resr_collection ) { lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; lfs->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; } else { DEBUG_WEBDAV("ERROR: Unknown resource type %d", res->type); } 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; } csync_vio_file_stat_set_file_id(lfs, res->file_id); if (res->directDownloadUrl) { lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADURL; lfs->directDownloadUrl = c_strdup(res->directDownloadUrl); } if (res->directDownloadCookies) { lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADCOOKIES; lfs->directDownloadCookies = c_strdup(res->directDownloadCookies); } if (strlen(res->remotePerm) > 0) { lfs->fields = CSYNC_VIO_FILE_STAT_FIELDS_PERM; strncpy(lfs->remotePerm, res->remotePerm, sizeof(lfs->remotePerm)); } }
/* * helper: convert a resource struct to file_stat struct. */ void resourceToFileStat(csync_vio_file_stat_t *lfs, struct resource *res ) { ZERO_STRUCTP(lfs); lfs->name = c_strdup( res->name ); lfs->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; if( res->type == resr_normal ) { lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; lfs->type = CSYNC_VIO_FILE_TYPE_REGULAR; } else if( res->type == resr_collection ) { lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; lfs->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; } else { 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; } csync_vio_file_stat_set_file_id(lfs, res->file_id); if (res->directDownloadUrl) { lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADURL; lfs->directDownloadUrl = c_strdup(res->directDownloadUrl); } if (res->directDownloadCookies) { lfs->fields |= CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADCOOKIES; lfs->directDownloadCookies = c_strdup(res->directDownloadCookies); } }
void set_errno_from_neon_errcode( int neon_code ) { if( neon_code != NE_OK ) { DEBUG_WEBDAV("Neon error code was %d", neon_code); } switch(neon_code) { case NE_OK: /* Success, but still the possiblity of problems */ case NE_ERROR: /* Generic error; use ne_get_error(session) for message */ set_errno_from_session(); /* Something wrong with http communication */ break; case NE_LOOKUP: /* Server or proxy hostname lookup failed */ errno = ERRNO_LOOKUP_ERROR; break; case NE_AUTH: /* User authentication failed on server */ errno = ERRNO_USER_UNKNOWN_ON_SERVER; break; case NE_PROXYAUTH: /* User authentication failed on proxy */ errno = ERRNO_PROXY_AUTH; break; case NE_CONNECT: /* Could not connect to server */ errno = ERRNO_CONNECT; break; case NE_TIMEOUT: /* Connection timed out */ errno = ERRNO_TIMEOUT; break; case NE_FAILED: /* The precondition failed */ errno = ERRNO_PRECONDITION; break; case NE_RETRY: /* Retry request (ne_end_request ONLY) */ errno = ERRNO_RETRY; break; case NE_REDIRECT: /* See ne_redirect.h */ errno = ERRNO_REDIRECT; break; default: errno = ERRNO_GENERAL_ERROR; } }
static int owncloud_mkdir(const char *uri, mode_t mode) { int rc = NE_OK; char buf[PATH_MAX +1]; int len = 0; char *path = _cleanPath( uri ); (void) mode; /* unused */ if( ! path ) { errno = EINVAL; rc = -1; } rc = dav_connect(uri); if (rc < 0) { errno = EINVAL; } /* the uri path is required to have a trailing slash */ if( rc >= 0 ) { memset( buf,0, PATH_MAX+1 ); len = strlen( path ); strncpy( buf, path, len ); if( buf[len-1] != '/' ) { buf[len] = '/'; } DEBUG_WEBDAV("MKdir on %s", buf ); rc = ne_mkcol(dav_session.ctx, buf ); if (rc != NE_OK ) { set_errno_from_session(); } } SAFE_FREE( path ); if( rc < 0 || rc != NE_OK ) { return -1; } return 0; }