/* 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;
}
Example #2
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;
}
/* This implements the `svn_ra_neon__startelem_cb_t' prototype. */
static svn_error_t *
gloc_start_element(int *elem, void *userdata, int parent_state,
                   const char *ns, const char *ln, const char **atts)
{
  get_locations_baton_t *baton = userdata;
  const svn_ra_neon__xml_elm_t *elm;

  elm = svn_ra_neon__lookup_xml_elem(gloc_report_elements, ns, ln);

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

  if (parent_state == ELEM_get_locations_report
      && elm->id == ELEM_location)
    {
      svn_revnum_t rev = SVN_INVALID_REVNUM;
      const char *path;
      const char *r;

      r = svn_xml_get_attr_value("rev", atts);
      if (r)
        rev = SVN_STR_TO_REV(r);

      path = svn_xml_get_attr_value("path", atts);

      if (SVN_IS_VALID_REVNUM(rev) && path)
        apr_hash_set(baton->hash,
                     apr_pmemdup(baton->pool, &rev, sizeof(rev)),
                     sizeof(rev), apr_pstrdup(baton->pool, path));
      else
        return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                _("Expected a valid revnum and path"));
    }

  *elem = elm->id;

  return SVN_NO_ERROR;
}
Example #4
0
static svn_error_t *
start_element(svn_ra_serf__xml_parser_t *parser,
              svn_ra_serf__dav_props_t name,
              const char **attrs,
              apr_pool_t *scratch_pool)
{
  iprops_context_t *iprops_ctx = parser->user_data;
  iprops_state_e state;

  state = parser->state->current_state;
  if (state == NONE
      && strcmp(name.name, SVN_DAV__INHERITED_PROPS_REPORT) == 0)
    {
      svn_ra_serf__xml_push_state(parser, IPROPS_REPORT);
    }
  else if (state == IPROPS_REPORT &&
           strcmp(name.name, SVN_DAV__IPROP_ITEM) == 0)
    {
      svn_stringbuf_setempty(iprops_ctx->curr_path);
      svn_stringbuf_setempty(iprops_ctx->curr_propname);
      svn_stringbuf_setempty(iprops_ctx->curr_propval);
      iprops_ctx->curr_prop_val_encoding = NULL;
      iprops_ctx->curr_iprop = NULL;
      svn_ra_serf__xml_push_state(parser, IPROPS_ITEM);
    }
  else if (state == IPROPS_ITEM &&
           strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
    {
      const char *prop_val_encoding = svn_xml_get_attr_value("encoding",
                                                             attrs);
      iprops_ctx->curr_prop_val_encoding = apr_pstrdup(iprops_ctx->pool,
                                                       prop_val_encoding);
      svn_ra_serf__xml_push_state(parser, IPROPS_PROPVAL);
    }
  else if (state == IPROPS_ITEM &&
           strcmp(name.name, SVN_DAV__IPROP_PATH) == 0)
    {
      svn_ra_serf__xml_push_state(parser, IPROPS_PATH);
    }
  else if (state == IPROPS_ITEM &&
           strcmp(name.name, SVN_DAV__IPROP_PROPNAME) == 0)
    {
      svn_ra_serf__xml_push_state(parser, IPROPS_PROPNAME);
    }
  else if (state == IPROPS_ITEM &&
           strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
    {
      svn_ra_serf__xml_push_state(parser, IPROPS_PROPVAL);
    }

  return SVN_NO_ERROR;
}
static svn_error_t *
start_getloc(svn_ra_serf__xml_parser_t *parser,
             void *userData,
             svn_ra_serf__dav_props_t name,
             const char **attrs)
{
    loc_context_t *loc_ctx = userData;

    if (!loc_ctx->state && strcmp(name.name, "get-locations-report") == 0)
    {
        push_state(loc_ctx, REPORT);
    }
    else if (loc_ctx->state &&
             loc_ctx->state->state == REPORT &&
             strcmp(name.name, "location") == 0)
    {
        svn_revnum_t rev = SVN_INVALID_REVNUM;
        const char *revstr, *path;

        revstr = svn_xml_get_attr_value("rev", attrs);
        if (revstr)
        {
            rev = SVN_STR_TO_REV(revstr);
        }

        path = svn_xml_get_attr_value("path", attrs);

        if (SVN_IS_VALID_REVNUM(rev) && path)
        {
            apr_hash_set(loc_ctx->paths,
                         apr_pmemdup(loc_ctx->pool, &rev, sizeof(rev)),
                         sizeof(rev),
                         apr_pstrdup(loc_ctx->pool, path));
        }
    }

    return SVN_NO_ERROR;
}
/* This implements the `svn_ra_neon__startelm_cb_t' prototype. */
static svn_error_t *
getlocks_start_element(int *elem, void *userdata, int parent_state,
                       const char *ns, const char *ln, const char **atts)
{
  get_locks_baton_t *baton = userdata;
  const svn_ra_neon__xml_elm_t *elm;

  elm = svn_ra_neon__lookup_xml_elem(getlocks_report_elements, ns, ln);

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

  if (elm->id == ELEM_lock)
    {
      if (parent_state != ELEM_get_locks_report)
        return UNEXPECTED_ELEMENT(ns, ln);
      else
        /* allocate a new svn_lock_t in the permanent pool */
        baton->current_lock = svn_lock_create(baton->pool);
    }

  else if (elm->id == ELEM_lock_path
           || elm->id == ELEM_lock_token
           || elm->id == ELEM_lock_owner
           || elm->id == ELEM_lock_comment
           || elm->id == ELEM_lock_creationdate
           || elm->id == ELEM_lock_expirationdate)
    {
      const char *encoding;

      if (parent_state != ELEM_lock)
        return UNEXPECTED_ELEMENT(ns, ln);

      /* look for any incoming encodings on these elements. */
      encoding = svn_xml_get_attr_value("encoding", atts);
      if (encoding)
        baton->encoding = apr_pstrdup(baton->scratchpool, encoding);
    }

  *elem = elm->id;

  return SVN_NO_ERROR;
}
Example #7
0
File: log.c Project: vocho/openqnx
/*
 * This implements the `svn_ra_neon__xml_startelm_cb' prototype.
 */
static svn_error_t *
log_start_element(int *elem, void *baton, int parent,
                  const char *nspace, const char *name, const char **atts)
{
  const char *copyfrom_path, *copyfrom_revstr;
  svn_revnum_t copyfrom_rev;
  struct log_baton *lb = baton;
  static const svn_ra_neon__xml_elm_t log_report_elements[] =
    {
      { SVN_XML_NAMESPACE, "log-report", ELEM_log_report, 0 },
      { SVN_XML_NAMESPACE, "log-item", ELEM_log_item, 0 },
      { SVN_XML_NAMESPACE, "date", ELEM_log_date, SVN_RA_NEON__XML_CDATA },
      { SVN_XML_NAMESPACE, "added-path", ELEM_added_path,
        SVN_RA_NEON__XML_CDATA },
      { SVN_XML_NAMESPACE, "deleted-path", ELEM_deleted_path,
        SVN_RA_NEON__XML_CDATA },
      { SVN_XML_NAMESPACE, "modified-path", ELEM_modified_path,
        SVN_RA_NEON__XML_CDATA },
      { SVN_XML_NAMESPACE, "replaced-path", ELEM_replaced_path,
        SVN_RA_NEON__XML_CDATA },
      { SVN_XML_NAMESPACE, "revprop", ELEM_revprop,
        SVN_RA_NEON__XML_CDATA },
      { "DAV:", SVN_DAV__VERSION_NAME, ELEM_version_name,
        SVN_RA_NEON__XML_CDATA },
      { "DAV:", "creator-displayname", ELEM_creator_displayname,
        SVN_RA_NEON__XML_CDATA },
      { "DAV:", "comment", ELEM_comment, SVN_RA_NEON__XML_CDATA },
      { SVN_XML_NAMESPACE, "has-children", ELEM_has_children,
        SVN_RA_NEON__XML_CDATA },
      { NULL }
    };
  const svn_ra_neon__xml_elm_t *elm
    = svn_ra_neon__lookup_xml_elem(log_report_elements, nspace, name);

  *elem = elm ? elm->id : SVN_RA_NEON__XML_DECLINE;
  if (!elm)
    return SVN_NO_ERROR;

  switch (elm->id)
    {
    case ELEM_creator_displayname:
    case ELEM_log_date:
    case ELEM_version_name:
    case ELEM_added_path:
    case ELEM_replaced_path:
    case ELEM_deleted_path:
    case ELEM_modified_path:
    case ELEM_revprop:
    case ELEM_comment:
      lb->want_cdata = lb->cdata;
      svn_stringbuf_setempty(lb->cdata);
      if (elm->id == ELEM_revprop)
        {
          lb->revprop_name = apr_pstrdup(lb->subpool,
                                         svn_xml_get_attr_value("name",
                                                                atts));
          if (lb->revprop_name == NULL)
            return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                     _("Missing name attr in revprop element"));
        }
      break;
    case ELEM_has_children:
      lb->log_entry->has_children = TRUE;
      break;

    default:
      lb->want_cdata = NULL;
      break;
    }

  switch (elm->id)
    {
    case ELEM_added_path:
    case ELEM_replaced_path:
    case ELEM_deleted_path:
    case ELEM_modified_path:
      lb->this_path_item = apr_pcalloc(lb->subpool,
                                       sizeof(*(lb->this_path_item)));
      lb->this_path_item->copyfrom_rev = SVN_INVALID_REVNUM;

      /* See documentation for `svn_repos_node_t' in svn_repos.h,
         and `svn_log_changed_path_t' in svn_types.h, for more
         about these action codes. */
      if ((elm->id == ELEM_added_path) || (elm->id == ELEM_replaced_path))
        {
          lb->this_path_item->action
            = (elm->id == ELEM_added_path) ? 'A' : 'R';
          copyfrom_path = svn_xml_get_attr_value("copyfrom-path", atts);
          copyfrom_revstr = svn_xml_get_attr_value("copyfrom-rev", atts);
          if (copyfrom_path && copyfrom_revstr
              && (SVN_IS_VALID_REVNUM
                  (copyfrom_rev = SVN_STR_TO_REV(copyfrom_revstr))))
            {
              lb->this_path_item->copyfrom_path = apr_pstrdup(lb->subpool,
                                                              copyfrom_path);
              lb->this_path_item->copyfrom_rev = copyfrom_rev;
            }
        }
      else if (elm->id == ELEM_deleted_path)
        {
          lb->this_path_item->action = 'D';
        }
      else
        {
          lb->this_path_item->action = 'M';
        }
      break;

    default:
      lb->this_path_item = NULL;
      break;
    }
  return SVN_NO_ERROR;
}
static svn_error_t *
start_element(int *elem, void *baton, int parent_state, const char *nspace,
              const char *elt_name, const char **atts)
{
  replay_baton_t *rb = baton;

  const svn_ra_neon__xml_elm_t *elm
    = svn_ra_neon__lookup_xml_elem(editor_report_elements, nspace, elt_name);

  if (! elm)
    {
      *elem = NE_XML_DECLINE;
      return SVN_NO_ERROR;
    }

  if (parent_state == ELEM_root)
    {
      /* If we're at the root of the tree, the element has to be the editor
       * report itself. */
      if (elm->id != ELEM_editor_report)
        return UNEXPECTED_ELEMENT(nspace, elt_name);
    }
  else if (parent_state != ELEM_editor_report)
    {
      /* If we're not at the root, our parent has to be the editor report,
       * since we don't actually nest any elements. */
      return UNEXPECTED_ELEMENT(nspace, elt_name);
    }

  switch (elm->id)
    {
    case ELEM_target_revision:
      {
        const char *crev = svn_xml_get_attr_value("rev", atts);
        if (! crev)
          return MISSING_ATTR(nspace, elt_name, "rev");
        else
          return rb->editor->set_target_revision(rb->edit_baton,
                                                 SVN_STR_TO_REV(crev),
                                                 rb->pool);
      }
      break;

    case ELEM_open_root:
      {
        const char *crev = svn_xml_get_attr_value("rev", atts);

        if (! crev)
          return MISSING_ATTR(nspace, elt_name, "rev");
        else
          {
            apr_pool_t *subpool = svn_pool_create(rb->pool);
            void *dir_baton;
            SVN_ERR(rb->editor->open_root(rb->edit_baton,
                                          SVN_STR_TO_REV(crev), subpool,
                                          &dir_baton));
            push_dir(rb, dir_baton, "", subpool);
          }
      }
      break;

    case ELEM_delete_entry:
      {
        const char *path = svn_xml_get_attr_value("name", atts);
        const char *crev = svn_xml_get_attr_value("rev", atts);

        if (! path)
          return MISSING_ATTR(nspace, elt_name, "name");
        else if (! crev)
          return MISSING_ATTR(nspace, elt_name, "rev");
        else
          {
            dir_item_t *di = &TOP_DIR(rb);

            SVN_ERR(rb->editor->delete_entry(path, SVN_STR_TO_REV(crev),
                                             di->baton, di->pool));
          }
      }
      break;

    case ELEM_open_directory:
    case ELEM_add_directory:
      {
        const char *crev = svn_xml_get_attr_value("rev", atts);
        const char *name = svn_xml_get_attr_value("name", atts);

        if (! name)
          return MISSING_ATTR(nspace, elt_name, "name");
        else
          {
            dir_item_t *parent = &TOP_DIR(rb);
            apr_pool_t *subpool = svn_pool_create(parent->pool);
            svn_revnum_t rev;
            void *dir_baton;

            if (crev)
              rev = SVN_STR_TO_REV(crev);
            else
              rev = SVN_INVALID_REVNUM;

            if (elm->id == ELEM_open_directory)
              SVN_ERR(rb->editor->open_directory(name, parent->baton,
                                                 rev, subpool, &dir_baton));
            else if (elm->id == ELEM_add_directory)
              {
                const char *cpath = svn_xml_get_attr_value("copyfrom-path",
                                                           atts);

                crev = svn_xml_get_attr_value("copyfrom-rev", atts);

                if (crev)
                  rev = SVN_STR_TO_REV(crev);
                else
                  rev = SVN_INVALID_REVNUM;

                SVN_ERR(rb->editor->add_directory(name, parent->baton,
                                                  cpath, rev, subpool,
                                                  &dir_baton));
              }
            else
              SVN_ERR_MALFUNCTION();

            push_dir(rb, dir_baton, name, subpool);
          }
      }
      break;

    case ELEM_open_file:
    case ELEM_add_file:
      {
        const char *path = svn_xml_get_attr_value("name", atts);
        svn_revnum_t rev;

        dir_item_t *parent = &TOP_DIR(rb);

        if (! path)
          return MISSING_ATTR(nspace, elt_name, "name");

        svn_pool_clear(parent->file_pool);

        if (elm->id == ELEM_add_file)
          {
            const char *cpath = svn_xml_get_attr_value("copyfrom-path", atts);
            const char *crev = svn_xml_get_attr_value("copyfrom-rev", atts);

            if (crev)
              rev = SVN_STR_TO_REV(crev);
            else
              rev = SVN_INVALID_REVNUM;

            SVN_ERR(rb->editor->add_file(path, parent->baton, cpath, rev,
                                         parent->file_pool, &rb->file_baton));
          }
        else
          {
            const char *crev = svn_xml_get_attr_value("rev", atts);

            if (crev)
              rev = SVN_STR_TO_REV(crev);
            else
              rev = SVN_INVALID_REVNUM;

            SVN_ERR(rb->editor->open_file(path, parent->baton, rev,
                                          parent->file_pool,
                                          &rb->file_baton));
          }
      }
      break;

    case ELEM_apply_textdelta:
      if (! rb->file_baton)
        return svn_error_create
                 (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                  _("Got apply-textdelta element without preceding "
                    "add-file or open-file"));
      else
        {
          const char *checksum = svn_xml_get_attr_value("checksum", atts);

          SVN_ERR(rb->editor->apply_textdelta(rb->file_baton,
                                              checksum,
                                              TOP_DIR(rb).file_pool,
                                              &rb->whandler,
                                              &rb->whandler_baton));

          rb->svndiff_decoder = svn_txdelta_parse_svndiff
                                  (rb->whandler, rb->whandler_baton,
                                   TRUE, TOP_DIR(rb).file_pool);
          rb->base64_decoder = svn_base64_decode(rb->svndiff_decoder,
                                                 TOP_DIR(rb).file_pool);
        }
      break;

    case ELEM_close_file:
      if (! rb->file_baton)
        return svn_error_create
                  (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                   _("Got close-file element without preceding "
                     "add-file or open-file"));
      else
        {
          const char *checksum = svn_xml_get_attr_value("checksum", atts);

          SVN_ERR(rb->editor->close_file(rb->file_baton,
                                         checksum,
                                         TOP_DIR(rb).file_pool));
          rb->file_baton = NULL;
        }
      break;

    case ELEM_close_directory:
      if (rb->dirs->nelts == 0)
        return svn_error_create
                 (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                  _("Got close-directory element without ever opening "
                    "a directory"));
      else
        {
          dir_item_t *di = &TOP_DIR(rb);

          SVN_ERR(rb->editor->close_directory(di->baton, di->pool));

          svn_pool_destroy(di->pool);

          apr_array_pop(rb->dirs);
        }
      break;

    case ELEM_change_file_prop:
    case ELEM_change_dir_prop:
      {
        const char *name = svn_xml_get_attr_value("name", atts);

        if (! name)
          return MISSING_ATTR(nspace, elt_name, "name");
        else
          {
            svn_pool_clear(rb->prop_pool);

            if (svn_xml_get_attr_value("del", atts))
              rb->prop_accum = NULL;
            else
              rb->prop_accum = svn_stringbuf_create("", rb->prop_pool);

            rb->prop_name = apr_pstrdup(rb->prop_pool, name);
          }
      }
      break;
    }

  *elem = elm->id;

  return SVN_NO_ERROR;
}
Example #9
0
static int
start_err_element(void *baton, int parent,
                  const char *nspace, const char *name, const char **atts)
{
  const svn_ra_neon__xml_elm_t *elm
    = svn_ra_neon__lookup_xml_elem(error_elements, nspace, name);
  int acc = elm
    ? validate_error_elements(parent, elm->id) : SVN_RA_NEON__XML_DECLINE;
  error_parser_baton_t *b = baton;
  svn_error_t **err = &(b->tmp_err);

  if (acc < 1) /* ! > 0 */
    return acc;

  switch (elm->id)
    {
    case ELEM_svn_error:
      {
        /* allocate the svn_error_t.  Hopefully the value will be
           overwritten by the <human-readable> tag, or even someday by
           a <D:failed-precondition/> tag. */
        *err = svn_error_create(APR_EGENERAL, NULL,
                                _("General svn error from server"));
        break;
      }
    case ELEM_human_readable:
      {
        /* get the errorcode attribute if present */
        const char *errcode_str =
          svn_xml_get_attr_value("errcode", /* ### make constant in
                                               some mod_dav header? */
                                 atts);

        if (errcode_str && *err)
          {
            apr_int64_t val;
            svn_error_t *err2;

            err2 = svn_cstring_atoi64(&val, errcode_str);
            if (err2)
              {
                svn_error_clear(err2);
                break;
              }
            (*err)->apr_err = (apr_status_t)val;
          }

        break;
      }

    default:
      break;
    }

  switch (elm->id)
    {
    case ELEM_human_readable:
      b->want_cdata = b->cdata;
      svn_stringbuf_setempty(b->want_cdata);
      break;

    default:
      b->want_cdata = NULL;
      break;
    }

  return elm->id;
}