source: greenstone3/trunk/web/WEB-INF/cgi/gsdlCGI.pm@ 16217

Last change on this file since 16217 was 16217, checked in by ak19, 16 years ago

Default library URL for GS3 is changed to just greenstone3 rather than greenstone3/library, since GLI appends the -library to it

File size: 11.4 KB
Line 
1package gsdlCGI;
2
3# This file merges Michael Dewsnip's gsdlCGI.pm for GS2 and Quan Qiu's gsdlCGI4gs3.pm (GS3)
4
5use strict;
6no strict 'subs';
7no strict 'refs'; # allow filehandles to be variables and viceversa
8
9use CGI;
10use Cwd;
11
12@gsdlCGI::ISA = ( 'CGI' );
13
14sub new {
15 my $class = shift @_;
16
17 my $self;
18
19 # We'll determine the correct config file in this constructor itself
20 # and use it to determine the Greenstone server's version.
21 # Perhaps later, another test can be used for finding out what version
22 # of the Greenstone server we are working with.
23 my $version;
24 if (-e "gsdl3site.cfg") {
25 $version = 3;
26 } else {
27 $version = 2;
28 }
29
30 if ((defined $ENV{'REQUEST_METHOD'}) && ($ENV{'REQUEST_METHOD'} eq "POST")) {
31
32 # Check if we're dealing with the upload-coll-file cmd. Because it will be a
33 # multipart POST message and must be dealt with by the default CGI() constructor
34 if((defined $ENV{'QUERY_STRING'}) && ($ENV{'QUERY_STRING'} =~ /upload-collection-file/)) {
35 $self = new CGI();
36 }
37
38 else { # all other POST commands processed using CGI($line)
39 my $line = <STDIN>;
40 if ((defined $line) && ($line ne "")) {
41 $self = new CGI($line);
42 }
43 }
44
45 }
46
47 # If one of the conditions above did not hold, then self=new CGI()
48 if (!defined $self) {
49 $self = new CGI();
50 }
51
52 if ($version == 2) {
53 $self->{'site_filename'} = "gsdlsite.cfg";
54 $self->{'greenstone_version'} = 2;
55 }
56 elsif ($version == 3) {
57 $self->{'site_filename'} = "gsdl3site.cfg";
58 $self->{'greenstone_version'} = 3;
59 }
60
61 return bless $self, $class;
62}
63
64
65sub parse_cgi_args
66{
67 my $self = shift @_;
68 my $xml = (defined $self->param("xml")) ? 1 : 0;
69
70 $self->{'xml'} = $xml;
71
72 my @var_names = $self->param;
73 my @arg_list = ();
74 foreach my $n ( @var_names ) {
75 my $arg = "$n=";
76 my $val = $self->param($n);
77 $arg .= $val if (defined $val);
78 push(@arg_list,$arg);
79 }
80
81 $self->{'args'} = join("&",@arg_list);
82}
83
84
85sub clean_param
86{
87 my $self = shift @_;
88 my ($param) = @_;
89
90 my $val = $self->SUPER::param($param);
91 $val =~ s/[\r\n]+$// if (defined $val);
92
93 return $val;
94}
95
96sub safe_val
97{
98 my $self = shift @_;
99 my ($val) = @_;
100
101 # ensure only alpha-numeric plus a few other special chars remain
102
103 $val =~ s/[^[:alnum:]@\.\/\- :_]//g if (defined $val);
104
105 return $val;
106}
107
108sub generate_message
109{
110 my $self = shift @_;
111 my ($message) = @_;
112
113 #if($self->{'greenstone_version'} == 2) { # plain text, for IIS 6
114 print STDOUT "Content-type:text/plain\n\n$message";
115 #} else {
116 #print "Content-type:text/html\n\n";
117 #print "<pre>";
118 #print STDOUT $message;
119 #print "</pre>";
120 #}
121}
122
123sub generate_error
124{
125 my $self = shift @_;
126 my ($mess) = @_;
127
128 my $xml = $self->{'xml'};
129
130 my $full_mess;
131 my $args = $self->{'args'};
132
133 if ($xml) {
134 # Make $args XML safe
135 my $args_xml_safe = $args;
136 $args_xml_safe =~ s/&/&amp;/g;
137
138 $full_mess = "<Error>\n";
139 $full_mess .= " $mess\n";
140 $full_mess .= " CGI args were: $args_xml_safe\n";
141 $full_mess .= "</Error>\n";
142 }
143 else {
144 $full_mess = "ERROR: $mess\n ($args)\n";
145 }
146
147 $self->generate_message($full_mess);
148
149 die $full_mess;
150}
151
152sub generate_warning
153{
154 my $self = shift @_;
155 my ($mess) = @_;
156
157 my $xml = $self->{'xml'};
158
159 my $full_mess;
160 my $args = $self->{'args'};
161
162 if ($xml) {
163 # Make $args XML safe
164 my $args_xml_safe = $args;
165 $args_xml_safe =~ s/&/&amp;/g;
166
167 $full_mess = "<Warning>\n";
168 $full_mess .= " $mess\n";
169 $full_mess .= " CGI args were: $args_xml_safe\n";
170 $full_mess .= "</Warning>\n";
171 }
172 else {
173 $full_mess = "Warning: $mess ($args)\n";
174 }
175
176 $self->generate_message($full_mess);
177
178 print STDERR $full_mess;
179}
180
181
182sub generate_ok_message
183{
184 my $self = shift @_;
185 my ($mess) = @_;
186
187 my $xml = $self->{'xml'};
188
189 my $full_mess;
190
191 if ($xml) {
192 $full_mess = "<Accepted>\n";
193 $full_mess .= " $mess\n";
194 $full_mess .= "</Accepted>\n";
195 }
196 else {
197 $full_mess = "$mess\n";
198 }
199
200 $self->generate_message($full_mess);
201}
202
203
204
205sub get_config_info {
206 my $self = shift @_;
207 my ($infotype, $ignore) = @_;
208
209 my $site_filename = $self->{'site_filename'};
210 open (FILEIN, "<$site_filename")
211 || $self->generate_error("Could not open $site_filename");
212
213 my $config_content = "";
214 while(defined (my $line = <FILEIN>)) {
215 $config_content .= $line;
216 }
217 close(FILEIN);
218
219 my ($loc) = ($config_content =~ m/^$infotype\s+((\".+\")|(\S+))\s*\n/m);
220 $loc =~ s/\"//g;
221
222 if ((!defined $loc) || ($loc =~ m/^\s*$/)) {
223 if((!defined $ignore) || (!$ignore)) {
224 $self->generate_error("$infotype is not set in $site_filename");
225 }
226 }
227
228 return $loc;
229}
230
231sub get_gsdl3_src_home{
232 my $self = shift @_;
233 if (defined $self->{'gsdl3srchome'}) {
234 return $self->{'gsdl3srchome'};
235 }
236
237 my $gsdl3srchome = $self->get_config_info("gsdl3srchome");
238
239 if(defined $gsdl3srchome) {
240 $gsdl3srchome =~ s/(\/|\\)$//; # remove trailing slash
241 }
242 $self->{'gsdl3srchome'} = $gsdl3srchome;
243
244 return $gsdl3srchome;
245}
246
247
248sub get_gsdl_home {
249 my $self = shift @_;
250
251 if (defined $self->{'gsdlhome'}) {
252 return $self->{'gsdlhome'};
253 }
254
255 my $gsdlhome = $self->get_config_info("gsdlhome");
256
257 $gsdlhome =~ s/(\/|\\)$//; # remove trailing slash
258
259 $self->{'gsdlhome'} = $gsdlhome;
260
261 return $gsdlhome;
262}
263
264sub get_java_home {
265 my $self = shift @_;
266
267 if (defined $self->{'javahome'}) {
268 return $self->{'javahome'};
269 }
270
271 my $javahome = $self->get_config_info("javahome");
272
273 $javahome =~ s/(\/|\\)$//; # remove trailing slash
274
275 return $javahome;
276}
277
278sub get_perl_path {
279 my $self = shift @_;
280
281 if (defined $self->{'perlpath'}) {
282 return $self->{'perlpath'};
283 }
284
285 my $perlpath = $self->get_config_info("perlpath");
286
287 $perlpath =~ s/(\/|\\)$//; # remove trailing slash
288
289 return $perlpath;
290}
291
292sub get_gsdl_os {
293 my $self = shift @_;
294
295 my $os = $^O;
296
297 if ($os =~ m/linux/i) {
298 return "linux";
299 }
300 elsif ($os =~ /mswin/i) {
301 return "windows";
302 }
303 elsif ($os =~ /macos/i) {
304 return "darwin";
305 }
306 else {
307 # return as is.
308 return $os;
309 }
310}
311
312sub get_library_url_suffix {
313 my $self = shift @_;
314
315 if (defined $self->{'library_url_suffix'}) {
316 return $self->{'library_url_suffix'};
317 }
318
319 my $ignore = 1; # ignore absence of gwcgi if not found
320 my $library_url = $self->get_config_info("gwcgi", $ignore);
321 if(defined $library_url) {
322 $library_url =~ s/(\/|\\)$//; # remove trailing slash
323 }
324 else {
325
326 if($self->{'greenstone_version'} == 2) {
327 $library_url = $self->get_config_info("httpprefix");
328 $library_url = "$library_url/cgi-bin/library";
329 }
330 else { # greenstone 3 or later and gwcgi not defined
331 $library_url = "/greenstone3"; #"/greenstone3/library";
332 }
333 }
334
335 return $library_url;
336}
337
338sub setup_gsdl {
339 my $self = shift @_;
340
341 my $gsdlhome = $self->get_gsdl_home();
342 my $gsdlos = $self->get_gsdl_os();
343 my $library_url = $self->get_library_url_suffix();
344
345 $ENV{'GSDLHOME'} = $gsdlhome;
346 $ENV{'GSDLOS'} = $gsdlos;
347 $self->{'library_url_suffix'} = $library_url;
348
349 if($self->{'greenstone_version'} == 3) {
350 my $gsdl3srchome = $self->get_gsdl3_src_home();
351 my $javahome = $self->get_java_home();
352
353 $ENV{'GSDL3SRCHOME'} = $gsdl3srchome;
354 $ENV{'JAVA_HOME'} = $javahome;
355 }
356
357 require "$gsdlhome/perllib/util.pm";
358
359 my $gsdl_bin_script = &util::filename_cat($gsdlhome,"bin","script");
360 &util::envvar_append("PATH",$gsdl_bin_script);
361
362 my $gsdl_bin_os = &util::filename_cat($gsdlhome,"bin",$gsdlos);
363 &util::envvar_append("PATH",$gsdl_bin_os);
364
365 if ($gsdlos eq "windows") {
366 my $gsdl_perl_bin_directory = &util::filename_cat($gsdlhome, "bin", "windows", "perl", "bin");
367 &util::envvar_append("PATH", $gsdl_perl_bin_directory);
368 }
369 elsif($self->{'greenstone_version'} == 3) { # and it's on linux now
370 my $perlpath = $self->get_perl_path();
371 &util::envvar_append("PATH", $perlpath);
372 }
373}
374
375sub greenstone_version {
376 my $self = shift @_;
377 return $self->{'greenstone_version'};
378}
379
380sub library_url_suffix {
381 my $self = shift @_;
382 return $self->{'library_url_suffix'};
383}
384
385# Only useful to call this after calling setup_gsdl, as it uses some environment variables
386# Returns the Greenstone collect directory, or a specific collection directory inside collect
387sub get_collection_dir {
388 my $self = shift @_;
389 my ($site, $collection) = @_; # both may be undefined
390
391 require "$ENV{'GSDLHOME'}/perllib/util.pm";
392 my $collection_directory;
393 if($self->{'greenstone_version'} == 2 && defined $ENV{'GSDLHOME'}) {
394 if(defined $collection) {
395 $collection_directory = &util::filename_cat($ENV{'GSDLHOME'}, "collect", $collection);
396 } else {
397 $collection_directory = &util::filename_cat($ENV{'GSDLHOME'}, "collect");
398 }
399 }
400 elsif($self->{'greenstone_version'} == 3 && defined $ENV{'GSDL3SRCHOME'}) {
401 if(defined $collection) {
402 $collection_directory = &util::filename_cat($ENV{'GSDL3SRCHOME'}, "web", "sites", $site, "collect", $collection);
403 } else {
404 $collection_directory = &util::filename_cat($ENV{'GSDL3SRCHOME'}, "web", "sites", $site, "collect");
405 }
406 }
407}
408
409sub local_rm_r
410{
411 my $self = shift @_;
412 my ($local_dir) = @_;
413
414 my $prefix_dir = getcwd();
415 my $full_dir = &util::filename_cat($prefix_dir,$local_dir);
416
417 if ($prefix_dir !~ m/collect/) {
418 $self->generate_error("Trying to delete outside of Greenstone collect: $full_dir");
419 }
420
421 # Delete recursively
422 if (!-e $full_dir) {
423 $self->generate_error("File/Directory does not exist: $full_dir");
424 }
425
426 &util::rm_r($full_dir);
427}
428
429
430sub get_java_path()
431{
432 # Check the JAVA_HOME environment variable first
433 if (defined $ENV{'JAVA_HOME'}) {
434 my $java_home = $ENV{'JAVA_HOME'};
435 $java_home =~ s/\/$//; # Remove trailing slash if present (Unix specific)
436 return &util::filename_cat($java_home, "bin", "java");
437 }
438
439 # Hope that Java is on the PATH
440 return "java";
441}
442
443
444sub check_java_home()
445{
446 # Return a warning unless the JAVA_HOME environment variable is set
447 if (!defined $ENV{'JAVA_HOME'}) {
448 return "JAVA_HOME environment variable not set. Might not be able to find Java unless in PATH (" . $ENV{'PATH'} . ")";
449 }
450
451 return "";
452}
453
454
455sub checked_chdir
456{
457 my $self = shift @_;
458 my ($dir) = @_;
459
460 if (!-e $dir) {
461 $self->generate_error("Directory '$dir' does not exist");
462 }
463
464 chdir $dir
465 || $self->generate_error("Unable to change to directory: $dir");
466}
467
468sub rot13()
469{
470 my $self = shift @_;
471 my ($password)=@_;
472 my @password_arr=split(//,$password);
473
474 my @encrypt_password;
475 foreach my $str (@password_arr){
476 my $char=unpack("c",$str);
477 if ($char>=97 && $char<=109){
478 $char+=13;
479 }elsif ($char>=110 && $char<=122){
480 $char-=13;
481 }elsif ($char>=65 && $char<=77){
482 $char+=13;
483 }elsif ($char>=78 && $char<=90){
484 $char-=13;
485 }
486 $char=pack("c",$char);
487 push(@encrypt_password,$char);
488 }
489 return join("",@encrypt_password);
490}
491
492sub encrypt_password
493{
494 my $self = shift @_;
495
496 if (defined $self->param("pw")) { ##
497 if ($self->{'greenstone_version'} == 3) { # GS3 is in Java, so needs different encryption
498 $self->param('-name' => "pw", '-value' => $self->rot13($self->clean_param("pw")));
499 }
500 else { # GS2 (and versions of GS other than 3?)
501 #require "$self->{'gsdlhome'}/perllib/util.pm"; # This is OK on Windows
502 require "$self->{'gsdlhome'}/perllib/cpan/Crypt/UnixCrypt.pm"; # This is OK on Windows
503 $self->param('-name' => "pw", '-value' => &Crypt::UnixCrypt::crypt($self->clean_param("pw"), "Tp"));
504 }
505 }
506}
507
5081;
509
Note: See TracBrowser for help on using the repository browser.