#!/usr/bin/perl -w use strict; use CGI qw(:standard); my $version = '1.0b'; my $portagedir = '/usr/portage'; my $scriptloc = '/home/httpd/rsync'; my $disp = param('disp') || ''; my @dirs = fetchcats($portagedir); if (!$disp) { main_menu(); } elsif ($disp eq 'gocat') { gocat(); } elsif ($disp eq 'goapp') { goapp(); } elsif ($disp eq 'view_ebuild') { view_ebuild(); } elsif ($disp eq 'results') { results(); } elsif ($disp eq 'about') { about(); } elsif ($disp eq 'view_cl') { view_cl(); } elsif ($disp eq 'view_md') { view_md(); } else { main_menu(); } # --------------------------------------- # # Main Menu # # --------------------------------------- # sub main_menu { print header,start_html('PortageView'); print '

PortageView

'."\n". '
'."\n". 'Search: '. ''."\n". ' Search Description: '."\n". '
'."\n". ''."\n" . ''."\n"; my $i = 1; foreach my $dir (@dirs) { print ''."\n"; ($i % 3) ? undef : print "\n\n"; $i++; } print '
Category
 '.$dir.'
'; footerpg(); } # --------------------------------------- # # Grab all info on application # # --------------------------------------- # sub goapp { my $app = param('app') || 'invalid'; my $cat = param('cat') || 'invalid'; error('Invalid Package!') if (!-d "$portagedir/$cat/$app"); chdir("$portagedir/$cat/$app"); my @ebuilds = grep /\.ebuild$/i, <*>; # Parse ebuild my %info = ( DESCRIPTION => '', HOMEPAGE => '', SRC_URI => '', LICENSE => '' ); open(EBUILD,"$portagedir/$cat/$app/$ebuilds[$#ebuilds]") || error('Cannot Open ebuild for parsing: '.$!." -> '$cat/$app/$ebuilds[$#ebuilds]'"); while() { if (/^DESCRIPTION="(.*)"/) { $info{DESCRIPTION} = $1 || ''; } elsif (/^HOMEPAGE="(.*)"/) { $info{HOMEPAGE} = $1 || ''; } elsif (/^SRC_URI="(.*)"/) { $info{SRC_URI} = $1 || ''; } elsif (/^LICENSE="(.*)"/) { $info{LICENSE} = $1 || ''; } } close(EBUILD); my $package = $ebuilds[$#ebuilds]; $package =~ s/\.ebuild$//; $info{SRC_URI} =~ s/\$\{M??Y??_??P\}/$package/; my $md = ''; if (-f "$portagedir/$cat/$app/metadata.xml") { $md = ''."\n". '  MetaData: '."\n". '  metadata.xml'."\n". ''."\n"; } print header,start_html('PortageView :: '.$cat.'/'.$app); print '

PortageView :: '. ''. $cat.'/'.$app.'

'."\n"; print ''."\n" . ''."\n". ''."\n". ' '."\n". ' '."\n". ''."\n". ''."\n". ' '."\n". ' '."\n". ''."\n". ''."\n". ' '."\n". ' '."\n". ''."\n". ''."\n". ' '."\n". ' '."\n". ''."\n". $md . ''."\n". ' '."\n". ' '."\n". ''."\n". ''."\n". ' '."\n". ' '."\n". ''."\n". '
'.$cat.'/'.$app.'
 Description:  '.$info{DESCRIPTION}.'
 Homepage:  '. $info{HOMEPAGE}.'
 Source URI:  '.$info{SRC_URI}.'
 License:  '.$info{LICENSE}.'
 ChangeLog:  ChangeLog
 Ebuilds: '; foreach (@ebuilds) { print ' '.$_.'
'."\n"; } print '
'."\n"; footerpg(); } # --------------------------------------- # # View the Ebuild Securely # # --------------------------------------- # sub view_ebuild { my $ebuild = param('ebuild') || 'invalid'; my $app = param('app') || 'invalid'; my $cat = param('cat') || 'invalid'; error('Invalid ebuild!') if ($ebuild !~ /\.ebuild$/); error('Invalid ebuild!') if (!-f "$portagedir/$cat/$app/$ebuild"); print header(-type=>'text/plain',-name=> "$ebuild"); open(EBUILD,"$portagedir/$cat/$app/$ebuild") || error('Error opening ebuild: '.$!."-> '$cat/$app/$ebuild'."); while() { print; } close(EBUILD); exit(); } # --------------------------------------- # # View the Changelog Securely # # --------------------------------------- # sub view_cl { my $app = param('app') || 'invalid'; my $cat = param('cat') || 'invalid'; error('Invalid ChangeLog!') if (!-f "$portagedir/$cat/$app/ChangeLog"); print header(-type=>'text/plain',-name=> "ChangeLog.txt"); open(CHANGELOG,"$portagedir/$cat/$app/ChangeLog") || error('Error opening ebuild: '.$!."-> '$cat/$app/ChangeLog'."); while() { print; } close(CHANGELOG); exit(); } # --------------------------------------- # # View the metadata.xml file securly # # --------------------------------------- # sub view_md { my $app = param('app') || 'invalid'; my $cat = param('cat') || 'invalid'; error('Invalid metadata.xml file!') if (!-f "$portagedir/$cat/$app/metadata.xml"); print header(-type=>'text/plain',-name=> "metadata.xml"); open(METADATA,"$portagedir/$cat/$app/metadata.xml") || error('Error opening file: '.$!."-> '$cat/$app/metadata.xml'."); while() { print; } close(METADATA); exit(); } # --------------------------------------- # # Search Results # # --------------------------------------- # sub results { my $q = param('q') || error('You Must Specify some search terms!'); my $sd= param('sd') || ''; $q =~ tr/[]#|%><`~&*()@!;:}{//d; error('Invalid Search Terms!') if (!$q); # Write query to log for stats use Fcntl qw(:flock); open(SLOG,'>>slog.dat') || error('Error Opening Searchlog Datafile: '.$!); flock(SLOG, LOCK_EX); print SLOG $q.':'; print SLOG $sd if ($sd); print SLOG "\n"; flock(SLOG, LOCK_UN); close(SLOG); chdir($portagedir); my @foo; my $fcount = 0; # if (!$sd) { foreach my $d (@dirs) { push(@foo,grep /$q/i, <$d/*>); } # } # else { # ----------------------------------------------------------------------------- # # Code below is for dynamic description searching. It is only recommended for # Use on high performance raid systems because it requires a lot of disk access # # foreach my $d (@dirs) { # my @subs = <$d/*>; # foreach my $sd (@subs) { # my @eb = <$sd/*.ebuild>; # foreach my $e (@eb) { # open(EBUILD,"$e") || error("Error opening ebuild : '$e' .. $!"); # $fcount++; # while() { # /^DESCRIPTION="(.*)"/; # if ($1 =~ /$q/i) { # push(@foo,"$sd"); # last; # } # } # close(EBUILD); # last; # } # } # } chdir($scriptloc); #open(DFILE,'descfile.dat') || error("Cannot open descriptions file"); # while() { # my ($file,$desc) = split(/:/); # $file =~ s/^$portagedir\///; # push(@foo,"$file") if ($desc =~ /$q/i); # } #close(DFILE); # } print header,start_html('Search Results: '.$q); print '

PortageView

'."\n". '

Search Results: '.$q.'

'."\n" . ''.scalar(@foo).' Results found.'; print ' Searched '.$fcount.' ebuilds.' if $fcount > 0; print ''."\n" . ''."\n"; my ($cat,$app); foreach(@foo) { ($cat,$app) = split(/\//); print '\n"; } print '
Package
 '. ''.$cat.'/'.$app.''." 
'; footerpg(); } # --------------------------------------- # # List all subdirectories in category # # --------------------------------------- # sub gocat { my $cat = param('cat') || 'none-entered'; my $go = 0; my @files; foreach (@dirs) { if ($cat eq $_) { $go++; } } if ($go == 1) { @files = fetchcats($portagedir.'/'.$cat); } else { error('Invalid category "'.$cat.'".'); } print header,start_html('PortageView :: '.$cat); print '

PortageView :: '.$cat.'

'."\n". ''."\n" . ''."\n"; my $i = 1; foreach my $file (@files) { print ''."\n"; ($i % 3) ? undef : print "\n\n"; $i++; } print '
Package
 '.$file.'
'; footerpg(); } # --------------------------------------- # # About # # --------------------------------------- # sub about { print header,start_html('About PortageView'); print '

PortageView - About

'."\n". 'I wrote this to be a super quick version of emerge --search
combined with the'. ' Gentoo Package List on Gentoo\'s website. Since this program
runs on my rsync server, '. 'rsync19.us.gentoo.org, it is totally
up to date every 30 minutes with portage.'. ' Written in perl.'. '
*Updates*
'."\n". '2003-09-03: Will now show metadata.xml file if it exists.
'."\n". '2003-09-15: Implemented a cached description system. Greatly improved description searching.
'."\n". '

Email Comments, etc. ==> raven [at] netpimpz.com
'; footerpg(); } # --------------------------------------- # # Fetch all main categories # # --------------------------------------- # sub fetchcats { my $dir = shift; my %invalid = ( eclass => 1, licenses => 1, metadata => 1, profiles => 1, scripts => 1, distfiles => 1, "sec-policy" => 1 ); opendir(DIR, $dir) || die "can't opendir $dir: $!"; my @dirs = grep { /[^.]/ && -d "$dir/$_" && !$invalid{$_}} readdir(DIR); closedir DIR; @dirs = sort { $a cmp $b }@dirs; return(@dirs); } # --------------------------------------- # # Display Page footer # # --------------------------------------- # sub footerpg { print '


'. '[ '. 'About PortageView v'.$version.' ]'."\n". "\n"; } # --------------------------------------- # # Display Error Message # # --------------------------------------- # sub error { my $err = shift; print header,start_html('Error!'); print '

PortageView - Error!

'.$err.''; footerpg(); exit(); }