]> git.deb.at Git - deb/packages.git/blob - cgi-bin/dispatcher.pl
Fix a few warnings, be more strict in what we accept
[deb/packages.git] / cgi-bin / dispatcher.pl
1 #!/usr/bin/perl -T
2 # $Id: search_packages.pl 91 2006-02-10 22:18:31Z jeroen $
3 # dispatcher.pl -- CGI interface for packages.debian.org
4 #
5 # Copyright (C) 2004-2006 Frank Lichtenheld
6 #
7 # use is allowed under the terms of the GNU Public License (GPL)                              
8 # see http://www.fsf.org/copyleft/gpl.html for a copy of the license
9
10 use strict;
11 use warnings;
12
13 use lib '../lib';
14 use CGI;
15 use POSIX;
16 use URI::Escape;
17 use HTML::Entities;
18 use DB_File;
19 use Benchmark ':hireswallclock';
20
21 use Deb::Versions;
22 use Packages::Config qw( $DBDIR $ROOT $SEARCH_CGI $SEARCH_PAGE
23                          @SUITES @SECTIONS @ARCHIVES @ARCHITECTURES );
24 use Packages::CGI;
25 use Packages::DB;
26 use Packages::Search qw( :all );
27 use Packages::HTML ();
28 use Packages::Sections;
29
30 use Packages::DoSearch;
31 use Packages::DoSearchContents;
32 use Packages::DoShow;
33 use Packages::DoDownload;
34 use Packages::DoFilelist;
35
36 &Packages::CGI::reset;
37
38 $ENV{PATH} = "/bin:/usr/bin";
39
40 # Read in all the variables set by the form
41 my $input;
42 if ($ARGV[0] && ($ARGV[0] eq 'php')) {
43         $input = new CGI(\*STDIN);
44 } else {
45         $input = new CGI;
46 }
47
48 my $pet0 = new Benchmark;
49 my $tet0 = new Benchmark;
50 # use this to disable debugging in production mode completly
51 my $debug_allowed = 1;
52 my $debug = $debug_allowed && $input->param("debug");
53 $debug = 0 if !defined($debug) || $debug !~ /^\d+$/o;
54 $Packages::CGI::debug = $debug;
55
56 &Packages::Config::init( '../' );
57 &Packages::DB::init();
58
59 my $what_to_do = 'show';
60 my $source = 0;
61 if (my $path = $input->path_info() || $input->param('PATH_INFO')) {
62     my @components = grep { $_ } map { lc $_ } split /\//, $path;
63
64     debug( "components[0]=$components[0]", 2 ) if @components>0;
65     if (@components > 0 and $components[0] eq 'source') {
66         shift @components;
67         $input->param( 'source', 1 );
68     }
69     if (@components > 0 and $components[0] eq 'search') {
70         shift @components;
71         $what_to_do = 'search';
72         # Done
73         fatal_error( "search doesn't take any more path elements" )
74             if @components > 0;
75     } elsif (@components == 0) {
76         fatal_error( "We're supposed to display the homepage here, instead of
77             getting dispatch.pl" );
78     } elsif (@components == 1) {
79         $what_to_do = 'search';
80     } else {
81
82         for ($components[-1]) {
83             /^(changelog|copyright|download|filelist)$/ && do {
84                 pop @components;
85                 $what_to_do = $1;
86                 last;
87             };
88         }
89
90         my %SUITES = map { $_ => 1 } @SUITES;
91         my %SUITES_ALIAS = ( woody => 'oldstable',
92                              sarge => 'stable',
93                              etch => 'testing',
94                              sid => 'unstable', );
95         my %SECTIONS = map { $_ => 1 } @SECTIONS;
96         my %ARCHIVES = map { $_ => 1 } @ARCHIVES;
97         my %ARCHITECTURES = map { $_ => 1 } (@ARCHITECTURES, 'all');
98         my %params_set;
99         sub set_param_once {
100             my ($cgi, $params_set, $key, $val) = @_;
101             if ($params_set->{$key}++) {
102                 fatal_error( "$key set more than once in path" );
103             } else {
104                 $cgi->param( $key, $val );
105             }
106         }
107
108         my @tmp;
109         foreach (@components) {
110             if ($SUITES{$_}) {
111                 set_param_once( $input, \%params_set, 'suite', $_);
112 #possible conflicts with package names
113 #           } elsif (my $s = $SUITES_ALIAS{$_}) {
114 #               set_param_once( $input, \%params_set, 'suite', $s);
115             } elsif ($SECTIONS{$_}) {
116                 set_param_once( $input, \%params_set, 'section', $_);
117             } elsif ($ARCHIVES{$_}) {
118                 set_param_once( $input, \%params_set, 'archive', $_);
119             } elsif ($ARCHITECTURES{$_}) {
120                 set_param_once( $input, \%params_set, 'arch', $_);
121             } elsif ($sections_descs{$_}) {
122                 set_param_once( $input, \%params_set, 'subsection', $_);
123             } elsif ($_ eq 'source') {
124                 set_param_once( $input, \%params_set, 'source', 1);
125             } else {
126                 push @tmp, $_;
127             }
128         }
129         @components = @tmp;
130
131         if (@components > 1) {
132             fatal_error( "two or more packages specified (@components)" );
133         }
134     } # else if (@components == 1)
135     
136     if (@components) {
137         $input->param( 'keywords', $components[0] );
138         $input->param( 'package', $components[0] );
139     }
140 }
141
142 my ( $pkg, @suites, @sections, @subsections, @archives, @archs );
143
144 my %params_def = ( keywords => { default => undef,
145                                  match => '^\s*([-+\@\s\w\/.:]+)\s*$',
146                              },
147                    package => { default => undef,
148                                 match => '^([\w.+-]+)$',
149                                 var => \$pkg },
150                    suite => { default => 'all', match => '^([\w-]+)$',
151                               array => ',', var => \@suites,
152                               replace => { all => \@SUITES } },
153                    archive => { default => ($what_to_do eq 'search') ?
154                                     'all' : 'default',
155                                     match => '^([\w-]+)$',
156                                     array => ',', var => \@archives,
157                                     replace => { all => \@ARCHIVES,
158                                                  default => [qw(us security non-US)]} },
159                    exact => { default => 0, match => '^(\w+)$',  },
160                    source => { default => 0, match => '^(\d+)$',  },
161                    searchon => { default => 'names', match => '^(\w+)$', },
162                    section => { default => 'all', match => '^([\w-]+)$',
163                                 alias => 'release', array => ',',
164                                 var => \@sections,
165                                 replace => { all => \@SECTIONS } },
166                    subsection => { default => 'default', match => '^([\w-]+)$',
167                                    array => ',', var => \@subsections,
168                                    replace => { default => [] } },
169                    arch => { default => 'any', match => '^([\w-]+)$',
170                              array => ',', var => \@archs, replace =>
171                              { any => \@ARCHITECTURES } },
172                    );
173 my %opts;
174 my %params = Packages::Search::parse_params( $input, \%params_def, \%opts );
175
176 $opts{h_suites} = { map { $_ => 1 } @suites };
177 $opts{h_sections} = { map { $_ => 1 } @sections };
178 $opts{h_archives} = { map { $_ => 1 } @archives };
179 $opts{h_archs} = { map { $_ => 1 } @archs };
180
181 if ((($opts{searchon} eq 'names') && $opts{source}) ||
182     ($opts{searchon} eq 'sourcenames')) {
183     $opts{source} = 1;
184     $opts{searchon} = 'names',
185     $opts{searchon_form} = 'sourcenames';
186 } else {
187     $opts{searchon_form} = $opts{searchon};
188 }
189 if ($opts{searchon} eq 'contents' or $opts{searchon} eq 'filenames') {
190     $what_to_do = 'search_contents';
191 }
192
193 my $pet1 = new Benchmark;
194 my $petd = timediff($pet1, $pet0);
195 debug( "Parameter evaluation took ".timestr($petd) );
196
197 print $input->header( -charset => 'utf-8' );
198
199 my (%html_header, $menu, $page_content);
200 unless (@Packages::CGI::fatal_errors) {
201     no strict 'refs';
202     &{"do_$what_to_do"}( \%params, \%opts, \%html_header,
203                          \$menu, \$page_content );
204 } else {
205     %html_header = ( title => 'Error',
206                      lang => 'en',
207                      print_title => 1,
208                      print_search_field => 'packages',
209                      search_field_values => { 
210                          keywords => 'search for a package',
211                          searchon => 'default',
212                          arch => 'any',
213                          suite => 'all',
214                          section => 'all',
215                          exact => 1,
216                          debug => $debug,
217                      },
218                      );
219 }
220
221 print Packages::HTML::header( %html_header );
222
223 print $menu||'';
224 print_errors();
225 print_hints();
226 print_msgs();
227 print_debug();
228 print_notes();
229
230 unless (@Packages::CGI::fatal_errors) {
231     print $page_content;
232 }
233
234 my $tet1 = new Benchmark;
235 my $tetd = timediff($tet1, $tet0);
236 print "Total page evaluation took ".timestr($tetd)."<br>"
237     if $debug_allowed;
238
239 my $trailer = Packages::HTML::trailer( $ROOT );
240 $trailer =~ s/LAST_MODIFIED_DATE/gmtime()/e; #FIXME
241 print $trailer;
242
243 # vim: ts=8 sw=4
244