Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/mod_dav_svn/repos.c view on Meta::CPAN
#include <http_request.h>
#include <http_protocol.h>
#include <http_log.h>
#include <http_core.h> /* for ap_construct_url */
#include <mod_dav.h>
#define CORE_PRIVATE /* To make ap_show_mpm public in 2.2 */
#include <http_config.h>
#include "svn_hash.h"
#include "svn_types.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_time.h"
#include "svn_fs.h"
#include "svn_repos.h"
#include "svn_dav.h"
#include "svn_sorts.h"
#include "svn_version.h"
#include "svn_props.h"
#include "svn_ctype.h"
#include "svn_subst.h"
#include "mod_dav_svn.h"
#include "svn_ra.h" /* for SVN_RA_CAPABILITY_* */
#include "svn_dirent_uri.h"
#include "private/svn_log.h"
#include "private/svn_fspath.h"
#include "private/svn_repos_private.h"
#include "dav_svn.h"
#define DEFAULT_ACTIVITY_DB "dav/activities.d"
struct dav_stream {
const dav_resource *res;
/* for reading from the FS */
svn_stream_t *rstream;
/* for writing to the FS. we use wstream OR the handler/baton. */
svn_stream_t *wstream;
svn_txdelta_window_handler_t delta_handler;
void *delta_baton;
};
/* Convenience structure that facilitates combined memory allocation of
a dav_resource and dav_resource_private pair. */
typedef struct dav_resource_combined {
dav_resource res;
dav_resource_private priv;
} dav_resource_combined;
/* Helper-wrapper around svn_fs_check_path(), which takes the same
arguments. But: if we attempt to stat a path like "file1/file2",
then still return 'svn_node_none' to signal nonexistence, rather
than a full-blown filesystem error. This allows mod_dav to throw
404 instead of 500. */
static dav_error *
fs_check_path(svn_node_kind_t *kind,
svn_fs_root_t *root,
const char *path,
apr_pool_t *pool)
{
svn_error_t *serr;
svn_node_kind_t my_kind;
serr = svn_fs_check_path(&my_kind, root, path, pool);
/* Possibly trap other fs-errors here someday -- errors which may
simply indicate the path's nonexistence, rather than a critical
problem. */
if (serr && serr->apr_err == SVN_ERR_FS_NOT_DIRECTORY)
{
svn_error_clear(serr);
*kind = svn_node_none;
return NULL;
}
else if (serr)
{
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
apr_psprintf(pool, "Error checking kind of "
"path '%s' in repository",
path),
pool);
}
*kind = my_kind;
return NULL;
}
static int
parse_version_uri(dav_resource_combined *comb,
const char *path,
const char *label,
int use_checked_in)
{
const char *slash;
const char *created_rev_str;
/* format: CREATED_REV/REPOS_PATH */
/* ### what to do with LABEL and USE_CHECKED_IN ?? */
comb->res.type = DAV_RESOURCE_TYPE_VERSION;
comb->res.versioned = TRUE;
slash = ap_strchr_c(path, '/');
if (slash == NULL)
{
/* http://host.name/repos/$svn/ver/0
This URL form refers to the root path of the repository.
*/
created_rev_str = apr_pstrndup(comb->res.pool, path, strlen(path));
comb->priv.root.rev = SVN_STR_TO_REV(created_rev_str);
comb->priv.repos_path = "/";
src/subversion/subversion/mod_dav_svn/repos.c view on Meta::CPAN
comb->res.type = DAV_RESOURCE_TYPE_REGULAR;
comb->res.versioned = TRUE;
/* The location of these resources corresponds directly to the URI,
and we keep the leading "/". */
comb->priv.repos_path = comb->priv.uri_path->data;
}
return FALSE;
}
static dav_error *
prep_regular(dav_resource_combined *comb)
{
apr_pool_t *pool = comb->res.pool;
dav_svn_repos *repos = comb->priv.repos;
svn_error_t *serr;
dav_error *derr;
svn_node_kind_t kind;
/* A REGULAR resource might have a specific revision already (e.g. if it
is part of a baseline collection). However, if it doesn't, then we
will assume that we need the youngest revision.
### other cases besides a BC? */
if (comb->priv.root.rev == SVN_INVALID_REVNUM)
{
serr = svn_fs_youngest_rev(&comb->priv.root.rev, repos->fs, pool);
if (serr != NULL)
{
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"Could not determine the proper "
"revision to access",
pool);
}
}
/* get the root of the tree */
serr = svn_fs_revision_root(&comb->priv.root.root, repos->fs,
comb->priv.root.rev, pool);
if (serr != NULL)
{
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"Could not open the root of the "
"repository",
pool);
}
derr = fs_check_path(&kind, comb->priv.root.root,
comb->priv.repos_path, pool);
if (derr != NULL)
return derr;
comb->res.exists = (kind != svn_node_none);
comb->res.collection = (kind == svn_node_dir);
/* HACK: dav_get_resource_state() is making shortcut assumptions
about how to distinguish a null resource from a lock-null
resource. This is the only way to get around that problem.
Without it, it won't ever detect lock-nulls, and thus 'svn unlock
nonexistentURL' will always return 404's. */
if (! comb->res.exists)
comb->priv.r->path_info = (char *) "";
return NULL;
}
static dav_error *
prep_version(dav_resource_combined *comb)
{
svn_error_t *serr;
apr_pool_t *pool = comb->res.pool;
/* we are accessing the Version Resource by REV/PATH */
/* ### assert: .baselined = TRUE */
/* if we don't have a revision, then assume the youngest */
if (!SVN_IS_VALID_REVNUM(comb->priv.root.rev))
{
serr = svn_fs_youngest_rev(&comb->priv.root.rev,
comb->priv.repos->fs,
pool);
if (serr != NULL)
{
/* ### might not be a baseline */
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"Could not fetch 'youngest' revision "
"to enable accessing the latest "
"baseline resource.",
pool);
}
}
/* ### baselines have no repos_path, and we don't need to open
### a root (yet). we just needed to ensure that we have the proper
### revision number. */
if (!comb->priv.root.root)
{
serr = svn_fs_revision_root(&comb->priv.root.root,
comb->priv.repos->fs,
comb->priv.root.rev,
pool);
if (serr != NULL)
{
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"Could not open a revision root.",
pool);
}
}
/* ### we should probably check that the revision is valid */
comb->res.exists = TRUE;
/* Set up the proper URI. Most likely, we arrived here via a VCC,
so the URI will be incorrect. Set the canonical form. */
/* ### assuming a baseline */
comb->res.uri = dav_svn__build_uri(comb->priv.repos,
( run in 0.996 second using v1.01-cache-2.11-cpan-39bf76dae61 )