⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 props.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * props.c :  routines for fetching DAV properties * * ==================================================================== * 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 <apr_pools.h>#include <apr_tables.h>#include <apr_strings.h>#define APR_WANT_STRFUNC#include <apr_want.h>#include <ne_socket.h>#include <ne_basic.h>#include <ne_props.h>#include <ne_xml.h>#include "svn_error.h"#include "svn_path.h"#include "svn_dav.h"#include "svn_base64.h"#include "svn_xml.h"#include "svn_time.h"#include "svn_pools.h"#include "svn_props.h"#include "../libsvn_ra/ra_loader.h"#include "svn_private_config.h"#include "ra_dav.h"/* some definitions of various properties that may be fetched */const ne_propname svn_ra_dav__vcc_prop = {  "DAV:", "version-controlled-configuration"};const ne_propname svn_ra_dav__checked_in_prop = {  "DAV:", "checked-in"};/* when we begin a checkout, we fetch these from the "public" resources to   steer us towards a Baseline Collection. we fetch the resourcetype to   verify that we're accessing a collection. */static const ne_propname starting_props[] ={  { "DAV:", "version-controlled-configuration" },  { "DAV:", "resourcetype" },  { SVN_DAV_PROP_NS_DAV, "baseline-relative-path" },  { SVN_DAV_PROP_NS_DAV, "repository-uuid"},  { NULL }};/* when speaking to a Baseline to reach the Baseline Collection, fetch these   properties. */static const ne_propname baseline_props[] ={  { "DAV:", "baseline-collection" },  { "DAV:", "version-name" },  { NULL }};/*** Propfind Implementation ***/typedef struct {  svn_ra_dav__xml_elmid id;  const char *name;  int is_property;      /* is it a property, or part of some structure? */} elem_defn;static const elem_defn elem_definitions[] ={  /*** NOTE: Make sure that every item in here is also represented in       propfind_elements[] ***/  /* DAV elements */  { ELEM_multistatus, "DAV:multistatus", 0 },  { ELEM_response, "DAV:response", 0 },  { ELEM_href, "DAV:href", SVN_RA_DAV__XML_CDATA },  { ELEM_propstat, "DAV:propstat", 0 },  { ELEM_prop, "DAV:prop", 0 },  { ELEM_status, "DAV:status", SVN_RA_DAV__XML_CDATA },  { ELEM_baseline, "DAV:baseline", SVN_RA_DAV__XML_CDATA },  { ELEM_collection, "DAV:collection", SVN_RA_DAV__XML_CDATA },  { ELEM_resourcetype, "DAV:resourcetype", 0 },  { ELEM_baseline_coll, SVN_RA_DAV__PROP_BASELINE_COLLECTION, 0 },  { ELEM_checked_in, SVN_RA_DAV__PROP_CHECKED_IN, 0 },  { ELEM_vcc, SVN_RA_DAV__PROP_VCC, 0 },  { ELEM_version_name, SVN_RA_DAV__PROP_VERSION_NAME, 1 },  { ELEM_get_content_length, SVN_RA_DAV__PROP_GETCONTENTLENGTH, 1 },  { ELEM_creationdate, SVN_RA_DAV__PROP_CREATIONDATE, 1 },  { ELEM_creator_displayname, SVN_RA_DAV__PROP_CREATOR_DISPLAYNAME, 1 },  /* SVN elements */  { ELEM_baseline_relpath, SVN_RA_DAV__PROP_BASELINE_RELPATH, 1 },  { ELEM_md5_checksum, SVN_RA_DAV__PROP_MD5_CHECKSUM, 1 },  { ELEM_repository_uuid, SVN_RA_DAV__PROP_REPOSITORY_UUID, 1 },  { ELEM_deadprop_count, SVN_RA_DAV__PROP_DEADPROP_COUNT, 1 },  { 0 }};static const svn_ra_dav__xml_elm_t propfind_elements[] = {  /*** NOTE: Make sure that every item in here is also represented in       elem_definitions[] ***/  /* DAV elements */  { "DAV:", "multistatus", ELEM_multistatus, 0 },  { "DAV:", "response", ELEM_response, 0 },  { "DAV:", "href", ELEM_href, SVN_RA_DAV__XML_CDATA },  { "DAV:", "propstat", ELEM_propstat, 0 },  { "DAV:", "prop", ELEM_prop, 0 },  { "DAV:", "status", ELEM_status, SVN_RA_DAV__XML_CDATA },  { "DAV:", "baseline", ELEM_baseline, SVN_RA_DAV__XML_CDATA },  { "DAV:", "baseline-collection", ELEM_baseline_coll, SVN_RA_DAV__XML_CDATA },  { "DAV:", "checked-in", ELEM_checked_in, 0 },  { "DAV:", "collection", ELEM_collection, SVN_RA_DAV__XML_CDATA },  { "DAV:", "resourcetype", ELEM_resourcetype, 0 },  { "DAV:", "version-controlled-configuration", ELEM_vcc, 0 },  { "DAV:", "version-name", ELEM_version_name, SVN_RA_DAV__XML_CDATA },  { "DAV:", "getcontentlength", ELEM_get_content_length,    SVN_RA_DAV__XML_CDATA },  { "DAV:", "creationdate", ELEM_creationdate, SVN_RA_DAV__XML_CDATA },  { "DAV:", "creator-displayname", ELEM_creator_displayname,    SVN_RA_DAV__XML_CDATA },  /* SVN elements */  { SVN_DAV_PROP_NS_DAV, "baseline-relative-path", ELEM_baseline_relpath,    SVN_RA_DAV__XML_CDATA },  { SVN_DAV_PROP_NS_DAV, "md5-checksum", ELEM_md5_checksum,    SVN_RA_DAV__XML_CDATA },  { SVN_DAV_PROP_NS_DAV, "repository-uuid", ELEM_repository_uuid,    SVN_RA_DAV__XML_CDATA },  { SVN_DAV_PROP_NS_DAV, "deadprop-count", ELEM_deadprop_count,    SVN_RA_DAV__XML_CDATA },  /* Unknowns */  { "", "", ELEM_unknown, SVN_RA_DAV__XML_COLLECT },  { NULL } };typedef struct propfind_ctx_t{  apr_hash_t *props; /* const char *URL-PATH -> svn_ra_dav_resource_t */  svn_ra_dav_resource_t *rsrc; /* the current resource. */  const char *encoding; /* property encoding (or NULL) */  int status; /* status for the current <propstat> (or 0 if unknown). */  apr_hash_t *propbuffer; /* holds properties until their status is known. */  svn_ra_dav__xml_elmid last_open_id; /* the id of the last opened tag. */  ne_xml_parser *parser; /* xml parser handling the PROPSET request. */  apr_pool_t *pool;} propfind_ctx_t;/* Look up an element definition ID.  May return NULL if the elem is   not recognized. */static const elem_defn *defn_from_id(svn_ra_dav__xml_elmid id){  const elem_defn *defn;  for (defn = elem_definitions; defn->name != NULL; ++defn)    {      if (id == defn->id)        return defn;    }  return NULL;}/* Assign URL to RSRC.  Use POOL for any allocations. */static void assign_rsrc_url(svn_ra_dav_resource_t *rsrc,                             const char *url,                            apr_pool_t *pool){  char *url_path;  apr_size_t len;  ne_uri parsed_url;  /* Parse the PATH element out of the URL.     NOTE: mod_dav does not (currently) use an absolute URL, but simply a     server-relative path (i.e. this uri_parse is effectively a no-op).  */  (void) ne_uri_parse(url, &parsed_url);  url_path = apr_pstrdup(pool, parsed_url.path);  ne_uri_free(&parsed_url);  /* Clean up trailing slashes from the URL. */  len = strlen(url_path);  if (len > 1 && url_path[len - 1] == '/')    url_path[len - 1] = '\0';  rsrc->url = url_path;}static int validate_element(void *userdata,                             svn_ra_dav__xml_elmid parent,                             svn_ra_dav__xml_elmid child){  switch (parent)    {    case ELEM_root:      if (child == ELEM_multistatus)        return SVN_RA_DAV__XML_VALID;      else        return SVN_RA_DAV__XML_INVALID;    case ELEM_multistatus:      if (child == ELEM_response)        return SVN_RA_DAV__XML_VALID;      else        return SVN_RA_DAV__XML_DECLINE;    case ELEM_response:      if ((child == ELEM_href) || (child == ELEM_propstat))        return SVN_RA_DAV__XML_VALID;      else        return SVN_RA_DAV__XML_DECLINE;    case ELEM_propstat:      if ((child == ELEM_prop) || (child == ELEM_status))        return SVN_RA_DAV__XML_VALID;      else        return SVN_RA_DAV__XML_DECLINE;    case ELEM_prop:      return SVN_RA_DAV__XML_VALID; /* handle all children of <prop> */            case ELEM_baseline_coll:    case ELEM_checked_in:    case ELEM_vcc:      if (child == ELEM_href)        return SVN_RA_DAV__XML_VALID;      else        return SVN_RA_DAV__XML_DECLINE; /* not concerned with other types */          case ELEM_resourcetype:      if ((child == ELEM_collection) || (child == ELEM_baseline))        return SVN_RA_DAV__XML_VALID;      else        return SVN_RA_DAV__XML_DECLINE; /* not concerned with other types                                           (### now) */    default:      return SVN_RA_DAV__XML_DECLINE;    }  /* NOTREACHED */}static int start_element(void *userdata,                          const svn_ra_dav__xml_elm_t *elm,                          const char **atts){  propfind_ctx_t *pc = userdata;  switch (elm->id)    {    case ELEM_response:      if (pc->rsrc)        return SVN_RA_DAV__XML_INVALID;      /* Create a new resource. */      pc->rsrc = apr_pcalloc(pc->pool, sizeof(*(pc->rsrc)));      pc->rsrc->pool = pc->pool;      pc->rsrc->propset = apr_hash_make(pc->pool);      pc->status = 0;      break;    case ELEM_propstat:      pc->status = 0;      break;    case ELEM_href:      /* Remember this <href>'s parent so that when we close this tag,         we know to whom the URL assignment belongs.  Could be the         resource itself, or one of the properties:         ELEM_baseline_coll, ELEM_checked_in, ELEM_vcc: */      pc->rsrc->href_parent = pc->last_open_id;      break;    case ELEM_collection:      pc->rsrc->is_collection = 1;      break;    case ELEM_unknown:      /* these are our user-visible properties, presumably. */      pc->encoding = ne_xml_get_attr(pc->parser, atts, SVN_DAV_PROP_NS_DAV,                                     "encoding");      if (pc->encoding)        pc->encoding = apr_pstrdup(pc->pool, pc->encoding);      break;    default:      /* nothing to do for these */      break;    }  /* Remember the last tag we opened. */  pc->last_open_id = elm->id;  return SVN_RA_DAV__XML_VALID;}static int end_element(void *userdata,                        const svn_ra_dav__xml_elm_t *elm,                       const char *cdata){  propfind_ctx_t *pc = userdata;  svn_ra_dav_resource_t *rsrc = pc->rsrc;  const char *name;  const svn_string_t *value = NULL;  const elem_defn *parent_defn;  const elem_defn *defn;  ne_status status;  switch (elm->id)    {    case ELEM_response:      /* Verify that we've received a URL for this resource. */      if (!pc->rsrc->url)        return SVN_RA_DAV__XML_INVALID;      /* Store the resource in the top-level hash table. */      apr_hash_set(pc->props, pc->rsrc->url, APR_HASH_KEY_STRING, pc->rsrc);      pc->rsrc = NULL;      return SVN_RA_DAV__XML_VALID;    case ELEM_propstat:      /* We're at the end of a set of properties.  Do the right thing         status-wise. */      if (pc->status)        {          /* We have a status.  Loop over the buffered properties, and             if the status is a good one (200), copy them into the             resources's property hash.  Regardless of the status,             we'll be removing these from the temporary buffer as we             go along. */          apr_hash_index_t *hi = apr_hash_first(pc->pool, pc->propbuffer);          for (; hi; hi = apr_hash_next(hi))            {              const void *key;              apr_ssize_t klen;              void *val;              apr_hash_this(hi, &key, &klen, &val);              if (pc->status == 200)                apr_hash_set(rsrc->propset, key, klen, val);              apr_hash_set(pc->propbuffer, key, klen, NULL);            }        }      else if (! pc->status)        {          /* No status at all?  Bogosity. */          return SVN_RA_DAV__XML_INVALID;        }      return SVN_RA_DAV__XML_VALID;    case ELEM_status:      /* Parse the <status> tag's CDATA for a status code. */      if (ne_parse_statusline(cdata, &status))        return SVN_RA_DAV__XML_INVALID;      free(status.reason_phrase);      pc->status = status.code;      return SVN_RA_DAV__XML_VALID;    case ELEM_href:      /* Special handling for <href> that belongs to the <response> tag. */      if (rsrc->href_parent == ELEM_response)        {          assign_rsrc_url(pc->rsrc, cdata, pc->pool);          return SVN_RA_DAV__XML_VALID;        }      /* Use the parent element's name, not the href. */      parent_defn = defn_from_id(rsrc->href_parent);      /* No known parent?  Get outta here. */      if (!parent_defn)        return SVN_RA_DAV__XML_VALID;      /* All other href's we'll treat as property values. */      name = parent_defn->name;      value = svn_string_create(cdata, pc->pool);      break;    default:      /*** This case is, as usual, for everything not covered by other           cases.  ELM->id should be either ELEM_unknown, or one of           the ids in the elem_definitions[] structure.  In this case,           we seek to handle properties.  Since ELEM_unknown should           only occur for properties, we will handle that id.  All           other ids will be searched for in the elem_definitions[]           structure to determine if they are properties.  Properties,           we handle; all else hits the road.  ***/      if (elm->id == ELEM_unknown)        {          name = apr_pstrcat(pc->pool, elm->nspace, elm->name, NULL);        }      else        {          defn = defn_from_id(elm->id);          if (! (defn && defn->is_property))            return SVN_RA_DAV__XML_VALID;          name = defn->name;                  }      /* Check for encoding attribute. */      if (pc->encoding == NULL) {        /* Handle the property value by converting it to string. */        value = svn_string_create(cdata, pc->pool);        break;      }      /* Check for known encoding type */      if (strcmp(pc->encoding, "base64") != 0)        return SVN_RA_DAV__XML_INVALID;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -