From 80573baec4a6211fc9a01d83690c0d73015cfbdc Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Mon, 19 Mar 2007 16:55:57 +0100 Subject: cvsserver: Introduce new state variable 'method' $state->{method} contains the CVS access method used, either 'ext' or 'pserver' Signed-off-by: Frank Lichtenheld Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'git-cvsserver.perl') diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 68aa75255..e9d489bc3 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"; @@ -1026,7 +1028,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; -- cgit v1.2.1 From 92a39a14d00fdfe6868bacf86cbf933a2cc6be93 Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Mon, 19 Mar 2007 16:55:58 +0100 Subject: cvsserver: Handle three part keys in git config correctly This is intended to be used in the form gitcvs.. but this patch doesn't introduce any users yet. Signed-off-by: Frank Lichtenheld Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'git-cvsserver.perl') diff --git a/git-cvsserver.perl b/git-cvsserver.perl index e9d489bc3..4edb79601 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -183,8 +183,12 @@ sub req_Root } foreach my $line ( @gitvars ) { - next unless ( $line =~ /^(.*?)\.(.*?)=(.*)$/ ); - $cfg->{$1}{$2} = $3; + next unless ( $line =~ /^(.*?)\.(.*?)(?:\.(.*?))?=(.*)$/ ); + unless ($3) { + $cfg->{$1}{$2} = $4; + } else { + $cfg->{$1}{$2}{$3} = $4; + } } unless ( defined ( $cfg->{gitcvs}{enabled} ) and $cfg->{gitcvs}{enabled} =~ /^\s*(1|true|yes)\s*$/i ) -- cgit v1.2.1 From d55820ced668477e07be7d9488c7965906a61b54 Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Mon, 19 Mar 2007 16:55:59 +0100 Subject: cvsserver: Allow to override the configuration per access method Allow to override the gitcvs.enabled and gitcvs.logfile configuration variables for each access method (i.e. "ext" or "pserver") in the form gitcvs.. Signed-off-by: Frank Lichtenheld Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'git-cvsserver.perl') diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 4edb79601..5d2b6f357 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -191,7 +191,10 @@ sub req_Root } } - unless ( defined ( $cfg->{gitcvs}{enabled} ) and $cfg->{gitcvs}{enabled} =~ /^\s*(1|true|yes)\s*$/i ) + unless ( ($cfg->{gitcvs}{$state->{method}}{enabled} + and $cfg->{gitcvs}{$state->{method}}{enabled} =~ /^\s*(1|true|yes)\s*$/i) + or ($cfg->{gitcvs}{enabled} + and $cfg->{gitcvs}{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"; @@ -200,9 +203,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(); } -- cgit v1.2.1 From eb1780d480c2c57c58024692055a6ee33074a95f Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Mon, 19 Mar 2007 16:56:00 +0100 Subject: cvsserver: Make the database backend configurable Make all the different parts of the database backend connection configurable. This adds the following string configuration variables: - gitcvs.dbdriver - gitcvs.dbname - gitcvs.dbuser - gitcvs.dbpass The default values emulate the current behavior exactly for backwards compatibility. All configuration variables can also be specified for a specific access method (i.e. in the form gitcvs..) The dbdriver/dbuser/dbpass variables are added for completness. No other backend than SQLite is tested yet. The dbname variable on the other hand is useful with this backend already (to not discriminate against other possible backends it was not splitted in dbdir and dbfile). Both dbname and dbuser support dynamic variable substitution where the available variables are: %m -- the CVS 'module' (i.e. GIT 'head') worked on %a -- CVS access method used (i.e. 'ext' or 'pserver') %u -- User name of the user invoking git-cvsserver %G -- .git directory name %g -- .git directory name, mangled to be used in a filename, currently this substitutes all chars except for [\w.-] with '_' Signed-off-by: Frank Lichtenheld Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'git-cvsserver.perl') diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 5d2b6f357..6d10aa334 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -2141,19 +2141,33 @@ 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} || "dbi: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; + + $self->{dbh} = DBI->connect("$self->{dbdriver}:dbname=$self->{dbname}", + $self->{dbuser}, + $self->{dbpass}); $self->{tables} = {}; foreach my $table ( $self->{dbh}->tables ) @@ -2857,5 +2871,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; -- cgit v1.2.1 From 920a449af5a6b4ecbf01a5a4e3bc4894ad302634 Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Mon, 19 Mar 2007 16:56:01 +0100 Subject: cvsserver: Abort if connect to database fails Currently all calls to the database backend make no error checking or handling at all. At least abort if the connection to the database failed since there is really no way we could do anything useful after that. Signed-off-by: Frank Lichtenheld Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 1 + 1 file changed, 1 insertion(+) (limited to 'git-cvsserver.perl') diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 6d10aa334..941a91bca 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -2168,6 +2168,7 @@ sub new $self->{dbh} = DBI->connect("$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 ) -- cgit v1.2.1 From 0cf611a300fbbbd12827f9defb9cbcc934a3b1d6 Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Sat, 31 Mar 2007 15:57:47 +0200 Subject: cvsserver: Use DBI->table_info instead of DBI->tables DBI->table_info is portable across different DBD backends, DBI->tables is not. Limit the output to objects of type TABLE. Signed-off-by: Junio C Hamano Signed-off-by: Frank Lichtenheld --- git-cvsserver.perl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'git-cvsserver.perl') diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 941a91bca..5532ae7a3 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -2171,10 +2171,8 @@ sub new 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; } -- cgit v1.2.1 From 473937ed44c112e5d3ced52ab3f9a9e53eccc272 Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Sat, 7 Apr 2007 16:58:09 +0200 Subject: cvsserver: Corrections to the database backend configuration Don't include the scheme name in gitcvs.dbdriver, it is always 'dbi' anyway. Don't allow ':' in driver names nor ';' in database names for sanity reasons. Signed-off-by: Frank Lichtenheld Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'git-cvsserver.perl') diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 5532ae7a3..7fe7949b3 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -2149,7 +2149,7 @@ sub new die "Git repo '$self->{git_path}' doesn't exist" unless ( -d $self->{git_path} ); $self->{dbdriver} = $cfg->{gitcvs}{$state->{method}}{dbdriver} || - $cfg->{gitcvs}{dbdriver} || "dbi:SQLite"; + $cfg->{gitcvs}{dbdriver} || "SQLite"; $self->{dbname} = $cfg->{gitcvs}{$state->{method}}{dbname} || $cfg->{gitcvs}{dbname} || "%Ggitcvs.%m.sqlite"; $self->{dbuser} = $cfg->{gitcvs}{$state->{method}}{dbuser} || @@ -2165,7 +2165,9 @@ sub new $self->{dbname} =~ s/%([mauGg])/$mapping{$1}/eg; $self->{dbuser} =~ s/%([mauGg])/$mapping{$1}/eg; - $self->{dbh} = DBI->connect("$self->{dbdriver}:dbname=$self->{dbname}", + 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}; -- cgit v1.2.1 From 4db0c8dec5c009cbbb61135a321a48278e668a25 Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Thu, 12 Apr 2007 00:51:33 +0200 Subject: cvsserver: Allow to "add" a removed file CVS allows you to add a removed file (where the removal is not yet committed) which will cause the server to send the latest revision of the file and to delete the "removed" status. Copy this behaviour. Signed-off-by: Frank Lichtenheld Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'git-cvsserver.perl') diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 7fe7949b3..d5674caaa 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -360,12 +360,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"; -- cgit v1.2.1