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

version 1.128, 2024/05/13 13:55:50 version 1.129, 2024/05/21 02:57:16
Line 822  sub Decompress1 { Line 822  sub Decompress1 {
 sub Archive1 {  sub Archive1 {
     my ($request,$fn) = @_;      my ($request,$fn) = @_;
     my @posstypes = qw(problem library sty sequence page task rights meta xml html xhtml htm xhtm css js tex txt gif jpg jpeg png svg other);      my @posstypes = qw(problem library sty sequence page task rights meta xml html xhtml htm xhtm css js tex txt gif jpg jpeg png svg other);
     my (%location_of,%default,$compstyle);      my (%location_of,%defaults);
     foreach my $program ('tar','gzip','bzip2','xz','zip') {      my ($compstyle,$canarchive,$cancompress,$numformat,$numcompress,$defext) =
         foreach my $dir ('/bin/','/usr/bin/','/usr/local/bin/','/sbin/',          &archive_tools(\%location_of,\%defaults);
                          '/usr/sbin/') {  
             if (-x $dir.$program) {  
                 $location_of{$program} = $dir.$program;  
                 last;  
             }  
         }  
     }  
     my (%defaults,$cancompress,$canarchive);  
     if (exists($location_of{'tar'})) {  
         $default{'tar'} = ' checked="checked"';  
         $canarchive = 1;  
         $compstyle = 'block';  
     } elsif (exists($location_of{'zip'})) {  
         $default{'zip'} = ' checked="checked"';  
         $canarchive = 1;  
         $compstyle = 'none';  
     }  
     foreach my $compress ('gzip','bzip2','xz') {  
         if (exists($location_of{$compress})) {  
             $default{$compress} = ' checked="checked"';  
             $cancompress = 1;  
             last;  
         }  
     }  
     if (!$canarchive) {      if (!$canarchive) {
         $request->print('<p class="LC_error">'.          $request->print('<p class="LC_error">'.
                         &mt('This LON-CAPA instance does not seem to have either tar or zip installed.').'</p>'.                          &mt('This LON-CAPA instance does not seem to have either tar or zip installed.').'</p>'."\n".
                         '<span class="LC_warning">'.                          '<span class="LC_warning">'.
                         &mt('At least one of the two is needed in order to be able to create an archive file for: [_1].',                          &mt('At least one of the two is needed in order to be able to create an archive file for: [_1].',
                             &display($fn)).                              &display($fn))."\n".
                         '</span></form>');                          '</span></form>');
     } elsif (-e $fn) {      } elsif (-e $fn) {
         $request->print(&Apache::lonhtmlcommon::start_pick_box().          $request->print('<input type="hidden" name="adload" value="" />'."\n".
                           &Apache::lonhtmlcommon::start_pick_box().
                         &Apache::lonhtmlcommon::row_title(&mt('Directory')).                          &Apache::lonhtmlcommon::row_title(&mt('Directory')).
                         &display($fn).                          &display($fn).
                         &Apache::lonhtmlcommon::row_closure().                          &Apache::lonhtmlcommon::row_closure().
Line 909  sub Archive1 { Line 886  sub Archive1 {
             if (exists($location_of{$possfmt})) {              if (exists($location_of{$possfmt})) {
                 $request->print('<span class="LC_nobreak">'.                  $request->print('<span class="LC_nobreak">'.
                                 '<label><input type="radio" name="format" value="'.$possfmt.'"'.                                  '<label><input type="radio" name="format" value="'.$possfmt.'"'.
                                 $default{$possfmt}.' onclick="toggleCompression(this.form);" /> '.                                  $defaults{$possfmt}.' onclick="toggleCompression(this.form);" /> '.
                                 $possfmt.'</label></span>&nbsp;&nbsp; ');                                  $possfmt.'</label></span>&nbsp;&nbsp; ');
             }              }
         }          }
Line 921  sub Archive1 { Line 898  sub Archive1 {
             foreach my $compress ('gzip','bzip2','xz') {              foreach my $compress ('gzip','bzip2','xz') {
                 if (exists($location_of{$compress})) {                  if (exists($location_of{$compress})) {
                     $request->print('<label><input type="radio" name="compress" value="'.$compress.'"'.                      $request->print('<label><input type="radio" name="compress" value="'.$compress.'"'.
                                     $default{$compress}.'  />'.$compress.'</label>&nbsp;&nbsp;');                                      $defaults{$compress}.' onclick="setArchiveExt(this.form);"  />'.
                                       $compress.'</label>&nbsp;&nbsp;');
                 }                  }
             }              }
         } else {          } else {
Line 929  sub Archive1 { Line 907  sub Archive1 {
                             &mt('This LON-CAPA instance does not seem to have gzip, bzip2 or xz installed.').                              &mt('This LON-CAPA instance does not seem to have gzip, bzip2 or xz installed.').
                             '<br />'.&mt('No compression will be used.').'</span>');                              '<br />'.&mt('No compression will be used.').'</span>');
         }          }
         $request->print('</fieldset>'.           $request->print('</fieldset>'."\n".
                           '<fieldset style="display:none" id="archive_saveas">'.
                           '<legend>'.&mt('Filename to download').'</legend>'.
                           '<table style="border-spacing:0"><tr><td style="padding:0;">'.&mt('Name').'<br />'."\n".
                           '<input type="text" name="archivefname" value="" size="8" /></td><td style="padding:0;">'.
                           &mt('Extension').'<br />'."\n".
                           '<input type="text" name="archiveext" id="archiveext" value="" size="4" readonly="readonly" />'.
                           '</td></tr></table></fieldset>'."\n".
                         &Apache::lonhtmlcommon::row_closure(1).                          &Apache::lonhtmlcommon::row_closure(1).
                         &Apache::lonhtmlcommon::end_pick_box()                          &Apache::lonhtmlcommon::end_pick_box().'<br />'."\n"
         );          );
         &CloseForm1($request, $fn);          &CloseForm1($request, $fn);
     } else {      } else {
Line 941  sub Archive1 { Line 926  sub Archive1 {
                        .'</p></form>'                         .'</p></form>'
         );          );
     }      }
       return;
   }
   
   sub archive_tools {
       my ($location_of,$defaults) = @_;
       my ($compstyle,$canarchive,$cancompress,$numformat,$numcompress,$defext);
       ($numformat,$numcompress) = (0,0);
       if ((ref($location_of) eq 'HASH') && (ref($defaults) eq 'HASH')) {
           foreach my $program ('tar','gzip','bzip2','xz','zip') {
               foreach my $dir ('/bin/','/usr/bin/','/usr/local/bin/','/sbin/',
                                '/usr/sbin/') {
                   if (-x $dir.$program) {
                       $location_of->{$program} = $dir.$program;
                       last;
                   }
               }
           }
           foreach my $format ('tar','zip') {
               if (exists($location_of->{$format})) {
                   unless ($canarchive) {
                       $defext = $format;
                       $defaults->{$format} = ' checked="checked"';
                       if ($format eq 'tar') {
                           $compstyle = 'block';
                       } else {
                           $compstyle = 'none';
                       }
                   }
                   $canarchive = 1;
                   $numformat ++;
               }
           }
           foreach my $compress ('gzip','bzip2','xz') {
               if (exists($location_of->{$compress})) {
                   $numcompress ++;
                   unless ($cancompress) {
                       if ($defext eq 'tar') {
                           if ($compress eq 'gzip') {
                               $defext .= '.gz';
                           } elsif ($compress eq 'bzip2') {
                               $defext .= '.bz2';
                           } else {
                               $defext .= ".$compress";
                           }
                       }
                       $defaults->{$compress} = ' checked="checked"';
                       $cancompress = 1;
                   }
               }
           }
       }
       if (wantarray) {
           return ($compstyle,$canarchive,$cancompress,$numformat,$numcompress,$defext);
       } else {
           return $defext;
       }
   }
   
   sub archive_in_progress {
       my ($earlyout,$idnum);
       if ($env{'cgi.author.archive'} =~ /^(\d+)_\d+_\d+$/) {
           my $timestamp = $1;
           $idnum = $env{'cgi.author.archive'};
           if (exists($env{'cgi.'.$idnum.'.archive'})) {
               my $hashref = &Apache::lonnet::thaw_unescape($env{'cgi.'.$idnum.'.archive'});
               my $lonprtdir = $Apache::lonnet::perlvar{'lonPrtDir'};
               if (-e $lonprtdir.'/'.$env{'user.name'}.'_'.$env{'user.domain'}.'_archive_'.$idnum.'.txt') {
                   $earlyout = $timestamp;
               } elsif (ref($hashref) eq 'HASH') {
                   my $suffix = $hashref->{'extension'};
                   if (-e $lonprtdir.'/'.$env{'user.name'}.'_'.$env{'user.domain'}.'_archive_'.$idnum.$suffix) {
                       $earlyout = $timestamp;
                   }
               }
               unless ($earlyout) {
                   &Apache::lonnet::delenv('cgi.'.$idnum.'.archive');
                   &Apache::lonnet::delenv('cgi.author.archive');
               }
           } else {
               &Apache::lonnet::delenv('cgi.author.archive');
           }
       }
       return ($earlyout,$idnum);
   }
   
   sub cancel_archive_form {
       my ($r,$title,$fname,$earlyout,$idnum) = @_;
       $r->print('<h2>'.$title.'</h2>'."\n".
                 '<form action="/adm/cfile" method="post" onsubmit="return confirmation(this);">'."\n".
                 '<input type="hidden" name="filename" value="'.$fname.'" />'."\n".
                 '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n".
                 '<p>'.&mt('Each author may only have one archive request in process at a time.')."\n".'<ul>'.
                 '<li>'.&mt('An incomplete archive request was begun: [_1].',
                            &Apache::lonlocal::locallocaltime($earlyout)).
                 '</li>'."\n".
                 '<li>'.&mt('An archive request is considered complete when the archive file has been successfully downloaded.').'</li>'."\n".
                 '<li>'.
                 &mt('To submit a new archive request, either wait for the existing request (e.g., in another tab/window) to complete, or remove it.').'</li>'."\n".
                 '</ul></p>'."\n".
                 '<p><span class="LC_nobreak">'.&mt('Remove existing archive request?').'&nbsp;'."\n".
                 '<label><input type="radio" name="remove_archive_request" value="'.$idnum.'" />'.&mt('Yes').'</label>'.
                 ('&nbsp;'x2)."\n".
                 '<label><input type="radio" name="remove_archive_request" value="" checked="checked" />'.&mt('No').'</label></span></p>'."\n".
                 '<br />');
 }  }
   
 =pod  =pod
Line 1118  sub phaseone { Line 1207  sub phaseone {
                   '</a></p>');                    '</a></p>');
         return;          return;
     }      }
     $r->print('<form action="/adm/cfile" method="post" name="phaseone">'.      $r->print('<form action="/adm/cfile" method="post" name="phaseone">'."\n".
       '<input type="hidden" name="qualifiedfilename" value="'.$fn.'" />'.        '<input type="hidden" name="qualifiedfilename" value="'.$fn.'" />'."\n".
       '<input type="hidden" name="phase" value="two" />'.        '<input type="hidden" name="phase" value="two" />'."\n".
       '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />');        '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n");
   
     if ($env{'form.action'} eq 'newfile' ||      if ($env{'form.action'} eq 'newfile' ||
         $env{'form.action'} eq 'newhtmlfile' ||          $env{'form.action'} eq 'newhtmlfile' ||
Line 1437  sub decompress2 { Line 1526  sub decompress2 {
 }  }
   
 sub Archive2 {  sub Archive2 {
     my ($r,$name,$udom,$fn,$identifier) = @_;      my ($r,$uname,$udom,$fn,$identifier) = @_;
     my %options = (      my %options = (
                     dir => $fn,                      dir => $fn,
                       uname => $uname,
                       udom => $udom,
                   );                    );
       if ($env{'form.adload'}) {
           $options{'adload'} = 1;
           if ($env{'form.archivefname'} ne '') {
               $env{'form.archivefname'} =~ s{\.+}{.}g;
               $options{'fname'} = $env{'form.archivefname'};
           }
           if ($env{'form.archiveext'} ne '') {
               $options{'extension'} = $env{'form.archiveext'};
           }
       }
     my @filetypes = qw(problem library sty sequence page task rights meta xml html xhtml htm xhtm css js tex txt gif jpg jpeg png svg other);      my @filetypes = qw(problem library sty sequence page task rights meta xml html xhtml htm xhtm css js tex txt gif jpg jpeg png svg other);
     my (@include,%oktypes);      my (@include,%oktypes);
     map { $oktypes{$_} = 1; } @filetypes;      map { $oktypes{$_} = 1; } @filetypes;
Line 1473  sub Archive2 { Line 1574  sub Archive2 {
     }      }
     my $key = 'cgi.'.$identifier.'.archive';      my $key = 'cgi.'.$identifier.'.archive';
     my $storestring = &Apache::lonnet::freeze_escape(\%options);      my $storestring = &Apache::lonnet::freeze_escape(\%options);
     &Apache::lonnet::appenv({$key => $storestring});      &Apache::lonnet::appenv({$key => $storestring,
                                'cgi.author.archive' => $identifier});
     return 1;      return 1;
 }  }
   
   sub Archive3 {
       my ($hashref) = @_;
       if (ref($hashref) eq 'HASH') {
           if (($hashref->{'uname'} eq $env{'user.name'}) &&
               ($hashref->{'udom'} eq $env{'user.domain'}) &&
               ($env{'environment.canarchive'}) &&
               ($env{'form.delarchive'})) {
               my $filesdest = $Apache::lonnet::perlvar{'lonPrtDir'}.'/'.$env{'user.name'}.'_'.$env{'user.domain'}.'_archive_'.$env{'form.delarchive'};
               if (-e $filesdest) {
                   my $size = (stat($filesdest))[7];
                   if (unlink($filesdest)) {
                       my ($identifier,$suffix) = split(/\./,$env{'form.delarchive'},2);
                       if (($identifier) && (exists($env{'cgi.'.$identifier.'.archive'}))) {
                           my $delres = &Apache::lonnet::delenv('cgi.'.$identifier.'.archive');
                           if (($delres eq 'ok') &&
                               (exists($env{'cgi.author.archive'})) &&
                               ($env{'cgi.author.archive'} eq $identifier)) {
                               &Apache::lonnet::authorarchivelog($hashref,$size,$filesdest,'delete');
                               &Apache::lonnet::delenv('cgi.author.archive');
                           }
                       }
                       return 1;
                   }
               }
           }
       }
       return 0;
   }
   
 =pod  =pod
   
 =item phasetwo($r, $fn, $uname, $udom,$identifier)  =item phasetwo($r, $fn, $uname, $udom,$identifier)
Line 1624  sub handler { Line 1755  sub handler {
 #  #
 # Determine the root filename  # Determine the root filename
 # This could come in as "filename", which actually is a URL, or  # This could come in as "filename", which actually is a URL, or
 # as "qualifiedfilename", which is indeed a real filename in filesystem  # as "qualifiedfilename", which is indeed a real filename in filesystem,
   # or in value of decompress form element, or need to be extracted
   # from %env from hashref retrieved for cgi.<id>.archive key, where id
   # is a unique cgi_id created when an Author creates an archive of
   # Authoring Space for download.
 #  #
     my $fn;      my ($fn,$archiveref);
   
     if ($env{'form.filename'}) {      if ($env{'form.filename'}) {
  &Debug($r, "test: $env{'form.filename'}");   &Debug($r, "test: $env{'form.filename'}");
  $fn=&unescape($env{'form.filename'});   $fn=&unescape($env{'form.filename'});
  $fn=&URLToPath($fn);   $fn=&URLToPath($fn);
       } elsif ($env{'form.delarchive'}) {
           my ($delarchive,$suffix) = split(/\./,$env{'form.delarchive'});
           if (($delarchive) && (exists($env{'cgi.'.$delarchive.'.archive'}))) {
               $archiveref = &Apache::lonnet::thaw_unescape($env{'cgi.'.$delarchive.'.archive'});
               if (ref($archiveref) eq 'HASH') {
                   $fn = $archiveref->{'dir'};
               }
           }
     } elsif($ENV{'QUERY_STRING'} && $env{'form.phase'} ne 'two') {      } elsif($ENV{'QUERY_STRING'} && $env{'form.phase'} ne 'two') {
  #Just hijack the script only the first time around to inject the   #Just hijack the script only the first time around to inject the
  #correct information for further processing   #correct information for further processing
Line 1666  sub handler { Line 1809  sub handler {
        $r->filename);         $r->filename);
  return HTTP_NOT_ACCEPTABLE;   return HTTP_NOT_ACCEPTABLE;
     }      }
       if (($env{'form.delarchive'}) &&
           ($env{'environment.canarchive'})) {
           &Apache::loncommon::content_type($r,'text/plain');
           $r->send_http_header;
           $r->print(&Archive3($archiveref));
           return OK;
       }
   
     &Apache::loncommon::content_type($r,'text/html');      &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;      $r->send_http_header;
   
     my ($js,$identifier);  # Declarations for items used for directory archive requests
       my ($js,$identifier,$defext,$archive_earlyout,$archive_idnum);
     my $args = {};      my $args = {};
   
     if (($env{'form.action'} eq 'newdir') && ($env{'form.phase'} eq 'two') &&       if (($env{'form.action'} eq 'newdir') && ($env{'form.phase'} eq 'two') && 
Line 1691  function writeDone() { Line 1841  function writeDone() {
 ENDJS  ENDJS
         $args->{'add_entries'} = { onload => "writeDone()" };          $args->{'add_entries'} = { onload => "writeDone()" };
     } elsif (($env{'form.action'} eq 'archive') &&      } elsif (($env{'form.action'} eq 'archive') &&
              ($env{'environment.authorarchive'})) {                ($env{'environment.canarchive'})) {
         if ($env{'form.phase'} eq 'two') {  # Check if author already has an archive request in process
             $identifier = &Apache::loncommon::get_cgi_id();          ($archive_earlyout,$archive_idnum) = &archive_in_progress();
             $args->{'redirect'} = [0,"/cgi-bin/archive.pl?$identifier"];  # Check if archive request was in process which author wishes to terminate
         } else {          if ($env{'form.remove_archive_request'}) {
             my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript();              if ($env{'form.remove_archive_request'} eq $archive_idnum) {
                   if (exists($env{'cgi.'.$archive_idnum.'.archive'})) {
                       my $archiveref = &Apache::lonnet::thaw_unescape($env{'cgi.'.$archive_idnum.'.archive'});
                       if (ref($archiveref) eq 'HASH') {
                           $env{'form.delarchive'} = $archive_idnum.$archiveref->{'extension'};
                           if (&Archive3($archiveref)) {
                               ($archive_earlyout,$archive_idnum) = &archive_in_progress();
                           }
                           delete($env{'form.delarchive'});
                       }
                   }
               }
           }
           if ($archive_earlyout) {
               my $conftext =
                   &mt('Removing an existing request will terminate an active download of the archive file.');
               &js_escape(\$conftext);
             $js = <<"ENDJS";              $js = <<"ENDJS";
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
   function confirmation(form) {
       if (form.remove_archive_request.length) {
           for (var i=0; i<form.remove_archive_request.length; i++) {
               if (form.remove_archive_request[i].checked) {
                   if (form.remove_archive_request[i].value == '$archive_idnum') {
                       if (!confirm('$conftext')) {
                           return false;
                       }
                   }
               }
           }
       }
       return true;
   }
   // ]]>
   </script>
   
   ENDJS
           } else {
               if ($env{'form.phase'} eq 'two') {
                   $identifier = &Apache::loncommon::get_cgi_id();
                   $args->{'redirect'} = [0.1,"/cgi-bin/archive.pl?$identifier"];
               } else {
                   my (%location_of,%defaults);
                   $defext = &archive_tools(\%location_of,\%defaults);
                   my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript();
                   $js = <<"ENDJS";
   <script type="text/javascript">
   // <![CDATA[
 function toggleCompression(form) {  function toggleCompression(form) {
     if (document.getElementById('tar_compression')) {      if (document.getElementById('tar_compression')) {
         if (form.format.length > 1) {          if (form.format.length > 1) {
Line 1715  function toggleCompression(form) { Line 1910  function toggleCompression(form) {
             }              }
         }          }
     }      }
       setArchiveExt(form);
     return;      return;
 }  }
   
   function setArchiveExt(form) {
       var newfmt;
       var newcomp;
       var newdef;
       if (document.getElementById('archiveext')) {
           if (form.format.length) {
               for (var i=0; i<form.format.length; i++) {
                   if (form.format[i].checked) {
                       newfmt = form.format[i].value;
                       break;
                   }
               }
           } else {
               newfmt = form.format[0];
           }
           if (newfmt == 'tar') {
               if (document.getElementById('tar_compression')) {
                   if (form.compress.length) {
                       for (var i=0; i<form.compress.length; i++) {
                           if (form.compress[i].checked) {
                               newcomp = form.compress[i].value;
                               break;
                           }
                       }
                   } else {
                       newcomp = form.compress[0];
                   }
               }
               if (newcomp == 'gzip') {
                   newdef = newfmt+'.gz';
               } else if (newcomp == 'bzip2') {
                   newdef = newfmt+'.bz2';
               } else if (newcomp == 'xz') {
                   newdef = newfmt+'.'+newcomp;
               } else {
                   newdef = newfmt;
               }
           } else if (newfmt == 'zip') {
               newdef = newfmt;
           }
           if ((newdef == '') || (newdef == undefined) || (newdef == null)) {
               newdef = '.$defext';
           }
           document.getElementById('archiveext').value = newdef;
       }
   }
   
 function resetForm() {  function resetForm() {
     if (document.phaseone.filetype.length) {      if (document.phaseone.filetype.length) {
         for (var i=0; i<document.phaseone.filetype.length; i++) {          for (var i=0; i<document.phaseone.filetype.length; i++) {
Line 1746  function resetForm() { Line 1989  function resetForm() {
         }          }
     }      }
     document.phaseone.recurse.checked = false;      document.phaseone.recurse.checked = false;
       var a = document.createElement('a');
       var vis;
       if (typeof a.download != "undefined") {
           document.phaseone.adload.value = '1';
           if (document.getElementById('archive_saveas')) {
               document.getElementById('archive_saveas').style.display = 'block';
               vis = '1';
           }
       }
       if (vis == '1') {
           if (document.getElementById('archiveext')) {
               document.getElementById('archiveext').value='.$defext';
           }
       } else {
           if (document.getElementById('archive_saveas')) {
               document.getElementById('archive_saveas').style.display = 'none';
           }
           if (document.getElementById('archiveext')) {
               document.getElementById('archiveext').value='';
           }
       }
 }  }
   
 $check_uncheck_js  $check_uncheck_js
Line 1754  $check_uncheck_js Line 2018  $check_uncheck_js
 </script>  </script>
   
 ENDJS  ENDJS
             $args->{'add_entries'} = { onload => "resetForm()" };                   $args->{'add_entries'} = { onload => "resetForm()" };
               }
         }          }
     }      }
     my $londocroot = $r->dir_config('lonDocRoot');      my $londocroot = $r->dir_config('lonDocRoot');
Line 1854  ENDJS Line 2119  ENDJS
                 return OK;                   return OK; 
             }              }
         } elsif ($env{'form.action'} eq 'archive') {          } elsif ($env{'form.action'} eq 'archive') {
             unless ($env{'environment.authorarchive'}) {              if ($env{'environment.canarchive'}) {
                   if ($archive_earlyout) {
                       my $fname = &url($fn);
                       my $title = $action{$env{'form.action'}};
                       &cancel_archive_form($r,$title,$fname,$archive_earlyout,$archive_idnum);
                       &CloseForm1($r,$fn);
                       $r->print(&Apache::loncommon::end_page());
                       return OK;
                   }
               } else {
                 $r->print('<p>'.&mt('Location').': '.&display($fn).'</p>'."\n".                  $r->print('<p>'.&mt('Location').': '.&display($fn).'</p>'."\n".
                           '<p class="LC_error">'.                            '<p class="LC_error">'.
                           &mt('You do not have permission to export to an archive file in this Authoring Space').                            &mt('You do not have permission to export to an archive file in this Authoring Space').
Line 1863  ENDJS Line 2137  ENDJS
                 return OK;                  return OK;
             }              }
         }          }
         $r->print('<h2>'.$action{$env{'form.action'}}.'</h2>');          $r->print('<h2>'.$action{$env{'form.action'}}.'</h2>'."\n");
     } else {      } else {
         $r->print('<p class="LC_error">'          $r->print('<p class="LC_error">'
                  .&mt('Unknown Action: [_1]',$env{'form.action'})                   .&mt('Unknown Action: [_1]',$env{'form.action'})

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


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