source: trunk/dasscm/dasscm@ 234

Last change on this file since 234 was 234, checked in by joergs, on Oct 8, 2008 at 4:29:29 PM

removed the requirement for perl-libconfigfile, because it didn't exist for all systems. Replaced by the simple get_config function

  • Property keyword set to id
  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 21.0 KB
Line 
1#!/usr/bin/perl -w
2
3# $Id: dasscm 234 2008-10-08 14:29:29Z joergs $
4
5use strict;
6
7use Env
8 qw($DASSCM_PROD $DASSCM_REPO $USER $DASSCM_USERNAME $DASSCM_USER $DASSCM_PASSWORD);
9use Cwd;
10use Getopt::Long;
11use File::Basename;
12use File::Compare;
13use File::Copy;
14use File::stat;
15use File::Path;
16use Term::ReadKey;
17#use Data::Dumper;
18
19#####################################################################
20#
21# global
22#
23
24# file to store permissions
25my $permissions_file = "/etc/permissions.d/dasscm.permission_backup";
26
27# configuration file
28my $config_file = "/etc/dasscm.conf";
29my $config = get_config($config_file);
30my $DASSCM_LOCAL_REPOSITORY_BASE;
31my $DASSCM_REPOSITORY_NAME;
32my $DASSCM_SVN_REPOSITORY;
33
34my $SVN = "svn ";
35my $svnOptions = "";
36my $svnCheckoutCredentials = "";
37my $svnPasswordCredentials = "";
38
39# command line options get stored in options hash
40my %options = ();
41
42# subcommand, that gets executed (add, commit, ...)
43my $command;
44
45my $verbose = 0;
46
47#####################################################################
48#
49# util functions
50#
51sub usage()
52{
53 print "usage: dasscm <subcommand> [options] [args]\n";
54 print "\n";
55 print "dasscm is intended to help versioning configuration files\n";
56 print "\n";
57 print "Available subcommands:\n";
58 print " help <subcommand>\n";
59 print " init\n";
60 print " login\n";
61 print " up\n";
62 print " ls\n";
63 print " add <filename>\n";
64 print " commit <filename>\n";
65 print " status <filename>\n";
66 print " diff <filename>\n";
67 print " permissions\n";
68 print "\n";
69 print "preperation:\n", " if dasscm is already configured,\n",
70 " use 'dasscm login' and than eg. 'add'.\n",
71 " The environment variables\n", " DASSCM_REPO\n", " DASSCM_PROD\n",
72 " DASSCM_USERNAME\n", " DASSCM_PASSWORD\n",
73 " are evaluated, but set automatically by 'dasscm login'.\n", "\n",
74 " If dasscm is not yet configured, read",
75 " /usr/share/doc/packages/dasscm/dasscm_howto.txt\n";
76}
77
78sub warning(@)
79{
80 print "Warning: " . join( "\n ", @_ ) . "\n";
81}
82
83sub error(@)
84{
85 print "Error: " . join( "\n ", @_ ) . "\n";
86}
87
88sub fatalerror(@)
89{
90 error( @_ );
91 #print "Exiting\n";
92 exit 1
93}
94
95sub get_config
96{
97 my $file = $_[0];
98
99 if( ! $file ) {
100 fatalerror( "failed to open config file" . $file );
101 }
102
103 my $data = {};
104
105 # try to open config file
106 if ( !open( FH, $file ) ) {
107 fatalerror( "failed to open config file" . $file );
108 } else {
109 while (<FH>) {
110 chomp;
111 if (/^#/) {
112 next;
113 }
114 if ( $_ =~ /=/g ) {
115 ## splitting in 2 fields at maximum
116 my ( $option, $value ) = split( /=/, $_, 2 );
117 $option =~ s/^\s+//g;
118 $option =~ s/\s+$//g;
119 $option =~ s/\"+//g;
120 $value =~ s/^\s+//g;
121 $value =~ s/\s+$//g;
122 $value =~ s/\"+//g;
123
124 if ( length($option) ) {
125 $data->{$option} = $value;
126 }
127 }
128 }
129 }
130 close(FH);
131
132 return $data;
133}
134
135
136sub check_env()
137{
138
139 # DASSCM_PROD
140 if ( !$DASSCM_PROD ) {
141 $DASSCM_PROD = "/";
142 }
143
144 if ( !-d $DASSCM_PROD ) {
145 die "DASSCM_PROD ($DASSCM_PROD) is not set to a directory.\n";
146 }
147 if ($verbose) { print "DASSCM_PROD: " . $DASSCM_PROD . "\n"; }
148
149 # DASSCM_REPOSITORY_NAME
150 if ( !$DASSCM_REPOSITORY_NAME ) {
151 die
152 "Variable DASSCM_REPOSITORY_NAME is not defined.\nIt needs to be a unique name.\nNormally the full qualified host name is used.\nUse file $config_file to configure it.\n";
153 }
154
155 # DASSCM_REPO
156 if ( !$DASSCM_REPO ) {
157 if ( $DASSCM_LOCAL_REPOSITORY_BASE && $DASSCM_REPOSITORY_NAME ) {
158 $DASSCM_REPO =
159 $DASSCM_LOCAL_REPOSITORY_BASE . "/" . $DASSCM_REPOSITORY_NAME;
160 } else {
161 die
162 "Envirnonment variable DASSCM_REPO not set.\nSet DASSCM_REPO to the directory of the versioning system checkout for this machine.\n";
163 }
164 }
165 if ($verbose) { print "DASSCM_REPO: " . $DASSCM_REPO . "\n"; }
166
167 #
168 # check if local repository directory exist (if not creating by init)
169 #
170 if ( $command ne "init" ) {
171 if ( not -d $DASSCM_REPO ) {
172 die
173 "Can't access local repository DASSCM_REPO\n($DASSCM_REPO)\nCheck configuration and execute\n dasscm init\n";
174 }
175
176 #
177 # user settings
178 #
179
180 # DASSCM_USER is legacy. Use DASSCM_USERNAME instead
181 if ( !$DASSCM_USERNAME ) {
182 $DASSCM_USERNAME = $DASSCM_USER;
183 }
184
185 # user root is not allowed for checkins.
186 # if user is root, DASSCM_USER has to be set,
187 # otherwise USER can be used
188 if ( "$USER" eq "root" ) {
189 if ( ( not $DASSCM_USERNAME ) and ( $command ne "login" ) ) {
190 die
191 "Envirnonment variable DASSCM_USERNAME not set.\nSet DASSCM_USERNAME to your subversion user account.\n";
192 }
193 $svnOptions .= " --no-auth-cache ";
194 } elsif ( !$DASSCM_USERNAME ) {
195 $DASSCM_USERNAME = $USER;
196 }
197
198 #
199 # password
200 #
201 if ($DASSCM_PASSWORD) {
202 $svnPasswordCredentials = " --password $DASSCM_PASSWORD ";
203 }
204 }
205
206 #$svnOptions .= " --username $DASSCM_USERNAME "
207}
208
209sub check_parameter(@)
210{
211 if( not @_ ) {
212 fatalerror( "no files specified. See 'dasscm --help'" );
213 }
214}
215
216sub get_filenames(@)
217{
218 my $filename_prod = $_[0];
219 if ( !( $filename_prod =~ m/^\// ) ) {
220 $filename_prod = cwd() . "/" . $filename_prod;
221 }
222
223 if( not -r $filename_prod ) {
224 fatalerror( $filename_prod . " is not accessable" );
225 } elsif( -l $filename_prod ) {
226 my $dest = readlink($filename_prod);
227 # TODO:
228 # default: disallow, but offer cmd switch to activate
229 # (or check, if file is already checked in and has been a link before)
230 warning( "'$filename_prod' is a link to '$dest'.", "Please check, if '$dest' should be stored in repository instead" );
231 if( ! -f $dest ) {
232 fatalerror( "link target '$dest' is not a regular file. Giving up" );
233 }
234 } elsif( ! -f $filename_prod ) {
235 fatalerror( $filename_prod . " is not a regular file. Only regular files can be checked in." );
236 }
237
238 # TODO: dirname buggy: eg. "/etc/" is reduced to "/",
239 # "/etc" is used as filename
240 my $dirname_prod = dirname($filename_prod);
241 chdir $dirname_prod or die $!;
242 $dirname_prod = cwd();
243 my $basename = basename($filename_prod);
244
245 if ($verbose) {
246 print "dir: " . $dirname_prod . "\n";
247 print "fn: " . $basename . "\n";
248 }
249
250 my $dirname_repo = $DASSCM_REPO . "/" . $dirname_prod;
251 my $filename_repo = "$dirname_repo/$basename";
252
253 return (
254 $basename, $dirname_prod, $dirname_repo,
255 $filename_prod, $filename_repo
256 );
257}
258
259sub generatePermissionList
260{
261
262 # generieren der Zeilen für Permission-Savefile
263 my @files = @_;
264 my @permlist = ();
265 foreach my $file (@files) {
266 $file = "/" . $file;
267 if( -e $file ) {
268 my $info = stat( $file ) || die "failed to stat $file: aborting";
269 my $mode = get_type( $info->mode ) & 07777;
270 my $modestring = sprintf( "%04o", $mode );
271 my $uid = $info->uid;
272 my $uidname = getpwuid($uid);
273 my $gid = $info->gid;
274 my $gidname = getgrgid($gid);
275 push(
276 @permlist,
277 sprintf( "%-55s %-17s %4d",
278 $file, "${uidname}:${gidname}", $modestring )
279 );
280 } else {
281 print "failed to get status of $file. It exists in the repository, but not on the system\n";
282 }
283 }
284 return @permlist;
285}
286
287sub get_type
288{
289
290 # Funktion übernommen aus /usr/bin/chkstat
291 my $S_IFLNK = 0120000; # symbolic link
292 my $S_IFREG = 0100000; # regular file
293 my $S_IFDIR = 0040000; # directory
294 my $S_IFCHAR = 0020000; # character device
295 my $S_IFBLK = 0060000; # block device
296 my $S_IFFIFO = 0010000; # fifo
297 my $S_IFSOCK = 0140000; # socket
298 my $S_IFMT = 0170000; # type of file
299
300 my $S_m;
301 if ( ( $_[0] & $S_IFMT ) == $S_IFLNK ) { $S_m = $_[0] - $S_IFLNK; }
302 elsif ( ( $_[0] & $S_IFMT ) == $S_IFREG ) { $S_m = $_[0] - $S_IFREG; }
303 elsif ( ( $_[0] & $S_IFMT ) == $S_IFDIR ) { $S_m = $_[0] - $S_IFDIR; }
304 elsif ( ( $_[0] & $S_IFMT ) == $S_IFCHAR ) { $S_m = $_[0] - $S_IFCHAR; }
305 elsif ( ( $_[0] & $S_IFMT ) == $S_IFBLK ) { $S_m = $_[0] - $S_IFBLK; }
306 elsif ( ( $_[0] & $S_IFMT ) == $S_IFFIFO ) { $S_m = $_[0] - $S_IFFIFO; }
307 elsif ( ( $_[0] & $S_IFMT ) == $S_IFSOCK ) { $S_m = $_[0] - $S_IFSOCK; }
308 $S_m;
309}
310
311sub run_command
312{
313 my $command = shift;
314
315 #print "executing command: " . $command . "\n";
316
317 open( RESULT, $command . ' 2>&1 |' );
318 my @result = <RESULT>;
319 close(RESULT);
320 my $retcode = $? >> 8;
321
322 #print @result;
323 #if( $retcode ) { print "return code: " . $retcode . "\n"; }
324
325 return ( $retcode, @result );
326}
327
328sub run_interactive
329{
330
331 if ($verbose) {
332 print "run_interactive:" . join( " ", @_ ) . "\n";
333 }
334
335 system(@_);
336 if ( $? == -1 ) {
337 printf "failed to execute: $!\n";
338 } elsif ( $? & 127 ) {
339 printf "child died with signal %d, %s coredump\n", ( $? & 127 ),
340 ( $? & 128 ) ? 'with' : 'without';
341 } elsif ( $? >> 8 != 0 ) {
342 printf "child exited with value %d\n", $? >> 8;
343 }
344 return ( $? >> 8 );
345}
346
347sub svn_check_credentials( $$ )
348{
349 my $username = shift;
350 my $password = shift;
351
352 print "checking credentials ... ";
353
354 # Options for "svn info" are not supported by subversion 1.0.0 (SLES9),
355 # therefore switching to "svn status"
356 # ( my $rc_update, my @result ) =
357 # run_command(
358 # "$SVN info --non-interactive --no-auth-cache --username $username --password $password $DASSCM_SVN_REPOSITORY"
359 # );
360 #print @result;
361
362 ( my $rc_update, my @result ) =
363 run_command(
364 "$SVN ls --non-interactive --no-auth-cache --username $username --password $password $DASSCM_SVN_REPOSITORY"
365 );
366
367 if ( $rc_update != 0 ) {
368 print @result;
369 die;
370 }
371
372}
373
374sub svn_update( ;$ )
375{
376 my $update_path = shift || $DASSCM_REPO;
377 ( my $rc_update, my @result ) =
378 run_command(
379 "$SVN update --non-interactive $svnCheckoutCredentials $update_path");
380 print @result;
381 if ( $rc_update != 0 ) {
382 die;
383 }
384}
385
386sub svn_getStoredFiles( ;$ )
387{
388
389 # TODO: get_filenames?
390 #my $rel_path = shift || "";
391 #my $path = "${DASSCM_REPO}/${rel_path}";
392 my $path = ${DASSCM_REPO};
393
394 # svn ls -R is better, but much, much slower
395 # ( my $rc, my @result ) = run_command("$SVN ls --recursive $svnCheckoutCredentials $path");
396 ( my $rc, my @result ) =
397 run_command(
398 "cd $path && find | grep -v '/.svn' | sed -e 's/\.\\///' | grep -v '^\$'"
399 );
400 if ( $rc != 0 ) {
401 print @result;
402 die;
403 }
404 chomp(@result);
405 return @result;
406}
407
408#####################################################################
409#
410# functions
411
412sub help(;@)
413{
414 if ( @_ == 0 ) {
415 usage();
416 } else {
417 print "help for @_: ...\n";
418 usage();
419 }
420}
421
422sub login(@)
423{
424 check_parameter( @_, 1 );
425 check_env();
426
427 my $input_username = $1;
428
429 if ( not $input_username ) {
430 my $output_username = "";
431 if ($DASSCM_USERNAME) {
432 $output_username = " ($DASSCM_USERNAME)";
433 }
434
435 print "Enter DASSCM user name", $output_username, ": ";
436 $input_username = <STDIN>;
437 chomp($input_username);
438 }
439
440 # hidden password input
441 print "Enter DASSCM user password: ";
442 ReadMode('noecho');
443 my $input_password = <STDIN>;
444 ReadMode('normal');
445 chomp($input_password);
446 print "\n";
447
448 svn_check_credentials( $input_username, $input_password );
449
450 #
451 # set environment variables
452 #
453 $ENV{'DASSCM_USERNAME'} = $input_username;
454 $ENV{'DASSCM_PASSWORD'} = $input_password;
455
456 print "subversion access okay\n\n", "DASSCM_USERNAME: $input_username\n",
457 "DASSCM_PASSWORD: (hidden)\n", "DASSCM_PROD: $DASSCM_PROD\n",
458 "DASSCM_REPO: $DASSCM_REPO\n",
459 "Server Repository: $DASSCM_SVN_REPOSITORY\n", "\n", "[dasscm shell]\n\n";
460
461 exec("bash") or die "failed to start new shell";
462}
463
464sub init(@)
465{
466 check_parameter( @_, 1 );
467 check_env();
468
469 # update complete repository
470 # and create permission file
471 my $retcode =
472 run_interactive(
473 "cd $DASSCM_LOCAL_REPOSITORY_BASE; $SVN checkout $svnCheckoutCredentials $svnOptions $DASSCM_SVN_REPOSITORY; touch $permissions_file"
474 );
475}
476
477sub ls(@)
478{
479 check_parameter( @_, 1 );
480 check_env();
481
482 my @files = svn_getStoredFiles(@_);
483
484 print join( "\n", @files );
485 print "\n";
486}
487
488sub update(@)
489{
490 check_parameter( @_, 1 );
491 check_env();
492
493 #
494 # update local repository
495 #
496 svn_update();
497}
498
499sub add_helper(@)
500{
501 (
502 my $basename,
503 my $dirname_prod,
504 my $dirname_repo,
505 my $filename_prod,
506 my $filename_repo
507 )
508 = get_filenames( $_[0] );
509
510 if ( $command eq "add" ) {
511 mkpath($dirname_repo);
512 }
513
514 copy( $filename_prod, $filename_repo ) or die "failed to copy $filename_prod to repository: $!";
515
516 if ( $command eq "add" ) {
517
518 # already checked in?
519 chdir($DASSCM_REPO);
520
521 # also add the path to filename.
522 for my $dir ( split( '/', $dirname_prod ) ) {
523 if ($dir) {
524 my( $rc, @out ) = run_command("$SVN add --non-recursive \"" . $dir . "\"" );
525 if( $rc > 0 ) {
526 print join( "\n", @out );
527 }
528 chdir $dir;
529 }
530 }
531 my( $rc, @out ) = run_command("$SVN add \"" . $basename . "\"");
532 if( $rc > 0 ) {
533 print join( "\n", @out );
534 }
535 }
536}
537
538#
539# add (is used for command add and commit)
540#
541sub add(@)
542{
543 check_parameter( @_, 1 );
544 check_env();
545
546 #
547 # update local repository
548 #
549 svn_update();
550
551 # TODO: check all files
552
553 for my $file (@_) {
554 # add file
555 add_helper( $file );
556 }
557
558 # create new permissions file
559 permissions();
560
561 # add permissions file
562 add_helper($permissions_file);
563
564 if ( $options{'message'} ) {
565 $svnOptions .= " --message \"$options{'message'}\" ";
566 }
567
568 # commit calls $EDITOR. uses "interactive" here, to display output
569 my $retcode =
570 run_interactive(
571 "$SVN commit $svnOptions --username $DASSCM_USERNAME $svnPasswordCredentials $DASSCM_REPO"
572 );
573
574 #print $filename_prod. "\n";
575 #print $dirname_repo. "\n";
576}
577
578sub blame(@)
579{
580 check_parameter( @_, 1 );
581 check_env();
582
583 (
584 my $basename,
585 my $dirname_prod,
586 my $dirname_repo,
587 my $filename_prod,
588 my $filename_repo
589 )
590 = get_filenames( $_[0] );
591
592 my $retcode = run_interactive("$SVN blame $svnOptions $filename_repo");
593}
594
595sub diff(@)
596{
597 check_parameter( @_, 1 );
598 check_env();
599
600 (
601 my $basename,
602 my $dirname_prod,
603 my $dirname_repo,
604 my $filename_prod,
605 my $filename_repo
606 )
607 = get_filenames( $_[0] );
608
609 #print "$basename,$dirname_prod,$dirname_repo\n";
610
611 ( my $rc_update, my @result ) = run_command("$SVN update $filename_repo");
612 if ( $rc_update != 0 ) {
613 print @result;
614 die;
615 }
616
617 ( my $rc_diff, my @diff ) =
618 run_command("diff $filename_repo $filename_prod");
619 print @diff;
620}
621
622sub status(@)
623{
624 check_parameter( @_, 1 );
625 check_env();
626
627 #
628 # update local repository
629 #
630 svn_update();
631
632 # TODO: start at subdirectories ?
633 my $dir = $DASSCM_REPO;
634 my @files = svn_getStoredFiles($dir);
635
636 # Liste der geänderten Files ausgeben, falls nicht leer
637 if (@files) {
638
639 # stores result from status (cvscheck)
640 my %removedfiles = ();
641 my %changedfiles = ();
642
643 foreach my $file (@files) {
644
645 my $realfile = "/" . $file;
646 my $cvsworkfile = "${DASSCM_REPO}/${file}";
647
648 if ( -d $realfile ) {
649
650 # directory. do nothing
651 } elsif ( !-r $realfile ) {
652 $removedfiles{"$realfile"} = $cvsworkfile;
653 } else {
654 ( -r "$cvsworkfile" )
655 || die("Fehler: $cvsworkfile ist nicht lesbar");
656 if ( compare( $cvsworkfile, $realfile ) != 0 ) {
657 $changedfiles{"$realfile"} = $cvsworkfile;
658 }
659 }
660 }
661
662 if (%removedfiles) {
663 print "deleted files (found in repository, but not in system):\n";
664 foreach my $key ( values %removedfiles ) {
665 print "$key\n";
666 }
667 print "\n";
668 }
669
670 if (%changedfiles) {
671 print "modified files:\n";
672 foreach my $key ( keys %changedfiles ) {
673 print "$key\n";
674 }
675 }
676 } else {
677 print "no modified files found in $dir\n";
678 }
679
680 print "\n";
681}
682
683sub permissions(@)
684{
685 check_parameter( @_, 1 );
686 check_env();
687
688 #
689 # update local repository
690 #
691 #svn_update();
692
693 # TODO: start at subdirectories ?
694 my $dir = $DASSCM_REPO;
695 my @files = svn_getStoredFiles($dir);
696
697 if (@files) {
698
699 # generieren der Permissions
700 my @permissions = generatePermissionList(@files);
701 my $OUTFILE;
702 my $tofile = 0; # Status für schreiben in File
703
704 if ( -w dirname($permissions_file) ) {
705
706 # Verzeichnis existiert => schreiben
707 print "storing permissions in file $permissions_file\n";
708 open( OUTFILE, ">$permissions_file" )
709 || die("failed to write to $permissions_file: $!");
710 $tofile = 1; # Merken, daß in File geschrieben wird
711 print OUTFILE "#\n";
712 print OUTFILE "# created by dasscm permissions\n";
713 print OUTFILE
714 "# It is intended to be used for restoring permissions\n";
715 } else {
716
717 # Pfad für Sicherungsdatei existiert nicht => schreiben auf stdout
718 # Alias Filehandle für stdout erzeugen
719 *OUTFILE = *STDOUT;
720 }
721 foreach my $line (@permissions) {
722 print OUTFILE "$line\n";
723 }
724
725 if ($tofile) {
726 close(OUTFILE);
727 }
728 }
729}
730
731#####################################################################
732#
733# main
734#
735
736my $number_arguments = @ARGV;
737
738if ( $number_arguments > 0 ) {
739
740 # get subcommand and remove it from @ARGV
741 $command = $ARGV[0];
742 shift @ARGV;
743
744 $DASSCM_LOCAL_REPOSITORY_BASE = $config->{'DASSCM_LOCAL_REPOSITORY_BASE'};
745 $DASSCM_REPOSITORY_NAME = $config->{'DASSCM_REPOSITORY_NAME'};
746
747 # TODO: check variables
748 $DASSCM_SVN_REPOSITORY =
749 $config->{'DASSCM_SVN_REPOSITORY_BASE'} . "/" . $DASSCM_REPOSITORY_NAME;
750
751 my $DASSCM_CHECKOUT_USERNAME = $config->{'DASSCM_CHECKOUT_USERNAME'};
752 my $DASSCM_CHECKOUT_PASSWORD = $config->{'DASSCM_CHECKOUT_PASSWORD'};
753
754 #
755 # if a user is given by dasscm configuration file, we use it.
756 # Otherwise we expect that read-only account is configured
757 # as local subversion configuration.
758 # If this is also not the case,
759 # user is required to type username and password.
760 # This will be stored as local subversion configuration thereafter.
761 #
762 if ( $DASSCM_CHECKOUT_USERNAME && $DASSCM_CHECKOUT_PASSWORD ) {
763 $svnCheckoutCredentials =
764 " --username $DASSCM_CHECKOUT_USERNAME --password $DASSCM_CHECKOUT_PASSWORD ";
765 }
766
767 # get command line options and store them in options hash
768 my $result = GetOptions( \%options, 'verbose', 'message=s' );
769
770 # print options
771 foreach my $option ( keys %options ) {
772 print "${option}: $options{$option}\n";
773 }
774
775 # set verbose to command line option
776 $verbose = $options{'verbose'};
777
778 #
779 # action accordinly to command are taken
780 # $command is rewritten in standard format,
781 # so we can test for it later on more simply
782 #
783 $_ = $command;
784 if (m/help/i) {
785 help(@ARGV);
786 } elsif (m/login/i) {
787 $command = "login";
788 login(@ARGV);
789 } elsif (m/init/i) {
790 $command = "init";
791 init(@ARGV);
792 } elsif (m/ls/i) {
793 $command = "ls";
794 ls(@ARGV);
795 } elsif (m/up/i) {
796 $command = "update";
797 update(@ARGV);
798 } elsif (m/add/i) {
799 $command = "add";
800 add(@ARGV);
801 } elsif (m/commit/i) {
802 $command = "commit";
803 add(@ARGV);
804 } elsif (m/blame/i) {
805 $command = "blame";
806 blame(@ARGV);
807 } elsif (m/diff/i) {
808 $command = "diff";
809 diff(@ARGV);
810 } elsif (m/status/i) {
811 $command = "status";
812 status(@ARGV);
813 } elsif (m/permissions/i) {
814 $command = "permissions";
815 permissions(@ARGV);
816 } else {
817 print "unknown command: $command\n\n";
818 usage();
819 check_env();
820 }
821
822 # cleanup (svn-commit.tmp)
823 # commitall
824 # revert
825 # activate
826 # rm
827}
Note: See TracBrowser for help on using the repository browser.