2 * date_rev.c : RA get-dated-revision API implementation
4 * ====================================================================
5 * Copyright (c) 2000-2007 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
21 #define APR_WANT_STRFUNC
22 #include <apr_want.h> /* for strcmp() */
24 #include <apr_pools.h>
25 #include <apr_tables.h>
26 #include <apr_strings.h>
32 #include "svn_error.h"
33 #include "svn_pools.h"
35 #include "../libsvn_ra/ra_loader.h"
41 #include "private/svn_dav_protocol.h"
42 #include "svn_private_config.h"
47 /* -------------------------------------------------------------------------
49 ** DATED REV REPORT HANDLING
51 ** DeltaV provides no mechanism for mapping a date to a revision, so
52 ** we use a custom report, S:dated-rev-report. The request contains a
53 ** DAV:creationdate element giving the requested date; the response
54 ** contains a DAV:version-name element giving the most recent revision
57 ** Since this report is so simple, we don't bother with validation or
58 ** baton structures or anything; we just set the revision number in
59 ** the end-element handler for DAV:version-name.
62 /* Elements used in a dated-rev-report response */
63 static const svn_ra_neon__xml_elm_t drev_report_elements
[] =
65 { SVN_XML_NAMESPACE
, "dated-rev-report", ELEM_dated_rev_report
, 0 },
66 { "DAV:", "version-name", ELEM_version_name
, SVN_RA_NEON__XML_CDATA
},
72 svn_stringbuf_t
*cdata
;
74 svn_revnum_t revision
;
78 /* This implements the `svn_ra_neon__xml_startelm_cb' prototype. */
80 drev_start_element(int *elem
, void *baton
, int parent
,
81 const char *nspace
, const char *name
, const char **atts
)
83 const svn_ra_neon__xml_elm_t
*elm
=
84 svn_ra_neon__lookup_xml_elem(drev_report_elements
, nspace
, name
);
85 drev_baton_t
*b
= baton
;
87 *elem
= elm
? elm
->id
: SVN_RA_NEON__XML_DECLINE
;
91 if (elm
->id
== ELEM_version_name
)
92 b
->cdata
= svn_stringbuf_create("", b
->pool
);
97 /* This implements the `svn_ra_neon__xml_endelm_cb' prototype. */
99 drev_end_element(void *baton
, int state
,
100 const char *nspace
, const char *name
)
102 drev_baton_t
*b
= baton
;
104 if (state
== ELEM_version_name
&& b
->cdata
)
106 b
->revision
= SVN_STR_TO_REV(b
->cdata
->data
);
113 svn_error_t
*svn_ra_neon__get_dated_revision(svn_ra_session_t
*session
,
114 svn_revnum_t
*revision
,
115 apr_time_t timestamp
,
118 svn_ra_neon__session_t
*ras
= session
->priv
;
122 drev_baton_t
*b
= apr_palloc(pool
, sizeof(*b
));
126 b
->revision
= SVN_INVALID_REVNUM
;
128 /* Run the 'dated-rev-report' on the VCC url, which is always
129 guaranteed to exist. */
130 SVN_ERR(svn_ra_neon__get_vcc(&vcc_url
, ras
, ras
->root
.path
, pool
));
132 body
= apr_psprintf(pool
,
133 "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
134 "<S:dated-rev-report xmlns:S=\"" SVN_XML_NAMESPACE
"\" "
136 "<D:" SVN_DAV__CREATIONDATE
">%s</D:"
137 SVN_DAV__CREATIONDATE
"></S:dated-rev-report>",
138 svn_time_to_cstring(timestamp
, pool
));
140 err
= svn_ra_neon__parsed_request(ras
, "REPORT",
141 vcc_url
, body
, NULL
, NULL
,
143 svn_ra_neon__xml_collect_cdata
,
145 b
, NULL
, NULL
, FALSE
, pool
);
146 if (err
&& err
->apr_err
== SVN_ERR_UNSUPPORTED_FEATURE
)
147 return svn_error_quick_wrap(err
, _("Server does not support date-based "
152 if (b
->revision
== SVN_INVALID_REVNUM
)
153 return svn_error_create(SVN_ERR_INCOMPLETE_DATA
, NULL
,
154 _("Invalid server response to dated-rev request"));
156 *revision
= b
->revision
;