Exemple #1
0
/* Implements the #merge_dir_config method of Apache's #module vtable. */
static void *
merge_dir_config(apr_pool_t *p, void *base, void *overrides)
{
  dir_conf_t *parent = base;
  dir_conf_t *child = overrides;
  dir_conf_t *newconf;

  newconf = apr_pcalloc(p, sizeof(*newconf));

  newconf->fs_path = INHERIT_VALUE(parent, child, fs_path);
  newconf->master_uri = INHERIT_VALUE(parent, child, master_uri);
  newconf->activities_db = INHERIT_VALUE(parent, child, activities_db);
  newconf->repo_name = INHERIT_VALUE(parent, child, repo_name);
  newconf->xslt_uri = INHERIT_VALUE(parent, child, xslt_uri);
  newconf->fs_parent_path = INHERIT_VALUE(parent, child, fs_parent_path);
  newconf->autoversioning = INHERIT_VALUE(parent, child, autoversioning);
  newconf->bulk_updates = INHERIT_VALUE(parent, child, bulk_updates);
  newconf->v2_protocol = INHERIT_VALUE(parent, child, v2_protocol);
  newconf->path_authz_method = INHERIT_VALUE(parent, child, path_authz_method);
  newconf->list_parentpath = INHERIT_VALUE(parent, child, list_parentpath);
  newconf->txdelta_cache = INHERIT_VALUE(parent, child, txdelta_cache);
  newconf->fulltext_cache = INHERIT_VALUE(parent, child, fulltext_cache);
  newconf->root_dir = INHERIT_VALUE(parent, child, root_dir);

  if (parent->fs_path)
    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
                 "mod_dav_svn: nested Location '%s' hinders access to '%s' "
                 "in SVNPath Location '%s'",
                 child->root_dir,
                 svn_fspath__skip_ancestor(parent->root_dir, child->root_dir),
                 parent->root_dir);

  return newconf;
}
Exemple #2
0
svn_error_t *
svn_fs_bdb__changes_fetch(apr_hash_t **changes_p,
                          svn_fs_t *fs,
                          const char *key,
                          trail_t *trail,
                          apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  DBC *cursor;
  DBT query, result;
  int db_err = 0, db_c_err = 0;
  svn_error_t *err = SVN_NO_ERROR;
  apr_hash_t *changes = apr_hash_make(pool);
  apr_pool_t *subpool = svn_pool_create(pool);

  /* Get a cursor on the first record matching KEY, and then loop over
     the records, adding them to the return array. */
  svn_fs_base__trail_debug(trail, "changes", "cursor");
  SVN_ERR(BDB_WRAP(fs, N_("creating cursor for reading changes"),
                   bfd->changes->cursor(bfd->changes, trail->db_txn,
                                        &cursor, 0)));

  /* Advance the cursor to the key that we're looking for. */
  svn_fs_base__str_to_dbt(&query, key);
  svn_fs_base__result_dbt(&result);
  db_err = svn_bdb_dbc_get(cursor, &query, &result, DB_SET);
  if (! db_err)
    svn_fs_base__track_dbt(&result, pool);

  while (! db_err)
    {
      change_t *change;
      svn_skel_t *result_skel;

      /* Clear the per-iteration subpool. */
      svn_pool_clear(subpool);

      /* RESULT now contains a change record associated with KEY.  We
         need to parse that skel into an change_t structure ...  */
      result_skel = svn_skel__parse(result.data, result.size, subpool);
      if (! result_skel)
        {
          err = svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                                  _("Error reading changes for key '%s'"),
                                  key);
          goto cleanup;
        }
      err = svn_fs_base__parse_change_skel(&change, result_skel, subpool);
      if (err)
        goto cleanup;

      /* ... and merge it with our return hash.  */
      err = fold_change(changes, change);
      if (err)
        goto cleanup;

      /* Now, if our change was a deletion or replacement, we have to
         blow away any changes thus far on paths that are (or, were)
         children of this path.
         ### i won't bother with another iteration pool here -- at
             most we talking about a few extra dups of paths into what
             is already a temporary subpool.
      */
      if ((change->kind == svn_fs_path_change_delete)
          || (change->kind == svn_fs_path_change_replace))
        {
          apr_hash_index_t *hi;

          for (hi = apr_hash_first(subpool, changes);
               hi;
               hi = apr_hash_next(hi))
            {
              /* KEY is the path. */
              const void *hashkey;
              apr_ssize_t klen;
              const char *child_relpath;

              apr_hash_this(hi, &hashkey, &klen, NULL);

              /* If we come across our own path, ignore it.
                 If we come across a child of our path, remove it. */
              child_relpath = svn_fspath__skip_ancestor(change->path, hashkey);
              if (child_relpath && *child_relpath)
                apr_hash_set(changes, hashkey, klen, NULL);
            }
        }

      /* Advance the cursor to the next record with this same KEY, and
         fetch that record. */
      svn_fs_base__result_dbt(&result);
      db_err = svn_bdb_dbc_get(cursor, &query, &result, DB_NEXT_DUP);
      if (! db_err)
        svn_fs_base__track_dbt(&result, pool);
    }

  /* Destroy the per-iteration subpool. */
  svn_pool_destroy(subpool);

  /* If there are no (more) change records for this KEY, we're
     finished.  Just return the (possibly empty) array.  Any other
     error, however, needs to get handled appropriately.  */
  if (db_err && (db_err != DB_NOTFOUND))
    err = BDB_WRAP(fs, N_("fetching changes"), db_err);

 cleanup:
  /* Close the cursor. */
  db_c_err = svn_bdb_dbc_close(cursor);

  /* If we had an error prior to closing the cursor, return the error. */
  if (err)
    return svn_error_trace(err);

  /* If our only error thus far was when we closed the cursor, return
     that error. */
  if (db_c_err)
    SVN_ERR(BDB_WRAP(fs, N_("closing changes cursor"), db_c_err));

  /* Finally, set our return variable and get outta here. */
  *changes_p = changes;
  return SVN_NO_ERROR;
}
Exemple #3
0
/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
getlocks_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)
{
  lock_context_t *lock_ctx = baton;

  if (leaving_state == LOCK)
    {
      const char *path = svn_hash_gets(attrs, "path");
      svn_boolean_t save_lock = FALSE;

      /* Filter out unwanted paths.  Since Subversion only allows
         locks on files, we can treat depth=immediates the same as
         depth=files for filtering purposes.  Meaning, we'll keep
         this lock if:

         a) its path is the very path we queried, or
         b) we've asked for a fully recursive answer, or
         c) we've asked for depth=files or depth=immediates, and this
            lock is on an immediate child of our query path.
      */
      if (strcmp(lock_ctx->path, path) == 0
          || lock_ctx->requested_depth == svn_depth_infinity)
        {
          save_lock = TRUE;
        }
      else if (lock_ctx->requested_depth == svn_depth_files
               || lock_ctx->requested_depth == svn_depth_immediates)
        {
          const char *relpath = svn_fspath__skip_ancestor(lock_ctx->path,
                                                          path);
          if (relpath && (svn_path_component_count(relpath) == 1))
            save_lock = TRUE;
        }

      if (save_lock)
        {
          /* We get to put the structure on the stack rather than using
             svn_lock_create(). Bwahahaha....   */
          svn_lock_t lock = { 0 };
          const char *date;
          svn_lock_t *result_lock;

          /* Note: these "attributes" came from child elements. Some of
             them may have not been sent, so the value will be NULL.  */

          lock.path = path;
          lock.token = svn_hash_gets(attrs, "token");
          lock.owner = svn_hash_gets(attrs, "owner");
          lock.comment = svn_hash_gets(attrs, "comment");

          date = svn_hash_gets(attrs, SVN_DAV__CREATIONDATE);
          if (date)
            SVN_ERR(svn_time_from_cstring(&lock.creation_date, date,
                                          scratch_pool));

          date = svn_hash_gets(attrs, "expirationdate");
          if (date)
            SVN_ERR(svn_time_from_cstring(&lock.expiration_date, date,
                                          scratch_pool));

          result_lock = svn_lock_dup(&lock, lock_ctx->pool);
          svn_hash_sets(lock_ctx->hash, result_lock->path, result_lock);
        }
    }
  else
    {
      const char *name;

      SVN_ERR_ASSERT(cdata != NULL);

      if (leaving_state == PATH)
        name = "path";
      else if (leaving_state == TOKEN)
        name = "token";
      else if (leaving_state == OWNER)
        name = "owner";
      else if (leaving_state == COMMENT)
        name = "comment";
      else if (leaving_state == CREATION_DATE)
        name = SVN_DAV__CREATIONDATE;
      else if (leaving_state == EXPIRATION_DATE)
        name = "expirationdate";
      else
        SVN_ERR_MALFUNCTION();

      /* Store the lock information onto the LOCK elemstate.  */
      svn_ra_serf__xml_note(xes, LOCK, name, cdata->data);
    }

  return SVN_NO_ERROR;
}