Diff for /loncom/publisher/loncfile.pm between versions 1.10 and 1.24

version 1.10, 2002/05/27 03:18:46 version 1.24, 2003/02/10 23:13:17
Line 8 Line 8
 #  and requests confirmation.  The second phase commits the action  #  and requests confirmation.  The second phase commits the action
 #  and displays a page showing the results of the action.  #  and displays a page showing the results of the action.
 #  #
   
 #  #
 # $Id$  # $Id$
 #  #
Line 53 Line 52
 # 05/07/02 Ron Fox:  # 05/07/02 Ron Fox:
 #           - Added Debug log output so that I can trace what the heck this  #           - Added Debug log output so that I can trace what the heck this
 #             undocumented thingy does.  #             undocumented thingy does.
   # 05/28/02  Ron Fox:
   #           - Started putting in pod in standard format.
   =pod
   
   =head1 NAME
   
   Apache::loncfile - Construction space file management.
   
   =head1 SYNOPSIS
    
    Content handler for buttons on the top frame of the construction space 
   directory.
   
   =head1 INTRODUCTION
   
     loncfile is invoked when buttons in the top frame of the construction 
   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
   confirms the operation, the second phase commits the operation and indicates
   completion.  When the user dismisses the output of phase2, they are returned to
   an "appropriate" directory listing in general.
   
       This is part of the LearningOnline Network with CAPA project
   described at http://www.lon-capa.org.
   
   =head2 Subroutines
   
   =cut
   
 package Apache::loncfile;  package Apache::loncfile;
   
 use strict;  use strict;
 use Apache::File;  use Apache::File;
   use File::Basename;
 use File::Copy;  use File::Copy;
   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::Log ();
   use Apache::lonnet;
   
 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.
 #  
 #  Debug  =pod
 #    If debugging is enabled puts out a debuggin message determined by the  
 #    caller.  The debug message goes to the Apache error log file.  =item Debug($request, $message)
 #  
 #  Parameters:    If debugging is enabled puts out a debugging message determined by the
 #     r       - Apache request [in]    caller.  The debug message goes to the Apache error log file. Debugging
 #     message - String [in]     is enabled by setting the module global DEBUG variable to nonzero (TRUE).
 # Returns:  
 #    nothing.   Parameters:
   
   =over 4
    
   =item $request - The current request operation.
   
   =item $message - The message to put in the log file.
   
   =back
     
    Returns:
      nothing.
   
   =cut
   
 sub Debug {  sub Debug {
     my $r       = shift;    
     my $log     = $r->log;    # Marshall the parameters.
     my $message = shift;    
     if ($DEBUG) {    my $r       = shift;
  $log->debug($message);        my $log     = $r->log;
     }    my $message = shift;
     
     # Put out the indicated message butonly if DEBUG is true.
     
     if ($DEBUG) {
       $log->debug($message);
     }
 }  }
 #  
 #   URLToPath  =pod
 #     Convert a URL to a file system path.  
 #  =item URLToPath($url)
 #   In order to manipulate the construction space objects, it's necessary  
 #   to access url identified objects a filespace objects.  This function    Convert a URL to a file system path.
 #   translates a construction space URL to a file system path.    
 # Parameters:    In order to manipulate the construction space objects, it is necessary
 #    Url    - string [in] The url to convert.    to access url identified objects a filespace objects.  This function
 # Returns:    translates a construction space URL to a file system path.
 #    The corresponing file system path.   Parameters:
 sub URLToPath  
   =over 4
   
   =item  Url    - string [in] The url to convert.
     
   =back
     
    Returns:
   
   =over 4
   
   =item  The corresponding file system path. 
   
   =back
   
   Global References
   
   =over 4
   
   =item  $r      - Request object [in] Referenced in the &Debug calls.
   
   =back
   
   =cut
   
   sub URLToPath {
     my $Url = shift;
     &Debug($r, "UrlToPath got: $Url");
     $Url=~ s/^http\:\/\/[^\/]+\/\~(\w+)/\/home\/$1\/public_html/;
     $Url=~ s/^http\:\/\/[^\/]+//;
     &Debug($r, "Returning $Url \n");
     return $Url;
   }
   
   =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 $Url = shift;    my ($domain, $user, $dir, $file)=@_;
     &Debug($r, "UrlToPath got: $Url");  
     $Url=~ s/^http\:\/\/[^\/]+\/\~(\w+)/\/home\/$1\/public_html/;    return '/home/httpd/html/res/'.$domain.'/'.$user.'/'.$dir.'/'.
     $Url=~ s/^http\:\/\/[^\/]+//;   $file;
     &Debug($r, "Returning $Url \n");  }
     return $Url;  
   =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;
   
   }
   =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;
   
 }  }
   
   =pod
   
   =item exists($user, $domain, $directory, $file)
   
      Determine if a resource file name has been published or exists
      in the construction space.
   
    Parameters:
   
   =over 4
   
   =item  $user   - string [in] - Name of the user for which to check.
   
   =item  $domain - string [in] - Name of the domain in which the resource
                             might have been published.
   
   =item  $dir    - string [in] - Path relative to construction or resource space
                             in which the resource might live.
   
   =item  $file   - string [in] - Name of the file.
   
   =back
   
   Returns:
   
   =over 4
   
   =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
              does not exist.
     
   =back
   
   =cut
   
 sub exists {  sub exists {
     my ($uname,$udom,$dir,$newfile)=@_;    my ($user, $domain, $dir, $file) = @_;
     my $published='/home/httpd/html/res/'.$udom.'/'.$uname.'/'.$dir.'/'.  
  $ENV{'form.newfilename'};    # Create complete paths in publication and construction space.
     my $construct='/home/'.$uname.'/public_html/'.$dir.'/'.    my $relativedir=$dir;
  $ENV{'form.newfilename'};    $relativedir=s|/home/\Q$user\E/public_html||;
     my $result;    my $published = &PublicationPath($domain, $user, $relativedir, $file);
     if (-e $published) {    my $construct = &ConstructionPath($user, $relativedir, $file);
  $result.='<p><font color=red>Warning: target file exists, and has been published!</font></p>';  
     } elsif ( -e $construct ) {    # If the resource exists in either space indicate this fact.
  $result.='<p><font color=red>Warning: target file exists!</font></p>';    # Note that the check for existence in resource space is stricter.
     }  
     return $result;    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;
   
 }  }
   
   =pod
   
   =item checksuffix($old, $new)
           
     Determine if a resource filename suffix (the stuff after the .) would change
   as a result of this operation.
   
    Parameters:
   
   =over 4
   
   =item  $old   = string [in]  Previous filename.
   
   =item  $new   = string [in]  Resultant filename.
   
   =back
   
    Returns:
   
   =over 4
   
   =item    Empty string if everything worked.
   
   =item    String containing an error message if there was a problem.
   
   =back
   
   =cut
   
 sub checksuffix {  sub checksuffix {
     my ($old,$new) = @_;      my ($old,$new) = @_;
     my $result;      my $result;
Line 126  sub checksuffix { Line 382  sub checksuffix {
     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 ($oldsuffix ne $newsuffix) {
  $result.='<p><font color=red>Warning: change of MIME type!</font></p>';   $result.=
               '<p><font color="red">Warning: change of MIME type!</font></p>';
     }      }
     return $result;      return $result;
 }  }
   =pod
   
 sub phaseone {  =item CloseForm1($request, $user, $file)
     my ($r,$fn,$uname,$udom)=@_;  
      Close of a form on the successful completion of phase 1 processing
   
   Parameters:
   
   =over 4
   
   =item  $request - Apache Request Object [in] - Apache server request object.
   
   =item  $cancelurl - the url to go to on cancel.
   
   =back
   
   =cut
   
   sub CloseForm1 {
      my ($request,  $cancelurl) = @_;
   
   
      &Debug($request, "Cancel url is: ".$cancelurl);
      $request->print('<p><input type="submit" value="Continue" /></p></form>');
      $request->print('<form action="'.$cancelurl.
      '" method="GET"><p><input type="submit" value="Cancel" /></p></form>');
   
   }
   
   
   =pod
   
   =item CloseForm2($request, $user, $directory)
   
      Successfully close off the phase 2 form.
   
   Parameters:
   
   =over 4
   
   =item   $request    - Apache Request object [in] - The request that is being
                    executed.
   
   =item   $user       - string [in] - Name of the user that is initiating the
                    request.
   
   =item   $directory  - string [in] - Directory in which the operation is 
                    being done relative to the top level construction space
                    directory.
   
     $fn=~m:(.*)/([^/]+)\.(\w+)$:;  =back
     my $dir=$1;  
     my $main=$2;  =cut
     my $suffix=$3;  
   sub CloseForm2 {
     my $conspace='/home/'.$uname.'/public_html'.$fn;    my ($request, $user, $directory) = @_;
   
     $r->print('<form action=/adm/cfile method=post>'.    $request->print('<h3><a href="/priv/'.$user.$directory.'/">Done </a> </h3>');
       '<input type=hidden name=filename value="/~'.$uname.$fn.'">'.  }
               '<input type=hidden name=phase value=two>'.  
               '<input type=hidden name=action value='.$ENV{'form.action'}.'>');  =pod
   
     if ($ENV{'form.action'} eq 'rename') {  =item Rename1($request, $filename, $user, $domain, $dir)
  if (-e $conspace) {   
     if ($ENV{'form.newfilename'}) {     Perform phase 1 processing of the file rename operation.
  $r->print(&checksuffix($fn,$ENV{'form.newfilename'}));  
  $r->print(&exists($uname,$udom,$dir,$ENV{'form.newfilename'}));  Parameters:
        $r->print('<input type=hidden name=newfilename value="'.  
                          $ENV{'form.newfilename'}.  =over 4
                          '"><p>Rename <tt>'.$fn.'</tt> to <tt>'.  
                          $dir.'/'.$ENV{'form.newfilename'}.'</tt>?</p>');  =item  $request   - Apache Request Object [in] The request object for the 
     } else {  current request.
        $r->print('<p>No new filename specified.</p></form>');  
                return;  =item  $filename  - The filename relative to construction space.
   
   =item  $user      - Name of the user making the request.
   
   =item  $domain    - User login domain.
   
   =item  $dir       - Directory specification of the path to the file.
   
   =back
   
   Side effects:
   
   =over 4
   
   =item A new form is displayed prompting for confirmation.  The newfilename
   hidden field of this form is loaded with
   new filename relative to the current directory ($dir).
   
   =back
   
   =cut  
   
   sub Rename1 {
       my ($request, $filename, $user, $domain, $dir) = @_;
       &Debug($request, "Username - ".$user." filename: ".$filename."\n");
       my $conspace = $filename;
   
       my $cancelurl = "/priv/".$filename;
       $cancelurl    =~ s/\/home\///;
       $cancelurl    =~ s/\/public_html//;
       
       if(-e $conspace) {
    if($ENV{'form.newfilename'}) {
       my $newfilename = $ENV{'form.newfilename'};
       if ($newfilename =~ m|^[^\.]+$|) {
    #no extension add on orignal extension
    if ($filename =~ m|/[^\.]*\.([^\.]+)$|) {
       $newfilename.='.'.$1;
    }
     }      }
         } else {      $request->print(&checksuffix($filename, $newfilename));
     $r->print('<p>No such file.</p></form>');      my $return=&exists($user, $domain, $dir, $newfilename);
             return;      $request->print($return);
         }      if ($return =~/^Error:/) {
     } elsif ($ENV{'form.action'} eq 'delete') {    $request->print('<br /><a href="'.$cancelurl.'">Cancel</a>');
  if (-e $conspace) {   return;
             $r->print('<p>Delete <tt>'.$fn.'</tt>?</p>');  
         } else {  
     $r->print('<p>No such file.</p></form>');  
             return;  
         }  
     } elsif ($ENV{'form.action'} eq 'copy') {   
  if (-e $conspace) {  
     if ($ENV{'form.newfilename'}) {  
  $r->print(&checksuffix($fn,$ENV{'form.newfilename'}));  
  $r->print(&exists($uname,$udom,$dir,$ENV{'form.newfilename'}));  
        $r->print('<input type=hidden name=newfilename value="'.  
                          $ENV{'form.newfilename'}.  
                          '"><p>Copy <tt>'.$fn.'</tt> to <tt>'.  
                          $dir.'/'.$ENV{'form.newfilename'}.'</tt>?</p>');  
     } else {  
        $r->print('<p>No new filename specified.</p></form>');  
                return;  
     }      }
         } else {      my $dest=&SimplifyDir($dir,$newfilename);
     $r->print('<p>No such file.</p></form>');      $request->print('<input type="hidden" name="newfilename" value="'.
             return;      $newfilename.
         }      '" /><p>Rename <tt>'.$filename.
     } elsif ($ENV{'form.action'} eq 'newdir') {      '</tt><br /> to <tt>'.
         my $newdir='/home/'.$uname.'/public_html/'.      $dest.'</tt>?</p>');
                    $fn.$ENV{'form.newfilename'};      &CloseForm1($request, $cancelurl);
  if (-e $newdir) {   } else {
             $r->print('<p>Directory exists.</p></form>');      $request->print('<p>No new filename specified</p></form>');
             return;      return;
         }   }
  $r->print('<input type=hidden name=newfilename value="'.      } else {
                   $ENV{'form.newfilename'}.   $request->print('<p> No such File </p> </form>');
                   '"><p>Make new directory <tt>'.   return;
                   $fn.$ENV{'form.newfilename'}.'</tt>?</p>');      }
              
     }  }
     $r->print('<p><input type=submit value=Continue></p></form>');  =pod
     $r->print('<form action="/priv/'.$uname.$fn.  
       '" method="GET"><p><input type=submit value=Cancel></p></form>');  =item Delete1
   
      Performs phase 1 processing of the delete operation.  In phase one
     we just check to be sure the file exists.
   
   Parameters:
   
   =over 4
   
   =item   $request   - Apache Request Object [in] request object for the current
                   request.
   
   =item   $user      - string [in] Name of session user.
   
   
   =item   $filename  - string [in] Name fo the file to be deleted:
                   Filename is the full filesystem path to the file.
   
   =back
   
   =cut
   
   sub Delete1 {
     my ($request, $user,  $filename) = @_;
   
     my $cancelurl = '/priv/'.$filename;
     $cancelurl    =~ s/\/home\///;
     $cancelurl    =~ s/\/public_html//;
     
   
     if( -e $filename) {
       $request->print('<input type="hidden" name="newfilename" value="'.
       $filename.'"/>');
       $request->print('<p> Delete <tt>'.$filename.'</tt>?</p>');
       &CloseForm1($request, $cancelurl);
     } else {
       $request->print('<p> No Such file: <tt>'.$filename.'</tt></p></form>');
     }
 }  }
   
 sub phasetwo {  =pod
     my ($r,$fn,$uname,$udom)=@_;  
   
     &Debug($r, "loncfile - Entering phase 2 for $fn");  =item Copy1($request, $user, $domain, $filename, $newfilename)
   
     $fn=~/(.*)\/([^\/]+)\.(\w+)$/;     Performs phase 1 processing of the construction space copy command.
     my $dir=$1;     Ensure that the source file exists.  Ensure that a destination exists,
     my $main=$2;     also warn if the destination already exists.
     my $suffix=$3;  
   Parameters:
   
   =over 4
   
   =item   $request   - Apache Request Object [in] request object for the current 
                   request.
   
   =item   $user      - string [in]  Name of the user initiating the request.
   
   =item   $domain    - string [in]  Domain the initiating user is logged in as
   
   =item   $dir       - string [in]  Directory path.
   
   =item   $filename  - string [in]  Source filename.
   
   =item   $newfilename-string [in]  Destination filename.
   
   =back
   
   =cut
   
   sub Copy1 {
     my ($request, $user, $domain, $dir, $filename, $newfilename) = @_;
   
     my $cancelurl = "/priv/".$filename;
     $cancelurl    =~ s/\/home\///;
     $cancelurl    =~ s/\/public_html//;
           
   
     if(-e $filename) {
       $request->print(&checksuffix($filename,$newfilename));
       my $return=&exists($user, $domain, $dir, $newfilename);
       $request->print($return);
       if ($return =~/^Error:/) {
    $request->print('<br /><a href="'.$cancelurl.'">Cancel</a>');
    return;
       }
       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
   
   =item NewDir1
    
     Does all phase 1 processing of directory creation:
     Ensures that the user provides a new directory name,
     and that the directory does not already exist.
   
   Parameters:
   
   =over 4
   
   =item   $request  - Apache Request Object [in] - Server request object for the
                  current url.
   
   =item   $username - Name of the user that is requesting the directory creation.
   
   =item   $path     - current directory relative to construction space.
   
   =item   $newdir   - Name of the directory to be created; path relative to the 
                  top level of construction space.
   =back
   
   Side Effects:
   
   =over 4
   
   =item A new form is displayed.  Clicking on the confirmation button
   causes the newdir operation to transition into phase 2.  The hidden field
   "newfilename" is set with the construction space path to the new directory.
   
   
   =back
   
   =cut
   
   
   sub NewDir1
   {
     my ($request, $username, $path, $newdir) = @_;
   
     my $fullpath = '/home/'.$username.'/public_html/'.
       $path.'/'.$newdir;
   
     my $cancelurl = '/priv/'.$username.'/'.$path;
   
     &Debug($request, "Full path is : ".$fullpath);
   
     if(-e $fullpath) {
       $request->print('<p>Directory exists.</p></form>');
     }
     else {
       $request->print('<input type="hidden" name="newfilename" value="'.
       $newdir.'" /><p>Make new directory <tt>'.
       $path."/".$newdir.'</tt>?</p>');
       &CloseForm1($request, $cancelurl);
   
     }
   }
   
   =pod
   
   =item NewFile1
    
     Does all phase 1 processing of file creation:
     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,
     problem, page, or sequence, it then creates a form link to hand the
     actual creation off to the proper handler.
   
   Parameters:
   
   =over 4
   
   =item   $request  - Apache Request Object [in] - Server request object for the
                  current url.
   
   =item   $username - Name of the user that is requesting the directory creation.
   
   =item   $domain   - Name of the domain of the user
   
   =item   $dir      - current absolute diretory
   
   =item   $newfilename
                     - Name of the file to be created; no path information
   =back
   
   Side Effects:
   
   =over 4
   
   =item 2 new forms are displayed.  Clicking on the confirmation button
   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
   button which returns you to the driectory listing you came from
   
   =back
   
   =cut
   
   
   sub NewFile1 {
       my ($request, $user, $domain, $dir, $newfilename) = @_;
   
       &Debug($request, "Dir is : ".$dir);
       &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;
    if ($newfilename !~ /\Q.$extension\E$/) {
       $newfilename.=".$extension";
    }
       }
   
       my $fullpath = $dir.'/'.$newfilename;
   
       &Debug($request, "Full path is : ".$fullpath);
   
       if(-e $fullpath) {
    $request->print('<p>File exists.</p></form>');
       }
       else {
    $request->print('<p>Make new file <tt>'.$newfilename.'</tt>?</p>');
    my $dest=&MakeFinalUrl($request,$fullpath);
    &Debug($request, "Cancel url is: ".$cancelurl);
    &Debug($request, "Dest url is: ".$dest);
    $request->print('</form>');
    $request->print('<form action="'.$dest.
    '" method="GET"><p><input type="submit" value="Continue" /></p></form>');
    $request->print('<form action="'.$cancelurl.
    '" method="GET"><p><input type="submit" value="Cancel" /></p></form>');
       }
   }
   
   =pod
   
   =item phaseone($r, $fn, $uname, $udom)
   
     Peforms phase one processing of the request.  In phase one, error messages
   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
   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 
   performed and reported to the user.
   
    Parameters:
   
   =over 4
   
   =item $r  - request object [in] - The Apache request being executed.
   
   =item $fn = string [in] - The filename being manipulated by the 
                                request.
   
   =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. 
   
   =back
   
   =cut
   
   sub phaseone {
     my ($r,$fn,$uname,$udom)=@_;
     
     $fn=~m:(.*)/([^/]+)\.(\w+)$:;
     my $dir=$1;
     my $main=$2;
     my $suffix=$3;
     
     #  my $conspace=ConstructionPathFromRelative($uname, $fn);
     
     
     $r->print('<form action="/adm/cfile" method="post">'.
       '<input type="hidden" name="filename" value="/~'.$uname.$fn.'" />'.
       '<input type="hidden" name="phase" value="two" />'.
       '<input type="hidden" name="action" value="'.$ENV{'form.action'}.'" />');
     
     if ($ENV{'form.action'} eq 'rename') {
           
     &Debug($r, "loncfile::phase2 dir = $dir main = $main suffix = $suffix");      &Rename1($r, $fn, $uname, $udom, $dir);
       
     } elsif ($ENV{'form.action'} eq 'delete') { 
       
       &Delete1($r, $uname, $fn);
       
     } elsif ($ENV{'form.action'} eq 'copy') { 
       if($ENV{'form.newfilename'}) {
         my $newfilename = $ENV{'form.newfilename'};
         &Copy1($r, $uname, $udom, $dir, $fn, $newfilename);
       }else {
         $r->print('<p>No new filename specified.</p></form>');
       }
     } elsif ($ENV{'form.action'} eq 'newdir') {
       &NewDir1($r, $uname, $dir, $ENV{'form.newfilename'});
     }  elsif ($ENV{'form.action'} eq 'newfile' ||
       $ENV{'form.action'} eq 'newhtmlfile' ||
       $ENV{'form.action'} eq 'newproblemfile') {
       if($ENV{'form.newfilename'}) {
         my $newfilename = $ENV{'form.newfilename'};
         if (!defined($dir)) {
     $fn=~m:(.*)/:;
     $dir=$1;
         }
         &NewFile1($r, $uname, $udom, $dir, $fn, $newfilename);
       }else {
         $r->print('<p>No new filename specified.</p></form>');
       }
     }
   }
   
     my $conspace=$fn;  =pod
   
   =item Rename2($request, $user, $directory, $oldfile, $newfile)
   
   Performs phase 2 processing of a rename reequest.   This is where the
   actual rename is performed.
   
   Parameters
   
   =over 4
   
   =item $request - Apache request object [in] The request being processed.
   
   =item $user  - string [in] The name of the user initiating the request.
   
   =item $directory - string [in] The name of the directory relative to the
                    construction space top level of the renamed file.
   
   =item $oldfile - Name of the file.
   
   =item $newfile - Name of the new file.
   
   =back
   
   Returns:
   
   =over 4
   
   =item 1 Success.
   
   =item 0 Failure.
   
   =cut
   
   sub Rename2 {
   
     my ($request, $user, $directory, $oldfile, $newfile) = @_;
   
     &Debug($request, "Rename2 directory: ".$directory." old file: ".$oldfile.
    " new file ".$newfile."\n");
     &Debug($request, "Target is: ".$directory.'/'.
    $newfile);
   
     if(-e $oldfile) {
         unless(rename($oldfile,
       $directory.'/'.$newfile)) {
     $request->print('<font color="red">Error: '.$!.'</font>');
     return 0;
         } else {}
     } else {
         $request->print("<p> No such file: /home".$user.'/public_html'.
         $oldfile.' </p></form>');
         return 0;
     }
     return 1;
   }
   =pod
   
   =item Delete2($request, $user, $filename)
   
     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
   delete attempt are indicated.
   
   Parameters:
   
   =over 4
   
   =item $request - Apache Request object [in] the request object for the current
                    delete operation.
   
   =item $user    - string [in]  The name of the user initiating the delete
                    request.
   
   =item $filename - string [in] The name of the file, relative to construction
                     space, to delete.
   
   =back
   
   Returns:
     1 - success.
     0 - Failure.
   
   =cut
   
   sub Delete2 {
     my ($request, $user, $filename) = @_;
   
     if(-e $filename) {
       unless(unlink($filename)) {
         $request->print('<font color="red">Error: '.$!.'</font>');
         return 0;
       }
     } else {
       $request->print('<p> No such file. </p></form');
       return 0;
     }
     return 1;
   }
   
   =pod
   
   =item Copy2($request, $username, $dir, $oldfile, $newfile)
   
      Performs phase 2 of a copy.  The file is copied and the status 
      of that copy is reported back to the user.
   
   =over 4
   
   =item $request - Apache request object [in]; the apache request currently
                    being executed.
   
   =item $username - string [in] Name of the user who is requesting the copy.
   
   =item $dir - string [in] Directory path relative to the construction space
                of the destination file.
   
   =item $oldfile - string [in] Name of the source file.
   
   =item $newfile - string [in] Name of the destination file.
   
     &Debug($r, "loncfile::phase2 Full construction space name: $conspace");  
   
     &Debug($r, "loncfie::phase2 action is $ENV{'form.action'}");  =back
   
     if ($ENV{'form.action'} eq 'rename') {  Returns 0 failure, and 0 successs.
  if (-e $conspace) {  
     if ($ENV{'form.newfilename'}) {  =cut
                unless (rename('/home/'.$uname.'/public_html'.$fn,  
           '/home/'.$uname.'/public_html'.$dir.'/'.$ENV{'form.newfilename'})) {  sub Copy2 {
     $r->print('<font color=red>Error: '.$!.'</font>');      my ($request, $username, $dir, $oldfile, $newfile) = @_;
                }      &Debug($request ,"Will try to copy $oldfile to $newfile");
             }      if(-e $oldfile) {
         } else {   unless (copy($oldfile, $newfile)) {
     $r->print('<p>No such file.</form>');      $request->print('<font color="red"> copy Error: '.$!.'</font>');
             return;      return 0;
         }   } else {
       unless (chmod(0660, $newfile)) {
    $request->print('<font color="red"> chmod error: '.$!.'</font>');
    return 0;
       }
       return 1;
    }
       } else {
    $request->print('<p> No such file </p>');
    return 0;
       }
       return 1;
   }
   =pod
   
   =item NewDir2($request, $user, $newdirectory)
   
    Performs phase 2 processing of directory creation.  This involves creating the directory and
    reporting the results of that creation to the user.
   
   Parameters:
   =over 4
   
   =item $request  - Apache request object [in].  Object representing the current HTTP request.
   
   =item $user - string [in] The name of the user that is initiating the request.
   
   =item $newdirectory - string [in] The full path of the directory being created.
   
   =back
   
   Returns 0 - failure 1 - success.
   
   =cut
   
   sub NewDir2 {
     my ($request, $user, $newdirectory) = @_;
     
     unless(mkdir($newdirectory, 02770)) {
       $request->print('<font color="red">Error: '.$!.'</font>');
       return 0;
     }
     unless(chmod(02770, ($newdirectory))) {
         $request->print('<font color="red"> Error: '.$!.'</font>');
         return 0;
     }
     return 1;
   }
   
   =pod
   
   =item phasetwo($r, $fn, $uname, $udom)
   
      Controls the phase 2 processing of file management
      requests for construction space.  In phase one, the user
      was asked to confirm the operation.  In phase 2, the operation
      is performed and the result is shown.
   
     The strategy is to break out the processing into specific action processors
     named action2 where action is the requested action and the 2 denotes 
     phase 2 processing.
   
   Parameters:
   
   =over 4
   
   =item  $r     - Apache Request object [in] The request object for this httpd
              transaction.
   
   =item  $fn    - string [in]  A filename indicating the object that is being
              manipulated.
   
   =item  $uname - string [in] The name of the user initiating the file management
              request.
   
   =item  $udom  - string  [in] The login domain of the user initiating the
              file management request.
   =back
   
   =cut
   
   sub phasetwo {
       my ($r,$fn,$uname,$udom)=@_;
       
       &Debug($r, "loncfile - Entering phase 2 for $fn");
       
       # Break down the file into it's component pieces.
       
       $fn=~/(.*)\/([^\/]+)\.(\w+)$/;
       my $dir=$1; # Directory path
       my $main=$2; # Filename.
       my $suffix=$3; # Extension.
       
       my $dest;                   # On success this is where we'll go.
       
       &Debug($r, 
      "loncfile::phase2 dir = $dir main = $main suffix = $suffix");
       &Debug($r,
      "    newfilename = ".$ENV{'form.newfilename'});
   
       my $conspace=$fn;
       
       &Debug($r, 
      "loncfile::phase2 Full construction space name: $conspace");
       
       &Debug($r, 
      "loncfie::phase2 action is $ENV{'form.action'}");
       
       # Select the appropriate processing sub.
       
       if ($ENV{'form.action'} eq 'rename') { # Rename.
    if($ENV{'form.newfilename'}) {
       if(!&Rename2($r, $uname, $dir, $fn, $ENV{'form.newfilename'})) {
    return;
       }
       # Prepend the directory to the new name to form the basis of the
       # url of the new resource.
       #
       $dest = $dir."/".$ENV{'form.newfilename'};
    }
     } elsif ($ENV{'form.action'} eq 'delete') {       } elsif ($ENV{'form.action'} eq 'delete') { 
  if (-e $conspace) {   if(!&Delete2($r, $uname, $ENV{'form.newfilename'})) {
             unless (unlink('/home/'.$uname.'/public_html'.$fn)) {      return ;
        $r->print('<font color=red>Error: '.$!.'</font>');   }
             }   # Once a resource is deleted, we just list the directory that
         } else {   # previously held it.
     $r->print('<p>No such file.</form>');   #
             return;   $dest = $dir."/."; # Parent dir.
         }  
     } elsif ($ENV{'form.action'} eq 'copy') {       } elsif ($ENV{'form.action'} eq 'copy') { 
  if (-e $conspace) {   if($ENV{'form.newfilename'}) {
     if ($ENV{'form.newfilename'}) {      if(!&Copy2($r, $uname, $dir, $fn, $ENV{'form.newfilename'})) {
                unless (copy('/home/'.$uname.'/public_html'.$fn,   return
            '/home/'.$uname.'/public_html'.$dir.'/'.$ENV{'form.newfilename'})) {   }
           $r->print('<font color=red>Error: '.$!.'</font>');      $dest = $ENV{'form.newfilename'};
                }       
     } else {   } else {
        $r->print('<p>No new filename specified.</form>');      $r->print('<p>No New filename specified</p></form>');
                return;      return;
     }   }
         } else {  
     $r->print('<p>No such file.</form>');  
             return;  
         }  
     } elsif ($ENV{'form.action'} eq 'newdir') {      } elsif ($ENV{'form.action'} eq 'newdir') {
    #
    # 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'};          my $newdir= $fn.$ENV{'form.newfilename'};
    if(!&NewDir2($r, $uname, $newdir)) {
       return;
    }
    $dest = $newdir."/"
       }
       #
       #  Substitute for priv for the first home in $dir to get our
       # construction space path.
       #
       $dest=&MakeFinalUrl($r,$dest);
   
  &Debug($r, "loncfile::phasetwo - new directory name: $newdir");      $r->print('<h3><a href="'.$dest.'">Done</a></h3>');
   }
   
         unless (mkdir($newdir,0770)) {  sub MakeFinalUrl {
     $r->print('<font color=red>Error: '.$!.'</font>');      my($r,$dest)=@_;
     &Debug($r, "loncfile::phasetwo - mkdir failed $!");      &Debug($r, "Final url is: $dest");
         }      $dest =~ s|/home/|/priv/|;
  &Debug($r, "Done button: uname = $uname, dir = $dir, fn = $fn");      $dest =~ s|/public_html||;
  my $url = '/priv/'.$uname.$newdir.'/';  
  &Debug($r, "URL[1] = ".$url);      my $base = &File::Basename::basename($dest);
  $url =~ s/\/home\/$uname\/public_html//o;      my $dpath= &File::Basename::dirname($dest);
         &Debug($r, "URL = ".$url);      if ($base eq '.') { $base=''; }
       $dest = &HTML::Entities::encode($dpath.'/'.$base);
   
         $r->print('<h3><a href="'.$url.'">Done</a></h3>');      &Debug($r, "Final url after rewrite: $dest");
         return;      return $dest;
     }  
     $r->print('<h3><a href="/priv/'.$uname.$dir.'/">Done</a></h3>');  
 }  }
   
 sub handler {  sub handler {
Line 288  sub handler { Line 1181  sub handler {
   
   
   &Debug($r, "loncfile.pm - handler entered");    &Debug($r, "loncfile.pm - handler entered");
     &Debug($r, " filename: ".$ENV{'form.filename'});
     &Debug($r, " newfilename: ".$ENV{'form.newfilename'});
   
   my $fn;    my $fn;
   
   if ($ENV{'form.filename'}) {    if ($ENV{'form.filename'}) {
       $fn=$ENV{'form.filename'};        $fn=&Apache::lonnet::unescape($ENV{'form.filename'});
       &Debug($r, "loncfile::handler - raw url: $fn");        &Debug($r, "loncfile::handler - raw url: $fn");
 #      $fn=~s/^http\:\/\/[^\/]+\/\~(\w+)/\/home\/$1\/public_html/;  #      $fn=~s/^http\:\/\/[^\/]+\/\~(\w+)/\/home\/$1\/public_html/;
 #      $fn=~s/^http\:\/\/[^\/]+//;  #      $fn=~s/^http\:\/\/[^\/]+//;
Line 338  sub handler { Line 1233  sub handler {
   $r->print('<html><head><title>LON-CAPA Construction Space</title></head>');    $r->print('<html><head><title>LON-CAPA Construction Space</title></head>');
   
   $r->print(    $r->print(
    '<body bgcolor="#FFFFFF"><img align=right src=/adm/lonIcons/lonlogos.gif>');     '<body bgcolor="#FFFFFF"><img align="right" src="/adm/lonIcons/lonlogos.gif" />');
   
       
   $r->print('<h1>Construction Space <tt>'.$fn.'</tt></h1>');    $r->print('<h1>Construction Space <tt>'.$fn.'</tt></h1>');
       
   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('<h3><font color="red">Co-Author: '.$uname.' at '.$udom.
                '</font></h3>');                 '</font></h3>');
   }    }
   
Line 359  sub handler { Line 1254  sub handler {
       $r->print('<h3>New Directory</h3>');        $r->print('<h3>New Directory</h3>');
   } elsif ($ENV{'form.action'} eq 'copy') {    } elsif ($ENV{'form.action'} eq 'copy') {
       $r->print('<h3>Copy</h3>');        $r->print('<h3>Copy</h3>');
     } elsif ($ENV{'form.action'} eq 'newfile' ||
      $ENV{'form.action'} eq 'newhtmlfile' ||
      $ENV{'form.action'} eq 'newproblemfile') {
         $r->print('<h3>New Resource</h3>');
   } else {    } else {
      $r->print('<p>Unknown Action</body></html>');       $r->print('<p>Unknown Action</p></body></html>');
      return OK;         return OK;  
   }    }
   if ($ENV{'form.phase'} eq 'two') {    if ($ENV{'form.phase'} eq 'two') {

Removed from v.1.10  
changed lines
  Added in v.1.24


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