/*============================================================================== Copyright (C) 2007 Martin Furter This file is part of svntar svntar is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. svntar is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with svntar; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ==============================================================================*/ #include "svn_tar_url.h" #include "svn_props.h" typedef struct { apr_pool_t* pool; svn_client_ctx_t* ctx; svn_tar_t* tar; const char* url; svn_revnum_t rev; apr_time_t mtime; svn_ra_session_t* ra; /* for use in the callbacks */ const char* path; apr_hash_t* props; } list_baton_t; static svn_error_t* url_propget( const char* name, const char** value, void* baton, apr_pool_t* pool ) { list_baton_t* lb = baton; if( lb->props ) { svn_string_t* s; s = apr_hash_get( lb->props, name, APR_HASH_KEY_STRING ); *value = s ? s->data : 0; } else { *value = 0; } return SVN_NO_ERROR; } static svn_error_t* url_file_stream( svn_stream_t* filestream, void* baton, apr_pool_t* pool ) { list_baton_t* lb = baton; SVN_ERR( svn_ra_get_file( lb->ra, lb->path, lb->rev, filestream, 0, 0, pool ) ); return svn_stream_close( filestream ); } static svn_error_t* list_func( void* baton, const char* path, const svn_dirent_t* dirent, const svn_lock_t* lock, const char* abs_path, apr_pool_t* pool ) { list_baton_t* lb = baton; if( path[0] == 0 ) { return SVN_NO_ERROR; } if( !lb->ra ) { SVN_ERR( svn_client_open_ra_session( &lb->ra, lb->url, lb->ctx, lb->pool ) ); } if( dirent->has_props ) { if( dirent->kind == svn_node_dir ) { SVN_ERR( svn_ra_get_dir2( lb->ra, 0 /* dirents */, 0 /* fetched_rev */, &lb->props, path, lb->rev, 0 /* dirent_fields */, pool ) ); } else { SVN_ERR( svn_ra_get_file( lb->ra, path, lb->rev, 0 /* stream */, 0 /* fetched_rev */, &lb->props, pool ) ); } } else { lb->props = 0; } lb->path = path; return svn_tar_add( path, dirent->kind, dirent->size, url_propget, baton, url_file_stream, baton, lb->tar, pool ); } svn_error_t* info_receiver( void* baton, const char* path, const svn_info_t* info, apr_pool_t* pool ) { list_baton_t* lb = baton; lb->url = apr_pstrdup( lb->pool, info->URL ); lb->rev = info->rev; lb->mtime = info->last_changed_date; // info->kind; return SVN_NO_ERROR; } svn_error_t* svn_tar_url( svn_tar_t* tar, const char* url, svn_opt_revision_t* peg, svn_opt_revision_t* rev, svn_client_ctx_t* ctx, apr_pool_t* pool ) { list_baton_t lb; lb.pool = pool; lb.ctx = ctx; lb.tar = tar; lb.url = url; lb.ra = NULL; SVN_ERR( svn_client_info( url, peg, rev, info_receiver, &lb, FALSE /* recurse */, ctx, pool ) ); svn_tar_set_mtime( tar, apr_time_sec( lb.mtime ) ); SVN_ERR( svn_client_list( url, peg, rev, TRUE /* recurse */, SVN_DIRENT_ALL, FALSE /* fetch_locks */, list_func, &lb, ctx, pool ) ); return SVN_NO_ERROR; }