Exemple #1
0
/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
blame_closed(svn_ra_serf__xml_estate_t *xes,
             void *baton,
             int leaving_state,
             const svn_string_t *cdata,
             apr_hash_t *attrs,
             apr_pool_t *scratch_pool)
{
  blame_context_t *blame_ctx = baton;

  if (leaving_state == FILE_REV)
    {
      /* Note that we test STREAM, but any pointer is currently invalid.
         It was closed when left the TXDELTA state.  */
      if (blame_ctx->stream == NULL)
        {
          const char *path;
          const char *rev;

          path = svn_hash_gets(attrs, "path");
          rev = svn_hash_gets(attrs, "rev");

          /* Send a "no content" notification.  */
          SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton,
                                      path, SVN_STR_TO_REV(rev),
                                      blame_ctx->rev_props,
                                      FALSE /* result_of_merge */,
                                      NULL, NULL, /* txdelta / baton */
                                      blame_ctx->prop_diffs,
                                      scratch_pool));
        }
    }
  else if (leaving_state == MERGED_REVISION)
    {
      svn_ra_serf__xml_note(xes, FILE_REV, "merged-revision", "*");
    }
  else if (leaving_state == TXDELTA)
    {
      SVN_ERR(svn_stream_close(blame_ctx->stream));
    }
  else
    {
      const char *name;
      const svn_string_t *value;

      SVN_ERR_ASSERT(leaving_state == REV_PROP
                     || leaving_state == SET_PROP
                     || leaving_state == REMOVE_PROP);

      name = apr_pstrdup(blame_ctx->state_pool,
                         svn_hash_gets(attrs, "name"));

      if (leaving_state == REMOVE_PROP)
        {
          value = NULL;
        }
      else
        {
          const char *encoding = svn_hash_gets(attrs, "encoding");

          if (encoding && strcmp(encoding, "base64") == 0)
            value = svn_base64_decode_string(cdata, blame_ctx->state_pool);
          else
            value = svn_string_dup(cdata, blame_ctx->state_pool);
        }

      if (leaving_state == REV_PROP)
        {
          svn_hash_sets(blame_ctx->rev_props, name, value);
        }
      else
        {
          svn_prop_t *prop = apr_array_push(blame_ctx->prop_diffs);

          prop->name = name;
          prop->value = value;
        }
    }

  return SVN_NO_ERROR;
}
Exemple #2
0
svn_error_t *
svn_repos__get_commit_ev2(svn_editor_t **editor,
                          svn_repos_t *repos,
                          svn_authz_t *authz,
                          const char *authz_repos_name,
                          const char *authz_user,
                          apr_hash_t *revprops,
                          svn_commit_callback2_t commit_cb,
                          void *commit_baton,
                          svn_cancel_func_t cancel_func,
                          void *cancel_baton,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
{
  static const svn_editor_cb_many_t editor_cbs = {
    add_directory_cb,
    add_file_cb,
    add_symlink_cb,
    add_absent_cb,
    alter_directory_cb,
    alter_file_cb,
    alter_symlink_cb,
    delete_cb,
    copy_cb,
    move_cb,
    rotate_cb,
    complete_cb,
    abort_cb
  };
  struct ev2_baton *eb;
  const svn_string_t *author;
  apr_hash_t *hooks_env;

  /* Parse the hooks-env file (if any). */
  SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
                                     scratch_pool, scratch_pool));

  /* Can the user modify the repository at all?  */
  /* ### check against AUTHZ.  */

  author = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR);

  eb = apr_palloc(result_pool, sizeof(*eb));
  eb->repos = repos;
  eb->authz = authz;
  eb->authz_repos_name = authz_repos_name;
  eb->authz_user = authz_user;
  eb->commit_cb = commit_cb;
  eb->commit_baton = commit_baton;

  SVN_ERR(svn_fs__editor_create(&eb->inner, &eb->txn_name,
                                repos->fs, SVN_FS_TXN_CHECK_LOCKS,
                                cancel_func, cancel_baton,
                                result_pool, scratch_pool));

  /* The TXN has been created. Go ahead and apply all revision properties.  */
  SVN_ERR(apply_revprops(repos->fs, eb->txn_name, revprops, scratch_pool));

  /* Okay... some access is allowed. Let's run the start-commit hook.  */
  SVN_ERR(svn_repos__hooks_start_commit(repos, hooks_env,
                                        author ? author->data : NULL,
                                        repos->client_capabilities,
                                        eb->txn_name, scratch_pool));

  /* Wrap the FS editor within our editor.  */
  SVN_ERR(svn_editor_create(editor, eb, cancel_func, cancel_baton,
                            result_pool, scratch_pool));
  SVN_ERR(svn_editor_setcb_many(*editor, &editor_cbs, scratch_pool));

  return SVN_NO_ERROR;
}
Exemple #3
0
svn_error_t *
svn_config_walk_auth_data(const char *config_dir,
                          svn_config_auth_walk_func_t walk_func,
                          void *walk_baton,
                          apr_pool_t *scratch_pool)
{
  int i;
  apr_pool_t *iterpool;
  svn_boolean_t finished = FALSE;
  const char *cred_kinds[] =
    {
      SVN_AUTH_CRED_SIMPLE,
      SVN_AUTH_CRED_USERNAME,
      SVN_AUTH_CRED_SSL_CLIENT_CERT,
      SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
      SVN_AUTH_CRED_SSL_SERVER_TRUST,
      NULL
    };

  iterpool = svn_pool_create(scratch_pool);
  for (i = 0; cred_kinds[i]; i++)
    {
      const char *item_path;
      const char *dir_path;
      apr_hash_t *nodes;
      svn_error_t *err;
      apr_pool_t *itempool;
      apr_hash_index_t *hi;

      svn_pool_clear(iterpool);

      if (finished)
        break;

      SVN_ERR(svn_auth__file_path(&item_path, cred_kinds[i], "!", config_dir,
                                  iterpool));

      dir_path = svn_dirent_dirname(item_path, iterpool);

      err = svn_io_get_dirents3(&nodes, dir_path, TRUE, iterpool, iterpool);
      if (err)
        {
          if (!APR_STATUS_IS_ENOENT(err->apr_err)
              && !SVN__APR_STATUS_IS_ENOTDIR(err->apr_err))
            return svn_error_trace(err);

          svn_error_clear(err);
          continue;
        }

      itempool = svn_pool_create(iterpool);
      for (hi = apr_hash_first(iterpool, nodes); hi; hi = apr_hash_next(hi))
        {
          svn_io_dirent2_t *dirent = svn__apr_hash_index_val(hi);
          svn_stream_t *stream;
          apr_hash_t *creds_hash;
          const svn_string_t *realm;
          svn_boolean_t delete_file = FALSE;

          if (finished)
            break;

          if (dirent->kind != svn_node_file)
            continue;

          svn_pool_clear(itempool);

          item_path = svn_dirent_join(dir_path, svn__apr_hash_index_key(hi),
                                      itempool);

          err = svn_stream_open_readonly(&stream, item_path,
                                         itempool, itempool);
          if (err)
            {
              /* Ignore this file. There are no credentials in it anyway */
              svn_error_clear(err);
              continue;
            }

          creds_hash = apr_hash_make(itempool);
          err = svn_hash_read2(creds_hash, stream,
                               SVN_HASH_TERMINATOR, itempool);
          err = svn_error_compose_create(err, svn_stream_close(stream));
          if (err)
            {
              /* Ignore this file. There are no credentials in it anyway */
              svn_error_clear(err);
              continue;
            }

          realm = svn_hash_gets(creds_hash, SVN_CONFIG_REALMSTRING_KEY);
          if (! realm)
            continue; /* Not an auth file */

          err = walk_func(&delete_file, walk_baton, cred_kinds[i],
                          realm->data, creds_hash, itempool);
          if (err && err->apr_err == SVN_ERR_CEASE_INVOCATION)
            {
              svn_error_clear(err);
              err = SVN_NO_ERROR;
              finished = TRUE;
            }
          SVN_ERR(err);

          if (delete_file)
            {
              /* Delete the file on disk */
              SVN_ERR(svn_io_remove_file2(item_path, TRUE, itempool));
            }
        }
    }

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}
Exemple #4
0
/* Given a list of committables described by their common base abspath
   BASE_ABSPATH and a list of relative dirents TARGET_RELPATHS determine
   which absolute paths must be locked to commit all these targets and
   return this as a const char * array in LOCK_TARGETS

   Allocate the result in RESULT_POOL and use SCRATCH_POOL for temporary
   storage */
static svn_error_t *
determine_lock_targets(apr_array_header_t **lock_targets,
                       svn_wc_context_t *wc_ctx,
                       const char *base_abspath,
                       const apr_array_header_t *target_relpaths,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  apr_hash_t *wc_items; /* const char *wcroot -> apr_array_header_t */
  apr_hash_index_t *hi;
  int i;

  wc_items = apr_hash_make(scratch_pool);

  /* Create an array of targets for each working copy used */
  for (i = 0; i < target_relpaths->nelts; i++)
    {
      const char *target_abspath;
      const char *wcroot_abspath;
      apr_array_header_t *wc_targets;
      svn_error_t *err;
      const char *target_relpath = APR_ARRAY_IDX(target_relpaths, i,
                                                 const char *);

      svn_pool_clear(iterpool);
      target_abspath = svn_dirent_join(base_abspath, target_relpath,
                                       scratch_pool);

      err = svn_wc__get_wcroot(&wcroot_abspath, wc_ctx, target_abspath,
                               iterpool, iterpool);

      if (err)
        {
          if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
            {
              svn_error_clear(err);
              continue;
            }
          return svn_error_trace(err);
        }

      wc_targets = svn_hash_gets(wc_items, wcroot_abspath);

      if (! wc_targets)
        {
          wc_targets = apr_array_make(scratch_pool, 4, sizeof(const char *));
          svn_hash_sets(wc_items, apr_pstrdup(scratch_pool, wcroot_abspath),
                        wc_targets);
        }

      APR_ARRAY_PUSH(wc_targets, const char *) = target_abspath;
    }

  *lock_targets = apr_array_make(result_pool, apr_hash_count(wc_items),
                                 sizeof(const char *));

  /* For each working copy determine where to lock */
  for (hi = apr_hash_first(scratch_pool, wc_items);
       hi;
       hi = apr_hash_next(hi))
    {
      const char *common;
      const char *wcroot_abspath = apr_hash_this_key(hi);
      apr_array_header_t *wc_targets = apr_hash_this_val(hi);

      svn_pool_clear(iterpool);

      if (wc_targets->nelts == 1)
        {
          const char *target_abspath;
          target_abspath = APR_ARRAY_IDX(wc_targets, 0, const char *);

          if (! strcmp(wcroot_abspath, target_abspath))
            {
              APR_ARRAY_PUSH(*lock_targets, const char *)
                      = apr_pstrdup(result_pool, target_abspath);
            }
          else
            {
              /* Lock the parent to allow deleting the target */
              APR_ARRAY_PUSH(*lock_targets, const char *)
                      = svn_dirent_dirname(target_abspath, result_pool);
            }
        }