X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/e3f91afc4c1555a0bdc9731a6df3ee75094abfd6e9c94cf8024c84004da6d63d..2632541dc57dd0ccba7e315e2755c9dbd028ed210fff7a39a86c0346e879e365:/gitweb.cgi diff --git a/gitweb.cgi b/gitweb.cgi index 14d5541..7d50f04 100755 --- a/gitweb.cgi +++ b/gitweb.cgi @@ -38,10 +38,22 @@ my $home_link = $my_uri; # html text to include at home page my $home_text = "indextext.html"; +# URI of default stylesheet +my $stylesheet = "gitweb.css"; + # source of projects list #my $projects_list = $projectroot; my $projects_list = "index/index.aux"; +# default blob_plain mimetype and default charset for text/plain blob +my $default_blob_plain_mimetype = 'text/plain'; +my $default_text_plain_charset = undef; + +# file to use for guessing MIME types before trying /etc/mime.types +# (relative to the current git repository) +my $mimetypes_file = undef; + + # input validation and dispatch my $action = $cgi->param('a'); if (defined $action) { @@ -249,6 +261,12 @@ sub git_header_html { $title .= " - $project"; if (defined $action) { $title .= "/$action"; + if (defined $file_name) { + $title .= " - $file_name"; + if ($action eq "tree" && $file_name !~ m|/$|) { + $title .= "/"; + } + } } } print $cgi->header(-type=>'text/html', -charset => 'utf-8', -status=> $status, -expires => $expires); @@ -260,68 +278,9 @@ sub git_header_html { + $title $rss_link - EOF @@ -837,6 +796,25 @@ sub git_read_projects { return @list; } +sub git_get_project_config { + my $key = shift; + + return unless ($key); + $key =~ s/^gitweb\.//; + return if ($key =~ m/\W/); + + my $val = qx(git-repo-config --get gitweb.$key); + return ($val); +} + +sub git_get_project_config_bool { + my $val = git_get_project_config (@_); + if ($val and $val =~ m/true|yes|on/) { + return (1); + } + return; # implicit false +} + sub git_project_list { my @list = git_read_projects(); my @projects; @@ -1233,6 +1211,7 @@ sub git_tag { sub git_blame { my $fd; + die_error('403 Permission denied', "Permission denied.") if (!git_get_project_config_bool ('blame')); die_error('404 Not Found', "What file will it be, master?") if (!$file_name); $hash_base ||= git_read_head($project); die_error(undef, "Reading commit failed.") unless ($hash_base); @@ -1468,6 +1447,7 @@ sub git_blob { my $base = $hash_base || git_read_head($project); $hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file."); } + my $have_blame = git_get_project_config_bool ('blame'); open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or die_error(undef, "Open failed."); git_header_html(); if (defined $hash_base && (my %co = git_read_commit($hash_base))) { @@ -1479,8 +1459,10 @@ sub git_blob { " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . "
\n"; if (defined $file_name) { - print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name")}, "blame") . - " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash;f=$file_name")}, "plain") . + if ($have_blame) { + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name")}, "blame") . " | "; + } + print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash;f=$file_name")}, "plain") . " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=HEAD;f=$file_name")}, "head") . "
\n"; } else { print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash")}, "plain") . "
\n"; @@ -1515,15 +1497,85 @@ sub git_blob { git_footer_html(); } +sub mimetype_guess_file { + my $filename = shift; + my $mimemap = shift; + -r $mimemap or return undef; + + my %mimemap; + open(MIME, $mimemap) or return undef; + while () { + my ($mime, $exts) = split(/\t+/); + my @exts = split(/\s+/, $exts); + foreach my $ext (@exts) { + $mimemap{$ext} = $mime; + } + } + close(MIME); + + $filename =~ /\.(.*?)$/; + return $mimemap{$1}; +} + +sub mimetype_guess { + my $filename = shift; + my $mime; + $filename =~ /\./ or return undef; + + if ($mimetypes_file) { + my $file = $mimetypes_file; + #$file =~ m#^/# or $file = "$projectroot/$path/$file"; + $mime = mimetype_guess_file($filename, $file); + } + $mime ||= mimetype_guess_file($filename, '/etc/mime.types'); + return $mime; +} + +sub git_blob_plain_mimetype { + my $fd = shift; + my $filename = shift; + + # just in case + return $default_blob_plain_mimetype unless $fd; + + if ($filename) { + my $mime = mimetype_guess($filename); + $mime and return $mime; + } + + if (-T $fd) { + return 'text/plain' . + ($default_text_plain_charset ? '; charset='.$default_text_plain_charset : ''); + } elsif (! $filename) { + return 'application/octet-stream'; + } elsif ($filename =~ m/\.png$/i) { + return 'image/png'; + } elsif ($filename =~ m/\.gif$/i) { + return 'image/gif'; + } elsif ($filename =~ m/\.jpe?g$/i) { + return 'image/jpeg'; + } else { + return 'application/octet-stream'; + } +} + sub git_blob_plain { - my $save_as = "$hash.txt"; + open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or return; + my $type = git_blob_plain_mimetype($fd, $file_name); + + # save as filename, even when no $file_name is given + my $save_as = "$hash"; if (defined $file_name) { $save_as = $file_name; + } elsif ($type =~ m/^text\//) { + $save_as .= '.txt'; } - print $cgi->header(-type => "text/plain", -charset => 'utf-8', '-content-disposition' => "inline; filename=\"$save_as\""); - open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or return; + + print $cgi->header(-type => "$type", '-content-disposition' => "inline; filename=\"$save_as\""); undef $/; + binmode STDOUT, ':raw'; print <$fd>; + binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi $/ = "\n"; close $fd; }