]> git.deb.at Git - deb/packages.git/blob - cgi-bin/dispatcher.pl
Only have one CGI-Script and move most of the code from the
[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;
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::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()) {
61     my @components = grep { $_ } map { lc $_ } split /\/+/, $path;
62
63     debug( "components[0]=$components[0]", 2 );
64     if ($components[0] eq 'search') {
65         shift @components;
66         $what_to_do = 'search';
67     }
68     if ($components[0] eq 'source') {
69         shift @components;
70         $input->param( 'source', 1 );
71     }
72     if (@components == 0) {
73         # we just hope we get the information through our parameters...
74     } elsif (@components == 1) {
75         $what_to_do = 'search';
76     } else {
77
78         for ($components[-1]) {
79             /^(changelog|copyright|download|filelist)$/ && do {
80                 pop @components;
81                 $what_to_do = $1;
82                 last;
83             };
84         }
85
86         my %SUITES = map { $_ => 1 } @SUITES;
87         my %SUITES_ALIAS = ( woody => 'oldstable',
88                              sarge => 'stable',
89                              etch => 'testing',
90                              sid => 'unstable', );
91         my %SECTIONS = map { $_ => 1 } @SECTIONS;
92         my %ARCHIVES = map { $_ => 1 } @ARCHIVES;
93         my %ARCHITECTURES = map { $_ => 1 } (@ARCHITECTURES, 'all');
94         my %params_set;
95         sub set_param_once {
96             my ($cgi, $params_set, $key, $val) = @_;
97             if ($params_set->{$key}++) {
98                 fatal_error( "$key set more than once in path" );
99             } else {
100                 $cgi->param( $key, $val );
101             }
102         }
103
104         my @tmp;
105         foreach (@components) {
106             if ($SUITES{$_}) {
107                 set_param_once( $input, \%params_set, 'suite', $_);
108 #possible conflicts with package names
109 #           } elsif (my $s = $SUITES_ALIAS{$_}) {
110 #               set_param_once( $input, \%params_set, 'suite', $s);
111             } elsif ($SECTIONS{$_}) {
112                 set_param_once( $input, \%params_set, 'section', $_);
113             } elsif ($ARCHIVES{$_}) {
114                 set_param_once( $input, \%params_set, 'archive', $_);
115             } elsif ($ARCHITECTURES{$_}) {
116                 set_param_once( $input, \%params_set, 'arch', $_);
117             } elsif ($sections_descs{$_}) {
118                 set_param_once( $input, \%params_set, 'subsection', $_);
119             } elsif ($_ eq 'source') {
120                 set_param_once( $input, \%params_set, 'source', 1);
121             } else {
122                 push @tmp, $_;
123             }
124         }
125         @components = @tmp;
126
127         if (@components > 1) {
128             fatal_error( "two or more packages specified (@components)" );
129         }
130     } # else if (@components == 1)
131     
132     if (@components) {
133         $input->param( 'keywords', $components[0] );
134         $input->param( 'package', $components[0] );
135     }
136 }
137
138 my ( $pkg, @suites, @sections, @subsections, @archives, @archs );
139
140 my %params_def = ( keywords => { default => undef,
141                                  match => '^\s*([-+\@\s\w\/.:]+)\s*$',
142                              },
143                    package => { default => undef,
144                                 match => '^([\w.+-]+)$',
145                                 var => \$pkg },
146                    suite => { default => 'all', match => '^([\w-]+)$',
147                               array => ',', var => \@suites,
148                               replace => { all => \@SUITES } },
149                    archive => { default => ($what_to_do eq 'search') ?
150                                     'all' : 'default',
151                                     match => '^([\w-]+)$',
152                                     array => ',', var => \@archives,
153                                     replace => { all => \@ARCHIVES,
154                                              default => [qw(us security non-US)]} },
155                    exact => { default => 0, match => '^(\w+)$',  },
156                    source => { default => 0, match => '^(\d+)$',  },
157                    searchon => { default => 'names', match => '^(\w+)$', },
158                    section => { default => 'all', match => '^([\w-]+)$',
159                                 alias => 'release', array => ',',
160                                 var => \@sections,
161                                 replace => { all => \@SECTIONS } },
162                    subsection => { default => 'default', match => '^([\w-]+)$',
163                                    array => ',', var => \@subsections,
164                                    replace => { default => [] } },
165                    arch => { default => 'any', match => '^(\w+)$',
166                              array => ',', var => \@archs, replace =>
167                              { any => \@ARCHITECTURES } },
168                    );
169 my %opts;
170 my %params = Packages::Search::parse_params( $input, \%params_def, \%opts );
171
172 $opts{h_suites} = { map { $_ => 1 } @suites };
173 $opts{h_sections} = { map { $_ => 1 } @sections };
174 $opts{h_archives} = { map { $_ => 1 } @archives };
175 $opts{h_archs} = { map { $_ => 1 } @archs };
176
177 if ((($opts{searchon} eq 'names') && $opts{source}) ||
178     ($opts{searchon} eq 'sourcenames')) {
179     $opts{source} = 1;
180     $opts{searchon} = 'names',
181     $opts{searchon_form} = 'sourcenames';
182 }
183
184 my $pet1 = new Benchmark;
185 my $petd = timediff($pet1, $pet0);
186 debug( "Parameter evaluation took ".timestr($petd) );
187
188 print $input->header( -charset => 'utf-8' );
189
190 my (%html_header, $menu, $page_content);
191 unless (@Packages::CGI::fatal_errors) {
192     no strict 'refs';
193     &{"do_$what_to_do"}( \%params, \%opts, \%html_header,
194                          \$menu, \$page_content );
195 } else {
196     %html_header = ( title => 'Error',
197                      lang => 'en',
198                      print_title => 1,
199                      print_search_field => 'packages',
200                      search_field_values => { 
201                          keywords => 'search for a package',
202                          searchon => 'default',
203                          arch => 'any',
204                          suite => 'all',
205                          section => 'all',
206                          exact => 1,
207                          debug => $debug,
208                      },
209                      );
210 }
211
212 print Packages::HTML::header( %html_header );
213
214 print $menu||'';
215 print_errors();
216 print_hints();
217 print_msgs();
218 print_debug();
219 print_notes();
220
221 unless (@Packages::CGI::fatal_errors) {
222     print $page_content;
223 }
224
225 my $tet1 = new Benchmark;
226 my $tetd = timediff($tet1, $tet0);
227 print "Total page evaluation took ".timestr($tetd)."<br>"
228     if $debug_allowed;
229
230 my $trailer = Packages::HTML::trailer( $ROOT );
231 $trailer =~ s/LAST_MODIFIED_DATE/gmtime()/e; #FIXME
232 print $trailer;
233
234 # vim: ts=8 sw=4
235