밤새 lxr을 설치했는데.... 펄스크립트 문제..특정 파일을 보여
삽질끝에 lxr의 설치를 다했습니다.
lxr-0.9.4를 sf.net에서 다운받아 설치하고
glimpse 도 같이 설치하고
겨우 겨우 설치를 다 했는데............
대부분의 파일이 다 보입니다.
근데.. 몇몇 파일만 내용이 안보이데요 ㅠㅠ 울면서 이것 저것 막 열어봤더니
파일 경로에 마이너스 기호가 있는 파일만 열리지가 않습니다.
예를 들어
/aaa/bbb/ddd.c 는 잘 열리지만
/aaa/bbb/ddd-1.c 는 안열립니다.
웹상에서 lxr에 파일명이 ddd를 포함하고 있는
모든 파일을 검색했더니 아래와 같이 검색이 되는데
/aaa/bbb/ddd.c
/aaa/bbb/ddd-1.c
상세내용을 보려고 하면
ddd-1.c 파일을 볼수가 없습니다.
디렉토리도 마찬가지로 마이너스 기호가 있으면
서브디렉토리 목록이 안나오네요
스크립트를 보니깐..
디렉토리나 파일 오픈이 실패하면 파일이 없다는 오류를 뿌리는데
웹 페이지 상에 파일이 없다는 오류를 뿌리지 않는거 보면 오픈은 성공하는 것 같은데..
( 제가 5번 정도 설치했는데..환경설정이 잘못되서
실제로 파일경로를 잘못 적은 적도 있엇거든요..
그때는 파일이 없다는 에러를 뿌려주었었습니다
근데 이번엔 파일이 없다는 에러를 뿌리지는 않는군요
)
아래는 혹시나 하는 마음으로
펄스크립트 파일 두개를 첨부해드립니다.
경로를 파싱하는 펄 스크립트 하나와
그 펄스크립트가 참조하는(라이브러리인가) 스크립트도 첨부해봅니다.
아래의 파일이 /source/aaa/bbb/ddd-1.c 의 경로명을 파싱해서 실제로 html 형태로 뿌려주는 펄스크립트인데.. 문법이 너무 어려워서리.. #!/usr/bin/perl -T # $Id: source,v 1.44 2004/09/02 15:26:42 brondsem Exp $ # source -- Present sourcecode as html, complete with references # the '/icons' images are available in any standard Apache installation # # Arne Georg Gleditsch <argggh@ifi.uio.no> # Per Kristian Gjermshus <pergj@ifi.uio.no> # # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ###################################################################### $CVSID = '$Id: source,v 1.44 2004/09/02 15:26:42 brondsem Exp $ '; use strict; use lib '.'; # for Local.pm use lib do { $0 =~ m{(.*)/} ? "$1/lib" : "lib" }; # if LXR modules are in ./lib use LXR::Common qw(:html); use Local; sub diricon { my ($templ, $node, $dir) = @_; my $img; if ($node eq '../') { $img = "/icons/back.gif"; } else { $img = "/icons/folder.gif"; } return fileref("<img align=\"bottom\" border=\"0\" src=\"$img\" alt=\"folder\">", "", $dir . $node); } sub dirname { my ($templ, $node, $dir) = @_; if ($node eq '../') { return fileref("Parent directory", "dirfolder", $dir . $node); } else { return fileref($node, "dirfolder", $dir . $node); } } sub fileicon { my ($templ, $node, $dir) = @_; my $img; if ($node =~ /^.*\.[ch]$/) { $img = "/icons/c.gif"; } elsif ($node =~ /^.*\.(cpp|cc|java)$/) { # TODO: Find a nice icon for c++ files (KDE?) $img = "/icons/c.gif"; } elsif ($node =~ /^.*\.(txt)$/) { $img = "/icons/text.gif"; } elsif ($node =~ /^.*\.(jar|war|ear|zip|tar|gz|tgz|cab)$/) { $img = "/icons/compressed.gif"; } elsif ($node =~ /^.*\.(jpg|jpeg|gif|bmp|png)$/) { $img = "/icons/image2.gif"; } else { $img = "/icons/generic.gif"; } return fileref("<img align=\"bottom\" border=\"0\" src=\"$img\" alt=\"\">", "", $dir . $node); } sub filename { my ($templ, $node, $dir) = @_; return fileref($node, "dirfile", $dir . $node); } sub filesize { my ($templ, $node, $dir) = @_; my $s = $files->getfilesize($dir . $node, $release); my $str; if ($s < 1 << 10) { $str = "$s"; } else { # if ($s < 1<<20) { $str = ($s >> 10) . "k"; # } else { # $str = ($s>>20) . "M"; # } } return expandtemplate( $templ, ( 'bytes' => sub { return $str }, 'kbytes' => sub { return $str }, 'mbytes' => sub { return $str } ) ); } sub modtime { my ($templ, $node, $dir) = @_; my $current_time = time; my $file_time = $files->getfiletime($dir . $node, $release); return '-' unless defined($file_time); my @t = gmtime($file_time); my ($sec, $min, $hour, $mday, $mon, $year) = @t; return sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec); } sub bgcolor { my ($templ, $line) = @_; return ((($line - 1) / 3) % 2) ? "#FFFFFF" : "#EEEEEE"; } sub rowclass { my ($templ, $line) = @_; return ((($line - 1) / 3) % 2) ? "dirrow2" : "dirrow1"; } sub direxpand { my ($templ, $dir) = @_; my $direx = ''; my $line = 1; my %index; my @nodes; my $node; @nodes = $files->getdir($dir, $release); unless (@nodes) { print( "<p align=\"center\">\n<i>The directory " . $files->toreal($dir, $release) . " does not exist.</i>\n"); print( "\<p align=\"center\">\n<i>This directory might exist in other versions, try 'Show attic files' or select a different Version.</i>\n" ) if $files->isa("LXR::Files::CVS") and !$HTTP->{'param'}->{'showattic'}; #FIXME what does this do? if ($files->toreal($dir, $release) =~ m#(.+[^/])[/]*$#) { if (-e $1) { warning("Unable to open " . $files->toreal($dir, $release)); } } return; } unshift(@nodes, '../') unless $dir eq '/'; #CSS checked _PH_ foreach $node (@nodes) { if ($node =~ /\/$/) { $direx .= expandtemplate( $templ, ( 'iconlink' => sub { diricon(@_, $node, $dir) }, 'namelink' => sub { dirname(@_, $node, $dir) }, 'filesize' => sub { '-' }, 'modtime' => sub { modtime(@_, $node, $dir) }, 'bgcolor' => sub { bgcolor(@_, $line++) }, 'css' => sub { rowclass(@_, $line++) }, 'description' => sub { descexpand(@_, $node, $dir, $release) } ) ); } else { next if $node =~ /^.*\.[oa]$|^core$|^00-INDEX$/; $direx .= expandtemplate( $templ, ( 'iconlink' => sub { fileicon(@_, $node, $dir) }, 'namelink' => sub { filename(@_, $node, $dir) }, 'filesize' => sub { filesize(@_, $node, $dir) }, 'modtime' => sub { modtime(@_, $node, $dir) }, 'bgcolor' => sub { bgcolor(@_, $line++) }, 'css' => sub { rowclass(@_, $line++) }, 'description' => sub { ( $files->toreal($dir . $node, $release) =~ m|/Attic/| ? "<i>In Attic</i> " : "" ) . descexpand(@_, $node, $dir, $release); } ) ); } } return ($direx); } sub printdir { my $dir = shift; my $templ; $templ = "<ul>\n\$files{\n<li>\$iconlink \$namelink\n}</ul>\n"; if ($config->htmldir) { unless (open(TEMPL, $config->htmldir)) { warning("Template " . $config->htmldir . " does not exist."); } else { local ($/) = undef; $templ = <TEMPL>; close(TEMPL); } } # print the description of the current directory print dirdesc($dir, $release); # print the listing itself print(expandtemplate($templ, ('files' => sub { direxpand(@_, $dir) }))); } sub printfile { my $raw = shift; if ($pathname =~ m|/$|) { printdir($pathname); } else { my $fileh = $files->getfilehandle($pathname, $release); if ($fileh) { if ($raw) { print($fileh->getlines ); } else { if ($config->cvswebprefix) { my $revtarget = ""; $revtarget = "#rev$release" if lc($release) ne "head"; print "<a href='" . $config->cvswebprefix . $pathname . $config->cvswebpostfix . $revtarget . "'>View CVS Log</a>"; } my @ann = $files->getannotations($pathname, $release); if (@ann) { my ($a, $b); foreach $a (@ann) { if ($a eq $b) { $a = ' ' x 16; next; } $b = $a; $a .= ' ' x (6 - length($a)) . $files->getauthor($pathname, $a); $a .= ' ' x (16 - length($a)); } } my $l; my $outfun = sub { $l = shift; $l =~ s/(\n)/$1.shift(@ann)/ge; print $l; }; &$outfun("<pre class=\"file\">\n"); markupfile($fileh, $outfun); &$outfun("</pre>\n"); } } else { print("\<p align=\"center\">\n<i>The file $pathname does not exist.</i>\n"); print( "\<p align=\"center\">\n<i>This file might exist in other versions, try 'Show attic files' or select a different Version.</i>\n" ) if $files->isa("LXR::Files::CVS") and !$HTTP->{'param'}->{'showattic'}; if (-f $files->toreal($pathname, $release)) { warning("Unable to open " . $files->toreal($pathname, $release)); } } } } httpinit; if ($config->filter && $pathname !~ $config->filter) { makeheader('source'); print("\<p align=\"center\">\n<i>The file $pathname does not exist.</i>\n"); makefooter('source'); exit; } # If the file is html then simply pump it out. if ($pathname =~ /\.(html)$/ || $HTTP->{'param'}->{'raw'}) { printfile(1); } else { my $type = ($pathname !~ m|/$| ? 'source' : 'sourcedir'); makeheader($type); printfile(0); makefooter($type); } httpclean;
이 파일은 Common.pm 파일입니다.
아마도 위의 펄스크립트에서 참조하는 것 같습니다
# -*- tab-width: 4 -*- ############################################### # # $Id: Common.pm,v 1.51 2005/05/04 23:19:33 mbox Exp $ # # FIXME: java doesn't support super() or super.x # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. package LXR::Common; $CVSID = '$Id: Common.pm,v 1.51 2005/05/04 23:19:33 mbox Exp $ '; use strict; require Exporter; use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $files $index $config $pathname $identifier $release $HTTP $wwwdebug $tmpcounter); @ISA = qw(Exporter); @EXPORT = qw($files $index $config &fatal); @EXPORT_OK = qw($files $index $config $pathname $identifier $release $HTTP &warning &fatal &abortall &fflush &urlargs &fileref &idref &incref &htmlquote &freetextmarkup &markupfile &markupstring &httpinit &makeheader &makefooter &expandtemplate &httpclean); %EXPORT_TAGS = ('html' => [@EXPORT_OK]); require Local; require LXR::SimpleParse; require LXR::Config; require LXR::Files; require LXR::Index; require LXR::Lang; $wwwdebug = 0; $tmpcounter = 23; sub warning { my $c = join(", line ", (caller)[ 0, 2 ]); print(STDERR "[", scalar(localtime), "] warning: $c: $_[0]\n"); print("<h4 align=\"center\"><i>** Warning: $_[0]</i></h4>\n") if $wwwdebug; } sub fatal { my $c = join(", line ", (caller)[ 0, 2 ]); print(STDERR "[", scalar(localtime), "] fatal: $c: $_[0]\n"); print(STDERR '[@INC ', join(" ", @INC), ' $0 ', $0, "\n"); print(STDERR '$config', join(" ", %$config), "\n") if ref($config) eq "HASH"; print("<h4 align=\"center\"><i>** Fatal: $_[0]</i></h4>\n") if $wwwdebug; exit(1); } sub abortall { my $c = join(", line ", (caller)[ 0, 2 ]); print(STDERR "[", scalar(localtime), "] abortall: $c: $_[0]\n"); print( "Content-Type: text/html; charset=iso-8859-1\n\n", "<html>\n<head>\n<title>Abort</title>\n</head>\n", "<body><h1>Abort!</h1>\n", "<b><i>** Aborting: $_[0]</i></b>\n", "</body>\n</html>\n" ) if $wwwdebug; exit(1); } sub fflush { $| = 1; print(''); } sub tmpcounter { return $tmpcounter++; } sub urlargs { my @args = @_; my %args = (); my $val; foreach (@args) { $args{$1} = $2 if /(\S+)=(\S*)/; } @args = (); foreach ($config->allvariables) { $val = $args{$_} || $config->variable($_); push(@args, "$_=$val") unless ($val eq $config->vardefault($_)); delete($args{$_}); } foreach (keys(%args)) { push(@args, "$_=$args{$_}"); } return ($#args < 0 ? '' : '?' . join(';', @args)); } sub fileref { my ($desc, $css, $path, $line, @args) = @_; # jwz: URL-quote any special characters. $path =~ s|([^-a-zA-Z0-9.\@/_\r\n])|sprintf("%%%02X", ord($1))|ge; if ($line > 0 && length($line) < 3) { $line = ('0' x (3 - length($line))) . $line; } return ("<a class='$css' href=\"$config->{virtroot}/source$path" . &urlargs(@args) . ($line > 0 ? "#$line" : "") . "\"\>$desc</a>"); } sub diffref { my ($desc, $css, $path, $darg) = @_; my $dval; ($darg, $dval) = $darg =~ /(.*?)=(.*)/; return ("<a class='$css' href=\"$config->{virtroot}/diff$path" . &urlargs(($darg ? "diffvar=$darg" : ""), ($dval ? "diffval=$dval" : "")) . "\"\>$desc</a>"); } sub idref { my ($desc, $css, $id, @args) = @_; return ("<a class='$css' href=\"$config->{virtroot}/ident" . &urlargs(($id ? "i=$id" : ""), @args) . "\"\>$desc</a>"); } sub incref { my ($name, $css, $file, @paths) = @_; my ($dir, $path); push(@paths, $config->incprefix); foreach $dir (@paths) { $dir =~ s/\/+$//; $path = $config->mappath($dir . "/" . $file); return &fileref($name, $css, $path) if $files->isfile($path, $release); } return $name; } sub http_wash { my $t = shift; if (!defined($t)) { return (undef); } $t =~ s/\+/ /g; $t =~ s/\%([\da-f][\da-f])/pack("C", hex($1))/gie; return ($t); } # dme: Smaller version of the markupfile function meant for marking up # the descriptions in source directory listings. sub markupstring { my ($string, $virtp) = @_; # Mark special characters so they don't get processed just yet. $string =~ s/([\&\<\>])/\0$1/g; # Look for identifiers and create links with identifier search query. # TODO: Is there a performance problem with this? $string =~ s#(^|\s)([a-zA-Z_~][a-zA-Z0-9_]*)\b# $1.(is_linkworthy($2) ? &idref($2, "", $2) : $2)#ge; # HTMLify the special characters we marked earlier, # but not the ones in the recently added xref html links. $string =~ s/\0&/&/g; $string =~ s/\0</</g; $string =~ s/\0>/>/g; # HTMLify email addresses and urls. $string =~ s#((ftp|http|nntp|snews|news)://(\w|\w\.\w|\~|\-|\/|\#)+(?!\.\b))#<a href=\"$1\">$1</a>#g; # htmlify certain addresses which aren't surrounded by <> $string =~ s/([\w\-\_]*\@netscape.com)(?!>)/<a href=\"mailto:$1\">$1<\/a>/g; $string =~ s/([\w\-\_]*\@mozilla.org)(?!>)/<a href=\"mailto:$1\">$1<\/a>/g; $string =~ s/([\w\-\_]*\@gnome.org)(?!>)/<a href=\"mailto:$1\">$1<\/a>/g; $string =~ s/([\w\-\_]*\@linux.no)(?!>)/<a href=\"mailto:$1\">$1<\/a>/g; $string =~ s/([\w\-\_]*\@sourceforge.net)(?!>)/<a href=\"mailto:$1\">$1<\/a>/g; $string =~ s/([\w\-\_]*\@sf.net)(?!>)/<a href=\"mailto:$1\">$1<\/a>/g; $string =~ s/(<)(.*@.*)(>)/$1<a href=\"mailto:$2\">$2<\/a>$3/g; # HTMLify file names, assuming file is in the current directory. $string =~ s#\b(([\w\-_\/]+\.(c|h|cc|cp|hpp|cpp|java))|README)\b#<a href=\"$config->{virtroot}/source$virtp$1\">$1</a>#g; return ($string); } # dme: Return true if string is in the identifier db and it seems like its # use in the sentence is as an identifier and its not just some word that # happens to have been used as a variable name somewhere. We don't want # words like "of", "to" and "a" to get links. The string must be long # enough, and either contain "_" or if some letter besides the first # is capitalized sub is_linkworthy { my ($string) = @_; if ( $string =~ /....../ && ($string =~ /_/ || $string =~ /.[A-Z]/) # && defined($xref{$string}) FIXME ) { return (1); } else { return (0); } } sub markspecials { $_[0] =~ s/([\&\<\>])/\0$1/g; } sub htmlquote { $_[0] =~ s/\0&/&/g; $_[0] =~ s/\0</</g; $_[0] =~ s/\0>/>/g; } sub freetextmarkup { $_[0] =~ s{((f|ht)tp://[^\s<>\0]*[^\s<>\0.])} {<a class='offshore' href="$1">$1</a>}g; $_[0] =~ s{(\0<([^\s<>\0]+@[^\s<>\0]+)\0>)} {<a class='offshore' href="mailto:$2">$1</a>}g; } sub markupfile { #_PH_ supress block is here to avoid the <pre> tag output #while called from diff my ($fileh, $outfun) = @_; my ($dir) = $pathname =~ m|^(.*/)|; my $line = '001'; my @ltag = &fileref(1, "fline", $pathname, 1) =~ /^(<a)(.*\#)001(\">)1(<\/a>)$/; $ltag[0] .= ' name='; $ltag[3] .= " "; my @itag = &idref(1, "fid", 1) =~ /^(.*=)1(\">)1(<\/a>)$/; my $lang = new LXR::Lang($pathname, $release, @itag); # A source code file if ($lang) { my $language = $lang->language; # To get back to the key to lookup the tabwidth. &LXR::SimpleParse::init($fileh, $config->filetype->{$language}[3], $lang->parsespec); my ($btype, $frag) = &LXR::SimpleParse::nextfrag; #&$outfun("<pre class=\"file\">\n"); &$outfun(join($line++, @ltag)) if defined($frag); while (defined($frag)) { &markspecials($frag); if ($btype eq 'comment') { # Comment # Convert mail adresses to mailto: &freetextmarkup($frag); $lang->processcomment(\$frag); } elsif ($btype eq 'string') { # String $frag = "<span class='string'>$frag</span>"; } elsif ($btype eq 'include') { # Include directive $lang->processinclude(\$frag, $dir); } else { # Code $lang->processcode(\$frag); } &htmlquote($frag); my $ofrag = $frag; ($btype, $frag) = &LXR::SimpleParse::nextfrag; $ofrag =~ s/\n$// unless defined($frag); $ofrag =~ s/\n/"\n".join($line++, @ltag)/ge; &$outfun($ofrag); } #&$outfun("</pre>"); } elsif ($pathname =~ /$config->graphicfile/) { &$outfun("<ul><table><tr><th valign=\"center\"><b>Image: </b></th>"); &$outfun("<img src=\"$config->{virtroot}/source" . $pathname . &urlargs("raw=1") . "\" border=\"0\" alt=\"$pathname\">\n"); &$outfun("</tr></td></table></ul>"); } elsif ($pathname =~ m|/CREDITS$|) { while (defined($_ = $fileh->getline)) { &LXR::SimpleParse::untabify($_); &markspecials($_); &htmlquote($_); s/^N:\s+(.*)/<strong>$1<\/strong>/gm; s/^(E:\s+)(\S+@\S+)/$1<a href=\"mailto:$2\">$2<\/a>/gm; s/^(W:\s+)(.*)/$1<a href=\"$2\">$2<\/a>/gm; # &$outfun("<a name=\"L$.\"><\/a>".$_); &$outfun(join($line++, @ltag) . $_); } } else { return unless defined($_ = $fileh->getline); # If it's not a script or something with an Emacs spec header and # the first line is very long or containts control characters... if ( !/^\#!/ && !/-\*-.*-\*-/i && (length($_) > 132 || /[\000-\010\013\014\016-\037\200-?/)) { # We postulate that it's a binary file. &$outfun("<ul><b>Binary File: "); # jwz: URL-quote any special characters. my $uname = $pathname; $uname =~ s|([^-a-zA-Z0-9.\@/_\r\n])|sprintf("%%%02X", ord($1))|ge; &$outfun("<a href=\"$config->{virtroot}/source" . $uname . &urlargs("raw=1") . "\">"); &$outfun("$pathname</a></b>"); &$outfun("</ul>"); } else { #&$outfun("<pre class=\"file\">\n"); do { &LXR::SimpleParse::untabify($_); &markspecials($_); &freetextmarkup($_); &htmlquote($_); # &$outfun("<a name=\"L$.\"><\/a>".$_); &$outfun(join($line++, @ltag) . $_); } while (defined($_ = $fileh->getline)); #&$outfun("</pre>"); } } } sub fixpaths { my $node = '/' . shift; while ($node =~ s|/[^/]+/\.\./|/|g) { } $node =~ s|/\.\./|/|g; $node .= '/' if $files->isdir($node); $node =~ s|//+|/|g; return $node; } sub printhttp { # Print out a Last-Modified date that is the larger of: the # underlying file that we are presenting; and the "source" script # itself (passed in as an argument to this function.) If we can't # stat either of them, don't print out a L-M header. (Note that this # stats lxr/source but not lxr/lib/LXR/Common.pm. Oh well, I can # live with that I guess...) -- jwz, 16-Jun-98 # Made it stat all currently loaded modules. -- agg. # Todo: check lxr.conf. my $time = $files->getfiletime($pathname, $release); my $time2 = (stat($config->confpath))[9]; $time = $time2 if $time2 > $time; # Remove this to see if we get a speed increase by not stating all # the modules. Since for most sites the modules change rarely, # this is a big hit for each access. # my %mods = ('main' => $0, %INC); # my ($mod, $path); # while (($mod, $path) = each %mods) { # $mod =~ s/.pm$//; # $mod =~ s|/|::|g; # $path =~ s|/+|/|g; # no strict 'refs'; # next unless $ {$mod.'::CVSID'}; # $time2 = (stat($path))[9]; # $time = $time2 if $time2 > $time; # } if ($time > 0) { my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($time); my @days = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"); my @months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); $year += 1900; $wday = $days[$wday]; $mon = $months[$mon]; # Last-Modified: Wed, 10 Dec 1997 00:55:32 GMT printf("Last-Modified: %s, %2d %s %d %02d:%02d:%02d GMT\n", $wday, $mday, $mon, $year, $hour, $min, $sec); } if ($HTTP->{'param'}->{'raw'}) { #FIXME - need more types here my %type = ( 'gif' => 'image/gif', 'html' => 'text/html' ); if ($pathname =~ /\.([^.]+)$/ && $type{$1}) { print("Content-type: ", $type{$1}, "\n"); } else { print("Content-Type: text/plain\n"); } } else { print("Content-Type: text/html; charset=iso-8859-1\n"); # print("Content-Type: text/html\n"); } # Close the HTTP header block. print("\n"); } # httpinit - parses and cleans up the URL parameters and sets up the various variables # Also prints the HTTP header & sets up the signal handlers # This is also where we protect from malicious input # # HTTP: # path_info - # param - Array of parameters # this_url - The current url # sub httpinit { $SIG{__WARN__} = \&warning; $SIG{__DIE__} = \&fatal; $HTTP->{'path_info'} = http_wash($ENV{'PATH_INFO'}); $HTTP->{'path_info'} = clean_path($HTTP->{'path_info'}); $HTTP->{'this_url'} = 'http://' . $ENV{'SERVER_NAME'}; $HTTP->{'this_url'} .= ':' . $ENV{'SERVER_PORT'} if $ENV{'SERVER_PORT'} != 80; $HTTP->{'this_url'} .= $ENV{'SCRIPT_NAME'} . $ENV{'PATH_INFO'}; $HTTP->{'this_url'} .= '?' . $ENV{'QUERY_STRING'} if $ENV{'QUERY_STRING'}; # We don't clean all the parameters here, as some scripts need extended characters # e.g. regexp searching $HTTP->{'param'} = { map { http_wash($_) } $ENV{'QUERY_STRING'} =~ /([^;&=]+)(?:=([^;&]+)|)/g }; # But do clean up these $HTTP->{'param'}->{'v'} ||= $HTTP->{'param'}->{'version'}; $HTTP->{'param'}->{'a'} ||= $HTTP->{'param'}->{'arch'}; $HTTP->{'param'}->{'i'} ||= $HTTP->{'param'}->{'identifier'}; $identifier = clean_identifier($HTTP->{'param'}->{'i'}); # remove the param versions to prevent unclean versions being used delete $HTTP->{'param'}->{'i'}; delete $HTTP->{'param'}->{'identifier'}; $config = new LXR::Config($HTTP->{'this_url'}); die "Can't find config for " . $HTTP->{'this_url'} if !defined($config); $files = new LXR::Files($config->sourceroot); die "Can't create Files for " . $config->sourceroot if !defined($files); $index = new LXR::Index($config->dbname); die "Can't create Index for " . $config->dbname if !defined($index); foreach ($config->allvariables) { $config->variable($_, $HTTP->{'param'}->{$_}) if $HTTP->{'param'}->{$_}; delete $HTTP->{'param'}->{$_}; } $release = clean_release($config->variable('v')); $config->variable('v', $release); # put back into config obj $HTTP->{'param'}->{'file'} = clean_path($HTTP->{'param'}->{'file'}); $pathname = fixpaths($HTTP->{'path_info'} || $HTTP->{'param'}->{'file'}); printhttp; } sub clean_release { my $release = shift; my @rels= $config->varrange('v'); my %test; @test{@rels} = undef; if(!exists $test{$release}) { $release = $config->vardefault('v'); } return $release; } sub clean_identifier { my $id = shift; $id =~ s/(^[\w`:.,]+).*/$1/ if defined $id; return $id; } sub clean_path { # Cleans up a string to path my $path = shift; if(defined $path) { # First suppress anything after a dodgy character $path =~ s!(^[\w_+-,.%^/]+).*!$1!; # Clean out /../ while ($path =~ m!/../!) { $path = s!/\.\./!/!g; } } return $path; } sub httpclean { $config = undef; $files = undef; $index = undef; } sub expandtemplate { my ($templ, %expfunc) = @_; my ($expfun, $exppar); while ($templ =~ s/(\{[^\{\}]*)\{([^\{\}]*)\}/$1\01$2\02/s) { } $templ =~ s/(\$(\w+)(\{([^\}]*)\}|))/{ if (defined($expfun = $expfunc{$2})) { if ($3 eq '') { &$expfun(undef); } else { $exppar = $4; $exppar =~ s#\01#\{#gs; $exppar =~ s#\02#\}#gs; &$expfun($exppar); } } else { $1; } }/ges; $templ =~ s/\01/\{/gs; $templ =~ s/\02/\}/gs; return ($templ); } # What follows is somewhat less hairy way of expanding nested # templates than it used to be. State information is passed via # function arguments, as God intended. sub bannerexpand { my ($templ, $who) = @_; if ($who eq 'source' || $who eq 'sourcedir' || $who eq 'diff') { my $fpath = ''; my $furl = fileref($config->sourcerootname . '/', "banner", '/'); foreach ($pathname =~ m|([^/]+/?)|g) { $fpath .= $_; # jwz: put a space after each / in the banner so that it's # possible for the pathnames to wrap. The <wbr> tag ought # to do this, but it is ignored when sizing table cells, # so we have to use a real space. It's somewhat ugly to # have these spaces be visible, but not as ugly as getting # a horizontal scrollbar... $furl .= ' ' . fileref($_, "banner", "/$fpath"); } $furl =~ s|/</a>|</a>/|gi; return "<span class=\"banner\">$furl</span>"; } else { return ''; } } sub pathname { return $pathname; } sub titleexpand { my ($templ, $who) = @_; if ($who eq 'source' || $who eq 'diff' || $who eq 'sourcedir') { return $config->sourcerootname . $pathname; } elsif ($who eq 'ident') { my $i = $HTTP->{'param'}->{'i'}; return $config->sourcerootname . ' identifier search' . ($i ? ": $i" : ''); } elsif ($who eq 'search') { my $s = $HTTP->{'param'}->{'string'}; return $config->sourcerootname . ' general search' . ($s ? ": $s" : ''); } } sub thisurl { my $url = $HTTP->{'this_url'}; $url =~ s/([\?\&\;\=])/sprintf('%%%02x',(unpack('c',$1)))/ge; return ($url); } sub baseurl { (my $url = $config->baseurl) =~ s|/*$|/|; return $url; } sub stylesheet { return $config->stylesheet; } sub dotdoturl { my $url = $config->baseurl; $url =~ s@/$@@; $url =~ s@/[^/]*$@@; return ($url); } # This one isn't too bad either. We just expand the "modes" template # by filling in all the relevant values in the nested "modelink" # template. sub modeexpand { my ($templ, $who) = @_; my $modex = ''; my @mlist = (); my $mode; if ($who eq 'source' || $who eq 'sourcedir') { push(@mlist, "<span class='modes-sel'>source navigation</span>"); } else { push(@mlist, fileref("source navigation", "modes", $pathname)); } if ($who eq 'diff') { push(@mlist, "<span class='modes-sel'>diff markup</span>"); } elsif ($who eq 'source' && $pathname !~ m|/$|) { push(@mlist, diffref("diff markup", "modes", $pathname)); } if ($who eq 'ident') { push(@mlist, "<span class='modes-sel'>identifier search</span>"); } else { push(@mlist, idref("identifier search", "modes", "")); } if ($who eq 'search') { push(@mlist, "<span class='modes-sel'>general search</span>"); } else { push(@mlist, "<a class=\"modes\" " . "href=\"$config->{virtroot}/search" . urlargs . "\">general search</a>"); } foreach $mode (@mlist) { $modex .= expandtemplate($templ, ('modelink' => sub { return $mode })); } return ($modex); } # This is where it gets a bit tricky. varexpand expands the # "variables" template using varname and varlinks, the latter in turn # expands the nested "varlinks" template using varval. sub varlinks { my ($templ, $who, $var) = @_; my $vlex = ''; my ($val, $oldval); my $vallink; $oldval = $config->variable($var); foreach $val ($config->varrange($var)) { if ($val eq $oldval) { $vallink = "<span class=\"var-sel\">$val</span>"; } else { if ($who eq 'source' || $who eq 'sourcedir') { $vallink = &fileref($val, "varlink", $config->mappath($pathname, "$var=$val"), 0, "$var=$val"); } elsif ($who eq 'diff') { $vallink = &diffref($val, "varlink", $pathname, "$var=$val"); } elsif ($who eq 'ident') { $vallink = &idref($val, "varlink", $identifier, "$var=$val"); } elsif ($who eq 'search') { $vallink = "<a class=\"varlink\" href=\"$config->{virtroot}/search" . &urlargs("$var=$val", "string=" . $HTTP->{'param'}->{'string'}) . "\">$val</a>"; } } $vlex .= expandtemplate($templ, ('varvalue' => sub { return $vallink })); } return ($vlex); } sub varexpand { my ($templ, $who) = @_; my $varex = ''; my $var; foreach $var ($config->allvariables) { $varex .= expandtemplate( $templ, ( 'varname' => sub { $config->vardescription($var) }, 'varlinks' => sub { varlinks(@_, $who, $var) } ) ); } return ($varex); } sub devinfo { my ($templ) = @_; my (@mods, $mod, $path); my %mods = ('main' => $0, %INC); while (($mod, $path) = each %mods) { $mod =~ s/.pm$//; $mod =~ s|/|::|g; $path =~ s|/+|/|g; no strict 'refs'; next unless ${ $mod . '::CVSID' }; push(@mods, [ ${ $mod . '::CVSID' }, $path, (stat($path))[9] ]); } return join( '', map { expandtemplate( $templ, ( 'moduleid' => sub { $$_[0] }, 'modpath' => sub { $$_[1] }, 'modtime' => sub { scalar(localtime($$_[2])) } ) ); } sort { $$b[2] <=> $$a[2] } @mods ); } sub atticlink { return " " if !$files->isa("LXR::Files::CVS"); return " " if $ENV{'SCRIPT_NAME'} !~ m|/source$|; if ($HTTP->{'param'}->{'showattic'}) { return ("<a class='modes' href=\"$config->{virtroot}/source" . $HTTP->{'path_info'} . &urlargs("showattic=0") . "\">Hide attic files</a>"); } else { return ("<a class='modes' href=\"$config->{virtroot}/source" . $HTTP->{'path_info'} . &urlargs("showattic=1") . "\">Show attic files</a>"); } } sub makeheader { my $who = shift; my $tmplname; my $template = "<html><body>\n<hr>\n"; $tmplname = $who . "head"; unless ($who ne "sourcedir" || $config->sourcedirhead) { $tmplname = "sourcehead"; } unless ($config->value($tmplname)) { $tmplname = "htmlhead"; } if ($config->value($tmplname)) { if (open(TEMPL, $config->value($tmplname))) { local ($/) = undef; $template = <TEMPL>; close(TEMPL); } else { warning("Template " . $config->value($tmplname) . " does not exist."); } } #CSS checked _PH_ print( expandtemplate( $template, ( 'title' => sub { titleexpand(@_, $who) }, 'banner' => sub { bannerexpand(@_, $who) }, 'baseurl' => sub { baseurl(@_) }, 'stylesheet' => sub { stylesheet(@_) }, 'dotdoturl' => sub { dotdoturl(@_) }, 'thisurl' => sub { thisurl(@_) }, 'pathname' => sub { pathname(@_) }, 'modes' => sub { modeexpand(@_, $who) }, 'variables' => sub { varexpand(@_, $who) }, 'devinfo' => sub { devinfo(@_) }, 'atticlink' => sub { atticlink(@_) }, ) ) ); } sub makefooter { my $who = shift; my $tmplname; my $template = "<hr>\n</body>\n"; $tmplname = $who . "tail"; unless ($who ne "sourcedir" || $config->sourcedirhead) { $tmplname = "sourcetail"; } unless ($config->value($tmplname)) { $tmplname = "htmltail"; } if ($config->value($tmplname)) { if (open(TEMPL, $config->value($tmplname))) { local ($/) = undef; $template = <TEMPL>; close(TEMPL); } else { warning("Template " . $config->value($tmplname) . " does not exist."); } } print( expandtemplate( $template, ( 'banner' => sub { bannerexpand(@_, $who) }, 'thisurl' => sub { thisurl(@_) }, 'modes' => sub { modeexpand(@_, $who) }, 'variables' => sub { varexpand(@_, $who) }, 'devinfo' => sub { devinfo(@_) } ) ), "</html>\n" ); } 1;
펄스크립트로 되어 있던데.. 문법 공부할 시간도 없고
에휴..
다른 분들은 어떻게 해결하셨는지요..
댓글 달기