source: trunk/gsdl/cgi-bin/gliserver.pl@ 13180

Last change on this file since 13180 was 13180, checked in by mdewsnip, 18 years ago

Now checks that the directory doesn't already exist before trying to create it in upload_collection_file (was causing errors in the Apache error_log file).

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 27.4 KB
Line 
1#!perl -w
2# Need to specify the full path of Perl above
3
4
5use gsdlCGI;
6use strict;
7
8
9my $authentication_enabled = 1;
10my $debugging_enabled = 0;
11
12my $mail_enabled = 0;
13my $mail_to_address = "user\@server"; # Set this appropriately
14my $mail_from_address = "user\@server"; # Set this appropriately
15my $mail_smtp_server = "smtp.server"; # Set this appropriately
16
17
18sub main
19{
20 my $gsdl_cgi = new gsdlCGI();
21
22 # Load the Greenstone modules that we need to use
23 $gsdl_cgi->setup_gsdl();
24 my $gsdlhome = $ENV{'GSDLHOME'};
25 $gsdl_cgi->checked_chdir($gsdlhome);
26 require "$gsdlhome/perllib/util.pm"; # This is OK on Windows
27 require "$gsdlhome/perllib/cpan/Crypt/UnixCrypt.pm"; # This is OK on Windows
28
29 # Encrypt the password
30 if (defined $gsdl_cgi->param("pw")) {
31 $gsdl_cgi->param('-name' => "pw", '-value' => &Crypt::UnixCrypt::crypt($gsdl_cgi->clean_param("pw"), "Tp"));
32 }
33
34 $gsdl_cgi->parse_cgi_args();
35
36 # We don't want the gsdlCGI module to return errors and warnings in XML
37 $gsdl_cgi->{'xml'} = 0;
38
39 # Retrieve the (required) command CGI argument
40 my $cmd = $gsdl_cgi->clean_param("cmd");
41 if (!defined $cmd) {
42 $gsdl_cgi->generate_error("No command specified.");
43 }
44 $gsdl_cgi->delete("cmd");
45
46 # The check-installation command has no arguments
47 if ($cmd eq "check-installation") {
48 &check_installation($gsdl_cgi);
49 return;
50 }
51
52 # All other commands require a username, for locking and authentication
53 my $username = $gsdl_cgi->clean_param("un");
54 if ((!defined $username) || ($username =~ m/^\s*$/)) {
55 $gsdl_cgi->generate_error("No username specified.");
56 }
57 $gsdl_cgi->delete("un");
58
59 if ($cmd eq "delete-collection") {
60 &delete_collection($gsdl_cgi, $username);
61 }
62 elsif ($cmd eq "download-collection") {
63 &download_collection($gsdl_cgi, $username);
64 }
65 elsif ($cmd eq "download-collection-archives") {
66 &download_collection_archives($gsdl_cgi, $username);
67 }
68 elsif ($cmd eq "download-collection-configurations") {
69 &download_collection_configurations($gsdl_cgi, $username);
70 }
71 elsif ($cmd eq "download-collection-file") {
72 &download_collection_file($gsdl_cgi, $username);
73 }
74 elsif ($cmd eq "delete-collection-file") {
75 &delete_collection_file($gsdl_cgi, $username);
76 }
77 elsif ($cmd eq "get-script-options") {
78 &get_script_options($gsdl_cgi, $username);
79 }
80 elsif ($cmd eq "move-collection-file") {
81 &move_collection_file($gsdl_cgi, $username);
82 }
83 elsif ($cmd eq "new-collection-directory") {
84 &new_collection_directory($gsdl_cgi, $username);
85 }
86 elsif ($cmd eq "run-script") {
87 &run_script($gsdl_cgi, $username);
88 }
89 elsif ($cmd eq "timeout-test") {
90 while (1) { }
91 }
92 elsif ($cmd eq "upload-collection-file") {
93 &upload_collection_file($gsdl_cgi, $username);
94 }
95 else {
96 $gsdl_cgi->generate_error("Unrecognised command: '$cmd'");
97 }
98}
99
100
101sub authenticate_user
102{
103 my $gsdl_cgi = shift(@_);
104 my $username = shift(@_);
105 my $collection = shift(@_);
106
107 # Even if we're not authenticating remove the un and pw arguments, since these can mess up other scripts
108 my $user_password = $gsdl_cgi->clean_param("pw");
109 $gsdl_cgi->delete("pw");
110
111 # Only authenticate if it is enabled
112 return "all-collections-editor" if (!$authentication_enabled);
113
114 if ((!defined $user_password) || ($user_password =~ m/^\s*$/)) {
115 $gsdl_cgi->generate_error("Authentication failed: no password specified.");
116 }
117
118 my $gsdlhome = $ENV{'GSDLHOME'};
119 my $etc_directory = &util::filename_cat($gsdlhome, "etc");
120 my $users_db_file_path = &util::filename_cat($etc_directory, "users.db");
121
122 # Use db2txt instead of GDBM_File to get the user accounts information
123 my $users_db_content = "";
124 open(USERS_DB, "db2txt \"$users_db_file_path\" |");
125 while (<USERS_DB>) {
126 $users_db_content .= $_;
127 }
128
129 # Get the user account information from the users.db database
130 my %users_db_data = ();
131 foreach my $users_db_entry (split(/-{70}/, $users_db_content)) {
132 if ($users_db_entry =~ /\n?\[(.+)\]\n/) {
133 $users_db_data{$1} = $users_db_entry;
134 }
135 }
136
137 # Check username
138 my $user_data = $users_db_data{$username};
139 if (!defined $user_data) {
140 $gsdl_cgi->generate_error("Authentication failed: no account for user '$username'.");
141 }
142
143 # Check password
144 my ($valid_user_password) = ($user_data =~ /\<password\>(.*)/);
145 if ($user_password ne $valid_user_password) {
146 $gsdl_cgi->generate_error("Authentication failed: incorrect password.");
147 }
148
149 # Check group
150 my ($user_groups) = ($user_data =~ /\<groups\>(.*)/);
151 if ($collection eq "") {
152 # If we're not editing a collection then the user doesn't need to be in a particular group
153 return $user_groups; # Authentication successful
154 }
155 foreach my $user_group (split(/\,/, $user_groups)) {
156 # Does this user have access to all collections?
157 if ($user_group eq "all-collections-editor") {
158 return $user_groups; # Authentication successful
159 }
160 # Does this user have access to personal collections, and is this one?
161 if ($user_group eq "personal-collections-editor" && $collection =~ /^$username\-/) {
162 return $user_groups; # Authentication successful
163 }
164 # Does this user have access to this collection
165 if ($user_group eq "$collection-collection-editor") {
166 return $user_groups; # Authentication successful
167 }
168 }
169
170 $gsdl_cgi->generate_error("Authentication failed: user is not in the required group.");
171}
172
173
174sub lock_collection
175{
176 my $gsdl_cgi = shift(@_);
177 my $username = shift(@_);
178 my $collection = shift(@_);
179
180 my $steal_lock = $gsdl_cgi->clean_param("steal_lock");
181 $gsdl_cgi->delete("steal_lock");
182
183 my $gsdlhome = $ENV{'GSDLHOME'};
184 my $collection_directory = &util::filename_cat($gsdlhome, "collect", $collection);
185 $gsdl_cgi->checked_chdir($collection_directory);
186
187 # Check if a lock file already exists for this collection
188 my $lock_file_name = "gli.lck";
189 if (-e $lock_file_name) {
190 # A lock file already exists... check if it's ours
191 open(LOCK_FILE, "<$lock_file_name");
192 my $lock_file_owner = <LOCK_FILE>;
193 close(LOCK_FILE);
194
195 # The lock file is ours, so there is no problem
196 if ($lock_file_owner eq $username) {
197 return;
198 }
199
200 # The lock file is not ours, so throw an error unless "steal_lock" is set
201 unless (defined $steal_lock) {
202 $gsdl_cgi->generate_error("Collection is locked by: $lock_file_owner");
203 }
204 }
205
206 # Create a lock file for us and we're done
207 open(LOCK_FILE, ">$lock_file_name");
208 print LOCK_FILE "$username";
209 close(LOCK_FILE);
210}
211
212
213# ----------------------------------------------------------------------------------------------------
214# ACTIONS
215# ----------------------------------------------------------------------------------------------------
216
217
218sub check_installation
219{
220 my ($gsdl_cgi) = @_;
221
222 # Check that Java is installed and accessible
223 my $java = $gsdl_cgi->get_java_path();
224 my $java_command = "$java -version 2>&1";
225 my $java_output = `$java_command`;
226 my $java_status = $?;
227 if ($java_status < 0) {
228 $gsdl_cgi->generate_error("Java failed -- do you have the Java run-time installed?\n" . $gsdl_cgi->check_java_home());
229 }
230
231 $gsdl_cgi->generate_ok_message("Java found: $java_output\nInstallation OK!");
232}
233
234
235sub delete_collection
236{
237 my ($gsdl_cgi, $username) = @_;
238
239 my $collection = $gsdl_cgi->clean_param("c");
240 if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
241 $gsdl_cgi->generate_error("No collection specified.");
242 }
243
244 # Ensure the user is allowed to edit this collection
245 &authenticate_user($gsdl_cgi, $username, $collection);
246
247 my $gsdlhome = $ENV{'GSDLHOME'};
248 my $collect_directory = &util::filename_cat($gsdlhome, "collect");
249 $gsdl_cgi->checked_chdir($collect_directory);
250
251 # Check that the collection exists
252 if (!-d $collection) {
253 $gsdl_cgi->generate_error("Collection $collection does not exist.");
254 }
255
256 # Make sure the collection isn't locked by someone else
257 &lock_collection($gsdl_cgi, $username, $collection);
258
259 $gsdl_cgi->checked_chdir($collect_directory);
260 $gsdl_cgi->local_rm_r("$collection");
261
262 # Check that the collection was deleted
263 if (-e $collection) {
264 $gsdl_cgi->generate_error("Could not delete collection $collection.");
265 }
266
267 $gsdl_cgi->generate_ok_message("Collection $collection deleted successfully.");
268}
269
270
271sub delete_collection_file
272{
273 my ($gsdl_cgi, $username) = @_;
274
275 my $collection = $gsdl_cgi->clean_param("c");
276 if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
277 $gsdl_cgi->generate_error("No collection specified.");
278 }
279 my $file = $gsdl_cgi->clean_param("file");
280 if ((!defined $file) || ($file =~ m/^\s*$/)) {
281 $gsdl_cgi->generate_error("No file specified.");
282 }
283 $file =~ s/\|/&util::get_dirsep()/eg; # Convert the '|' characters into whatever is right for this OS
284
285 # Make sure we don't try to delete anything outside the collection
286 if ($file =~ /\.\./) {
287 $gsdl_cgi->generate_error("Illegal file specified.");
288 }
289
290 # Ensure the user is allowed to edit this collection
291 &authenticate_user($gsdl_cgi, $username, $collection);
292
293 my $gsdlhome = $ENV{'GSDLHOME'};
294 my $collection_directory = &util::filename_cat($gsdlhome, "collect", $collection);
295 $gsdl_cgi->checked_chdir($collection_directory);
296
297 # Make sure the collection isn't locked by someone else
298 &lock_collection($gsdl_cgi, $username, $collection);
299
300 # Check that the collection file exists
301 if (!-e $file) {
302 $gsdl_cgi->generate_ok_message("Collection file $file does not exist.");
303 }
304 $gsdl_cgi->local_rm_r("$file");
305
306 # Check that the collection file was deleted
307 if (-e $file) {
308 $gsdl_cgi->generate_error("Could not delete collection file $file.");
309 }
310
311 $gsdl_cgi->generate_ok_message("Collection file $file deleted successfully.");
312}
313
314
315sub download_collection
316{
317 my ($gsdl_cgi, $username) = @_;
318
319 my $collection = $gsdl_cgi->clean_param("c");
320 if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
321 $gsdl_cgi->generate_error("No collection specified.");
322 }
323
324 # Ensure the user is allowed to edit this collection
325 &authenticate_user($gsdl_cgi, $username, $collection);
326
327 my $gsdlhome = $ENV{'GSDLHOME'};
328 my $collect_directory = &util::filename_cat($gsdlhome, "collect");
329 $gsdl_cgi->checked_chdir($collect_directory);
330
331 # Check that the collection exists
332 if (!-d $collection) {
333 $gsdl_cgi->generate_error("Collection $collection does not exist.");
334 }
335
336 # Make sure the collection isn't locked by someone else
337 &lock_collection($gsdl_cgi, $username, $collection);
338
339 # Zip up the collection
340 my $java = $gsdl_cgi->get_java_path();
341 my $java_classpath = &util::filename_cat($gsdlhome, "bin", "java", "GLIServer.jar");
342 my $zip_file_path = &util::filename_cat($collect_directory, $username . "-" . $collection . ".zip");
343 my $java_args = "\"$zip_file_path\" \"$collect_directory\" \"$collection\"";
344 my $java_command = "$java -classpath \"$java_classpath\" org.greenstone.gatherer.remote.ZipCollectionShell $java_args";
345
346 my $java_output = `$java_command`;
347 my $java_status = $?;
348 if ($java_status > 0) {
349 $gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home());
350 }
351
352 # Check that the zip file was created successfully
353 if (!-e $zip_file_path || -z $zip_file_path) {
354 $gsdl_cgi->generate_error("Collection zip file $zip_file_path could not be created.");
355 }
356
357 &put_file($gsdl_cgi, $zip_file_path, "application/zip");
358 unlink("$zip_file_path") unless $debugging_enabled;
359}
360
361
362sub download_collection_archives
363{
364 my ($gsdl_cgi, $username) = @_;
365
366 my $collection = $gsdl_cgi->clean_param("c");
367 if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
368 $gsdl_cgi->generate_error("No collection specified.");
369 }
370
371 # Ensure the user is allowed to edit this collection
372 &authenticate_user($gsdl_cgi, $username, $collection);
373
374 my $gsdlhome = $ENV{'GSDLHOME'};
375 my $collect_directory = &util::filename_cat($gsdlhome, "collect");
376 $gsdl_cgi->checked_chdir($collect_directory);
377
378 # Check that the collection archives exist
379 if (!-d &util::filename_cat($collection, "archives")) {
380 $gsdl_cgi->generate_error("Collection archives do not exist.");
381 }
382
383 # Make sure the collection isn't locked by someone else
384 &lock_collection($gsdl_cgi, $username, $collection);
385
386 # Zip up the collection archives
387 my $java = $gsdl_cgi->get_java_path();
388 my $java_classpath = &util::filename_cat($gsdlhome, "bin", "java", "GLIServer.jar");
389 my $zip_file_path = &util::filename_cat($collect_directory, $username . "-" . $collection . "-archives.zip");
390 my $java_args = "\"$zip_file_path\" \"$collect_directory\" \"$collection\"";
391 my $java_command = "$java -classpath \"$java_classpath\" org.greenstone.gatherer.remote.ZipCollectionArchives $java_args";
392
393 my $java_output = `$java_command`;
394 my $java_status = $?;
395 if ($java_status > 0) {
396 $gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home());
397 }
398
399 # Check that the zip file was created successfully
400 if (!-e $zip_file_path || -z $zip_file_path) {
401 $gsdl_cgi->generate_error("Collection archives zip file $zip_file_path could not be created.");
402 }
403
404 &put_file($gsdl_cgi, $zip_file_path, "application/zip");
405 unlink("$zip_file_path") unless $debugging_enabled;
406}
407
408
409# Collection locking unnecessary because this action isn't related to a particular collection
410sub download_collection_configurations
411{
412 my ($gsdl_cgi, $username) = @_;
413
414 # Users can be in any group to perform this action
415 my $user_groups = &authenticate_user($gsdl_cgi, $username, "");
416
417 my $gsdlhome = $ENV{'GSDLHOME'};
418 my $collect_directory = &util::filename_cat($gsdlhome, "collect");
419 $gsdl_cgi->checked_chdir($collect_directory);
420
421 # Zip up the collection configurations
422 my $java = $gsdl_cgi->get_java_path();
423 my $java_classpath = &util::filename_cat($gsdlhome, "bin", "java", "GLIServer.jar");
424 my $zip_file_path = &util::filename_cat($collect_directory, $username . "-" . "collection-configurations.zip");
425 my $java_args = "\"$zip_file_path\" \"$collect_directory\" \"$username\" \"$user_groups\"";
426 my $java_command = "$java -classpath \"$java_classpath\" org.greenstone.gatherer.remote.ZipCollectionConfigurations $java_args";
427
428 my $java_output = `$java_command`;
429 my $java_status = $?;
430 if ($java_status > 0) {
431 $gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home());
432 }
433
434 # Check that the zip file was created successfully
435 if (!-e $zip_file_path || -z $zip_file_path) {
436 $gsdl_cgi->generate_error("Collection configurations zip file $zip_file_path could not be created.");
437 }
438
439 &put_file($gsdl_cgi, $zip_file_path, "application/zip");
440 unlink("$zip_file_path") unless $debugging_enabled;
441}
442
443
444sub download_collection_file
445{
446 my ($gsdl_cgi, $username) = @_;
447
448 my $collection = $gsdl_cgi->clean_param("c");
449 if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
450 $gsdl_cgi->generate_error("No collection specified.");
451 }
452 my $file = $gsdl_cgi->clean_param("file");
453 if ((!defined $file) || ($file =~ m/^\s*$/)) {
454 $gsdl_cgi->generate_error("No file specified.");
455 }
456 $file =~ s/\|/&util::get_dirsep()/eg; # Convert the '|' characters into whatever is right for this OS
457
458 # Make sure we don't try to download anything outside the collection
459 if ($file =~ /\.\./) {
460 $gsdl_cgi->generate_error("Illegal file specified.");
461 }
462
463 # Ensure the user is allowed to edit this collection
464 &authenticate_user($gsdl_cgi, $username, $collection);
465
466 my $gsdlhome = $ENV{'GSDLHOME'};
467 my $collection_directory = &util::filename_cat($gsdlhome, "collect", $collection);
468 $gsdl_cgi->checked_chdir($collection_directory);
469
470 # Check that the collection file exists
471 if (!-e $file) {
472 $gsdl_cgi->generate_error("Collection file $file does not exist.");
473 }
474
475 # Make sure the collection isn't locked by someone else
476 &lock_collection($gsdl_cgi, $username, $collection);
477
478 # Zip up the collection file
479 my $java = $gsdl_cgi->get_java_path();
480 my $java_classpath = &util::filename_cat($gsdlhome, "bin", "java", "GLIServer.jar");
481 my $zip_file_path = &util::filename_cat($collection_directory, $username . "-" . $collection . "-file.zip");
482 my $java_args = "\"$zip_file_path\" \"$collection_directory\" \"$file\"";
483 my $java_command = "$java -classpath \"$java_classpath\" org.greenstone.gatherer.remote.ZipFiles $java_args";
484
485 my $java_output = `$java_command`;
486 my $java_status = $?;
487 if ($java_status > 0) {
488 $gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home());
489 }
490
491 # Check that the zip file was created successfully
492 if (!-e $zip_file_path || -z $zip_file_path) {
493 $gsdl_cgi->generate_error("Collection archives zip file $zip_file_path could not be created.");
494 }
495
496 &put_file($gsdl_cgi, $zip_file_path, "application/zip");
497 unlink("$zip_file_path") unless $debugging_enabled;
498}
499
500
501# Collection locking unnecessary because this action isn't related to a particular collection
502sub get_script_options
503{
504 my ($gsdl_cgi, $username) = @_;
505
506 my $script = $gsdl_cgi->clean_param("script");
507 if ((!defined $script) || ($script =~ m/^\s*$/)) {
508 $gsdl_cgi->generate_error("No script specified.");
509 }
510 $gsdl_cgi->delete("script");
511
512 # Users can be in any group to perform this action
513 &authenticate_user($gsdl_cgi, $username, "");
514
515 my $perl_args = "";
516 if ($script eq "classinfo.pl") {
517 $perl_args = $gsdl_cgi->clean_param("classifier") || "";
518 $gsdl_cgi->delete("classifier");
519 }
520 if ($script eq "pluginfo.pl") {
521 $perl_args = $gsdl_cgi->clean_param("plugin") || "";
522 $gsdl_cgi->delete("plugin");
523 }
524
525 foreach my $cgi_arg_name ($gsdl_cgi->param) {
526 my $cgi_arg_value = $gsdl_cgi->clean_param($cgi_arg_name) || "";
527 $cgi_arg_value = $gsdl_cgi->safe_val($cgi_arg_value);
528 if ($cgi_arg_value eq "") {
529 $perl_args = "-$cgi_arg_name " . $perl_args;
530 }
531 else {
532 $perl_args = "-$cgi_arg_name \"$cgi_arg_value\" " . $perl_args;
533 }
534 }
535
536 my $perl_command = "perl -S $script $perl_args 2>&1";
537 my $perl_output = `$perl_command`;
538 my $perl_status = $?;
539 if ($perl_status > 0) {
540 $gsdl_cgi->generate_error("Perl failed: $perl_command\n--\n$perl_output\nExit status: " . ($perl_status / 256));
541 }
542
543 print STDOUT "Content-type:text/plain\n\n";
544 print STDOUT $perl_output;
545}
546
547
548sub move_collection_file
549{
550 my ($gsdl_cgi, $username) = @_;
551
552 my $collection = $gsdl_cgi->clean_param("c");
553 if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
554 $gsdl_cgi->generate_error("No collection specified.");
555 }
556 my $source_file = $gsdl_cgi->clean_param("source");
557 if ((!defined $source_file) || ($source_file =~ m/^\s*$/)) {
558 $gsdl_cgi->generate_error("No source file specified.");
559 }
560 $source_file =~ s/\|/&util::get_dirsep()/eg; # Convert the '|' characters into whatever is right for this OS
561 my $target_file = $gsdl_cgi->clean_param("target");
562 if ((!defined $target_file) || ($target_file =~ m/^\s*$/)) {
563 $gsdl_cgi->generate_error("No target file specified.");
564 }
565 $target_file =~ s/\|/&util::get_dirsep()/eg; # Convert the '|' characters into whatever is right for this OS
566
567 # Make sure we don't try to move anything outside the collection
568 if ($source_file =~ /\.\./ || $target_file =~ /\.\./) {
569 $gsdl_cgi->generate_error("Illegal file specified.");
570 }
571
572 # Ensure the user is allowed to edit this collection
573 &authenticate_user($gsdl_cgi, $username, $collection);
574
575 my $gsdlhome = $ENV{'GSDLHOME'};
576 my $collection_directory = &util::filename_cat($gsdlhome, "collect", $collection);
577 $gsdl_cgi->checked_chdir($collection_directory);
578
579 # Check that the collection source file exists
580 if (!-e $source_file) {
581 $gsdl_cgi->generate_error("Collection file $source_file does not exist.");
582 }
583
584 # Make sure the collection isn't locked by someone else
585 &lock_collection($gsdl_cgi, $username, $collection);
586
587 &util::mv($source_file, $target_file);
588
589 # Check that the collection source file was moved
590 if (-e $source_file || !-e $target_file) {
591 $gsdl_cgi->generate_error("Could not move collection file $source_file to $target_file.");
592 }
593
594 $gsdl_cgi->generate_ok_message("Collection file $source_file moved to $target_file successfully.");
595}
596
597
598sub new_collection_directory
599{
600 my ($gsdl_cgi, $username) = @_;
601
602 my $collection = $gsdl_cgi->clean_param("c");
603 if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
604 $gsdl_cgi->generate_error("No collection specified.");
605 }
606 my $directory = $gsdl_cgi->clean_param("directory");
607 if ((!defined $directory) || ($directory =~ m/^\s*$/)) {
608 $gsdl_cgi->generate_error("No directory specified.");
609 }
610 $directory =~ s/\|/&util::get_dirsep()/eg; # Convert the '|' characters into whatever is right for this OS
611
612 # Make sure we don't try to create anything outside the collection
613 if ($directory =~ /\.\./) {
614 $gsdl_cgi->generate_error("Illegal directory specified.");
615 }
616
617 # Ensure the user is allowed to edit this collection
618 &authenticate_user($gsdl_cgi, $username, $collection);
619
620 my $gsdlhome = $ENV{'GSDLHOME'};
621 my $collection_directory = &util::filename_cat($gsdlhome, "collect", $collection);
622 $gsdl_cgi->checked_chdir($collection_directory);
623
624 # Check that the collection directory doesn't already exist
625 if (-d $directory) {
626 $gsdl_cgi->generate_error("Collection directory $directory already exists.");
627 }
628
629 # Make sure the collection isn't locked by someone else
630 &lock_collection($gsdl_cgi, $username, $collection);
631
632 &util::mk_dir($directory);
633
634 # Check that the collection directory was created
635 if (!-d $directory) {
636 $gsdl_cgi->generate_error("Could not create collection directory $directory.");
637 }
638
639 $gsdl_cgi->generate_ok_message("Collection directory $directory created successfully.");
640}
641
642
643sub run_script
644{
645 my ($gsdl_cgi, $username) = @_;
646
647 my $script = $gsdl_cgi->clean_param("script");
648 if ((!defined $script) || ($script =~ m/^\s*$/)) {
649 $gsdl_cgi->generate_error("No script specified.");
650 }
651 $gsdl_cgi->delete("script");
652 my $collection = $gsdl_cgi->clean_param("c");
653 if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
654 $gsdl_cgi->generate_error("No collection specified.");
655 }
656 $gsdl_cgi->delete("c");
657
658 # Ensure the user is allowed to edit this collection
659 &authenticate_user($gsdl_cgi, $username, $collection);
660
661 # Make sure the collection isn't locked by someone else (unless we're running mkcol.pl, of course)
662 &lock_collection($gsdl_cgi, $username, $collection) unless ($script eq "mkcol.pl");
663
664 my $perl_args = $collection;
665 foreach my $cgi_arg_name ($gsdl_cgi->param) {
666 my $cgi_arg_value = $gsdl_cgi->safe_val($gsdl_cgi->clean_param($cgi_arg_name));
667 if ($cgi_arg_value eq "") {
668 $perl_args = "-$cgi_arg_name " . $perl_args;
669 }
670 else {
671 $perl_args = "-$cgi_arg_name \"$cgi_arg_value\" " . $perl_args;
672 }
673 }
674
675 my $perl_command = "perl -S $script $perl_args 2>&1";
676 if (!open(PIN, "$perl_command |")) {
677 $gsdl_cgi->generate_error("Unable to execute command: $perl_command");
678 }
679
680 print STDOUT "Content-type:text/plain\n\n";
681 while (defined (my $perl_output_line = <PIN>)) {
682 print STDOUT $perl_output_line;
683 }
684 close(PIN);
685
686 my $perl_status = $?;
687 if ($perl_status > 0) {
688 $gsdl_cgi->generate_error("Perl failed: $perl_command\n--\nExit status: " . ($perl_status / 256));
689 }
690 elsif ($mail_enabled) {
691 if ($script eq "buildcol.pl") {
692 &send_mail($gsdl_cgi, "Remote Greenstone building event", "Build of collection '$collection' complete.");
693 }
694 }
695}
696
697
698sub upload_collection_file
699{
700 my ($gsdl_cgi, $username) = @_;
701
702 my $collection = $gsdl_cgi->clean_param("c");
703 if ((!defined $collection) || ($collection =~ m/^\s*$/)) {
704 $gsdl_cgi->generate_error("No collection specified.");
705 }
706 my $file = $gsdl_cgi->clean_param("file");
707 if ((!defined $file) || ($file =~ m/^\s*$/)) {
708 $gsdl_cgi->generate_error("No file specified.");
709 }
710 my $directory = $gsdl_cgi->clean_param("directory") || "";
711 $directory =~ s/\|/&util::get_dirsep()/eg; # Convert the '|' characters into whatever is right for this OS
712 my $zip = $gsdl_cgi->clean_param("zip");
713
714 # Make sure we don't try to upload anything outside the collection
715 if ($file =~ /\.\./) {
716 $gsdl_cgi->generate_error("Illegal file specified.");
717 }
718 if ($directory =~ /\.\./) {
719 $gsdl_cgi->generate_error("Illegal directory specified.");
720 }
721
722 # Ensure the user is allowed to edit this collection
723 &authenticate_user($gsdl_cgi, $username, $collection);
724
725 my $gsdlhome = $ENV{'GSDLHOME'};
726 my $collection_directory = &util::filename_cat($gsdlhome, "collect", $collection);
727 $gsdl_cgi->checked_chdir($collection_directory);
728
729 # Make sure the collection isn't locked by someone else
730 &lock_collection($gsdl_cgi, $username, $collection);
731
732 my $directory_path = &util::filename_cat($collection_directory, $directory);
733 if (!-d $directory_path) {
734 &util::mk_dir($directory_path);
735 if (!-d $directory_path) {
736 $gsdl_cgi->generate_error("Could not create directory $directory_path.");
737 }
738 }
739
740 my $file_path = &util::filename_cat($directory_path, $username . "-" . $file);
741 if (!open(FOUT, ">$file_path")) {
742 $gsdl_cgi->generate_error("Unable to write file $file_path");
743 }
744
745 # Read the uploaded data and write it out to file
746 my $buf;
747 my $num_bytes = 0;
748 binmode(FOUT);
749 while (read(STDIN, $buf, 1024) > 0) {
750 print FOUT $buf;
751 $num_bytes += length($buf);
752 }
753 close(FOUT);
754
755 # If we have downloaded a zip file, unzip it
756 if (defined $zip) {
757 my $java = $gsdl_cgi->get_java_path();
758 my $java_classpath = &util::filename_cat($gsdlhome, "bin", "java", "GLIServer.jar");
759 my $java_args = "\"$file_path\" \"$directory_path\"";
760 my $java_command = "$java -classpath \"$java_classpath\" org.greenstone.gatherer.util.Unzip $java_args";
761
762 my $java_output = `$java_command`;
763 my $java_status = $?;
764
765 # Remove the zip file once we have unzipped it, since it is an intermediate file only
766 unlink("$file_path");
767
768 if ($java_status > 0) {
769 $gsdl_cgi->generate_error("Java failed: $java_command\n--\n$java_output\nExit status: " . ($java_status / 256) . "\n" . $gsdl_cgi->check_java_home());
770 }
771 }
772
773 $gsdl_cgi->generate_ok_message("Collection file $file uploaded successfully.");
774}
775
776
777sub put_file
778{
779 my $gsdl_cgi = shift(@_);
780 my $file_path = shift(@_);
781 my $content_type = shift(@_);
782
783 if (open(PIN, "<$file_path")) {
784 print STDOUT "Content-type:$content_type\n\n";
785
786 my $buf;
787 my $num_bytes = 0;
788 binmode(PIN);
789 while (read(PIN, $buf, 1024) > 0) {
790 print STDOUT $buf;
791 $num_bytes += length($buf);
792 }
793
794 close(PIN);
795 }
796 else {
797 $gsdl_cgi->generate_error("Unable to read file $file_path\n $!");
798 }
799}
800
801
802sub send_mail
803{
804 my $gsdl_cgi = shift(@_);
805 my $mail_subject = shift(@_);
806 my $mail_content = shift(@_);
807
808 my $sendmail_command = "perl -S sendmail.pl";
809 $sendmail_command .= " -to \"" . $mail_to_address . "\"";
810 $sendmail_command .= " -from \"" . $mail_from_address . "\"";
811 $sendmail_command .= " -smtp \"" . $mail_smtp_server . "\"";
812 $sendmail_command .= " -subject \"" . $mail_subject . "\"";
813
814 if (!open(POUT, "| $sendmail_command")) {
815 $gsdl_cgi->generate_error("Unable to execute command: $sendmail_command");
816 }
817 print POUT $mail_content . "\n";
818 close(POUT);
819}
820
821
822&main();
Note: See TracBrowser for help on using the repository browser.