Diff for /loncom/auth/lonroles.pm between versions 1.309 and 1.313

version 1.309, 2014/12/14 21:47:48 version 1.313, 2016/04/02 04:31:33
Line 140  use Apache::lonnavdisplay(); Line 140  use Apache::lonnavdisplay();
 use Apache::loncoursequeueadmin;  use Apache::loncoursequeueadmin;
 use Apache::longroup;  use Apache::longroup;
 use Apache::lonrss;  use Apache::lonrss;
   use Apache::lonplacementtest;
 use GDBM_File;  use GDBM_File;
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
 use HTML::Entities;  use HTML::Entities;
Line 286  sub handler { Line 287  sub handler {
     &Apache::lonnet::put('email_status',\%temp);      &Apache::lonnet::put('email_status',\%temp);
     &Apache::lonnet::delenv('user.state.'.$env{'request.course.id'});      &Apache::lonnet::delenv('user.state.'.$env{'request.course.id'});
  }   }
  &Apache::lonnet::appenv({"request.course.id"   => '',   &Apache::lonnet::appenv({"request.course.id"           => '',
  "request.course.fn"   => '',   "request.course.fn"           => '',
  "request.course.uri"  => '',   "request.course.uri"          => '',
  "request.course.sec"  => '',   "request.course.sec"          => '',
                                  "request.course.tied" => '',                                   "request.course.tied"         => '',
  "request.role"        => 'cm',                                   "request.course.timechecked"  => '',
                                  "request.role.adv"    => $env{'user.adv'},   "request.role"                => 'cm',
  "request.role.domain" => $env{'user.domain'}});                                   "request.role.adv"            => $env{'user.adv'},
    "request.role.domain"         => $env{'user.domain'}});
 # Check if user is a DC trying to enter a course or author space and needs privs to be created  # Check if user is a DC trying to enter a course or author space and needs privs to be created
         if ($numdc > 0) {          if ($numdc > 0) {
             foreach my $envkey (keys(%env)) {              foreach my $envkey (keys(%env)) {
Line 382  sub handler { Line 384  sub handler {
                             my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired');                              my %curr_reqd_hash = &Apache::lonnet::userenvironment($cdom,$cnum,'internal.releaserequired');
                             if ($curr_reqd_hash{'internal.releaserequired'} ne '') {                              if ($curr_reqd_hash{'internal.releaserequired'} ne '') {
                                 my ($switchserver,$switchwarning) =                                  my ($switchserver,$switchwarning) =
                                     &check_release_required($loncaparev,$cdom.'_'.$cnum,$trolecode,$curr_reqd_hash{'internal.releaserequired'});                                      &Apache::loncommon::check_release_required($loncaparev,$cdom.'_'.$cnum,$trolecode,
                                                                                  $curr_reqd_hash{'internal.releaserequired'});
                                 if ($switchwarning ne '' || $switchserver ne '') {                                  if ($switchwarning ne '' || $switchserver ne '') {
                                     &Apache::loncommon::content_type($r,'text/html');                                      &Apache::loncommon::content_type($r,'text/html');
                                     &Apache::loncommon::no_cache($r);                                      &Apache::loncommon::no_cache($r);
                                     $r->send_http_header;                                      $r->send_http_header;
                                     my $end_page=&Apache::loncommon::end_page();                                      $r->print(&Apache::loncommon::check_release_result($switchwarning,$switchserver));
                                     $r->print(&Apache::loncommon::start_page('Selected course unavailable on this server').  
                                               '<p class="LC_warning">');  
                                     if ($switchwarning) {  
                                         $r->print($switchwarning.'<br /><a href="/adm/roles">');  
                                         if (&Apache::loncommon::show_course()) {  
                                             $r->print(&mt('Display courses'));  
                                         } else {  
                                             $r->print(&mt('Display roles'));  
                                         }  
                                         $r->print('</a>');  
                                     } elsif ($switchserver) {  
         $r->print(&mt('This course requires a newer version of LON-CAPA than is installed on this server.').  
                                                   '<br />'.  
                                                   '<a href="/adm/switchserver?'.$switchserver.'">'.  
                                                   &mt('Switch Server').  
                                                   '</a>');  
                                     }  
                                     $r->print('</p>'.&Apache::loncommon::end_page());  
                                     return OK;                                      return OK;
                                 }                                  }
                             }                              }
Line 604  ENDENTERKEY Line 589  ENDENTERKEY
     $furl = "/adm/helper/course.initialization.helper";      $furl = "/adm/helper/course.initialization.helper";
     # Send the user to the course they selected      # Send the user to the course they selected
  } elsif ($env{'request.course.id'}) {   } elsif ($env{'request.course.id'}) {
                                       if ((&Apache::loncommon::course_type() eq 'Placement') && 
                                           (!$env{'request.role.adv'})) {
                                           my ($score,$incomplete) = 
                                               &Apache::lonplacementtest::check_completion(undef,undef,1);
                                           if (($incomplete) && ($incomplete < 100)) {
                                               &redirect_user($r, &mt('Entering [_1]',
                                                             $env{'course.'.$cdom.'_'.$cnum.'.description'}),
                                                             '/adm/placement', $msg);
                                               return OK;
                                           }
                                       }
                                     my ($dest,$destsymb,$checkenc);                                      my ($dest,$destsymb,$checkenc);
                                     $dest = $env{'form.destinationurl'};                                      $dest = $env{'form.destinationurl'};
                                     $destsymb = $env{'form.destsymb'};                                      $destsymb = $env{'form.destsymb'};
Line 673  ENDENTERKEY Line 669  ENDENTERKEY
     }      }
  }   }
                                 # Are we allowed to look at the first resource?                                  # Are we allowed to look at the first resource?
                                   my $access;
                                 if ($furl =~ m{^(/adm/wrapper|)/ext/}) {                                  if ($furl =~ m{^(/adm/wrapper|)/ext/}) {
                                     # If it's an external resource,                                      # If it's an external resource,
                                     # strip off the symb argument and possible query                                      # strip off the symb argument and possible query
Line 680  ENDENTERKEY Line 677  ENDENTERKEY
                                     # Unencode $symb                                      # Unencode $symb
                                     $symb = &unescape($symb);                                      $symb = &unescape($symb);
                                     # Then check for permission                                      # Then check for permission
                                     if (!&Apache::lonnet::allowed('bre',$exturl,$symb)) {                                      $access = &Apache::lonnet::allowed('bre',$exturl,$symb);
                                         $furl = &Apache::lonpageflip::first_accessible_resource();  
                                     }  
                                 # For other resources just check for permission                                  # For other resources just check for permission
                                 } elsif (!&Apache::lonnet::allowed('bre',$furl)) {                                  } else {
                                       $access = &Apache::lonnet::allowed('bre',$furl);
                                   }
                                   if (!$access) {
                                     $furl = &Apache::lonpageflip::first_accessible_resource();                                      $furl = &Apache::lonpageflip::first_accessible_resource();
                                   } elsif ($access eq 'B') {
                                       $furl = '/adm/navmaps?showOnlyHomework=1';
                                 }                                  }
    
                                 $msg = &mt('Entering [_1] ...',                                  $msg = &mt('Entering [_1] ...',
    $env{'course.'.$cdom.'_'.$cnum.'.description'});     $env{'course.'.$cdom.'_'.$cnum.'.description'});
  &redirect_user($r, &mt('Entering [_1]',   &redirect_user($r, &mt('Entering [_1]',
Line 753  ENDENTERKEY Line 752  ENDENTERKEY
     my $showcount = &roles_from_env(\%roles_in_env,$update);       my $showcount = &roles_from_env(\%roles_in_env,$update); 
   
     my $swinfo=&Apache::lonmenu::rawconfig();      my $swinfo=&Apache::lonmenu::rawconfig();
     my $start_page=&Apache::loncommon::start_page($pagetitle,undef,{bread_crumbs=>$brcrum});  
     my %domdefs=&Apache::lonnet::get_domain_defaults($env{'user.domain'});       my %domdefs=&Apache::lonnet::get_domain_defaults($env{'user.domain'}); 
     my $cattype = 'std';      my $cattype = 'std';
     if ($domdefs{'catauth'}) {      if ($domdefs{'catauth'}) {
         $cattype = $domdefs{'catauth'};          $cattype = $domdefs{'catauth'};
     }      }
     my $funcs = &get_roles_functions($showcount,$cattype);      my $placementonly;
     $standby=~s/\n/\\n/g;      if ($showcount == 1) {
           if ($env{'request.course.id'}) {
               if ($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Placement') {
                   $placementonly = 1;
               }
           } else {
               foreach my $rolecode (keys(%roles_in_env)) {
                   my ($cid) = ($rolecode =~ m{^\Quser.role.st./\E($match_domain/$match_courseid)(?:/|$)});
                   if ($cid) {
                       my %coursedescription =
                           &Apache::lonnet::coursedescription($cid,{'one_time' => '1'});
                       if ($coursedescription{'type'} eq 'Placement') {
                           $placementonly = 1;
                       }
                       last;
                   }
               }
           }
       }
       my ($start_page,$funcs);
       if ($placementonly) {
           $start_page=&Apache::loncommon::start_page($pagetitle,undef,
                                                     {bread_crumbs=>$brcrum,crstype=>'Placement'});
       } else {
           $start_page=&Apache::loncommon::start_page($pagetitle,undef,{bread_crumbs=>$brcrum}); 
           $funcs = &get_roles_functions($showcount,$cattype);
       }
       &js_escape(\$standby);
     my $noscript='<br /><span class="LC_error">'.&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.').'<br />'.&mt('As this is not the case, most functionality in the system will be unavailable.').'</span><br />';      my $noscript='<br /><span class="LC_error">'.&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.').'<br />'.&mt('As this is not the case, most functionality in the system will be unavailable.').'</span><br />';
   
     $r->print(<<ENDHEADER);      $r->print(<<ENDHEADER);
Line 902  ENDHEADER Line 927  ENDHEADER
                       \%sortrole,\%roleclass,\%futureroles,\%timezones,$loncaparev);                        \%sortrole,\%roleclass,\%futureroles,\%timezones,$loncaparev);
     $refresh = $now;      $refresh = $now;
     &Apache::lonnet::appenv({'user.refresh.time'  => $refresh});      &Apache::lonnet::appenv({'user.refresh.time'  => $refresh});
     if ((($cattype eq 'std') || ($cattype eq 'domonly')) && (!$env{'user.adv'})) {      if ($countactive == 1) {
           if ($env{'request.course.id'}) {
               if ($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Placement') {
                   $placementonly = 1;
               }
           } elsif ($possiblerole) {
               if ($possiblerole =~ m{^st\./($match_domain)/($match_courseid)(?:/|$)}) {
                   if ($env{'course.'.$1.'_'.$2.'.type'} eq 'Placement') {
                       $placementonly = 1;
                   }
               }
           }
       }
       if ((($cattype eq 'std') || ($cattype eq 'domonly')) && (!$env{'user.adv'}) &&
             (!$placementonly)) {
         if ($countactive > 0) {          if ($countactive > 0) {
             my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');              my $domdesc = &Apache::lonnet::domain($env{'user.domain'},'description');
             my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&');               my $esc_dom = &HTML::Entities::encode($env{'user.domain'},'"<>&'); 
Line 955  ENDHEADER Line 994  ENDHEADER
         }          }
         $r->print(&Apache::loncommon::end_page());          $r->print(&Apache::loncommon::end_page());
  return OK;   return OK;
       } elsif (($placementonly) && ($env{'request.role'} eq 'cm')) {
    $r->print('<h3>'.&mt('Please stand by.').'</h3>
             <input type="hidden" name="'.$possiblerole.'" value="1" />
                     <noscript><br />
                     <input type="submit" name="submit" value="'.&mt('Continue').'" />
                     </noscript></form>');
    $r->rflush();
    $r->print('<script type="text/javascript">document.forms.rolechoice.submit();</script>');
    $r->print(&Apache::loncommon::end_page());
    return OK;
     }      }
 # ----------------------------------------------------------------------- Table  # ----------------------------------------------------------------------- Table
   
Line 1156  sub gather_roles { Line 1205  sub gather_roles {
                 $trole=Apache::lonnet::plaintext($role);                  $trole=Apache::lonnet::plaintext($role);
                 my $ttype;                  my $ttype;
                 my $twhere;                  my $twhere;
                   my $skipcal;
                 my ($tdom,$trest,$tsection)=                  my ($tdom,$trest,$tsection)=
                     split(/\//,Apache::lonnet::declutter($where));                      split(/\//,Apache::lonnet::declutter($where));
                 # First, Co-Authorship roles                  # First, Co-Authorship roles
Line 1211  sub gather_roles { Line 1261  sub gather_roles {
                                 my $required = $env{'course.'.$tcourseid.'.internal.releaserequired'};                                  my $required = $env{'course.'.$tcourseid.'.internal.releaserequired'};
                                 if ($required ne '') {                                  if ($required ne '') {
                                     ($switchserver,$switchwarning) =                                       ($switchserver,$switchwarning) = 
                                         &check_release_required($loncaparev,$tcourseid,$trolecode,$required);                                          &Apache::loncommon::check_release_required($loncaparev,$tcourseid,$trolecode,$required);
                                     if ($switchserver || $switchwarning) {                                      if ($switchserver || $switchwarning) {
                                         $button = 0;                                          $button = 0;
                                     }                                      }
Line 1234  sub gather_roles { Line 1284  sub gather_roles {
                                 my $required = $newhash{'internal.releaserequired'};                                  my $required = $newhash{'internal.releaserequired'};
                                 if ($required ne '') {                                  if ($required ne '') {
                                     ($switchserver,$switchwarning) =                                      ($switchserver,$switchwarning) =
                                         &check_release_required($loncaparev,$tcourseid,$trolecode,$required);                                          &Apache::loncommon::check_release_required($loncaparev,$tcourseid,$trolecode,$required);
                                     if ($switchserver || $switchwarning) {                                      if ($switchserver || $switchwarning) {
                                         $button = 0;                                          $button = 0;
                                     }                                      }
Line 1245  sub gather_roles { Line 1295  sub gather_roles {
                             $env{'course.'.$tcourseid.'.description'}=$twhere;                              $env{'course.'.$tcourseid.'.description'}=$twhere;
                             $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;                              $sortkey=$role."\0".$tdom."\0".$twhere."\0".$envkey;
                             $ttype = 'Unavailable';                              $ttype = 'Unavailable';
                               $skipcal = 1;
                         }                          }
                     }                      }
                       if ($ttype eq 'Placement') {
                           $ttype = 'Placement Test';
                       }
                     if ($tsection) {                      if ($tsection) {
                         $twhere.='<br />'.&mt('Section').': '.$tsection;                          $twhere.='<br />'.&mt('Section').': '.$tsection;
                     }                      }
Line 1263  sub gather_roles { Line 1317  sub gather_roles {
                 ($role_text,$role_text_end) =                  ($role_text,$role_text_end) =
                     &build_roletext($trolecode,$tdom,$trest,$tstatus,$tryagain,                      &build_roletext($trolecode,$tdom,$trest,$tstatus,$tryagain,
                                     $advanced,$tremark,$tbg,$trole,$twhere,$tpstart,                                      $advanced,$tremark,$tbg,$trole,$twhere,$tpstart,
                                     $tpend,$nochoose,$button,$switchserver,$reinit,$switchwarning);                                      $tpend,$nochoose,$button,$switchserver,$reinit,
                                       $switchwarning,$skipcal);
                 $roletext->{$envkey}=[$role_text,$role_text_end];                  $roletext->{$envkey}=[$role_text,$role_text_end];
                 if (!$sortkey) {$sortkey=$twhere."\0".$envkey;}                  if (!$sortkey) {$sortkey=$twhere."\0".$envkey;}
                 $sortrole->{$sortkey}=$envkey;                  $sortrole->{$sortkey}=$envkey;
Line 1361  sub roletable_headers { Line 1416  sub roletable_headers {
 }  }
   
 sub roletypes {  sub roletypes {
     my @types = ('Domain','Authoring Space','Course','Community','Unavailable','System');      my @types = ('Domain','Authoring Space','Course','Placement Test','Community','Unavailable','System');
     return @types;       return @types; 
 }  }
   
Line 1557  sub privileges_info { Line 1612  sub privileges_info {
 }  }
   
 sub build_roletext {  sub build_roletext {
     my ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$trole,$twhere,$tpstart,$tpend,$nochoose,$button,$switchserver,$reinit,$switchwarning) = @_;      my ($trolecode,$tdom,$trest,$tstatus,$tryagain,$advanced,$tremark,$tbg,$trole,$twhere,
           $tpstart,$tpend,$nochoose,$button,$switchserver,$reinit,$switchwarning,$skipcal) = @_;
     my ($roletext,$roletext_end);      my ($roletext,$roletext_end);
     my $is_dc=($trolecode =~ m/^dc\./);      my $is_dc=($trolecode =~ m/^dc\./);
     my $rowspan=($is_dc) ? ''      my $rowspan=($is_dc) ? ''
Line 1613  sub build_roletext { Line 1669  sub build_roletext {
                         $trolecode."','".$buttonname.'\');" /></td>';                          $trolecode."','".$buttonname.'\');" /></td>';
         }          }
     }      }
     if ($trolecode !~ m/^(dc|ca|au|aa)\./) {      if (($trolecode !~ m/^(dc|ca|au|aa)\./)  && (!$skipcal)) {
  $tremark.=&Apache::lonannounce::showday(time,1,   $tremark.=&Apache::lonannounce::showday(time,1,
  &Apache::lonannounce::readcalendar($tdom.'_'.$trest));   &Apache::lonannounce::readcalendar($tdom.'_'.$trest));
     }      }
Line 1759  sub check_forcc { Line 1815  sub check_forcc {
     return $is_cc;      return $is_cc;
 }  }
   
 sub check_release_required {  
     my ($loncaparev,$tcourseid,$trolecode,$required) = @_;  
     my ($switchserver,$warning);  
     if ($required ne '') {  
         my ($reqdmajor,$reqdminor) = ($required =~ /^(\d+)\.(\d+)$/);  
         my ($major,$minor) = ($loncaparev =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?$/);  
         if ($reqdmajor ne '' && $reqdminor ne '') {  
             my $otherserver;  
             if (($major eq '' && $minor eq '') ||   
                 (($reqdmajor > $major) || (($reqdmajor == $major) && ($reqdminor > $minor)))) {  
                 my ($userdomserver) = &Apache::lonnet::choose_server($env{'user.domain'},undef,$required,1);  
                 my $switchlcrev =   
                     &Apache::lonnet::get_server_loncaparev($env{'user.domain'},  
                                                            $userdomserver);  
                 my ($swmajor,$swminor) = ($switchlcrev =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?$/);  
                 if (($swmajor eq '' && $swminor eq '') || ($reqdmajor > $swmajor) ||   
                     (($reqdmajor == $swmajor) && ($reqdminor > $swminor))) {  
                     my $cdom = $env{'course.'.$tcourseid.'.domain'};  
                     if ($cdom ne $env{'user.domain'}) {  
                         my ($coursedomserver,$coursehostname) = &Apache::lonnet::choose_server($cdom,undef,$required,1);   
                         my $serverhomeID = &Apache::lonnet::get_server_homeID($coursehostname);  
                         my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID);  
                         my %defdomdefaults = &Apache::lonnet::get_domain_defaults($serverhomedom);  
                         my %udomdefaults = &Apache::lonnet::get_domain_defaults($env{'user.domain'});  
                         my $remoterev = &Apache::lonnet::get_server_loncaparev($serverhomedom,$coursedomserver);  
                         my $canhost =  
                             &Apache::lonnet::can_host_session($env{'user.domain'},  
                                                               $coursedomserver,  
                                                               $remoterev,  
                                                               $udomdefaults{'remotesessions'},  
                                                               $defdomdefaults{'hostedsessions'});  
   
                         if ($canhost) {  
                             $otherserver = $coursedomserver;  
                         } else {  
                             $warning = &mt('Requires LON-CAPA version [_1].',$env{'course.'.$tcourseid.'.internal.releaserequired'}).'<br />'. &mt("No suitable server could be found amongst servers in either your own domain or in the course's domain.");  
                         }  
                     } else {  
                         $warning = &mt('Requires LON-CAPA version [_1].',$env{'course.'.$tcourseid.'.internal.releaserequired'}).'<br />'.&mt("No suitable server could be found amongst servers in your own domain (which is also the course's domain).");  
                     }  
                 } else {  
                     $otherserver = $userdomserver;  
                 }  
             }  
             if ($otherserver ne '') {  
                 $switchserver = 'otherserver='.$otherserver.'&amp;role='.$trolecode;  
             }  
         }  
     }  
     return ($switchserver,$warning);  
 }  
   
 sub courselink {  sub courselink {
     my ($dcdom,$rowtype) = @_;      my ($dcdom,$rowtype) = @_;
     my $courseform=&Apache::loncommon::selectcourse_link      my $courseform=&Apache::loncommon::selectcourse_link
Line 1825  sub courselink { Line 1829  sub courselink {
 }  }
   
 sub coursepick_jscript {  sub coursepick_jscript {
     my %lt = &Apache::lonlocal::texthash(      my %js_lt = &Apache::lonlocal::texthash(
                   plsu => "Please use the 'Select Course/Community' link to open a separate pick course window where you may select the course or community you wish to enter.",                    plsu => "Please use the 'Select Course/Community' link to open a separate pick course window where you may select the course or community you wish to enter.",
                   youc => 'You can only use this screen to select courses and communities in the current domain.',                    youc => 'You can only use this screen to select courses and communities in the current domain.',
              );               );
       &js_escape(\%js_lt);
     my $verify_script = <<"END";      my $verify_script = <<"END";
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
Line 1845  function verifyCoursePick(caller) { Line 1850  function verifyCoursePick(caller) {
             }              }
         }          }
         else {          else {
             alert("$lt{'plsu'}");              alert("$js_lt{'plsu'}");
         }          }
     }      }
     else {      else {
         alert("$lt{'youc'}")          alert("$js_lt{'youc'}")
     }      }
 }  }
 function getIndex(caller) {  function getIndex(caller) {
Line 1887  sub display_cc_role { Line 1892  sub display_cc_role {
             my $trolecode = $ccrole.'./'.$tdom.'/'.$trest;              my $trolecode = $ccrole.'./'.$tdom.'/'.$trest;
             my $twhere;              my $twhere;
             my $ttype;              my $ttype;
               my $skipcal;
             my $tbg='LC_roles_is';              my $tbg='LC_roles_is';
             my %newhash=&Apache::lonnet::coursedescription($tcourseid);              my %newhash=&Apache::lonnet::coursedescription($tcourseid);
             if (%newhash) {              if (%newhash) {
Line 1898  sub display_cc_role { Line 1904  sub display_cc_role {
             } else {              } else {
                 $twhere=&mt('Currently not available');                  $twhere=&mt('Currently not available');
                 $env{'course.'.$tcourseid.'.description'}=$twhere;                  $env{'course.'.$tcourseid.'.description'}=$twhere;
                   $skipcal = 1;
             }              }
             my $trole = &Apache::lonnet::plaintext($ccrole,$ttype,$tcourseid);              my $trole = &Apache::lonnet::plaintext($ccrole,$ttype,$tcourseid);
             $twhere.="<br />".&mt('Domain').":".$tdom;              $twhere.="<br />".&mt('Domain').":".$tdom;
             ($roletext,$roletext_end) = &build_roletext($trolecode,$tdom,$trest,'is',$tryagain,$advanced,'',$tbg,$trole,$twhere,'','','',1,'');              ($roletext,$roletext_end) = &build_roletext($trolecode,$tdom,$trest,'is',$tryagain,$advanced,'',$tbg,$trole,$twhere,'','','',1,'','','',$skipcal);
         }          }
     }      }
     return ($roletext,$roletext_end);      return ($roletext,$roletext_end);

Removed from v.1.309  
changed lines
  Added in v.1.313


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