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

Last change on this file since 13811 was 13811, checked in by mdewsnip, 17 years ago

Now uses the new timestamp argument instead of the username in zip file names, to avoid having the username in the name twice for personal collections.

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