/*** From logs.c ***/ svn_error_t * svn_repos_get_logs3(svn_repos_t *repos, 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_repos_authz_func_t authz_read_func, void *authz_read_baton, svn_log_message_receiver_t receiver, void *receiver_baton, apr_pool_t *pool) { svn_log_entry_receiver_t receiver2; void *receiver2_baton; svn_compat_wrap_log_receiver(&receiver2, &receiver2_baton, receiver, receiver_baton, pool); return svn_repos_get_logs4(repos, paths, start, end, limit, discover_changed_paths, strict_node_history, FALSE, svn_compat_log_revprops_in(pool), authz_read_func, authz_read_baton, receiver2, receiver2_baton, pool); }
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); }
dav_error * dav_svn__log_report(const dav_resource *resource, const apr_xml_doc *doc, ap_filter_t *output) { svn_error_t *serr; dav_error *derr = NULL; apr_xml_elem *child; struct log_receiver_baton lrb; dav_svn__authz_read_baton arb; const dav_svn_repos *repos = resource->info->repos; const char *target = NULL; int limit = 0; int ns; svn_boolean_t seen_revprop_element; /* These get determined from the request document. */ svn_revnum_t start = SVN_INVALID_REVNUM; /* defaults to HEAD */ svn_revnum_t end = SVN_INVALID_REVNUM; /* defaults to HEAD */ svn_boolean_t discover_changed_paths = FALSE; /* off by default */ svn_boolean_t strict_node_history = FALSE; /* off by default */ svn_boolean_t include_merged_revisions = FALSE; /* off by default */ apr_array_header_t *revprops = apr_array_make(resource->pool, 3, sizeof(const char *)); apr_array_header_t *paths = apr_array_make(resource->pool, 1, sizeof(const char *)); /* Sanity check. */ if (!resource->info->repos_path) return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0, "The request does not specify a repository path"); 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); } /* If this is still FALSE after the loop, we haven't seen either of the revprop elements, meaning a pre-1.5 client; we'll return the standard author/date/log revprops. */ seen_revprop_element = FALSE; lrb.requested_custom_revprops = FALSE; lrb.encode_binary_props = FALSE; 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, "start-revision") == 0) start = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1)); else if (strcmp(child->name, "end-revision") == 0) end = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1)); else if (strcmp(child->name, "limit") == 0) { serr = svn_cstring_atoi(&limit, dav_xml_get_cdata(child, resource->pool, 1)); if (serr) { return dav_svn__convert_err(serr, HTTP_BAD_REQUEST, "Malformed CDATA in element " "\"limit\"", resource->pool); } } else if (strcmp(child->name, "discover-changed-paths") == 0) discover_changed_paths = TRUE; /* presence indicates positivity */ else if (strcmp(child->name, "strict-node-history") == 0) strict_node_history = TRUE; /* presence indicates positivity */ else if (strcmp(child->name, "include-merged-revisions") == 0) include_merged_revisions = TRUE; /* presence indicates positivity */ else if (strcmp(child->name, "encode-binary-props") == 0) lrb.encode_binary_props = TRUE; /* presence indicates positivity */ else if (strcmp(child->name, "all-revprops") == 0) { revprops = NULL; /* presence indicates fetch all revprops */ seen_revprop_element = lrb.requested_custom_revprops = TRUE; } else if (strcmp(child->name, "no-revprops") == 0) { /* presence indicates fetch no revprops */ seen_revprop_element = lrb.requested_custom_revprops = TRUE; } else if (strcmp(child->name, "revprop") == 0) { if (revprops) { /* We're not fetching all revprops, append to fetch list. */ const char *name = dav_xml_get_cdata(child, resource->pool, 0); APR_ARRAY_PUSH(revprops, const char *) = name; if (!lrb.requested_custom_revprops && strcmp(name, SVN_PROP_REVISION_AUTHOR) != 0 && strcmp(name, SVN_PROP_REVISION_DATE) != 0 && strcmp(name, SVN_PROP_REVISION_LOG) != 0) lrb.requested_custom_revprops = TRUE; } seen_revprop_element = TRUE; } else if (strcmp(child->name, "path") == 0) { const char *rel_path = dav_xml_get_cdata(child, resource->pool, 0); if ((derr = dav_svn__test_canonical(rel_path, resource->pool))) return derr; /* Force REL_PATH to be a relative path, not an fspath. */ rel_path = svn_relpath_canonicalize(rel_path, resource->pool); /* Append the REL_PATH to the base FS path to get an absolute repository path. */ target = svn_fspath__join(resource->info->repos_path, rel_path, resource->pool); APR_ARRAY_PUSH(paths, const char *) = target; } /* else unknown element; skip it */ } if (!seen_revprop_element) { /* pre-1.5 client */ APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_AUTHOR; APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_DATE; APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_LOG; } /* Build authz read baton */ arb.r = resource->info->r; arb.repos = resource->info->repos; /* Build log receiver baton */ lrb.bb = apr_brigade_create(resource->pool, /* not the subpool! */ output->c->bucket_alloc); lrb.output = output; lrb.needs_header = TRUE; lrb.stack_depth = 0; /* lrb.requested_custom_revprops set above */ /* Our svn_log_entry_receiver_t sends the <S:log-report> header in a lazy fashion. Before writing the first log message, it assures that the header has already been sent (checking the needs_header flag in our log_receiver_baton structure). */ /* Send zero or more log items. */ serr = svn_repos_get_logs4(repos->repos, paths, start, end, limit, discover_changed_paths, strict_node_history, include_merged_revisions, revprops, dav_svn__authz_read_func(&arb), &arb, log_receiver, &lrb, resource->pool); if (serr) { derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST, serr->message, resource->pool); goto cleanup; } if ((serr = maybe_send_header(&lrb))) { derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, "Error beginning REPORT response.", resource->pool); goto cleanup; } if ((serr = dav_svn__brigade_puts(lrb.bb, lrb.output, "</S:log-report>" DEBUG_CR))) { derr = dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, "Error ending REPORT response.", resource->pool); goto cleanup; } cleanup: dav_svn__operational_log(resource->info, svn_log__log(paths, start, end, limit, discover_changed_paths, strict_node_history, include_merged_revisions, revprops, resource->pool)); return dav_svn__final_flush_or_error(resource->info->r, lrb.bb, output, derr, resource->pool); }