コード例 #1
0
ファイル: cmdline.c プロジェクト: DJEX93/dsploit
/* Note: This is substantially copied from svn_opt__args_to_target_array() in
 * order to move to libsvn_client while maintaining backward compatibility. */
svn_error_t *
svn_client_args_to_target_array2(apr_array_header_t **targets_p,
                                 apr_getopt_t *os,
                                 const apr_array_header_t *known_targets,
                                 svn_client_ctx_t *ctx,
                                 svn_boolean_t keep_last_origpath_on_truepath_collision,
                                 apr_pool_t *pool)
{
  int i;
  svn_boolean_t rel_url_found = FALSE;
  const char *root_url = NULL;
  svn_error_t *err = SVN_NO_ERROR;
  apr_array_header_t *input_targets =
    apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *));
  apr_array_header_t *output_targets =
    apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *));
  apr_array_header_t *reserved_names = NULL;

  /* Step 1:  create a master array of targets that are in UTF-8
     encoding, and come from concatenating the targets left by apr_getopt,
     plus any extra targets (e.g., from the --targets switch.)
     If any of the targets are relative urls, then set the rel_url_found
     flag.*/

  for (; os->ind < os->argc; os->ind++)
    {
      /* The apr_getopt targets are still in native encoding. */
      const char *raw_target = os->argv[os->ind];
      const char *utf8_target;

      SVN_ERR(svn_utf_cstring_to_utf8(&utf8_target,
                                      raw_target, pool));

      if (arg_is_repos_relative_url(utf8_target))
        rel_url_found = TRUE;

      APR_ARRAY_PUSH(input_targets, const char *) = utf8_target;
    }

  if (known_targets)
    {
      for (i = 0; i < known_targets->nelts; i++)
        {
          /* The --targets array have already been converted to UTF-8,
             because we needed to split up the list with svn_cstring_split. */
          const char *utf8_target = APR_ARRAY_IDX(known_targets,
                                                  i, const char *);

          if (arg_is_repos_relative_url(utf8_target))
            rel_url_found = TRUE;

          APR_ARRAY_PUSH(input_targets, const char *) = utf8_target;
        }
    }

  /* Step 2:  process each target.  */

  for (i = 0; i < input_targets->nelts; i++)
    {
      const char *utf8_target = APR_ARRAY_IDX(input_targets, i, const char *);

      /* Relative urls will be canonicalized when they are resolved later in
       * the function
       */
      if (arg_is_repos_relative_url(utf8_target))
        {
          APR_ARRAY_PUSH(output_targets, const char *) = utf8_target;
        }
      else
        {
          const char *true_target;
          const char *peg_rev;
          const char *target;

          /*
           * This is needed so that the target can be properly canonicalized,
           * otherwise the canonicalization does not treat a ".@BASE" as a "."
           * with a BASE peg revision, and it is not canonicalized to "@BASE".
           * If any peg revision exists, it is appended to the final
           * canonicalized path or URL.  Do not use svn_opt_parse_path()
           * because the resulting peg revision is a structure that would have
           * to be converted back into a string.  Converting from a string date
           * to the apr_time_t field in the svn_opt_revision_value_t and back to
           * a string would not necessarily preserve the exact bytes of the
           * input date, so its easier just to keep it in string form.
           */
          SVN_ERR(svn_opt__split_arg_at_peg_revision(&true_target, &peg_rev,
                                                     utf8_target, pool));

          /* URLs and wc-paths get treated differently. */
          if (svn_path_is_url(true_target))
            {
              SVN_ERR(svn_opt__arg_canonicalize_url(&true_target,
                                                    true_target, pool));
            }
          else  /* not a url, so treat as a path */
            {
              const char *base_name;
              const char *original_target;

              original_target = svn_dirent_internal_style(true_target, pool);
              SVN_ERR(svn_opt__arg_canonicalize_path(&true_target,
                                                     true_target, pool));

              /* There are two situations in which a 'truepath-conversion'
                 (case-canonicalization to on-disk path on case-insensitive
                 filesystem) needs to be undone:

                 1. If KEEP_LAST_ORIGPATH_ON_TRUEPATH_COLLISION is TRUE, and
                    this is the last target of a 2-element target list, and
                    both targets have the same truepath. */
              if (keep_last_origpath_on_truepath_collision
                  && input_targets->nelts == 2 && i == 1
                  && strcmp(original_target, true_target) != 0)
                {
                  const char *src_truepath = APR_ARRAY_IDX(output_targets,
                                                           0,
                                                           const char *);
                  if (strcmp(src_truepath, true_target) == 0)
                    true_target = original_target;
                }

              /* 2. If there is an exact match in the wc-db without a
                    corresponding on-disk path (e.g. a scheduled-for-delete
                    file only differing in case from an on-disk file). */
              if (strcmp(original_target, true_target) != 0)
                {
                  const char *target_abspath;
                  svn_node_kind_t kind;
                  svn_error_t *err2;

                  SVN_ERR(svn_dirent_get_absolute(&target_abspath,
                                                  original_target, pool));
                  err2 = svn_wc_read_kind(&kind, ctx->wc_ctx, target_abspath,
                                          FALSE, pool);
                  if (err2
                      && (err2->apr_err == SVN_ERR_WC_NOT_WORKING_COPY
                          || err2->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED))
                    {
                      svn_error_clear(err2);
                    }
                  else
                    {
                      SVN_ERR(err2);
                      /* We successfully did a lookup in the wc-db. Now see
                         if it's something interesting. */
                      if (kind == svn_node_file || kind == svn_node_dir)
                        true_target = original_target;
                    }
                }

              /* If the target has the same name as a Subversion
                 working copy administrative dir, skip it. */
              base_name = svn_dirent_basename(true_target, pool);

              if (svn_wc_is_adm_dir(base_name, pool))
                {
                  if (!reserved_names)
                    reserved_names = apr_array_make(pool, DEFAULT_ARRAY_SIZE,
                                                    sizeof(const char *));

                  APR_ARRAY_PUSH(reserved_names, const char *) = utf8_target;

                  continue;
                }
            }

          target = apr_pstrcat(pool, true_target, peg_rev, (char *)NULL);

          if (rel_url_found)
            {
              /* Later targets have priority over earlier target, I
                 don't know why, see basic_relative_url_multi_repo. */
              SVN_ERR(check_root_url_of_target(&root_url, target,
                                               ctx, pool));
            }

          APR_ARRAY_PUSH(output_targets, const char *) = target;
        }
    }

  /* Only resolve relative urls if there were some actually found earlier. */
  if (rel_url_found)
    {
      /*
       * Use the current directory's root url if one wasn't found using the
       * arguments.
       */
      if (root_url == NULL)
        {
          err = svn_client_root_url_from_path(&root_url, "", ctx, pool);
          if (err || root_url == NULL)
            return svn_error_create(SVN_ERR_WC_NOT_WORKING_COPY, err,
                                    _("Resolving '^/': no repository root "
                                      "found in the target arguments or "
                                      "in the current directory"));
        }

      *targets_p = apr_array_make(pool, output_targets->nelts,
                                  sizeof(const char *));

      for (i = 0; i < output_targets->nelts; i++)
        {
          const char *target = APR_ARRAY_IDX(output_targets, i,
                                             const char *);

          if (arg_is_repos_relative_url(target))
            {
              const char *abs_target;
              const char *true_target;
              const char *peg_rev;

              SVN_ERR(svn_opt__split_arg_at_peg_revision(&true_target, &peg_rev,
                                                         target, pool));

              SVN_ERR(resolve_repos_relative_url(&abs_target, true_target,
                                                 root_url, pool));

              SVN_ERR(svn_opt__arg_canonicalize_url(&true_target, abs_target,
                                                    pool));

              target = apr_pstrcat(pool, true_target, peg_rev, (char *)NULL);
            }

          APR_ARRAY_PUSH(*targets_p, const char *) = target;
        }
    }
  else
コード例 #2
0
ファイル: opt.c プロジェクト: ChaosJohn/freebsd
/* Note: This is substantially copied into svn_client_args_to_target_array() in
 * order to move to libsvn_client while maintaining backward compatibility. */
svn_error_t *
svn_opt__args_to_target_array(apr_array_header_t **targets_p,
                              apr_getopt_t *os,
                              const apr_array_header_t *known_targets,
                              apr_pool_t *pool)
{
  int i;
  svn_error_t *err = SVN_NO_ERROR;
  apr_array_header_t *input_targets =
    apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *));
  apr_array_header_t *output_targets =
    apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *));

  /* Step 1:  create a master array of targets that are in UTF-8
     encoding, and come from concatenating the targets left by apr_getopt,
     plus any extra targets (e.g., from the --targets switch.) */

  for (; os->ind < os->argc; os->ind++)
    {
      /* The apr_getopt targets are still in native encoding. */
      const char *raw_target = os->argv[os->ind];
      SVN_ERR(svn_utf_cstring_to_utf8
              ((const char **) apr_array_push(input_targets),
               raw_target, pool));
    }

  if (known_targets)
    {
      for (i = 0; i < known_targets->nelts; i++)
        {
          /* The --targets array have already been converted to UTF-8,
             because we needed to split up the list with svn_cstring_split. */
          const char *utf8_target = APR_ARRAY_IDX(known_targets,
                                                  i, const char *);
          APR_ARRAY_PUSH(input_targets, const char *) = utf8_target;
        }
    }

  /* Step 2:  process each target.  */

  for (i = 0; i < input_targets->nelts; i++)
    {
      const char *utf8_target = APR_ARRAY_IDX(input_targets, i, const char *);
      const char *true_target;
      const char *target;      /* after all processing is finished */
      const char *peg_rev;

      /*
       * This is needed so that the target can be properly canonicalized,
       * otherwise the canonicalization does not treat a ".@BASE" as a "."
       * with a BASE peg revision, and it is not canonicalized to "@BASE".
       * If any peg revision exists, it is appended to the final
       * canonicalized path or URL.  Do not use svn_opt_parse_path()
       * because the resulting peg revision is a structure that would have
       * to be converted back into a string.  Converting from a string date
       * to the apr_time_t field in the svn_opt_revision_value_t and back to
       * a string would not necessarily preserve the exact bytes of the
       * input date, so its easier just to keep it in string form.
       */
      SVN_ERR(svn_opt__split_arg_at_peg_revision(&true_target, &peg_rev,
                                                 utf8_target, pool));

      /* URLs and wc-paths get treated differently. */
      if (svn_path_is_url(true_target))
        {
          SVN_ERR(svn_opt__arg_canonicalize_url(&true_target, true_target,
                                                 pool));
        }
      else  /* not a url, so treat as a path */
        {
          const char *base_name;

          SVN_ERR(svn_opt__arg_canonicalize_path(&true_target, true_target,
                                                 pool));

          /* If the target has the same name as a Subversion
             working copy administrative dir, skip it. */
          base_name = svn_dirent_basename(true_target, pool);

          /* FIXME:
             The canonical list of administrative directory names is
             maintained in libsvn_wc/adm_files.c:svn_wc_set_adm_dir().
             That list can't be used here, because that use would
             create a circular dependency between libsvn_wc and
             libsvn_subr.  Make sure changes to the lists are always
             synchronized! */
          if (0 == strcmp(base_name, ".svn")
              || 0 == strcmp(base_name, "_svn"))
            {
              err = svn_error_createf(SVN_ERR_RESERVED_FILENAME_SPECIFIED,
                                      err, _("'%s' ends in a reserved name"),
                                      utf8_target);
              continue;
            }
        }

      target = apr_pstrcat(pool, true_target, peg_rev, (char *)NULL);

      APR_ARRAY_PUSH(output_targets, const char *) = target;
    }


  /* kff todo: need to remove redundancies from targets before
     passing it to the cmd_func. */

  *targets_p = output_targets;

  return err;
}
コード例 #3
0
ファイル: svnversion.c プロジェクト: svn2github/subversion
/*
 * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
 * either return an error to be displayed, or set *EXIT_CODE to non-zero and
 * return SVN_NO_ERROR.
 *
 * Why is this not an svn subcommand?  I have this vague idea that it could
 * be run as part of the build process, with the output embedded in the svn
 * program.  Obviously we don't want to have to run svn when building svn.
 */
static svn_error_t *
sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
{
  const char *wc_path, *trail_url;
  const char *local_abspath;
  svn_wc_revision_status_t *res;
  svn_boolean_t no_newline = FALSE, committed = FALSE;
  svn_error_t *err;
  apr_getopt_t *os;
  svn_wc_context_t *wc_ctx;
  svn_boolean_t quiet = FALSE;
  svn_boolean_t is_version = FALSE;
  const apr_getopt_option_t options[] =
    {
      {"no-newline", 'n', 0, N_("do not output the trailing newline")},
      {"committed",  'c', 0, N_("last changed rather than current revisions")},
      {"help", 'h', 0, N_("display this help")},
      {"version", SVNVERSION_OPT_VERSION, 0,
       N_("show program version information")},
      {"quiet",         'q', 0,
       N_("no progress (only errors) to stderr")},
      {0,             0,  0,  0}
    };

  /* Check library versions */
  SVN_ERR(check_lib_versions());

#if defined(WIN32) || defined(__CYGWIN__)
  /* Set the working copy administrative directory name. */
  if (getenv("SVN_ASP_DOT_NET_HACK"))
    {
      SVN_ERR(svn_wc_set_adm_dir("_svn", pool));
    }
#endif

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

  os->interleave = 1;
  while (1)
    {
      int opt;
      const char *arg;
      apr_status_t status = apr_getopt_long(os, options, &opt, &arg);
      if (APR_STATUS_IS_EOF(status))
        break;
      if (status != APR_SUCCESS)
        {
          *exit_code = EXIT_FAILURE;
          usage(pool);
          return SVN_NO_ERROR;
        }

      switch (opt)
        {
        case 'n':
          no_newline = TRUE;
          break;
        case 'c':
          committed = TRUE;
          break;
        case 'q':
          quiet = TRUE;
          break;
        case 'h':
          help(options, pool);
          return SVN_NO_ERROR;
        case SVNVERSION_OPT_VERSION:
          is_version = TRUE;
          break;
        default:
          *exit_code = EXIT_FAILURE;
          usage(pool);
          return SVN_NO_ERROR;
        }
    }

  if (is_version)
    {
      SVN_ERR(version(quiet, pool));
      return SVN_NO_ERROR;
    }
  if (os->ind > argc || os->ind < argc - 2)
    {
      *exit_code = EXIT_FAILURE;
      usage(pool);
      return SVN_NO_ERROR;
    }

  SVN_ERR(svn_utf_cstring_to_utf8(&wc_path,
                                  (os->ind < argc) ? os->argv[os->ind] : ".",
                                  pool));

  SVN_ERR(svn_opt__arg_canonicalize_path(&wc_path, wc_path, pool));
  SVN_ERR(svn_dirent_get_absolute(&local_abspath, wc_path, pool));
  SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));

  if (os->ind+1 < argc)
    SVN_ERR(svn_utf_cstring_to_utf8(&trail_url, os->argv[os->ind+1], pool));
  else
    trail_url = NULL;

  err = svn_wc_revision_status2(&res, wc_ctx, local_abspath, trail_url,
                                committed, NULL, NULL, pool, pool);

  if (err && (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND
              || err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY))
    {
      svn_node_kind_t kind;
      svn_boolean_t special;

      svn_error_clear(err);

      SVN_ERR(svn_io_check_special_path(local_abspath, &kind, &special, pool));

      if (special)
        SVN_ERR(svn_cmdline_printf(pool, _("Unversioned symlink%s"),
                                   no_newline ? "" : "\n"));
      else if (kind == svn_node_dir)
        SVN_ERR(svn_cmdline_printf(pool, _("Unversioned directory%s"),
                                   no_newline ? "" : "\n"));
      else if (kind == svn_node_file)
        SVN_ERR(svn_cmdline_printf(pool, _("Unversioned file%s"),
                                   no_newline ? "" : "\n"));
      else
        {
          SVN_ERR(svn_cmdline_fprintf(stderr, pool,
                                      kind == svn_node_none
                                       ? _("'%s' doesn't exist\n")
                                       : _("'%s' is of unknown type\n"),
                                      svn_dirent_local_style(local_abspath,
                                                             pool)));
          *exit_code = EXIT_FAILURE;
          return SVN_NO_ERROR;
        }
      return SVN_NO_ERROR;
    }

  SVN_ERR(err);

  if (! SVN_IS_VALID_REVNUM(res->min_rev))
    {
      /* Local uncommitted modifications, no revision info was found. */
      SVN_ERR(svn_cmdline_printf(pool, _("Uncommitted local addition, "
                                         "copy or move%s"),
                                 no_newline ? "" : "\n"));
      return SVN_NO_ERROR;
    }

  /* Build compact '123[:456]M?S?' string. */
  SVN_ERR(svn_cmdline_printf(pool, "%ld", res->min_rev));
  if (res->min_rev != res->max_rev)
    SVN_ERR(svn_cmdline_printf(pool, ":%ld", res->max_rev));
  if (res->modified)
    SVN_ERR(svn_cmdline_fputs("M", stdout, pool));
  if (res->switched)
    SVN_ERR(svn_cmdline_fputs("S", stdout, pool));
  if (res->sparse_checkout)
    SVN_ERR(svn_cmdline_fputs("P", stdout, pool));

  if (! no_newline)
    SVN_ERR(svn_cmdline_fputs("\n", stdout, pool));

  return SVN_NO_ERROR;
}