예제 #1
0
svn_error_t*
CommitEditor::provide_props_cb(apr_hash_t **props,
                               svn_revnum_t *revision,
                               void *baton,
                               const char *repos_relpath,
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
{
  CommitEditor* editor = static_cast<CommitEditor*>(baton);
  if (editor->m_get_props_cb.get())
    {
      const Java::Env env;
      SVN_JAVAHL_CATCH(env, SVN_ERR_BASE,
                       invoke_get_props_cb(props, revision, env,
                                           editor->m_get_props_cb.get(),
                                           repos_relpath,
                                           result_pool));
    }
  else
    {
      SVN_ERR(open_callback_session(editor->m_callback_session,
                                    editor->m_callback_session_url,
                                    editor->m_callback_session_uuid,
                                    editor->m_session->m_context,
                                    editor->pool));

      svn_node_kind_t kind = svn_node_unknown;
      SVN_ERR(svn_ra_check_path(editor->m_callback_session,
                                repos_relpath, SVN_INVALID_REVNUM, &kind,
                                scratch_pool));

      // FIXME: Getting properties from the youngest revision is in
      // fact not such a bright idea, as the path may have been moved
      // or deleted in the repository. On the other hand, if that
      // happens, the commit would fail due to a conflict anyway.
      if (kind == svn_node_file)
        return svn_ra_get_file(editor->m_callback_session,
                               repos_relpath, SVN_INVALID_REVNUM,
                               NULL, revision, props, scratch_pool);
      else if (kind == svn_node_dir)
        return svn_ra_get_dir2(editor->m_callback_session, NULL, revision,
                               props, repos_relpath, SVN_INVALID_REVNUM, 0,
                               scratch_pool);
      else
        return svn_error_createf(
            SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
            _("Expected node kind '%s' or '%s' but got '%s'"),
            svn_node_kind_to_word(svn_node_file),
            svn_node_kind_to_word(svn_node_dir),
            svn_node_kind_to_word(kind));
    }
  return SVN_NO_ERROR;
}
예제 #2
0
파일: log.c 프로젝트: mishin/Alien-SVN
/* This implements `svn_log_entry_receiver_t'.
   BATON is a `struct log_receiver_baton *'.  */
static svn_error_t *
log_receiver(void *baton,
             svn_log_entry_t *log_entry,
             apr_pool_t *pool)
{
  struct log_receiver_baton *lrb = baton;
  apr_pool_t *iterpool = svn_pool_create(pool);

  SVN_ERR(maybe_send_header(lrb));

  if (log_entry->revision == SVN_INVALID_REVNUM)
    {
      /* If the stack depth is zero, we've seen the last revision, so don't
         send it, just return.  The footer will be sent later. */
      if (lrb->stack_depth == 0)
        return SVN_NO_ERROR;
      else
        lrb->stack_depth--;
    }

  SVN_ERR(dav_svn__brigade_printf(lrb->bb, lrb->output,
                                  "<S:log-item>" DEBUG_CR "<D:version-name>%ld"
                                  "</D:version-name>" DEBUG_CR,
                                  log_entry->revision));

  if (log_entry->revprops)
    {
      apr_hash_index_t *hi;
      for (hi = apr_hash_first(pool, log_entry->revprops);
           hi != NULL;
           hi = apr_hash_next(hi))
        {
          char *name;
          void *val;
          const svn_string_t *value;
          const char *encoding_str = "";

          svn_pool_clear(iterpool);
          apr_hash_this(hi, (void *)&name, NULL, &val);
          value = val;

          /* If the client is okay with us encoding binary (or really,
             any non-XML-safe) property values, do so as necessary. */
          if (lrb->encode_binary_props)
            {
              if (! svn_xml_is_xml_safe(value->data, value->len))
                {
                  value = svn_base64_encode_string2(value, TRUE, iterpool);
                  encoding_str = " encoding=\"base64\"";
                }
            }

          if (strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<D:creator-displayname%s>%s</D:creator-displayname>"
                     DEBUG_CR, encoding_str,
                     apr_xml_quote_string(iterpool, value->data, 0)));
          else if (strcmp(name, SVN_PROP_REVISION_DATE) == 0)
            /* ### this should be DAV:creation-date, but we need to format
               ### that date a bit differently */
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<S:date%s>%s</S:date>" DEBUG_CR, encoding_str,
                     apr_xml_quote_string(iterpool, value->data, 0)));
          else if (strcmp(name, SVN_PROP_REVISION_LOG) == 0)
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<D:comment%s>%s</D:comment>" DEBUG_CR, encoding_str,
                     apr_xml_quote_string(pool,
                                          svn_xml_fuzzy_escape(value->data,
                                                               iterpool), 0)));
          else
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<S:revprop name=\"%s\"%s>%s</S:revprop>" DEBUG_CR,
                     apr_xml_quote_string(iterpool, name, 0), encoding_str,
                     apr_xml_quote_string(iterpool, value->data, 0)));
        }
    }

  if (log_entry->has_children)
    {
      SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output, "<S:has-children/>"));
      lrb->stack_depth++;
    }

  if (log_entry->subtractive_merge)
    SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                  "<S:subtractive-merge/>"));

  if (log_entry->changed_paths2)
    {
      apr_hash_index_t *hi;
      char *path;

      for (hi = apr_hash_first(pool, log_entry->changed_paths2);
           hi != NULL;
           hi = apr_hash_next(hi))
        {
          void *val;
          svn_log_changed_path2_t *log_item;
          const char *close_element = NULL;

          svn_pool_clear(iterpool);
          apr_hash_this(hi, (void *) &path, NULL, &val);
          log_item = val;

          /* ### todo: is there a D: namespace equivalent for
             `changed-path'?  Should use it if so. */
          switch (log_item->action)
            {
            case 'A':
              if (log_item->copyfrom_path
                  && SVN_IS_VALID_REVNUM(log_item->copyfrom_rev))
                SVN_ERR(dav_svn__brigade_printf
                        (lrb->bb, lrb->output,
                         "<S:added-path copyfrom-path=\"%s\""
                         " copyfrom-rev=\"%ld\"",
                         apr_xml_quote_string(iterpool,
                                              log_item->copyfrom_path,
                                              1), /* escape quotes */
                         log_item->copyfrom_rev));
              else
                SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                              "<S:added-path"));

              close_element = "S:added-path";
              break;

            case 'R':
              if (log_item->copyfrom_path
                  && SVN_IS_VALID_REVNUM(log_item->copyfrom_rev))
                SVN_ERR(dav_svn__brigade_printf
                        (lrb->bb, lrb->output,
                         "<S:replaced-path copyfrom-path=\"%s\""
                         " copyfrom-rev=\"%ld\"",
                         apr_xml_quote_string(iterpool,
                                              log_item->copyfrom_path,
                                              1), /* escape quotes */
                         log_item->copyfrom_rev));
              else
                SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                              "<S:replaced-path"));

              close_element = "S:replaced-path";
              break;

            case 'D':
              SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                            "<S:deleted-path"));
              close_element = "S:deleted-path";
              break;

            case 'M':
              SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                            "<S:modified-path"));
              close_element = "S:modified-path";
              break;

            default:
              break;
            }

          /* If we need to close the element, then send the attributes
             that apply to all changed items and then close the element. */
          if (close_element)
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     " node-kind=\"%s\""
                     " text-mods=\"%s\""
                     " prop-mods=\"%s\">%s</%s>" DEBUG_CR,
                     svn_node_kind_to_word(log_item->node_kind),
                     svn_tristate__to_word(log_item->text_modified),
                     svn_tristate__to_word(log_item->props_modified),
                     apr_xml_quote_string(iterpool, path, 0),
                     close_element));
        }
    }

  svn_pool_destroy(iterpool);

  SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                "</S:log-item>" DEBUG_CR));

  return SVN_NO_ERROR;
}
예제 #3
0
파일: log.c 프로젝트: gunjanms/svnmigration
/* This implements `svn_log_entry_receiver_t'.
   BATON is a `struct log_receiver_baton *'.  */
static svn_error_t *
log_receiver(void *baton,
             svn_log_entry_t *log_entry,
             apr_pool_t *pool)
{
  struct log_receiver_baton *lrb = baton;
  apr_pool_t *iterpool = svn_pool_create(pool);

  SVN_ERR(maybe_send_header(lrb));

  if (log_entry->revision == SVN_INVALID_REVNUM)
    {
      /* If the stack depth is zero, we've seen the last revision, so don't
         send it, just return.  The footer will be sent later. */
      if (lrb->stack_depth == 0)
        return SVN_NO_ERROR;
      else
        lrb->stack_depth--;
    }

  SVN_ERR(dav_svn__brigade_printf(lrb->bb, lrb->output,
                                  "<S:log-item>" DEBUG_CR "<D:version-name>%ld"
                                  "</D:version-name>" DEBUG_CR,
                                  log_entry->revision));

  if (log_entry->revprops)
    {
      apr_hash_index_t *hi;
      for (hi = apr_hash_first(pool, log_entry->revprops);
           hi != NULL;
           hi = apr_hash_next(hi))
        {
          char *name;
          void *val;
          const svn_string_t *value;
          const char *encoding_str = "";

          svn_pool_clear(iterpool);
          apr_hash_this(hi, (void *)&name, NULL, &val);
          value = val;

          /* If the client is okay with us encoding binary (or really,
             any non-XML-safe) property values, do so as necessary. */
          if (lrb->encode_binary_props)
            {
              if (! svn_xml_is_xml_safe(value->data, value->len))
                {
                  value = svn_base64_encode_string2(value, TRUE, iterpool);
                  encoding_str = " encoding=\"base64\"";
                }
            }

          if (strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<D:creator-displayname%s>%s</D:creator-displayname>"
                     DEBUG_CR, encoding_str,
                     apr_xml_quote_string(iterpool, value->data, 0)));
          else if (strcmp(name, SVN_PROP_REVISION_DATE) == 0)
            /* ### this should be DAV:creation-date, but we need to format
               ### that date a bit differently */
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<S:date%s>%s</S:date>" DEBUG_CR, encoding_str,
                     apr_xml_quote_string(iterpool, value->data, 0)));
          else if (strcmp(name, SVN_PROP_REVISION_LOG) == 0)
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<D:comment%s>%s</D:comment>" DEBUG_CR, encoding_str,
                     apr_xml_quote_string(pool,
                                          svn_xml_fuzzy_escape(value->data,
                                                               iterpool), 0)));
          else
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     "<S:revprop name=\"%s\"%s>%s</S:revprop>" DEBUG_CR,
                     apr_xml_quote_string(iterpool, name, 0), encoding_str,
                     apr_xml_quote_string(iterpool, value->data, 0)));
        }
    }

  if (log_entry->has_children)
    {
      SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output, "<S:has-children/>"));
      lrb->stack_depth++;
    }

  if (log_entry->subtractive_merge)
    SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                  "<S:subtractive-merge/>"));

  if (log_entry->changed_paths2)
    {
      apr_hash_index_t *hi;
      char *path;

      for (hi = apr_hash_first(pool, log_entry->changed_paths2);
           hi != NULL;
           hi = apr_hash_next(hi))
        {
          void *val;
          svn_log_changed_path2_t *log_item;
          const char *close_element = NULL;

          svn_pool_clear(iterpool);
          apr_hash_this(hi, (void *) &path, NULL, &val);
          log_item = val;

          /* ### todo: is there a D: namespace equivalent for
             `changed-path'?  Should use it if so. */
          switch (log_item->action)
            {
            case 'A':
            case 'R':
              SVN_ERR(start_path_with_copy_from(&close_element, lrb,
                                                log_item, iterpool));
              break;

            case 'D':
              SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                            "<S:deleted-path"));
              close_element = "S:deleted-path";
              break;

            case 'M':
              SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                            "<S:modified-path"));
              close_element = "S:modified-path";
              break;

            default:
              break;
            }

          /* If we need to close the element, then send the attributes
             that apply to all changed items and then close the element. */
          if (close_element)
            SVN_ERR(dav_svn__brigade_printf
                    (lrb->bb, lrb->output,
                     " node-kind=\"%s\""
                     " text-mods=\"%s\""
                     " prop-mods=\"%s\">%s</%s>" DEBUG_CR,
                     svn_node_kind_to_word(log_item->node_kind),
                     svn_tristate__to_word(log_item->text_modified),
                     svn_tristate__to_word(log_item->props_modified),
                     apr_xml_quote_string(iterpool, path, 0),
                     close_element));
        }
    }

  svn_pool_destroy(iterpool);

  SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
                                "</S:log-item>" DEBUG_CR));

  /* In general APR will flush the brigade every 8000 bytes through the filter
     stack, but log items may not be generated that fast, especially in
     combination with authz and busy servers. We now explictly flush after
     log-item 4, 16, 64 and 256 to produce a few results fast.

     This introduces 4 full flushes of our brigade and the installed output
     filters at growing intervals and then falls back to the standard
     buffering of 8000 bytes + whatever buffers are added in output filters. */
  lrb->result_count++;
  if (lrb->result_count == lrb->next_forced_flush)
    {
      apr_status_t apr_err;

      /* This flush is similar to that in dav_svn__final_flush_or_error().

         Compared to using ap_filter_flush(), which we use in other place
         this adds a flush frame before flushing the brigade, to make output
         filters perform a flush as well */

      /* No brigade empty check. We want output filters to flush anyway */
      apr_err = ap_fflush(lrb->output, lrb->bb);
      if (apr_err)
        return svn_error_create(apr_err, NULL, NULL);

      /* Check for an aborted connection, just like our brigade write
         helper functions, since the brigade functions don't appear to
         be return useful errors when the connection is dropped. */
      if (lrb->output->c->aborted)
        return svn_error_create(SVN_ERR_APMOD_CONNECTION_ABORTED,
                                NULL, NULL);

      if (lrb->result_count < 256)
        lrb->next_forced_flush = lrb->next_forced_flush * 4;
    }

  return SVN_NO_ERROR;
}