source: gsdl/trunk/cgi-bin/gsdlCGI.pm@ 16467

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

Merged GS2's gliserver.pl and gsdlCGI.pm with GS3's gliserver4gs3.pl and gsdlCGI4gs3.pm and moved them into gs2's svn trunk (previously still in GS3's svn trunk). Now there's one set of gliserver files that will work for both GS2 and GS3 remote Greenstone servers.

  • Property svn:keywords set to Author Date Id Revision
File size: 14.9 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'} =~ m/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, $optional) = @_;
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 if defined $loc;
221
222 if ((!defined $loc) || ($loc =~ m/^\s*$/)) {
223 if((!defined $optional) || (!$optional)) {
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_gsdl3_home {
265 my $self = shift @_;
266 my ($optional) = @_;
267
268 if (defined $self->{'gsdl3home'}) {
269 return $self->{'gsdl3home'};
270 }
271
272 my $gsdl3home = $self->get_config_info("gsdl3home", $optional);
273
274 if(defined $gsdl3home) {
275 $gsdl3home =~ s/(\/|\\)$//; # remove trailing slash
276 $self->{'gsdl3home'} = $gsdl3home;
277 }
278 return $gsdl3home;
279}
280
281sub get_java_home {
282 my $self = shift @_;
283 my ($optional) = @_;
284
285 if (defined $self->{'javahome'}) {
286 return $self->{'javahome'};
287 }
288
289 my $javahome = $self->get_config_info("javahome", $optional);
290 if(defined $javahome) {
291 $javahome =~ s/(\/|\\)$//; # remove trailing slash
292 $self->{'javahome'} = $javahome;
293 }
294 return $javahome;
295}
296
297sub get_perl_path {
298 my $self = shift @_;
299
300 if (defined $self->{'perlpath'}) {
301 return $self->{'perlpath'};
302 }
303
304 my $perlpath = $self->get_config_info("perlpath");
305
306 if(defined $perlpath) {
307 $perlpath =~ s/(\/|\\)$//; # remove trailing slash
308 $self->{'perlpath'} = $perlpath;
309 }
310 return $perlpath;
311}
312
313sub get_gsdl_os {
314 my $self = shift @_;
315
316 my $os = $^O;
317
318 if ($os =~ m/linux/i) {
319 return "linux";
320 }
321 elsif ($os =~ m/mswin/i) {
322 return "windows";
323 }
324 elsif ($os =~ m/macos/i) {
325 return "darwin";
326 }
327 else {
328 # return as is.
329 return $os;
330 }
331}
332
333sub get_library_url_suffix {
334 my $self = shift @_;
335
336 if (defined $self->{'library_url_suffix'}) {
337 return $self->{'library_url_suffix'};
338 }
339
340 my $optional = 1; # ignore absence of gwcgi if not found
341 my $library_url = $self->get_config_info("gwcgi", $optional);
342 if(defined $library_url) {
343 $library_url =~ s/(\/|\\)$//; # remove trailing slash
344 }
345 else {
346
347 if($self->{'greenstone_version'} == 2) {
348 $library_url = $self->get_config_info("httpprefix");
349 $library_url = "$library_url/cgi-bin/library";
350
351 my $gsdlos = (defined $ENV{'GSDLOS'}) ? $ENV{'GSDLOS'} : $self->get_gsdl_os();
352 if($gsdlos =~ m/windows/) { # remote GS2 server on Windows uses "library.exe"
353 $library_url .= ".exe";
354 }
355 }
356 else { # greenstone 3 or later and gwcgi not defined
357 $library_url = "/greenstone3"; #"/greenstone3/library";
358 }
359 }
360
361 $self->{'library_url_suffix'} = $library_url;
362 return $library_url;
363}
364
365sub setup_fedora_homes {
366 my $self = shift @_;
367 my ($optional) = @_;
368
369 # The following will still allow the FEDORA_HOME and FEDORA_VERSION environment
370 # variables to have been set outside the gsdlsite.cfg file. Existing env vars
371 # are only overwritten if they've *also* been defined in gsdlsite.cfg.
372
373 if (!defined $self->{'fedora_home'}) # Don't need to go through it all again if we'd already done this before
374 {
375 # First look in the gsdlsite.cfg file for the fedora properties to be defined
376 # and set $ENV{FEDORA_HOME} and $ENV{FEDORA_VERSION} if values were provided
377 $self->{'fedora_home'} = $self->get_config_info("fedorahome", $optional);
378
379 if (defined $self->{'fedora_home'}) {
380 $ENV{'FEDORA_HOME'} = $self->{'fedora_home'};
381 }
382 elsif (defined $ENV{'FEDORA_HOME'}) { # check environment variable
383 $self->{'fedora_home'} = $ENV{'FEDORA_HOME'};
384 }
385
386 # if FEDORA_HOME is now defined, we can look for the fedora version that is being used
387 if (defined $ENV{'FEDORA_HOME'})
388 {
389 # first look in the file
390 $self->{'fedora_version'} = $self->get_config_info("fedoraversion", $optional);
391
392 if (defined $self->{'fedora_version'}) {
393 $ENV{'FEDORA_VERSION'} = $self->{'fedora_version'};
394 }
395 elsif (defined $ENV{'FEDORA_VERSION'}) { # then check environment variable
396 $self->{'fedora_version'} = $ENV{'FEDORA_VERSION'};
397 }
398 else { # finally, default to version 3 and warn the user
399 $ENV{'FEDORA_VERSION'} = "3";
400 $self->{'fedora_version'} = $ENV{'FEDORA_VERSION'};
401 #$self->generate_ok_message("FEDORA_HOME is set, but not FEDORA_VERSION, defaulted to: 3.");
402 }
403 }
404 }
405}
406
407sub setup_gsdl {
408 my $self = shift @_;
409 my $optional = 1; # ignore absence of specified properties in gsdl(3)site.cfg if not found
410
411 my $gsdlhome = $self->get_gsdl_home();
412 my $gsdlos = $self->get_gsdl_os();
413 $ENV{'GSDLHOME'} = $gsdlhome;
414 $ENV{'GSDLOS'} = $gsdlos;
415
416 my $library_url = $self->get_library_url_suffix(); # best to have GSDLOS set beforehand
417 $self->{'library_url_suffix'} = $library_url;
418
419 require "$gsdlhome/perllib/util.pm";
420
421 if($self->{'greenstone_version'} == 3) {
422 my $gsdl3srchome = $self->get_gsdl3_src_home();
423 $ENV{'GSDL3SRCHOME'} = $gsdl3srchome;
424
425 my $gsdl3home = $self->get_gsdl3_home($optional);
426 # if a specific location for GS3's web folder is not provided,
427 # assume the GS3 web folder is in the default location
428 if(!defined $gsdl3home) {
429 $gsdl3home = &util::filename_cat($ENV{'GSDL3SRCHOME'}, "web");
430 $self->{'gsdl3home'} = $gsdl3home;
431 }
432 $ENV{'GSDL3HOME'} = $gsdl3home;
433 }
434
435
436 my $gsdl_bin_script = &util::filename_cat($gsdlhome,"bin","script");
437 &util::envvar_append("PATH",$gsdl_bin_script);
438
439 my $gsdl_bin_os = &util::filename_cat($gsdlhome,"bin",$gsdlos);
440 &util::envvar_append("PATH",$gsdl_bin_os);
441
442 # Perl comes installed with the GS Windows Release Kit.
443 # However, if GS is from SVN, the user must have their own Perl and put it on the path.
444 my $perl_bin_dir; # undefined
445 if ($gsdlos eq "windows") {
446 $perl_bin_dir = &util::filename_cat($gsdlhome, "bin", "windows", "perl", "bin");
447 if(-e $perl_bin_dir) {
448 &util::envvar_append("PATH", $perl_bin_dir);
449 }
450 }
451
452 # Uncomment these lines if you want to read the "perlpath" property from
453 # the gsdl(3)site.cfg config file into PATH
454 #if(!defined $perl_bin_dir) {
455 #$perl_bin_dir = $self->get_perl_path();
456 #&util::envvar_append("PATH", $perl_bin_dir);
457 #}
458
459 # gsdl(3)site.cfg can specify JAVA_HOME and FEDORA_HOME along with Fedora's version. Both
460 # are needed (by scripts g2f-import and g2f-buildcol) when using Greenstone 2 with Fedora.
461 if(!defined $ENV{'JAVA_HOME'}) {
462 $ENV{'JAVA_HOME'} = $self->get_java_home($optional);
463 }
464
465 $self->setup_fedora_homes($optional);
466}
467
468sub greenstone_version {
469 my $self = shift @_;
470 return $self->{'greenstone_version'};
471}
472
473sub library_url_suffix {
474 my $self = shift @_;
475 return $self->{'library_url_suffix'};
476}
477
478# Only useful to call this after calling setup_gsdl, as it uses some environment variables
479# Returns the Greenstone collect directory, or a specific collection directory inside collect
480sub get_collection_dir {
481 my $self = shift @_;
482 my ($site, $collection) = @_; # both may be undefined
483
484 require "$ENV{'GSDLHOME'}/perllib/util.pm";
485 my $collection_directory;
486 if($self->{'greenstone_version'} == 2 && defined $ENV{'GSDLHOME'}) {
487 if(defined $collection) {
488 $collection_directory = &util::filename_cat($ENV{'GSDLHOME'}, "collect", $collection);
489 } else {
490 $collection_directory = &util::filename_cat($ENV{'GSDLHOME'}, "collect");
491 }
492 }
493 elsif($self->{'greenstone_version'} == 3 && defined $ENV{'GSDL3SRCHOME'}) {
494 if(defined $collection) {
495 $collection_directory = &util::filename_cat($ENV{'GSDL3SRCHOME'}, "web", "sites", $site, "collect", $collection);
496 } else {
497 $collection_directory = &util::filename_cat($ENV{'GSDL3SRCHOME'}, "web", "sites", $site, "collect");
498 }
499 }
500}
501
502sub local_rm_r
503{
504 my $self = shift @_;
505 my ($local_dir) = @_;
506
507 my $prefix_dir = getcwd();
508 my $full_path = &util::filename_cat($prefix_dir,$local_dir);
509
510 if ($prefix_dir !~ m/collect/) {
511 $self->generate_error("Trying to delete outside of Greenstone collect: $full_path");
512 }
513
514 # Delete recursively
515 if (!-e $full_path) {
516 $self->generate_error("File/Directory does not exist: $full_path");
517 }
518
519 &util::rm_r($full_path);
520}
521
522
523sub get_java_path()
524{
525 # Check the JAVA_HOME environment variable first
526 if (defined $ENV{'JAVA_HOME'}) {
527 my $java_home = $ENV{'JAVA_HOME'};
528 $java_home =~ s/\/$//; # Remove trailing slash if present (Unix specific)
529 return &util::filename_cat($java_home, "bin", "java");
530 }
531
532 # Hope that Java is on the PATH
533 return "java";
534}
535
536
537sub check_java_home()
538{
539 # Return a warning unless the JAVA_HOME environment variable is set
540 if (!defined $ENV{'JAVA_HOME'}) {
541 return "JAVA_HOME environment variable not set. Might not be able to find Java unless in PATH (" . $ENV{'PATH'} . ")";
542 }
543
544 return "";
545}
546
547
548sub checked_chdir
549{
550 my $self = shift @_;
551 my ($dir) = @_;
552
553 if (!-e $dir) {
554 $self->generate_error("Directory '$dir' does not exist");
555 }
556
557 chdir $dir
558 || $self->generate_error("Unable to change to directory: $dir");
559}
560
561sub rot13()
562{
563 my $self = shift @_;
564 my ($password)=@_;
565 my @password_arr=split(//,$password);
566
567 my @encrypt_password;
568 foreach my $str (@password_arr){
569 my $char=unpack("c",$str);
570 if ($char>=97 && $char<=109){
571 $char+=13;
572 }elsif ($char>=110 && $char<=122){
573 $char-=13;
574 }elsif ($char>=65 && $char<=77){
575 $char+=13;
576 }elsif ($char>=78 && $char<=90){
577 $char-=13;
578 }
579 $char=pack("c",$char);
580 push(@encrypt_password,$char);
581 }
582 return join("",@encrypt_password);
583}
584
585sub encrypt_password
586{
587 my $self = shift @_;
588
589 if (defined $self->param("pw")) { ##
590 if ($self->{'greenstone_version'} == 3) { # GS3 is in Java, so needs different encryption
591 $self->param('-name' => "pw", '-value' => $self->rot13($self->clean_param("pw")));
592 }
593 else { # GS2 (and versions of GS other than 3?)
594 #require "$self->{'gsdlhome'}/perllib/util.pm"; # This is OK on Windows
595 require "$self->{'gsdlhome'}/perllib/cpan/Crypt/UnixCrypt.pm"; # This is OK on Windows
596 $self->param('-name' => "pw", '-value' => &Crypt::UnixCrypt::crypt($self->clean_param("pw"), "Tp"));
597 }
598 }
599}
600
6011;
602
Note: See TracBrowser for help on using the repository browser.