X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-cvsserver.perl;h=1de517791f8a293a9c770f6260ff48f9719845ad;hb=e97593693ed36da918413732c9ca4b09c3e9d213;hp=65fcc840497fb44fd0bd843b6eedaab258d8b88f;hpb=c379c4b176ce350a8d6c0773a3ad211996d809db;p=git.git diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 65fcc8404..1de517791 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -91,7 +91,9 @@ $log->debug("Temporary directory is '$TEMP_DIR'"); # if we are called with a pserver argument, # deal with the authentication cat before entering the # main loop +$state->{method} = 'ext'; if (@ARGV && $ARGV[0] eq 'pserver') { + $state->{method} = 'pserver'; my $line = ; chomp $line; unless( $line eq 'BEGIN AUTH REQUEST') { die "E Do not understand $line - expecting BEGIN AUTH REQUEST\n"; @@ -103,6 +105,7 @@ if (@ARGV && $ARGV[0] eq 'pserver') { unless ($line eq 'anonymous') { print "E Only anonymous user allowed via pserver\n"; print "I HATE YOU\n"; + exit 1; } $line = ; chomp $line; # validate the password? $line = ; chomp $line; @@ -181,12 +184,17 @@ sub req_Root } foreach my $line ( @gitvars ) { - next unless ( $line =~ /^(.*?)\.(.*?)=(.*)$/ ); - $cfg->{$1}{$2} = $3; + next unless ( $line =~ /^(gitcvs)\.(?:(ext|pserver)\.)?([\w-]+)=(.*)$/ ); + unless ($2) { + $cfg->{$1}{$3} = $4; + } else { + $cfg->{$1}{$2}{$3} = $4; + } } - unless ( defined ( $cfg->{gitcvs}{enabled} ) and $cfg->{gitcvs}{enabled} =~ /^\s*(1|true|yes)\s*$/i ) - { + my $enabled = ($cfg->{gitcvs}{$state->{method}}{enabled} + || $cfg->{gitcvs}{enabled}); + unless ($enabled && $enabled =~ /^\s*(1|true|yes)\s*$/i) { print "E GITCVS emulation needs to be enabled on this repo\n"; print "E the repo config file needs a [gitcvs] section added, and the parameter 'enabled' set to 1\n"; print "E \n"; @@ -194,9 +202,10 @@ sub req_Root return 0; } - if ( defined ( $cfg->{gitcvs}{logfile} ) ) + my $logfile = $cfg->{gitcvs}{$state->{method}}{logfile} || $cfg->{gitcvs}{logfile}; + if ( $logfile ) { - $log->setfile($cfg->{gitcvs}{logfile}); + $log->setfile($logfile); } else { $log->nofile(); } @@ -350,12 +359,52 @@ sub req_add argsplit("add"); + my $updater = GITCVS::updater->new($state->{CVSROOT}, $state->{module}, $log); + $updater->update(); + + argsfromdir($updater); + my $addcount = 0; foreach my $filename ( @{$state->{args}} ) { $filename = filecleanup($filename); + my $meta = $updater->getmeta($filename); + my $wrev = revparse($filename); + + if ($wrev && $meta && ($wrev < 0)) + { + # previously removed file, add back + $log->info("added file $filename was previously removed, send 1.$meta->{revision}"); + + print "MT +updated\n"; + print "MT text U \n"; + print "MT fname $filename\n"; + print "MT newline\n"; + print "MT -updated\n"; + + unless ( $state->{globaloptions}{-n} ) + { + my ( $filepart, $dirpart ) = filenamesplit($filename,1); + + print "Created $dirpart\n"; + print $state->{CVSROOT} . "/$state->{module}/$filename\n"; + + # this is an "entries" line + my $kopts = kopts_from_path($filepart); + $log->debug("/$filepart/1.$meta->{revision}//$kopts/"); + print "/$filepart/1.$meta->{revision}//$kopts/\n"; + # permissions + $log->debug("SEND : u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}"); + print "u=$meta->{mode},g=$meta->{mode},o=$meta->{mode}\n"; + # transmit file + transmitfile($meta->{filehash}); + } + + next; + } + unless ( defined ( $state->{entries}{$filename}{modified_filename} ) ) { print "E cvs add: nothing known about `$filename'\n"; @@ -843,6 +892,7 @@ sub req_update if ( defined ( $wrev ) and defined($meta->{revision}) and $wrev == $meta->{revision} + and defined($state->{entries}{$filename}{modified_hash}) and not exists ( $state->{opt}{C} ) ) { $log->info("Tell the client the file is modified"); @@ -947,6 +997,7 @@ sub req_update # we need to merge with the local changes ( M=successful merge, C=conflict merge ) $log->info("Merging $file_local, $file_old, $file_new"); + print "M Merging differences between 1.$oldmeta->{revision} and 1.$meta->{revision} into $filename\n"; $log->debug("Temporary directory for merge is $dir"); @@ -973,6 +1024,7 @@ sub req_update elsif ( $return == 1 ) { $log->info("Merged with conflicts"); + print "E cvs update: conflicts found in $filename\n"; print "M C $filename\n"; # Don't want to actually _DO_ the update if -n specified @@ -1024,7 +1076,7 @@ sub req_ci $log->info("req_ci : " . ( defined($data) ? $data : "[NULL]" )); - if ( @ARGV && $ARGV[0] eq 'pserver') + if ( $state->{method} eq 'pserver') { print "error 1 pserver access cannot commit\n"; exit; @@ -1067,6 +1119,7 @@ sub req_ci $log->info("Created index '$file_index' with for head $state->{module} - exit status $?"); my @committedfiles = (); + my %oldmeta; # foreach file specified on the command line ... foreach my $filename ( @{$state->{args}} ) @@ -1077,6 +1130,7 @@ sub req_ci next unless ( exists $state->{entries}{$filename}{modified_filename} or not $state->{entries}{$filename}{unchanged} ); my $meta = $updater->getmeta($filename); + $oldmeta{$filename} = $meta; my $wrev = revparse($filename); @@ -1205,11 +1259,18 @@ sub req_ci $log->debug("Checked-in $dirpart : $filename"); + print "M $state->{CVSROOT}/$state->{module}/$filename,v <-- $dirpart$filepart\n"; if ( defined $meta->{filehash} && $meta->{filehash} eq "deleted" ) { + print "M new revision: delete; previous revision: 1.$oldmeta{$filename}{revision}\n"; print "Remove-entry $dirpart\n"; print "$filename\n"; } else { + if ($meta->{revision} == 1) { + print "M initial revision: 1.1\n"; + } else { + print "M new revision: 1.$meta->{revision}; previous revision: 1.$oldmeta{$filename}{revision}\n"; + } print "Checked-in $dirpart\n"; print "$filename\n"; my $kopts = kopts_from_path($filepart); @@ -1295,7 +1356,7 @@ sub req_status } if ( defined($meta->{revision}) ) { - print "M Repository revision:\t1." . $meta->{revision} . "\t$state->{repository}/$filename,v\n"; + print "M Repository revision:\t1." . $meta->{revision} . "\t$state->{CVSROOT}/$state->{module}/$filename,v\n"; print "M Sticky Tag:\t\t(none)\n"; print "M Sticky Date:\t\t(none)\n"; print "M Sticky Options:\t\t(none)\n"; @@ -2120,25 +2181,40 @@ sub new bless $self, $class; - $self->{dbdir} = $config . "/"; - die "Database dir '$self->{dbdir}' isn't a directory" unless ( defined($self->{dbdir}) and -d $self->{dbdir} ); - $self->{module} = $module; - $self->{file} = $self->{dbdir} . "/gitcvs.$module.sqlite"; - $self->{git_path} = $config . "/"; $self->{log} = $log; die "Git repo '$self->{git_path}' doesn't exist" unless ( -d $self->{git_path} ); - $self->{dbh} = DBI->connect("dbi:SQLite:dbname=" . $self->{file},"",""); + $self->{dbdriver} = $cfg->{gitcvs}{$state->{method}}{dbdriver} || + $cfg->{gitcvs}{dbdriver} || "SQLite"; + $self->{dbname} = $cfg->{gitcvs}{$state->{method}}{dbname} || + $cfg->{gitcvs}{dbname} || "%Ggitcvs.%m.sqlite"; + $self->{dbuser} = $cfg->{gitcvs}{$state->{method}}{dbuser} || + $cfg->{gitcvs}{dbuser} || ""; + $self->{dbpass} = $cfg->{gitcvs}{$state->{method}}{dbpass} || + $cfg->{gitcvs}{dbpass} || ""; + my %mapping = ( m => $module, + a => $state->{method}, + u => getlogin || getpwuid($<) || $<, + G => $self->{git_path}, + g => mangle_dirname($self->{git_path}), + ); + $self->{dbname} =~ s/%([mauGg])/$mapping{$1}/eg; + $self->{dbuser} =~ s/%([mauGg])/$mapping{$1}/eg; + + die "Invalid char ':' in dbdriver" if $self->{dbdriver} =~ /:/; + die "Invalid char ';' in dbname" if $self->{dbname} =~ /;/; + $self->{dbh} = DBI->connect("dbi:$self->{dbdriver}:dbname=$self->{dbname}", + $self->{dbuser}, + $self->{dbpass}); + die "Error connecting to database\n" unless defined $self->{dbh}; $self->{tables} = {}; - foreach my $table ( $self->{dbh}->tables ) + foreach my $table ( keys %{$self->{dbh}->table_info(undef,undef,undef,'TABLE')->fetchall_hashref('TABLE_NAME')} ) { - $table =~ s/^"//; - $table =~ s/"$//; $self->{tables}{$table} = 1; } @@ -2442,7 +2518,7 @@ sub update #$log->debug("ADDED $name"); $head->{$name} = { name => $name, - revision => 1, + revision => $head->{$name}{revision} ? $head->{$name}{revision}+1 : 1, filehash => $hash, commithash => $commit->{hash}, modified => $commit->{date}, @@ -2836,5 +2912,19 @@ sub safe_pipe_capture { return wantarray ? @output : join('',@output); } +=head2 mangle_dirname + +create a string from a directory name that is suitable to use as +part of a filename, mainly by converting all chars except \w.- to _ + +=cut +sub mangle_dirname { + my $dirname = shift; + return unless defined $dirname; + + $dirname =~ s/[^\w.-]/_/g; + + return $dirname; +} 1;