📄 repos.c
字号:
/*
* repos.c: mod_dav_svn repository provider functions for Subversion
*
* ====================================================================
* Copyright (c) 2000-2004 CollabNet. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://subversion.tigris.org/license-1.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
*
* This software consists of voluntary contributions made by many
* individuals. For exact contribution history, see the revision
* history and logs, available at http://subversion.tigris.org/.
* ====================================================================
*/
#include <httpd.h>
#include <http_protocol.h>
#include <http_log.h>
#include <http_core.h> /* for ap_construct_url */
#include <mod_dav.h>
#define APR_WANT_STRFUNC
#include <apr_want.h>
#include <apr_strings.h>
#include <apr_hash.h>
#include "svn_types.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_fs.h"
#include "svn_repos.h"
#include "svn_dav.h"
#include "svn_sorts.h"
#include "svn_version.h"
#include "dav_svn.h"
#include "mod_dav_svn.h"
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;
};
typedef struct {
ap_filter_t *output;
apr_pool_t *pool;
} dav_svn_diff_ctx_t;
typedef struct {
dav_resource res;
dav_resource_private priv;
} dav_resource_combined;
/* private context for doing a walk */
typedef struct {
/* the input walk parameters */
const dav_walk_params *params;
/* reused as we walk */
dav_walk_resource wres;
/* the current resource */
dav_resource res; /* wres.resource refers here */
dav_resource_private info; /* the info in res */
svn_stringbuf_t *uri; /* the uri within res */
svn_stringbuf_t *repos_path; /* the repos_path within res */
} dav_svn_walker_context;
static int dav_svn_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 = "/";
}
else if (slash == path)
{
/* the CREATED_REV was missing(?)
### not sure this can happen, though, because it would imply two
### slashes, yet those are cleaned out within get_resource
*/
return TRUE;
}
else
{
apr_size_t len = slash - path;
created_rev_str = apr_pstrndup(comb->res.pool, path, len);
comb->priv.root.rev = SVN_STR_TO_REV(created_rev_str);
comb->priv.repos_path = slash;
}
/* if the CREATED_REV parsing blew, then propagate it. */
if (comb->priv.root.rev == SVN_INVALID_REVNUM)
return TRUE;
return FALSE;
}
static int dav_svn_parse_history_uri(dav_resource_combined *comb,
const char *path,
const char *label,
int use_checked_in)
{
/* format: ??? */
/* ### what to do with LABEL and USE_CHECKED_IN ?? */
comb->res.type = DAV_RESOURCE_TYPE_HISTORY;
/* ### parse path */
comb->priv.repos_path = path;
return FALSE;
}
static int dav_svn_parse_working_uri(dav_resource_combined *comb,
const char *path,
const char *label,
int use_checked_in)
{
const char *slash;
/* format: ACTIVITY_ID/REPOS_PATH */
/* ### what to do with LABEL and USE_CHECKED_IN ?? */
comb->res.type = DAV_RESOURCE_TYPE_WORKING;
comb->res.working = TRUE;
comb->res.versioned = TRUE;
slash = ap_strchr_c(path, '/');
/* This sucker starts with a slash. That's bogus. */
if (slash == path)
return TRUE;
if (slash == NULL)
{
/* There's no slash character in our path. Assume it's just an
ACTIVITY_ID pointing to the root path. That should be cool.
We'll just drop through to the normal case handling below. */
comb->priv.root.activity_id = apr_pstrdup(comb->res.pool, path);
comb->priv.repos_path = "/";
}
else
{
comb->priv.root.activity_id = apr_pstrndup(comb->res.pool, path,
slash - path);
comb->priv.repos_path = slash;
}
return FALSE;
}
static int dav_svn_parse_activity_uri(dav_resource_combined *comb,
const char *path,
const char *label,
int use_checked_in)
{
/* format: ACTIVITY_ID */
/* ### what to do with LABEL and USE_CHECKED_IN ?? */
comb->res.type = DAV_RESOURCE_TYPE_ACTIVITY;
comb->priv.root.activity_id = path;
return FALSE;
}
static int dav_svn_parse_vcc_uri(dav_resource_combined *comb,
const char *path,
const char *label,
int use_checked_in)
{
/* format: "default" (a singleton) */
if (strcmp(path, DAV_SVN_DEFAULT_VCC_NAME) != 0)
return TRUE;
if (label == NULL && !use_checked_in)
{
/* Version Controlled Configuration (baseline selector) */
/* ### mod_dav has a proper model for these. technically, they are
### version-controlled resources (REGULAR), but that just monkeys
### up a lot of stuff for us. use a PRIVATE for now. */
comb->res.type = DAV_RESOURCE_TYPE_PRIVATE; /* _REGULAR */
comb->priv.restype = DAV_SVN_RESTYPE_VCC;
comb->res.exists = TRUE;
comb->res.versioned = TRUE;
comb->res.baselined = TRUE;
/* NOTE: comb->priv.repos_path == NULL */
}
else
{
/* a specific Version Resource; in this case, a Baseline */
int revnum;
if (label != NULL)
{
revnum = SVN_STR_TO_REV(label); /* assume slash terminates */
if (!SVN_IS_VALID_REVNUM(revnum))
return TRUE; /* ### be nice to get better feedback */
}
else /* use_checked_in */
{
/* use the DAV:checked-in value of the VCC. this is always the
"latest" (or "youngest") revision. */
/* signal dav_svn_prep_version to look it up */
revnum = SVN_INVALID_REVNUM;
}
comb->res.type = DAV_RESOURCE_TYPE_VERSION;
/* exists? need to wait for now */
comb->res.versioned = TRUE;
comb->res.baselined = TRUE;
/* which baseline (revision tree) to access */
comb->priv.root.rev = revnum;
/* NOTE: comb->priv.repos_path == NULL */
/* NOTE: comb->priv.created_rev == SVN_INVALID_REVNUM */
}
return FALSE;
}
static int dav_svn_parse_baseline_coll_uri(dav_resource_combined *comb,
const char *path,
const char *label,
int use_checked_in)
{
const char *slash;
int revnum;
/* format: REVISION/REPOS_PATH */
/* ### what to do with LABEL and USE_CHECKED_IN ?? */
slash = ap_strchr_c(path, '/');
if (slash == NULL)
slash = "/"; /* they are referring to the root of the BC */
else if (slash == path)
return TRUE; /* the REVISION was missing(?)
### not sure this can happen, though, because
### it would imply two slashes, yet those are
### cleaned out within get_resource */
revnum = SVN_STR_TO_REV(path); /* assume slash terminates conversion */
if (!SVN_IS_VALID_REVNUM(revnum))
return TRUE; /* ### be nice to get better feedback */
/* ### mod_dav doesn't have a proper model for these. they are standard
### VCRs, but we need some additional semantics attached to them.
### need to figure out a way to label them as special. */
comb->res.type = DAV_RESOURCE_TYPE_REGULAR;
comb->res.versioned = TRUE;
comb->priv.root.rev = revnum;
comb->priv.repos_path = slash;
return FALSE;
}
static int dav_svn_parse_baseline_uri(dav_resource_combined *comb,
const char *path,
const char *label,
int use_checked_in)
{
int revnum;
/* format: REVISION */
/* ### what to do with LABEL and USE_CHECKED_IN ?? */
revnum = SVN_STR_TO_REV(path);
if (!SVN_IS_VALID_REVNUM(revnum))
return TRUE; /* ### be nice to get better feedback */
/* create a Baseline resource (a special Version Resource) */
comb->res.type = DAV_RESOURCE_TYPE_VERSION;
/* exists? need to wait for now */
comb->res.versioned = TRUE;
comb->res.baselined = TRUE;
/* which baseline (revision tree) to access */
comb->priv.root.rev = revnum;
/* NOTE: comb->priv.repos_path == NULL */
/* NOTE: comb->priv.created_rev == SVN_INVALID_REVNUM */
return FALSE;
}
static int dav_svn_parse_wrk_baseline_uri(dav_resource_combined *comb,
const char *path,
const char *label,
int use_checked_in)
{
const char *slash;
/* format: ACTIVITY_ID/REVISION */
/* ### what to do with LABEL and USE_CHECKED_IN ?? */
comb->res.type = DAV_RESOURCE_TYPE_WORKING;
comb->res.working = TRUE;
comb->res.versioned = TRUE;
comb->res.baselined = TRUE;
if ((slash = ap_strchr_c(path, '/')) == NULL
|| slash == path
|| slash[1] == '\0')
return TRUE;
comb->priv.root.activity_id = apr_pstrndup(comb->res.pool, path,
slash - path);
comb->priv.root.rev = SVN_STR_TO_REV(slash + 1);
/* NOTE: comb->priv.repos_path == NULL */
return FALSE;
}
static const struct special_defn
{
const char *name;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -