~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/svnlook/svnlook.c

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2015-08-07 21:32:47 UTC
  • mfrom: (0.2.15) (4.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20150807213247-ozyewtmgsr6tkewl
Tags: 1.9.0-1
* Upload to unstable
* New upstream release.
  + Security fixes
    - CVE-2015-3184: Mixed anonymous/authenticated path-based authz with
      httpd 2.4
    - CVE-2015-3187: svn_repos_trace_node_locations() reveals paths hidden
      by authz
* Add >= 2.7 requirement for python-all-dev Build-Depends, needed to run
  tests.
* Remove Build-Conflicts against ruby-test-unit.  (Closes: #791844)
* Remove patches/apache_module_dependency in favor of expressing the
  dependencies in authz_svn.load/dav_svn.load.
* Build-Depend on apache2-dev (>= 2.4.16) to ensure ap_some_authn_required()
  is available when building mod_authz_svn and Depend on apache2-bin (>=
  2.4.16) for runtime support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
#include "svn_version.h"
55
55
#include "svn_xml.h"
56
56
 
 
57
#include "private/svn_cmdline_private.h"
57
58
#include "private/svn_diff_private.h"
58
 
#include "private/svn_cmdline_private.h"
59
59
#include "private/svn_fspath.h"
60
60
#include "private/svn_io_private.h"
61
 
#include "private/svn_subr_private.h"
 
61
#include "private/svn_sorts_private.h"
62
62
 
63
63
#include "svn_private_config.h"
64
64
 
102
102
    svnlook__ignore_properties,
103
103
    svnlook__properties_only,
104
104
    svnlook__diff_cmd,
105
 
    svnlook__show_inherited_props
 
105
    svnlook__show_inherited_props,
 
106
    svnlook__no_newline
106
107
  };
107
108
 
108
109
/*
143
144
  {"properties-only",   svnlook__properties_only, 0,
144
145
   N_("show only properties during the operation")},
145
146
 
 
147
  {"no-newline",        svnlook__no_newline, 0,
 
148
   N_("do not output the trailing newline")},
 
149
 
146
150
  {"non-recursive",     'N', 0,
147
151
   N_("operate on single directory only")},
148
152
 
187
191
      "                             "
188
192
      "  --ignore-eol-style: Ignore changes in EOL style\n"
189
193
      "                             "
 
194
      "  -U ARG, --context ARG: Show ARG lines of context\n"
 
195
      "                             "
190
196
      "  -p, --show-c-function: Show C function name")},
191
197
 
192
198
  {"quiet",             'q', 0,
300
306
  {"youngest", subcommand_youngest, {0},
301
307
   N_("usage: svnlook youngest REPOS_PATH\n\n"
302
308
      "Print the youngest revision number.\n"),
303
 
   {0} },
 
309
   {svnlook__no_newline} },
304
310
 
305
311
  { NULL, NULL, {0}, NULL, {0} }
306
312
};
333
339
  svn_boolean_t properties_only;    /* --properties-only */
334
340
  const char *diff_cmd;           /* --diff-cmd */
335
341
  svn_boolean_t show_inherited_props; /*  --show-inherited-props */
 
342
  svn_boolean_t no_newline;       /* --no-newline */
336
343
};
337
344
 
338
345
 
804
811
 
805
812
  SVN_ERR(svn_diff__display_prop_diffs(
806
813
            outstream, encoding, propchanges, original_props,
807
 
            FALSE /* pretty_print_mergeinfo */, pool));
 
814
            FALSE /* pretty_print_mergeinfo */,
 
815
            -1 /* context_size */,
 
816
            check_cancel, NULL, pool));
808
817
 
809
818
  return SVN_NO_ERROR;
810
819
}
1058
1067
                    SVN_ERR(generate_label(&orig_label, base_root,
1059
1068
                                           base_path, pool));
1060
1069
                  SVN_ERR(generate_label(&new_label, root, path, pool));
1061
 
                  SVN_ERR(svn_diff_file_output_unified3
1062
 
                          (out_stream, diff, orig_path, new_path,
 
1070
                  SVN_ERR(svn_diff_file_output_unified4(
 
1071
                           out_stream, diff, orig_path, new_path,
1063
1072
                           orig_label, new_label,
1064
1073
                           svn_cmdline_output_encoding(pool), NULL,
1065
 
                           opts->show_c_function, pool));
 
1074
                           opts->show_c_function, opts->context_size,
 
1075
                           check_cancel, NULL, pool));
1066
1076
                  SVN_ERR(svn_stream_printf_from_utf8(out_stream, encoding, pool,
1067
1077
                                                      "\n"));
1068
1078
                  diff_header_printed = TRUE;
1599
1609
    {
1600
1610
      phb->count++;
1601
1611
      if (phb->count >= phb->limit)
1602
 
        /* Not L10N'd, since this error is supressed by the caller. */
 
1612
        /* Not L10N'd, since this error is suppressed by the caller. */
1603
1613
        return svn_error_create(SVN_ERR_CEASE_INVOCATION, NULL,
1604
1614
                                _("History item limit reached"));
1605
1615
    }
1696
1706
       if (path == NULL)
1697
1707
         {
1698
1708
           /* We're operating on a revprop (e.g. c->is_revision). */
1699
 
           err_msg = apr_psprintf(pool,
1700
 
                                  _("Property '%s' not found on revision %ld"),
1701
 
                                  propname, c->rev_id);
 
1709
           if (SVN_IS_VALID_REVNUM(c->rev_id))
 
1710
             err_msg = apr_psprintf(pool,
 
1711
                                    _("Property '%s' not found on revision %ld"),
 
1712
                                    propname, c->rev_id);
 
1713
           else
 
1714
             err_msg = apr_psprintf(pool,
 
1715
                                    _("Property '%s' not found on transaction %s"),
 
1716
                                    propname, c->txn_name);
1702
1717
         }
1703
1718
       else
1704
1719
         {
1761
1776
              else
1762
1777
                {
1763
1778
                  svn_string_t *propval =
1764
 
                    svn__apr_hash_index_val(apr_hash_first(pool,
1765
 
                                                           elt->prop_hash));
 
1779
                    apr_hash_this_val(apr_hash_first(pool, elt->prop_hash));
1766
1780
 
1767
1781
                  SVN_ERR(svn_stream_printf(
1768
1782
                    stdout_stream, pool, "%s - ",
1877
1891
      svn_xml_make_header2(&sb, "UTF-8", pool);
1878
1892
 
1879
1893
      /* "<properties>" */
1880
 
      svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "properties", NULL);
 
1894
      svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "properties",
 
1895
                            SVN_VA_NULL);
1881
1896
    }
1882
1897
 
1883
1898
  if (inherited_props)
1896
1911
              svn_xml_make_open_tag(
1897
1912
                &sb, pool, svn_xml_normal, "target", "path",
1898
1913
                svn_fspath__canonicalize(elt->path_or_url, pool),
1899
 
                NULL);
 
1914
                SVN_VA_NULL);
1900
1915
              SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, elt->prop_hash,
1901
1916
                                                       !verbose, TRUE,
1902
1917
                                                       pool));
1923
1938
              char *revstr = apr_psprintf(pool, "%ld", c->rev_id);
1924
1939
 
1925
1940
              svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops",
1926
 
                                    "rev", revstr, NULL);
 
1941
                                    "rev", revstr, SVN_VA_NULL);
1927
1942
            }
1928
1943
          else
1929
1944
            {
1930
1945
              svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops",
1931
 
                                    "txn", c->txn_name, NULL);
 
1946
                                    "txn", c->txn_name, SVN_VA_NULL);
1932
1947
            }
1933
1948
        }
1934
1949
      else
1935
1950
        {
1936
1951
          /* "<target ...>" */
1937
1952
          svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "target",
1938
 
                                "path", path, NULL);
 
1953
                                "path", path, SVN_VA_NULL);
1939
1954
        }
1940
1955
    }
1941
1956
 
1944
1959
 
1945
1960
  for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi))
1946
1961
    {
1947
 
      const char *pname = svn__apr_hash_index_key(hi);
1948
 
      svn_string_t *propval = svn__apr_hash_index_val(hi);
 
1962
      const char *pname = apr_hash_this_key(hi);
 
1963
      svn_string_t *propval = apr_hash_this_val(hi);
1949
1964
 
1950
1965
      SVN_ERR(check_cancel(NULL));
1951
1966
 
1982
1997
        }
1983
1998
      else if (xml)
1984
1999
        svn_xml_make_open_tag(&sb, pool, svn_xml_self_closing, "property",
1985
 
                              "name", pname, NULL);
 
2000
                              "name", pname, SVN_VA_NULL);
1986
2001
      else
1987
2002
        printf("  %s\n", pname);
1988
2003
    }
2003
2018
      /* "</properties>" */
2004
2019
      svn_xml_make_close_tag(&sb, pool, "properties");
2005
2020
 
 
2021
      errno = 0;
2006
2022
      if (fputs(sb->data, stdout) == EOF)
2007
2023
        {
2008
 
          if (errno)
2009
 
            return svn_error_wrap_apr(errno, _("Write error"));
 
2024
          if (apr_get_os_error()) /* is errno on POSIX */
 
2025
            return svn_error_wrap_apr(apr_get_os_error(), _("Write error"));
2010
2026
          else
2011
2027
            return svn_error_create(SVN_ERR_IO_WRITE_ERROR, NULL, NULL);
2012
2028
        }
2074
2090
{
2075
2091
  svnlook_ctxt_t *baton = apr_pcalloc(pool, sizeof(*baton));
2076
2092
 
2077
 
  SVN_ERR(svn_repos_open2(&(baton->repos), opt_state->repos_path, NULL,
2078
 
                          pool));
 
2093
  SVN_ERR(svn_repos_open3(&(baton->repos), opt_state->repos_path, NULL,
 
2094
                          pool, pool));
2079
2095
  baton->fs = svn_repos_fs(baton->repos);
2080
2096
  svn_fs_set_warning_func(baton->fs, warning_func, NULL);
2081
2097
  baton->show_ids = opt_state->show_ids;
2214
2230
  struct svnlook_opt_state *opt_state = baton;
2215
2231
  const char *header =
2216
2232
    _("general usage: svnlook SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]\n"
 
2233
      "Subversion repository inspection tool.\n"
 
2234
      "Type 'svnlook help <subcommand>' for help on a specific subcommand.\n"
 
2235
      "Type 'svnlook --version' to see the program version and FS modules.\n"
2217
2236
      "Note: any subcommand which takes the '--revision' and '--transaction'\n"
2218
2237
      "      options will, if invoked without one of those options, act on\n"
2219
2238
      "      the repository's youngest revision.\n"
2220
 
      "Type 'svnlook help <subcommand>' for help on a specific subcommand.\n"
2221
 
      "Type 'svnlook --version' to see the program version and FS modules.\n"
2222
2239
      "\n"
2223
2240
      "Available subcommands:\n");
2224
2241
 
2409
2426
  SVN_ERR(check_number_of_args(opt_state, 0));
2410
2427
 
2411
2428
  SVN_ERR(get_ctxt_baton(&c, opt_state, pool));
2412
 
  SVN_ERR(svn_cmdline_printf(pool, "%ld\n", c->rev_id));
 
2429
  SVN_ERR(svn_cmdline_printf(pool, "%ld%s", c->rev_id,
 
2430
                             opt_state->no_newline ? "" : "\n"));
2413
2431
  return SVN_NO_ERROR;
2414
2432
}
2415
2433
 
2433
2451
 
2434
2452
/*** Main. ***/
2435
2453
 
2436
 
int
2437
 
main(int argc, const char *argv[])
 
2454
/*
 
2455
 * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
 
2456
 * either return an error to be displayed, or set *EXIT_CODE to non-zero and
 
2457
 * return SVN_NO_ERROR.
 
2458
 */
 
2459
static svn_error_t *
 
2460
sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
2438
2461
{
2439
2462
  svn_error_t *err;
2440
2463
  apr_status_t apr_err;
2441
 
  apr_pool_t *pool;
2442
2464
 
2443
2465
  const svn_opt_subcommand_desc2_t *subcommand = NULL;
2444
2466
  struct svnlook_opt_state opt_state;
2447
2469
  apr_array_header_t *received_opts;
2448
2470
  int i;
2449
2471
 
2450
 
  /* Initialize the app. */
2451
 
  if (svn_cmdline_init("svnlook", stderr) != EXIT_SUCCESS)
2452
 
    return EXIT_FAILURE;
2453
 
 
2454
 
  /* Create our top-level pool.  Use a separate mutexless allocator,
2455
 
   * given this application is single threaded.
2456
 
   */
2457
 
  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
2458
 
 
2459
2472
  received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
2460
2473
 
2461
2474
  /* Check library versions */
2462
 
  err = check_lib_versions();
2463
 
  if (err)
2464
 
    return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
 
2475
  SVN_ERR(check_lib_versions());
2465
2476
 
2466
2477
  /* Initialize the FS library. */
2467
 
  err = svn_fs_initialize(pool);
2468
 
  if (err)
2469
 
    return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
 
2478
  SVN_ERR(svn_fs_initialize(pool));
2470
2479
 
2471
2480
  if (argc <= 1)
2472
2481
    {
2473
 
      SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
2474
 
      svn_pool_destroy(pool);
2475
 
      return EXIT_FAILURE;
 
2482
      SVN_ERR(subcommand_help(NULL, NULL, pool));
 
2483
      *exit_code = EXIT_FAILURE;
 
2484
      return SVN_NO_ERROR;
2476
2485
    }
2477
2486
 
2478
2487
  /* Initialize opt_state. */
2480
2489
  opt_state.rev = SVN_INVALID_REVNUM;
2481
2490
 
2482
2491
  /* Parse options. */
2483
 
  err = svn_cmdline__getopt_init(&os, argc, argv, pool);
2484
 
  if (err)
2485
 
    return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
 
2492
  SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
2486
2493
 
2487
2494
  os->interleave = 1;
2488
2495
  while (1)
2495
2502
        break;
2496
2503
      else if (apr_err)
2497
2504
        {
2498
 
          SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
2499
 
          svn_pool_destroy(pool);
2500
 
          return EXIT_FAILURE;
 
2505
          SVN_ERR(subcommand_help(NULL, NULL, pool));
 
2506
          *exit_code = EXIT_FAILURE;
 
2507
          return SVN_NO_ERROR;
2501
2508
        }
2502
2509
 
2503
2510
      /* Stash the option code in an array before parsing it. */
2512
2519
            if ((! SVN_IS_VALID_REVNUM(opt_state.rev))
2513
2520
                || (! digits_end)
2514
2521
                || *digits_end)
2515
 
              SVN_INT_ERR(svn_error_create
2516
 
                          (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
2517
 
                           _("Invalid revision number supplied")));
 
2522
              return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
 
2523
                                      _("Invalid revision number supplied"));
2518
2524
          }
2519
2525
          break;
2520
2526
 
2561
2567
            opt_state.limit = strtol(opt_arg, &end, 10);
2562
2568
            if (end == opt_arg || *end != '\0')
2563
2569
              {
2564
 
                err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
2565
 
                                       _("Non-numeric limit argument given"));
2566
 
                return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
 
2570
                return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
 
2571
                                        _("Non-numeric limit argument given"));
2567
2572
              }
2568
2573
            if (opt_state.limit <= 0)
2569
2574
              {
2570
 
                err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
 
2575
                return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
2571
2576
                                    _("Argument to --limit must be positive"));
2572
 
                return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
2573
2577
              }
2574
2578
          }
2575
2579
          break;
2614
2618
          opt_state.show_inherited_props = TRUE;
2615
2619
          break;
2616
2620
 
 
2621
        case svnlook__no_newline:
 
2622
          opt_state.no_newline = TRUE;
 
2623
          break;
 
2624
 
2617
2625
        default:
2618
 
          SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
2619
 
          svn_pool_destroy(pool);
2620
 
          return EXIT_FAILURE;
 
2626
          SVN_ERR(subcommand_help(NULL, NULL, pool));
 
2627
          *exit_code = EXIT_FAILURE;
 
2628
          return SVN_NO_ERROR;
2621
2629
 
2622
2630
        }
2623
2631
    }
2624
2632
 
2625
2633
  /* The --transaction and --revision options may not co-exist. */
2626
2634
  if ((opt_state.rev != SVN_INVALID_REVNUM) && opt_state.txn)
2627
 
    SVN_INT_ERR(svn_error_create
 
2635
    return svn_error_create
2628
2636
                (SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
2629
2637
                 _("The '--transaction' (-t) and '--revision' (-r) arguments "
2630
 
                   "cannot co-exist")));
 
2638
                   "cannot co-exist"));
2631
2639
 
2632
2640
  /* The --show-inherited-props and --revprop options may not co-exist. */
2633
2641
  if (opt_state.show_inherited_props && opt_state.revprop)
2634
 
    SVN_INT_ERR(svn_error_create
 
2642
    return svn_error_create
2635
2643
                (SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
2636
2644
                 _("Cannot use the '--show-inherited-props' option with the "
2637
 
                   "'--revprop' option")));
 
2645
                   "'--revprop' option"));
2638
2646
 
2639
2647
  /* If the user asked for help, then the rest of the arguments are
2640
2648
     the names of subcommands to get help on (if any), or else they're
2665
2673
              svn_error_clear
2666
2674
                (svn_cmdline_fprintf(stderr, pool,
2667
2675
                                     _("Subcommand argument required\n")));
2668
 
              SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
2669
 
              svn_pool_destroy(pool);
2670
 
              return EXIT_FAILURE;
 
2676
              SVN_ERR(subcommand_help(NULL, NULL, pool));
 
2677
              *exit_code = EXIT_FAILURE;
 
2678
              return SVN_NO_ERROR;
2671
2679
            }
2672
2680
        }
2673
2681
      else
2677
2685
          if (subcommand == NULL)
2678
2686
            {
2679
2687
              const char *first_arg_utf8;
2680
 
              err = svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg,
2681
 
                                            pool);
2682
 
              if (err)
2683
 
                return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
 
2688
              SVN_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8, first_arg,
 
2689
                                              pool));
2684
2690
              svn_error_clear(
2685
2691
                svn_cmdline_fprintf(stderr, pool,
2686
2692
                                    _("Unknown subcommand: '%s'\n"),
2687
2693
                                    first_arg_utf8));
2688
 
              SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
 
2694
              SVN_ERR(subcommand_help(NULL, NULL, pool));
2689
2695
 
2690
2696
              /* Be kind to people who try 'svnlook verify'. */
2691
2697
              if (strcmp(first_arg_utf8, "verify") == 0)
2695
2701
                                        _("Try 'svnadmin verify' instead.\n")));
2696
2702
                }
2697
2703
 
2698
 
 
2699
 
              svn_pool_destroy(pool);
2700
 
              return EXIT_FAILURE;
 
2704
              *exit_code = EXIT_FAILURE;
 
2705
              return SVN_NO_ERROR;
2701
2706
            }
2702
2707
        }
2703
2708
    }
2716
2721
      /* Get the repository. */
2717
2722
      if (os->ind < os->argc)
2718
2723
        {
2719
 
          SVN_INT_ERR(svn_utf_cstring_to_utf8(&repos_path,
2720
 
                                              os->argv[os->ind++],
2721
 
                                              pool));
 
2724
          SVN_ERR(svn_utf_cstring_to_utf8(&repos_path,
 
2725
                                          os->argv[os->ind++],
 
2726
                                          pool));
2722
2727
          repos_path = svn_dirent_internal_style(repos_path, pool);
2723
2728
        }
2724
2729
 
2727
2732
          svn_error_clear
2728
2733
            (svn_cmdline_fprintf(stderr, pool,
2729
2734
                                 _("Repository argument required\n")));
2730
 
          SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
2731
 
          svn_pool_destroy(pool);
2732
 
          return EXIT_FAILURE;
 
2735
          SVN_ERR(subcommand_help(NULL, NULL, pool));
 
2736
          *exit_code = EXIT_FAILURE;
 
2737
          return SVN_NO_ERROR;
2733
2738
        }
2734
2739
      else if (svn_path_is_url(repos_path))
2735
2740
        {
2737
2742
            (svn_cmdline_fprintf(stderr, pool,
2738
2743
                                 _("'%s' is a URL when it should be a path\n"),
2739
2744
                                 repos_path));
2740
 
          svn_pool_destroy(pool);
2741
 
          return EXIT_FAILURE;
 
2745
          *exit_code = EXIT_FAILURE;
 
2746
          return SVN_NO_ERROR;
2742
2747
        }
2743
2748
 
2744
2749
      opt_state.repos_path = repos_path;
2746
2751
      /* Get next arg (arg1), if any. */
2747
2752
      if (os->ind < os->argc)
2748
2753
        {
2749
 
          SVN_INT_ERR(svn_utf_cstring_to_utf8
2750
 
                      (&arg1, os->argv[os->ind++], pool));
 
2754
          SVN_ERR(svn_utf_cstring_to_utf8(&arg1, os->argv[os->ind++], pool));
2751
2755
          arg1 = svn_dirent_internal_style(arg1, pool);
2752
2756
        }
2753
2757
      opt_state.arg1 = arg1;
2755
2759
      /* Get next arg (arg2), if any. */
2756
2760
      if (os->ind < os->argc)
2757
2761
        {
2758
 
          SVN_INT_ERR(svn_utf_cstring_to_utf8
2759
 
                      (&arg2, os->argv[os->ind++], pool));
 
2762
          SVN_ERR(svn_utf_cstring_to_utf8(&arg2, os->argv[os->ind++], pool));
2760
2763
          arg2 = svn_dirent_internal_style(arg2, pool);
2761
2764
        }
2762
2765
      opt_state.arg2 = arg2;
2782
2785
                                          pool);
2783
2786
          svn_opt_format_option(&optstr, badopt, FALSE, pool);
2784
2787
          if (subcommand->name[0] == '-')
2785
 
            SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
 
2788
            SVN_ERR(subcommand_help(NULL, NULL, pool));
2786
2789
          else
2787
2790
            svn_error_clear
2788
2791
              (svn_cmdline_fprintf
2790
2793
                _("Subcommand '%s' doesn't accept option '%s'\n"
2791
2794
                  "Type 'svnlook help %s' for usage.\n"),
2792
2795
                subcommand->name, optstr, subcommand->name));
2793
 
          svn_pool_destroy(pool);
2794
 
          return EXIT_FAILURE;
 
2796
          *exit_code = EXIT_FAILURE;
 
2797
          return SVN_NO_ERROR;
2795
2798
        }
2796
2799
    }
2797
2800
 
2832
2835
          err = svn_error_quick_wrap(err,
2833
2836
                                     _("Try 'svnlook help' for more info"));
2834
2837
        }
2835
 
      return svn_cmdline_handle_exit_error(err, pool, "svnlook: ");
 
2838
      return err;
2836
2839
    }
2837
 
  else
 
2840
 
 
2841
  return SVN_NO_ERROR;
 
2842
}
 
2843
 
 
2844
int
 
2845
main(int argc, const char *argv[])
 
2846
{
 
2847
  apr_pool_t *pool;
 
2848
  int exit_code = EXIT_SUCCESS;
 
2849
  svn_error_t *err;
 
2850
 
 
2851
  /* Initialize the app. */
 
2852
  if (svn_cmdline_init("svnlook", stderr) != EXIT_SUCCESS)
 
2853
    return EXIT_FAILURE;
 
2854
 
 
2855
  /* Create our top-level pool.  Use a separate mutexless allocator,
 
2856
   * given this application is single threaded.
 
2857
   */
 
2858
  pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
 
2859
 
 
2860
  err = sub_main(&exit_code, argc, argv, pool);
 
2861
 
 
2862
  /* Flush stdout and report if it fails. It would be flushed on exit anyway
 
2863
     but this makes sure that output is not silently lost if it fails. */
 
2864
  err = svn_error_compose_create(err, svn_cmdline_fflush(stdout));
 
2865
 
 
2866
  if (err)
2838
2867
    {
2839
 
      svn_pool_destroy(pool);
2840
 
      /* Ensure everything is printed on stdout, so the user sees any
2841
 
         print errors. */
2842
 
      SVN_INT_ERR(svn_cmdline_fflush(stdout));
2843
 
      return EXIT_SUCCESS;
 
2868
      exit_code = EXIT_FAILURE;
 
2869
      svn_cmdline_handle_exit_error(err, NULL, "svnlook: ");
2844
2870
    }
 
2871
 
 
2872
  svn_pool_destroy(pool);
 
2873
  return exit_code;
2845
2874
}