static void dump_hash(apr_pool_t *p, apr_hash_t *h, char str[][MAX_LTH]) { apr_hash_index_t *hi; int i = 0; for (hi = apr_hash_first(p, h); hi; hi = apr_hash_next(hi)) { const char *key = apr_hash_this_key(hi); apr_ssize_t len = apr_hash_this_key_len(hi); char *val = apr_hash_this_val(hi); str[i][0]='\0'; apr_snprintf(str[i], MAX_LTH, "%sKey %s (%" APR_SSIZE_T_FMT ") Value %s\n", str[i], key, len, val); i++; } str[i][0]='\0'; apr_snprintf(str[i], MAX_LTH, "%s#entries %d\n", str[i], i); /* Sort the result strings so that they can be checked for expected results easily, * without having to worry about platform quirks */ qsort( str, /* Pointer to elements */ i, /* number of elements */ MAX_LTH, /* size of one element */ comp_string /* Pointer to comparison routine */ ); }
/* Write to DIGEST_PATH a representation of CHILDREN (which may be empty, if the versioned path in FS represented by DIGEST_PATH has no children) and LOCK (which may be NULL if that versioned path is lock itself locked). Set the permissions of DIGEST_PATH to those of PERMS_REFERENCE. Use POOL for all allocations. */ static svn_error_t * write_digest_file(apr_hash_t *children, svn_lock_t *lock, const char *fs_path, const char *digest_path, const char *perms_reference, apr_pool_t *pool) { svn_error_t *err = SVN_NO_ERROR; svn_stream_t *stream; apr_hash_index_t *hi; apr_hash_t *hash = apr_hash_make(pool); const char *tmp_path; SVN_ERR(svn_fs_fs__ensure_dir_exists(svn_dirent_join(fs_path, PATH_LOCKS_DIR, pool), fs_path, pool)); SVN_ERR(svn_fs_fs__ensure_dir_exists(svn_dirent_dirname(digest_path, pool), fs_path, pool)); if (lock) { const char *creation_date = NULL, *expiration_date = NULL; if (lock->creation_date) creation_date = svn_time_to_cstring(lock->creation_date, pool); if (lock->expiration_date) expiration_date = svn_time_to_cstring(lock->expiration_date, pool); hash_store(hash, PATH_KEY, sizeof(PATH_KEY)-1, lock->path, APR_HASH_KEY_STRING, pool); hash_store(hash, TOKEN_KEY, sizeof(TOKEN_KEY)-1, lock->token, APR_HASH_KEY_STRING, pool); hash_store(hash, OWNER_KEY, sizeof(OWNER_KEY)-1, lock->owner, APR_HASH_KEY_STRING, pool); hash_store(hash, COMMENT_KEY, sizeof(COMMENT_KEY)-1, lock->comment, APR_HASH_KEY_STRING, pool); hash_store(hash, IS_DAV_COMMENT_KEY, sizeof(IS_DAV_COMMENT_KEY)-1, lock->is_dav_comment ? "1" : "0", 1, pool); hash_store(hash, CREATION_DATE_KEY, sizeof(CREATION_DATE_KEY)-1, creation_date, APR_HASH_KEY_STRING, pool); hash_store(hash, EXPIRATION_DATE_KEY, sizeof(EXPIRATION_DATE_KEY)-1, expiration_date, APR_HASH_KEY_STRING, pool); } if (apr_hash_count(children)) { svn_stringbuf_t *children_list = svn_stringbuf_create_empty(pool); for (hi = apr_hash_first(pool, children); hi; hi = apr_hash_next(hi)) { svn_stringbuf_appendbytes(children_list, apr_hash_this_key(hi), apr_hash_this_key_len(hi)); svn_stringbuf_appendbyte(children_list, '\n'); } hash_store(hash, CHILDREN_KEY, sizeof(CHILDREN_KEY)-1, children_list->data, children_list->len, pool); } SVN_ERR(svn_stream_open_unique(&stream, &tmp_path, svn_dirent_dirname(digest_path, pool), svn_io_file_del_none, pool, pool)); if ((err = svn_hash_write2(hash, stream, SVN_HASH_TERMINATOR, pool))) { svn_error_clear(svn_stream_close(stream)); return svn_error_createf(err->apr_err, err, _("Cannot write lock/entries hashfile '%s'"), svn_dirent_local_style(tmp_path, pool)); } SVN_ERR(svn_stream_close(stream)); SVN_ERR(svn_io_file_rename(tmp_path, digest_path, pool)); SVN_ERR(svn_io_copy_perms(perms_reference, digest_path, pool)); return SVN_NO_ERROR; }
svn_error_t * svn_ra__get_inherited_props_walk(svn_ra_session_t *session, const char *path, svn_revnum_t revision, apr_array_header_t **inherited_props, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { const char *repos_root_url; const char *session_url; const char *parent_url; apr_pool_t *iterpool = svn_pool_create(scratch_pool); *inherited_props = apr_array_make(result_pool, 1, sizeof(svn_prop_inherited_item_t *)); /* Walk to the root of the repository getting inherited props for PATH. */ SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, scratch_pool)); SVN_ERR(svn_ra_get_session_url(session, &session_url, scratch_pool)); parent_url = session_url; while (strcmp(repos_root_url, parent_url)) { apr_hash_index_t *hi; apr_hash_t *parent_props; apr_hash_t *final_hash = apr_hash_make(result_pool); svn_error_t *err; svn_pool_clear(iterpool); parent_url = svn_uri_dirname(parent_url, scratch_pool); SVN_ERR(svn_ra_reparent(session, parent_url, iterpool)); err = session->vtable->get_dir(session, NULL, NULL, &parent_props, "", revision, SVN_DIRENT_ALL, iterpool); /* If the user doesn't have read access to a parent path then skip, but allow them to inherit from further up. */ if (err) { if ((err->apr_err == SVN_ERR_RA_NOT_AUTHORIZED) || (err->apr_err == SVN_ERR_RA_DAV_FORBIDDEN)) { svn_error_clear(err); continue; } else { return svn_error_trace(err); } } for (hi = apr_hash_first(scratch_pool, parent_props); hi; hi = apr_hash_next(hi)) { const char *name = apr_hash_this_key(hi); apr_ssize_t klen = apr_hash_this_key_len(hi); svn_string_t *value = apr_hash_this_val(hi); if (svn_property_kind2(name) == svn_prop_regular_kind) { name = apr_pstrdup(result_pool, name); value = svn_string_dup(value, result_pool); apr_hash_set(final_hash, name, klen, value); } } if (apr_hash_count(final_hash)) { svn_prop_inherited_item_t *new_iprop = apr_palloc(result_pool, sizeof(*new_iprop)); new_iprop->path_or_url = svn_uri_skip_ancestor(repos_root_url, parent_url, result_pool); new_iprop->prop_hash = final_hash; svn_sort__array_insert(*inherited_props, &new_iprop, 0); } } /* Reparent session back to original URL. */ SVN_ERR(svn_ra_reparent(session, session_url, scratch_pool)); svn_pool_destroy(iterpool); return SVN_NO_ERROR; }