Esempio n. 1
0
/* Return the path to something in PATH's administrative area.
 *
 * First, the adm subdir is appended to PATH as a component, then the
 * "tmp" directory is added iff USE_TMP is set, then each of the
 * varargs in AP (char *'s) is appended as a path component.  The list
 * must be terminated with a NULL argument.
 *
 * Adding an empty component results in no effect (i.e., the separator
 * char is not doubled).
 *
 * If EXTENSION is non-null, it will be appended to the final string
 * without a separator character.
 */
static const char *
v_extend_with_adm_name(const char *path,
                       const char *extension,
                       svn_boolean_t use_tmp,
                       apr_pool_t *pool,
                       va_list ap)
{
  const char *this;

  /* Tack on the administrative subdirectory. */
  path = svn_path_join(path, adm_dir_name, pool);

  /* If this is a tmp file, name it into the tmp area. */
  if (use_tmp)
    path = svn_path_join(path, SVN_WC__ADM_TMP, pool);

  /* Tack on everything else. */
  while ((this = va_arg(ap, const char *)) != NULL)
    {
      if (this[0] == '\0')
        continue;

      path = svn_path_join(path, this, pool);
    }

  if (extension)
    path = apr_pstrcat(pool, path, extension, NULL);

  return path;
}
Esempio n. 2
0
/* Return filename for ACTIVITY_ID under the repository in REPOS. */
static const char *
activity_pathname(const dav_svn_repos *repos, const char *activity_id)
{
  return svn_path_join(repos->activities_db,
                       escape_activity(activity_id, repos->pool),
                       repos->pool);
}
Esempio n. 3
0
static svn_error_t *
svn_ra_local__get_mergeinfo(svn_ra_session_t *session,
                            svn_mergeinfo_catalog_t *catalog,
                            const apr_array_header_t *paths,
                            svn_revnum_t revision,
                            svn_mergeinfo_inheritance_t inherit,
                            svn_boolean_t include_descendants,
                            apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  svn_mergeinfo_catalog_t tmp_catalog;
  int i;
  apr_array_header_t *abs_paths =
    apr_array_make(pool, 0, sizeof(const char *));

  for (i = 0; i < paths->nelts; i++)
    {
      const char *relative_path = APR_ARRAY_IDX(paths, i, const char *);
      APR_ARRAY_PUSH(abs_paths, const char *) =
        svn_path_join(sess->fs_path->data, relative_path, pool);
    }

  SVN_ERR(svn_repos_fs_get_mergeinfo(&tmp_catalog, sess->repos, abs_paths,
                                     revision, inherit, include_descendants,
                                     NULL, NULL, pool));
  if (apr_hash_count(tmp_catalog) > 0)
    SVN_ERR(svn_mergeinfo__remove_prefix_from_catalog(catalog,
                                                      tmp_catalog,
                                                      sess->fs_path->data,
                                                      pool));
  else
    *catalog = NULL;

  return SVN_NO_ERROR;
}
Esempio n. 4
0
/* Make a new entry named NAME in PARENT.  If IS_DIR is true, then the
   node revision the new entry points to will be a directory, else it
   will be a file.  The new node will be allocated in POOL.  PARENT
   must be mutable, and must not have an entry named NAME.  */
static svn_error_t *
make_entry(dag_node_t **child_p,
           dag_node_t *parent,
           const char *parent_path,
           const char *name,
           svn_boolean_t is_dir,
           const char *txn_id,
           apr_pool_t *pool)
{
    const svn_fs_id_t *new_node_id;
    node_revision_t new_noderev, *parent_noderev;

    /* Make sure that NAME is a single path component. */
    if (! svn_path_is_single_path_component(name))
        return svn_error_createf
               (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL,
                _("Attempted to create a node with an illegal name '%s'"), name);

    /* Make sure that parent is a directory */
    if (parent->kind != svn_node_dir)
        return svn_error_create
               (SVN_ERR_FS_NOT_DIRECTORY, NULL,
                _("Attempted to create entry in non-directory parent"));

    /* Check that the parent is mutable. */
    if (! svn_fs_fs__dag_check_mutable(parent))
        return svn_error_createf
               (SVN_ERR_FS_NOT_MUTABLE, NULL,
                _("Attempted to clone child of non-mutable node"));

    /* Create the new node's NODE-REVISION */
    memset(&new_noderev, 0, sizeof(new_noderev));
    new_noderev.kind = is_dir ? svn_node_dir : svn_node_file;
    new_noderev.created_path = svn_path_join(parent_path, name, pool);

    SVN_ERR(get_node_revision(&parent_noderev, parent, pool));
    new_noderev.copyroot_path = apr_pstrdup(pool,
                                            parent_noderev->copyroot_path);
    new_noderev.copyroot_rev = parent_noderev->copyroot_rev;
    new_noderev.copyfrom_rev = SVN_INVALID_REVNUM;
    new_noderev.copyfrom_path = NULL;

    SVN_ERR(svn_fs_fs__create_node
            (&new_node_id, svn_fs_fs__dag_get_fs(parent), &new_noderev,
             svn_fs_fs__id_copy_id(svn_fs_fs__dag_get_id(parent)),
             txn_id, pool));

    /* Create a new dag_node_t for our new node */
    SVN_ERR(svn_fs_fs__dag_get_node(child_p, svn_fs_fs__dag_get_fs(parent),
                                    new_node_id, pool));

    /* We can safely call set_entry because we already know that
       PARENT is mutable, and we just created CHILD, so we know it has
       no ancestors (therefore, PARENT cannot be an ancestor of CHILD) */
    return set_entry(parent, name, svn_fs_fs__dag_get_id(*child_p),
                     new_noderev.kind, txn_id, pool);
}
Esempio n. 5
0
/* Getting just one file. */
static svn_error_t *
svn_ra_local__get_file(svn_ra_session_t *session,
                       const char *path,
                       svn_revnum_t revision,
                       svn_stream_t *stream,
                       svn_revnum_t *fetched_rev,
                       apr_hash_t **props,
                       apr_pool_t *pool)
{
  svn_fs_root_t *root;
  svn_stream_t *contents;
  svn_revnum_t youngest_rev;
  svn_ra_local__session_baton_t *sess = session->priv;
  const char *abs_path = svn_path_join(sess->fs_path->data, path, pool);

  /* Open the revision's root. */
  if (! SVN_IS_VALID_REVNUM(revision))
    {
      SVN_ERR(svn_fs_youngest_rev(&youngest_rev, sess->fs, pool));
      SVN_ERR(svn_fs_revision_root(&root, sess->fs, youngest_rev, pool));
      if (fetched_rev != NULL)
        *fetched_rev = youngest_rev;
    }
  else
    SVN_ERR(svn_fs_revision_root(&root, sess->fs, revision, pool));

  if (stream)
    {
      /* Get a stream representing the file's contents. */
      SVN_ERR(svn_fs_file_contents(&contents, root, abs_path, pool));

      /* Now push data from the fs stream back at the caller's stream.
         Note that this particular RA layer does not computing a
         checksum as we go, and confirming it against the repository's
         checksum when done.  That's because it calls
         svn_fs_file_contents() directly, which already checks the
         stored checksum, and all we're doing here is writing bytes in
         a loop.  Truly, Nothing Can Go Wrong :-).  But RA layers that
         go over a network should confirm the checksum.

         Note: we are not supposed to close the passed-in stream, so
         disown the thing.
      */
      SVN_ERR(svn_stream_copy3(contents, svn_stream_disown(stream, pool),
                               sess->callbacks
                                 ? sess->callbacks->cancel_func : NULL,
                               sess->callback_baton,
                               pool));
    }

  /* Handle props if requested. */
  if (props)
    SVN_ERR(get_node_props(props, sess, root, abs_path, pool));

  return SVN_NO_ERROR;
}
Esempio n. 6
0
static svn_error_t *
svn_ra_local__lock(svn_ra_session_t *session,
                   apr_hash_t *path_revs,
                   const char *comment,
                   svn_boolean_t force,
                   svn_ra_lock_callback_t lock_func,
                   void *lock_baton,
                   apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  apr_hash_index_t *hi;
  apr_pool_t *iterpool = svn_pool_create(pool);

  /* A username is absolutely required to lock a path. */
  SVN_ERR(get_username(session, pool));

  for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi))
    {
      svn_lock_t *lock;
      const void *key;
      const char *path;
      void *val;
      svn_revnum_t *revnum;
      const char *abs_path;
      svn_error_t *err, *callback_err = NULL;

      svn_pool_clear(iterpool);
      apr_hash_this(hi, &key, NULL, &val);
      path = key;
      revnum = val;

      abs_path = svn_path_join(sess->fs_path->data, path, iterpool);

      /* This wrapper will call pre- and post-lock hooks. */
      err = svn_repos_fs_lock(&lock, sess->repos, abs_path, NULL, comment,
                              FALSE /* not DAV comment */,
                              0 /* no expiration */, *revnum, force,
                              iterpool);

      if (err && !SVN_ERR_IS_LOCK_ERROR(err))
        return err;

      if (lock_func)
        callback_err = lock_func(lock_baton, path, TRUE, err ? NULL : lock,
                                 err, iterpool);

      svn_error_clear(err);

      if (callback_err)
        return callback_err;
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}
Esempio n. 7
0
static svn_error_t *
svn_ra_local__get_lock(svn_ra_session_t *session,
                       svn_lock_t **lock,
                       const char *path,
                       apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  const char *abs_path = svn_path_join(sess->fs_path->data, path, pool);
  return svn_fs_get_lock(lock, sess->fs, abs_path, pool);
}
Esempio n. 8
0
static svn_error_t *
svn_ra_local__unlock(svn_ra_session_t *session,
                     apr_hash_t *path_tokens,
                     svn_boolean_t force,
                     svn_ra_lock_callback_t lock_func,
                     void *lock_baton,
                     apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  apr_hash_index_t *hi;
  apr_pool_t *iterpool = svn_pool_create(pool);

  /* A username is absolutely required to unlock a path. */
  SVN_ERR(get_username(session, pool));

  for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi))
    {
      const void *key;
      const char *path;
      void *val;
      const char *abs_path, *token;
      svn_error_t *err, *callback_err = NULL;

      svn_pool_clear(iterpool);
      apr_hash_this(hi, &key, NULL, &val);
      path = key;
      /* Since we can't store NULL values in a hash, we turn "" to
         NULL here. */
      if (strcmp(val, "") != 0)
        token = val;
      else
        token = NULL;

      abs_path = svn_path_join(sess->fs_path->data, path, iterpool);

      /* This wrapper will call pre- and post-unlock hooks. */
      err = svn_repos_fs_unlock(sess->repos, abs_path, token, force,
                                iterpool);

      if (err && !SVN_ERR_IS_UNLOCK_ERROR(err))
        return err;

      if (lock_func)
        callback_err = lock_func(lock_baton, path, FALSE, NULL, err, iterpool);

      svn_error_clear(err);

      if (callback_err)
        return callback_err;
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}
Esempio n. 9
0
static svn_error_t *
svn_ra_local__get_log(svn_ra_session_t *session,
                      const apr_array_header_t *paths,
                      svn_revnum_t start,
                      svn_revnum_t end,
                      int limit,
                      svn_boolean_t discover_changed_paths,
                      svn_boolean_t strict_node_history,
                      svn_boolean_t include_merged_revisions,
                      const apr_array_header_t *revprops,
                      svn_log_entry_receiver_t receiver,
                      void *receiver_baton,
                      apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  int i;
  struct log_baton lb;
  apr_array_header_t *abs_paths =
    apr_array_make(pool, 0, sizeof(const char *));

  if (paths)
    {
      for (i = 0; i < paths->nelts; i++)
        {
          const char *relative_path = APR_ARRAY_IDX(paths, i, const char *);
          APR_ARRAY_PUSH(abs_paths, const char *) =
            svn_path_join(sess->fs_path->data, relative_path, pool);
        }
    }

  if (sess->callbacks &&
      sess->callbacks->cancel_func)
    {
      lb.real_cb = receiver;
      lb.real_baton = receiver_baton;
      lb.sess = sess;

      receiver = cancellation_log_receiver;
      receiver_baton = &lb;
    }

  return svn_repos_get_logs4(sess->repos,
                             abs_paths,
                             start,
                             end,
                             limit,
                             discover_changed_paths,
                             strict_node_history,
                             include_merged_revisions,
                             revprops,
                             NULL, NULL,
                             receiver,
                             receiver_baton,
                             pool);
}
Esempio n. 10
0
static svn_error_t *
svn_ra_local__get_session_url(svn_ra_session_t *session,
                              const char **url,
                              apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  *url = svn_path_join(sess->repos_url,
                       svn_path_uri_encode(sess->fs_path->data + 1, pool),
                       pool);
  return SVN_NO_ERROR;
}
Esempio n. 11
0
svn_error_t *
svn_fs_fs__dag_copy(dag_node_t *to_node,
                    const char *entry,
                    dag_node_t *from_node,
                    svn_boolean_t preserve_history,
                    svn_revnum_t from_rev,
                    const char *from_path,
                    const char *txn_id,
                    apr_pool_t *pool)
{
    const svn_fs_id_t *id;

    if (preserve_history)
    {
        node_revision_t *from_noderev, *to_noderev;
        const char *copy_id;
        const svn_fs_id_t *src_id = svn_fs_fs__dag_get_id(from_node);
        svn_fs_t *fs = svn_fs_fs__dag_get_fs(from_node);

        /* Make a copy of the original node revision. */
        SVN_ERR(get_node_revision(&from_noderev, from_node, pool));
        to_noderev = copy_node_revision(from_noderev, pool);

        /* Reserve a copy ID for this new copy. */
        SVN_ERR(svn_fs_fs__reserve_copy_id(&copy_id, fs, txn_id, pool));

        /* Create a successor with its predecessor pointing at the copy
           source. */
        to_noderev->predecessor_id = svn_fs_fs__id_copy(src_id, pool);
        if (to_noderev->predecessor_count != -1)
            to_noderev->predecessor_count++;
        to_noderev->created_path =
            svn_path_join(svn_fs_fs__dag_get_created_path(to_node), entry,
                          pool);
        to_noderev->copyfrom_path = apr_pstrdup(pool, from_path);
        to_noderev->copyfrom_rev = from_rev;

        /* Set the copyroot equal to our own id. */
        to_noderev->copyroot_path = NULL;

        SVN_ERR(svn_fs_fs__create_successor(&id, fs, src_id, to_noderev,
                                            copy_id, txn_id, pool));

    }
    else  /* don't preserve history */
    {
        id = svn_fs_fs__dag_get_id(from_node);
    }

    /* Set the entry in to_node to the new id. */
    return svn_fs_fs__dag_set_entry(to_node, entry, id, from_node->kind,
                                    txn_id, pool);
}
Esempio n. 12
0
/* This implements 'svn_commit_callback_t'.  Its invokes the original
   (wrapped) callback, but also does deltification on the new revision and
   possibly unlocks committed paths.
   BATON is 'struct deltify_etc_baton *'. */
static svn_error_t *
deltify_etc(const svn_commit_info_t *commit_info,
            void *baton, apr_pool_t *pool)
{
  struct deltify_etc_baton *db = baton;
  svn_error_t *err1, *err2;
  apr_hash_index_t *hi;
  apr_pool_t *iterpool;

  /* Invoke the original callback first, in case someone's waiting to
     know the revision number so they can go off and annotate an
     issue or something. */
  err1 = (*db->callback)(commit_info, db->callback_baton, pool);

  /* Maybe unlock the paths. */
  if (db->lock_tokens)
    {
      iterpool = svn_pool_create(db->pool);
      for (hi = apr_hash_first(db->pool, db->lock_tokens); hi;
           hi = apr_hash_next(hi))
        {
          const void *rel_path;
          void *val;
          const char *abs_path, *token;

          svn_pool_clear(iterpool);
          apr_hash_this(hi, &rel_path, NULL, &val);
          token = val;
          abs_path = svn_path_join(db->fs_path, rel_path, iterpool);
          /* We may get errors here if the lock was broken or stolen
             after the commit succeeded.  This is fine and should be
             ignored. */
          svn_error_clear(svn_repos_fs_unlock(db->repos, abs_path, token,
                                              FALSE, iterpool));
        }
      svn_pool_destroy(iterpool);
    }

  /* But, deltification shouldn't be stopped just because someone's
     random callback failed, so proceed unconditionally on to
     deltification. */
  err2 = svn_fs_deltify_revision(db->fs, commit_info->revision, db->pool);

  /* It's more interesting if the original callback failed, so let
     that one dominate. */
  if (err1)
    {
      svn_error_clear(err2);
      return err1;
    }

  return err2;
}
Esempio n. 13
0
static svn_error_t *
test_delete_entry(const char *path,
                  svn_revnum_t revision,
                  void *parent_baton,
                  apr_pool_t *pool)
{
  struct dir_baton *pb = parent_baton;

  /* Construct the full path of this entry and delete it from the txn. */
  return svn_fs_delete(pb->edit_baton->txn_root, 
                       svn_path_join(pb->edit_baton->root_path, path, pool),
                       pool);
}
Esempio n. 14
0
static svn_error_t *
svn_ra_local__get_locks(svn_ra_session_t *session,
                        apr_hash_t **locks,
                        const char *path,
                        apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  const char *abs_path = svn_path_join(sess->fs_path->data, path, pool);

  /* Kinda silly to call the repos wrapper, since we have no authz
     func to give it.  But heck, why not. */
  return svn_repos_fs_get_locks(locks, sess->repos, abs_path,
                                NULL, NULL, pool);
}
Esempio n. 15
0
static svn_error_t *
svn_ra_local__get_locations(svn_ra_session_t *session,
                            apr_hash_t **locations,
                            const char *path,
                            svn_revnum_t peg_revision,
                            apr_array_header_t *location_revisions,
                            apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  const char *abs_path = svn_path_join(sess->fs_path->data, path, pool);
  return svn_repos_trace_node_locations(sess->fs, locations, abs_path,
                                        peg_revision, location_revisions,
                                        NULL, NULL, pool);
}
Esempio n. 16
0
/* Write the format number and maximum number of files per directory
   to a new format file in PATH, overwriting a previously existing file.

   Use POOL for temporary allocation.

   This implementation is largely stolen from libsvn_fs_fs/fs_fs.c. */
static svn_error_t *
write_format(const char *path,
             int format,
             int max_files_per_dir,
             apr_pool_t *pool)
{
  const char *contents;

  path = svn_path_join(path, "format", pool);

  if (format >= SVN_FS_FS__MIN_LAYOUT_FORMAT_OPTION_FORMAT)
    {
      if (max_files_per_dir)
        contents = apr_psprintf(pool,
                                "%d\n"
                                "layout sharded %d\n",
                                format, max_files_per_dir);
      else
        contents = apr_psprintf(pool,
                                "%d\n"
                                "layout linear",
                                format);
    }
  else
    {
      contents = apr_psprintf(pool, "%d\n", format);
    }

    {
      const char *path_tmp;

      SVN_ERR(svn_io_write_unique(&path_tmp,
                                  svn_path_dirname(path, pool),
                                  contents, strlen(contents),
                                  svn_io_file_del_none, pool));

#ifdef WIN32
      /* make the destination writable, but only on Windows, because
         Windows does not let us replace read-only files. */
      SVN_ERR(svn_io_set_file_read_write(path, TRUE, pool));
#endif /* WIN32 */

      /* rename the temp file as the real destination */
      SVN_ERR(svn_io_file_rename(path_tmp, path, pool));
    }

  /* And set the perms to make it read only */
  return svn_io_set_file_read_only(path, FALSE, pool);
}
Esempio n. 17
0
static svn_error_t *
svn_ra_local__do_check_path(svn_ra_session_t *session,
                            const char *path,
                            svn_revnum_t revision,
                            svn_node_kind_t *kind,
                            apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  svn_fs_root_t *root;
  const char *abs_path = svn_path_join(sess->fs_path->data, path, pool);

  if (! SVN_IS_VALID_REVNUM(revision))
    SVN_ERR(svn_fs_youngest_rev(&revision, sess->fs, pool));
  SVN_ERR(svn_fs_revision_root(&root, sess->fs, revision, pool));
  return svn_fs_check_path(kind, root, abs_path, pool);
}
Esempio n. 18
0
static svn_error_t *
svn_ra_local__get_file_revs(svn_ra_session_t *session,
                            const char *path,
                            svn_revnum_t start,
                            svn_revnum_t end,
                            svn_boolean_t include_merged_revisions,
                            svn_file_rev_handler_t handler,
                            void *handler_baton,
                            apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  const char *abs_path = svn_path_join(sess->fs_path->data, path, pool);
  return svn_repos_get_file_revs2(sess->repos, abs_path, start, end,
                                  include_merged_revisions, NULL, NULL,
                                  handler, handler_baton, pool);
}
Esempio n. 19
0
static svn_error_t *
svn_ra_local__get_location_segments(svn_ra_session_t *session,
                                    const char *path,
                                    svn_revnum_t peg_revision,
                                    svn_revnum_t start_rev,
                                    svn_revnum_t end_rev,
                                    svn_location_segment_receiver_t receiver,
                                    void *receiver_baton,
                                    apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  const char *abs_path = svn_path_join(sess->fs_path->data, path, pool);
  return svn_repos_node_location_segments(sess->repos, abs_path,
                                          peg_revision, start_rev, end_rev,
                                          receiver, receiver_baton,
                                          NULL, NULL, pool);
}
Esempio n. 20
0
/* A callback function used when the RA layer needs a handle to a
   temporary file.  This is a reduced version of the callback used in
   the official svn cmdline client. */
static svn_error_t *
open_tmp_file (apr_file_t **fp,
               void *callback_baton,
               apr_pool_t *pool)
{
  const char *path;
  const char *ignored_filename;

  SVN_ERR (svn_io_temp_dir (&path, pool));
  path = svn_path_join (path, "tempfile", pool);

  /* Open a unique file, with delete-on-close set. */
  SVN_ERR (svn_io_open_unique_file2 (fp, &ignored_filename,
                                     path, ".tmp",
                                     svn_io_file_del_on_close, pool));

  return SVN_NO_ERROR;
}
Esempio n. 21
0
dav_svn_get_repos_path(request_rec *r,
                       const char *root_path,
                       const char **repos_path)
{

  const char *fs_path;
  const char *fs_parent_path;
  const char *repos_name;
  const char *ignored_path_in_repos;
  const char *ignored_cleaned_uri;
  const char *ignored_relative;
  int ignored_had_slash;
  dav_error *derr;

  /* Handle the SVNPath case. */
  fs_path = dav_svn__get_fs_path(r);

  if (fs_path != NULL)
    {
      *repos_path = fs_path;
      return NULL;
    }

  /* Handle the SVNParentPath case.  If neither directive was used,
     dav_svn_split_uri will throw a suitable error for us - we do
     not need to check that here. */
  fs_parent_path = dav_svn__get_fs_parent_path(r);

  /* Split the svn URI to get the name of the repository below
     the parent path. */
  derr = dav_svn_split_uri(r, r->uri, root_path,
                           &ignored_cleaned_uri, &ignored_had_slash,
                           &repos_name,
                           &ignored_relative, &ignored_path_in_repos);
  if (derr)
    return derr;

  /* Construct the full path from the parent path base directory
     and the repository name. */
  *repos_path = svn_path_join(fs_parent_path, repos_name, r->pool);
  return NULL;
}
Esempio n. 22
0
static svn_error_t *
svn_ra_local__get_deleted_rev(svn_ra_session_t *session,
                              const char *path,
                              svn_revnum_t peg_revision,
                              svn_revnum_t end_revision,
                              svn_revnum_t *revision_deleted,
                              apr_pool_t *pool)
{
  svn_ra_local__session_baton_t *sess = session->priv;
  const char *abs_path = svn_path_join(sess->fs_path->data, path, pool);

  SVN_ERR(svn_repos_deleted_rev(sess->fs,
                                abs_path,
                                peg_revision,
                                end_revision,
                                revision_deleted,
                                pool));

  return SVN_NO_ERROR;
}
Esempio n. 23
0
static svn_error_t *
test_open_file(const char *path,
               void *parent_baton,
               svn_revnum_t base_revision,
               apr_pool_t *file_pool,
               void **file_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct file_baton *fb = apr_pcalloc(file_pool, sizeof(*fb));
  svn_fs_root_t *rev_root = NULL;

  /* Fill in the file baton. */
  fb->path = svn_path_join(eb->root_path, path, eb->pool);
  fb->edit_baton = eb;

  SVN_ERR(svn_fs_revision_root(&rev_root, eb->fs, base_revision, file_pool));
  SVN_ERR(svn_fs_revision_link(rev_root, eb->txn_root, fb->path, file_pool));

  *file_baton = fb;
  return SVN_NO_ERROR;
}
Esempio n. 24
0
static svn_error_t *
test_open_directory(const char *path,
                    void *parent_baton,
                    svn_revnum_t base_revision,
                    apr_pool_t *dir_pool,
                    void **child_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct dir_baton *db = apr_pcalloc(dir_pool, sizeof(*db));
  svn_fs_root_t *rev_root = NULL;

  /* Construct the full path of the new directory */
  db->full_path = svn_path_join(eb->root_path, path, eb->pool);
  db->edit_baton = eb;

  SVN_ERR(svn_fs_revision_root(&rev_root, eb->fs, base_revision, dir_pool));
  SVN_ERR(svn_fs_revision_link(rev_root, eb->txn_root, db->full_path, 
                               dir_pool));

  *child_baton = db;
  return SVN_NO_ERROR;
}
Esempio n. 25
0
static void
find_real_base_location(const char **path_p,
                        svn_revnum_t *rev_p,
                        svn_repos_node_t *node,
                        apr_pool_t *pool)
{
  /* If NODE is an add-with-history, then its real base location is
     the copy source. */
  if ((node->action == 'A')
      && node->copyfrom_path
      && SVN_IS_VALID_REVNUM(node->copyfrom_rev))
    {
      *path_p = node->copyfrom_path;
      *rev_p = node->copyfrom_rev;
      return;
    }

  /* Otherwise, if NODE has a parent, we'll recurse, and add NODE's
     name to whatever the parent's real base path turns out to be (and
     pass the base revision on through). */
  if (node->parent)
    {
      const char *path;
      svn_revnum_t rev;

      find_real_base_location(&path, &rev, node->parent, pool);
      *path_p = svn_path_join(path, node->name, pool);
      *rev_p = rev;
      return;
    }

  /* Finally, if the node has no parent, then its name is "/", and it
     has no interesting base revision.  */
  *path_p = "/";
  *rev_p = SVN_INVALID_REVNUM;
  return;
}
Esempio n. 26
0
static svn_error_t *
test_add_file(const char *path,
              void *parent_baton,
              const char *copyfrom_path,
              svn_revnum_t copyfrom_revision,
              apr_pool_t *file_pool,
              void **file_baton)
{
  struct dir_baton *db = parent_baton;
  struct edit_baton *eb = db->edit_baton;
  struct file_baton *fb = apr_pcalloc(file_pool, sizeof(*fb));

  /* Fill in the file baton. */
  fb->path = svn_path_join(eb->root_path, path, eb->pool);
  fb->edit_baton = eb;

  if (copyfrom_path)  /* add with history */
    {
      svn_fs_root_t *rev_root = NULL;

      SVN_ERR(svn_fs_revision_root(&rev_root,
                                   eb->fs,
                                   copyfrom_revision,
                                   file_pool));

      SVN_ERR(svn_fs_copy(rev_root,
                          copyfrom_path,
                          eb->txn_root,
                          fb->path,
                          file_pool));
    }
  else  /* add without history */
    SVN_ERR(svn_fs_make_file(eb->txn_root, fb->path, file_pool));

  *file_baton = fb;
  return SVN_NO_ERROR;
}
Esempio n. 27
0
static svn_error_t *
test_add_directory(const char *path,
                   void *parent_baton,
                   const char *copyfrom_path,
                   svn_revnum_t copyfrom_revision,
                   apr_pool_t *dir_pool,
                   void **child_baton)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  struct dir_baton *db = apr_pcalloc(dir_pool, sizeof(*db));

  /* Construct the full path of the new directory */
  db->full_path = svn_path_join(eb->root_path, path, eb->pool);
  db->edit_baton = eb;

  if (copyfrom_path)  /* add with history */
    {
      svn_fs_root_t *rev_root = NULL;

      SVN_ERR(svn_fs_revision_root(&rev_root,
                                   eb->fs,
                                   copyfrom_revision,
                                   dir_pool));

      SVN_ERR(svn_fs_copy(rev_root,
                          copyfrom_path,
                          eb->txn_root,
                          db->full_path,
                          dir_pool));
    }
  else  /* add without history */
    SVN_ERR(svn_fs_make_dir(eb->txn_root, db->full_path, dir_pool));

  *child_baton = db;
  return SVN_NO_ERROR;
}
Esempio n. 28
0
/* Respond to a S:deleted-rev-report request. */
dav_error *
dav_svn__get_deleted_rev_report(const dav_resource *resource,
                                const apr_xml_doc *doc,
                                ap_filter_t *output)
{
  apr_xml_elem *child;
  int ns;
  const char *rel_path = NULL, *abs_path;
  svn_revnum_t peg_rev = SVN_INVALID_REVNUM, end_rev = SVN_INVALID_REVNUM,
      deleted_rev;
  apr_bucket_brigade *bb;
  svn_error_t *err;
  apr_status_t apr_err;
  dav_error *derr = NULL;

  /* Sanity check. */
  ns = dav_svn__find_ns(doc->namespaces, SVN_XML_NAMESPACE);
  if (ns == -1)
    return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0,
                                  "The request does not contain the 'svn:' "
                                  "namespace, so it is not going to have "
                                  "certain required elements.",
                                  SVN_DAV_ERROR_NAMESPACE,
                                  SVN_DAV_ERROR_TAG);

  for (child = doc->root->first_child; child != NULL; child = child->next)
    {
      /* If this element isn't one of ours, then skip it. */
      if (child->ns != ns )
        continue;

      if (strcmp(child->name, "peg-revision") == 0)
        {
          peg_rev = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                     resource->pool, 1));
        }
      else if (strcmp(child->name, "end-revision") == 0)
        {
          end_rev = SVN_STR_TO_REV(dav_xml_get_cdata(child,
                                                     resource->pool, 1));
        }
      else if (strcmp(child->name, "path") == 0)
        {
          rel_path = dav_xml_get_cdata(child, resource->pool, 0);
          if ((derr = dav_svn__test_canonical(rel_path, resource->pool)))
            return derr;
        }
    }

    /* Check that all parameters are present. */
  if (! (rel_path
         && SVN_IS_VALID_REVNUM(peg_rev)
         && SVN_IS_VALID_REVNUM(end_rev)))
    {
      return dav_svn__new_error_tag(resource->pool, HTTP_BAD_REQUEST, 0,
                                    "Not all parameters passed.",
                                    SVN_DAV_ERROR_NAMESPACE,
                                    SVN_DAV_ERROR_TAG);
    }

  /* Append the relative path to the base FS path to get an absolute
     repository path. */
  abs_path = svn_path_join(resource->info->repos_path, rel_path,
                           resource->pool);

  /* Do what we actually came here for: Find the rev abs_path was deleted. */
  err = svn_repos_deleted_rev(resource->info->repos->fs,
                              abs_path, peg_rev, end_rev,
                              &deleted_rev, resource->pool);
  if (err)
    {
      svn_error_clear(err);
      return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
                           "Could not find revision path was deleted.");
    }

  bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
  apr_err = ap_fprintf(output, bb,
                       DAV_XML_HEADER DEBUG_CR
                       "<S:get-deleted-rev-report xmlns:S=\""
                       SVN_XML_NAMESPACE "\" xmlns:D=\"DAV:\">" DEBUG_CR
                       "<D:" SVN_DAV__VERSION_NAME ">%ld</D:"
                       SVN_DAV__VERSION_NAME ">""</S:get-deleted-rev-report>",
                       deleted_rev);
  if (apr_err)
    derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
                                HTTP_INTERNAL_SERVER_ERROR,
                                "Error writing REPORT response.",
                                resource->pool);

  return dav_svn__final_flush_or_error(resource->info->r, bb, output,
                                       derr, resource->pool);
}
Esempio n. 29
0
svn_error_t *
svn_client_blame4(const char *target,
                  const svn_opt_revision_t *peg_revision,
                  const svn_opt_revision_t *start,
                  const svn_opt_revision_t *end,
                  const svn_diff_file_options_t *diff_options,
                  svn_boolean_t ignore_mime_type,
                  svn_boolean_t include_merged_revisions,
                  svn_client_blame_receiver2_t receiver,
                  void *receiver_baton,
                  svn_client_ctx_t *ctx,
                  apr_pool_t *pool)
{
  struct file_rev_baton frb;
  svn_ra_session_t *ra_session;
  const char *url;
  svn_revnum_t start_revnum, end_revnum;
  struct blame *walk, *walk_merged = NULL;
  apr_file_t *file;
  apr_pool_t *iterpool;
  svn_stream_t *stream;

  if (start->kind == svn_opt_revision_unspecified
      || end->kind == svn_opt_revision_unspecified)
    return svn_error_create
      (SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
  else if (start->kind == svn_opt_revision_working
           || end->kind == svn_opt_revision_working)
    return svn_error_create
      (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
       _("blame of the WORKING revision is not supported"));

  /* Get an RA plugin for this filesystem object. */
  SVN_ERR(svn_client__ra_session_from_path(&ra_session, &end_revnum,
                                           &url, target, NULL,
                                           peg_revision, end,
                                           ctx, pool));

  SVN_ERR(svn_client__get_revision_number(&start_revnum, NULL, ra_session,
                                          start, target, pool));

  if (end_revnum < start_revnum)
    return svn_error_create
      (SVN_ERR_CLIENT_BAD_REVISION, NULL,
       _("Start revision must precede end revision"));

  frb.start_rev = start_revnum;
  frb.end_rev = end_revnum;
  frb.target = target;
  frb.ctx = ctx;
  frb.diff_options = diff_options;
  frb.ignore_mime_type = ignore_mime_type;
  frb.include_merged_revisions = include_merged_revisions;
  frb.last_filename = NULL;
  frb.last_original_filename = NULL;
  frb.chain = apr_palloc(pool, sizeof(*frb.chain));
  frb.chain->blame = NULL;
  frb.chain->avail = NULL;
  frb.chain->pool = pool;
  if (include_merged_revisions)
    {
      frb.merged_chain = apr_palloc(pool, sizeof(*frb.merged_chain));
      frb.merged_chain->blame = NULL;
      frb.merged_chain->avail = NULL;
      frb.merged_chain->pool = pool;
    }

  SVN_ERR(svn_io_temp_dir(&frb.tmp_path, pool));
  frb.tmp_path = svn_path_join(frb.tmp_path, "tmp", pool),

  frb.mainpool = pool;
  /* The callback will flip the following two pools, because it needs
     information from the previous call.  Obviously, it can't rely on
     the lifetime of the pool provided by get_file_revs. */
  frb.lastpool = svn_pool_create(pool);
  frb.currpool = svn_pool_create(pool);
  if (include_merged_revisions)
    {
      frb.filepool = svn_pool_create(pool);
      frb.prevfilepool = svn_pool_create(pool);
    }

  /* Collect all blame information.
     We need to ensure that we get one revision before the start_rev,
     if available so that we can know what was actually changed in the start
     revision. */
  SVN_ERR(svn_ra_get_file_revs2(ra_session, "",
                                start_revnum - (start_revnum > 0 ? 1 : 0),
                                end_revnum, include_merged_revisions,
                                file_rev_handler, &frb, pool));

  /* Report the blame to the caller. */

  /* The callback has to have been called at least once. */
  assert(frb.last_filename != NULL);

  /* Create a pool for the iteration below. */
  iterpool = svn_pool_create(pool);

  /* Open the last file and get a stream. */
  SVN_ERR(svn_io_file_open(&file, frb.last_filename, APR_READ | APR_BUFFERED,
                           APR_OS_DEFAULT, pool));
  stream = svn_subst_stream_translated(svn_stream_from_aprfile(file, pool),
                                       "\n", TRUE, NULL, FALSE, pool);

  /* Perform optional merged chain normalization. */
  if (include_merged_revisions)
    {
      /* If we never created any blame for the original chain, create it now,
         with the most recent changed revision.  This could occur if a file
         was created on a branch and them merged to another branch.  This is
         semanticly a copy, and we want to use the revision on the branch as
         the most recently changed revision.  ### Is this really what we want
         to do here?  Do the sematics of copy change? */
      if (!frb.chain->blame)
        frb.chain->blame = blame_create(frb.chain, frb.rev, 0);

      normalize_blames(frb.chain, frb.merged_chain, pool);
      walk_merged = frb.merged_chain->blame;
    }

  /* Process each blame item. */
  for (walk = frb.chain->blame; walk; walk = walk->next)
    {
      apr_off_t line_no;
      svn_revnum_t merged_rev;
      const char *merged_author, *merged_date, *merged_path;

      if (walk_merged)
        {
          merged_rev = walk_merged->rev->revision;
          merged_author = walk_merged->rev->author;
          merged_date = walk_merged->rev->date;
          merged_path = walk_merged->rev->path;
        }
      else
        {
          merged_rev = SVN_INVALID_REVNUM;
          merged_author = NULL;
          merged_date = NULL;
          merged_path = NULL;
        }

      for (line_no = walk->start;
           !walk->next || line_no < walk->next->start;
           ++line_no)
        {
          svn_boolean_t eof;
          svn_stringbuf_t *sb;

          svn_pool_clear(iterpool);
          SVN_ERR(svn_stream_readline(stream, &sb, "\n", &eof, iterpool));
          if (ctx->cancel_func)
            SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
          if (!eof || sb->len)
            SVN_ERR(receiver(receiver_baton, line_no, walk->rev->revision,
                             walk->rev->author, walk->rev->date,
                             merged_rev, merged_author, merged_date,
                             merged_path, sb->data, iterpool));
          if (eof) break;
        }

      if (walk_merged)
        walk_merged = walk_merged->next;
    }

  SVN_ERR(svn_stream_close(stream));

  /* We don't need the temp file any more. */
  SVN_ERR(svn_io_file_close(file, pool));

  svn_pool_destroy(frb.lastpool);
  svn_pool_destroy(frb.currpool);
  if (include_merged_revisions)
    {
      svn_pool_destroy(frb.filepool);
      svn_pool_destroy(frb.prevfilepool);
    }
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}
Esempio n. 30
0
File: nls.c Progetto: vocho/openqnx
svn_error_t *
svn_nls_init(void)
{
    svn_error_t *err = SVN_NO_ERROR;

#ifdef ENABLE_NLS
#ifdef WIN32
    {
        WCHAR ucs2_path[MAX_PATH];
        char* utf8_path;
        const char* internal_path;
        apr_pool_t* pool;
        apr_status_t apr_err;
        apr_size_t inwords, outbytes, outlength;

        apr_pool_create(&pool, 0);
        /* get exe name - our locale info will be in '../share/locale' */
        inwords = GetModuleFileNameW(0, ucs2_path,
                                     sizeof(ucs2_path) / sizeof(ucs2_path[0]));
        if (! inwords)
        {
            /* We must be on a Win9x machine, so attempt to get an ANSI path,
               and convert it to Unicode. */
            CHAR ansi_path[MAX_PATH];

            if (GetModuleFileNameA(0, ansi_path, sizeof(ansi_path)))
            {
                inwords =
                    MultiByteToWideChar(CP_ACP, 0, ansi_path, -1, ucs2_path,
                                        sizeof(ucs2_path) / sizeof(ucs2_path[0]));
                if (! inwords) {
                    err =
                        svn_error_createf(APR_EINVAL, NULL,
                                          _("Can't convert string to UCS-2: '%s'"),
                                          ansi_path);
                }
            }
            else
            {
                err = svn_error_create(APR_EINVAL, NULL,
                                       _("Can't get module file name"));
            }
        }

        if (! err)
        {
            outbytes = outlength = 3 * (inwords + 1);
            utf8_path = apr_palloc(pool, outlength);
            apr_err = apr_conv_ucs2_to_utf8(ucs2_path, &inwords,
                                            utf8_path, &outbytes);
            if (!apr_err && (inwords > 0 || outbytes == 0))
                apr_err = APR_INCOMPLETE;
            if (apr_err)
            {
                err = svn_error_createf(apr_err, NULL,
                                        _("Can't convert module path "
                                          "to UTF-8 from UCS-2: '%s'"),
                                        ucs2_path);
            }
            else
            {
                utf8_path[outlength - outbytes] = '\0';
                internal_path = svn_path_internal_style(utf8_path, pool);
                /* get base path name */
                internal_path = svn_path_dirname(internal_path, pool);
                internal_path = svn_path_join(internal_path,
                                              SVN_LOCALE_RELATIVE_PATH,
                                              pool);
                bindtextdomain(PACKAGE_NAME, internal_path);
            }
        }
        svn_pool_destroy(pool);
    }
#else
    bindtextdomain(PACKAGE_NAME, SVN_LOCALE_DIR);
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
    bind_textdomain_codeset(PACKAGE_NAME, "UTF-8");
#endif
#endif
#endif

    return err;
}