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

📄 util.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * util.c :  utility functions for the RA/DAV library * * ==================================================================== * 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>#define APR_WANT_STRFUNC#include <apr_want.h>#include <ne_socket.h>#include <ne_uri.h>#include <ne_compress.h>#include <ne_basic.h>#include "svn_pools.h"#include "svn_path.h"#include "svn_string.h"#include "svn_utf.h"#include "svn_xml.h"#include "svn_private_config.h"#include "ra_dav.h"#define WOOTWOOT 1typedef struct {  apr_pool_t *pool;                          /* pool on which this is alloc-d */  void *original_userdata;                   /* userdata for callbacks */  const svn_ra_dav__xml_elm_t *elements;     /* old-style elements table */  svn_ra_dav__xml_validate_cb *validate_cb;  /* old-style validate callback */  svn_ra_dav__xml_startelm_cb *startelm_cb;  /* old-style startelm callback */  svn_ra_dav__xml_endelm_cb *endelm_cb;      /* old-style endelm callback */  svn_stringbuf_t *cdata_accum;              /* stringbuffer for CDATA */} neon_shim_baton_t;const svn_ra_dav__xml_elm_t *svn_ra_dav__lookup_xml_elem(const svn_ra_dav__xml_elm_t *table,                            const char *nspace,                            const char *name){  /* placeholder for `unknown' element if it's present */  const svn_ra_dav__xml_elm_t *elem_unknown = NULL;  const svn_ra_dav__xml_elm_t *elem;  for(elem = table; elem->nspace; ++elem)    {      if (strcmp(elem->nspace, nspace) == 0          && strcmp(elem->name, name) == 0)        return elem;      /* Use a single loop to save CPU cycles.       *       * Maybe this element is defined as `unknown'? */      if (elem->id == ELEM_unknown)        elem_unknown = elem;    }  /* ELEM_unknown position in the table or NULL */  return elem_unknown;}/** Fill in temporary structure for ELEM_unknown element. * * Call only for element ELEM_unknown!  For Neon 0.23 API * compatibility, we need to fill the XML element structure with real * namespace and element name, as "old-style" handler used to get that * from Neon parser. This is a hack, so don't expect it to be elegant. * The @a elem_pointer is a reference to element pointer which is * returned by svn_ra_dav__lookup_xml_elem, and supposedly points at * en entry in the XML elements table supplied by an "old-style" * handler. @a elem_unknown_temporary is a reference to XML element * structure allocated on the stack. There's no reason to allocate it * anywhere else because it's going to use @a nspace and @a name which * are passed into the "new-style" handler by the Neon parser, so the * structure pointed at by @a elem_unknown_temporary must die when the * calling function completes. This function is designed to be called * from "new-style" startelm and endelm callbacks. */static voidhandle_unknown(const svn_ra_dav__xml_elm_t **elem_pointer,               svn_ra_dav__xml_elm_t *elem_unknown_temporary,               const char *nspace, const char *name){  elem_unknown_temporary->nspace = nspace;  elem_unknown_temporary->name = name;  elem_unknown_temporary->id = (*elem_pointer)->id;  elem_unknown_temporary->flags = (*elem_pointer)->flags;  /* The pointer will use temporary record instead of a table record */  *elem_pointer = elem_unknown_temporary;}/** (Neon 0.24) Start element parsing. * * Calls "old-style" API callbacks validate_cb and startelm_cb to emulate * Neon 0.23 parser. @a userdata is a @c neon_shim_baton_t instance. * ---- ne_xml.h ---- * The startelm callback may return: *   <0 =>  abort the parse (NE_XML_ABORT) *    0 =>  decline this element  (NE_XML_DECLINE) *   >0 =>  accept this element; value is state for this element. * The 'parent' integer is the state returned by the handler of the * parent element. */static intshim_startelm(void *userdata, int parent_state, const char *nspace,              const char *name, const char **attrs){  neon_shim_baton_t *baton = userdata;  svn_ra_dav__xml_elm_t elem_unknown_temporary;  const svn_ra_dav__xml_elm_t *elem =    svn_ra_dav__lookup_xml_elem(baton->elements, nspace, name);  int rc;  if (!elem)    return NE_XML_DECLINE; /* Let Neon handle this */  /* TODO: explore an option of keeping element pointer in the baton   * to cut one loop in endelm */  /* 'parent' here actually means a parent element's id as opposed   * to 'parent' parameter passed to the startelm() function */  rc = baton->validate_cb(baton->original_userdata, parent_state, elem->id);  if (rc != SVN_RA_DAV__XML_VALID) {    return (rc == SVN_RA_DAV__XML_DECLINE) ? NE_XML_DECLINE : NE_XML_ABORT;  }  if (elem->id == ELEM_unknown)    handle_unknown(&elem, &elem_unknown_temporary, nspace, name);  rc = baton->startelm_cb(baton->original_userdata, elem, attrs);  if (rc != SVN_RA_DAV__XML_VALID) {    return (rc == SVN_RA_DAV__XML_DECLINE) ? NE_XML_DECLINE : NE_XML_ABORT;  }  if (baton->cdata_accum != NULL)    svn_stringbuf_setempty(baton->cdata_accum);  else    baton->cdata_accum = svn_stringbuf_create("", baton->pool);  /* @a parent in the pre-Neon 0.24 interface was a parent's element   * id but now it's the status returned by parent's startelm(), so we need to   * bridge this by returning this element's id as a status.   * We also need to ensure that element ids start with 1, because   * zero is `decline'. See ra_dav.h definition of ELEM_* values.   */  return elem->id;}/** (Neon 0.24) Collect element's contents. * * Collects element's contents into @a userdata string buffer. @a userdata is a * @c neon_shim_baton_t instance. * May return non-zero to abort the parse. */static int shim_cdata(void *userdata, int state, const char *cdata, size_t len){  const neon_shim_baton_t *baton = userdata;  svn_stringbuf_appendbytes(baton->cdata_accum, cdata, len);  return 0; /* no error */}/** (Neon 0.24) Finish parsing element. * * Calls "old-style" endelm_cb callback. @a userdata is a @c neon_shim_baton_t * instance. * May return non-zero to abort the parse. */static int shim_endelm(void *userdata, int state, const char *nspace,                       const char *name){  const neon_shim_baton_t *baton = userdata;  svn_ra_dav__xml_elm_t elem_unknown_temporary;  const svn_ra_dav__xml_elm_t *elem =    svn_ra_dav__lookup_xml_elem(baton->elements, nspace, name);  int rc;  if (!elem)    return -1; /* shouldn't be here if startelm didn't abort the parse */  if (elem->id == ELEM_unknown)    handle_unknown(&elem, &elem_unknown_temporary, nspace, name);  rc = baton->endelm_cb(baton->original_userdata,                        elem,                        baton->cdata_accum->data);  if (rc != SVN_RA_DAV__XML_VALID)    return -1; /* abort the parse */  return 0; /* no error */}/** Push an XML handler onto Neon's handler stack. * * Parser @a p uses a stack of handlers to process XML. The handler is * composed of validation callback @a validate_cb, start-element * callback @a startelm_cb, and end-element callback @a endelm_cb, which * collectively handle elements supplied in an array @a elements. Parser * passes given user baton @a userdata to all callbacks. * This is a new function on top of ne_xml_push_handler, adds memory pool * @a pool as the last parameter. This parameter is not used with Neon * 0.23.9, but will be with Neon 0.24. When Neon 0.24 is used, ra_dav * receives calls from the new interface and performs functions described * above by itself, using @a elements and calling callbacks according to * 0.23 interface. */static void shim_xml_push_handler(ne_xml_parser *p,                                  const svn_ra_dav__xml_elm_t *elements,                                  svn_ra_dav__xml_validate_cb validate_cb,                                  svn_ra_dav__xml_startelm_cb startelm_cb,                                  svn_ra_dav__xml_endelm_cb endelm_cb,                                   void *userdata,                                  apr_pool_t *pool){  neon_shim_baton_t *baton = apr_pcalloc(pool, sizeof(neon_shim_baton_t));  baton->pool = pool;  baton->original_userdata = userdata;  baton->elements = elements;  baton->validate_cb = validate_cb;  baton->startelm_cb = startelm_cb;  baton->endelm_cb = endelm_cb;  baton->cdata_accum = NULL; /* don't create until startelm is called */  ne_xml_push_handler(p, shim_startelm, shim_cdata, shim_endelm, baton);}void svn_ra_dav__copy_href(svn_stringbuf_t *dst, const char *src){  ne_uri parsed_url;  /* parse the PATH element out of the URL and store it.     ### do we want to verify the rest matches the current session?     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(src, &parsed_url);  svn_stringbuf_set(dst, parsed_url.path);  ne_uri_free(&parsed_url);}svn_error_t *svn_ra_dav__convert_error(ne_session *sess,                                       const char *context,                                       int retcode,                                       apr_pool_t *pool){  int errcode = SVN_ERR_RA_DAV_REQUEST_FAILED;  const char *msg;  const char *hostport;  /* Convert the return codes. */  switch (retcode)     {    case NE_AUTH:      errcode = SVN_ERR_RA_NOT_AUTHORIZED;      msg = _("authorization failed");      break;          case NE_CONNECT:      msg = _("could not connect to server");      break;    case NE_TIMEOUT:      msg = _("timed out waiting for server");      break;    default:      /* Get the error string from neon and convert to UTF-8. */      SVN_ERR(svn_utf_cstring_to_utf8(&msg, ne_get_error(sess), pool));      break;    }  /* The hostname may contain non-ASCII characters, so convert it to UTF-8. */  SVN_ERR(svn_utf_cstring_to_utf8(&hostport, ne_get_server_hostport(sess),                                  pool));  return svn_error_createf(errcode, NULL, "%s: %s (%s://%s)",                            context, msg, ne_get_scheme(sess),                            hostport);}/** Error parsing **//* Custom function of type ne_accept_response. */static int ra_dav_error_accepter(void *userdata,                                 ne_request *req,                                 const ne_status *st){  /* Before, this function was being run for *all* responses including     the 401 auth challenge.  In neon 0.24.x that was harmless.  But     in neon 0.25.0, trying to parse a 401 response as XML using     ne_xml_parse_v aborts the response; so the auth hooks never got a     chance. */#ifdef SVN_NEON_0_25  ne_content_type ctype;  /* Only accept non-2xx responses with text/xml content-type */  if (st->klass != 2 && ne_get_content_type(req, &ctype) == 0)    {      int is_xml =         (strcmp(ctype.type, "text") == 0 && strcmp(ctype.subtype, "xml") == 0);      ne_free(ctype.value);              return is_xml;    }  else     return 0;#else /* ! SVN_NEON_0_25 */  /* Only accept the body-response if the HTTP status code is *not* 2XX. */  return (st->klass != 2);#endif /* if/else SVN_NEON_0_25 */}static const svn_ra_dav__xml_elm_t error_elements[] ={  { "DAV:", "error", ELEM_error, 0 },  { "svn:", "error", ELEM_svn_error, 0 },  { "http://apache.org/dav/xmlns", "human-readable", 

⌨️ 快捷键说明

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