Diff for /loncom/publisher/loncfile.pm between versions 1.32 and 1.110

version 1.32, 2003/06/19 21:04:37 version 1.110, 2011/10/23 23:46:07
Line 33 Line 33
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
 #  
 # (Handler to retrieve an old version of a file  
 #  
 # (Publication Handler  
 #   
 # (TeX Content Handler  
 #  
 # 05/29/00,05/30,10/11 Gerd Kortemeyer)  
 #  
 # 11/28,11/29,11/30,12/01,12/02,12/04,12/23 Gerd Kortemeyer  
 # 03/23 Guy Albertelli  
 # 03/24,03/29 Gerd Kortemeyer)  
 #  
 # 03/31,04/03,05/02,05/09,06/23,06/24 Gerd Kortemeyer)  
 #  
 # 06/23 Gerd Kortemeyer  
 # 05/07/02 Ron Fox:  
 #           - Added Debug log output so that I can trace what the heck this  
 #             undocumented thingy does.  
 # 05/28/02  Ron Fox:  
 #           - Started putting in pod in standard format.  
 =pod  =pod
   
 =head1 NAME  =head1 NAME
Line 90  use File::Copy; Line 69  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::loncacc;
 use Apache::Log ();  
 use Apache::lonnet;  use Apache::lonnet;
   use Apache::loncommon();
   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 120  my $r;    # Needs to be global for some Line 102  my $r;    # Needs to be global for some
 =cut  =cut
   
 sub Debug {  sub Debug {
         # Put out the indicated message butonly 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 ($url)=@_;
   if ($DEBUG) {     my $done=&mt("Done");
     $log->debug($message);     return(<<ENDDONE);
   }  <a href="$url">$done</a>
   <script type="text/javascript">
   location.href="$url";
   </script>
   ENDDONE
 }  }
   
 =pod  =pod
Line 170  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\:\/\/[^\/]+\/\~(\w+)/\/home\/$1\/public_html/;      $Url=~ s/\/+/\//g;
   $Url=~ s/^http\:\/\/[^\/]+//;      $Url=~ s/^https?\:\/\/[^\/]+//;
   &Debug($r, "Returning $Url \n");      $Url=~ s/^\///;
   return $Url;      $Url='/home/httpd/html/'.$Url;
       &Debug($r, "Returning $Url \n");
       return $Url;
   }
   
   sub url {
       my $fn=shift;
       $fn=~s/^\/home\/httpd\/html//;
       $fn=~s/\/\.\//\//g;
       $fn=&HTML::Entities::encode($fn,'<>"&');
       return $fn;
   }
   
   sub display {
       my $fn=shift;
       $fn=~s/^\/home\/httpd\/html//;
       $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  
 {  
   my ($domain, $user, $dir, $file)=@_;  
   
   return '/home/httpd/html/res/'.$domain.'/'.$user.'/'.$dir.'/'.  
  $file;  
 }  
   
 =pod  
   
 =item ConstructionPath($domain, $user, $dir, $file)  
   
    Determines the filesystem path corresponding to a construction space  
    resource specification.  The returned value is the path  
 Parameters:  
   
 =over 4  
   
 =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.  
   
 Returns:  
   
 =item  string - full path to the file if it exists in Construction space.  
   
 =back  
        
 =cut  
   
 sub ConstructionPath {  
   my ($user, $dir, $file) = @_;  
   
   return '/home/'.$user.'/public_html/'.$dir.'/'.$file;  
   
   # see if the file is
   # a) published (return 0 if not)
   # b) if, so obsolete (return 0 if not)
   
   sub obsolete_unpub {
       my ($user,$domain,$construct)=@_;
       my $published=$construct;
       $published=~
    s/^\/home\/$user\/public\_html\//\/home\/httpd\/html\/res\/$domain\/$user\//;
       if (-e $published) {
    if (&Apache::lonnet::metadata($published,'obsolete')) {
       return 1;
    }
    return 0;
       } else {
    return 1;
       }
 }  }
 =pod  
   
 =item  ConstructionPathFromRelative($user, $relname)  
   
    Determines the path to a construction space file given  
 the username and the path relative to the root of construction space.  
   
 Parameters:  
   
 =over 4  
   
 =item  $user  - string [in] Name of the user in whose construction space the  
            file [will] live.  
   
 =item  $relname - string[in] Path to the file relative to the root of the  
             construction space.  
   
 =back  
   
 Returns:  
   
 =over 4     
   
 =item  string - Full path to the file.  
   
 =back  
   
 =cut  
   
 sub ConstructionPathFromRelative {  
   
   my ($user, $relname) = @_;  
   return '/home/'.$user.'/public_html'.$relname;  
   
   # see if directory is empty
   # ignores any .meta, .save, .bak, and .log files created for a previously
   # published file, which has since been marked obsolete and deleted.
   sub empty_directory {
       my ($dirname,$phase) = @_;
       if (opendir DIR, $dirname) {
           my @files = grep(!/^\.\.?$/, readdir(DIR)); # ignore . and ..
           if (@files) { 
               my @orphans = grep(/\.(meta|save|log|bak)$/,@files);
               if (scalar(@files) - scalar(@orphans) > 0) { 
                   return 0;
               } else {
                   if (($phase eq 'Delete2') && (@orphans > 0)) {
                       foreach my $file (@orphans) {
                           if ($file =~ /\.(meta|save|log|bak)$/) {
                               unlink($dirname.$file);
                           }
                       }
                   }
               }
           }
           closedir(DIR);
           return 1;
       }
       return 0;
 }  }
   
 =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 file name has been published or exists
    in the construction space.     in the construction space.
Line 294  sub ConstructionPathFromRelative { Line 239  sub ConstructionPathFromRelative {
   
 =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 310  Returns: Line 256  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.
Line 319  Returns: Line 268  Returns:
 =cut  =cut
   
 sub exists {  sub exists {
   my ($user, $domain, $dir, $file) = @_;      my ($user, $domain, $construct, $creating) = @_;
       $creating ||= 'file';
   
       my $published=$construct;
       $published=~s{^/home/httpd/html/priv/}{/home/httpd/html/res/};
       my ($type,$result);
       if ( -d $construct ) {
    return ('error','<p><span class="LC_error">'.&mt('Error: destination for operation is an existing directory.').'</span></p>');
   
       }
   
   # Create complete paths in publication and construction space.      if ( -e $published) {
   my $relativedir=$dir;   if ( -e $construct ) {
   $relativedir=s|/home/\Q$user\E/public_html||;      $type = 'warning';
   my $published = &PublicationPath($domain, $user, $relativedir, $file);      $result.='<p><span class="LC_warning">'.&mt('Warning: target file exists, and has been published!').'</span></p>';
   my $construct = &ConstructionPath($user, $relativedir, $file);   } else {
       my $published_type = (-d $published) ? 'directory' : 'file';
   # If the resource exists in either space indicate this fact.  
   # Note that the check for existence in resource space is stricter.  
   
   my $result;      
   if ( -d $construct ) {  
       return 'Error: destination for operation is a directory.';  
   }  
   if ( -e $published) {  
       $result.='<p><font color="red">Warning: target file exists, and has been published!</font></p>';  
   }  
   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><span class="LC_warning">'.&mt("Warning: a published $published_type of this name exists.").'</span></p>';
       } else {
    $type = 'error';
    $result.='<p><span class="LC_error">'.&mt("Error: a published $published_type of this name exists.").'</span></p>';
       }
    }
       } elsif ( -e $construct) {
    $type = 'warning';
    $result.='<p><span class="LC_warning">'.&mt('Warning: target file exists!').'</span></p>';
       }
   
       return ($type,$result);
 }  }
   
 =pod  =pod
Line 381  sub checksuffix { Line 338  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><span class="LC_warning">'.&mt('Warning: change of MIME type!').'</span></p>';
     }      }
     return $result;      return $result;
 }  }
   
 sub cleanDest {  sub cleanDest {
     my ($request,$dest)=@_;      my ($request,$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 $error='';
  $dest=~s/[\#\?&]//g;      if ($subdir && $dest =~/\./) {
    $foundbad=1;
    $dest=~s/\.//g;
       }
       $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") {
       $request->print('<p><span 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 file name."
                                  ,&display($newpath))
                              .'</span></p>');
       $dest=~s|.*/||;
    }
     }      }
     return $dest;      if ($dest =~ /\.(\d+)\.(\w+)$/){
    $request->print('<p><span 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>')
    .'</span></p>');
    $dest =~ s/\.(\d+)(\.\w+)$/$2/;
       }
       if ($foundbad) {
           $request->print('<p><span class="LC_warning">'
                          .&mt('Invalid characters in requested name have been removed.')
                           .'</span></p>'
           );
       }
       return ($dest,$error);
   }
   
   sub relativeDest {
       my ($fn,$newfilename,$uname,$udom)=@_;
       my $error = '';
       if ($newfilename=~/^\//) {
   # absolute, simply add path
    $newfilename='/home/httpd/html/res/'.$udom.'/'.$uname.'/';
       } else {
    my $dir=$fn;
    $dir=~s/\/[^\/]+$//;
    $newfilename=$dir.'/'.$newfilename;
       }
       $newfilename=~s://+:/:g; # remove duplicate /
       while ($newfilename=~m:/\.\./:) {
    $newfilename=~ s:/[^/]+/\.\./:/:g; #remove dir/..
       }
       if ($newfilename =~ m{^/home/($match_username)/(?:public\_html|priv)/}) {
           my $otheruname = $1;
           unless ($otheruname eq $uname) {
               my ($authorname,$authordom)=
                   &Apache::loncacc::constructaccess($newfilename,$env{'request.role.domain'});
               unless (($authorname eq $otheruname) && ($authordom ne '')) {
                   my $otherdir = &display($newfilename);
                   $error = &mt('Access denied to [_1]',$otherdir);
               }
           }
       }
       return ($newfilename,$error);
 }  }
   
 =pod  =pod
Line 417  Parameters: Line 437  Parameters:
 =cut  =cut
   
 sub CloseForm1 {  sub CloseForm1 {
    my ($request,  $cancelurl) = @_;      my ($request,  $fn) = @_;
       $request->print('<p><input type="submit" value="'.&mt('Continue').'" /></p></form>');
       $request->print('<form action="'.&url($fn).
    &Debug($request, "Cancel url is: ".$cancelurl);      '" method="post"><p><input type="submit" value="'.&mt('Cancel').'" /></p></form>');
    $request->print('<p><input type="submit" value="Continue" /></p></form>');  
    $request->print('<form action="'.$cancelurl.  
    '" method="POST"><p><input type="submit" value="Cancel" /></p></form>');  
   
 }  }
   
   
Line 453  Parameters: Line 469  Parameters:
 =cut  =cut
   
 sub CloseForm2 {  sub CloseForm2 {
   my ($request, $user, $directory) = @_;      my ($request, $user, $fn) = @_;
       $request->print(&done(&url($fn)));
   $request->print('<h3><a href="/priv/'.$user.$directory.'/">Done </a> </h3>');  
 }  }
   
 =pod  =pod
Line 494  new filename relative to the current dir Line 509  new filename relative to the current dir
 =cut    =cut  
   
 sub Rename1 {  sub Rename1 {
     my ($request, $filename, $user, $domain, $dir) = @_;      my ($request, $user, $domain, $fn, $newfilename, $style) = @_;
     &Debug($request, "Username - ".$user." filename: ".$filename."\n");  
     my $conspace = $filename;      if(-e $fn) {
    if($newfilename) {
     my $cancelurl = "/priv/".$filename;      # is dest a dir
     $cancelurl    =~ s/\/home\///;      if ($style eq 'move') {
     $cancelurl    =~ s/\/public_html//;   if (-d $newfilename) {
           if ($fn =~ m|/([^/]*)$|) { $newfilename .= '/'.$1; }
     if(-e $conspace) {   }
  if($ENV{'form.newfilename'}) {      }
     my $newfilename = $ENV{'form.newfilename'};  
     if ($newfilename =~ m|/[^\.]+$|) {      if ($newfilename =~ m|/[^\.]+$|) {
  #no extension add on orignal extension   #no extension add on original extension
  if ($filename =~ m|/[^\.]*\.([^\.]+)$|) {   if ($fn =~ m|/[^\.]*\.([^\.]+)$|) {
     $newfilename.='.'.$1;      $newfilename.='.'.$1;
  }   }
     }      }
     $request->print(&checksuffix($filename, $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
     if ($filename =~ m|/$|) {      if (-d $fn) {
  $filename =~ s|/$||;   $newfilename=~/\.(\w+)$/;
  $dir =~ s|/[^/]*$||;   if (&Apache::loncommon::fileembstyle($1) eq 'ssi') {
       $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="'.$cancelurl.'">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;
     }      }
     my $dest=&SimplifyDir($dir,$newfilename);      my $action;
     $request->print('<input type="hidden" name="newfilename" value="'.      if ($style eq 'rename') {
     $newfilename.   $action='Rename';
     '" /><p>Rename <tt>'.$filename.      } else {
     '</tt><br /> to <tt>'.   $action='Move';
     $dest.'</tt>?</p>');      }
     &CloseForm1($request, $cancelurl);              $request->print('<input type="hidden" name="newfilename" value="'
                              .$newfilename.'" />'
                              .'<p>'
                              .&mt($action.' [_1] to [_2]?',
                                   &display($fn),
                                   &display($newfilename))
                              .'</p>'
           );
       &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 </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 552  Parameters: Line 598  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 session user.  =item   $user      - string [in]  Name of the user initiating the request.
   
   =item   $domain    - string [in]  Domain the initiating user is logged in as
   
 =item   $filename  - string [in] Name fo the file to be deleted:  =item   $filename  - string [in]  Source filename.
                 Filename is the full filesystem path to the file.  
   
 =back  =back
   
 =cut  =cut
   
 sub Delete1 {  sub Delete1 {
   my ($request, $user,  $filename) = @_;      my ($request, $user, $domain, $fn) = @_;
   
   my $cancelurl = '/priv/'.$filename;  
   $cancelurl    =~ s/\/home\///;  
   $cancelurl    =~ s/\/public_html//;  
     
   
   if( -e $filename) {      if( -e $fn) {
     $request->print('<input type="hidden" name="newfilename" value="'.   $request->print('<input type="hidden" name="newfilename" value="'.
     $filename.'"/>');   $fn.'" />');
     $request->print('<p> Delete <tt>'.$filename.'</tt>?</p>');          if (-d $fn) {
     &CloseForm1($request, $cancelurl);              unless (&empty_directory($fn,'Delete1')) {
   } else {                  $request->print('<p>'
     $request->print('<p> No Such file: <tt>'.$filename.'</tt></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 602  Parameters: Line 673  Parameters:
   
 =item   $domain    - string [in]  Domain the initiating user is logged in as  =item   $domain    - string [in]  Domain the initiating user is logged in as
   
 =item   $dir       - string [in]  Directory path.  =item   $fn  - string [in]  Source filename.
   
 =item   $filename  - string [in]  Source filename.  
   
 =item   $newfilename-string [in]  Destination filename.  =item   $newfilename-string [in]  Destination filename.
   
Line 613  Parameters: Line 682  Parameters:
 =cut  =cut
   
 sub Copy1 {  sub Copy1 {
   my ($request, $user, $domain, $dir, $filename, $newfilename) = @_;      my ($request, $user, $domain, $fn, $newfilename) = @_;
   
   my $cancelurl = "/priv/".$filename;  
   $cancelurl    =~ s/\/home\///;  
   $cancelurl    =~ s/\/public_html//;  
       
   
   if(-e $filename) {      if(-e $fn) {
     $request->print(&checksuffix($filename,$newfilename));   # is dest a dir
     my $return=&exists($user, $domain, $dir, $newfilename);   if (-d $newfilename) {
     $request->print($return);      if ($fn =~ m|/([^/]*)$|) { $newfilename .= '/'.$1; }
     if ($return =~/^Error:/) {   }
  $request->print('<br /><a href="'.$cancelurl.'">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>');
       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>'
           );
     }      }
     my $dest=&SimplifyDir($dir,$newfilename);  
     $request->print('<input type = "hidden" name = "newfilename" value = "'.  
     $dir.'/'.$newfilename.  
     '" /><p>Copy <tt>'.$filename.'</tt><br />  to '.  
     '<tt>'.$dest.'</tt>?</p>');  
     &CloseForm1($request, $cancelurl);  
   } else {  
     $request->print('<p>No such file <tt>'.$filename.'</p></form>');  
   }  
 }  
   
 =pod  
   
 =item SimplifyDir  
   
   Removes all extra / and all .. references  
   
 Parameters:  
   
 =over 4  
   
 =item $dir - string [in] a directory name  
   
 =item $file - string [in] a file reference relative to $dir  
   
 =back  
   
 Results: the concatenated path.  
   
 =cut  
   
 sub SimplifyDir {  
     my ($dir,$file) = @_;  
     my $location = $dir. '/'.$file;  
     $location=~s://+:/:g; # remove duplicate /  
     while ($location=~m:/\.\./:) {$location=~s:/[^/]+/\.\./:/:g;}#remove dir/..  
     return $location;  
 }  }
   
 =pod  =pod
Line 684  Parameters: Line 740  Parameters:
   
 =item   $username - Name of the user that is requesting the directory creation.  =item   $username - Name of the user that is requesting the directory creation.
   
 =item   $path     - current directory relative to construction space.  =item $domain - Domain user is in
   
   =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.
Line 704  causes the newdir operation to transitio Line 762  causes the newdir operation to transitio
 =cut  =cut
   
   
 sub NewDir1  sub NewDir1 {
 {      my ($request, $username, $domain, $fn, $newfilename, $mode) = @_;
   my ($request, $username, $path, $newdir) = @_;  
       my ($type, $result)=&exists($username,$domain,$newfilename,'directory');
   my $fullpath = '/home/'.$username.'/public_html/'.      $request->print($result);
     $path.'/'.$newdir;      if ($type eq 'error') {
    $request->print('</form>');
   my $cancelurl = '/priv/'.$username.'/'.$path;      } else {
    if (($mode eq 'testbank') || ($mode eq 'imsimport')) {
   &Debug($request, "Full path is : ".$fullpath);      $request->print('<input type="hidden" name="callingmode" value="'.$mode.'" />'."\n".
                               '<input type="hidden" name="inhibitmenu" value="yes" />');
   if(-e $fullpath) {   }
     $request->print('<p>Directory exists.</p></form>');          $request->print('<input type="hidden" name="newfilename" value="'
   }                         .$newfilename.'" />'
   else {                         .'<p>'
     $request->print('<input type="hidden" name="newfilename" value="'.                         .&mt('Make new directory [_1]?',
     $newdir.'" /><p>Make new directory <tt>'.                              &display($newfilename))
     $path."/".$newdir.'</tt>?</p>');                         .'</p>'
     &CloseForm1($request, $cancelurl);          );
    &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>'
           );
       }
 }  }
   
 =pod  =pod
Line 748  Parameters: Line 826  Parameters:
   
 =item   $domain   - Name of the domain of the user  =item   $domain   - Name of the domain of the user
   
 =item   $dir      - current absolute diretory  =item   $fn      - Source file name
   
 =item   $newfilename  =item   $newfilename
                   - Name of the file to be created; no path information                    - Name of the file to be created; no path information
Line 760  Side Effects: Line 838  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 Cancle  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 driectory listing you came from
   
 =back  =back
   
 =cut  =cut
   
   
 sub NewFile1 {  sub NewFile1 {
     my ($request, $user, $domain, $dir, $newfilename) = @_;      my ($request, $user, $domain, $fn, $newfilename) = @_;
       return if (&filename_check($newfilename) ne 'ok');
   
     &Debug($request, "Dir is : ".$dir);      if ($env{'form.action'} =~ /new(.+)file/) {
     &Debug($request, "Newfile is : ".$newfilename);  
   
     my $cancelurl = "/priv/".$dir;  
     $cancelurl    =~ s/\/home\///;  
     $cancelurl    =~ s/\/public_html//;  
   
     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);
       $request->print($result);
       if ($type eq 'error') {
    $request->print('</form>');
       } else {
           my $extension;
   
     my $fullpath = $dir.'/'.$newfilename;          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('<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 file name: ').'<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>');
               return;
           }
   
     &Debug($request, "Full path is : ".$fullpath);   $request->print('<p>'.&mt('Make new file').' '.&display($newfilename).'?</p>');
    $request->print('</form>');
   
     if(-e $fullpath) {   $request->print('<form action="'.&url($newfilename).
  $request->print('<p>File exists.</p></form>');   '" 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>');
     }      }
     else {      return;
  $request->print('<p>Make new file <tt>'.$dir.'/'.$newfilename.'</tt>?</p>');  }
  my $dest=&MakeFinalUrl($request,$fullpath);  
  &Debug($request, "Cancel url is: ".$cancelurl);  sub filename_check {
  &Debug($request, "Dest url is: ".$dest);      my ($newfilename) = @_;
  $request->print('</form>');      ##Informs User (name).(number).(extension) not allowed
  $request->print('<form action="'.$dest.      if($newfilename =~ /\.(\d+)\.(\w+)$/){
  '" method="POST"><p><input type="submit" value="Continue" /></p></form>');          $r->print('<span class="LC_error">'.$newfilename.
  $request->print('<form action="'.$cancelurl.                    ' - '.&mt('Bad Filename').'<br />('.&mt('name').').('.&mt('number').').('.&mt('extension').') '.
  '" method="POST"><p><input type="submit" value="Cancel" /></p></form>');                    ' '.&mt('Not Allowed').'</span>');
           return;
     }      }
       if($newfilename =~ /(\:\:\:|\&\&\&|\_\_\_)/){
           $r->print('<span class="LC_error">'.$newfilename.
                     ' - '.&mt('Bad Filename').'<br />('.&mt('Must not include').' '.$1.') '.
                     ' '.&mt('Not Allowed').'</span>');
           return;
       }
       return 'ok'; 
 }  }
   
 =pod  =pod
Line 838  performed and reported to the user. Line 946  performed and reported to the user.
 =cut  =cut
   
 sub phaseone {  sub phaseone {
   my ($r,$fn,$uname,$udom)=@_;      my ($r,$fn,$uname,$udom)=@_;
     
   $fn=~m:(.*)/([^/]+)\.(\w+)$:;  
   my $dir=$1;  
   my $main=$2;  
   my $suffix=$3;  
     
   #  my $conspace=ConstructionPathFromRelative($uname, $fn);  
       
   $ENV{'form.newfilename'}=&cleanDest($r,$ENV{'form.newfilename'});      my $doingdir=0;
       if ($env{'form.action'} eq 'newdir') { $doingdir=1; }
   $r->print('<form action="/adm/cfile" method="post">'.      my ($newfilename,$error) = 
     '<input type="hidden" name="filename" value="/~'.$uname.$fn.'" />'.          &cleanDest($r,$env{'form.newfilename'},$doingdir,$fn,$uname,$udom);
     '<input type="hidden" name="phase" value="two" />'.      unless ($error) {
     '<input type="hidden" name="action" value="'.$ENV{'form.action'}.'" />');          ($newfilename,$error)=&relativeDest($fn,$newfilename,$uname,$udom);
       }
       if ($error) {
           my $dirlist;
           if ($fn=~m{^(.*/)[^/]+$}) {
               $dirlist=$1;
           } else {
               $dirlist=$fn; 
           }
           $r->print('<div class="LC_error">'.$error.'</div>'.
                     '<h3><a href="'.&url($dirlist).'">'.&mt('Return to Directory').
                     '</a></h3>');
           return;
       }
       $r->print('<form action="/adm/cfile" method="post">'.
         '<input type="hidden" name="qualifiedfilename" value="'.$fn.'" />'.
         '<input type="hidden" name="phase" value="two" />'.
         '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />');
       
   if ($ENV{'form.action'} eq 'rename') {      if ($env{'form.action'} eq 'rename') {
       if (!defined($dir)) {   &Rename1($r, $uname, $udom, $fn, $newfilename, 'rename');
   $fn=~m:(.*)/:;      } elsif ($env{'form.action'} eq 'move') {
   $dir=$1;   &Rename1($r, $uname, $udom, $fn, $newfilename, 'move');
       }      } elsif ($env{'form.action'} eq 'delete') { 
       &Rename1($r, $fn, $uname, $udom, $dir);   &Delete1($r, $uname, $udom, $fn);
   } elsif ($ENV{'form.action'} eq 'delete') {       } elsif ($env{'form.action'} eq 'decompress') {
        &Decompress1($r, $uname, $udom, $fn);
     &Delete1($r, $uname, $fn);      } elsif ($env{'form.action'} eq 'copy') { 
        if($newfilename) {
   } elsif ($ENV{'form.action'} eq 'copy') {       &Copy1($r, $uname, $udom, $fn, $newfilename);
     if($ENV{'form.newfilename'}) {   } else {
       my $newfilename = $ENV{'form.newfilename'};              $r->print('<p class="LC_error">'
       &Copy1($r, $uname, $udom, $dir, $fn, $newfilename);                       .&mt('No new filename specified.')
     }else {                       .'</p></form>'
       $r->print('<p>No new filename specified.</p></form>');              );
     }   }
   } elsif ($ENV{'form.action'} eq 'newdir') {      } elsif ($env{'form.action'} eq 'newdir') {
     &NewDir1($r, $uname, $dir, $ENV{'form.newfilename'});   my $mode = '';
   }  elsif ($ENV{'form.action'} eq 'newfile' ||   if (exists($env{'form.callingmode'}) ) {
     $ENV{'form.action'} eq 'newhtmlfile' ||      $mode = $env{'form.callingmode'};
     $ENV{'form.action'} eq 'newproblemfile' ||   }   
             $ENV{'form.action'} eq 'newpagefile' ||   &NewDir1($r, $uname, $udom, $fn, $newfilename, $mode);
             $ENV{'form.action'} eq 'newsequencefile' ||      }  elsif ($env{'form.action'} eq 'newfile' ||
             $ENV{'form.action'} eq 'Select Action') {        $env{'form.action'} eq 'newhtmlfile' ||
       if($ENV{'form.newfilename'}) {        $env{'form.action'} eq 'newproblemfile' ||
   my $newfilename = $ENV{'form.newfilename'};        $env{'form.action'} eq 'newpagefile' ||
   if (!defined($dir)) {        $env{'form.action'} eq 'newsequencefile' ||
       $fn=~m:(.*)/:;        $env{'form.action'} eq 'newrightsfile' ||
       $dir=$1;        $env{'form.action'} eq 'newstyfile' ||
   }        $env{'form.action'} eq 'newtaskfile' ||
   &NewFile1($r, $uname, $udom, $dir, $newfilename);                $env{'form.action'} eq 'newlibraryfile' ||
       } else {        $env{'form.action'} eq 'Select Action') {
   $r->print('<p>No new filename specified.</p></form>');          my $empty=&mt('Type Name Here');
       }   if (($newfilename!~/\/$/) && ($newfilename!~/$empty$/)) {
   }      &NewFile1($r, $uname, $udom, $fn, $newfilename);
    } else {
               $r->print('<p class="LC_error">'
                        .&mt('No new filename specified.')
                        .'</p></form>'
               );
    }
       }
 }  }
   
 =pod  =pod
Line 928  Returns: Line 1053  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>'
              .&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)
Line 989  Returns: Line 1140  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
Line 1027  sub Delete2 { Line 1194  sub Delete2 {
   
 =back  =back
   
 Returns 0 failure, and 0 successs.  Returns 0 failure, and 1 successs.
   
 =cut  =cut
   
Line 1035  sub Copy2 { Line 1202  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 1074  Returns 0 - failure 1 - success. Line 1251  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;
 }  }
   
 =pod  =pod
Line 1124  sub phasetwo { Line 1312  sub phasetwo {
           
     &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,       &Debug($r,"loncfie::phase2 action is $env{'form.action'}");
    "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 '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('<h3><a href="javascript:self.close()">'.&mt('Done').'</a></h3>');
       } else {
           if ($env{'form.action'} eq 'rename') {
               $r->print('<h3><a href="'.&url($dest).'">'.&mt('Return to Directory').'</a></h3>');
               $r->print('<h3><a href="'.&url($dest_newname).'">'.$disp_newname.'</a></h3>');
           } else {
       $r->print(&done(&url($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']);
   
       &Debug($r, "loncfile.pm - handler entered");
       &Debug($r, " filename: ".$env{'form.filename'});
       &Debug($r, " newfilename: ".$env{'form.newfilename'});
   #
   # Determine the root filename
   # This could come in as "filename", which actually is a URL, or
   # as "qualifiedfilename", which is indeed a real filename in filesystem
   #
       my $fn;
   
       if ($env{'form.filename'}) {
    &Debug($r, "test: $env{'form.filename'}");
    $fn=&unescape($env{'form.filename'});
    $fn=&URLToPath($fn);
       }  elsif($ENV{'QUERY_STRING'} && $env{'form.phase'} ne 'two') {  
    #Just hijack the script only the first time around to inject the
    #correct information for further processing
    $fn=&unescape($env{'form.decompress'});
    $fn=&URLToPath($fn);
    $env{'form.action'}="decompress";
       } elsif ($env{'form.qualifiedfilename'}) {
    $fn=$env{'form.qualifiedfilename'};
       } else {
    &Debug($r, "loncfile::handler - no form.filename");
    $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
          ' unspecified filename for cfile', $r->filename); 
    return HTTP_NOT_FOUND;
       }
   
   &Debug($r, "loncfile.pm - handler entered");      unless ($fn) { 
   &Debug($r, " filename: ".$ENV{'form.filename'});   &Debug($r, "loncfile::handler - doctored url is empty");
   &Debug($r, " newfilename: ".$ENV{'form.newfilename'});   $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
          ' trying to cfile non-existing file', $r->filename); 
   my $fn;   return HTTP_NOT_FOUND;
       } 
   if ($ENV{'form.filename'}) {  
       $fn=&Apache::lonnet::unescape($ENV{'form.filename'});  
       &Debug($r, "loncfile::handler - raw url: $fn");  
 #      $fn=~s/^http\:\/\/[^\/]+\/\~(\w+)/\/home\/$1\/public_html/;  
 #      $fn=~s/^http\:\/\/[^\/]+//;  
       $fn=URLToPath($fn);  
       &Debug($r, "loncfile::handler - doctored url: $fn");  
   
   } else {  
       &Debug($r, "loncfile::handler - no form.filename");  
      $r->log_reason($ENV{'user.name'}.' at '.$ENV{'user.domain'}.  
          ' unspecified filename for cfile', $r->filename);   
      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 $uname;
   my $udom;      my $udom;
   
   ($uname,$udom)=      ($uname,$udom)=
     &Apache::loncacc::constructaccess($fn,$r->dir_config('lonDefDomain'));   &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");
   unless (($uname) && ($udom)) {      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;
   }      }
   
   $fn=~s/\/\~(\w+)//;  
   &Debug($r, "loncfile::handler ~ removed filename: $fn");  
   
   $r->content_type('text/html');  
   $r->send_http_header;  
   
   $r->print('<html><head><title>LON-CAPA Construction Space</title></head>');      &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;
   
   $r->print(      my (%loaditem,$js);
    '<body bgcolor="#FFFFFF"><img align="right" src="/adm/lonIcons/lonlogos.gif" />');  
   
       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'};
    $js = qq|
   <script type="text/javascript">
   function writeDone() {
       window.focus();
       opener.document.info.newdir.value = "$newdirname";
       setTimeout("self.close()",10000);
   }
     </script>
   |;
    $loaditem{'onload'} = "writeDone()";
       }
       
       # Breadcrumbs
       &Apache::lonhtmlcommon::clear_breadcrumbs();
       &Apache::lonhtmlcommon::add_breadcrumb({
           'text'  => 'Construction Space',
           'href'  => &Apache::loncommon::authorspace(),
       });
       &Apache::lonhtmlcommon::add_breadcrumb({
           'text'  => 'File Operation',
           'title' => 'Construction Space File Operation',
           'href'  => '',
       });
   
       $r->print(&Apache::loncommon::start_page('Construction Space File Operation',
        $js,
        {'add_entries' => \%loaditem,})
                .&Apache::lonhtmlcommon::breadcrumbs()
                .&Apache::loncommon::head_subbox(
                     &Apache::loncommon::CSTR_pageheader())
       );
       
   $r->print('<h1>Construction Space <tt>'.$fn.'</tt></h1>');      $r->print('<h3>'.&mt('Location').': '.&display($fn).'</h3>');
       
   if (($uname ne $ENV{'user.name'}) || ($udom ne $ENV{'user.domain'})) {      if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
           $r->print('<h3><font color="red">Co-Author: '.$uname.' at '.$udom.          $r->print('<p class="LC_info">'
                '</font></h3>');                   .&mt('Co-Author [_1]',$uname.':'.$udom)
   }                   .'</p>'
           );
       }
   &Debug($r, "loncfile::handler Form action is $ENV{'form.action'} ");  
   if ($ENV{'form.action'} eq 'delete') {  
             &Debug($r, "loncfile::handler Form action is $env{'form.action'} ");
       $r->print('<h3>Delete</h3>');      if ($env{'form.action'} eq 'delete') {
   } elsif ($ENV{'form.action'} eq 'rename') {        $r->print('<h3>'.&mt('Delete').'</h3>');
       $r->print('<h3>Rename</h3>');      } elsif ($env{'form.action'} eq 'rename') {
   } elsif ($ENV{'form.action'} eq 'newdir') {   $r->print('<h3>'.&mt('Rename').'</h3>');
       $r->print('<h3>New Directory</h3>');      } elsif ($env{'form.action'} eq 'move') {
   } elsif ($ENV{'form.action'} eq 'copy') {   $r->print('<h3>'.&mt('Move').'</h3>');
       $r->print('<h3>Copy</h3>');      } elsif ($env{'form.action'} eq 'newdir') {
   } elsif ($ENV{'form.action'} eq 'newfile' ||   $r->print('<h3>'.&mt('New Directory').'</h3>');
    $ENV{'form.action'} eq 'newhtmlfile' ||      } elsif ($env{'form.action'} eq 'decompress') {
    $ENV{'form.action'} eq 'newproblemfile' ||   $r->print('<h3>'.&mt('Decompress').'</h3>');
            $ENV{'form.action'} eq 'newpagefile' ||      } elsif ($env{'form.action'} eq 'copy') {
            $ENV{'form.action'} eq 'newsequencefile' ||   $r->print('<h3>'.&mt('Copy').'</h3>');
            $ENV{'form.action'} eq 'Select Action' ) {      } elsif ($env{'form.action'} eq 'newfile' ||
       $r->print('<h3>New Resource</h3>');       $env{'form.action'} eq 'newhtmlfile' ||
   } else {       $env{'form.action'} eq 'newproblemfile' ||
      $r->print('<p>Unknown Action '.$ENV{'form.action'}.' </p></body></html>');       $env{'form.action'} eq 'newpagefile' ||
      return OK;         $env{'form.action'} eq 'newsequencefile' ||
   }       $env{'form.action'} eq 'newrightsfile' ||
   if ($ENV{'form.phase'} eq 'two') {       $env{'form.action'} eq 'newstyfile' ||
       &Debug($r, "loncfile::handler  entering phase2");       $env{'form.action'} eq 'newtaskfile' ||
       &phasetwo($r,$fn,$uname,$udom);               $env{'form.action'} eq 'newlibraryfile' ||
   } else {       $env{'form.action'} eq 'Select Action' ) {
       &Debug($r, "loncfile::handler  entering phase1");   $r->print('<h3>'.&mt('New Resource').'</h3>');
       &phaseone($r,$fn,$uname,$udom);      } else {
   }          $r->print('<p class="LC_error">'
                    .&mt('Unknown Action').' '.$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);
       } 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.32  
changed lines
  Added in v.1.110


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