00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <unistd.h>
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <getopt.h>
00013 #include <sys/time.h>
00014 #include <time.h>
00015 #include <stdarg.h>
00016 #include <langinfo.h>
00017 #include <locale.h>
00018
00019 #include <apr_pools.h>
00020
00021 #include <subversion-1/svn_error.h>
00022
00023 #include "global.h"
00024 #include "interface.h"
00025 #include "ignore.h"
00026 #include "checksum.h"
00027 #include "helper.h"
00028 #include "waa.h"
00029 #include "options.h"
00030 #include "cp_mv.h"
00031 #include "status.h"
00032 #include "url.h"
00033 #include "warnings.h"
00034 #include "options.h"
00035 #include "actions.h"
00036 #include "racallback.h"
00037
00314 char parm_dump[]="dump",
00315 parm_test[]="test",
00316 parm_load[]="load";
00317
00318
00319 int debuglevel=0,
00321 opt_recursive=1;
00322
00323 svn_revnum_t target_revision;
00324 svn_revnum_t opt_target_revision=SVN_INVALID_REVNUM;
00325 svn_revnum_t opt_target_revision2=SVN_INVALID_REVNUM;
00326 int opt_target_revisions_given=0;
00327
00328 char *opt_commitmsg,
00329 *opt_debugprefix,
00330 *opt_commitmsgfile;
00331
00338 int make_STOP_silent=0;
00339
00341 static char *program_name;
00343 char *start_path=NULL;
00345 int start_path_len=0;
00346
00347 #ifdef HAVE_LOCALES
00348 char *local_codeset;
00349 #endif
00350
00351 apr_pool_t *global_pool;
00352
00353 struct url_t *current_url;
00354
00355
00356 char **environ=NULL;
00357
00358
00366 void _DEBUGP_open_output(FILE **output, int *was_popened)
00367 {
00368 const char *fn;
00369 FILE *tmp;
00370
00371
00372 *output=stdout;
00373 *was_popened=0;
00374
00375 fn=opt__get_string(OPT__DEBUG_OUTPUT);
00376 if (fn)
00377 {
00378 *was_popened= (fn[0] == '|');
00379 if (*was_popened)
00380 tmp=popen(fn+1, "w");
00381 else
00382 tmp=fopen(fn, "w");
00383
00384 if (tmp) *output=tmp;
00385 else DEBUGP("'%s' cannot be opened: %d=%s",
00386 opt__get_string(OPT__DEBUG_OUTPUT),
00387 errno, strerror(errno));
00388 }
00389 }
00390
00393 #define MAX_DEBUG_LINE_LEN (1024)
00394
00400 void _DEBUGP(const char *file, int line,
00401 const char *func,
00402 char *format, ...)
00403 {
00404 static struct timeval tv;
00405 static struct timezone tz;
00406 struct tm *tm;
00407 va_list va;
00408 static FILE *debug_out=NULL;
00409 static int was_popened=0;
00410 int ms;
00411 const char *fn;
00412 static char *buffer_start=NULL;
00413 static int did_wrap=0;
00414 FILE *real_out;
00415 long mem_pos;
00416
00417
00418 if (!file)
00419 {
00420 if (line && opt__get_int(OPT__DEBUG_BUFFER) && debug_out)
00421 {
00422
00423 _DEBUGP_open_output(&real_out, &was_popened);
00424
00425 mem_pos=ftell(debug_out);
00426 if (mem_pos>=0 && did_wrap)
00427 {
00428 buffer_start[mem_pos]=0;
00429
00430
00431 fn=strchr(buffer_start+mem_pos,'\n');
00432 if (fn)
00433 fputs(fn+1, real_out);
00434 }
00435 fputs(buffer_start, real_out);
00436
00437
00438 fclose(debug_out);
00439
00440 debug_out=real_out;
00441 }
00442
00443 if (debug_out)
00444 {
00445 if (was_popened)
00446 pclose(debug_out);
00447 else
00448 if (debug_out != stdout)
00449 fclose(debug_out);
00450 debug_out=NULL;
00451 }
00452 return;
00453 }
00454
00455 if (!debuglevel) return;
00456
00457
00458 if (opt_debugprefix &&
00459 strncmp(opt_debugprefix, func, strlen(opt_debugprefix)))
00460 return;
00461
00462 if (!debug_out)
00463 {
00464
00465 debug_out=stdout;
00466
00467 if (opt__get_int(OPT__DEBUG_BUFFER))
00468 {
00469 buffer_start=malloc(opt__get_int(OPT__DEBUG_BUFFER));
00470 if (buffer_start)
00471 debug_out=fmemopen(buffer_start,
00472 opt__get_int(OPT__DEBUG_BUFFER), "w+");
00473
00474 if (buffer_start && debug_out)
00475 {
00476 DEBUGP("using a buffer of %d bytes.", opt__get_int(OPT__DEBUG_BUFFER));
00477 }
00478 else
00479 {
00480 opt__set_int(OPT__DEBUG_BUFFER, PRIO_MUSTHAVE, 0);
00481 debug_out=stdout;
00482 DEBUGP("cannot use memory buffer for debug");
00483 }
00484 }
00485 else
00486 {
00487 _DEBUGP_open_output(&debug_out, &was_popened);
00488 }
00489 }
00490
00491 gettimeofday(&tv, &tz);
00492 tm=localtime(&tv.tv_sec);
00493
00494
00495 ms=tv.tv_usec/1000;
00496
00497
00498 if (opt__get_int(OPT__DEBUG_BUFFER))
00499 {
00500
00501 mem_pos=ftell(debug_out);
00502 if (mem_pos+MAX_DEBUG_LINE_LEN >= opt__get_int(OPT__DEBUG_BUFFER))
00503 {
00504
00505 fseek(debug_out, 0, SEEK_SET);
00506 did_wrap++;
00507 }
00508 }
00509
00510 fprintf(debug_out, "%02d:%02d:%02d.%03d %s[%s:%d] ",
00511 tm->tm_hour, tm->tm_min, tm->tm_sec, ms,
00512 func,
00513 file, line);
00514
00515 va_start(va, format);
00516 vfprintf(debug_out, format, va);
00517
00518 fputc('\n', debug_out);
00519 fflush(debug_out);
00520 }
00521
00522
00537 int _STOP(const char *file, int line, const char *function,
00538 int errl, const char *format, ...)
00539 {
00540 static int already_stopping=0;
00541 static int error_number;
00542 int is_usererror;
00543 struct timeval tv;
00544 struct timezone tz;
00545 struct tm *tm;
00546 va_list va;
00547 FILE *stop_out=stderr;
00548 char errormsg[256];
00549
00550
00551 if (make_STOP_silent) return errl;
00552 if (errl==-EPIPE) return errl;
00553
00554 is_usererror= format && *format == '!';
00555 if (is_usererror) format++;
00556
00557
00558
00559 if ( (already_stopping || !format) &&
00560 !(opt__get_int(OPT__VERBOSE) & VERBOSITY_STACKTRACE))
00561 return error_number;
00562
00563 if (! (already_stopping++))
00564 {
00565
00566 fflush(NULL);
00567
00568 if (is_usererror)
00569 {
00570 va_start(va, format);
00571 vfprintf(stop_out, format, va);
00572 if (!(debuglevel || opt__is_verbose()>0))
00573 goto eol;
00574 }
00575
00576
00577 fputs("\n\nAn error occurred", stop_out);
00578
00579 if (debuglevel || opt__is_verbose()>0)
00580 {
00581 gettimeofday(&tv, &tz);
00582 tm=localtime(&tv.tv_sec);
00583 fprintf(stop_out, " at %02d:%02d:%02d.%03d",
00584 tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec+500)/1000);
00585 }
00586
00587 errormsg[0]=0;
00588 svn_strerror (errl, errormsg, sizeof(errormsg));
00589 fprintf(stop_out, ": %s (%d)\n",
00590 errormsg[0] ? errormsg : strerror(abs(errl)), errl);
00591 }
00592
00593
00594 fputs(" in ", stop_out);
00595 fputs(function, stop_out);
00596 if (debuglevel)
00597 fprintf(stop_out, " [%s:%d]", file, line);
00598
00599 if (format)
00600 {
00601 fputs(": ", stop_out);
00602
00603 va_start(va, format);
00604 vfprintf(stop_out, format, va);
00605 }
00606
00607 eol:
00608 fputc('\n', stop_out);
00609 fflush(stop_out);
00610
00611 error_number=errl;
00612 already_stopping=1;
00613 return errl;
00614 }
00615
00616
00617 #define _STRINGIFY(x) #x
00618 #define STRINGIFY(x) " " #x "=" _STRINGIFY(x)
00619
00621 const char* Version(FILE *output)
00622 {
00623 static const char Id[] ="$Id: fsvs.c 3526 2009-05-27 06:16:14Z flip $";
00624
00625 fprintf(output, "FSVS (licensed under the GPLv3), (C) by Ph. Marek;"
00626 " version " FSVS_VERSION "\n");
00627 if (opt__is_verbose()>0)
00628 {
00629 fprintf(output, "compiled on " __DATE__ " " __TIME__
00630 ", with options:\n\t"
00631 #ifdef HAVE_VALGRIND
00632 STRINGIFY(HAVE_VALGRIND)
00633 #endif
00634 #ifdef HAVE_VALGRIND_VALGRIND_H
00635 STRINGIFY(HAVE_VALGRIND_VALGRIND_H)
00636 #endif
00637 #ifdef ENABLE_DEBUG
00638 STRINGIFY(ENABLE_DEBUG)
00639 #endif
00640 #ifdef ENABLE_GCOV
00641 STRINGIFY(ENABLE_GCOV)
00642 #endif
00643 #ifdef ENABLE_RELEASE
00644 STRINGIFY(ENABLE_RELEASE)
00645 #endif
00646 #ifdef HAVE_LOCALES
00647 STRINGIFY(HAVE_LOCALES)
00648 #endif
00649 #ifdef HAVE_UINT32_T
00650 STRINGIFY(HAVE_UINT32_T)
00651 #endif
00652 #ifdef AC_CV_C_UINT32_T
00653 STRINGIFY(AC_CV_C_UINT32_T)
00654 #endif
00655 #ifdef HAVE_LINUX_TYPES_H
00656 STRINGIFY(HAVE_LINUX_TYPES_H)
00657 #endif
00658 #ifdef HAVE_LINUX_UNISTD_H
00659 STRINGIFY(HAVE_LINUX_UNISTD_H)
00660 #endif
00661 #ifdef HAVE_DIRFD
00662 STRINGIFY(HAVE_DIRFD)
00663 #endif
00664 #ifdef HAVE_STRUCT_STAT_ST_MTIM
00665 STRINGIFY(HAVE_STRUCT_STAT_ST_MTIM)
00666 #endif
00667 #ifdef CHROOTER_JAIL
00668 STRINGIFY(CHROOTER_JAIL)
00669 #endif
00670 #ifdef HAVE_COMPARISON_FN_T
00671 STRINGIFY(HAVE_COMPARISON_FN_T)
00672 #endif
00673 #ifdef HAVE_O_DIRECTORY
00674 STRINGIFY(HAVE_O_DIRECTORY)
00675 #endif
00676 #ifdef O_DIRECTORY
00677 STRINGIFY(O_DIRECTORY)
00678 #endif
00679 #ifdef HAVE_LINUX_KDEV_T_H
00680 STRINGIFY(HAVE_LINUX_KDEV_T_H)
00681 #endif
00682 #ifdef ENABLE_DEV_FAKE
00683 STRINGIFY(ENABLE_DEV_FAKE)
00684 #endif
00685 #ifdef DEVICE_NODES_DISABLED
00686 STRINGIFY(DEVICE_NODES_DISABLED)
00687 #endif
00688 #ifdef HAVE_STRSEP
00689 STRINGIFY(HAVE_STRSEP)
00690 #endif
00691 #ifdef HAVE_LUTIMES
00692 STRINGIFY(HAVE_LUTIMES)
00693 #endif
00694 #ifdef HAVE_LCHOWN
00695 STRINGIFY(HAVE_LCHOWN)
00696 #endif
00697 #ifdef WAA_WC_MD5_CHARS
00698 STRINGIFY(WAA_WC_MD5_CHARS)
00699 #endif
00700 STRINGIFY(NAME_MAX)
00701 "\n");
00702 }
00703 return Id;
00704 }
00705
00706
00722 int ac__Usage(struct estat *root UNUSED,
00723 int argc UNUSED, char *argv[])
00724 {
00725 int status;
00726 int i, hpos, len;
00727 char const* const*names;
00728
00729
00730 status=0;
00731 Version(stdout);
00732
00733
00734 if (argv && *argv)
00735 {
00736 STOPIF( act__find_action_by_name(*argv, &action), NULL);
00737 printf("\n"
00738 "Help for command \"%s\".\n", action->name[0]);
00739 names=action->name+1;
00740 if (*names)
00741 {
00742 printf("Aliases: ");
00743 while (*names)
00744 {
00745 printf("%s%s",
00746 names[0],
00747 names[1] ? ", " : "\n");
00748 names++;
00749 }
00750 }
00751
00752 puts("");
00753
00754 puts(action->help_text);
00755 }
00756 else
00757 {
00758
00759 printf(
00760 "\n"
00761 "Known commands:\n"
00762 "\n ");
00763 hpos=2;
00764 for(i=0; i<action_list_count; i++)
00765 {
00766 len = strlen(action_list[i].name[0]);
00767
00768
00769 if (hpos+2+len >= 75)
00770 {
00771 printf("\n ");
00772 hpos=2;
00773 }
00774
00775 printf("%s%s", action_list[i].name[0],
00776 i+1 == action_list_count ? "\n" : ", ");
00777 hpos += 2 + len;
00778 }
00779
00780 puts(
00781 "\n"
00782 "Parameters:\n"
00783 "\n"
00784 "-v increase verbosity\n"
00785 "-q decrease verbosity (quiet)\n"
00786 "\n"
00787 "-C checksum possibly changed files;\n"
00788 " if given twice checksum *all* files.\n"
00789 "\n"
00790 "-V show version\n"
00791 "\n"
00792 "Environment variables:\n"
00793 "\n"
00794 "$FSVS_CONF defines the location of the FSVS Configuration area\n"
00795 " Default is " DEFAULT_CONF_PATH ", but any writeable directory is allowed.\n"
00796 "$FSVS_WAA defines the location of the Working copy Administrative Area\n"
00797 " Default is " DEFAULT_WAA_PATH ", but any writeable directory is allowed.\n"
00798 );
00799 }
00800
00801 ex:
00802 exit(status);
00803
00804
00805 return 0;
00806 }
00807
00808
00816 void sigUSR1(int num)
00817 {
00818 if (opt__get_int(OPT__VERBOSE) < VERBOSITY_DEFAULT)
00819 opt__set_int(OPT__VERBOSE, PRIO_MUSTHAVE, VERBOSITY_DEFAULT);
00820 else if (debuglevel < 3)
00821 {
00822 debuglevel++;
00823 DEBUGP("more debugging via SIGUSR1");
00824 }
00825 }
00827 void sigUSR2(int num)
00828 {
00829 if (debuglevel)
00830 {
00831 DEBUGP("less debugging via SIGUSR2");
00832 debuglevel--;
00833 }
00834 else if (opt__get_int(OPT__VERBOSE) >= VERBOSITY_DEFAULT)
00835 opt__set_int(OPT__VERBOSE, PRIO_MUSTHAVE, VERBOSITY_QUIET);
00836 }
00837
00838
00846 #ifdef ENABLE_DEBUG
00848 void sigDebug(int num)
00849 {
00850 char ppid_str[20];
00851 int pid;
00852 int pipes[2];
00853
00854
00855
00856 signal(SIGSEGV, SIG_DFL);
00857
00858
00859 _DEBUGP(NULL, EBUSY, NULL, NULL);
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870 pipes[0]=pipes[1]=-1;
00871 if ( pipe(pipes) == -1) goto ex;
00872
00873 pid=fork();
00874 if (pid == -1) return;
00875
00876 if (pid)
00877 {
00878
00879
00880 close(pipes[0]);
00881
00882 sprintf(ppid_str, "%d", pid);
00883 execlp("gdb", "gdb", program_name, ppid_str, NULL);
00884
00885 close(pipes[1]);
00886 exit(1);
00887 }
00888 else
00889 {
00890
00891
00892
00893 close(pipes[1]);
00894 pipes[1]=-1;
00895 read(pipes[0], &pid, 1);
00896 }
00897
00898 ex:
00899 if (pipes[0] != -1) close(pipes[0]);
00900 if (pipes[1] != -1) close(pipes[1]);
00901 }
00902
00903
00908 void sigPipe(int num)
00909 {
00910 DEBUGP("got SIGPIPE");
00911 signal(SIGPIPE, SIG_DFL);
00912 }
00913
00914
00919 void *_do_component_tests(int a)
00920 {
00921
00922 static int int_array[10];
00923 static void *voidp_array[10];
00924 static char *charp_array_1[10];
00925 static char *charp_array_2[10];
00926 static char **charpp;
00927 static char buffer[1024];
00928 static struct estat *estat_array[10];
00929
00930 int_array[0]=fileno(stdin);
00931 voidp_array[0]=stdin+fileno(stdout);
00932 buffer[0]=fileno(stderr);
00933 charpp=charp_array_2+4;
00934
00935 switch(a)
00936 {
00937 case 4: return int_array;
00938 case 9: return voidp_array;
00939 case 6: return buffer;
00940 case 2: return charp_array_1;
00941 case 3: return estat_array;
00942 case 7: return charpp;
00943 case 8: return charp_array_2;
00944 }
00945 return NULL;
00946 }
00947 #endif
00948
00949
01044 int main(int argc, char *args[], char *env[])
01045 {
01046 struct estat root = { };
01047 int status, help;
01048 char *cmd;
01049 svn_error_t *status_svn;
01050 int eo_args, i;
01051 void *mem_start, *mem_end;
01052
01053
01054 help=0;
01055 eo_args=1;
01056 environ=env;
01057 program_name=args[0];
01058 #ifdef ENABLE_DEBUG
01059
01060
01061 if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO))
01062 signal(SIGSEGV, sigDebug);
01063
01064 signal(SIGPIPE, sigPipe);
01065
01066
01067 cmd=getenv(FSVS_DEBUG_ENV);
01068 if (cmd)
01069 debuglevel = atoi(cmd);
01070 #endif
01071
01072 signal(SIGUSR1, sigUSR1);
01073 signal(SIGUSR2, sigUSR2);
01074 mem_start=sbrk(0);
01075
01076
01077 #ifdef HAVE_LOCALES
01078
01079
01080
01081 cmd=setlocale(LC_ALL, "");
01082 DEBUGP("LC_ALL gives %s", cmd);
01083
01084
01085
01086
01087
01088 cmd=setlocale(LC_CTYPE, "");
01089 DEBUGP("LC_CTYPE gives %s", cmd);
01090
01091 local_codeset=nl_langinfo(CODESET);
01092 if (!local_codeset)
01093 {
01094 STOPIF( wa__warn(WRN__CHARSET_INVALID, EINVAL,
01095 "Could not retrieve the current character set - assuming UTF-8."),
01096 "nl_langinfo(CODESET) failed - check locale configuration.");
01097 }
01098 else
01099 {
01100 DEBUGP("codeset found to be %s", local_codeset);
01101 if (strcmp(local_codeset, "UTF-8")==0)
01102
01103
01104 local_codeset=NULL;
01105 }
01106
01107 if (!local_codeset)
01108 DEBUGP("codeset: using identity");
01109 #else
01110 DEBUGP("build without locales");
01111 #endif
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 STOPIF( hlp__chrooter(), NULL);
01125
01126
01127 STOPIF( opt__load_env(environ), NULL);
01128 STOPIF( waa__save_cwd(&start_path, &start_path_len, 0), NULL);
01129
01130
01131 if (!isatty(STDOUT_FILENO))
01132 opt__set_int( OPT__STATUS_COLOR, PRIO_PRE_CMDLINE, 0);
01133
01134
01135
01136 root.repos_rev=0;
01137 root.name=root.strings=".";
01138 root.st.size=0;
01139 root.st.mode=S_IFDIR | 0700;
01140 root.entry_count=0;
01141
01142
01143
01144 root.do_filter_allows=1;
01145 root.do_filter_allows_done=1;
01146
01147
01148 while (1)
01149 {
01150
01151
01152
01153
01154
01155
01156 status=getopt(argc, args, "+a:VhdvCm:F:D:qf:r:W:NRo:u:?");
01157 if (status == -1)
01158 {
01159 DEBUGP("no argument at optind=%d of %d",optind, argc);
01160
01161 if (optind == argc) break;
01162
01163
01164 if (strcmp("--", args[optind-1])==0)
01165 {
01166
01167 while (optind < argc) args[eo_args++] = args[optind++];
01168 break;
01169 }
01170
01171
01172 args[eo_args++]=args[optind++];
01173 continue;
01174 }
01175
01176 switch (status)
01177 {
01178 case '?':
01179 case 'h':
01180 default:
01181 help=1;
01182 break;
01183
01184 case 'W':
01185 STOPIF( wa__set_warn_option(optarg, PRIO_CMDLINE),
01186 "Warning option '%s' is invalid", optarg);
01187 break;
01188
01189 case 'C':
01190 i = hlp__rightmost_0_bit(opt__get_int(OPT__CHANGECHECK));
01191 opt__set_int(OPT__CHANGECHECK, PRIO_CMDLINE,
01192 opt__get_int(OPT__CHANGECHECK) | i);
01193 break;
01194
01195 case 'o':
01196 STOPIF( opt__parse( optarg, NULL, PRIO_CMDLINE, 0),
01197 "!Cannot parse option string '%s'.", optarg);
01198 break;
01199
01200 case 'f':
01201 STOPIF( opt__parse_option(OPT__FILTER, PRIO_CMDLINE, optarg), NULL);
01202 break;
01203
01204 case 'u':
01205
01206
01207
01208
01209
01210
01211
01212
01213 STOPIF( url__store_url_name(optarg), NULL);
01214 break;
01215
01216
01217
01218
01219 case 'R':
01220 opt_recursive++;
01221 break;
01222 case 'N':
01223 opt_recursive--;
01224 break;
01225
01226 case 'F':
01227 if (opt_commitmsg) ac__Usage_this();
01228 opt_commitmsgfile=optarg;
01229 break;
01230 case 'm':
01231 if (opt_commitmsgfile) ac__Usage_this();
01232 opt_commitmsg=optarg;
01233 break;
01234
01235 case 'r':
01236
01237 cmd=strchr(optarg, ':');
01238 if (cmd) *(cmd++)=0;
01239
01240 STOPIF( hlp__parse_rev(optarg, NULL, &opt_target_revision), NULL);
01241 opt_target_revisions_given=1;
01242
01243 if (cmd && *cmd)
01244 {
01245 STOPIF( hlp__parse_rev(cmd, NULL, &opt_target_revision2), NULL);
01246 opt_target_revisions_given=2;
01247 }
01248 break;
01249
01250 #if ENABLE_RELEASE
01251 case 'D':
01252 case 'd':
01253 fprintf(stderr, "This image was compiled as a release "
01254 "(without debugging support).\n"
01255 "-d and -D are not available.\n\n");
01256 exit(1);
01257 #else
01258 case 'D':
01259 opt_debugprefix=optarg;
01260 if (!debuglevel) debuglevel++;
01261
01262 break;
01263 case 'd':
01264
01265
01266
01267
01268 if (debuglevel == 1)
01269 {
01270
01271
01272 _DEBUGP(NULL, 0, NULL, NULL);
01273
01274
01275 opt__set_string(OPT__DEBUG_OUTPUT, PRIO_MUSTHAVE, NULL);
01276 opt__set_int(OPT__DEBUG_BUFFER, PRIO_MUSTHAVE, 0);
01277
01278
01279 DEBUGP("Debugging set to unfiltered console");
01280 }
01281 debuglevel++;
01282 break;
01283 #endif
01284 case 'q':
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294 opt__set_int(OPT__VERBOSE, PRIO_CMDLINE,
01295 opt__get_int(OPT__VERBOSE) <= VERBOSITY_QUIET ?
01296 VERBOSITY_VERYQUIET : VERBOSITY_QUIET);
01297 break;
01298
01299 case 'v':
01300
01301 i=opt__get_int(OPT__VERBOSE);
01302 if (i == VERBOSITY_QUIET)
01303 i=VERBOSITY_DEFAULT;
01304 else
01305 i |= hlp__rightmost_0_bit(i);
01306
01307 opt__set_int(OPT__VERBOSE, PRIO_CMDLINE, i);
01308
01309
01310 opt__set_int(OPT__FILTER, PRIO_PRE_CMDLINE, FILTER__ALL);
01311 break;
01312
01313 case 'V':
01314 Version(stdout);
01315 exit(0);
01316 }
01317 }
01318
01319
01320 argc=eo_args;
01321
01322 args[argc]=NULL;
01323
01324 optind=1;
01325
01326
01327
01328 if (opt__get_int(OPT__DEBUG_BUFFER) &&
01329 opt__get_prio(OPT__DEBUG_BUFFER)==PRIO_CMDLINE &&
01330 !debuglevel)
01331 {
01332 debuglevel++;
01333 DEBUGP("debug capturing started by the debug_buffer option.");
01334 }
01335
01336
01337
01338 if (args[optind])
01339 {
01340 cmd=args[optind];
01341 optind++;
01342
01343 STOPIF( act__find_action_by_name(cmd, &action), NULL);
01344 if (help) ac__Usage_this();
01345 }
01346 else
01347 {
01348 if (help) ac__Usage_dflt();
01349 action=action_list+0;
01350 }
01351
01352 DEBUGP("optind=%d per_sts=%d action=%s rec=%d filter=%s",
01353 optind,
01354 (int)sizeof(root),
01355 action->name[0],
01356 opt_recursive,
01357 st__status_string_fromint( opt__get_int(OPT__FILTER)) );
01358
01359 for(eo_args=1; eo_args<argc; eo_args++)
01360 DEBUGP("argument %d: %s", eo_args, args[eo_args]);
01361
01362
01363
01364
01365
01366 STOPIF( waa__init(), NULL);
01367
01368
01369
01370 strcpy(conf_tmp_fn, "config");
01371 STOPIF( opt__load_settings(conf_tmp_path, NULL, PRIO_ETC_FILE ), NULL);
01372
01373
01374 #ifdef ENABLE_DEBUG
01375
01376
01377 STOPIF( wa__warn( WRN__TEST_WARNING, 0, "test warning" ), NULL );
01378
01379
01380
01381 if (debuglevel) _do_component_tests(optind);
01382 #endif
01383
01384
01385
01386
01387
01388 STOPIF( apr_initialize(), "apr_initialize");
01389 STOPIF( apr_pool_create_ex(&global_pool, NULL, NULL, NULL),
01390 "create an apr_pool");
01391 STOPIF_SVNERR( svn_ra_initialize, (global_pool));
01392 STOPIF_SVNERR( cb__init, (global_pool));
01393
01394
01395 STOPIF( action->work(&root, argc-optind, args+optind),
01396 "action %s failed", action->name[0]);
01397
01398
01399 STOPIF( cm__get_source(NULL, NULL, NULL, NULL, status),
01400 NULL);
01401
01402
01403
01404
01405
01406 STOPIF( wa__summary(), NULL);
01407
01408 STOPIF( url__close_sessions(), NULL);
01409
01410 ex:
01411 mem_end=sbrk(0);
01412 DEBUGP("memory stats: %p to %p, %llu KB",
01413 mem_start, mem_end, (t_ull)(mem_end-mem_start)/1024);
01414 if (status == -EPIPE)
01415 DEBUGP("got EPIPE, ignoring.");
01416
01417 _DEBUGP(NULL, status, NULL, NULL);
01418
01419 if (status) return 2;
01420
01421 return 0;
01422 }
01423
01424