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