static svn_error_t *vwrite_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                 const char *fmt, va_list ap)
{
  svn_boolean_t opt = FALSE;
  svn_revnum_t rev;
  const char *cstr;
  const svn_string_t *str;

  if (*fmt == '!')
    fmt++;
  else
    SVN_ERR(svn_ra_svn_start_list(conn, pool));
  for (; *fmt; fmt++)
    {
      if (*fmt == 'n' && !opt)
        SVN_ERR(svn_ra_svn_write_number(conn, pool, va_arg(ap, apr_uint64_t)));
      else if (*fmt == 'r')
        {
          rev = va_arg(ap, svn_revnum_t);
          SVN_ERR_ASSERT(opt || SVN_IS_VALID_REVNUM(rev));
          if (SVN_IS_VALID_REVNUM(rev))
            SVN_ERR(svn_ra_svn_write_number(conn, pool, rev));
        }
      else if (*fmt == 's')
        {
          str = va_arg(ap, const svn_string_t *);
          SVN_ERR_ASSERT(opt || str);
          if (str)
            SVN_ERR(svn_ra_svn_write_string(conn, pool, str));
        }
      else if (*fmt == 'c')
Esempio n. 2
0
svn_error_t *
svn_repos_get_fs_build_parser4(const svn_repos_parse_fns3_t **callbacks,
                               void **parse_baton,
                               svn_repos_t *repos,
                               svn_revnum_t start_rev,
                               svn_revnum_t end_rev,
                               svn_boolean_t use_history,
                               svn_boolean_t validate_props,
                               enum svn_repos_load_uuid uuid_action,
                               const char *parent_dir,
                               svn_repos_notify_func_t notify_func,
                               void *notify_baton,
                               apr_pool_t *pool)
{
  svn_repos_parse_fns3_t *parser = apr_pcalloc(pool, sizeof(*parser));
  struct parse_baton *pb = apr_pcalloc(pool, sizeof(*pb));

  if (parent_dir)
    parent_dir = svn_relpath_canonicalize(parent_dir, pool);

  SVN_ERR_ASSERT((SVN_IS_VALID_REVNUM(start_rev) &&
                  SVN_IS_VALID_REVNUM(end_rev))
                 || ((! SVN_IS_VALID_REVNUM(start_rev)) &&
                     (! SVN_IS_VALID_REVNUM(end_rev))));
  if (SVN_IS_VALID_REVNUM(start_rev))
    SVN_ERR_ASSERT(start_rev <= end_rev);

  parser->magic_header_record = magic_header_record;
  parser->uuid_record = uuid_record;
  parser->new_revision_record = new_revision_record;
  parser->new_node_record = new_node_record;
  parser->set_revision_property = set_revision_property;
  parser->set_node_property = set_node_property;
  parser->remove_node_props = remove_node_props;
  parser->set_fulltext = set_fulltext;
  parser->close_node = close_node;
  parser->close_revision = close_revision;
  parser->delete_node_property = delete_node_property;
  parser->apply_textdelta = apply_textdelta;

  pb->repos = repos;
  pb->fs = svn_repos_fs(repos);
  pb->use_history = use_history;
  pb->validate_props = validate_props;
  pb->notify_func = notify_func;
  pb->notify_baton = notify_baton;
  pb->uuid_action = uuid_action;
  pb->parent_dir = parent_dir;
  pb->pool = pool;
  pb->notify_pool = svn_pool_create(pool);
  pb->rev_map = apr_hash_make(pool);
  pb->oldest_old_rev = SVN_INVALID_REVNUM;
  pb->last_rev_mapped = SVN_INVALID_REVNUM;
  pb->start_rev = start_rev;
  pb->end_rev = end_rev;

  *callbacks = parser;
  *parse_baton = pb;
  return SVN_NO_ERROR;
}
Esempio n. 3
0
/* Create a packed filesystem in DIR.  Set the shard size to
   SHARD_SIZE and create NUM_REVS number of revisions (in addition to
   r0).  Use POOL for allocations.  After this function successfully
   completes, the filesystem's youngest revision number will be the
   same as NUM_REVS.  */
static svn_error_t *
create_packed_filesystem(const char *dir,
                         const svn_test_opts_t *opts,
                         int num_revs,
                         int shard_size,
                         apr_pool_t *pool)
{
  svn_fs_t *fs;
  svn_fs_txn_t *txn;
  svn_fs_root_t *txn_root;
  const char *conflict;
  svn_revnum_t after_rev;
  apr_pool_t *subpool = svn_pool_create(pool);
  apr_pool_t *iterpool;
  int version;

  /* Create a filesystem, then close it */
  SVN_ERR(svn_test__create_fs(&fs, dir, opts, subpool));
  svn_pool_destroy(subpool);

  subpool = svn_pool_create(pool);

  /* Rewrite the format file */
  SVN_ERR(svn_io_read_version_file(&version,
                                   svn_dirent_join(dir, "format", subpool),
                                   subpool));
  SVN_ERR(write_format(dir, version, shard_size, subpool));

  /* Reopen the filesystem */
  SVN_ERR(svn_fs_open(&fs, dir, NULL, subpool));

  /* Revision 1: the Greek tree */
  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, subpool));
  SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
  SVN_ERR(svn_test__create_greek_tree(txn_root, subpool));
  SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, subpool));
  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev));

  /* Revisions 2 thru NUM_REVS-1: content tweaks to "iota". */
  iterpool = svn_pool_create(subpool);
  while (after_rev < num_revs)
    {
      svn_pool_clear(iterpool);
      SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, iterpool));
      SVN_ERR(svn_fs_txn_root(&txn_root, txn, iterpool));
      SVN_ERR(svn_test__set_file_contents(txn_root, "iota",
                                          get_rev_contents(after_rev + 1,
                                                           iterpool),
                                          iterpool));
      SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, iterpool));
      SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev));
    }
  svn_pool_destroy(iterpool);
  svn_pool_destroy(subpool);

  /* Now pack the FS */
  return svn_fs_pack(dir, NULL, NULL, NULL, NULL, pool);
}
/* This implements the `svn_ra_neon__startelem_cb_t' prototype. */
static svn_error_t *
gls_start_element(int *elem, void *userdata, int parent_state,
                  const char *ns, const char *ln, const char **atts)
{
  get_location_segments_baton_t *baton = userdata;
  const svn_ra_neon__xml_elm_t *elm;

  /* Just skip unknown elements. */
  if (! ((elm = svn_ra_neon__lookup_xml_elem(gls_report_elements, ns, ln))))
    {
      *elem = NE_XML_DECLINE;
      return SVN_NO_ERROR;
    }

  if (parent_state == ELEM_get_location_segments_report
      && elm->id == ELEM_location_segment)
    {
      const char *rev_str;
      svn_revnum_t range_start = SVN_INVALID_REVNUM;
      svn_revnum_t range_end = SVN_INVALID_REVNUM;
      const char *path = NULL;

      path = svn_xml_get_attr_value("path", atts);
      rev_str = svn_xml_get_attr_value("range-start", atts);
      if (rev_str)
        range_start = SVN_STR_TO_REV(rev_str);
      rev_str = svn_xml_get_attr_value("range-end", atts);
      if (rev_str)
        range_end = SVN_STR_TO_REV(rev_str);

      if (SVN_IS_VALID_REVNUM(range_start) && SVN_IS_VALID_REVNUM(range_end))
        {
          svn_location_segment_t *segment = apr_pcalloc(baton->subpool,
                                                        sizeof(*segment));
          segment->path = path;
          segment->range_start = range_start;
          segment->range_end = range_end;
          SVN_ERR(baton->receiver(segment,
                                  baton->receiver_baton,
                                  baton->subpool));
          svn_pool_clear(baton->subpool);
        }
      else
        {
          return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                  _("Expected valid revision range"));
        }
    }

  *elem = elm->id;

  return SVN_NO_ERROR;
}
Esempio n. 5
0
static svn_error_t *
start_gls(svn_ra_serf__xml_parser_t *parser,
          void *userData,
          svn_ra_serf__dav_props_t name,
          const char **attrs)
{
  gls_context_t *gls_ctx = userData;

  if ((! gls_ctx->inside_report)
      && strcmp(name.name, "get-location-segments-report") == 0)
    {
      gls_ctx->inside_report = TRUE;
    }
  else if (gls_ctx->inside_report
           && strcmp(name.name, "location-segment") == 0)
    {
      const char *rev_str;
      svn_revnum_t range_start = SVN_INVALID_REVNUM;
      svn_revnum_t range_end = SVN_INVALID_REVNUM;
      const char *path = NULL;

      path = svn_xml_get_attr_value("path", attrs);
      rev_str = svn_xml_get_attr_value("range-start", attrs);
      if (rev_str)
        range_start = SVN_STR_TO_REV(rev_str);
      rev_str = svn_xml_get_attr_value("range-end", attrs);
      if (rev_str)
        range_end = SVN_STR_TO_REV(rev_str);

      if (SVN_IS_VALID_REVNUM(range_start) && SVN_IS_VALID_REVNUM(range_end))
        {
          svn_location_segment_t *segment = apr_pcalloc(gls_ctx->subpool,
                                                        sizeof(*segment));
          segment->path = path;
          segment->range_start = range_start;
          segment->range_end = range_end;
          SVN_ERR(gls_ctx->receiver(segment,
                                    gls_ctx->receiver_baton,
                                    gls_ctx->subpool));
          svn_pool_clear(gls_ctx->subpool);
        }
      else
        {
          return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                  _("Expected valid revision range"));
        }
    }

  return SVN_NO_ERROR;
}
Esempio n. 6
0
static svn_error_t *
change_dir_prop(void *dir_baton,
                const char *name,
                const svn_string_t *value,
                apr_pool_t *pool)
{
  struct dir_baton *db = dir_baton;
  struct edit_baton *eb = db->edit_baton;

  /* Check for write authorization. */
  SVN_ERR(check_authz(eb, db->path, eb->txn_root,
                      svn_authz_write, pool));

  if (SVN_IS_VALID_REVNUM(db->base_rev))
    {
      /* Subversion rule:  propchanges can only happen on a directory
         which is up-to-date. */
      svn_revnum_t created_rev;
      SVN_ERR(svn_fs_node_created_rev(&created_rev,
                                      eb->txn_root, db->path, pool));

      if (db->base_rev < created_rev)
        return out_of_date(db->path, svn_node_dir);
    }

  return svn_repos_fs_change_node_prop(eb->txn_root, db->path,
                                       name, value, pool);
}
Esempio n. 7
0
svn_wc_conflict_version_t *
svn_wc_conflict_version_create2(const char *repos_url,
                                const char *repos_uuid,
                                const char *repos_relpath,
                                svn_revnum_t revision,
                                svn_node_kind_t kind,
                                apr_pool_t *result_pool)
{
  svn_wc_conflict_version_t *version;

  version = apr_pcalloc(result_pool, sizeof(*version));

    SVN_ERR_ASSERT_NO_RETURN(svn_uri_is_canonical(repos_url, result_pool)
                             && svn_relpath_is_canonical(repos_relpath)
                             && SVN_IS_VALID_REVNUM(revision)
                             /* ### repos_uuid can be NULL :( */);

  version->repos_url = repos_url;
  version->peg_rev = revision;
  version->path_in_repos = repos_relpath;
  version->node_kind = kind;
  version->repos_uuid = repos_uuid;

  return version;
}
/* Create a repository with a filesystem based on OPTS in a subdir NAME,
 * commit the standard Greek tree as revision 1, and set *REPOS_URL to
 * the URL we will use to access it.
 *
 * ### This always returns a file: URL. We should upgrade this to use the
 *     test suite's specified URL scheme instead. */
static svn_error_t *
create_greek_repos(const char **repos_url,
                   const char *name,
                   const svn_test_opts_t *opts,
                   apr_pool_t *pool)
{
  svn_repos_t *repos;
  svn_revnum_t committed_rev;
  svn_fs_txn_t *txn;
  svn_fs_root_t *txn_root;

  /* Create a filesytem and repository. */
  SVN_ERR(svn_test__create_repos(&repos, name, opts, pool));

  /* Prepare and commit a txn containing the Greek tree. */
  SVN_ERR(svn_fs_begin_txn2(&txn, svn_repos_fs(repos), 0 /* rev */,
                            0 /* flags */, pool));
  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &committed_rev, txn, pool));
  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(committed_rev));

  SVN_ERR(svn_uri_get_file_url_from_dirent(repos_url, name, pool));
  return SVN_NO_ERROR;
}
Esempio n. 9
0
  svn_revnum_t
  Client::commit(const Targets & targets,
                 const char * message,
                 bool recurse,
                 bool keep_locks) throw(ClientException)
  {
    Pool pool;

    m_context->setLogMessage(message);

    svn_client_commit_info_t *commit_info = NULL;

    svn_error_t * error =
      svn_client_commit2(&commit_info,
                         targets.array(pool),
                         recurse,
                         keep_locks,
                         *m_context,
                         pool);
    if (error != NULL)
      throw ClientException(error);

    if (commit_info && SVN_IS_VALID_REVNUM(commit_info->revision))
      return commit_info->revision;

    return -1;
  }
Esempio n. 10
0
Py::Object toObject( pysvn_commit_info_t *commit_info )
{
    if( commit_info == NULL || !SVN_IS_VALID_REVNUM( commit_info->revision ) )
        return Py::None();

    return Py::asObject( new pysvn_revision( svn_opt_revision_number, 0, commit_info->revision ) );
}
Esempio n. 11
0
/* Utility for log_receiver opening a new XML element in LRB's brigade
   for LOG_ITEM and return the element's name in *ELEMENT.  Use POOL for
   temporary allocations.

   Call this function for items that may have a copy-from */
static svn_error_t *
start_path_with_copy_from(const char **element,
                          struct log_receiver_baton *lrb,
                          svn_log_changed_path2_t *log_item,
                          apr_pool_t *pool)
{
  switch (log_item->action)
    {
      case 'A': *element = "S:added-path";
                break;
      case 'R': *element = "S:replaced-path";
                break;
      default:  /* Caller, you did wrong! */
                SVN_ERR_MALFUNCTION();
    }

  if (log_item->copyfrom_path
      && SVN_IS_VALID_REVNUM(log_item->copyfrom_rev))
    SVN_ERR(dav_svn__brigade_printf
            (lrb->bb, lrb->output,
             "<%s copyfrom-path=\"%s\" copyfrom-rev=\"%ld\"",
             *element,
             apr_xml_quote_string(pool,
                                  log_item->copyfrom_path,
                                  1), /* escape quotes */
             log_item->copyfrom_rev));
  else
    SVN_ERR(dav_svn__brigade_printf(lrb->bb, lrb->output, "<%s", *element));

  return SVN_NO_ERROR;
}
Esempio n. 12
0
static svn_error_t *
commit_packed_fs(const svn_test_opts_t *opts,
                 apr_pool_t *pool)
{
  svn_fs_t *fs;
  svn_fs_txn_t *txn;
  svn_fs_root_t *txn_root;
  const char *conflict;
  svn_revnum_t after_rev;

  /* Bail (with success) on known-untestable scenarios */
  if ((strcmp(opts->fs_type, "fsfs") != 0)
      || (opts->server_minor_version && (opts->server_minor_version < 6)))
    return SVN_NO_ERROR;

  /* Create the packed FS and open it. */
  SVN_ERR(create_packed_filesystem(REPO_NAME, opts, MAX_REV, 5, pool));
  SVN_ERR(svn_fs_open(&fs, REPO_NAME, NULL, pool));

  /* Now do a commit. */
  SVN_ERR(svn_fs_begin_txn(&txn, fs, MAX_REV, pool));
  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
  SVN_ERR(svn_test__set_file_contents(txn_root, "iota",
          "How much better is it to get wisdom than gold! and to get "
          "understanding rather to be chosen than silver!", pool));
  SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, pool));
  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev));

  return SVN_NO_ERROR;
}
svn_error_t *
svn_ra_serf__blncache_set(svn_ra_serf__blncache_t *blncache,
                          const char *baseline_url,
                          svn_revnum_t revision,
                          const char *bc_url,
                          apr_pool_t *pool)
{
  if (bc_url && SVN_IS_VALID_REVNUM(revision))
    {
      apr_pool_t *cache_pool = apr_hash_pool_get(blncache->revnum_to_bc);

      /* If the caches are too big, delete and recreate 'em and move along. */
      if (MAX_CACHE_SIZE < (apr_hash_count(blncache->baseline_info)
                            + apr_hash_count(blncache->revnum_to_bc)))
        {
          svn_pool_clear(cache_pool);
          blncache->revnum_to_bc = apr_hash_make(cache_pool);
          blncache->baseline_info = apr_hash_make(cache_pool);
        }

      hash_set_copy(blncache->revnum_to_bc, &revision, sizeof(revision),
                    apr_pstrdup(cache_pool, bc_url));

      if (baseline_url)
        {
          hash_set_copy(blncache->baseline_info, baseline_url,
                        APR_HASH_KEY_STRING,
                        baseline_info_make(bc_url, revision, cache_pool));
        }
    }

  return SVN_NO_ERROR;
}
Esempio n. 14
0
static svn_error_t *ra_svn_add_dir(const char *path, void *parent_baton,
                                   const char *copy_path,
                                   svn_revnum_t copy_rev,
                                   apr_pool_t *pool, void **child_baton)
{
  ra_svn_baton_t *b = parent_baton;
  const char *token = make_token('d', b->eb, pool);

  SVN_ERR_ASSERT((copy_path && SVN_IS_VALID_REVNUM(copy_rev))
                 || (!copy_path && !SVN_IS_VALID_REVNUM(copy_rev)));
  SVN_ERR(check_for_error(b->eb, pool));
  SVN_ERR(svn_ra_svn__write_cmd_add_dir(b->conn, pool, path, b->token,
                                        token, copy_path, copy_rev));
  *child_baton = ra_svn_make_baton(b->conn, pool, b->eb, token);
  return SVN_NO_ERROR;
}
Esempio n. 15
0
svn_error_t *
svn_repos_fs_commit_txn(const char **conflict_p,
                        svn_repos_t *repos,
                        svn_revnum_t *new_rev,
                        svn_fs_txn_t *txn,
                        apr_pool_t *pool)
{
  svn_error_t *err, *err2;
  const char *txn_name;

  *new_rev = SVN_INVALID_REVNUM;

  /* Run pre-commit hooks. */
  SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
  SVN_ERR(svn_repos__hooks_pre_commit(repos, txn_name, pool));

  /* Commit. */
  err = svn_fs_commit_txn(conflict_p, new_rev, txn, pool);
  if (! SVN_IS_VALID_REVNUM(*new_rev))
    return err;

  /* Run post-commit hooks. */
  if ((err2 = svn_repos__hooks_post_commit(repos, *new_rev, pool)))
    {
      err2 = svn_error_create
               (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err2,
                _("Commit succeeded, but post-commit hook failed"));
    }

  return svn_error_compose_create(err, err2);
}
Esempio n. 16
0
static svn_error_t *
file_add(const char *path,
         void *parent_baton,
         const char *copyfrom_path,
         svn_revnum_t copyfrom_revision,
         apr_pool_t *result_pool,
         void **file_baton)
{
  struct file_baton_t *fb;

  SVN_ERR(file_open_or_add(path, parent_baton, &fb));

  if (copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_revision))
    {
      SVN_ERR(svn_client__repos_to_wc_copy_internal(NULL /*timestamp_sleep*/,
                                           svn_node_file,
                                           copyfrom_path,
                                           copyfrom_revision,
                                           fb->local_abspath,
                                           fb->eb->ra_session,
                                           fb->eb->ctx, fb->pool));
      fb->created = TRUE;
    }

  *file_baton = fb;
  return SVN_NO_ERROR;
}
Esempio n. 17
0
/* This implements svn_editor_cb_copy_t */
static svn_error_t *
copy_cb(void *baton,
        const char *src_relpath,
        svn_revnum_t src_revision,
        const char *dst_relpath,
        svn_revnum_t replaces_rev,
        apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *src_fspath = FSPATH(src_relpath, scratch_pool);
    const char *dst_fspath = FSPATH(dst_relpath, scratch_pool);
    svn_fs_root_t *root;
    svn_fs_root_t *src_root;

    SVN_ERR(get_root(&root, eb));

    /* Check if we can we replace the maybe-specified destination (revision).  */
    if (SVN_IS_VALID_REVNUM(replaces_rev))
    {
        SVN_ERR(can_modify(root, dst_fspath, replaces_rev, scratch_pool));
        SVN_ERR(svn_fs_delete(root, dst_fspath, scratch_pool));
    }
    else
    {
        SVN_ERR(can_create(root, dst_fspath, scratch_pool));
    }

    SVN_ERR(svn_fs_revision_root(&src_root, svn_fs_root_fs(root), src_revision,
                                 scratch_pool));
    SVN_ERR(svn_fs_copy(src_root, src_fspath, root, dst_fspath, scratch_pool));
    svn_fs_close_root(src_root);

    return SVN_NO_ERROR;
}
Esempio n. 18
0
static svn_error_t *
dir_add(const char *path,
        void *parent_baton,
        const char *copyfrom_path,
        svn_revnum_t copyfrom_revision,
        apr_pool_t *result_pool,
        void **child_baton)
{
  struct dir_baton_t *db;

  SVN_ERR(dir_open_or_add(path, parent_baton, &db));

  if (copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_revision))
    {
      SVN_ERR(svn_client__repos_to_wc_copy_internal(NULL /*timestamp_sleep*/,
                                           svn_node_dir,
                                           copyfrom_path,
                                           copyfrom_revision,
                                           db->local_abspath,
                                           db->eb->ra_session,
                                           db->eb->ctx, db->pool));
      db->created = TRUE;
    }
  else
    {
      SVN_ERR(svn_io_make_dir_recursively(db->local_abspath, db->pool));
    }

  *child_baton = db;
  return SVN_NO_ERROR;
}
Esempio n. 19
0
svn_error_t *
svn_cl__print_commit_info(const svn_commit_info_t *commit_info,
                          void *baton,
                          apr_pool_t *pool)
{
  /* Be very careful with returning errors from this callback as those
     will be returned as errors from editor->close_edit(...), which may
     cause callers to assume that the commit itself failed.

     See log message of r1659867 and the svn_ra_get_commit_editor3
     documentation for details on error scenarios. */

  if (SVN_IS_VALID_REVNUM(commit_info->revision))
    SVN_ERR(svn_cmdline_printf(pool, _("Committed revision %ld%s.\n"),
                               commit_info->revision,
                               commit_info->revision == 42 &&
                               getenv("SVN_I_LOVE_PANGALACTIC_GARGLE_BLASTERS")
                                 ?  _(" (the answer to life, the universe, "
                                      "and everything)")
                                 : ""));

  /* Writing to stdout, as there maybe systems that consider the
   * presence of stderr as an indication of commit failure.
   * OTOH, this is only of informational nature to the user as
   * the commit has succeeded. */
  if (commit_info->post_commit_err)
    SVN_ERR(svn_cmdline_printf(pool, _("\nWarning: %s\n"),
                               commit_info->post_commit_err));

  return SVN_NO_ERROR;
}
svn_error_t *svn_ra_change_rev_prop2(svn_ra_session_t *session,
                                     svn_revnum_t rev,
                                     const char *name,
                                     const svn_string_t *const *old_value_p,
                                     const svn_string_t *value,
                                     apr_pool_t *pool)
{
  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(rev));

  /* If an old value was specified, make sure the server supports
   * specifying it. */
  if (old_value_p)
    {
      svn_boolean_t has_atomic_revprops;

      SVN_ERR(svn_ra_has_capability(session, &has_atomic_revprops,
                                    SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
                                    pool));

      if (!has_atomic_revprops)
        /* API violation.  (Should be an ASSERT, but gstein talked me
         * out of it.) */
        return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                                 _("Specifying 'old_value_p' is not allowed when "
                                   "the '%s' capability is not advertised, and "
                                   "could indicate a bug in your client"),
                                   SVN_RA_CAPABILITY_ATOMIC_REVPROPS);
    }

  return session->vtable->change_rev_prop(session, rev, name,
                                          old_value_p, value, pool);
}
Esempio n. 21
0
/* This implements svn_editor_cb_add_directory_t */
static svn_error_t *
add_directory_cb(void *baton,
                 const char *relpath,
                 const apr_array_header_t *children,
                 apr_hash_t *props,
                 svn_revnum_t replaces_rev,
                 apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *fspath = FSPATH(relpath, scratch_pool);
    svn_fs_root_t *root;

    /* Note: we ignore CHILDREN. We have no "incomplete" state to worry about,
       so we don't need to be aware of what children will be created.  */

    SVN_ERR(get_root(&root, eb));

    if (SVN_IS_VALID_REVNUM(replaces_rev))
    {
        SVN_ERR(can_modify(root, fspath, replaces_rev, scratch_pool));
        SVN_ERR(svn_fs_delete(root, fspath, scratch_pool));
    }
    else
    {
        SVN_ERR(can_create(root, fspath, scratch_pool));
    }

    SVN_ERR(svn_fs_make_dir(root, fspath, scratch_pool));
    SVN_ERR(add_new_props(root, fspath, props, scratch_pool));

    return SVN_NO_ERROR;
}
Esempio n. 22
0
/* This implements svn_editor_cb_add_file_t */
static svn_error_t *
add_file_cb(void *baton,
            const char *relpath,
            const svn_checksum_t *checksum,
            svn_stream_t *contents,
            apr_hash_t *props,
            svn_revnum_t replaces_rev,
            apr_pool_t *scratch_pool)
{
    struct edit_baton *eb = baton;
    const char *fspath = FSPATH(relpath, scratch_pool);
    svn_fs_root_t *root;

    SVN_ERR(get_root(&root, eb));

    if (SVN_IS_VALID_REVNUM(replaces_rev))
    {
        SVN_ERR(can_modify(root, fspath, replaces_rev, scratch_pool));
        SVN_ERR(svn_fs_delete(root, fspath, scratch_pool));
    }
    else
    {
        SVN_ERR(can_create(root, fspath, scratch_pool));
    }

    SVN_ERR(svn_fs_make_file(root, fspath, scratch_pool));

    SVN_ERR(set_text(root, fspath, checksum, contents,
                     eb->cancel_func, eb->cancel_baton, scratch_pool));
    SVN_ERR(add_new_props(root, fspath, props, scratch_pool));

    return SVN_NO_ERROR;
}
Esempio n. 23
0
/* Helper for svn_cl__append_tree_conflict_info_xml().
 * Appends the attributes of the given VERSION to ATT_HASH.
 * SIDE is the content of the version tag's side="..." attribute,
 * currently one of "source-left" or "source-right".*/
static svn_error_t *
add_conflict_version_xml(svn_stringbuf_t **pstr,
                         const char *side,
                         const svn_wc_conflict_version_t *version,
                         apr_pool_t *pool)
{
  apr_hash_t *att_hash = apr_hash_make(pool);


  apr_hash_set(att_hash, "side", APR_HASH_KEY_STRING, side);

  if (version->repos_url)
    apr_hash_set(att_hash, "repos-url", APR_HASH_KEY_STRING,
                 version->repos_url);

  if (version->path_in_repos)
    apr_hash_set(att_hash, "path-in-repos", APR_HASH_KEY_STRING,
                 version->path_in_repos);

  if (SVN_IS_VALID_REVNUM(version->peg_rev))
    apr_hash_set(att_hash, "revision", APR_HASH_KEY_STRING,
                 apr_ltoa(pool, version->peg_rev));

  if (version->node_kind != svn_node_unknown)
    apr_hash_set(att_hash, "kind", APR_HASH_KEY_STRING,
                 svn_cl__node_kind_str_xml(version->node_kind));

  svn_xml_make_open_tag_hash(pstr, pool, svn_xml_self_closing,
                             "version", att_hash);
  return SVN_NO_ERROR;
}
Esempio n. 24
0
/* Write the textual representation of *PART into P and return a pointer
 * to the first position behind that string.
 */
static char *
unparse_id_part(char *p,
                const svn_fs_fs__id_part_t *part)
{
  if (SVN_IS_VALID_REVNUM(part->revision))
    {
      /* ordinary old style / new style ID */
      p += svn__ui64tobase36(p, part->number);
      if (part->revision > 0)
        {
          *(p++) = '-';
          p += svn__i64toa(p, part->revision);
        }
    }
  else
    {
      /* in txn: mark with "_" prefix */
      *(p++) = '_';
      p += svn__ui64tobase36(p, part->number);
    }

  *(p++) = '.';

  return p;
}
Esempio n. 25
0
/* Make a revision baton, parsing the relevant HEADERS.
 *
 * Set RB->skipped iff the revision number is outside the range given in PB.
 */
static struct revision_baton *
make_revision_baton(apr_hash_t *headers,
                    struct parse_baton *pb,
                    apr_pool_t *pool)
{
  struct revision_baton *rb = apr_pcalloc(pool, sizeof(*rb));
  const char *val;

  rb->pb = pb;
  rb->pool = pool;
  rb->rev = SVN_INVALID_REVNUM;
  rb->revprops = apr_array_make(rb->pool, 8, sizeof(svn_prop_t));

  if ((val = svn_hash_gets(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER)))
    {
      rb->rev = SVN_STR_TO_REV(val);

      /* If we're filtering revisions, is this one we'll skip? */
      rb->skipped = (SVN_IS_VALID_REVNUM(pb->start_rev)
                     && ((rb->rev < pb->start_rev) ||
                         (rb->rev > pb->end_rev)));
    }

  return rb;
}
Esempio n. 26
0
static svn_error_t *
gls_log_receiver(void *baton,
                 svn_log_entry_t *log_entry,
                 apr_pool_t *pool)
{
  struct gls_log_receiver_baton *lrb = baton;
  const char *current_path = lrb->last_path;
  const char *prev_path;
  svn_revnum_t copyfrom_rev;

  /* If we're done, ignore this invocation. */
  if (lrb->done)
    return SVN_NO_ERROR;

  /* Figure out at which repository path our object of interest lived
     in the previous revision, and if its current location is the
     result of copy since then. */
  SVN_ERR(prev_log_path(&prev_path, NULL, &copyfrom_rev,
                        log_entry->changed_paths2, current_path,
                        lrb->kind, log_entry->revision, pool));

  /* If we've run off the end of the path's history, we need to report
     our final segment (and then, we're done). */
  if (! prev_path)
    {
      lrb->done = TRUE;
      return maybe_crop_and_send_segment(current_path, lrb->start_rev,
                                         log_entry->revision, lrb->range_end,
                                         lrb->receiver, lrb->receiver_baton,
                                         pool);
    }

  /* If there was a copy operation of interest... */
  if (SVN_IS_VALID_REVNUM(copyfrom_rev))
    {
      /* ...then report the segment between this revision and the
         last-reported revision. */
      SVN_ERR(maybe_crop_and_send_segment(current_path, lrb->start_rev,
                                          log_entry->revision, lrb->range_end,
                                          lrb->receiver, lrb->receiver_baton,
                                          pool));
      lrb->range_end = log_entry->revision - 1;

      /* And if there was a revision gap, we need to report that, too. */
      if (log_entry->revision - copyfrom_rev > 1)
        {
          SVN_ERR(maybe_crop_and_send_segment(NULL, lrb->start_rev,
                                              copyfrom_rev + 1, lrb->range_end,
                                              lrb->receiver,
                                              lrb->receiver_baton, pool));
          lrb->range_end = copyfrom_rev;
        }

      /* Update our state variables. */
      lrb->last_path = apr_pstrdup(lrb->pool, prev_path);
    }

  return SVN_NO_ERROR;
}
int
main(int argc, const char *argv[])
{
  apr_pool_t *pool;
  int exit_code = EXIT_SUCCESS;
  svn_error_t *err;
  const char *url;
  svn_revnum_t revision;
  const char *propname;
  svn_string_t *propval;
  svn_string_t *old_propval;
  char *digits_end = NULL;
  svn_boolean_t want_error;
  const char *config_dir;

  if (argc != 7)
    {
      fprintf(stderr, USAGE_MSG, argv[0], KEY_OLD_PROPVAL, KEY_NEW_PROPVAL);
      exit(1);
    }

  if (apr_initialize() != APR_SUCCESS)
    {
      fprintf(stderr, "apr_initialize() failed.\n");
      exit(1);
    }

  /* set up the global pool */
  pool = svn_pool_create(NULL);

  /* Parse argv. */
  url = svn_uri_canonicalize(argv[1], pool);
  revision = strtol(argv[2], &digits_end, 10);
  propname = argv[3];
  SVN_INT_ERR(extract_values_from_skel(&old_propval, &propval, argv[4], pool));
  want_error = !strcmp(argv[5], "1");
  config_dir = svn_dirent_canonicalize(argv[6], pool);


  if ((! SVN_IS_VALID_REVNUM(revision)) || (! digits_end) || *digits_end)
    SVN_INT_ERR(svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                 _("Invalid revision number supplied")));

  /* Do something. */
  err = change_rev_prop(url, revision, propname, propval, old_propval,
                        want_error, config_dir, pool);
  if (err)
    {
      svn_handle_error2(err, stderr, FALSE, "atomic-ra-revprop-change: ");
      svn_error_clear(err);
      exit_code = EXIT_FAILURE;
    }

  /* Clean up, and get outta here */
  svn_pool_destroy(pool);
  apr_terminate();

  return exit_code;
}
Esempio n. 28
0
/* Write a single change entry, path PATH, change CHANGE, to STREAM.

   All temporary allocations are in SCRATCH_POOL. */
static svn_error_t *
write_change_entry(svn_stream_t *stream,
                   svn_fs_x__change_t *change,
                   apr_pool_t *scratch_pool)
{
  const char *change_string = NULL;
  const char *kind_string = "";
  svn_stringbuf_t *buf;
  apr_size_t len;

  switch (change->change_kind)
    {
    case svn_fs_path_change_modify:
      change_string = ACTION_MODIFY;
      break;
    case svn_fs_path_change_add:
      change_string = ACTION_ADD;
      break;
    case svn_fs_path_change_delete:
      change_string = ACTION_DELETE;
      break;
    case svn_fs_path_change_replace:
      change_string = ACTION_REPLACE;
      break;
    default:
      return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                               _("Invalid change type %d"),
                               change->change_kind);
    }

  SVN_ERR_ASSERT(change->node_kind == svn_node_dir
                 || change->node_kind == svn_node_file);
  kind_string = apr_psprintf(scratch_pool, "-%s",
                             change->node_kind == svn_node_dir
                             ? SVN_FS_X__KIND_DIR
                             : SVN_FS_X__KIND_FILE);

  buf = svn_stringbuf_createf(scratch_pool, "%s%s %s %s %s %s\n",
                              change_string, kind_string,
                              change->text_mod ? FLAG_TRUE : FLAG_FALSE,
                              change->prop_mod ? FLAG_TRUE : FLAG_FALSE,
                              change->mergeinfo_mod == svn_tristate_true
                                               ? FLAG_TRUE : FLAG_FALSE,
                              auto_escape_path(change->path.data, scratch_pool));

  if (SVN_IS_VALID_REVNUM(change->copyfrom_rev))
    {
      svn_stringbuf_appendcstr(buf, apr_psprintf(scratch_pool, "%ld %s",
                               change->copyfrom_rev,
                               auto_escape_path(change->copyfrom_path,
                                                scratch_pool)));
    }

  svn_stringbuf_appendbyte(buf, '\n');

  /* Write all change info in one write call. */
  len = buf->len;
  return svn_error_trace(svn_stream_write(stream, buf->data, &len));
}
svn_error_t *svn_ra_rev_proplist(svn_ra_session_t *session,
                                 svn_revnum_t rev,
                                 apr_hash_t **props,
                                 apr_pool_t *pool)
{
  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(rev));
  return session->vtable->rev_proplist(session, rev, props, pool);
}
Esempio n. 30
0
svn_error_t *
svn_ra_serf__create_propfind_handler(svn_ra_serf__handler_t **propfind_handler,
                                     svn_ra_serf__session_t *sess,
                                     const char *path,
                                     svn_revnum_t rev,
                                     const char *depth,
                                     const svn_ra_serf__dav_props_t *find_props,
                                     svn_ra_serf__prop_func_t prop_func,
                                     void *prop_func_baton,
                                     apr_pool_t *pool)
{
  propfind_context_t *new_prop_ctx;
  svn_ra_serf__handler_t *handler;
  svn_ra_serf__xml_context_t *xmlctx;

  new_prop_ctx = apr_pcalloc(pool, sizeof(*new_prop_ctx));

  new_prop_ctx->path = path;
  new_prop_ctx->find_props = find_props;
  new_prop_ctx->prop_func = prop_func;
  new_prop_ctx->prop_func_baton = prop_func_baton;
  new_prop_ctx->depth = depth;

  if (SVN_IS_VALID_REVNUM(rev))
    {
      new_prop_ctx->label = apr_ltoa(pool, rev);
    }
  else
    {
      new_prop_ctx->label = NULL;
    }

  xmlctx = svn_ra_serf__xml_context_create(propfind_ttable,
                                           propfind_opened,
                                           propfind_closed,
                                           NULL,
                                           new_prop_ctx,
                                           pool);
  handler = svn_ra_serf__create_expat_handler(sess, xmlctx,
                                              propfind_expected_status,
                                              pool);

  handler->method = "PROPFIND";
  handler->path = path;
  handler->body_delegate = create_propfind_body;
  handler->body_type = "text/xml";
  handler->body_delegate_baton = new_prop_ctx;
  handler->header_delegate = setup_propfind_headers;
  handler->header_delegate_baton = new_prop_ctx;

  handler->no_dav_headers = TRUE;

  new_prop_ctx->handler = handler;

  *propfind_handler = handler;

  return SVN_NO_ERROR;
}