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