Diff for /loncom/publisher/loncfile.pm between versions 1.36 and 1.128

version 1.36, 2003/08/03 00:40:00 version 1.128, 2024/05/13 13:55:50
Line 37 Line 37
   
 =head1 NAME  =head1 NAME
   
 Apache::loncfile - Construction space file management.  Apache::loncfile - Authoring space file management.
   
 =head1 SYNOPSIS  =head1 SYNOPSIS
    
  Content handler for buttons on the top frame of the construction space    Content handler for buttons on the top frame of the construction space
 directory.  directory.
   
 =head1 INTRODUCTION  =head1 INTRODUCTION
   
   loncfile is invoked when buttons in the top frame of the construction     loncfile is invoked when buttons in the top frame of the construction
 space directory listing are clicked.   All operations proceed in two phases.  space directory listing are clicked.   All operations proceed in two phases.
 The first phase describes to the user exactly what will be done.  If the user  The first phase describes to the user exactly what will be done.  If the user
 confirms the operation, the second phase commits the operation and indicates  confirms the operation, the second phase commits the operation and indicates
Line 68  use File::Basename; Line 68  use File::Basename;
 use File::Copy;  use File::Copy;
 use HTML::Entities();  use HTML::Entities();
 use Apache::Constants qw(:common :http :methods);  use Apache::Constants qw(:common :http :methods);
 use Apache::loncacc;  
 use Apache::Log ();  
 use Apache::lonnet;  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
   use Apache::lonhtmlcommon;
   use Apache::lonlocal;
   use LONCAPA qw(:DEFAULT :match);
   
 my $DEBUG=0;  my $DEBUG=0;
 my $r; # Needs to be global for some stuff RF.  my $r; # Needs to be global for some stuff RF.
Line 87  my $r;    # Needs to be global for some Line 88  my $r;    # Needs to be global for some
  Parameters:   Parameters:
   
 =over 4  =over 4
    
 =item $request - The current request operation.  =item $request - The current request operation.
   
 =item $message - The message to put in the log file.  =item $message - The message to put in the log file.
   
 =back  =back
     
  Returns:   Returns:
    nothing.     nothing.
   
 =cut  =cut
   
 sub Debug {  sub Debug {
         # Put out the indicated message but only if DEBUG is true.
   # Marshall the parameters.      if ($DEBUG) {
      my ($r,$message) = @_;
   my $r       = shift;   $r->log_reason($message);
   my $log     = $r->log;      }
   my $message = shift;  }
     
   # Put out the indicated message butonly if DEBUG is true.  sub done {
         my ($destfn) = @_;
   if ($DEBUG) {      return
     $log->debug($message);         '<p>'
   }        .&Apache::lonhtmlcommon::confirm_success(&mt("Done"))
         .'<br /><a href="'.&url($destfn).'">'.&mt("Continue").'</a>'
         .'<script type="text/javascript">'
         .'location.href="'.&url($destfn,'js').'";'
         .'</script>'
         .'</p>';
 }  }
   
 =pod  =pod
Line 119  sub Debug { Line 125  sub Debug {
 =item URLToPath($url)  =item URLToPath($url)
   
   Convert a URL to a file system path.    Convert a URL to a file system path.
     
   In order to manipulate the construction space objects, it is necessary    In order to manipulate the construction space objects, it is necessary
   to access url identified objects a filespace objects.  This function    to access url identified objects a filespace objects.  This function
   translates a construction space URL to a file system path.    translates a construction space URL to a file system path.
Line 128  sub Debug { Line 134  sub Debug {
 =over 4  =over 4
   
 =item  Url    - string [in] The url to convert.  =item  Url    - string [in] The url to convert.
     
 =back  =back
     
  Returns:   Returns:
   
 =over 4  =over 4
   
 =item  The corresponding file system path.   =item  The corresponding file system path.
   
 =back  =back
   
Line 150  Global References Line 156  Global References
 =cut  =cut
   
 sub URLToPath {  sub URLToPath {
   my $Url = shift;      my $Url = shift;
   &Debug($r, "UrlToPath got: $Url");      &Debug($r, "UrlToPath got: $Url");
   $Url=~ s/^http\:\/\/[^\/]+//;      $Url=~ s{^https?\://[^/]+}{};
   $Url=~ s/^\///;      $Url=~ s{//+}{/}g;
   $Url=~ s/(\~|priv\/)(\w+)\//\/home\/$2\/public_html\//;      $Url=~ s{^/}{};
   &Debug($r, "Returning $Url \n");      $Url=$Apache::lonnet::perlvar{'lonDocRoot'}."/$Url";
   return $Url;      &Debug($r, "Returning $Url \n");
       return $Url;
 }  }
   
 sub url {  sub url {
     my $fn=shift;      my ($fn,$context) = @_;
     $fn=~s/^\/home\/(\w+)\/public\_html/\/priv\/$1/;      my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
       $fn=~ s/^\Q$londocroot\E//;
       $fn=~s{/\./}{/}g;
       if ($context eq 'js') {
           &js_escape(\$fn);
       } else {
           $fn=&HTML::Entities::encode($fn,'\'<>"&');
       }
     return $fn;      return $fn;
 }  }
   
 sub display {  sub display {
     my $fn=shift;      my $fn=shift;
     $fn=~s/^\/home\/(\w+)\/public\_html//;      my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
     return '<tt>'.$fn.'</tt>';      $fn=~s/^\Q$londocroot\E//;
       $fn=~s{/\./}{/}g;
       return '<span class="LC_filename">'.$fn.'</span>';
 }  }
   
 =pod  
   
 =item PublicationPath($domain, $user, $dir, $file)  
   
    Determines the filesystem path corresponding to a published resource  
    specification.  The returned value is the path.  
 Parameters:  
   
 =over 4  
   
 =item   $domain - string [in] Name of the domain within which the resource is   
              stored.  
   
 =item   $user   - string [in] Name of the user asking about the resource.  
   
 =item   $dir    - Directory path relative to the top of the resource space.  
   
 =item   $file   - name of the resource file itself without path info.  
   
 =back  
   
 =over 4  
   
 Returns:  
   
 =item  string - full path to the file if it exists in publication space.  
   
 =back  
        
 =cut  
   
 sub PublicationPath  # see if the file is
 {  # a) published (return 0 if not)
   my ($domain, $user, $dir, $file)=@_;  # b) if, so obsolete (return 0 if not)
   
   return '/home/httpd/html/res/'.$domain.'/'.$user.'/'.$dir.'/'.  sub obsolete_unpub {
  $file;      my ($user,$domain,$construct)=@_;
       my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
       my $published=$construct;
       $published=~s{^\Q$londocroot/priv/\E}{$londocroot/res/};
       if (-e $published) {
    if (&Apache::lonnet::metadata($published,'obsolete')) {
       return 1;
    }
    return 0;
       } else {
    return 1;
       }
 }  }
   
 =pod  # see if directory is empty
   # ignores any .meta, .save, .bak, and .log files created for a previously
 =item ConstructionPath($domain, $user, $dir, $file)  # published file, which has since been marked obsolete and deleted.
   # ignores a .DS_Store file put there when viewing directory via webDAV on MacOS.
    Determines the filesystem path corresponding to a construction space  sub empty_directory {
    resource specification.  The returned value is the path      my ($dirname,$phase) = @_;
 Parameters:      if (opendir DIR, $dirname) {
           my @files = grep(!/^\.\.?$/, readdir(DIR)); # ignore . and ..
 =over 4          if (@files) {
               my @orphans = grep(/\.(meta|save|log|bak|DS_Store)$/,@files);
 =item   $user   - string [in] Name of the user asking about the resource.              if (scalar(@files) - scalar(@orphans) > 0) {
                   return 0;
 =item   $dir    - Directory path relative to the top of the resource space.              } else {
                   if (($phase eq 'Delete2') && (@orphans > 0)) {
 =item   $file   - name of the resource file itself without path info.                      foreach my $file (@orphans) {
                           if ($file =~ /\.(meta|save|log|bak)$/) {
 Returns:                              unlink($dirname.$file);
                           }
 =item  string - full path to the file if it exists in Construction space.                      }
                   }
 =back              }
                }
 =cut          closedir(DIR);
           return 1;
 sub ConstructionPath {      }
   my ($user, $dir, $file) = @_;      return 0;
   
   return '/home/'.$user.'/public_html/'.$dir.'/'.$file;  
   
 }  }
   
 =pod  =pod
   
 =item exists($user, $domain, $directory, $file)  =item exists($user, $domain, $file)
   
    Determine if a resource file name has been published or exists     Determine if a resource filename has been published or exists
    in the construction space.     in the construction space.
   
  Parameters:   Parameters:
   
 =over 4  =over 4
   
 =item  $user   - string [in] - Name of the user for which to check.  =item  $user     - string [in] - Name of the user for which to check.
   
 =item  $domain - string [in] - Name of the domain in which the resource  =item  $domain   - string [in] - Name of the domain in which the resource
                           might have been published.                            might have been published.
   
 =item  $dir    - string [in] - Path relative to construction or resource space  =item  $file     - string [in] - Name of the file.
                           in which the resource might live.  
   
 =item  $file   - string [in] - Name of the file.  =item  $creating - string [in] - optional, type of object being created,
                                  either 'directory' or 'file'. Defaults to
                                  'file' if unspecified.
   
 =back  =back
   
Line 268  Returns: Line 263  Returns:
   
 =over 4  =over 4
   
   =item  string - Either undef, 'warning' or 'error' depending on the
                   type of problem
   
 =item  string - Either where the resource exists as an html string that can  =item  string - Either where the resource exists as an html string that can
            be embedded in a dialog or an empty string if the resource             be embedded in a dialog or an empty string if the resource
            does not exist.             does not exist.
     
 =back  =back
   
 =cut  =cut
   
 sub exists {  sub exists {
   my ($user, $domain, $dir, $file) = @_;      my ($user, $domain, $construct, $creating) = @_;
       $creating ||= 'file';
   
   # Create complete paths in publication and construction space.      my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
   my $relativedir=$dir;      my $published=$construct;
   $relativedir=s|/home/\Q$user\E/public_html||;      $published=~s{^\Q$londocroot/priv/\E}{$londocroot/res/};
   my $published = &PublicationPath($domain, $user, $relativedir, $file);      my ($type,$result);
   my $construct = &ConstructionPath($user, $relativedir, $file);      if ( -d $construct ) {
    return ('error','<p class="LC_error">'.&mt('Error: destination for operation is an existing directory.').'</p>');
   # If the resource exists in either space indicate this fact.  
   # Note that the check for existence in resource space is stricter.      }
   
   my $result;          if ( -e $published) {
   if ( -d $construct ) {   if ( -e $construct ) {
       return 'Error: destination for operation is a directory.';      $type = 'warning';
   }      $result.='<p class="LC_warning">'.&mt('Warning: target file exists, and has been published!').'</p>';
   if ( -e $published) {   } else {
       $result.='<p><font color="red">Warning: target file exists, and has been published!</font></p>';      my $published_type = (-d $published) ? 'directory' : 'file';
   } elsif ( -e $construct) {  
       $result.='<p><font color="red">Warning: target file exists!</font></p>';  
   }  
   
   return $result;      if ($published_type eq $creating) {
    $type = 'warning';
    $result.='<p class="LC_warning">'.&mt("Warning: a published $published_type of this name exists.").'</p>';
       } else {
    $type = 'error';
    $result.='<p class="LC_error">'.&mt("Error: a published $published_type of this name exists.").'</p>';
       }
    }
       } elsif ( -e $construct) {
    $type = 'warning';
    $result.='<p class="LC_warning">'.&mt('Warning: target file exists!').'</p>';
       }
   
       return ($type,$result);
 }  }
   
 =pod  =pod
   
 =item checksuffix($old, $new)  =item checksuffix($old, $new)
           
   Determine if a resource filename suffix (the stuff after the .) would change    Determine if a resource filename suffix (the stuff after the .) would change
 as a result of this operation.  as a result of this operation.
   
Line 338  sub checksuffix { Line 346  sub checksuffix {
     my $newsuffix;      my $newsuffix;
     if ($new=~m:(.*/*)([^/]+)\.(\w+)$:) { $newsuffix=$3; }      if ($new=~m:(.*/*)([^/]+)\.(\w+)$:) { $newsuffix=$3; }
     if ($old=~m:(.*)/+([^/]+)\.(\w+)$:) { $oldsuffix=$3; }      if ($old=~m:(.*)/+([^/]+)\.(\w+)$:) { $oldsuffix=$3; }
     if ($oldsuffix ne $newsuffix) {      if (lc($oldsuffix) ne lc($newsuffix)) {
  $result.=   $result.=
             '<p><font color="red">Warning: change of MIME type!</font></p>';              '<p class="LC_warning">'.&mt('Warning: change of MIME type!').'></p>';
     }      }
     return $result;      return $result;
 }  }
   
 sub cleanDest {  sub cleanDest {
     my ($request,$dest)=@_;      my ($dest,$subdir,$fn,$uname,$udom)=@_;
     #remove bad characters      #remove bad characters
     if  ($dest=~/[\#\?&]/) {      my $foundbad=0;
  $request->print("<p><font color=\"red\">Invalid characters in requested name have been removed.</font></p>");      my $warnings;
  $dest=~s/[\#\?&]//g;      my $error='';
       if ($subdir && $dest =~/\./) {
    $foundbad=1;
    $dest=~s/\.//g;
     }      }
     return $dest;      $dest =~ s/(\s+$|^\s+)//g;
       if  ($dest=~/[\#\?&%\":]/) {
    $foundbad=1;
    $dest=~s/[\#\?&%\":]//g;
       }
       if ($dest=~m|/|) {
    my ($newpath)=($dest=~m|(.*)/|);
    ($newpath,$error)=&relativeDest($fn,$newpath,$uname,$udom);
    if (! -d "$newpath") {
       $warnings = '<p class="LC_warning">'
                          .&mt("You have requested to create file in directory [_1] which doesn't exist. The requested directory path has been removed from the requested filename."
                              ,&display($newpath))
                          .'</p>';
       $dest=~s|.*/||;
    }
       }
       if ($dest =~ /\.(\d+)\.(\w+)$/) {
    $warnings .= '<p class="LC_warning">'
                       .&mt('Bad filename [_1]',&display($dest))
                       .'<br />'
                       .&mt('[_1](name).(number).(extension)[_2] not allowed.','<tt>','</tt>')
                       .'<br />'
                       .&mt('Removing the [_1].number.[_2] from requested filename.','<tt>','</tt>')
                       .'</p>';
    $dest =~ s/\.(\d+)(\.\w+)$/$2/;
       }
       if ($foundbad) {
           $warnings .= '<p class="LC_warning">'
                       .&mt('Invalid characters in requested name have been removed.')
                       .'</p>';
       }
       return ($dest,$error,$warnings);
 }  }
   
 sub relativeDest {  sub relativeDest {
     my ($fn,$newfilename,$uname)=@_;      my ($fn,$newfilename,$uname,$udom)=@_;
       my $error = '';
     if ($newfilename=~/^\//) {      if ($newfilename=~/^\//) {
 # absolute, simply add path  # absolute, simply add path
  $newfilename='/home/'.$uname.'/public_html/';          my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
    $newfilename="$londocroot/res/$udom/$uname/";
     } else {      } else {
  my $dir=$fn;   my $dir=$fn;
  $dir=~s/\/[^\/]+$//;   $dir=~s{/[^/]+$}{};
  $newfilename=$dir.'/'.$newfilename;   $newfilename=$dir.'/'.$newfilename;
     }      }
     $newfilename=~s://+:/:g; # remove duplicate /      $newfilename=~s{//+}{/}g; # remove duplicate /
     while ($newfilename=~m:/\.\./:) {      while ($newfilename=~m{/\.\./}) {
  $newfilename=~ s:/[^/]+/\.\./:/:g; #remove dir/..   $newfilename=~ s{/[^/]+/\.\./}{/}g; #remove dir/..
       }
       my ($authorname,$authordom)=&Apache::lonnet::constructaccess($newfilename);
       unless (($authorname) && ($authordom)) {
          my $otherdir = &display($newfilename);
          $error = &mt('Access denied to [_1]',$otherdir);
     }      }
     return $newfilename;      return ($newfilename,$error);
 }  }
   
 =pod  =pod
Line 391  Parameters: Line 440  Parameters:
 =cut  =cut
   
 sub CloseForm1 {  sub CloseForm1 {
    my ($request,  $fn) = @_;      my ($request,  $fn) = @_;
    $request->print('<p><input type="submit" value="Continue" /></p></form>');      $request->print('<input type="submit" value="'.&mt('Continue').'" /></form>');
    $request->print('<form action="'.&url($fn).      $request->print(' <form action="'.&url($fn).'" method="post">'.
      '" method="POST"><p><input type="submit" value="Cancel" /></p></form>');                      '<input type="submit" value="'.&mt('Cancel').'" /></form>');
 }  }
   
   
Line 414  Parameters: Line 463  Parameters:
 =item   $user       - string [in] - Name of the user that is initiating the  =item   $user       - string [in] - Name of the user that is initiating the
                  request.                   request.
   
 =item   $directory  - string [in] - Directory in which the operation is   =item   $directory  - string [in] - Directory in which the operation is
                  being done relative to the top level construction space                   being done relative to the top level construction space
                  directory.                   directory.
   
Line 423  Parameters: Line 472  Parameters:
 =cut  =cut
   
 sub CloseForm2 {  sub CloseForm2 {
   my ($request, $user, $fn) = @_;      my ($request, $user, $fn) = @_;
   $request->print('<h3><a href="'.&url($fn).'/">Done</a></h3>');      $request->print(&done($fn));
 }  }
   
 =pod  =pod
   
 =item Rename1($request, $filename, $user, $domain, $dir)  =item Rename1($request, $filename, $user, $domain, $dir)
    
    Perform phase 1 processing of the file rename operation.     Perform phase 1 processing of the file rename operation.
   
 Parameters:  Parameters:
   
 =over 4  =over 4
   
 =item  $request   - Apache Request Object [in] The request object for the   =item  $request   - Apache Request Object [in] The request object for the
 current request.  current request.
   
 =item  $filename  - The filename relative to construction space.  =item  $filename  - The filename relative to construction space.
Line 460  new filename relative to the current dir Line 509  new filename relative to the current dir
   
 =back  =back
   
 =cut    =cut
   
 sub Rename1 {  sub Rename1 {
     my ($request, $user, $domain, $fn, $newfilename) = @_;      my ($request, $user, $domain, $fn, $newfilename, $style) = @_;
   
     if(-e $fn) {      if(-e $fn) {
  if($newfilename) {   if($newfilename) {
       # is dest a dir
       if ($style eq 'move') {
    if (-d $newfilename) {
       if ($fn =~ m|/([^/]*)$|) { $newfilename .= '/'.$1; }
    }
       }
     if ($newfilename =~ m|/[^\.]+$|) {      if ($newfilename =~ m|/[^\.]+$|) {
  #no extension add on original extension   #no extension add on original extension
  if ($fn =~ m|/[^\.]*\.([^\.]+)$|) {   if ($fn =~ m|/[^\.]*\.([^\.]+)$|) {
Line 475  sub Rename1 { Line 530  sub Rename1 {
     }      }
     $request->print(&checksuffix($fn, $newfilename));      $request->print(&checksuffix($fn, $newfilename));
     #renaming a dir, delete the trailing /      #renaming a dir, delete the trailing /
             #remove last element for current dir              #remove second to last element for current dir
     my $dir=$fn;      if (-d $fn) {
     if ($fn =~ m|/$|) {   $newfilename=~/\.(\w+)$/;
  $fn =~ s|/$||;   if (&Apache::loncommon::fileembstyle($1) eq 'ssi') {
  $dir =~ s|/[^/]*$||;      $request->print('<p><span class="LC_error">'.
       &mt('Cannot change MIME type of a directory.').
       '</span>'.
       '<br /><a href="'.&url($fn).'">'.&mt('Cancel').'</a></p>');
       return;
    }
    $newfilename=~s/\/[^\/]+\/([^\/]+)$/\/$1/;
       }
       $newfilename=~s://+:/:g; # remove duplicate /
       while ($newfilename=~m:/\.\./:) {
    $newfilename=~ s:/[^/]+/\.\./:/:g; #remove dir/..
     }      }
     my $return=&exists($user, $domain, $dir, $newfilename);      my ($type, $return)=&exists($user, $domain, $newfilename);
     $request->print($return);      $request->print($return);
     if ($return =~/^Error:/) {      if ($type eq 'error') {
  $request->print('<br /><a href="'.&url($fn).'">Cancel</a>');   $request->print('<br /><a href="'.&url($fn).'">'.&mt('Cancel').'</a>');
    return;
       }
       unless (&obsolete_unpub($user,$domain,$fn)) {
                   $request->print('<p><span class="LC_error">'
                                  .&mt('Cannot rename or move non-obsolete published file.')
                                  .'</span><br />'
                                  .'<a href="'.&url($fn).'">'.&mt('Cancel').'</a></p>'
                   );
  return;   return;
     }      }
     $request->print('<input type="hidden" name="newfilename" value="'.      my $action;
     $newfilename.      if ($style eq 'rename') {
     '" /><p>Rename '.&display($fn).   $action='Rename';
     '</tt><br />to '.&display($newfilename).'?</p>');      } else {
    $action='Move';
       }
               $request->print('<input type="hidden" name="newfilename" value="'
                              .$newfilename.'" />'
                              .'<p>'
                              .&mt($action.' [_1] to [_2]?',
                                   &display($fn),
                                   &display($newfilename))
                              .'</p>'
           );
     &CloseForm1($request, $fn);      &CloseForm1($request, $fn);
  } else {   } else {
     $request->print('<p>No new filename specified.</p></form>');      $request->print('<p class="LC_error">'.&mt('No new filename specified.').'</p></form>');
     return;      return;
  }   }
     } else {      } else {
  $request->print('<p> No such file: '.&display($fn).'</p></form>');          $request->print('<p class="LC_error">'
                          .&mt('No such file: [_1]',
                               &display($fn))
                          .'</p></form>'
           );
  return;   return;
     }      }
       
 }  }
   
 =pod  =pod
   
 =item Delete1  =item Delete1
Line 513  Parameters: Line 601  Parameters:
   
 =over 4  =over 4
   
 =item   $request   - Apache Request Object [in] request object for the current   =item   $request   - Apache Request Object [in] request object for the current
                 request.                  request.
   
 =item   $user      - string [in]  Name of the user initiating the request.  =item   $user      - string [in]  Name of the user initiating the request.
Line 527  Parameters: Line 615  Parameters:
 =cut  =cut
   
 sub Delete1 {  sub Delete1 {
   my ($request, $user, $domain, $fn) = @_;      my ($request, $user, $domain, $fn) = @_;
   
   if( -e $fn) {      if( -e $fn) {
     $request->print('<input type="hidden" name="newfilename" value="'.   $request->print('<input type="hidden" name="newfilename" value="'.
     $fn.'"/>');   $fn.'" />');
     $request->print('<p>Delete '.&display($fn).'?</p>');          if (-d $fn) {
     &CloseForm1($request, $fn);              unless (&empty_directory($fn,'Delete1')) {
   } else {                  $request->print('<p>'
     $request->print('<p>No such file: '.&display($fn).'</p></form>');                                 .'<span class="LC_error">'
   }                                 .&mt('Only empty directories may be deleted.')
                                  .'</span><br />'
                                  .&mt('You must delete the contents of the directory first.')
                                  .'</p>'
                                  .'<p><a href="'.&url($fn).'">'.&mt('Cancel').'</a></p>'
                   );
                   return;
               }
           } else {
       unless (&obsolete_unpub($user,$domain,$fn)) {
                   $request->print('<p><span class="LC_error">'
                                  .&mt('Cannot delete non-obsolete published file.')
                                  .'</span><br />'
                                  .'<a href="'.&url($fn).'">'.&mt('Cancel').'</a></p>'
                   );
           return;
       }
           }
           $request->print('<p>'
                          .&mt('Delete [_1]?',
                               &display($fn))
                          .'</p>'
           );
    &CloseForm1($request, $fn);
       } else {
           $request->print('<p class="LC_error">'
                          .&mt('No such file: [_1]',
                               &display($fn))
                          .'</p></form>'
           );
       }
 }  }
   
 =pod  =pod
Line 551  Parameters: Line 669  Parameters:
   
 =over 4  =over 4
   
 =item   $request   - Apache Request Object [in] request object for the current   =item   $request   - Apache Request Object [in] request object for the current
                 request.                  request.
   
 =item   $user      - string [in]  Name of the user initiating the request.  =item   $user      - string [in]  Name of the user initiating the request.
Line 567  Parameters: Line 685  Parameters:
 =cut  =cut
   
 sub Copy1 {  sub Copy1 {
   my ($request, $user, $domain, $fn, $newfilename) = @_;      my ($request, $user, $domain, $fn, $newfilename) = @_;
   
   if(-e $fn) {      if(-e $fn) {
     $request->print(&checksuffix($fn,$newfilename));   # is dest a dir
     my $return=&exists($user, $domain, $fn, $newfilename);   if (-d $newfilename) {
     $request->print($return);      if ($fn =~ m|/([^/]*)$|) { $newfilename .= '/'.$1; }
     if ($return =~/^Error:/) {   }
  $request->print('<br /><a href="'.&url($fn).'">Cancel</a>');   if ($newfilename =~ m|/[^\.]+$|) {
  return;      #no extension add on original extension
       if ($fn =~ m|/[^\.]*\.([^\.]+)$|) { $newfilename.='.'.$1; }
    }
    $newfilename=~s://+:/:g; # remove duplicate /
    while ($newfilename=~m:/\.\./:) {
       $newfilename=~ s:/[^/]+/\.\./:/:g; #remove dir/..
    }
    $request->print(&checksuffix($fn,$newfilename));
    my ($type,$return)=&exists($user, $domain, $newfilename);
    $request->print($return);
    if ($type eq 'error') {
       $request->print('<br /><a href="'.&url($fn).'">'.&mt('Cancel').'</a></form>');
       return;
    }
   # Check if there is enough space.
           my @fileinfo = stat($fn);
           my ($dir,$fname) = ($fn =~ m{^(.+/)([^/]+)$});
           my $filesize = $fileinfo[7];
           $filesize = int($filesize/1000); #expressed in kb
           my $output = &Apache::loncommon::excess_filesize_warning($user,$domain,'author',
                                                                    $fname,$filesize,'copy');
           if ($output) {
               $request->print($output.'<br /><a href="'.&url($dir).'">'.&mt('Cancel').'</a></form>');
               return;
           }
       $request->print(
           '<input type="hidden" name="newfilename"'
          .' value="'.$newfilename.'" />'
          .'<p>'
          .&mt('Copy [_1] to [_2]?',
               &display($fn),
               &display($newfilename))
          .'</p>'
           );
    &CloseForm1($request, $fn);
       } else {
           $request->print('<p class="LC_error">'
                          .&mt('No such file: [_1]',
                               &display($fn))
                          .'</p></form>'
           );
     }      }
     $request->print('<input type = "hidden" name = "newfilename" value = "'.  
     $newfilename.  
     '" /><p>Copy '.&display($fn).'<br />to '.  
     &display($newfilename).'?</p>');  
     &CloseForm1($request, $fn);  
   } else {  
     $request->print('<p>No such file: '.&display($fn).'</p></form>');  
   }  
 }  }
   
 =pod  =pod
   
 =item NewDir1  =item NewDir1
    
   Does all phase 1 processing of directory creation:    Does all phase 1 processing of directory creation:
   Ensures that the user provides a new directory name,    Ensures that the user provides a new directory name,
   and that the directory does not already exist.    and that the directory does not already exist.
Line 608  Parameters: Line 758  Parameters:
   
 =item   $fn     - source file.  =item   $fn     - source file.
   
 =item   $newdir   - Name of the directory to be created; path relative to the   =item   $newdir   - Name of the directory to be created; path relative to the
                top level of construction space.                 top level of construction space.
 =back  =back
   
Line 626  causes the newdir operation to transitio Line 776  causes the newdir operation to transitio
 =cut  =cut
   
   
 sub NewDir1  sub NewDir1 {
 {      my ($request, $username, $domain, $fn, $newfilename, $mode) = @_;
   my ($request, $username, $domain, $fn, $newfilename) = @_;  
       my ($type, $result)=&exists($username,$domain,$newfilename,'directory');
   if(-e $newfilename) {      $request->print($result);
     $request->print('<p>Directory exists.</p></form>');      if ($type eq 'error') {
   }   $request->print('</form>');
   else {      } else {
     $request->print('<input type="hidden" name="newfilename" value="'.   if (($mode eq 'testbank') || ($mode eq 'imsimport')) {
     $newfilename.'" /><p>Make new directory '.      $request->print('<input type="hidden" name="callingmode" value="'.$mode.'" />'."\n".
     &display($newfilename).'?</p>');                              '<input type="hidden" name="inhibitmenu" value="yes" />');
     &CloseForm1($request, $fn);   }
   }          $request->print('<input type="hidden" name="newfilename" value="'
                          .$newfilename.'" />'
                          .'<p>'
                          .&mt('Make new directory [_1]?',
                               &display($newfilename))
                          .'</p>'
           );
    &CloseForm1($request, $fn);
       }
   }
   
   
   sub Decompress1 {
       my ($request, $user, $domain, $fn) = @_;
       if( -e $fn) {
       $request->print('<input type="hidden" name="newfilename" value="'.$fn.'" />');
       $request->print('<p>'
                      .&mt('Decompress [_1]?',
                           &display($fn))
                      .'</p>'
       );
       &CloseForm1($request, $fn);
       } else {
           $request->print('<p class="LC_error">'
                          .&mt('No such file: [_1]',
                               &display($fn))
                          .'</p></form>'
           );
       }
   }
   
   sub Archive1 {
       my ($request,$fn) = @_;
       my @posstypes = qw(problem library sty sequence page task rights meta xml html xhtml htm xhtm css js tex txt gif jpg jpeg png svg other);
       my (%location_of,%default,$compstyle);
       foreach my $program ('tar','gzip','bzip2','xz','zip') {
           foreach my $dir ('/bin/','/usr/bin/','/usr/local/bin/','/sbin/',
                            '/usr/sbin/') {
               if (-x $dir.$program) {
                   $location_of{$program} = $dir.$program;
                   last;
               }
           }
       }
       my (%defaults,$cancompress,$canarchive);
       if (exists($location_of{'tar'})) {
           $default{'tar'} = ' checked="checked"';
           $canarchive = 1;
           $compstyle = 'block';
       } elsif (exists($location_of{'zip'})) {
           $default{'zip'} = ' checked="checked"';
           $canarchive = 1;
           $compstyle = 'none';
       }
       foreach my $compress ('gzip','bzip2','xz') {
           if (exists($location_of{$compress})) {
               $default{$compress} = ' checked="checked"';
               $cancompress = 1;
               last;
           }
       }
       if (!$canarchive) {
           $request->print('<p class="LC_error">'.
                           &mt('This LON-CAPA instance does not seem to have either tar or zip installed.').'</p>'.
                           '<span class="LC_warning">'.
                           &mt('At least one of the two is needed in order to be able to create an archive file for: [_1].',
                               &display($fn)).
                           '</span></form>');
       } elsif (-e $fn) {
           $request->print(&Apache::lonhtmlcommon::start_pick_box().
                           &Apache::lonhtmlcommon::row_title(&mt('Directory')).
                           &display($fn).
                           &Apache::lonhtmlcommon::row_closure().
                           &Apache::lonhtmlcommon::row_title(&mt('Options').
                           &Apache::loncommon::help_open_topic('Archiving_Directory_Options')).
                           '<fieldset><legend>'.&mt('Recurse').'</legend>'.
                           '<span class="LC_nobreak"><label><input type="checkbox" name="recurse" /> '.
                           &mt('include subdirectories').'</label></span>'.
                           '</fieldset>'.
                           '<fieldset><legend>'.&mt('File types (extensions) to include').('&nbsp;'x2).
                           '<span style="text-decoration:line-through">'.('&nbsp;'x5).'</span>'.('&nbsp;'x2).
                           '<input type="button" name="checkall" value="'.&mt('check all').
                           '" style="height:20px;" onclick="checkAll(document.phaseone.filetype);" />'.
                           ('&nbsp;'x2).
                           '<input type="button" name="uncheckall" value="'.&mt('uncheck all').
                           '" style="height:20px;" onclick="uncheckAll(document.phaseone.filetype);" /></legend>'.
                           '<table>');
           my $rem;
           my $numinrow = 6;
           for (my $i=0; $i<@posstypes; $i++) {
               my $rem = $i%($numinrow);
               if ($rem == 0) {
                  if ($i > 0) {
                       $request->print('</tr>'."\n");
                  }
                  $request->print('<tr>'."\n");
               }
               $request->print('<td class="LC_left_item">'.
                               '<span class="LC_nobreak"><label>'.
                               '<input type="checkbox" name="filetype" '.
                               'value="'.$posstypes[$i].'" /> '.
                               $posstypes[$i].'</label></span></td>'."\n");
           }
           $rem = scalar(@posstypes)%($numinrow);
           my $colsleft;
           if ($rem) {
               $colsleft = $numinrow - $rem;
           }
           if ($colsleft > 1 ) {
               $request->print('<td colspan="'.$colsleft.'" class="LC_left_item">'.
                               '&nbsp;</td>'."\n");
           } elsif ($colsleft == 1) {
               $request->print('<td class="LC_left_item">&nbsp;</td>'."\n");
           }
           $request->print('</tr></table>'."\n".
                           '</fieldset>'.
                           '<fieldset><legend>'.&mt('Archive file format').'</legend>');
           foreach my $possfmt ('tar','zip') {
               if (exists($location_of{$possfmt})) {
                   $request->print('<span class="LC_nobreak">'.
                                   '<label><input type="radio" name="format" value="'.$possfmt.'"'.
                                   $default{$possfmt}.' onclick="toggleCompression(this.form);" /> '.
                                   $possfmt.'</label></span>&nbsp;&nbsp; ');
               }
           }
           $request->print('</fieldset>'."\n".
                           '<fieldset style="display:'.$compstyle.'" id="tar_compression">'.
                           '<legend>'.&mt('Compression to apply to tar file').'</legend>'.
                           '<span class="LC_nobreak">');
           if ($cancompress) { 
               foreach my $compress ('gzip','bzip2','xz') {
                   if (exists($location_of{$compress})) {
                       $request->print('<label><input type="radio" name="compress" value="'.$compress.'"'.
                                       $default{$compress}.'  />'.$compress.'</label>&nbsp;&nbsp;');
                   }
               }
           } else {
               $request->print('<span class="LC_warning">'.
                               &mt('This LON-CAPA instance does not seem to have gzip, bzip2 or xz installed.').
                               '<br />'.&mt('No compression will be used.').'</span>');
           }
           $request->print('</fieldset>'. 
                           &Apache::lonhtmlcommon::row_closure(1).
                           &Apache::lonhtmlcommon::end_pick_box()
           );
           &CloseForm1($request, $fn);
       } else {
           $request->print('<p class="LC_error">'
                          .&mt('No such directory: [_1]',
                               &display($fn))
                          .'</p></form>'
           );
       }
 }  }
   
 =pod  =pod
   
 =item NewFile1  =item NewFile1
    
   Does all phase 1 processing of file creation:    Does all phase 1 processing of file creation:
   Ensures that the user provides a new filename, adds proper extension    Ensures that the user provides a new filename, adds proper extension
   if needed and that the file does not already exist, if it is a html,    if needed and that the file does not already exist, if it is a html,
Line 662  Parameters: Line 964  Parameters:
   
 =item   $domain   - Name of the domain of the user  =item   $domain   - Name of the domain of the user
   
 =item   $fn      - Source file name  =item   $fn      - Source filename
   
 =item   $newfilename  =item   $newfilename
                   - Name of the file to be created; no path information                    - Name of the file to be created; no path information
   
   =item   $warnings - Information about changes to filename made by cleanDest().
   
 =back  =back
   
 Side Effects:  Side Effects:
Line 675  Side Effects: Line 980  Side Effects:
 =item 2 new forms are displayed.  Clicking on the confirmation button  =item 2 new forms are displayed.  Clicking on the confirmation button
 causes the browser to attempt to load the specfied URL, allowing the  causes the browser to attempt to load the specfied URL, allowing the
 proper handler to take care of file creation. There is also a Cancel  proper handler to take care of file creation. There is also a Cancel
 button which returns you to the driectory listing you came from  button which returns you to the directory listing you came from
   
 =back  =back
   
 =cut  =cut
   
   
 sub NewFile1 {  sub NewFile1 {
     my ($request, $user, $domain, $fn, $newfilename) = @_;      my ($request, $user, $domain, $fn, $newfilename, $warnings) = @_;
       return if (&filename_check($newfilename,$warnings) ne 'ok');
   
     if ($ENV{'form.action'} =~ /new(.+)file/) {      if ($env{'form.action'} =~ /new(.+)file/) {
  my $extension=$1;   my $extension=$1;
  if ($newfilename !~ /\Q.$extension\E$/) {   if ($newfilename !~ /\Q.$extension\E$/) {
     if ($newfilename =~ m|^[^\.]*\.([^\.]+)$|) {      if ($newfilename =~ m|/[^/.]*\.(?:[^/.]+)$|) {
  #already has an extension strip it and add in expected one   #already has an extension strip it and add in expected one
  $newfilename =~ s|.([^\.]+)$||;   $newfilename =~ s|(/[^./])\.(?:[^.]+)$|$1|;
     }      }
     $newfilename.=".$extension";      $newfilename.=".$extension";
  }   }
     }      }
       my ($type, $result)=&exists($user,$domain,$newfilename);
       if ($type eq 'error') {
           $request->print($warnings.$result);
    $request->print('</form>');
       } else {
           my $extension;
   
           if ($newfilename =~ m{[^/.]+\.([^/.]+)$}) {
               $extension = $1;
           }
   
           my @okexts = qw(xml html xhtml htm xhtm problem page sequence rights sty task library js css txt);
           if (($extension eq '') || (!grep(/^\Q$extension\E/,@okexts))) {
               my $validexts = '.'.join(', .',@okexts);
               $request->print($warnings.$result);
               $request->print('<p class="LC_warning">'.
                   &mt('Invalid filename: ').&display($newfilename).'</p><p>'.
                   &mt('The name of the new file needs to end with an appropriate file extension to indicate the type of file to create.').'<br />'.
                   &mt('The following are valid extensions: [_1].',$validexts).
                   '</p></form><p>'.
    '<form name="fileaction" action="/adm/cfile" method="post">'.
                   '<input type="hidden" name="qualifiedfilename" value="'.$fn.'" />'.
    '<input type="hidden" name="action" value="newfile" />'.
           '<span class ="LC_nobreak">'.&mt('Enter a filename: ').'<input type="text" name="newfilename" value="Type Name Here" onfocus="if (this.value == '."'Type Name Here') this.value=''".'" />&nbsp;<input type="submit" value="Go" />'.
                   '</span></form></p>'.
                   '<p><form action="'.&url($fn).
                   '" method="post"><p><input type="submit" value="'.&mt('Cancel').'" /></form></p>');
           } elsif (($type ne 'warning') && ($warnings eq '') && ($result eq '')) {
               my $query = "";
               $query .= "?mode=" . $env{'form.mode'} unless (!exists($env{'form.mode'}) || !length($env{'form.mode'}));
               $request->print('
                   <script type="text/javascript">
                       window.location = "'.&url($newfilename,'js'). $query .'";
                   </script>');
           } else {
               $request->print($warnings.$result);
               $request->print('<p>'.&mt('Make new file').' '.&display($newfilename).'?</p>');
               $request->print('</form>');
               $request->print('<form action="'.&url($newfilename).
                           '" method="post"><p><input type="submit" value="'.&mt('Continue').'" /></p></form>');
               $request->print('<form action="'.&url($fn).
                           '" method="post"><p><input type="submit" value="'.&mt('Cancel').'" /></p></form>');
           }
       }
       return;
   }
   
     if(-e $newfilename) {  sub filename_check {
  $request->print('<p>File exists.</p></form>');      my ($newfilename) = @_;
       ##Informs User (name).(number).(extension) not allowed
       if($newfilename =~ /\.(\d+)\.(\w+)$/){
           $r->print('<span class="LC_error">'.$newfilename.
                     ' - '.&mt('Bad Filename').'<br />('.&mt('name').').('.&mt('number').').('.&mt('extension').') '.
                     ' '.&mt('Not Allowed').'</span>');
           return;
     }      }
     else {      if($newfilename =~ /(\:\:\:|\&\&\&|\_\_\_)/){
  $request->print('<p>Make new file '.&display($newfilename).'?</p>');          $r->print('<span class="LC_error">'.$newfilename.
  $request->print('</form>');                    ' - '.&mt('Bad Filename').'<br />('.&mt('Must not include').' '.$1.') '.
  $request->print('<form action="'.&url($newfilename).                    ' '.&mt('Not Allowed').'</span>');
  '" method="POST"><p><input type="submit" value="Continue" /></p></form>');          return;
  $request->print('<form action="'.&url($fn).  
  '" method="POST"><p><input type="submit" value="Cancel" /></p></form>');  
     }      }
       return 'ok';
 }  }
   
 =pod  =pod
Line 717  sub NewFile1 { Line 1073  sub NewFile1 {
 are returned if the request cannot be performed (e.g. attempts to manipulate  are returned if the request cannot be performed (e.g. attempts to manipulate
 files that are nonexistent).  If the operation can be performed, what is  files that are nonexistent).  If the operation can be performed, what is
 about to be done will be presented to the user for confirmation.  If the  about to be done will be presented to the user for confirmation.  If the
 user confirms the request, then phase two is executed, the action   user confirms the request, then phase two is executed, the action
 performed and reported to the user.  performed and reported to the user.
   
  Parameters:   Parameters:
Line 726  performed and reported to the user. Line 1082  performed and reported to the user.
   
 =item $r  - request object [in] - The Apache request being executed.  =item $r  - request object [in] - The Apache request being executed.
   
 =item $fn = string [in] - The filename being manipulated by the   =item $fn = string [in] - The filename being manipulated by the
                              request.                               request.
   
 =item $uname - string [in] Name of user logged in and doing this action.  =item $uname - string [in] Name of user logged in and doing this action.
   
 =item $udom  - string [in] Domain name under which the user logged in.   =item $udom  - string [in] Domain name under which the user logged in.
   
 =back  =back
   
 =cut  =cut
   
 sub phaseone {  sub phaseone {
   my ($r,$fn,$uname,$udom)=@_;      my ($r,$fn,$uname,$udom)=@_;
     
   my $newfilename=&cleanDest($r,$ENV{'form.newfilename'});      my $doingdir=0;
   $newfilename=&relativeDest($fn,$newfilename,$uname);      if ($env{'form.action'} eq 'newdir') { $doingdir=1; }
       my ($newfilename,$error,$warnings) =
   $r->print('<form action="/adm/cfile" method="post">'.          &cleanDest($env{'form.newfilename'},$doingdir,$fn,$uname,$udom);
       '<input type="hidden" name="qualifiedfilename" value="'.$fn.'" />'.      unless ($error) {
       '<input type="hidden" name="phase" value="two" />'.          ($newfilename,$error)=&relativeDest($fn,$newfilename,$uname,$udom);
       '<input type="hidden" name="action" value="'.$ENV{'form.action'}.'" />');      }
         if ($error) {
   if ($ENV{'form.action'} eq 'rename') {          my $dirlist;
       &Rename1($r, $uname, $udom, $fn, $newfilename);          if ($fn=~m{^(.*/)[^/]+$}) {
   } elsif ($ENV{'form.action'} eq 'delete') {               $dirlist=$1;
       &Delete1($r, $uname, $udom, $fn);          } else {
   } elsif ($ENV{'form.action'} eq 'copy') {               $dirlist=$fn;
       if($newfilename) {          }
   &Copy1($r, $uname, $udom, $fn, $newfilename);          if ($warnings) {
       } else {              $r->print($warnings);
   $r->print('<p>No new filename specified.</p></form>');          }
       }          $r->print('<div class="LC_error">'.$error.'</div>'.
   } elsif ($ENV{'form.action'} eq 'newdir') {                    '<p><a href="'.&url($dirlist).'">'.&mt('Return to Directory').
       &NewDir1($r, $uname, $udom, $fn, $newfilename);                    '</a></p>');
   }  elsif ($ENV{'form.action'} eq 'newfile' ||          return;
     $ENV{'form.action'} eq 'newhtmlfile' ||      }
     $ENV{'form.action'} eq 'newproblemfile' ||      $r->print('<form action="/adm/cfile" method="post" name="phaseone">'.
             $ENV{'form.action'} eq 'newpagefile' ||        '<input type="hidden" name="qualifiedfilename" value="'.$fn.'" />'.
             $ENV{'form.action'} eq 'newsequencefile' ||        '<input type="hidden" name="phase" value="two" />'.
             $ENV{'form.action'} eq 'newrightsfile' ||        '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />');
             $ENV{'form.action'} eq 'newstyfile' ||  
             $ENV{'form.action'} eq 'Select Action') {      if ($env{'form.action'} eq 'newfile' ||
       if ($newfilename) {          $env{'form.action'} eq 'newhtmlfile' ||
   &NewFile1($r, $uname, $udom, $fn, $newfilename);          $env{'form.action'} eq 'newproblemfile' ||
       } else {          $env{'form.action'} eq 'newpagefile' ||
   $r->print('<p>No new filename specified.</p></form>');          $env{'form.action'} eq 'newsequencefile' ||
       }          $env{'form.action'} eq 'newrightsfile' ||
   }          $env{'form.action'} eq 'newstyfile' ||
           $env{'form.action'} eq 'newtaskfile' ||
           $env{'form.action'} eq 'newlibraryfile' ||
           $env{'form.action'} eq 'Select Action') {
           my $empty=&mt('Type Name Here');
           if (($newfilename!~/\/$/) && ($newfilename!~/$empty$/)) {
               &NewFile1($r, $uname, $udom, $fn, $newfilename, $warnings);
           } else {
               if ($warnings) {
                   $r->print($warnings);
               }
               $r->print('<p class="LC_error">'
                        .&mt('No new filename specified.')
                        .'</p></form>'
               );
           }
       } else {
           if ($warnings) {
               $r->print($warnings);
           }
           if ($env{'form.action'} eq 'rename') {
       &Rename1($r, $uname, $udom, $fn, $newfilename, 'rename');
           } elsif ($env{'form.action'} eq 'move') {
       &Rename1($r, $uname, $udom, $fn, $newfilename, 'move');
           } elsif ($env{'form.action'} eq 'delete') {
       &Delete1($r, $uname, $udom, $fn);
           } elsif ($env{'form.action'} eq 'decompress') {
       &Decompress1($r, $uname, $udom, $fn);
           } elsif ($env{'form.action'} eq 'archive') {
               &Archive1($r,$fn);
           } elsif ($env{'form.action'} eq 'copy') {
       if ($newfilename) {
           &Copy1($r, $uname, $udom, $fn, $newfilename);
       } else {
                   $r->print('<p class="LC_error">'
                            .&mt('No new filename specified.')
                            .'</p></form>'
                   );
               }
           } elsif ($env{'form.action'} eq 'newdir') {
       my $mode = '';
       if (exists($env{'form.callingmode'}) ) {
           $mode = $env{'form.callingmode'};
       }
       &NewDir1($r, $uname, $udom, $fn, $newfilename, $mode);
           }
       }
 }  }
   
 =pod  =pod
Line 812  Returns: Line 1214  Returns:
   
 sub Rename2 {  sub Rename2 {
   
   my ($request, $user, $directory, $oldfile, $newfile) = @_;      my ($request, $user, $directory, $oldfile, $newfile) = @_;
   
   &Debug($request, "Rename2 directory: ".$directory." old file: ".$oldfile.      &Debug($request, "Rename2 directory: ".$directory." old file: ".$oldfile.
  " new file ".$newfile."\n");     " new file ".$newfile."\n");
   &Debug($request, "Target is: ".$directory.'/'.      &Debug($request, "Target is: ".$directory.'/'.
  $newfile);     $newfile);
       if (-e $oldfile) {
   if(-e $oldfile) {  
       my $dest;   my $oRN=$oldfile;
    my $nRN=$newfile;
       if ($oldfile =~ m|/$|) {   unless (rename($oldfile,$newfile)) {
   #renaming a dir      $request->print('<span class="LC_error">'.&mt('Error').': '.$!.'</span>');
   $oldfile =~ s|/$||;      return 0;
   $dest=$directory;   }
   $dest=~s|(/)([^/]*)$|$1|;   ## If old name.(extension) exits, move under new name.
   $dest.='/'.$newfile;   ## If it doesn't exist and a new.(extension) exists
       } else {   ## delete it (only concern when renaming over files)
   $dest=$directory.'/'.$newfile;   my $tmp1=$oRN.'.meta';
       }   my $tmp2=$nRN.'.meta';
    if(-e $tmp1){
       unless(rename($oldfile,$dest)) {      unless(rename($tmp1,$tmp2)){ }
   $request->print('<font color="red">Error: '.$!.'</font>');   } elsif(-e $tmp2){
   return 0;      unlink $tmp2;
       } else {}   }
   } else {   $tmp1=$oRN.'.save';
       $request->print("<p> No such file: /home".$user.'/public_html'.   $tmp2=$nRN.'.save';
       $oldfile.' </p></form>');   if(-e $tmp1){
       return 0;      unless(rename($tmp1,$tmp2)){ }
   }   } elsif(-e $tmp2){
   return 1;      unlink $tmp2;
    }
    $tmp1=$oRN.'.log';
    $tmp2=$nRN.'.log';
    if(-e $tmp1){
       unless(rename($tmp1,$tmp2)){ }
    } elsif(-e $tmp2){
       unlink $tmp2;
    }
    $tmp1=$oRN.'.bak';
    $tmp2=$nRN.'.bak';
    if(-e $tmp1){
       unless(rename($tmp1,$tmp2)){ }
    } elsif(-e $tmp2){
       unlink $tmp2;
    }
       } else {
           $request->print(
               '<p class="LC_error">'
              .&mt('No such file: [_1]',
                   &display($oldfile))
              .'</p></form>'
           );
    return 0;
       }
       return 1;
 }  }
   
 =pod  =pod
   
 =item Delete2($request, $user, $filename)  =item Delete2($request, $user, $filename)
   
   Performs phase two of a delete.  The user has confirmed that they want     Performs phase two of a delete.  The user has confirmed that they want
 to delete the selected file.   The file is deleted and the results of the  to delete the selected file.   The file is deleted and the results of the
 delete attempt are indicated.  delete attempt are indicated.
   
Line 873  Returns: Line 1301  Returns:
 =cut  =cut
   
 sub Delete2 {  sub Delete2 {
   my ($request, $user, $filename) = @_;      my ($request, $user, $filename) = @_;
       if (-d $filename) {
   if(-e $filename) {   unless (&empty_directory($filename,'Delete2')) {
     unless(unlink($filename)) {      $request->print('<span class="LC_error">'.&mt('Error: Directory Non Empty').'</span>');
       $request->print('<font color="red">Error: '.$!.'</font>');      return 0;
       return 0;   } else {
       if(-e $filename) {
    unless(rmdir($filename)) {
       $request->print('<span class="LC_error">'.&mt('Error').': '.$!.'</span>');
       return 0;
    }
       } else {
           $request->print('<p class="LC_error">'.&mt('No such file').'</p></form>');
    return 0;
       }
    }
       } else {
    if(-e $filename) {
       unless(unlink($filename)) {
    $request->print('<span class="LC_error">'.&mt('Error').': '.$!.'</span>');
    return 0;
       }
    } else {
               $request->print('<p class="LC_error">'.&mt('No such file').'</p></form>');
       return 0;
    }
     }      }
   } else {      return 1;
     $request->print('<p> No such file. </p></form');  
     return 0;  
   }  
   return 1;  
 }  }
   
 =pod  =pod
   
 =item Copy2($request, $username, $dir, $oldfile, $newfile)  =item Copy2($request, $username, $dir, $oldfile, $newfile)
   
    Performs phase 2 of a copy.  The file is copied and the status      Performs phase 2 of a copy.  The file is copied and the status
    of that copy is reported back to the user.     of that copy is reported back to the user.
   
 =over 4  =over 4
Line 911  sub Delete2 { Line 1355  sub Delete2 {
   
 =back  =back
   
 Returns 0 failure, and 0 successs.  Returns 0 failure, and 1 successs.
   
 =cut  =cut
   
Line 919  sub Copy2 { Line 1363  sub Copy2 {
     my ($request, $username, $dir, $oldfile, $newfile) = @_;      my ($request, $username, $dir, $oldfile, $newfile) = @_;
     &Debug($request ,"Will try to copy $oldfile to $newfile");      &Debug($request ,"Will try to copy $oldfile to $newfile");
     if(-e $oldfile) {      if(-e $oldfile) {
           if ($oldfile eq $newfile) {
               $request->print('<span class="LC_error">'.&mt('Warning').': '.&mt('Name of new file is the same as name of old file').' - '.&mt('no action taken').'.</span>');
               return 1;
           }
  unless (copy($oldfile, $newfile)) {   unless (copy($oldfile, $newfile)) {
     $request->print('<font color="red"> copy Error: '.$!.'</font>');      $request->print('<span class="LC_error">'.&mt('copy Error').': '.$!.'</span>');
       return 0;
    } elsif (!chmod(0660, $newfile)) {
       $request->print('<span class="LC_error">'.&mt('chmod error').': '.$!.'</span>');
       return 0;
    } elsif (-e $oldfile.'.meta' &&
    !copy($oldfile.'.meta', $newfile.'.meta') &&
    !chmod(0660, $newfile.'.meta')) {
       $request->print('<span class="LC_error">'.&mt('copy metadata error').
       ': '.$!.'</span>');
     return 0;      return 0;
  } else {   } else {
     unless (chmod(0660, $newfile)) {  
  $request->print('<font color="red"> chmod error: '.$!.'</font>');  
  return 0;  
     }  
     return 1;      return 1;
  }   }
     } else {      } else {
  $request->print('<p> No such file </p>');          $request->print('<p class="LC_error">'.&mt('No such file').'</p>');
  return 0;   return 0;
     }      }
     return 1;      return 1;
 }  }
   
 =pod  =pod
   
 =item NewDir2($request, $user, $newdirectory)  =item NewDir2($request, $user, $newdirectory)
Line 958  Returns 0 - failure 1 - success. Line 1412  Returns 0 - failure 1 - success.
 =cut  =cut
   
 sub NewDir2 {  sub NewDir2 {
   my ($request, $user, $newdirectory) = @_;      my ($request, $user, $newdirectory) = @_;
     
   unless(mkdir($newdirectory, 02770)) {      unless(mkdir($newdirectory, 02770)) {
     $request->print('<font color="red">Error: '.$!.'</font>');   $request->print('<span class="LC_error">'.&mt('Error').': '.$!.'</span>');
     return 0;   return 0;
   }      }
   unless(chmod(02770, ($newdirectory))) {      unless(chmod(02770, ($newdirectory))) {
       $request->print('<font color="red"> Error: '.$!.'</font>');   $request->print('<span class="LC_error">'.&mt('Error').': '.$!.'</span>');
       return 0;   return 0;
   }      }
   return 1;      return 1;
   }
   
   sub decompress2 {
       my ($r, $user, $dir, $file) = @_;
       &Apache::lonnet::appenv({'cgi.file' => $file});
       &Apache::lonnet::appenv({'cgi.dir' => $dir});
       my $result=&Apache::lonnet::ssi_body('/cgi-bin/decompress.pl');
       $r->print($result);
       &Apache::lonnet::delenv('cgi.file');
       &Apache::lonnet::delenv('cgi.dir');
       return 1;
   }
   
   sub Archive2 {
       my ($r,$name,$udom,$fn,$identifier) = @_;
       my %options = (
                       dir => $fn,
                     );
       my @filetypes = qw(problem library sty sequence page task rights meta xml html xhtml htm xhtm css js tex txt gif jpg jpeg png svg other);
       my (@include,%oktypes);
       map { $oktypes{$_} = 1; } @filetypes;
       my @posstypes = &Apache::loncommon::get_env_multiple('form.filetype');
       foreach my $type (@posstypes) {
           if ($oktypes{$type}) {
               push(@include,$type);
           }
       }
       if (scalar(@include) == scalar(@filetypes)) {
           $options{'types'} = 'all';
       } else {
           $options{'types'} = join(',',@include);
       }
       if (exists($env{'form.recurse'})) {
           $options{'recurse'} = 1;
       }
       if (exists($env{'form.encrypt'})) {
           if ($env{'form.enckey'} ne '') {
               $options{'encrypt'} = $env{'form.enckey'};
           }
       }
       $options{'format'} = 'tar';
       $options{'compress'} = 'gzip';
       if ((exists($env{'form.format'})) && $env{'form.format'} =~ /^zip$/i) {
           $options{'format'} = 'zip';
           delete($options{'compress'});
       } elsif ((exists($env{'form.compress'})) && ($env{'form.compress'} =~ /^(xz|bzip2)$/i)) {
           $options{'compress'} = lc($env{'form.compress'});  
       }
       my $key = 'cgi.'.$identifier.'.archive';
       my $storestring = &Apache::lonnet::freeze_escape(\%options);
       &Apache::lonnet::appenv({$key => $storestring});
       return 1;
 }  }
   
 =pod  =pod
   
 =item phasetwo($r, $fn, $uname, $udom)  =item phasetwo($r, $fn, $uname, $udom,$identifier)
   
    Controls the phase 2 processing of file management     Controls the phase 2 processing of file management
    requests for construction space.  In phase one, the user     requests for construction space.  In phase one, the user
Line 981  sub NewDir2 { Line 1487  sub NewDir2 {
    is performed and the result is shown.     is performed and the result is shown.
   
   The strategy is to break out the processing into specific action processors    The strategy is to break out the processing into specific action processors
   named action2 where action is the requested action and the 2 denotes     named action2 where action is the requested action and the 2 denotes
   phase 2 processing.    phase 2 processing.
   
 Parameters:  Parameters:
Line 1004  Parameters: Line 1510  Parameters:
 =cut  =cut
   
 sub phasetwo {  sub phasetwo {
     my ($r,$fn,$uname,$udom)=@_;      my ($r,$fn,$uname,$udom,$identifier)=@_;
       
     &Debug($r, "loncfile - Entering phase 2 for $fn");      &Debug($r, "loncfile - Entering phase 2 for $fn");
       
     # Break down the file into it's component pieces.      # Break down the file into its component pieces.
       
     my $dir; # Directory path      my $dir; # Directory path
     my $main; # Filename.      my $main; # Filename.
     my $suffix; # Extension.      my $suffix; # Extension.
       if ($fn=~m:(.*)/([^/]+):) {
     if ($fn=~m:(.*)/([^/]+)\.(\w+)$:) {  
  $dir=$1; # Directory path   $dir=$1; # Directory path
  $main=$2; # Filename.   $main=$2; # Filename.
  $suffix=$3; # Extension.  
     }      }
               if($main=~m:\.(\w+)$:){ # Fixes problems with filenames with no extensions
     my $dest;                   # On success this is where we'll go.   $suffix=$1; #This is the actually filename extension if it exists
        $main=~s/\.\w+$//; #strip the extension
     &Debug($r,       }
    "loncfile::phase2 dir = $dir main = $main suffix = $suffix");      my $dest;                       #
     &Debug($r,      my $dest_dir;                   # On success this is where we'll go.
    "    newfilename = ".$ENV{'form.newfilename'});      my $disp_newname;               #
       my $dest_newname;               #
       &Debug($r,"loncfile::phase2 dir = $dir main = $main suffix = $suffix");
       &Debug($r,"    newfilename = ".$env{'form.newfilename'});
   
     my $conspace=$fn;      my $conspace=$fn;
       
     &Debug($r,       &Debug($r,"loncfile::phase2 Full construction space name: $conspace");
    "loncfile::phase2 Full construction space name: $conspace");  
           &Debug($r,"loncfie::phase2 action is $env{'form.action'}");
     &Debug($r,   
    "loncfie::phase2 action is $ENV{'form.action'}");  
       
     # Select the appropriate processing sub.      # Select the appropriate processing sub.
           if ($env{'form.action'} eq 'decompress') {
     if ($ENV{'form.action'} eq 'rename') { # Rename.   $main .= '.'.$suffix;
  if($ENV{'form.newfilename'}) {   if(!&decompress2($r, $uname, $dir, $main)) {
       return ;
    }
    $dest = $dir."/.";
       } elsif ($env{'form.action'} eq 'archive') {
           &Archive2($r,$uname,$udom,$fn,$identifier);
           return;
       } elsif ($env{'form.action'} eq 'rename' ||
        $env{'form.action'} eq 'move') {
    if($env{'form.newfilename'}) {
     if (!defined($dir)) {      if (!defined($dir)) {
  $fn=~m:^(.*)/:;   $fn=~m:^(.*)/:;
  $dir=$1;   $dir=$1;
     }      }
     if(!&Rename2($r, $uname, $dir, $fn, $ENV{'form.newfilename'})) {      if(!&Rename2($r, $uname, $dir, $fn, $env{'form.newfilename'})) {
  return;   return;
     }      }
     # Prepend the directory to the new name to form the basis of the      $dest = $dir."/";
     # url of the new resource.      $dest_newname = $env{'form.newfilename'};
     #      $env{'form.newfilename'} =~ /.+(\/.+$)/;
     #renaming a dir      $disp_newname = $1;
             #remove last element for current dir      $disp_newname =~ s/\///;
     if ($fn =~ m|/$|) { $dir =~ s|/[^/]*$||; }  
     $dest = $dir."/".$ENV{'form.newfilename'};  
  }   }
     } elsif ($ENV{'form.action'} eq 'delete') {       } elsif ($env{'form.action'} eq 'delete') {
  if(!&Delete2($r, $uname, $ENV{'form.newfilename'})) {   if(!&Delete2($r, $uname, $env{'form.newfilename'})) {
     return ;      return ;
  }   }
  # Once a resource is deleted, we just list the directory that   # Once a resource is deleted, we just list the directory that
  # previously held it.   # previously held it.
  #   #
  $dest = $dir."/."; # Parent dir.   $dest = $dir."/."; # Parent dir.
     } elsif ($ENV{'form.action'} eq 'copy') {       } elsif ($env{'form.action'} eq 'copy') {
  if($ENV{'form.newfilename'}) {   if($env{'form.newfilename'}) {
     if(!&Copy2($r, $uname, $dir, $fn, $ENV{'form.newfilename'})) {      if(!&Copy2($r, $uname, $dir, $fn, $env{'form.newfilename'})) {
  return   return ;
  }      }
     $dest = $ENV{'form.newfilename'};      $dest = $env{'form.newfilename'};
              } else {
  } else {              $r->print('<p class="LC_error">'.&mt('No New filename specified').'</p></form>');
     $r->print('<p>No New filename specified</p></form>');  
     return;      return;
  }   }
   
     } elsif ($ENV{'form.action'} eq 'newdir') {      } elsif ($env{'form.action'} eq 'newdir') {
  #          my $newdir= $env{'form.newfilename'};
  # Since the newfilename form field is construction space  
  # relative, ew need to prepend the current path; now in $fn.  
  #  
         my $newdir= $fn.$ENV{'form.newfilename'};  
  if(!&NewDir2($r, $uname, $newdir)) {   if(!&NewDir2($r, $uname, $newdir)) {
     return;      return;
  }   }
  $dest = $newdir."/"   $dest = $newdir."/";
       }
       if ( ($env{'form.action'} eq 'newdir') && ($env{'form.phase'} eq 'two') && ( ($env{'form.callingmode'} eq 'testbank') || ($env{'form.callingmode'} eq 'imsimport') ) ) {
           $r->print(
               '<p>'
              .&Apache::lonhtmlcommon::confirm_success(&mt('Done'))
              .'<br /><a href="javascript:self.close()">'.&mt('Continue').'</a>'
              .'</p>'
           );
       } else {
           if ($env{'form.action'} eq 'rename') {
               $r->print(
                    '<p>'.&Apache::lonhtmlcommon::confirm_success(&mt('Done')).'</p>'
                   .&Apache::lonhtmlcommon::actionbox(
                        ['<a href="'.&url($dest).'">'.&mt('Return to Directory').'</a>',
                         '<a href="'.&url($dest_newname).'">'.$disp_newname.'</a>']));
           } else {
       $r->print(&done($dest));
    }
     }      }
     #  
     #  Substitute for priv for the first home in $dir to get our  
     # construction space path.  
     #  
     $dest=&MakeFinalUrl($r,$dest);  
   
     $r->print('<h3><a href="'.$dest.'">Done</a></h3>');  
 }  
   
 sub MakeFinalUrl {  
     my($r,$dest)=@_;  
     &Debug($r, "Final url is: $dest");  
     $dest =~ s|/home/|/priv/|;  
     $dest =~ s|/public_html||;  
   
     my $base = &File::Basename::basename($dest);  
     my $dpath= &File::Basename::dirname($dest);  
     if ($base eq '.') { $base=''; }  
     $dest = &HTML::Entities::encode($dpath.'/'.$base);  
   
     &Debug($r, "Final url after rewrite: $dest");  
     return $dest;  
 }  }
   
 sub handler {  sub handler {
   
   $r=shift;      $r=shift;
   
       &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['decompress','action','filename','newfilename','mode']);
   
   &Debug($r, "loncfile.pm - handler entered");      &Debug($r, "loncfile.pm - handler entered");
   &Debug($r, " filename: ".$ENV{'form.filename'});      &Debug($r, " filename: ".$env{'form.filename'});
   &Debug($r, " newfilename: ".$ENV{'form.newfilename'});      &Debug($r, " newfilename: ".$env{'form.newfilename'});
 #  #
 # Determine the root filename  # Determine the root filename
 # This could come in as "filename", which actually is a URL, or  # This could come in as "filename", which actually is a URL, or
 # as "qualifiedfilename", which is indeed a real filename in filesystem  # as "qualifiedfilename", which is indeed a real filename in filesystem
 #  #
   my $fn;      my $fn;
   
   if ($ENV{'form.filename'}) {      if ($env{'form.filename'}) {
       $fn=&Apache::lonnet::unescape($ENV{'form.filename'});   &Debug($r, "test: $env{'form.filename'}");
       $fn=&URLToPath($fn);   $fn=&unescape($env{'form.filename'});
   } elsif ($ENV{'form.qualifiedfilename'}) {   $fn=&URLToPath($fn);
       $fn=$ENV{'form.qualifiedfilename'};      } elsif($ENV{'QUERY_STRING'} && $env{'form.phase'} ne 'two') {
   } else {   #Just hijack the script only the first time around to inject the
       &Debug($r, "loncfile::handler - no form.filename");   #correct information for further processing
      $r->log_reason($ENV{'user.name'}.' at '.$ENV{'user.domain'}.   $fn=&unescape($env{'form.decompress'});
          ' unspecified filename for cfile', $r->filename);    $fn=&URLToPath($fn);
      return HTTP_NOT_FOUND;   $env{'form.action'}="decompress";
   }      } elsif ($env{'form.qualifiedfilename'}) {
    $fn=$env{'form.qualifiedfilename'};
   unless ($fn) {       } else {
       &Debug($r, "loncfile::handler - doctored url is empty");   &Debug($r, "loncfile::handler - no form.filename");
      $r->log_reason($ENV{'user.name'}.' at '.$ENV{'user.domain'}.   $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
          ' trying to cfile non-existing file', $r->filename);          ' unspecified filename for cfile', $r->filename);
      return HTTP_NOT_FOUND;   return HTTP_NOT_FOUND;
   }       }
   
       unless ($fn) {
    &Debug($r, "loncfile::handler - doctored url is empty");
    $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
          ' trying to cfile non-existing file', $r->filename);
    return HTTP_NOT_FOUND;
       }
   
 # ----------------------------------------------------------- Start page output  # ----------------------------------------------------------- Start page output
   my $uname;  
   my $udom;  
   
   ($uname,$udom)=      my ($uname,$udom) = &Apache::lonnet::constructaccess($fn);
     &Apache::loncacc::constructaccess($fn,$r->dir_config('lonDefDomain'));      &Debug($r,
   &Debug($r,      "loncfile::handler constructaccess uname = $uname domain = $udom");
  "loncfile::handler constructaccess uname = $uname domain = $udom");      if (($uname eq '') || ($udom eq '')) {
   unless (($uname) && ($udom)) {   $r->log_reason($uname.' at '.$udom.
      $r->log_reason($uname.' at '.$udom.         ' trying to manipulate file '.$env{'form.filename'}.
          ' trying to manipulate file '.$ENV{'form.filename'}.         ' ('.$fn.') - not authorized',
          ' ('.$fn.') - not authorized',          $r->filename);
          $r->filename);    return HTTP_NOT_ACCEPTABLE;
      return HTTP_NOT_ACCEPTABLE;      }
   }  
   
       &Apache::loncommon::content_type($r,'text/html');
   $r->content_type('text/html');      $r->send_http_header;
   $r->send_http_header;  
       my ($js,$identifier);
   $r->print('<html><head><title>LON-CAPA Construction Space</title></head>');      my $args = {};
   
   $r->print(&Apache::loncommon::bodytag('Construction Space File Operation'));      if (($env{'form.action'} eq 'newdir') && ($env{'form.phase'} eq 'two') && 
           (($env{'form.callingmode'} eq 'testbank') || ($env{'form.callingmode'} eq 'imsimport'))) {
      my $newdirname = $env{'form.newfilename'};
   $r->print('<h3>Location: '.&display($fn).'</h3>');          &js_escape(\$newdirname);
      $js = <<"ENDJS";
   if (($uname ne $ENV{'user.name'}) || ($udom ne $ENV{'user.domain'})) {  <script type="text/javascript">
           $r->print('<h3><font color="red">Co-Author: '.$uname.' at '.$udom.  // <![CDATA[
                '</font></h3>');  function writeDone() {
   }      window.focus();
       opener.document.info.newdir.value = "$newdirname";
       setTimeout("self.close()",10000);
   &Debug($r, "loncfile::handler Form action is $ENV{'form.action'} ");  }
   if ($ENV{'form.action'} eq 'delete') {  // ]]>
         </script>
       $r->print('<h3>Delete</h3>');  ENDJS
   } elsif ($ENV{'form.action'} eq 'rename') {          $args->{'add_entries'} = { onload => "writeDone()" };
       $r->print('<h3>Rename</h3>');      } elsif (($env{'form.action'} eq 'archive') &&
   } elsif ($ENV{'form.action'} eq 'newdir') {               ($env{'environment.authorarchive'})) { 
       $r->print('<h3>New Directory</h3>');          if ($env{'form.phase'} eq 'two') {
   } elsif ($ENV{'form.action'} eq 'copy') {              $identifier = &Apache::loncommon::get_cgi_id();
       $r->print('<h3>Copy</h3>');              $args->{'redirect'} = [0,"/cgi-bin/archive.pl?$identifier"];
   } elsif ($ENV{'form.action'} eq 'newfile' ||          } else {
    $ENV{'form.action'} eq 'newhtmlfile' ||              my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript();
    $ENV{'form.action'} eq 'newproblemfile' ||              $js = <<"ENDJS";
            $ENV{'form.action'} eq 'newpagefile' ||  <script type="text/javascript">
            $ENV{'form.action'} eq 'newsequencefile' ||  // <![CDATA[
    $ENV{'form.action'} eq 'newrightsfile' ||  function toggleCompression(form) {
    $ENV{'form.action'} eq 'newstyfile' ||      if (document.getElementById('tar_compression')) {
            $ENV{'form.action'} eq 'Select Action' ) {          if (form.format.length > 1) {
       $r->print('<h3>New Resource</h3>');              for (var i=0; i<form.format.length; i++) {
   } else {                  if (form.format[i].checked) {
      $r->print('<p>Unknown Action '.$ENV{'form.action'}.' </p></body></html>');                      if (form.format[i].value == 'zip') {
      return OK;                            document.getElementById('tar_compression').style.display = 'none';
   }                      } else if (form.format[i].value == 'tar') {
   if ($ENV{'form.phase'} eq 'two') {                          document.getElementById('tar_compression').style.display = 'block';
       &Debug($r, "loncfile::handler  entering phase2");                      }
       &phasetwo($r,$fn,$uname,$udom);                      break;
   } else {                  }
       &Debug($r, "loncfile::handler  entering phase1");              }
       &phaseone($r,$fn,$uname,$udom);          }
   }      }
       return;
   }
   
   function resetForm() {
       if (document.phaseone.filetype.length) {
           for (var i=0; i<document.phaseone.filetype.length; i++) {
               document.phaseone.filetype[i].checked = false;
           }
       }
       if (document.getElementById('tar_compression')) { 
           if (document.phaseone.format.length) {
               document.getElementById('tar_compression').style.display = 'block';
               for (var i=0; i<document.phaseone.format.length; i++) {
                   if (document.phaseone.format[i].value == 'tar') {
                       document.phaseone.format[i].checked = true;  
                   } else {
                       document.phaseone.format[i].checked = false;
                   }
               }
           }
           if (document.phaseone.compress.length) {
               for (var i=0; i<document.phaseone.compress.length; i++) {
                   if (document.phaseone.compress[i].value == 'gzip') {
                       document.phaseone.compress[i].checked = true;
                   } else {
                       document.phaseone.compress[i].checked = false;
                   }
               }
           }
       }
       document.phaseone.recurse.checked = false;
   }
   
   $check_uncheck_js
   
   // ]]>
   </script>
   
   ENDJS
               $args->{'add_entries'} = { onload => "resetForm()" }; 
           }
       }
       my $londocroot = $r->dir_config('lonDocRoot');
       my $trailfile = $fn;
       $trailfile =~ s{^/(priv/)}{$londocroot/$1};
   
       # Breadcrumbs
       my $crsauthor;
       my $text = 'Authoring Space';
       my $title = 'Authoring Space File Operation',
       my $href = &Apache::loncommon::authorspace(&url($fn));
       if ($env{'request.course.id'}) {
           my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
           my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
           if ($href eq "/priv/$cdom/$cnum/") {
               $text = 'Course Authoring Space';
               $title = 'Course Authoring Space File Operation',
               $crsauthor = 1;
           }
       }
       &Apache::lonhtmlcommon::clear_breadcrumbs();
       &Apache::lonhtmlcommon::add_breadcrumb({
           'text'  => $text,
           'href'  => $href,
       });
       &Apache::lonhtmlcommon::add_breadcrumb({
           'text'  => 'File Operation',
           'title' => $title,
           'href'  => '',
       });
   
       $r->print(&Apache::loncommon::start_page($title,$js,$args)
                .&Apache::lonhtmlcommon::breadcrumbs()
                .&Apache::loncommon::head_subbox(
                     &Apache::loncommon::CSTR_pageheader($trailfile))
       );
   
       unless ($env{'form.action'} eq 'archive') {
           $r->print('<p>'.&mt('Location').': '.&display($fn).'</p>');
       }
   
       if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
           unless ($crsauthor) {
               $r->print('<p class="LC_info">'
                        .&mt('Co-Author [_1]',$uname.':'.$udom)
                        .'</p>'
               );
           }
       }
   
   
       &Debug($r, "loncfile::handler Form action is $env{'form.action'} ");
       my %action = &Apache::lonlocal::texthash(
           'delete'          => 'Delete',
           'rename'          => 'Rename',
           'move'            => 'Move',
           'newdir'          => 'New Directory',
           'decompress'      => 'Decompress',
           'archive'         => 'Export directory to archive file',
           'copy'            => 'Copy',
           'newfile'         => 'New Resource',
    'newhtmlfile'     => 'New Resource',
    'newproblemfile'  => 'New Resource',
    'newpagefile'     => 'New Resource',
    'newsequencefile' => 'New Resource',
    'newrightsfile'   => 'New Resource',
    'newstyfile'      => 'New Resource',
    'newtaskfile'     => 'New Resource',
           'newlibraryfile'  => 'New Resource',
    'Select Action'   => 'New Resource',
       );
       if ($action{$env{'form.action'}}) {
           if ($crsauthor) {
               my @disallowed = qw(page sequence rights library);
               my $newtype;
               if ($env{'form.action'} =~ /^new(\w+)file$/) {
                   $newtype = $1;
               } elsif ($env{'form.action'} eq 'newfile') {
                   ($newtype) = ($env{'form.newfilename'} =~ m{\.([^/.]+)$});
                   $newtype = lc($newtype);
               }
               if (($newtype ne '') &&
                   (grep(/^\Q$newtype\E$/,@disallowed))) {
                   $r->print('<p class="LC_error">'
                            .&mt('Creation of a new file of type: [_1] is not permitted in Course Authoring Space',$newtype)
                            .'</p>'
                            .&Apache::loncommon::end_page()
                   );
                   return OK;
               }
               if ($env{'form.action'} eq 'archive') {
                   $r->print('<p>'.&mt('Location').': '.&display($fn).'</p>'."\n".
                             '<p class="LC_error">'.
                             &mt('Export to an archive file is not permitted in Course Authoring Space').
                             '</p>'."\n".
                             &Apache::loncommon::end_page());
                   return OK; 
               }
           } elsif ($env{'form.action'} eq 'archive') {
               unless ($env{'environment.authorarchive'}) {
                   $r->print('<p>'.&mt('Location').': '.&display($fn).'</p>'."\n".
                             '<p class="LC_error">'.
                             &mt('You do not have permission to export to an archive file in this Authoring Space').
                             '</p>'."\n".
                             &Apache::loncommon::end_page());
                   return OK;
               }
           }
           $r->print('<h2>'.$action{$env{'form.action'}}.'</h2>');
       } else {
           $r->print('<p class="LC_error">'
                    .&mt('Unknown Action: [_1]',$env{'form.action'})
                    .'</p>'
                    .&Apache::loncommon::end_page()
           );
           return OK;
       }
   
       if ($env{'form.phase'} eq 'two') {
    &Debug($r, "loncfile::handler  entering phase2");
    &phasetwo($r,$fn,$uname,$udom,$identifier);
       } else {
    &Debug($r, "loncfile::handler  entering phase1");
    &phaseone($r,$fn,$uname,$udom);
       }
   
   $r->print('</body></html>');      $r->print(&Apache::loncommon::end_page());
   return OK;        return OK;
 }  }
   
 1;  1;

Removed from v.1.36  
changed lines
  Added in v.1.128


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>