예제 #1
0
파일: editorp.c 프로젝트: Alkzndr/freebsd
static svn_error_t *ra_svn_handle_add_file(svn_ra_svn_conn_t *conn,
                                           apr_pool_t *pool,
                                           const apr_array_header_t *params,
                                           ra_svn_driver_state_t *ds)
{
  const char *path, *token, *file_token, *copy_path;
  svn_revnum_t copy_rev;
  ra_svn_token_entry_t *entry, *file_entry;

  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ccc(?cr)", &path, &token,
                                  &file_token, &copy_path, &copy_rev));
  SVN_ERR(lookup_token(ds, token, FALSE, &entry));
  ds->file_refs++;
  path = svn_relpath_canonicalize(path, pool);

  /* Some operations pass COPY_PATH as a full URL (commits, etc.).
     Others (replay, e.g.) deliver an fspath.  That's ... annoying. */
  if (copy_path)
    {
      if (svn_path_is_url(copy_path))
        copy_path = svn_uri_canonicalize(copy_path, pool);
      else
        copy_path = svn_fspath__canonicalize(copy_path, pool);
    }

  file_entry = store_token(ds, NULL, file_token, TRUE, ds->file_pool);
  SVN_CMD_ERR(ds->editor->add_file(path, entry->baton, copy_path, copy_rev,
                                   ds->file_pool, &file_entry->baton));
  return SVN_NO_ERROR;
}
예제 #2
0
파일: util.c 프로젝트: DJEX93/dsploit
svn_error_t *
svn_ra_neon__copy_href(svn_stringbuf_t *dst, const char *src,
                       apr_pool_t *pool)
{
  /* parse the PATH element out of the URL and store it.

     ### do we want to verify the rest matches the current session?

     Note: mod_dav does not (currently) use an absolute URL, but simply a
     server-relative path (i.e. this uri_parse is effectively a no-op).
  */

  apr_uri_t uri;
  apr_status_t apr_status;

  /* SRC can have trailing '/' */
  if (svn_path_is_url(src))
    src = svn_uri_canonicalize(src, pool);
  else
    src = svn_urlpath__canonicalize(src, pool);
  apr_status = apr_uri_parse(pool, src, &uri);

  if (apr_status != APR_SUCCESS)
    return svn_error_wrap_apr(apr_status,
                              _("Unable to parse URL '%s'"),
                              src);

  svn_stringbuf_setempty(dst);
  svn_stringbuf_appendcstr(dst, uri.path);

  return SVN_NO_ERROR;
}
int
main(int argc, const char *argv[])
{
  apr_pool_t *pool;
  int exit_code = EXIT_SUCCESS;
  svn_error_t *err;
  const char *url;
  svn_revnum_t revision;
  const char *propname;
  svn_string_t *propval;
  svn_string_t *old_propval;
  char *digits_end = NULL;
  svn_boolean_t want_error;
  const char *config_dir;

  if (argc != 7)
    {
      fprintf(stderr, USAGE_MSG, argv[0], KEY_OLD_PROPVAL, KEY_NEW_PROPVAL);
      exit(1);
    }

  if (apr_initialize() != APR_SUCCESS)
    {
      fprintf(stderr, "apr_initialize() failed.\n");
      exit(1);
    }

  /* set up the global pool */
  pool = svn_pool_create(NULL);

  /* Parse argv. */
  url = svn_uri_canonicalize(argv[1], pool);
  revision = strtol(argv[2], &digits_end, 10);
  propname = argv[3];
  SVN_INT_ERR(extract_values_from_skel(&old_propval, &propval, argv[4], pool));
  want_error = !strcmp(argv[5], "1");
  config_dir = svn_dirent_canonicalize(argv[6], pool);


  if ((! SVN_IS_VALID_REVNUM(revision)) || (! digits_end) || *digits_end)
    SVN_INT_ERR(svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                 _("Invalid revision number supplied")));

  /* Do something. */
  err = change_rev_prop(url, revision, propname, propval, old_propval,
                        want_error, config_dir, pool);
  if (err)
    {
      svn_handle_error2(err, stderr, FALSE, "atomic-ra-revprop-change: ");
      svn_error_clear(err);
      exit_code = EXIT_FAILURE;
    }

  /* Clean up, and get outta here */
  svn_pool_destroy(pool);
  apr_terminate();

  return exit_code;
}
예제 #4
0
파일: JNIUtil.cpp 프로젝트: Ranga123/test1
svn_error_t *JNIUtil::preprocessPath(const char *&path, apr_pool_t *pool)
{
  /* URLs and wc-paths get treated differently. */
  if (svn_path_is_url(path))
    {
      /* No need to canonicalize a URL's case or path separators. */

      /* Convert to URI. */
      path = svn_path_uri_from_iri(path, pool);

      /* Auto-escape some ASCII characters. */
      path = svn_path_uri_autoescape(path, pool);

      /* The above doesn't guarantee a valid URI. */
      if (! svn_path_is_uri_safe(path))
        return svn_error_createf(SVN_ERR_BAD_URL, NULL,
                                 _("URL '%s' is not properly URI-encoded"),
                                 path);

      /* Verify that no backpaths are present in the URL. */
      if (svn_path_is_backpath_present(path))
        return svn_error_createf(SVN_ERR_BAD_URL, NULL,
                                 _("URL '%s' contains a '..' element"),
                                 path);

      /* strip any trailing '/' */
      path = svn_uri_canonicalize(path, pool);
    }
  else  /* not a url, so treat as a path */
    {
      /* Normalize path to subversion internal style */

      /* ### In Subversion < 1.6 this method on Windows actually tried
         to lookup the path on disk to fix possible invalid casings in
         the passed path. (An extremely expensive operation; especially
         on network drives).

         This 'feature'is now removed as it penalizes every correct
         path passed, and also breaks behavior of e.g.
           'svn status .' returns '!' file, because there is only a "File"
             on disk.
            But when you then call 'svn status file', you get '? File'.

         As JavaHL is designed to be platform independent I assume users
         don't want this broken behavior on non round-trippable paths, nor
         the performance penalty.
       */

      path = svn_dirent_internal_style(path, pool);

      /* For kicks and giggles, let's absolutize it. */
      SVN_ERR(svn_dirent_get_absolute(&path, path, pool));
    }

  return NULL;
}
예제 #5
0
/* Parse the conflict info fields from SKEL into *VERSION_INFO. */
static svn_error_t *
read_node_version_info(const svn_wc_conflict_version_t **version_info,
                       const svn_skel_t *skel,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
{
  int n;
  const char *repos_root;
  const char *repos_relpath;
  svn_revnum_t peg_rev;
  svn_node_kind_t kind;

  if (!is_valid_version_info_skel(skel))
    return svn_error_create(SVN_ERR_WC_CORRUPT, NULL,
                            _("Invalid version info in tree conflict "
                              "description"));

  repos_root = apr_pstrmemdup(scratch_pool,
                              skel->children->next->data,
                              skel->children->next->len);
  if (*repos_root == '\0')
    {
      *version_info = NULL;
      return SVN_NO_ERROR;
    }

  /* Apply the Subversion 1.7+ url canonicalization rules to a pre 1.7 url */
  repos_root = svn_uri_canonicalize(repos_root, result_pool);

  peg_rev = SVN_STR_TO_REV(apr_pstrmemdup(scratch_pool,
                                          skel->children->next->next->data,
                                          skel->children->next->next->len));

  repos_relpath = apr_pstrmemdup(result_pool,
                                 skel->children->next->next->next->data,
                                 skel->children->next->next->next->len);

  SVN_ERR(read_enum_field(&n, node_kind_map,
                          skel->children->next->next->next->next));
  kind = (svn_node_kind_t)n;

  *version_info = svn_wc_conflict_version_create2(repos_root,
                                                  NULL,
                                                  repos_relpath,
                                                  peg_rev,
                                                  kind,
                                                  result_pool);

  return SVN_NO_ERROR;
}
예제 #6
0
/* This is read_path() for urls. This function does not do the is_canonical
   test for entries from working copies older than version 10, as since that
   version the canonicalization of urls has been changed. See issue #2475.
   If the test is done and fails, read_url returs an error. */
static svn_error_t *
read_url(const char **result,
         char **buf, const char *end,
         int wc_format,
         apr_pool_t *pool)
{
    SVN_ERR(read_str(result, buf, end, pool));

    /* Always canonicalize the url, as we have stricter canonicalization rules
       in 1.7+ then before */
    if (*result && **result)
        *result = svn_uri_canonicalize(*result, pool);

    return SVN_NO_ERROR;
}
예제 #7
0
파일: editor.c 프로젝트: ardumont/subvertpy
static PyObject *py_dir_editor_add_directory(PyObject *self, PyObject *args)
{
	PyObject *py_path, *py_copyfrom_path = Py_None;
	const char *path;
	const char *copyfrom_path = NULL;
	svn_revnum_t copyfrom_rev = -1;
	void *child_baton;
	EditorObject *editor = (EditorObject *)self;
	apr_pool_t *subpool;

	if (!PyArg_ParseTuple(args, "O|Ol", &py_path, &py_copyfrom_path, &copyfrom_rev))
		return NULL;

	if (editor->done) {
		PyErr_SetString(PyExc_RuntimeError, "directory editor already closed");
		return NULL;
	}

	if (editor->active_child) {
		PyErr_SetString(PyExc_RuntimeError, "child is already open");
		return NULL;
	}

	path = py_object_to_svn_relpath(py_path, editor->pool);
	if (path == NULL) {
		return NULL;
	}

	if (py_copyfrom_path != Py_None) {
		copyfrom_path = py_object_to_svn_uri(py_copyfrom_path, editor->pool);
		if (copyfrom_path == NULL) {
			return NULL;
		}
	}

	RUN_SVN(editor->editor->add_directory(
		path, editor->baton,
		copyfrom_path == NULL?NULL:svn_uri_canonicalize(copyfrom_path, editor->pool),
		copyfrom_rev, editor->pool, &child_baton));

	subpool = Pool(editor->pool);
	if (subpool == NULL)
		return NULL;

	return new_editor_object(editor, editor->editor, child_baton, subpool, 
							 &DirectoryEditor_Type, NULL, NULL, NULL);
}
예제 #8
0
파일: svnauthz.c 프로젝트: lysine/wasp
/* Canonicalize ACCESS_FILE into *CANONICALIZED_ACCESS_FILE based on the type
   of argument.  Error out on unsupported path types.  If WITHIN_TXN is set,
   ACCESS_FILE has to be a fspath in the repo.  Use POOL for allocations. */
static svn_error_t *
canonicalize_access_file(const char **canonicalized_access_file,
                         const char *access_file,
                         svn_boolean_t within_txn,
                         apr_pool_t *pool)
{
  if (svn_path_is_repos_relative_url(access_file))
    {
      /* Can't accept repos relative urls since we don't have the path to
       * the repository. */
      return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                               ("'%s' is a repository relative URL when it "
                               "should be a local path or file:// URL"),
                               access_file);
    }
  else if (svn_path_is_url(access_file))
    {
      if (within_txn)
        {
          /* Don't allow urls with transaction argument. */
          return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                   ("'%s' is a URL when it should be a "
                                   "repository-relative path"),
                                   access_file);
        }

      *canonicalized_access_file = svn_uri_canonicalize(access_file, pool);
    }
  else if (within_txn)
    {
      /* Transaction flag means this has to be a fspath to the access file
       * in the repo. */
      *canonicalized_access_file =
          svn_fspath__canonicalize(access_file, pool);
    }
  else
    {
      /* If it isn't a URL and there's no transaction flag then it's a
       * dirent to the access file on local disk. */
      *canonicalized_access_file =
          svn_dirent_internal_style(access_file, pool);
    }

  return SVN_NO_ERROR;
}
예제 #9
0
const char* CTSVNPath::GetSVNApiPath(apr_pool_t *pool) const
{
    // This funny-looking 'if' is to avoid a subtle problem with empty paths, whereby
    // each call to GetSVNApiPath returns a different pointer value.
    // If you made multiple calls to GetSVNApiPath on the same string, only the last
    // one would give you a valid pointer to an empty string, because each
    // call would invalidate the previous call's return.
    if(IsEmpty())
    {
        return "";
    }
    if(m_sFwdslashPath.IsEmpty())
    {
        SetFwdslashPath(m_sBackslashPath);
    }
    if(m_sUTF8FwdslashPath.IsEmpty())
    {
        SetUTF8FwdslashPath(m_sFwdslashPath);
    }

    if (svn_path_is_url(m_sUTF8FwdslashPath))
    {
        m_sUTF8FwdslashPathEscaped = CPathUtils::PathEscape(m_sUTF8FwdslashPath);
        m_sUTF8FwdslashPathEscaped.Replace("file:////", "file://");
        m_sUTF8FwdslashPathEscaped = svn_uri_canonicalize(m_sUTF8FwdslashPathEscaped, pool);
        return m_sUTF8FwdslashPathEscaped;
    }
    else
    {
        m_sUTF8FwdslashPath = svn_dirent_canonicalize(m_sUTF8FwdslashPath, pool);
        // for UNC paths that point to the server directly (e.g., \\MYSERVER), not
        // to a share on the server, the svn_dirent_canonicalize() API returns
        // a wrong path that asserts when subversion checks that the path is absolute
        // (it returns /MYSERVER instead of //MYSERVER).
        // We can't just add the second slash, since that would assert when svn checks
        // for canonicalized paths.
        // Since the network server itself isn't interesting anyway but only shares,
        // we just return an empty path here.
        if (!svn_dirent_is_absolute(m_sUTF8FwdslashPath))
            m_sUTF8FwdslashPath.Empty();
    }
    return m_sUTF8FwdslashPath;
}
예제 #10
0
파일: util.c 프로젝트: DJEX93/dsploit
const char *
svn_ra_neon__uri_unparse(const ne_uri *uri,
                         apr_pool_t *pool)
{
  char *unparsed_uri;
  const char *result;

  /* Unparse uri. */
  unparsed_uri = ne_uri_unparse(uri);

  /* Copy string to result pool, and make sure it conforms to
     Subversion rules */
  result = svn_uri_canonicalize(unparsed_uri, pool);

  /* Free neon's allocated copy. */
  ne_free(unparsed_uri);

  /* Return string allocated in result pool. */
  return result;
}
예제 #11
0
파일: opt.c 프로젝트: ChaosJohn/freebsd
svn_error_t *
svn_opt__arg_canonicalize_url(const char **url_out, const char *url_in,
                              apr_pool_t *pool)
{
  const char *target;

  /* Convert to URI. */
  target = svn_path_uri_from_iri(url_in, pool);
  /* Auto-escape some ASCII characters. */
  target = svn_path_uri_autoescape(target, pool);

#if '/' != SVN_PATH_LOCAL_SEPARATOR
  /* Allow using file:///C:\users\me/repos on Windows, like we did in 1.6 */
  if (strchr(target, SVN_PATH_LOCAL_SEPARATOR))
    {
      char *p = apr_pstrdup(pool, target);
      target = p;

      /* Convert all local-style separators to the canonical ones. */
      for (; *p != '\0'; ++p)
        if (*p == SVN_PATH_LOCAL_SEPARATOR)
          *p = '/';
    }
#endif

  /* Verify that no backpaths are present in the URL. */
  if (svn_path_is_backpath_present(target))
    return svn_error_createf(SVN_ERR_BAD_URL, 0,
                             _("URL '%s' contains a '..' element"),
                             target);

  /* Strip any trailing '/' and collapse other redundant elements. */
  target = svn_uri_canonicalize(target, pool);

  *url_out = target;
  return SVN_NO_ERROR;
}
예제 #12
0
int
main(int argc, const char **argv)
{
    svn_error_t *err = SVN_NO_ERROR;
    const svn_opt_subcommand_desc2_t *subcommand = NULL;
    opt_baton_t *opt_baton;
    svn_revnum_t latest_revision = SVN_INVALID_REVNUM;
    apr_pool_t *pool = NULL;
    const char *config_dir = NULL;
    const char *username = NULL;
    const char *password = NULL;
    svn_boolean_t no_auth_cache = FALSE;
    svn_boolean_t trust_server_cert = FALSE;
    svn_boolean_t non_interactive = FALSE;
    apr_array_header_t *config_options = NULL;
    apr_getopt_t *os;
    const char *first_arg;
    apr_array_header_t *received_opts;
    apr_allocator_t *allocator;
    int i;

    if (svn_cmdline_init ("svnrdump", stderr) != EXIT_SUCCESS)
        return EXIT_FAILURE;

    /* Create our top-level pool.  Use a separate mutexless allocator,
     * given this application is single threaded.
     */
    if (apr_allocator_create(&allocator))
        return EXIT_FAILURE;

    apr_allocator_max_free_set(allocator, SVN_ALLOCATOR_RECOMMENDED_MAX_FREE);

    pool = svn_pool_create_ex(NULL, allocator);
    apr_allocator_owner_set(allocator, pool);

    opt_baton = apr_pcalloc(pool, sizeof(*opt_baton));
    opt_baton->start_revision.kind = svn_opt_revision_unspecified;
    opt_baton->end_revision.kind = svn_opt_revision_unspecified;
    opt_baton->url = NULL;

    SVNRDUMP_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));

    os->interleave = TRUE; /* Options and arguments can be interleaved */

    /* Set up our cancellation support. */
    apr_signal(SIGINT, signal_handler);
#ifdef SIGBREAK
    /* SIGBREAK is a Win32 specific signal generated by ctrl-break. */
    apr_signal(SIGBREAK, signal_handler);
#endif
#ifdef SIGHUP
    apr_signal(SIGHUP, signal_handler);
#endif
#ifdef SIGTERM
    apr_signal(SIGTERM, signal_handler);
#endif
#ifdef SIGPIPE
    /* Disable SIGPIPE generation for the platforms that have it. */
    apr_signal(SIGPIPE, SIG_IGN);
#endif
#ifdef SIGXFSZ
    /* Disable SIGXFSZ generation for the platforms that have it, otherwise
     * working with large files when compiled against an APR that doesn't have
     * large file support will crash the program, which is uncool. */
    apr_signal(SIGXFSZ, SIG_IGN);
#endif

    received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));

    while (1)
    {
        int opt;
        const char *opt_arg;
        apr_status_t status = apr_getopt_long(os, svnrdump__options, &opt,
                                              &opt_arg);

        if (APR_STATUS_IS_EOF(status))
            break;
        if (status != APR_SUCCESS)
        {
            SVNRDUMP_ERR(usage(argv[0], pool));
            exit(EXIT_FAILURE);
        }

        /* Stash the option code in an array before parsing it. */
        APR_ARRAY_PUSH(received_opts, int) = opt;

        switch(opt)
        {
        case 'r':
        {
            /* Make sure we've not seen -r already. */
            if (opt_baton->start_revision.kind != svn_opt_revision_unspecified)
            {
                err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                       _("Multiple revision arguments "
                                         "encountered; try '-r N:M' instead "
                                         "of '-r N -r M'"));
                return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
            }
            /* Parse the -r argument. */
            if (svn_opt_parse_revision(&(opt_baton->start_revision),
                                       &(opt_baton->end_revision),
                                       opt_arg, pool) != 0)
            {
                const char *utf8_opt_arg;
                err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
                if (! err)
                    err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                            _("Syntax error in revision "
                                              "argument '%s'"), utf8_opt_arg);
                return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
            }
        }
        break;
        case 'q':
            opt_baton->quiet = TRUE;
            break;
        case opt_config_dir:
            config_dir = opt_arg;
            break;
        case opt_version:
            opt_baton->version = TRUE;
            break;
        case 'h':
            opt_baton->help = TRUE;
            break;
        case opt_auth_username:
            SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&username, opt_arg, pool));
            break;
        case opt_auth_password:
            SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&password, opt_arg, pool));
            break;
        case opt_auth_nocache:
            no_auth_cache = TRUE;
            break;
        case opt_non_interactive:
            non_interactive = TRUE;
            break;
        case opt_incremental:
            opt_baton->incremental = TRUE;
            break;
        case opt_trust_server_cert:
            trust_server_cert = TRUE;
            break;
        case opt_config_option:
            if (!config_options)
                config_options =
                    apr_array_make(pool, 1,
                                   sizeof(svn_cmdline__config_argument_t*));

            SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool));
            SVNRDUMP_ERR(svn_cmdline__parse_config_option(config_options,
                         opt_arg, pool));
        }
    }

    if (opt_baton->help)
    {
        subcommand = svn_opt_get_canonical_subcommand2(svnrdump__cmd_table,
                     "help");
    }
    if (subcommand == NULL)
    {
        if (os->ind >= os->argc)
        {
            if (opt_baton->version)
            {
                /* Use the "help" subcommand to handle the "--version" option. */
                static const svn_opt_subcommand_desc2_t pseudo_cmd =
                {   "--version", help_cmd, {0}, "",
                    {   opt_version,  /* must accept its own option */
                        'q',  /* --quiet */
                    }
                };
                subcommand = &pseudo_cmd;
            }

            else
            {
                SVNRDUMP_ERR(help_cmd(NULL, NULL, pool));
                svn_pool_destroy(pool);
                exit(EXIT_FAILURE);
            }
        }
        else
        {
            first_arg = os->argv[os->ind++];
            subcommand = svn_opt_get_canonical_subcommand2(svnrdump__cmd_table,
                         first_arg);

            if (subcommand == NULL)
            {
                const char *first_arg_utf8;
                err = svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg, pool);
                if (err)
                    return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
                svn_error_clear(svn_cmdline_fprintf(stderr, pool,
                                                    _("Unknown command: '%s'\n"),
                                                    first_arg_utf8));
                SVNRDUMP_ERR(help_cmd(NULL, NULL, pool));
                svn_pool_destroy(pool);
                exit(EXIT_FAILURE);
            }
        }
    }

    /* Check that the subcommand wasn't passed any inappropriate options. */
    for (i = 0; i < received_opts->nelts; i++)
    {
        int opt_id = APR_ARRAY_IDX(received_opts, i, int);

        /* All commands implicitly accept --help, so just skip over this
           when we see it. Note that we don't want to include this option
           in their "accepted options" list because it would be awfully
           redundant to display it in every commands' help text. */
        if (opt_id == 'h' || opt_id == '?')
            continue;

        if (! svn_opt_subcommand_takes_option3(subcommand, opt_id, NULL))
        {
            const char *optstr;
            const apr_getopt_option_t *badopt =
                svn_opt_get_option_from_code2(opt_id, svnrdump__options,
                                              subcommand, pool);
            svn_opt_format_option(&optstr, badopt, FALSE, pool);
            if (subcommand->name[0] == '-')
                SVN_INT_ERR(help_cmd(NULL, NULL, pool));
            else
                svn_error_clear(svn_cmdline_fprintf(
                                    stderr, pool,
                                    _("Subcommand '%s' doesn't accept option '%s'\n"
                                      "Type 'svnrdump help %s' for usage.\n"),
                                    subcommand->name, optstr, subcommand->name));
            svn_pool_destroy(pool);
            return EXIT_FAILURE;
        }
    }

    if (subcommand && strcmp(subcommand->name, "--version") == 0)
    {
        SVNRDUMP_ERR(version(argv[0], opt_baton->quiet, pool));
        svn_pool_destroy(pool);
        exit(EXIT_SUCCESS);
    }

    if (subcommand && strcmp(subcommand->name, "help") == 0)
    {
        SVNRDUMP_ERR(help_cmd(os, opt_baton, pool));
        svn_pool_destroy(pool);
        exit(EXIT_SUCCESS);
    }

    /* --trust-server-cert can only be used with --non-interactive */
    if (trust_server_cert && !non_interactive)
    {
        err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                               _("--trust-server-cert requires "
                                 "--non-interactive"));
        return svn_cmdline_handle_exit_error(err, pool, "svnrdump: ");
    }

    /* Expect one more non-option argument:  the repository URL. */
    if (os->ind != os->argc - 1)
    {
        SVNRDUMP_ERR(usage(argv[0], pool));
        svn_pool_destroy(pool);
        exit(EXIT_FAILURE);
    }
    else
    {
        const char *repos_url;

        SVNRDUMP_ERR(svn_utf_cstring_to_utf8(&repos_url,
                                             os->argv[os->ind], pool));
        if (! svn_path_is_url(repos_url))
        {
            err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, 0,
                                    "Target '%s' is not a URL",
                                    repos_url);
            SVNRDUMP_ERR(err);
            svn_pool_destroy(pool);
            exit(EXIT_FAILURE);
        }
        opt_baton->url = svn_uri_canonicalize(repos_url, pool);
    }

    SVNRDUMP_ERR(init_client_context(&(opt_baton->ctx),
                                     non_interactive,
                                     username,
                                     password,
                                     config_dir,
                                     no_auth_cache,
                                     trust_server_cert,
                                     config_options,
                                     pool));

    SVNRDUMP_ERR(svn_client_open_ra_session(&(opt_baton->session),
                                            opt_baton->url,
                                            opt_baton->ctx, pool));

    /* Have sane opt_baton->start_revision and end_revision defaults if
       unspecified.  */
    SVNRDUMP_ERR(svn_ra_get_latest_revnum(opt_baton->session,
                                          &latest_revision, pool));

    /* Make sure any provided revisions make sense. */
    SVNRDUMP_ERR(validate_and_resolve_revisions(opt_baton,
                 latest_revision, pool));

    /* Dispatch the subcommand */
    SVNRDUMP_ERR((*subcommand->cmd_func)(os, opt_baton, pool));

    svn_pool_destroy(pool);

    return EXIT_SUCCESS;
}
예제 #13
0
svn_error_t *svn_ra_open4(svn_ra_session_t **session_p,
                          const char **corrected_url_p,
                          const char *repos_URL,
                          const char *uuid,
                          const svn_ra_callbacks2_t *callbacks,
                          void *callback_baton,
                          apr_hash_t *config,
                          apr_pool_t *pool)
{
  apr_pool_t *sesspool = svn_pool_create(pool);
  svn_ra_session_t *session;
  const struct ra_lib_defn *defn;
  const svn_ra__vtable_t *vtable = NULL;
  svn_config_t *servers = NULL;
  const char *server_group;
  apr_uri_t repos_URI;
  apr_status_t apr_err;
#ifdef CHOOSABLE_DAV_MODULE
  const char *http_library = DEFAULT_HTTP_LIBRARY;
#endif
  /* Auth caching parameters. */
  svn_boolean_t store_passwords = SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS;
  svn_boolean_t store_auth_creds = SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS;
  const char *store_plaintext_passwords
    = SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS;
  svn_boolean_t store_pp = SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP;
  const char *store_pp_plaintext
    = SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT;
  const char *corrected_url;

  /* Initialize the return variable. */
  *session_p = NULL;

  apr_err = apr_uri_parse(sesspool, repos_URL, &repos_URI);
  /* ### Should apr_uri_parse leave hostname NULL?  It doesn't
   * for "file:///" URLs, only for bogus URLs like "bogus".
   * If this is the right behavior for apr_uri_parse, maybe we
   * should have a svn_uri_parse wrapper. */
  if (apr_err != APR_SUCCESS || repos_URI.hostname == NULL)
    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                             _("Illegal repository URL '%s'"),
                             repos_URL);

  if (callbacks->auth_baton)
    {
      /* The 'store-passwords' and 'store-auth-creds' parameters used to
       * live in SVN_CONFIG_CATEGORY_CONFIG. For backward compatibility,
       * if values for these parameters have already been set by our
       * callers, we use those values as defaults.
       *
       * Note that we can only catch the case where users explicitly set
       * "store-passwords = no" or 'store-auth-creds = no".
       *
       * However, since the default value for both these options is
       * currently (and has always been) "yes", users won't know
       * the difference if they set "store-passwords = yes" or
       * "store-auth-creds = yes" -- they'll get the expected behaviour.
       */

      if (svn_auth_get_parameter(callbacks->auth_baton,
                                 SVN_AUTH_PARAM_DONT_STORE_PASSWORDS) != NULL)
        store_passwords = FALSE;

      if (svn_auth_get_parameter(callbacks->auth_baton,
                                 SVN_AUTH_PARAM_NO_AUTH_CACHE) != NULL)
        store_auth_creds = FALSE;
    }

  if (config)
    {
      /* Grab the 'servers' config. */
      servers = apr_hash_get(config, SVN_CONFIG_CATEGORY_SERVERS,
                             APR_HASH_KEY_STRING);
      if (servers)
        {
          /* First, look in the global section. */

          SVN_ERR(svn_config_get_bool
            (servers, &store_passwords, SVN_CONFIG_SECTION_GLOBAL,
             SVN_CONFIG_OPTION_STORE_PASSWORDS,
             store_passwords));

          SVN_ERR(svn_config_get_yes_no_ask
            (servers, &store_plaintext_passwords, SVN_CONFIG_SECTION_GLOBAL,
             SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
             SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS));

          SVN_ERR(svn_config_get_bool
            (servers, &store_pp, SVN_CONFIG_SECTION_GLOBAL,
             SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
             store_pp));

          SVN_ERR(svn_config_get_yes_no_ask
            (servers, &store_pp_plaintext,
             SVN_CONFIG_SECTION_GLOBAL,
             SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
             SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT));

          SVN_ERR(svn_config_get_bool
            (servers, &store_auth_creds, SVN_CONFIG_SECTION_GLOBAL,
              SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
              store_auth_creds));

          /* Find out where we're about to connect to, and
           * try to pick a server group based on the destination. */
          server_group = svn_config_find_group(servers, repos_URI.hostname,
                                               SVN_CONFIG_SECTION_GROUPS,
                                               sesspool);

          if (server_group)
            {
              /* Override global auth caching parameters with the ones
               * for the server group, if any. */
              SVN_ERR(svn_config_get_bool(servers, &store_auth_creds,
                                          server_group,
                                          SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
                                          store_auth_creds));

              SVN_ERR(svn_config_get_bool(servers, &store_passwords,
                                          server_group,
                                          SVN_CONFIG_OPTION_STORE_PASSWORDS,
                                          store_passwords));

              SVN_ERR(svn_config_get_yes_no_ask
                (servers, &store_plaintext_passwords, server_group,
                 SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
                 store_plaintext_passwords));

              SVN_ERR(svn_config_get_bool
                (servers, &store_pp,
                 server_group, SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
                 store_pp));

              SVN_ERR(svn_config_get_yes_no_ask
                (servers, &store_pp_plaintext, server_group,
                 SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
                 store_pp_plaintext));
            }
#ifdef CHOOSABLE_DAV_MODULE
          /* Now, which DAV-based RA method do we want to use today? */
          http_library
            = svn_config_get_server_setting(servers,
                                            server_group, /* NULL is OK */
                                            SVN_CONFIG_OPTION_HTTP_LIBRARY,
                                            DEFAULT_HTTP_LIBRARY);

          if (strcmp(http_library, "neon") != 0 &&
              strcmp(http_library, "serf") != 0)
            return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
                                     _("Invalid config: unknown HTTP library "
                                       "'%s'"),
                                     http_library);
#endif
        }
    }

  if (callbacks->auth_baton)
    {
      /* Save auth caching parameters in the auth parameter hash. */
      if (! store_passwords)
        svn_auth_set_parameter(callbacks->auth_baton,
                               SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");

      svn_auth_set_parameter(callbacks->auth_baton,
                             SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS,
                             store_plaintext_passwords);

      if (! store_pp)
        svn_auth_set_parameter(callbacks->auth_baton,
                               SVN_AUTH_PARAM_DONT_STORE_SSL_CLIENT_CERT_PP,
                               "");

      svn_auth_set_parameter(callbacks->auth_baton,
                             SVN_AUTH_PARAM_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
                             store_pp_plaintext);

      if (! store_auth_creds)
        svn_auth_set_parameter(callbacks->auth_baton,
                               SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
    }

  /* Find the library. */
  for (defn = ra_libraries; defn->ra_name != NULL; ++defn)
    {
      const char *scheme;

      if ((scheme = has_scheme_of(defn->schemes, repos_URL)))
        {
          svn_ra__init_func_t initfunc = defn->initfunc;

#ifdef CHOOSABLE_DAV_MODULE
          if (defn->schemes == dav_schemes
              && strcmp(defn->ra_name, http_library) != 0)
            continue;
#endif

          if (! initfunc)
            SVN_ERR(load_ra_module(&initfunc, NULL, defn->ra_name,
                                   sesspool));
          if (! initfunc)
            /* Library not found. */
            continue;

          SVN_ERR(initfunc(svn_ra_version(), &vtable, sesspool));

          SVN_ERR(check_ra_version(vtable->get_version(), scheme));

          if (! has_scheme_of(vtable->get_schemes(sesspool), repos_URL))
            /* Library doesn't support the scheme at runtime. */
            continue;


          break;
        }
    }

  if (vtable == NULL)
    return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                             _("Unrecognized URL scheme for '%s'"),
                             repos_URL);

  /* Create the session object. */
  session = apr_pcalloc(sesspool, sizeof(*session));
  session->vtable = vtable;
  session->pool = sesspool;

  /* Ask the library to open the session. */
  SVN_ERR_W(vtable->open_session(session, &corrected_url, repos_URL,
                                 callbacks, callback_baton, config, sesspool),
            apr_psprintf(pool, "Unable to connect to a repository at URL '%s'",
                         repos_URL));

  /* If the session open stuff detected a server-provided URL
     correction (a 301 or 302 redirect response during the initial
     OPTIONS request), then kill the session so the caller can decide
     what to do. */
  if (corrected_url_p && corrected_url)
    {
      if (! svn_path_is_url(corrected_url))
        {
          /* RFC1945 and RFC2616 state that the Location header's
             value (from whence this CORRECTED_URL ultimately comes),
             if present, must be an absolute URI.  But some Apache
             versions (those older than 2.2.11, it seems) transmit
             only the path portion of the URI.  See issue #3775 for
             details. */
          apr_uri_t corrected_URI = repos_URI;
          corrected_URI.path = (char *)corrected_url;
          corrected_url = apr_uri_unparse(pool, &corrected_URI, 0);
        }
      *corrected_url_p = svn_uri_canonicalize(corrected_url, pool);
      svn_pool_destroy(sesspool);
      return SVN_NO_ERROR;
    }

  /* Check the UUID. */
  if (uuid)
    {
      const char *repository_uuid;

      SVN_ERR(vtable->get_uuid(session, &repository_uuid, pool));
      if (strcmp(uuid, repository_uuid) != 0)
        {
          /* Duplicate the uuid as it is allocated in sesspool */
          repository_uuid = apr_pstrdup(pool, repository_uuid);
          svn_pool_destroy(sesspool);
          return svn_error_createf(SVN_ERR_RA_UUID_MISMATCH, NULL,
                                   _("Repository UUID '%s' doesn't match "
                                     "expected UUID '%s'"),
                                   repository_uuid, uuid);
        }
    }

  *session_p = session;
  return SVN_NO_ERROR;
}
예제 #14
0
CStringA CPathUtils::GetAbsoluteURL
    ( const CStringA& URL
    , const CStringA& repositoryRootURL
    , const CStringA& parentPathURL)
{
    CStringA errorResult;
    SVNPool pool;

    /* If the URL is already absolute, there is nothing to do. */

    const char *canonicalized_url = svn_uri_canonicalize (URL, pool);
    if (svn_path_is_url (canonicalized_url))
        return canonicalized_url;

    /* Parse the parent directory URL into its parts. */

    apr_uri_t parent_dir_parsed_uri;
    if (apr_uri_parse (pool, parentPathURL, &parent_dir_parsed_uri))
        return errorResult;

    /* If the parent directory URL is at the server root, then the URL
       may have no / after the hostname so apr_uri_parse() will leave
       the URL's path as NULL. */

    if (! parent_dir_parsed_uri.path)
        parent_dir_parsed_uri.path = apr_pstrmemdup (pool, "/", 1);

    /* Handle URLs relative to the current directory or to the
       repository root.  The backpaths may only remove path elements,
       not the hostname.  This allows an external to refer to another
       repository in the same server relative to the location of this
       repository, say using SVNParentPath. */

    if ((0 == strncmp("../", URL, 3)) || (0 == strncmp("^/", URL, 2)))
    {
        apr_array_header_t *base_components = NULL;
        apr_array_header_t *relative_components = NULL;

        /* Decompose either the parent directory's URL path or the
           repository root's URL path into components.  */

        if (0 == strncmp ("../", URL, 3))
        {
            base_components
                = svn_path_decompose (parent_dir_parsed_uri.path, pool);
            relative_components
                = svn_path_decompose (canonicalized_url, pool);
        }
        else
        {
            apr_uri_t repos_root_parsed_uri;
            if (apr_uri_parse(pool, repositoryRootURL, &repos_root_parsed_uri))
                return errorResult;

            /* If the repository root URL is at the server root, then
               the URL may have no / after the hostname so
               apr_uri_parse() will leave the URL's path as NULL. */

            if (! repos_root_parsed_uri.path)
                repos_root_parsed_uri.path = apr_pstrmemdup (pool, "/", 1);

            base_components
                = svn_path_decompose (repos_root_parsed_uri.path, pool);
            relative_components
                = svn_path_decompose (canonicalized_url + 2, pool);
        }

        for (int i = 0; i < relative_components->nelts; ++i)
        {
            const char *component
                = APR_ARRAY_IDX(relative_components, i, const char *);

            if (0 == strcmp("..", component))
            {
                /* Constructing the final absolute URL together with
                   apr_uri_unparse() requires that the path be absolute,
                   so only pop a component if the component being popped
                   is not the component for the root directory. */

                if (base_components->nelts > 1)
                    apr_array_pop (base_components);
            }
            else
                APR_ARRAY_PUSH (base_components, const char *) = component;
        }

        parent_dir_parsed_uri.path = (char *)svn_path_compose(base_components,
                                                            pool);
        parent_dir_parsed_uri.query = NULL;
        parent_dir_parsed_uri.fragment = NULL;

        return apr_uri_unparse (pool, &parent_dir_parsed_uri, 0);
    }
예제 #15
0
/* NOTE: this is used for upgrading old XML-based entries file. Be wary of
         removing items.

   ### many attributes are no longer used within the old-style log files.
   ### These attrs need to be recognized for old entries, however. For these
   ### cases, the code will parse the attribute, but not set *MODIFY_FLAGS
   ### for that particular field. MODIFY_FLAGS is *only* used by the
   ### log-based entry modification system, and will go way once we
   ### completely move away from loggy.

   Set *NEW_ENTRY to a new entry, taking attributes from ATTS, whose
   keys and values are both char *.  Allocate the entry and copy
   attributes into POOL as needed. */
static svn_error_t *
atts_to_entry(svn_wc_entry_t **new_entry,
              apr_hash_t *atts,
              apr_pool_t *pool)
{
    svn_wc_entry_t *entry = alloc_entry(pool);
    const char *name;

    /* Find the name and set up the entry under that name. */
    name = svn_hash_gets(atts, ENTRIES_ATTR_NAME);
    entry->name = name ? apr_pstrdup(pool, name) : SVN_WC_ENTRY_THIS_DIR;

    /* Attempt to set revision (resolve_to_defaults may do it later, too)

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *revision_str
            = svn_hash_gets(atts, ENTRIES_ATTR_REVISION);

        if (revision_str)
            entry->revision = SVN_STR_TO_REV(revision_str);
        else
            entry->revision = SVN_INVALID_REVNUM;
    }

    /* Attempt to set up url path (again, see resolve_to_defaults).

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->url = extract_string(atts, ENTRIES_ATTR_URL, pool);
    if (entry->url)
        entry->url = svn_uri_canonicalize(entry->url, pool);

    /* Set up repository root.  Make sure it is a prefix of url.

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->repos = extract_string(atts, ENTRIES_ATTR_REPOS, pool);
    if (entry->repos)
        entry->repos = svn_uri_canonicalize(entry->repos, pool);

    if (entry->url && entry->repos
            && !svn_uri__is_ancestor(entry->repos, entry->url))
        return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
                                 _("Entry for '%s' has invalid repository "
                                   "root"),
                                 name ? name : SVN_WC_ENTRY_THIS_DIR);

    /* Set up kind. */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *kindstr
            = svn_hash_gets(atts, ENTRIES_ATTR_KIND);

        entry->kind = svn_node_none;
        if (kindstr)
        {
            if (strcmp(kindstr, ENTRIES_VALUE_FILE) == 0)
                entry->kind = svn_node_file;
            else if (strcmp(kindstr, ENTRIES_VALUE_DIR) == 0)
                entry->kind = svn_node_dir;
            else
                return svn_error_createf
                       (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
                        _("Entry '%s' has invalid node kind"),
                        (name ? name : SVN_WC_ENTRY_THIS_DIR));
        }
    }

    /* Look for a schedule attribute on this entry. */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *schedulestr
            = svn_hash_gets(atts, ENTRIES_ATTR_SCHEDULE);

        entry->schedule = svn_wc_schedule_normal;
        if (schedulestr)
        {
            if (strcmp(schedulestr, ENTRIES_VALUE_ADD) == 0)
                entry->schedule = svn_wc_schedule_add;
            else if (strcmp(schedulestr, ENTRIES_VALUE_DELETE) == 0)
                entry->schedule = svn_wc_schedule_delete;
            else if (strcmp(schedulestr, ENTRIES_VALUE_REPLACE) == 0)
                entry->schedule = svn_wc_schedule_replace;
            else if (strcmp(schedulestr, "") == 0)
                entry->schedule = svn_wc_schedule_normal;
            else
                return svn_error_createf(
                           SVN_ERR_ENTRY_ATTRIBUTE_INVALID, NULL,
                           _("Entry '%s' has invalid 'schedule' value"),
                           (name ? name : SVN_WC_ENTRY_THIS_DIR));
        }
    }

    /* Is this entry in a state of mental torment (conflict)? */
    entry->prejfile = extract_string_normalize(atts,
                      ENTRIES_ATTR_PREJFILE,
                      pool);
    entry->conflict_old = extract_string_normalize(atts,
                          ENTRIES_ATTR_CONFLICT_OLD,
                          pool);
    entry->conflict_new = extract_string_normalize(atts,
                          ENTRIES_ATTR_CONFLICT_NEW,
                          pool);
    entry->conflict_wrk = extract_string_normalize(atts,
                          ENTRIES_ATTR_CONFLICT_WRK,
                          pool);

    /* Is this entry copied? */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    SVN_ERR(do_bool_attr(&entry->copied, atts, ENTRIES_ATTR_COPIED, name));

    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->copyfrom_url = extract_string(atts, ENTRIES_ATTR_COPYFROM_URL, pool);

    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *revstr;

        revstr = svn_hash_gets(atts, ENTRIES_ATTR_COPYFROM_REV);
        if (revstr)
            entry->copyfrom_rev = SVN_STR_TO_REV(revstr);
    }

    /* Is this entry deleted?

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    SVN_ERR(do_bool_attr(&entry->deleted, atts, ENTRIES_ATTR_DELETED, name));

    /* Is this entry absent?

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    SVN_ERR(do_bool_attr(&entry->absent, atts, ENTRIES_ATTR_ABSENT, name));

    /* Is this entry incomplete?

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    SVN_ERR(do_bool_attr(&entry->incomplete, atts, ENTRIES_ATTR_INCOMPLETE,
                         name));

    /* Attempt to set up timestamps. */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *text_timestr;

        text_timestr = svn_hash_gets(atts, ENTRIES_ATTR_TEXT_TIME);
        if (text_timestr)
            SVN_ERR(svn_time_from_cstring(&entry->text_time, text_timestr, pool));

        /* Note: we do not persist prop_time, so there is no need to attempt
           to parse a new prop_time value from the log. Certainly, on any
           recent working copy, there will not be a log record to alter
           the prop_time value. */
    }

    /* Checksum. */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->checksum = extract_string(atts, ENTRIES_ATTR_CHECKSUM, pool);

    /* UUID.

       ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->uuid = extract_string(atts, ENTRIES_ATTR_UUID, pool);

    /* Setup last-committed values. */
    {
        const char *cmt_datestr, *cmt_revstr;

        cmt_datestr = svn_hash_gets(atts, ENTRIES_ATTR_CMT_DATE);
        if (cmt_datestr)
        {
            SVN_ERR(svn_time_from_cstring(&entry->cmt_date, cmt_datestr, pool));
        }
        else
            entry->cmt_date = 0;

        cmt_revstr = svn_hash_gets(atts, ENTRIES_ATTR_CMT_REV);
        if (cmt_revstr)
        {
            entry->cmt_rev = SVN_STR_TO_REV(cmt_revstr);
        }
        else
            entry->cmt_rev = SVN_INVALID_REVNUM;

        entry->cmt_author = extract_string(atts, ENTRIES_ATTR_CMT_AUTHOR, pool);
    }

    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    entry->lock_token = extract_string(atts, ENTRIES_ATTR_LOCK_TOKEN, pool);
    entry->lock_owner = extract_string(atts, ENTRIES_ATTR_LOCK_OWNER, pool);
    entry->lock_comment = extract_string(atts, ENTRIES_ATTR_LOCK_COMMENT, pool);
    {
        const char *cdate_str =
            svn_hash_gets(atts, ENTRIES_ATTR_LOCK_CREATION_DATE);
        if (cdate_str)
        {
            SVN_ERR(svn_time_from_cstring(&entry->lock_creation_date,
                                          cdate_str, pool));
        }
    }
    /* ----- end of lock handling.  */

    /* Note: if there are attributes for the (deprecated) has_props,
       has_prop_mods, cachable_props, or present_props, then we're just
       going to ignore them. */

    /* Translated size */
    /* ### not used by loggy; no need to set MODIFY_FLAGS  */
    {
        const char *val = svn_hash_gets(atts, ENTRIES_ATTR_WORKING_SIZE);
        if (val)
        {
            /* Cast to off_t; it's safe: we put in an off_t to start with... */
            entry->working_size = (apr_off_t)apr_strtoi64(val, NULL, 0);
        }
    }

    *new_entry = entry;
    return SVN_NO_ERROR;
}
예제 #16
0
static svn_error_t *
resolve_relative_external_url(const char **resolved_url,
                              const svn_wc_external_item2_t *item,
                              const char *repos_root_url,
                              const char *parent_dir_url,
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool)
{
  const char *url = item->url;
  apr_uri_t parent_dir_uri;
  apr_status_t status;

  *resolved_url = item->url;

  /* If the URL is already absolute, there is nothing to do. */
  if (svn_path_is_url(url))
    {
      /* "http://server/path" */
      *resolved_url = svn_uri_canonicalize(url, result_pool);
      return SVN_NO_ERROR;
    }

  if (url[0] == '/')
    {
      /* "/path", "//path", and "///path" */
      int num_leading_slashes = 1;
      if (url[1] == '/')
        {
          num_leading_slashes++;
          if (url[2] == '/')
            num_leading_slashes++;
        }

      /* "//schema-relative" and in some cases "///schema-relative".
         This last format is supported on file:// schema relative. */
      url = apr_pstrcat(scratch_pool,
                        apr_pstrndup(scratch_pool, url, num_leading_slashes),
                        svn_relpath_canonicalize(url + num_leading_slashes,
                                                 scratch_pool),
                        (char*)NULL);
    }
  else
    {
      /* "^/path" and "../path" */
      url = svn_relpath_canonicalize(url, scratch_pool);
    }

  /* Parse the parent directory URL into its parts. */
  status = apr_uri_parse(scratch_pool, parent_dir_url, &parent_dir_uri);
  if (status)
    return svn_error_createf(SVN_ERR_BAD_URL, 0,
                             "Illegal parent directory URL '%s'",
                             parent_dir_url);

  /* If the parent directory URL is at the server root, then the URL
     may have no / after the hostname so apr_uri_parse() will leave
     the URL's path as NULL. */
  if (! parent_dir_uri.path)
    parent_dir_uri.path = apr_pstrmemdup(scratch_pool, "/", 1);
  parent_dir_uri.query = NULL;
  parent_dir_uri.fragment = NULL;

  /* Handle URLs relative to the current directory or to the
     repository root.  The backpaths may only remove path elements,
     not the hostname.  This allows an external to refer to another
     repository in the same server relative to the location of this
     repository, say using SVNParentPath. */
  if ((0 == strncmp("../", url, 3)) ||
      (0 == strncmp("^/", url, 2)))
    {
      apr_array_header_t *base_components;
      apr_array_header_t *relative_components;
      int i;

      /* Decompose either the parent directory's URL path or the
         repository root's URL path into components.  */
      if (0 == strncmp("../", url, 3))
        {
          base_components = svn_path_decompose(parent_dir_uri.path,
                                               scratch_pool);
          relative_components = svn_path_decompose(url, scratch_pool);
        }
      else
        {
          apr_uri_t repos_root_uri;

          status = apr_uri_parse(scratch_pool, repos_root_url,
                                 &repos_root_uri);
          if (status)
            return svn_error_createf(SVN_ERR_BAD_URL, 0,
                                     "Illegal repository root URL '%s'",
                                     repos_root_url);

          /* If the repository root URL is at the server root, then
             the URL may have no / after the hostname so
             apr_uri_parse() will leave the URL's path as NULL. */
          if (! repos_root_uri.path)
            repos_root_uri.path = apr_pstrmemdup(scratch_pool, "/", 1);

          base_components = svn_path_decompose(repos_root_uri.path,
                                               scratch_pool);
          relative_components = svn_path_decompose(url + 2, scratch_pool);
        }

      for (i = 0; i < relative_components->nelts; ++i)
        {
          const char *component = APR_ARRAY_IDX(relative_components,
                                                i,
                                                const char *);
          if (0 == strcmp("..", component))
            {
              /* Constructing the final absolute URL together with
                 apr_uri_unparse() requires that the path be absolute,
                 so only pop a component if the component being popped
                 is not the component for the root directory. */
              if (base_components->nelts > 1)
                apr_array_pop(base_components);
            }
          else
            APR_ARRAY_PUSH(base_components, const char *) = component;
        }

      parent_dir_uri.path = (char *)svn_path_compose(base_components,
                                                     scratch_pool);
      *resolved_url = svn_uri_canonicalize(apr_uri_unparse(scratch_pool,
                                                           &parent_dir_uri, 0),
                                       result_pool);
      return SVN_NO_ERROR;
    }