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

📄 update.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * update.c :  entry point for update RA functions for ra_serf * * ==================================================================== * Copyright (c) 2006 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/. * ==================================================================== */#define APR_WANT_STRFUNC#include <apr_want.h>#include <apr_uri.h>#include <expat.h>#include <serf.h>#include "svn_pools.h"#include "svn_ra.h"#include "svn_dav.h"#include "svn_xml.h"#include "../libsvn_ra/ra_loader.h"#include "svn_config.h"#include "svn_delta.h"#include "svn_version.h"#include "svn_path.h"#include "svn_base64.h"#include "svn_private_config.h"#include "ra_serf.h"/* * This enum represents the current state of our XML parsing for a REPORT. * * A little explanation of how the parsing works.  Every time we see * an open-directory tag, we enter the OPEN_DIR state.  Likewise, for * add-directory, open-file, etc.  When we see the closing variant of the * open-directory tag, we'll 'pop' out of that state. * * Each state has a pool associated with it that can have temporary * allocations that will live as long as the tag is opened.  Once * the tag is 'closed', the pool will be reused. */typedef enum {    NONE = 0,    OPEN_DIR,    ADD_DIR,    OPEN_FILE,    ADD_FILE,    PROP,    IGNORE_PROP_NAME,    NEED_PROP_NAME,} report_state_e;/* * This structure represents the information for a directory. */typedef struct report_dir_t{  /* Our parent directory.   *   * This value is NULL when we are the root.   */  struct report_dir_t *parent_dir;  apr_pool_t *pool;  /* Our name sans any parents. */  const char *base_name;  /* the expanded directory name (including all parent names) */  const char *name;  /* temporary path buffer for this directory. */  svn_stringbuf_t *name_buf;  /* the canonical url for this directory. */  const char *url;  /* Our base revision - SVN_INVALID_REVNUM if we're adding this dir. */  svn_revnum_t base_rev;  /* The target revision we're retrieving. */  svn_revnum_t target_rev;  /* controlling dir baton - this is only created in open_dir() */  void *dir_baton;  apr_pool_t *dir_baton_pool;  /* Our master update editor and baton. */  const svn_delta_editor_t *update_editor;  void *update_baton;  /* How many references to this directory do we still have open? */  apr_size_t ref_count;  /* Namespace list allocated out of this ->pool. */  svn_ra_serf__ns_t *ns_list;  /* hashtable for all of the properties (shared within a dir) */  apr_hash_t *props;  /* hashtable for all to-be-removed properties (shared within a dir) */  apr_hash_t *removed_props;  /* The propfind request for our current directory */  svn_ra_serf__propfind_context_t *propfind;  /* Has the server told us to fetch the dir props? */  svn_boolean_t fetch_props;  /* Have we closed the directory tag (meaning no more additions)? */  svn_boolean_t tag_closed;  /* The children of this directory  */  struct report_dir_t *children;  /* The next sibling of this directory */  struct report_dir_t *sibling;} report_dir_t;/* * This structure represents the information for a file. * * A directory may have a report_info_t associated with it as well. * * This structure is created as we parse the REPORT response and * once the element is completed, we create a report_fetch_t structure * to give to serf to retrieve this file. */typedef struct report_info_t{  apr_pool_t *pool;  /* The enclosing directory.   *   * If this structure refers to a directory, the dir it points to will be   * itself.   */  report_dir_t *dir;  /* Our name sans any directory info. */  const char *base_name;  /* the expanded file name (including all parent directory names) */  const char *name;  /* file name buffer */  svn_stringbuf_t *name_buf;  /* the canonical url for this file. */  const char *url;  /* lock token, if we had one to start off with. */  const char *lock_token;  /* Our base revision - SVN_INVALID_REVNUM if we're adding this file. */  svn_revnum_t base_rev;  /* The target revision we're retrieving. */  svn_revnum_t target_rev;  /* our delta base, if present (NULL if we're adding the file) */  const svn_string_t *delta_base;  /* The propfind request for our current file (if present) */  svn_ra_serf__propfind_context_t *propfind;  /* Has the server told us to fetch the file props? */  svn_boolean_t fetch_props;  /* Has the server told us to go fetch - only valid if we had it already */  svn_boolean_t fetch_file;  /* The properties for this file */  apr_hash_t *props;  /* pool passed to update->add_file, etc. */  apr_pool_t *editor_pool;  /* controlling file_baton and textdelta handler */  void *file_baton;  svn_txdelta_window_handler_t textdelta;  void *textdelta_baton;  /* temporary property for this file which is currently being parsed   * It will eventually be stored in our parent directory's property hash.   */  const char *prop_ns;  const char *prop_name;  const char *prop_val;  apr_size_t prop_val_len;  const char *prop_encoding;} report_info_t;/* * This structure represents a single request to GET (fetch) a file with * its associated Serf session/connection. */typedef struct report_fetch_t {  /* Our pool. */  apr_pool_t *pool;  /* Non-NULL if we received an error during processing. */  svn_error_t *err;  /* The session we should use to fetch the file. */  svn_ra_serf__session_t *sess;  /* The connection we should use to fetch file. */  svn_ra_serf__connection_t *conn;  /* Stores the information for the file we want to fetch. */  report_info_t *info;  /* Have we read our response headers yet? */  svn_boolean_t read_headers;  /* This flag is set when our response is aborted before we reach the   * end and we decide to requeue this request.   */  svn_boolean_t aborted_read;  apr_off_t aborted_read_size;  /* This is the amount of data that we have read so far. */  apr_off_t read_size;  /* If we're receiving an svndiff, this will be non-NULL. */  svn_stream_t *delta_stream;  /* If we're writing this file to a stream, this will be non-NULL. */  svn_stream_t *target_stream;  /* Are we done fetching this file? */  svn_boolean_t done;  svn_ra_serf__list_t **done_list;  svn_ra_serf__list_t done_item;} report_fetch_t;/* * The master structure for a REPORT request and response. */typedef struct {  apr_pool_t *pool;  svn_ra_serf__session_t *sess;  svn_ra_serf__connection_t *conn;  /* Source path and destination path */  const char *source;  const char *destination;  /* Our update target. */  const char *update_target;  /* What is the target revision that we want for this REPORT? */  svn_revnum_t target_rev;  /* Have we been asked to ignore ancestry, recursion, or textdeltas? */  svn_boolean_t ignore_ancestry;  svn_boolean_t recurse;  svn_boolean_t text_deltas;  apr_hash_t *lock_path_tokens;  /* Our master update editor and baton. */  const svn_delta_editor_t *update_editor;  void *update_baton;  /* The request body for the REPORT. */  serf_bucket_t *buckets;  /* root directory object */  report_dir_t *root_dir;  /* number of pending GET requests */  unsigned int active_fetches;  /* completed fetches (contains report_fetch_t) */  svn_ra_serf__list_t *done_fetches;  /* number of pending PROPFIND requests */  unsigned int active_propfinds;  /* completed PROPFIND requests (contains propfind_context_t) */  svn_ra_serf__list_t *done_propfinds;  /* list of files that will only have prop changes (contains report_info_t) */  svn_ra_serf__list_t *file_propchanges_only;  /* The path to the REPORT request */  const char *path;  /* Are we done parsing the REPORT response? */  svn_boolean_t done;} report_context_t;/** Report state management helper **/static report_info_t *push_state(svn_ra_serf__xml_parser_t *parser,           report_context_t *ctx,           report_state_e state){  report_info_t *info;  apr_pool_t *info_parent_pool;  svn_ra_serf__xml_push_state(parser, state);  info = parser->state->private;  /* Our private pool needs to be disjoint from the state pool. */  if (!info)    {      info_parent_pool = ctx->pool;    }  else    {      info_parent_pool = info->pool;    }  if (state == OPEN_DIR || state == ADD_DIR)    {      report_info_t *new_info;      new_info = apr_palloc(info_parent_pool, sizeof(*new_info));      apr_pool_create(&new_info->pool, info_parent_pool);      new_info->lock_token = NULL;      new_info->dir = apr_pcalloc(new_info->pool, sizeof(*new_info->dir));      new_info->dir->pool = new_info->pool;      /* Create the root property tree. */      new_info->dir->props = apr_hash_make(new_info->pool);      new_info->props = new_info->dir->props;      new_info->dir->removed_props = apr_hash_make(new_info->pool);      /* Point to the update_editor */      new_info->dir->update_editor = ctx->update_editor;      new_info->dir->update_baton = ctx->update_baton;      if (info)        {          info->dir->ref_count++;          new_info->dir->parent_dir = info->dir;          /* Point our ns_list at our parents to try to reuse it. */          new_info->dir->ns_list = info->dir->ns_list;                    /* Add ourselves to our parent's list */          new_info->dir->sibling = info->dir->children;          info->dir->children = new_info->dir;        }      else        {          /* Allow us to be found later. */          ctx->root_dir = new_info->dir;        }      parser->state->private = new_info;    }  else if (state == OPEN_FILE || state == ADD_FILE)    {      report_info_t *new_info;      new_info = apr_palloc(info_parent_pool, sizeof(*new_info));      apr_pool_create(&new_info->pool, info_parent_pool);      new_info->file_baton = NULL;      new_info->lock_token = NULL;      new_info->fetch_file = FALSE;      /* Point at our parent's directory state. */      new_info->dir = info->dir;      info->dir->ref_count++;      new_info->props = apr_hash_make(new_info->pool);      parser->state->private = new_info;    }  return parser->state->private;}/** Wrappers around our various property walkers **/static svn_error_t *set_file_props(void *baton,               const char *ns, apr_ssize_t ns_len,               const char *name, apr_ssize_t name_len,               const svn_string_t *val,               apr_pool_t *pool){  report_info_t *info = baton;  const svn_delta_editor_t *editor = info->dir->update_editor;  return svn_ra_serf__set_baton_props(editor->change_file_prop,                                      info->file_baton,                                      ns, ns_len, name, name_len, val, pool);}static svn_error_t *set_dir_props(void *baton,              const char *ns, apr_ssize_t ns_len,              const char *name, apr_ssize_t name_len,              const svn_string_t *val,              apr_pool_t *pool){  report_dir_t *dir = baton;  return svn_ra_serf__set_baton_props(dir->update_editor->change_dir_prop,                                      dir->dir_baton,                                      ns, ns_len, name, name_len, val, pool);}static svn_error_t *remove_file_props(void *baton,                  const char *ns, apr_ssize_t ns_len,                  const char *name, apr_ssize_t name_len,                  const svn_string_t *val,                  apr_pool_t *pool){  report_info_t *info = baton;

⌨️ 快捷键说明

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