gitweb/indextext_readonly.html: include sample readonly file
[girocco.git] / cgi / html.cgi
blob9f3a67d63a7ba18d797819824958971a46ce40dd
1 #!/usr/bin/perl
2 # (c) Petr Baudis <pasky@suse.cz>
3 # Portions Copyright (c) Kyle J. McKay <mackyle@gmail.com>
4 # GPLv2
6 use strict;
7 use warnings;
9 use Digest::MD5 qw(md5_hex);
11 use lib "__BASEDIR__";
12 use Girocco::CGI;
13 use Girocco::Config;
14 use Girocco::Util;
16 BEGIN {
17 eval {
18 require Digest::SHA;
19 Digest::SHA->import(
20 qw(sha1_hex)
21 );1} ||
22 eval {
23 require Digest::SHA1;
24 Digest::SHA1->import(
25 qw(sha1_hex)
26 );1} ||
27 eval {
28 require Digest::SHA::PurePerl;
29 Digest::SHA::PurePerl->import(
30 qw(sha1_hex)
31 );1} ||
32 die "One of Digest::SHA or Digest::SHA1 or Digest::SHA::PurePerl "
33 . "must be available\n";
36 # Ultra-trivial templating engine;
37 # /^@section=SECTION
38 # /^@heading=HEADING
39 # /^@header produces HTML header based on @section and @heading
40 # /@@gitweburl@@/ substitute for gitweburl configuration variable
41 # /@@base(gitweburl)@@/ substitute for base portion of gitweburl variable
42 # /@@path(gitweburl)@@/ substitute for path portion of gitweburl variable
43 # /@@server(gitweburl)@@/ replace scheme://host:port portion of gitweburl variable
44 # /@@md5(relpath)@@/ produces MD5 hex of file in DOCUMENT_ROOT at relpath
45 # /@@sha1(relpath)@@/ produces SHA1 hex of file in DOCUMENT_ROOT at relpath
46 # /@@blob(relpath)@@/ produces git hash-object -t blob of file in DOCUMENT_ROOT
47 # /@@ifmob@@...@@end@@/ remove unless mob defined
48 # /@@ifssh@@...@@end@@/ remove unless pushurl defined
49 # /@@ifhttps@@...@@end@@/ remove unless httpspushurl defined
50 # /@@ifcustom@@...@@end@@/ remove if pretrustedroot defined (i.e. not custom root)
51 # /@@ctr()@@/ replace with 1-based up-counting value
53 my ($pathinfo, $docroot);
54 # Allow running from the command line
55 if (@ARGV == 2 || @ARGV == 3 and !defined($ENV{REQUEST_METHOD})) {
56 Girocco::CGI::enableHeader(0);
57 $pathinfo = $ARGV[1] || '';
58 $docroot = $ARGV[0] || '';
59 $Girocco::Config::basedir = $ARGV[2] if @ARGV == 3 && -d $ARGV[2];
60 } else {
61 $pathinfo = $ENV{PATH_INFO} || '';
62 $docroot = $ENV{DOCUMENT_ROOT} || '';
64 $pathinfo =~ s,^/,,;
65 unless ($pathinfo) {
66 my $gcgi = Girocco::CGI->new('HTML Templater');
67 print "<p>Hi, this is your friendly HTML templater speaking. Pass me template name.</p>\n";
68 exit;
71 my $templatefd;
72 unless ($pathinfo !~ m#\./# and open($templatefd, '<', "$Girocco::Config::basedir/html/$pathinfo")) {
73 my $gcgi = Girocco::CGI->new('HTML Templater');
74 print "<p>Invalid template name.</p>\n";
75 exit;
78 if ($pathinfo =~ /\.(png|jpe?g|gif|svgz?)$/) {
79 my $kind = $1;
80 $kind = 'jpeg' if $kind eq 'jpg';
81 $kind = 'svg+xml' if $kind =~ /^svg/;
82 print "Content-type: image/$kind\n\n";
83 my $buf;
84 while (read($templatefd, $buf, 32768)) {
85 print $buf;
87 exit;
90 sub get_file_hash {
91 my ($hash, $fn) = @_;
92 return '' unless $docroot && $docroot ne '/' && -d $docroot;
93 return '' if $hash ne 'md5' && $hash ne 'sha1' && $hash ne 'blob';
94 return '' if !$fn || $fn =~ m|^[./]| || $fn =~ m|[.]/| || $fn =~ m|/[.]|;
95 return '' unless -f "$docroot/$fn";
96 open(HASHFILE, '<', "$docroot/$fn") or return '';
97 local $/;
98 undef $/;
99 my $contents = <HASHFILE>;
100 close(HASHFILE);
101 $hash eq 'blob' and $contents = sprintf("blob %u\0", length($contents)) . $contents;
102 return $hash eq 'md5' ? md5_hex($contents) : sha1_hex($contents);
105 my ($gcgi, $section, $heading);
107 my $template=join('', map(to_utf8($_, 1), <$templatefd>));
108 close $templatefd;
109 $template =~ s/@\@ifmob@\@(.*?)@\@end@\@/$Girocco::Config::mob?$1:''/ges;
110 $template =~ s/@\@ifssh@\@(.*?)@\@end@\@/$Girocco::Config::pushurl?$1:''/ges;
111 $template =~ s/@\@ifcustom@\@(.*?)@\@end@\@/!$Girocco::Config::pretrustedroot?$1:''/ges;
112 $template =~ s/@\@ifhttps@\@(.*?)@\@end@\@/$Girocco::Config::httpspushurl?$1:''/ges;
114 my $counter = 0;
116 foreach (split(/\n/, $template)) {
117 chomp;
118 if (s/^\@section=//) {
119 $section = $_;
120 next;
121 } elsif (s/^\@heading=//) {
122 $heading = $_;
123 next;
124 } elsif (s/^\@header//) {
125 $gcgi = Girocco::CGI->new($heading, $section);
126 print "<div class=\"htmlcgi\">";
127 next;
128 } else {
129 s/@@(\w+?)@@/${$Girocco::Config::{$1}}/ge;
130 s/@\@base\((\w+?)\)@@/url_base(${$Girocco::Config::{$1}})/ge;
131 s/@\@path\((\w+?)\)@@/url_path(${$Girocco::Config::{$1}})/ge;
132 s/@\@server\((\w+?)\)@@/url_server(${$Girocco::Config::{$1}})/ge;
133 s/@\@(md5|sha1|blob)\(([^()]+?)\)@@/get_file_hash($1,$2)/ge;
134 s/@\@ctr\(\)@@/++$counter/ge;
135 print "$_\n";
138 print "</div>";
139 $gcgi and $gcgi->srcname("html/$pathinfo");