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

📄 prop_commands.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * prop_commands.c:  Implementation of propset, propget, and proplist.
 *
 * ====================================================================
 * 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/.
 * ====================================================================
 */

/* ==================================================================== */



/*** Includes. ***/

#include <ctype.h>

#define APR_WANT_STRFUNC
#include <apr_want.h>

#include "svn_client.h"
#include "client.h"
#include "svn_path.h"
#include "svn_pools.h"

#include "svn_private_config.h"


/*** Code. ***/

/* Check whether the UTF8 NAME is a valid property name.  For now, this means
 * the ASCII subset of an XML "Name".
 * XML "Name" is defined at http://www.w3.org/TR/REC-xml#sec-common-syn */
static svn_boolean_t
is_valid_prop_name (const char *name)
{
  const char *p = name;

  /* Each byte of a UTF8-encoded non-ASCII character has its high bit set and
   * so will be rejected by this function. */
  if (! isalpha (*p) && ! strchr ("_:", *p))
    return FALSE;
  p++;
  for (; *p; p++)
    {
      if (! isalnum (*p) && ! strchr (".-_:", *p))
        return FALSE;
    }
  return TRUE;
}


/* Check whether NAME is a revision property name.
 * 
 * Return TRUE if it is.
 * Return FALSE if it is not.  
 */ 
static svn_boolean_t
is_revision_prop_name (const char *name)
{
  apr_size_t i;
  const char *revision_props[] = 
    {
      SVN_PROP_REVISION_ALL_PROPS
    };

  for (i = 0; i < sizeof (revision_props) / sizeof (revision_props[0]); i++)
    {
      if (strcmp (name, revision_props[i]) == 0)
        return TRUE;
    }
  return FALSE;
}

/* A baton for propset_walk_cb. */
struct propset_walk_baton
{
  const char *propname;  /* The name of the property to set. */
  const svn_string_t *propval;  /* The value to set. */
  svn_wc_adm_access_t *base_access;  /* Access for the tree being walked. */
};

/* An entries-walk callback for svn_client_propset.
 * 
 * For the path given by PATH and ENTRY,
 * set the property named wb->PROPNAME to the value wb->PROPVAL,
 * where "wb" is the WALK_BATON of type "struct propset_walk_baton *".
 */
static svn_error_t *
propset_walk_cb (const char *path,
                 const svn_wc_entry_t *entry,
                 void *walk_baton,
                 apr_pool_t *pool)
{
  struct propset_walk_baton *wb = walk_baton;
  svn_error_t *err;
  svn_wc_adm_access_t *adm_access;

  /* We're going to receive dirents twice;  we want to ignore the
     first one (where it's a child of a parent dir), and only use
     the second one (where we're looking at THIS_DIR).  */
  if ((entry->kind == svn_node_dir)
      && (strcmp (entry->name, SVN_WC_ENTRY_THIS_DIR) != 0))
    return SVN_NO_ERROR;

  /* Ignore the entry if it does not exist at the time of interest. */
  if (entry->schedule == svn_wc_schedule_delete)
    return SVN_NO_ERROR;

  SVN_ERR (svn_wc_adm_retrieve (&adm_access, wb->base_access,
                                (entry->kind == svn_node_dir ? path
                                 : svn_path_dirname (path, pool)),
                                pool));
  err = svn_wc_prop_set (wb->propname, wb->propval,
                         path, adm_access, pool);
  if (err)
    {
      if (err->apr_err != SVN_ERR_ILLEGAL_TARGET)
        return err;
      svn_error_clear (err);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_client_propset (const char *propname,
                    const svn_string_t *propval,
                    const char *target,
                    svn_boolean_t recurse,
                    apr_pool_t *pool)
{
  svn_wc_adm_access_t *adm_access;
  const svn_wc_entry_t *node;

  if (is_revision_prop_name (propname))
    {
      return svn_error_createf (SVN_ERR_CLIENT_PROPERTY_NAME, NULL,
                                _("Revision property '%s' not allowed "
                                  "in this context"), propname);
    }

  if (svn_path_is_url (target))
    {
      /* ### Note that this function will need to take an auth baton
         if it's ever to support setting properties remotely. */
      return svn_error_createf
        (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
         _("Setting property on non-local target '%s' not yet supported"),
         target);
    }

  if (propval && ! is_valid_prop_name (propname))
    return svn_error_createf (SVN_ERR_CLIENT_PROPERTY_NAME, NULL,
                              _("Bad property name: '%s'"), propname);

  SVN_ERR (svn_wc_adm_probe_open2 (&adm_access, NULL, target, TRUE,
                                   recurse ? -1 : 0, pool));
  SVN_ERR (svn_wc_entry (&node, target, adm_access, FALSE, pool));
  if (!node)
    return svn_error_createf (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
                              _("'%s' is not under version control"), 
                              target);

  if (recurse && node->kind == svn_node_dir)
    {
      static const svn_wc_entry_callbacks_t walk_callbacks
        = { propset_walk_cb };
      struct propset_walk_baton wb;

      wb.base_access = adm_access;
      wb.propname = propname;
      wb.propval = propval;

      SVN_ERR (svn_wc_walk_entries (target, adm_access,
                                    &walk_callbacks, &wb, FALSE, pool));
    }
  else
    {
      SVN_ERR (svn_wc_prop_set (propname, propval, target, adm_access, pool));
    }

  SVN_ERR (svn_wc_adm_close (adm_access));
  return SVN_NO_ERROR;
}


svn_error_t *
svn_client_revprop_set (const char *propname,
                        const svn_string_t *propval,
                        const char *URL,
                        const svn_opt_revision_t *revision,
                        svn_revnum_t *set_rev,
                        svn_boolean_t force,
                        svn_client_ctx_t *ctx,
                        apr_pool_t *pool)
{
  void *ra_baton, *session;
  svn_ra_plugin_t *ra_lib;

  if ((strcmp (propname, SVN_PROP_REVISION_AUTHOR) == 0)
      && propval 
      && strchr (propval->data, '\n') != NULL 
      && (! force))
    return svn_error_create (SVN_ERR_CLIENT_REVISION_AUTHOR_CONTAINS_NEWLINE,
                             NULL, _("Value will not be set unless forced"));

  if (propval && ! is_valid_prop_name (propname))
    return svn_error_createf (SVN_ERR_CLIENT_PROPERTY_NAME, NULL,
                              _("Bad property name: '%s'"), propname);

  /* Open an RA session for the URL. Note that we don't have a local
     directory, nor a place to put temp files. */
  SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
  SVN_ERR (svn_ra_get_ra_library (&ra_lib, ra_baton, URL, pool));
  SVN_ERR (svn_client__open_ra_session (&session, ra_lib, URL, NULL,
                                        NULL, NULL, FALSE, TRUE,
                                        ctx, pool));

  /* Resolve the revision into something real, and return that to the
     caller as well. */
  SVN_ERR (svn_client__get_revision_number
           (set_rev, ra_lib, session, revision, NULL, pool));

  /* The actual RA call. */
  SVN_ERR (ra_lib->change_rev_prop (session, *set_rev, propname, propval,
                                    pool));

  return SVN_NO_ERROR;
}


/* Set *PROPS to the pristine (base) properties at PATH, if PRISTINE
 * is true, or else the working value if PRISTINE is false.  
 *
 * The keys of *PROPS will be 'const char *' property names, and the
 * values 'const svn_string_t *' property values.  Allocate *PROPS
 * and its contents in POOL.
 */
static svn_error_t *
pristine_or_working_props (apr_hash_t **props,
                           const char *path,
                           svn_wc_adm_access_t *adm_access,
                           svn_boolean_t pristine,
                           apr_pool_t *pool)
{
  if (pristine)
    SVN_ERR (svn_wc_get_prop_diffs (NULL, props, path, adm_access, pool));
  else
    SVN_ERR (svn_wc_prop_list (props, path, adm_access, pool));
  
  return SVN_NO_ERROR;
}


/* Set *PROPVAL to the pristine (base) value of property PROPNAME at
 * PATH, if PRISTINE is true, or else the working value if PRISTINE is
 * false.  Allocate *PROPVAL in POOL.
 */
static svn_error_t *
pristine_or_working_propval (const svn_string_t **propval,
                             const char *propname,
                             const char *path,
                             svn_wc_adm_access_t *adm_access,
                             svn_boolean_t pristine,
                             apr_pool_t *pool)
{
  if (pristine)
    {
      apr_hash_t *pristine_props;
      
      SVN_ERR (svn_wc_get_prop_diffs (NULL, &pristine_props, path, adm_access,
                                      pool));
      *propval = apr_hash_get (pristine_props, propname, APR_HASH_KEY_STRING);
    }
  else  /* get the working revision */
    {
      SVN_ERR (svn_wc_prop_get (propval, propname, path, adm_access, pool));
    }
  
  return SVN_NO_ERROR;
}


/* A baton for propget_walk_cb. */
struct propget_walk_baton
{
  const char *propname;  /* The name of the property to get. */
  svn_boolean_t pristine;  /* Select base rather than working props. */
  svn_wc_adm_access_t *base_access;  /* Access for the tree being walked. */
  apr_hash_t *props;  /* Out: mapping of (path:propval). */
};

/* An entries-walk callback for svn_client_propget.
 * 
 * For the path given by PATH and ENTRY,
 * populate wb->PROPS with the values of property wb->PROPNAME,
 * where "wb" is the WALK_BATON of type "struct propget_walk_baton *".
 * If wb->PRISTINE is true, use the base value, else use the working value.
 *
 * The keys of wb->PROPS will be 'const char *' paths, rooted at the
 * path svn_wc_adm_access_path(ADM_ACCESS), and the values are
 * 'const svn_string_t *' property values.
 */
static svn_error_t *
propget_walk_cb (const char *path,
                 const svn_wc_entry_t *entry,
                 void *walk_baton,

⌨️ 快捷键说明

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