Repository(char const* path) { svn_repos_t *repos; check_svn(svn_repos_open(&repos, path, apr_pool)); fs = svn_repos_fs(repos); svn_revnum_t revnum; check_svn(svn_fs_youngest_rev(&revnum, fs, apr_pool)); check_svn(svn_fs_revision_root(&fs_root, fs, revnum, apr_pool)); }
/* Helper to open a repository and set a warning func (so we don't * SEGFAULT when libsvn_fs's default handler gets run). */ static svn_error_t * open_repos (svn_repos_t **repos, const char *path, apr_pool_t *pool) { SVN_ERR (svn_repos_open (repos, path, pool)); svn_fs_set_warning_func (svn_repos_fs (*repos), warning_func, NULL); return SVN_NO_ERROR; }
static PyObject *repos_init(PyTypeObject *type, PyObject *args, PyObject *kwargs) { const char *path; char *kwnames[] = { "path", NULL }; svn_error_t *err; RepositoryObject *ret; PyObject *py_path; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwnames, &py_path)) return NULL; ret = PyObject_New(RepositoryObject, &Repository_Type); if (ret == NULL) return NULL; ret->pool = Pool(NULL); if (ret->pool == NULL) { PyObject_DEL(ret); return NULL; } path = py_object_to_svn_dirent(py_path, ret->pool); if (path == NULL) { Py_DECREF(ret); return NULL; } Py_BEGIN_ALLOW_THREADS err = svn_repos_open(&ret->repos, path, ret->pool); Py_END_ALLOW_THREADS if (err != NULL) { handle_svn_error(err); svn_error_clear(err); Py_DECREF(ret); return NULL; } return (PyObject *)ret; }
svn_error_t * svn_ra_local__split_URL(svn_repos_t **repos, const char **repos_url, const char **fs_path, const char *URL, apr_pool_t *pool) { svn_error_t *err = SVN_NO_ERROR; const char *repos_root; const char *hostname, *path; svn_stringbuf_t *urlbuf; /* Verify that the URL is well-formed (loosely) */ /* First, check for the "file://" prefix. */ if (strncmp(URL, "file://", 7) != 0) return svn_error_createf (SVN_ERR_RA_ILLEGAL_URL, NULL, _("Local URL '%s' does not contain 'file://' prefix"), URL); /* Then, skip what's between the "file://" prefix and the next occurance of '/' -- this is the hostname, and we are considering everything from that '/' until the end of the URL to be the absolute path portion of the URL. If we got just "file://", treat it the same as "file:///". */ hostname = URL + 7; if (*hostname == '\0') { path = "/"; hostname = NULL; } else { path = strchr(hostname, '/'); if (! path) return svn_error_createf (SVN_ERR_RA_ILLEGAL_URL, NULL, _("Local URL '%s' contains only a hostname, no path"), URL); /* Treat localhost as an empty hostname. */ if (hostname != path) { hostname = svn_path_uri_decode(apr_pstrmemdup(pool, hostname, path - hostname), pool); if (strncmp(hostname, "localhost", 9) == 0) hostname = NULL; } else hostname = NULL; } /* Duplicate the URL, starting at the top of the path. At the same time, we URI-decode the path. */ #if defined(WIN32) || defined(__CYGWIN__) /* On Windows, we'll typically have to skip the leading / if the path starts with a drive letter. Like most Web browsers, We support two variants of this scheme: file:///X:/path and file:///X|/path Note that, at least on WinNT and above, file:////./X:/path will also work, so we must make sure the transformation doesn't break that, and file:///path (that looks within the current drive only) should also keep working. If we got a non-empty hostname other than localhost, we convert this into an UNC path. In this case, we obviously don't strip the slash even if the path looks like it starts with a drive letter. Another thing to remember is that the form file:///\machine/share was the only way to access UNC paths in svn before 1.2. We need to support that for compatibility with old working copies. */ { static const char valid_drive_letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; /* Casting away const! */ char *dup_path = (char *)svn_path_uri_decode(path, pool); if (!hostname && dup_path[1] && strchr(valid_drive_letters, dup_path[1]) && (dup_path[2] == ':' || dup_path[2] == '|') && dup_path[3] == '/') { /* Skip the leading slash. */ ++dup_path; /* We're using path below to calculate fs_path, so keep it in sync. */ ++path; if (dup_path[1] == '|') dup_path[1] = ':'; } if (hostname) /* We still know that the path starts with a slash. */ repos_root = apr_pstrcat(pool, "//", hostname, path, NULL); else repos_root = dup_path; } #else /* Currently, the only hostnames we are allowing on non-Win32 platforms are the empty string and 'localhost'. */ if (hostname) return svn_error_createf (SVN_ERR_RA_ILLEGAL_URL, NULL, _("Local URL '%s' contains unsupported hostname"), URL); repos_root = svn_path_uri_decode(path, pool); #endif /* Search for a repository in the full path. */ repos_root = svn_repos_find_root_path(repos_root, pool); if (!repos_root) return svn_error_createf (SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED, NULL, _("Unable to open repository '%s'"), URL); /* Attempt to open a repository at URL. */ err = svn_repos_open(repos, repos_root, pool); if (err) return svn_error_createf (SVN_ERR_RA_LOCAL_REPOS_OPEN_FAILED, err, _("Unable to open repository '%s'"), URL); /* Assert capabilities directly, since client == server. */ { apr_array_header_t *caps = apr_array_make(pool, 1, sizeof(const char *)); APR_ARRAY_PUSH(caps, const char *) = SVN_RA_CAPABILITY_MERGEINFO; SVN_ERR(svn_repos_remember_client_capabilities(*repos, caps)); } /* What remains of URL after being hacked at in the previous step is REPOS_URL. FS_PATH is what we've hacked off in the process. Note that path is not encoded and what we gave to svn_root_find_root_path may have been destroyed by that function. So we have to decode it once more. But then, it is ours... We want the suffix of path after the repos root part. Note that repos_root may contain //hostname, but path doesn't. */ *fs_path = svn_path_uri_decode(path, pool) + (strlen(repos_root) - (hostname ? strlen(hostname) + 2 : 0)); /* Ensure that *FS_PATH has its leading slash. */ if (**fs_path != '/') *fs_path = apr_pstrcat(pool, "/", *fs_path, NULL); /* Remove the path components in *fs_path from the original URL, to get the URL to the repository root. */ urlbuf = svn_stringbuf_create(URL, pool); svn_path_remove_components(urlbuf, svn_path_component_count(*fs_path)); *repos_url = urlbuf->data; return SVN_NO_ERROR; }