Diff for /loncom/interface/createaccount.pm between versions 1.30 and 1.48

version 1.30, 2009/03/12 13:59:49 version 1.48, 2012/05/16 21:19:39
Line 45  use Crypt::DES; Line 45  use Crypt::DES;
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
 use HTML::Entities;  use HTML::Entities;
   
   #TODO this module needs documentation
   
 sub handler {  sub handler {
     my $r = shift;      my $r = shift;
     &Apache::loncommon::content_type($r,'text/html');      &Apache::loncommon::content_type($r,'text/html');
Line 65  sub handler { Line 67  sub handler {
     if ($sso_username ne '' && $sso_domain ne '') {      if ($sso_username ne '' && $sso_domain ne '') {
         $domain = $sso_domain;           $domain = $sso_domain; 
     } else {      } else {
         $domain = &Apache::lonnet::default_login_domain();          ($domain, undef) = Apache::lonnet::is_course($env{'form.courseid'}); 
         if (defined($env{'form.courseid'})) {          $domain ||= &Apache::lonnet::default_login_domain();
             if (&validate_course($env{'form.courseid'})) {  
                 if ($env{'form.courseid'} =~ /^($match_domain)_($match_courseid)$/) {  
                     $domain = $1;   
                 }  
             }  
         }  
     }      }
     my $domdesc = &Apache::lonnet::domain($domain,'description');      my $domdesc = &Apache::lonnet::domain($domain,'description');
     my $contact_name = &mt('LON-CAPA helpdesk');      my $contact_name = &mt('LON-CAPA helpdesk');
Line 92  sub handler { Line 88  sub handler {
         my $end_page =          my $end_page =
             &Apache::loncommon::end_page();              &Apache::loncommon::end_page();
         $r->print($start_page."\n".'<h2>'.&mt('You are already logged in').'</h2>'.          $r->print($start_page."\n".'<h2>'.&mt('You are already logged in').'</h2>'.
                   '<p>'.&mt('Please either [_1]continue the current session[_2] or [_3]logout[_4].','<a href="/adm/roles">','</a>','<a href="/adm/logout">','</a>').                    '<p>'.&mt('Please either [_1]continue the current session[_2] or [_3]log out[_4].','<a href="/adm/roles">','</a>','<a href="/adm/logout">','</a>').
                   '</p><p><a href="/adm/loginproblems.html">'.&mt('Login problems?').'</a></p>'.$end_page);                    '</p><p><a href="/adm/loginproblems.html">'.&mt('Login problems?').'</a></p>'.$end_page);
         return OK;          return OK;
     }      }
   
     my ($js,$courseid,$title);      my ($js,$courseid,$title);
     if (defined($env{'form.courseid'})) {      $courseid = Apache::lonnet::is_course($env{'form.courseid'});
         $courseid = &validate_course($env{'form.courseid'});  
     }  
     if ($courseid ne '') {      if ($courseid ne '') {
         $js = &catreturn_js();          $js = &catreturn_js();
         $title = 'Self-enroll in a LON-CAPA course';          $title = 'Self-enroll in a LON-CAPA course';
Line 112  sub handler { Line 106  sub handler {
         if ($env{'form.udom'} ne '') {          if ($env{'form.udom'} ne '') {
             $domain = $env{'form.udom'};              $domain = $env{'form.udom'};
         }          }
   
           my %domconfig = 
               &Apache::lonnet::get_dom('configuration',['usercreation'],$domain);
           my ($cancreate,$statustocreate) = 
               &get_creation_controls($domain,$domconfig{'usercreation'});
   
         my ($result,$output) =          my ($result,$output) =
             &username_validation($r,$env{'form.uname'},$domain,$domdesc,              &username_validation($r,$env{'form.uname'},$domain,$domdesc,
                                  $contact_name,$contact_email,$courseid,                                   $contact_name,$contact_email,$courseid,
                                  $lonhost);                                   $lonhost,$statustocreate);
         if ($result eq 'existingaccount') {          if ($result eq 'existingaccount') {
             $r->print($output);              $r->print($output);
             &print_footer($r);              &print_footer($r);
             return OK;              return OK;
         } else {          } else {
             $start_page =               $start_page = 
                 &Apache::loncommon::start_page($title,$js,                  &Apache::loncommon::start_page($title,$js);
                                                {'no_inline_link'   => 1,});  
             &print_header($r,$start_page,$courseid);              &print_header($r,$start_page,$courseid);
             $r->print($output);              $r->print($output);
             &print_footer($r);                  &print_footer($r);    
Line 131  sub handler { Line 130  sub handler {
         }          }
     }      }
     $start_page =      $start_page =
         &Apache::loncommon::start_page($title,$js,          &Apache::loncommon::start_page($title,$js);
                                        {'no_inline_link'   => 1,});  
     my @cancreate;  
     my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$domain);  
     if (ref($domconfig{'usercreation'}) eq 'HASH') {  
         if (ref($domconfig{'usercreation'}{'cancreate'}) eq 'HASH') {  
             if (ref($domconfig{'usercreation'}{'cancreate'}{'selfcreate'}) eq 'ARRAY') {  
                 @cancreate = @{$domconfig{'usercreation'}{'cancreate'}{'selfcreate'}};  
             } elsif (($domconfig{'usercreation'}{'cancreate'}{'selfcreate'} ne 'none') &&  
                      ($domconfig{'usercreation'}{'cancreate'}{'selfcreate'} ne '')) {  
                 @cancreate = ($domconfig{'usercreation'}{'cancreate'}{'selfcreate'});  
             }  
         }  
     }  
   
     if (@cancreate == 0) {      my %domconfig = 
           &Apache::lonnet::get_dom('configuration',['usercreation'],$domain);
       my ($cancreate,$statustocreate) = &get_creation_controls($domain,$domconfig{'usercreation'});
       if (@{$cancreate} == 0) {
         &print_header($r,$start_page,$courseid);          &print_header($r,$start_page,$courseid);
         my $output = '<h3>'.&mt('Account creation unavailable').'</h3>'.          my $output = '<h3>'.&mt('Account creation unavailable').'</h3>'.
                      '<span class="LC_warning">'.                       '<span class="LC_warning">'.
Line 160  sub handler { Line 149  sub handler {
         &print_header($r,$start_page,$courseid);          &print_header($r,$start_page,$courseid);
         my ($msg,$sso_logout);          my ($msg,$sso_logout);
         $sso_logout = &sso_logout_frag($r,$domain);          $sso_logout = &sso_logout_frag($r,$domain);
         if (grep(/^sso$/,@cancreate)) {          if (grep(/^sso$/,@{$cancreate})) {
             $msg = '<h3>'.&mt('Account creation').'</h3>'.              $msg = '<h3>'.&mt('Account creation').'</h3>'.
                    &mt("Although your username and password were authenticated by your institution's Single Sign On system, you do not currently have a LON-CAPA account at this institution.").'<br />';                     &mt("Although your username and password were authenticated by your institution's Single Sign On system, you do not currently have a LON-CAPA account at this institution.").'<br />';
   
             $msg .= &username_check($sso_username,$domain,$domdesc,$courseid,               $msg .= &username_check($sso_username,$domain,$domdesc,$courseid, 
                                     $lonhost,$contact_email,$contact_name,$sso_logout);                                      $lonhost,$contact_email,$contact_name,
                                       $sso_logout,$statustocreate);
         } else {          } else {
             $msg = '<h3>'.&mt('Account creation unavailable').'</h3>'.              $msg = '<h3>'.&mt('Account creation unavailable').'</h3>'.
                    '<span class="LC_warning">'.&mt("Although your username and password were authenticated by your institution's Single Sign On system, you do not currently have a LON-CAPA account at this institution, and you are not permitted to create one.").'</span><br /><br />'.&mt('Please contact the [_1] ([_2]) for assistance.',$contact_name,$contact_email).'<hr />'.                     '<span class="LC_warning">'.&mt("Although your username and password were authenticated by your institution's Single Sign On system, you do not currently have a LON-CAPA account at this institution, and you are not permitted to create one.").'</span><br /><br />'.&mt('Please contact the [_1] ([_2]) for assistance.',$contact_name,$contact_email).'<hr />'.
Line 215  sub handler { Line 205  sub handler {
         (my $result,$output) =           (my $result,$output) = 
             &username_validation($r,$env{'form.uname'},$domain,$domdesc,              &username_validation($r,$env{'form.uname'},$domain,$domdesc,
                                  $contact_name,$contact_email,$courseid,                                   $contact_name,$contact_email,$courseid,
                                  $lonhost);                                   $lonhost,$statustocreate);
         if ($result eq 'existingaccount') {          if ($result eq 'existingaccount') {
             $r->print($output);              $r->print($output);
             &print_footer($r);              &print_footer($r);
Line 226  sub handler { Line 216  sub handler {
     } elsif ($env{'form.create_with_email'}) {      } elsif ($env{'form.create_with_email'}) {
         &print_header($r,$start_page,$courseid);          &print_header($r,$start_page,$courseid);
         $output = &process_email_request($env{'form.useremail'},$domain,$domdesc,          $output = &process_email_request($env{'form.useremail'},$domain,$domdesc,
                                          $contact_name,$contact_email,\@cancreate,                                           $contact_name,$contact_email,$cancreate,
                                          $lonhost,$domconfig{'usercreation'},                                           $lonhost,$domconfig{'usercreation'},
                                          $courseid);                                           $courseid);
     } elsif (!$token) {      } elsif (!$token) {
         &print_header($r,$start_page,$courseid);          &print_header($r,$start_page,$courseid);
         my $now=time;          my $now=time;
         if (grep(/^login$/,@cancreate)) {          if (grep(/^login$/,@{$cancreate})) {
             my $jsh=Apache::File->new($include."/londes.js");              my $jsh=Apache::File->new($include."/londes.js");
             $r->print(<$jsh>);              $r->print(<$jsh>);
             $r->print(&javascript_setforms($now));              $r->print(&javascript_setforms($now));
         }          }
         if (grep(/^email$/,@cancreate)) {          if (grep(/^email$/,@{$cancreate})) {
             $r->print(&javascript_validmail());              $r->print(&javascript_validmail());
         }          }
         $output = &print_username_form($domain,$domdesc,\@cancreate,$now,$lonhost,          $output = &print_username_form($domain,$domdesc,$cancreate,$now,$lonhost,
                                        $courseid);                                         $courseid);
     }      }
     $r->print($output);      $r->print($output);
Line 280  sub selfenroll_crumbs { Line 270  sub selfenroll_crumbs {
     my ($r,$courseid,$desc) = @_;      my ($r,$courseid,$desc) = @_;
     &Apache::lonhtmlcommon::add_breadcrumb      &Apache::lonhtmlcommon::add_breadcrumb
          ({href=>"javascript:ToCatalog('backupcrumbs','')",           ({href=>"javascript:ToCatalog('backupcrumbs','')",
            text=>"Course Catalog"});             text=>"Course/Community Catalog"});
     if ($env{'form.coursenum'} ne '') {      if ($env{'form.coursenum'} ne '') {
         &Apache::lonhtmlcommon::add_breadcrumb          &Apache::lonhtmlcommon::add_breadcrumb
           ({href=>"javascript:ToCatalog('backupcrumbs','details')",            ({href=>"javascript:ToCatalog('backupcrumbs','details')",
Line 288  sub selfenroll_crumbs { Line 278  sub selfenroll_crumbs {
     }      }
     my $last_crumb;      my $last_crumb;
     if ($desc ne '') {      if ($desc ne '') {
         $last_crumb = &mt('Self-enroll in [_1]','<span class="LC_cusr_emph">'.$desc.'</span>');          $last_crumb = &mt('Self-enroll in [_1]',"<span class='LC_cusr_emph'>$desc</span>");
     } else {      } else {
         $last_crumb = &mt('Self-enroll');          $last_crumb = &mt('Self-enroll');
     }      }
Line 299  sub selfenroll_crumbs { Line 289  sub selfenroll_crumbs {
     return;      return;
 }  }
   
 sub validate_course {  
     my ($courseid) = @_;  
     my ($cdom,$cnum) = ($courseid =~ /^($match_domain)_($match_courseid)$/);  
     if (($cdom ne '') && ($cnum ne '')) {  
         if (&Apache::lonnet::is_course($cdom,$cnum)) {  
             return ($courseid);  
         }  
     }  
     return;  
 }  
   
 sub javascript_setforms {  sub javascript_setforms {
     my ($now) =  @_;      my ($now) =  @_;
     my $js = <<ENDSCRIPT;      my $js = <<ENDSCRIPT;
  <script language="JavaScript">   <script type="text/javascript" language="JavaScript">
     function send() {      function send() {
         this.document.server.elements.uname.value = this.document.client.elements.uname.value;          this.document.server.elements.uname.value = this.document.client.elements.uname.value;
           this.document.server.elements.udom.value = this.document.client.elements.udom.value;
         uextkey=this.document.client.elements.uextkey.value;          uextkey=this.document.client.elements.uextkey.value;
         lextkey=this.document.client.elements.lextkey.value;          lextkey=this.document.client.elements.lextkey.value;
         initkeys();          initkeys();
Line 346  sub javascript_checkpass { Line 326  sub javascript_checkpass {
         var upasscheck = this.document.client.elements.upasscheck$now.value;          var upasscheck = this.document.client.elements.upasscheck$now.value;
         if (upass == '') {          if (upass == '') {
             alert("$nopass");              alert("$nopass");
             return;              return false;
         }          }
         if (upass == upasscheck) {          if (upass == upasscheck) {
             this.document.client.elements.upasscheck$now.value='';              this.document.client.elements.upasscheck$now.value='';
             send();              send();
             return;              return false;
         } else {          } else {
             alert("$mismatchpass");              alert("$mismatchpass");
             return;              return false;
         }           }
     }      }
 </script>  </script>
 ENDSCRIPT  ENDSCRIPT
Line 413  sub print_username_form { Line 393  sub print_username_form {
                 } else {                  } else {
                     $output .= '<br />';                      $output .= '<br />';
                 }                  }
                 $output .=  '<form name="createaccount" method="post" onSubmit="return validate_email()" action="/adm/createaccount">'.                  $output .=  '<form name="createaccount" method="post" onsubmit="return validate_email()" action="/adm/createaccount">'.
                             &Apache::lonhtmlcommon::start_pick_box()."\n".                              &Apache::lonhtmlcommon::start_pick_box()."\n".
                             &Apache::lonhtmlcommon::row_title(&mt('E-mail address'),                              &Apache::lonhtmlcommon::row_title(&mt('E-mail address'),
                                                              'LC_pick_box_title')."\n".                                                               'LC_pick_box_title')."\n".
Line 425  sub print_username_form { Line 405  sub print_username_form {
                 if ($courseid ne '') {                  if ($courseid ne '') {
                     $output .= '<input type="hidden" name="courseid" value="'.$courseid.'"/>'."\n";                       $output .= '<input type="hidden" name="courseid" value="'.$courseid.'"/>'."\n"; 
                 }                  }
                 $output .= '<input type="submit" name="create_with_email" value="'.                   $output .=  &Apache::lonhtmlcommon::row_closure(1).
                               &Apache::lonhtmlcommon::row_title().'<br />'.
                               '<input type="submit" name="create_with_email" value="'. 
                             $submit_text.'" />'.                              $submit_text.'" />'.
                             &Apache::lonhtmlcommon::row_closure(1).                              &Apache::lonhtmlcommon::row_closure(1).
                             &Apache::lonhtmlcommon::end_pick_box().'<br /><br />';                              &Apache::lonhtmlcommon::end_pick_box().'<br /><br />';
Line 460  sub login_box { Line 442  sub login_box {
                                             );                                              );
     my ($lkey,$ukey) = &Apache::lonpreferences::des_keys();      my ($lkey,$ukey) = &Apache::lonpreferences::des_keys();
     my ($lextkey,$uextkey) = &getkeys($lkey,$ukey);      my ($lextkey,$uextkey) = &getkeys($lkey,$ukey);
     my $logtoken=Apache::lonnet::reply('tmpput:'.$ukey.$lkey.'&createaccount',      my $logtoken=Apache::lonnet::reply('tmpput:'.$ukey.$lkey.'&createaccount:createaccount',
                                        $lonhost);                                         $lonhost);
     $output = &serverform($logtoken,$lonhost,undef,$courseid,$context);      $output = &serverform($logtoken,$lonhost,undef,$courseid,$context);
     my $unameform = '<input type="text" name="uname" size="10" value="" />';      my $unameform = '<input type="text" name="uname" size="20" value="" />';
     my $upassform = '<input type="password" name="upass'.$now.'" size="10" />';      my $upassform = '<input type="password" name="upass'.$now.'" size="20" />';
     $output .= '<form name="client" method="post" action="/adm/createaccount">'."\n".      $output .= '<form name="client" method="post" action="" onsubmit="return(send());">'."\n".
                &Apache::lonhtmlcommon::start_pick_box()."\n";                 &Apache::lonhtmlcommon::start_pick_box()."\n".
     if ($context eq 'selfenroll') {                 &Apache::lonhtmlcommon::row_title($titles{$context},
         my $udomform =  '<input type="text" name="udom" size="10" value="'.  
                         $domain.'" />';  
         $output .= &Apache::lonhtmlcommon::row_title(&mt('Domain'),  
                                                      'LC_pick_box_title')."\n".  
                    $udomform."\n".  
                    &Apache::lonhtmlcommon::row_closure(1)."\n";  
     }  
   
     $output .= &Apache::lonhtmlcommon::row_title($titles{$context},  
                                                  'LC_pick_box_title')."\n".                                                   'LC_pick_box_title')."\n".
                $unameform."\n".                 $unameform."\n".
                &Apache::lonhtmlcommon::row_closure(1)."\n".                 &Apache::lonhtmlcommon::row_closure(1)."\n".
                &Apache::lonhtmlcommon::row_title(&mt('Password'),                 &Apache::lonhtmlcommon::row_title(&mt('Password'),
                                                 'LC_pick_box_title')."\n".                                                  'LC_pick_box_title')."\n".
                $upassform."\n".'<br /><br />'."\n".                 $upassform;
                '<input type="button" name="username_validation" value="'.      if ($context eq 'selfenroll') {
                $submit_text.'" onclick="javascript:send()" />'."\n".          my $udomform = '<input type="text" name="udom" size="10" value="'.
                &Apache::lonhtmlcommon::row_closure(1)."\n".                          $domain.'" />';
                &Apache::lonhtmlcommon::end_pick_box();          $output .= &Apache::lonhtmlcommon::row_closure(1)."\n".
     $output .= '<p>'.                     &Apache::lonhtmlcommon::row_title(&mt('Domain'),
                '<a href="/adm/resetpw">'.&mt('Forgot password?').'</a>'.                                                       'LC_pick_box_title')."\n".
                '</p>'."\n";                     $udomform."\n";
     $output .= '<input type="hidden" name="lextkey" value="'.$lextkey.'">'."\n".      } else {
                '<input type="hidden" name="uextkey" value="'.$uextkey.'">'."\n".          $output .= '<input type="hidden" name="udom" value="'.$domain.'" />';
       }
       $output .= &Apache::lonhtmlcommon::row_closure(1).
                  &Apache::lonhtmlcommon::row_title().
                  '<br /><input type="submit" name="username_validation" value="'.
                  $submit_text.'" />'."\n";
       if ($context eq 'selfenroll') {
           $output .= '<br /><br /><table width="100%"><tr><td align="right">'.
                      '<span class="LC_fontsize_medium">'.
                      '<a href="/adm/resetpw">'.&mt('Forgot password?').'</a>'.
                      '</span></td></tr></table>'."\n";
       }
       $output .= &Apache::lonhtmlcommon::row_closure(1)."\n".
                  &Apache::lonhtmlcommon::end_pick_box().'<br />'."\n";
       $output .= '<input type="hidden" name="lextkey" value="'.$lextkey.'" />'."\n".
                  '<input type="hidden" name="uextkey" value="'.$uextkey.'" />'."\n".
                '</form>';                 '</form>';
     return $output;      return $output;
 }  }
Line 540  sub process_email_request { Line 528  sub process_email_request {
                 if ($uhome eq 'no_host') {                  if ($uhome eq 'no_host') {
                     my (%rulematch,%inst_results,%curr_rules,%got_rules,%alerts);                      my (%rulematch,%inst_results,%curr_rules,%got_rules,%alerts);
                     &call_rulecheck($useremail,$domain,\%alerts,\%rulematch,                      &call_rulecheck($useremail,$domain,\%alerts,\%rulematch,
                                     \%inst_results,\%curr_rules,%got_rules,'username');                                      \%inst_results,\%curr_rules,\%got_rules,'username');
                     if (ref($alerts{'username'}) eq 'HASH') {                      if (ref($alerts{'username'}) eq 'HASH') {
                         if (ref($alerts{'username'}{$domain}) eq 'HASH') {                          if (ref($alerts{'username'}{$domain}) eq 'HASH') {
                             if ($alerts{'username'}{$domain}{$useremail}) {                              if ($alerts{'username'}{$domain}{$useremail}) {
Line 592  sub send_token { Line 580  sub send_token {
                 'domain'     => $domain,                  'domain'     => $domain,
                 'username'   => $email,                  'username'   => $email,
                 'courseid'   => $courseid);                  'courseid'   => $courseid);
     my $token = &Apache::lonnet::tmpput(\%info,$server);      my $token = &Apache::lonnet::tmpput(\%info,$server,'createaccount');
     if ($token !~ /^error/ && $token ne 'no_such_host') {      if ($token !~ /^error/ && $token ne 'no_such_host') {
         my $esc_token = &escape($token);          my $esc_token = &escape($token);
         my $showtime = localtime(time);          my $showtime = localtime(time);
Line 638  sub process_mailtoken { Line 626  sub process_mailtoken {
                 if ($result eq 'ok') {                  if ($result eq 'ok') {
                     $msg = $output;                       $msg = $output; 
                     my $shownow = &Apache::lonlocal::locallocaltime($now);                      my $shownow = &Apache::lonlocal::locallocaltime($now);
                     my $mailmsg = &mt('A LON-CAPA account for the institution: [_1] has been created [_2] from IP address: [_3].  If you did not perform this action or authorize it, please contact the [_4] ([_5]).',$domdesc,$shownow,$ENV{'REMOTE_ADDR'},$contact_name,$contact_email)."\n";                      my $mailmsg = &mt('A LON-CAPA account for the institution: [_1] has been created [_2] from IP address: [_3]. If you did not perform this action or authorize it, please contact the [_4] ([_5]).',$domdesc,$shownow,$ENV{'REMOTE_ADDR'},$contact_name,$contact_email)."\n";
                     my $mailresult = &Apache::resetpw::send_mail($domdesc,$data{'email'},                      my $mailresult = &Apache::resetpw::send_mail($domdesc,$data{'email'},
                                                                  $mailmsg,$contact_name,                                                                   $mailmsg,$contact_name,
                                                                  $contact_email);                                                                   $contact_email);
Line 647  sub process_mailtoken { Line 635  sub process_mailtoken {
                     } else {                      } else {
                         $msg .= &mt('An error occurred when sending e-mail to [_1] confirming creation of your LON-CAPA account.',$data{'username'});                          $msg .= &mt('An error occurred when sending e-mail to [_1] confirming creation of your LON-CAPA account.',$data{'username'});
                     }                      }
                     my %form = &start_session($r,$data{'username'},$domain,                       &start_session($r, $data{'username'}, $domain, $lonhost,
                                               $lonhost,$data{'courseid'},                          $data{'courseid'}, $token);
                                               $token);  
                     $nostart = 1;                      $nostart = 1;
                     $noend = 1;                      $noend = 1;
                 } else {                  } else {
Line 676  sub process_mailtoken { Line 663  sub process_mailtoken {
 }  }
   
 sub start_session {  sub start_session {
     my ($r,$username,$domain,$lonhost,$courseid,$token) = @_;      my ($r, $username, $domain, $lonhost, $courseid, $token) = @_;
     my %form = (  
                 uname => $username,  
                 udom  => $domain,  
                );  
     my $firsturl = '/adm/roles';  
     if (defined($courseid)) {  
         $courseid = &validate_course($courseid);  
         if ($courseid ne '') {  
             $form{'courseid'} = $courseid;  
             $firsturl = '/adm/selfenroll?courseid='.$courseid;  
         }  
     }  
     if ($r->dir_config('lonBalancer') eq 'yes') {      if ($r->dir_config('lonBalancer') eq 'yes') {
         &Apache::lonauth::success($r,$form{'uname'},$form{'udom'},          Apache::lonauth::success($r, $username, $domain, $lonhost,
                                   $lonhost,'noredirect',undef,\%form);              'noredirect', undef, {});
         if ($token ne '') {   
             my $delete = &Apache::lonnet::tmpdel($token);          Apache::lonnet::tmpdel($token) if $token;
         }  
         $r->internal_redirect('/adm/switchserver');          $r->internal_redirect('/adm/switchserver');
     } else {      } else {
         &Apache::lonauth::success($r,$form{'uname'},$form{'udom'},          $courseid = Apache::lonnet::is_course($courseid); 
                                   $lonhost,$firsturl,undef,\%form);  
           Apache::lonauth::success($r, $username, $domain, $lonhost,
               ($courseid ? "/adm/selfenroll?courseid=$courseid" : '/adm/roles'),
               undef, {}); 
     }      }
     return %form;  
       return;
 }  }
   
   
Line 716  sub print_dataentry_form { Line 696  sub print_dataentry_form {
         $output .= &javascript_setforms($now)."\n".&javascript_checkpass($now);          $output .= &javascript_setforms($now)."\n".&javascript_checkpass($now);
         my ($lkey,$ukey) = &Apache::lonpreferences::des_keys();          my ($lkey,$ukey) = &Apache::lonpreferences::des_keys();
         my ($lextkey,$uextkey) = &getkeys($lkey,$ukey);          my ($lextkey,$uextkey) = &getkeys($lkey,$ukey);
         my $logtoken=Apache::lonnet::reply('tmpput:'.$ukey.$lkey.'&createaccount',          my $logtoken=Apache::lonnet::reply('tmpput:'.$ukey.$lkey.'&createaccount:createaccount',
                                            $lonhost);                                             $lonhost);
         my @userinfo = ('firstname','middlename','lastname','generation','id',          my $formtag = '<form name="server" method="post" target="_top" action="/adm/createaccount">';
                         'permanentemail');          my ($datatable,$rowcount) =
         my %lt=&Apache::lonlocal::texthash(              &Apache::loncreateuser::personal_data_display($username,$domain,
                     'pd'             => "Personal Data",                                                            'email','selfcreate');
                     'firstname'      => "First Name",          if ($rowcount) {
                     'middlename'     => "Middle Name",              $output .= '<div class="LC_left_float">'.$formtag.$datatable;
                     'lastname'       => "Last Name",          } else {
                     'generation'     => "Generation",              $output .= $formtag;
                     'permanentemail' => "Permanent e-mail address",  
                     'id'             => "Student/Employee ID",  
                     'lg'             => "Login Data"  
         );  
         my %textboxsize = (  
                            firstname      => '15',  
                            middlename     => '15',  
                            lastname       => '15',  
                            generation     => '5',  
                            id             => '15',  
                           );  
         my $genhelp=&Apache::loncommon::help_open_topic('Generation');  
         $output .= '<div class="LC_left_float"><h3>'.$lt{'pd'}.'</h3>'.  
                   '<form name="server" method="post" target="_top" action="/adm/createaccount">'.  
                   &Apache::lonhtmlcommon::start_pick_box();  
         foreach my $item (@userinfo) {  
             my $rowtitle = $lt{$item};  
             if ($item eq 'generation') {  
                 $rowtitle = $genhelp.$rowtitle;  
             }  
             $output .= &Apache::lonhtmlcommon::row_title($rowtitle,undef,'LC_oddrow_value')."\n";  
             if ($item eq 'permanentemail') {  
                 $output .= $username;  
             } else {  
                 $output .= '<input type="text" name="c'.$item.'" size="'.$textboxsize{$item}.'" value="" />';  
             }  
             $output .= &Apache::lonhtmlcommon::row_closure(1);  
         }          }
         $output .= &Apache::lonhtmlcommon::end_pick_box();  
         $output .= <<"ENDSERVERFORM";          $output .= <<"ENDSERVERFORM";
    <input type="hidden" name="logtoken" value="$logtoken" />     <input type="hidden" name="logtoken" value="$logtoken" />
    <input type="hidden" name="token" value="$mailtoken" />     <input type="hidden" name="token" value="$mailtoken" />
    <input type="hidden" name="serverid" value="$lonhost" />     <input type="hidden" name="serverid" value="$lonhost" />
    <input type="hidden" name="uname" value="" />     <input type="hidden" name="uname" value="" />
    <input type="hidden" name="upass" value="" />     <input type="hidden" name="upass" value="" />
      <input type="hidden" name="udom" value="" />
    <input type="hidden" name="phase" value="createaccount" />     <input type="hidden" name="phase" value="createaccount" />
   </form></div>    </form>
 ENDSERVERFORM  ENDSERVERFORM
           if ($rowcount) {
               $output .= '</div>'.
                          '<div class="LC_left_float">';
           }
         my $upassone = '<input type="password" name="upass'.$now.'" size="10" />';          my $upassone = '<input type="password" name="upass'.$now.'" size="10" />';
         my $upasstwo = '<input type="password" name="upasscheck'.$now.'" size="10" />';          my $upasstwo = '<input type="password" name="upasscheck'.$now.'" size="10" />';
         my $submit_text = &mt('Create LON-CAPA account');          my $submit_text = &mt('Create LON-CAPA account');
         $output .= '<div class="LC_left_float"><h3>'.$lt{'lg'}.'</h3>'."\n".          $output .= '<h3>'.&mt('Login Data').'</h3>'."\n".
                    '<form name="client" method="post" />'."\n".                     '<form name="client" method="post" action="" '.
                      'onsubmit="return checkpass();">'."\n".
                    &Apache::lonhtmlcommon::start_pick_box()."\n".                     &Apache::lonhtmlcommon::start_pick_box()."\n".
                    &Apache::lonhtmlcommon::row_title(&mt('Username'),                     &Apache::lonhtmlcommon::row_title(&mt('Username'),
                                                     'LC_pick_box_title')."\n".                                                       'LC_pick_box_title',
                                                        'LC_oddrow_value')."\n".
                    $username."\n".                     $username."\n".
                    &Apache::lonhtmlcommon::row_closure(1)."\n".                     &Apache::lonhtmlcommon::row_closure(1)."\n".
                    &Apache::lonhtmlcommon::row_title(&mt('Password'),                     &Apache::lonhtmlcommon::row_title(&mt('Password'),
                                                     'LC_pick_box_title')."\n".                                                      'LC_pick_box_title',
                                                       'LC_oddrow_value')."\n".
                    $upassone."\n".                     $upassone."\n".
                    &Apache::lonhtmlcommon::row_closure(1)."\n".                     &Apache::lonhtmlcommon::row_closure(1)."\n".
                    &Apache::lonhtmlcommon::row_title(&mt('Confirm password'),                     &Apache::lonhtmlcommon::row_title(&mt('Confirm password'),
                                                 'LC_pick_box_title')."\n".                                                       'LC_pick_box_title',
                    $upasstwo."\n".                                                       'LC_oddrow_value')."\n".
                      $upasstwo.
                      &Apache::lonhtmlcommon::row_closure(1)."\n".
                      &Apache::lonhtmlcommon::row_title()."\n".
                      '<br /><input type="submit" name="createaccount" value="'.
                      $submit_text.'" />'.
                    &Apache::lonhtmlcommon::row_closure(1)."\n".                     &Apache::lonhtmlcommon::row_closure(1)."\n".
                    &Apache::lonhtmlcommon::end_pick_box()."\n".                     &Apache::lonhtmlcommon::end_pick_box()."\n".
                    '<input type="hidden" name="uname" value="'.$username.'">'."\n".                     '<input type="hidden" name="uname" value="'.$username.'" />'."\n".
                    '<input type="hidden" name="lextkey" value="'.$lextkey.'">'."\n".                     '<input type="hidden" name="udom" value="'.$domain.'" />'."\n".
                    '<input type="hidden" name="uextkey" value="'.$uextkey.'">'."\n".                     '<input type="hidden" name="lextkey" value="'.$lextkey.'" />'."\n".
                    '</form></div>'."\n".                     '<input type="hidden" name="uextkey" value="'.$uextkey.'" />'."\n".
                    '<div class="LC_clear_float_footer"><br /><br />'."\n".                     '</form>';
                    '<form name="buttonform">'."\n".          if ($rowcount) {
                    '<input type="button" name="createaccount" value="'.              $output .= '</div>'."\n".
                    $submit_text.'" onclick="javascript:checkpass();" /></form></div>';                         '<div class="LC_clear_float_footer"></div>'."\n";
           }
     } else {      } else {
         $output = &mt('Could not load javascript file [_1]','<tt>londes.js</tt>');          $output = &mt('Could not load javascript file [_1]','<tt>londes.js</tt>');
     }      }
     return $output;      return $output;
 }  }
   
   sub get_creation_controls {
       my ($domain,$usercreation) = @_;
       my (@cancreate,@statustocreate);
       if (ref($usercreation) eq 'HASH') {
           if (ref($usercreation->{'cancreate'}) eq 'HASH') {
               if (ref($usercreation->{'cancreate'}{'statustocreate'}) eq 'ARRAY') {
                   @statustocreate = @{$usercreation->{'cancreate'}{'statustocreate'}};
                   if (@statustocreate == 0) {
                       my ($othertitle,$usertypes,$types) =
                           &Apache::loncommon::sorted_inst_types($domain);
                       if (ref($types) eq 'ARRAY') {
                           if (@{$types} == 0) {
                               @statustocreate = ('default');
                           }
                       } else {
                           @statustocreate = ('default');
                       }
                   }
               } else {
                   @statustocreate = ('default');
                   my ($othertitle,$usertypes,$types) =
                       &Apache::loncommon::sorted_inst_types($domain);
                   if (ref($types) eq 'ARRAY') {
                       push(@statustocreate,@{$types});
                   }
               }
               if (ref($usercreation->{'cancreate'}{'selfcreate'}) eq 'ARRAY') {
                   @cancreate = @{$usercreation->{'cancreate'}{'selfcreate'}};
               } elsif (($usercreation->{'cancreate'}{'selfcreate'} ne 'none') &&
                        ($usercreation->{'cancreate'}{'selfcreate'} ne '')) {
                   @cancreate = ($usercreation->{'cancreate'}{'selfcreate'});
               }
           }
       }
       return (\@cancreate,\@statustocreate);
   }
   
 sub create_account {  sub create_account {
     my ($r,$domain,$lonhost,$username,$domdesc) = @_;      my ($r,$domain,$lonhost,$username,$domdesc) = @_;
     my ($retrieved,$output,$upass) = &process_credentials($env{'form.logtoken'},      my ($retrieved,$output,$upass) = &process_credentials($env{'form.logtoken'},
Line 834  sub create_account { Line 837  sub create_account {
   
 sub username_validation {  sub username_validation {
     my ($r,$username,$domain,$domdesc,$contact_name,$contact_email,$courseid,      my ($r,$username,$domain,$domdesc,$contact_name,$contact_email,$courseid,
         $lonhost) = @_;          $lonhost,$statustocreate) = @_;
     my ($retrieved,$output,$upass);      my ($retrieved,$output,$upass);
   
     $username= &LONCAPA::clean_username($username);      $username= &LONCAPA::clean_username($username);
Line 849  sub username_validation { Line 852  sub username_validation {
     if ($uhome ne 'no_host') {      if ($uhome ne 'no_host') {
         my $result = &Apache::lonnet::authenticate($username,$upass,$domain);          my $result = &Apache::lonnet::authenticate($username,$upass,$domain);
         if ($result ne 'no_host') {           if ($result ne 'no_host') { 
             my %form = &start_session($r,$username,$domain,$lonhost,$courseid);              &start_session($r, $username, $domain, $lonhost, $courseid);
             $output = '<br /><br />'.&mt('A LON-CAPA account already exists for username [_1] at this institution ([_2]).','<tt>'.$username.'</tt>',$domdesc).'<br />'.&mt('The password entered was also correct so you have been logged in.');              $output = '<br /><br />'.&mt('A LON-CAPA account already exists for username [_1] at this institution ([_2]).','<tt>'.$username.'</tt>',$domdesc).'<br />'.&mt('The password entered was also correct so you have been logged in.');
             return ('existingaccount',$output);              return ('existingaccount',$output);
         } else {          } else {
Line 868  sub username_validation { Line 871  sub username_validation {
         }          }
         if ($authok eq 'authorized') {          if ($authok eq 'authorized') {
             $output = &username_check($username,$domain,$domdesc,$courseid,$lonhost,              $output = &username_check($username,$domain,$domdesc,$courseid,$lonhost,
                                       $contact_email,$contact_name);                                        $contact_email,$contact_name,undef,
                                         $statustocreate);
         } else {          } else {
             $output = &login_failure_msg($courseid);              $output = &login_failure_msg($courseid);
         }          }
Line 893  sub login_failure_msg { Line 897  sub login_failure_msg {
 }  }
   
 sub username_check {  sub username_check {
     my ($username,$domain,$domdesc,$courseid,$lonhost,$contact_email,$contact_name,      my ($username,$domain,$domdesc,$courseid,$lonhost,$contact_email,
         $sso_logout) = @_;          $contact_name,$sso_logout,$statustocreate) = @_;
     my (%rulematch,%inst_results,$checkfail,$rowcount,$editable,$output,$msg,      my (%rulematch,%inst_results,$checkfail,$rowcount,$editable,$output,$msg,
         %alerts,%curr_rules,%got_rules);          %alerts,%curr_rules,%got_rules);
     &call_rulecheck($username,$domain,\%alerts,\%rulematch,      &call_rulecheck($username,$domain,\%alerts,\%rulematch,
                     \%inst_results,\%curr_rules,%got_rules,'username');                      \%inst_results,\%curr_rules,\%got_rules,'username');
     if (ref($alerts{'username'}) eq 'HASH') {      if (ref($alerts{'username'}) eq 'HASH') {
         if (ref($alerts{'username'}{$domain}) eq 'HASH') {          if (ref($alerts{'username'}{$domain}) eq 'HASH') {
             if ($alerts{'username'}{$domain}{$username}) {              if ($alerts{'username'}{$domain}{$username}) {
Line 914  sub username_check { Line 918  sub username_check {
         }          }
     }      }
     if (!$checkfail) {      if (!$checkfail) {
           if (ref($statustocreate) eq 'ARRAY') {
               $checkfail = 'inststatus';
               if (ref($inst_results{$username.':'.$domain}{inststatus}) eq 'ARRAY') {
                   foreach my $inststatus (@{$inst_results{$username.':'.$domain}{inststatus}}) {
                       if (grep(/^\Q$inststatus\E$/,@{$statustocreate})) {
                           undef($checkfail);
                           last;
                       }
                   }
               } elsif (grep(/^default$/,@{$statustocreate})) {
                   undef($checkfail);
               }
           }
       }
       if (!$checkfail) {
         $output = '<form method="post" action="/adm/createaccount">';          $output = '<form method="post" action="/adm/createaccount">';
         (my $datatable,$rowcount,$editable) =           (my $datatable,$rowcount,$editable) = 
             &Apache::loncreateuser::personal_data_display($username,$domain,1,'selfcreate',              &Apache::loncreateuser::personal_data_display($username,$domain,1,'selfcreate',
Line 929  sub username_check { Line 948  sub username_check {
                     'time'       => $now,                      'time'       => $now,
                     'domain'     => $domain,                      'domain'     => $domain,
                     'username'   => $username);                      'username'   => $username);
         my $authtoken = &Apache::lonnet::tmpput(\%info,$lonhost);          my $authtoken = &Apache::lonnet::tmpput(\%info,$lonhost,'createaccount');
         if ($authtoken !~ /^error/ && $authtoken ne 'no_such_host') {          if ($authtoken !~ /^error/ && $authtoken ne 'no_such_host') {
             $output .= '<input type="hidden" name="authtoken" value="'.&HTML::Entities::encode($authtoken,'&<>"').'" />';              $output .= '<input type="hidden" name="authtoken" value="'.&HTML::Entities::encode($authtoken,'&<>"').'" />';
         } else {          } else {
Line 940  sub username_check { Line 959  sub username_check {
         }          }
     }      }
     if ($checkfail) {       if ($checkfail) { 
         $msg = '<h4>'.&mt('Account creation unavailable').'</h4>';          $msg = '<br /><h4>'.&mt('Account creation unavailable').'</h4>';
         if ($checkfail eq 'username') {          if ($checkfail eq 'username') {
             $msg .= '<span class="LC_warning">'.              $msg .= '<span class="LC_warning">'.
                      &mt('A LON-CAPA account may not be created with the username you use.').                       &mt('A LON-CAPA account may not be created with the username you use.').
Line 948  sub username_check { Line 967  sub username_check {
         } elsif ($checkfail eq 'authtoken') {          } elsif ($checkfail eq 'authtoken') {
             $msg .= '<span class="LC_error">'.&mt('Error creating token.').'</span>'.              $msg .= '<span class="LC_error">'.&mt('Error creating token.').'</span>'.
                     '<br />'.$output;                      '<br />'.$output;
           } elsif ($checkfail eq 'inststatus') {
               $msg .= '<span class="LC_warning">'.
                        &mt('You are not permitted to create a LON-CAPA account.').
                        '</span><br /><br />'.$output;
         }          }
         $msg .= &mt('Please contact the [_1] ([_2]) for assistance.',          $msg .= &mt('Please contact the [_1] ([_2]) for assistance.',
                 $contact_name,$contact_email).'<br /><hr />'.                  $contact_name,$contact_email).'<br /><hr />'.
Line 962  sub username_check { Line 985  sub username_check {
         if ($rowcount) {          if ($rowcount) {
             if ($editable) {              if ($editable) {
                 if ($courseid ne '') {                   if ($courseid ne '') { 
                     $msg = '<h4>'.&mt('User information').'</h4>';                      $msg = '<br /><h4>'.&mt('User information').'</h4>';
                 }                  }
                 $msg .= &mt('To create one, use the table below to provide information about yourself, then click the [_1]Create LON-CAPA account[_2] button.','<span class="LC_cusr_emph">','</span>').'<br />';                  $msg .= &mt('To create one, use the table below to provide information about yourself, then click the [_1]Create LON-CAPA account[_2] button.','<span class="LC_cusr_emph">','</span>').'<br />';
             } else {              } else {
Line 1026  sub username_activation { Line 1049  sub username_activation {
         # Call modifyuser          # Call modifyuser
         my (%rulematch,%inst_results,%curr_rules,%got_rules,%alerts,%info);          my (%rulematch,%inst_results,%curr_rules,%got_rules,%alerts,%info);
         &call_rulecheck($username,$domain,\%alerts,\%rulematch,          &call_rulecheck($username,$domain,\%alerts,\%rulematch,
                         \%inst_results,\%curr_rules,%got_rules);                          \%inst_results,\%curr_rules,\%got_rules);
         my @userinfo = ('firstname','middlename','lastname','generation',          my @userinfo = ('firstname','middlename','lastname','generation',
                         'permanentemail','id');                          'permanentemail','id');
         my %canmodify =           my %canmodify = 
Line 1053  sub username_activation { Line 1076  sub username_activation {
         if ($result eq 'ok') {          if ($result eq 'ok') {
             my $delete = &Apache::lonnet::tmpdel($env{'form.authtoken'});              my $delete = &Apache::lonnet::tmpdel($env{'form.authtoken'});
             $output = &mt('A LON-CAPA account has been created for username: [_1] in domain: [_2].',$username,$domain);              $output = &mt('A LON-CAPA account has been created for username: [_1] in domain: [_2].',$username,$domain);
             my %form = &start_session($r,$username,$domain,$lonhost,$courseid);              &start_session($r, $username, $domain, $lonhost, $courseid);
             my $nostart = 1;              my $nostart = 1;
             return ('ok',$output,$nostart);              return ('ok',$output,$nostart);
         } else {          } else {
Line 1099  sub invalid_state { Line 1122  sub invalid_state {
     my ($error,$domdesc,$contact_name,$contact_email,$msgtext) = @_;      my ($error,$domdesc,$contact_name,$contact_email,$msgtext) = @_;
     my $msg = '<h3>'.&mt('Account creation unavailable').'</h3><span class="LC_error">';      my $msg = '<h3>'.&mt('Account creation unavailable').'</h3><span class="LC_error">';
     if ($error eq 'baduseremail') {      if ($error eq 'baduseremail') {
         $msg = &mt('The e-mail address you provided does not appear to be a valid address.');          $msg .= &mt('The e-mail address you provided does not appear to be a valid address.');
     } elsif ($error eq 'existinguser') {      } elsif ($error eq 'existinguser') {
         $msg = &mt('The e-mail address you provided is already in use as a username in LON-CAPA at this institution.');          $msg .= &mt('The e-mail address you provided is already in use as a username in LON-CAPA at this institution.');
     } elsif ($error eq 'userrules') {      } elsif ($error eq 'userrules') {
         $msg = &mt('Username rules at this institution do not allow the e-mail address you provided to be used as a username.');          $msg .= &mt('Username rules at this institution do not allow the e-mail address you provided to be used as a username.');
     } elsif ($error eq 'userformat') {      } elsif ($error eq 'userformat') {
         $msg = &mt('The e-mail address you provided may not be used as a username at this LON-CAPA institution.');          $msg .= &mt('The e-mail address you provided may not be used as a username at this LON-CAPA institution.');
     } elsif ($error eq 'captcha') {      } elsif ($error eq 'captcha') {
         $msg = &mt('Validation of the code your entered failed.');          $msg .= &mt('Validation of the code you entered failed.');
     } elsif ($error eq 'noemails') {      } elsif ($error eq 'noemails') {
         $msg = &mt('Creation of a new user account using an e-mail address as username is not permitted at this LON-CAPA institution.');          $msg .= &mt('Creation of a new user account using an e-mail address as username is not permitted at this LON-CAPA institution.');
     }      }
     $msg .= '</span>';      $msg .= '</span>';
     if ($msgtext) {      if ($msgtext) {
         $msg .= '<br />'.$msgtext;          $msg .= '<br />'.$msgtext;
     }      }
     $msg .= &linkto_email_help($contact_email,$domdesc);      $msg .= &linkto_email_help($contact_email,$domdesc,$error);
     return $msg;      return $msg;
 }  }
   
 sub linkto_email_help {  sub linkto_email_help {
     my ($contact_email,$domdesc) = @_;      my ($contact_email,$domdesc,$error) = @_;
     my $msg;      my $msg;
       my $href = '/adm/helpdesk';
     if ($contact_email ne '') {      if ($contact_email ne '') {
         my $escuri = &HTML::Entities::encode('/adm/createaccount','&<>"');          my $escuri = &HTML::Entities::encode('/adm/createaccount','&<>"');
         $msg .= '<br />'.&mt('You may wish to contact the [_1]LON-CAPA helpdesk[_2] for [_3].','<a href="/adm/helpdesk?origurl='.$escuri.'">','</a>',$domdesc).'<br />';          $href .= '?origurl='.$escuri;
           if ($error eq 'existinguser') {
               my $escemail = &HTML::Entities::encode($env{'form.useremail'});
               $href .= '&useremail='.$escemail.'&useraccount='.$escemail;
           }
           $msg .= '<br />'.&mt('You may wish to contact the [_1]LON-CAPA helpdesk[_2] for [_3].','<a href="'.$href.'">','</a>',$domdesc).'<br />';
     } else {      } else {
         $msg .= '<br />'.&mt('You may wish to send an e-mail to the server administrator: [_1] for [_2].',$Apache::lonnet::perlvar{'AdminEmail'},$domdesc).'<br />';          $msg .= '<br />'.&mt('You may wish to send an e-mail to the server administrator: [_1] for [_2].',$Apache::lonnet::perlvar{'AdminEmail'},$domdesc).'<br />';
     }      }
Line 1147  sub create_captcha { Line 1176  sub create_captcha {
             $output = '<input type="hidden" name="crypt" value="'.$md5sum.'" />'."\n".              $output = '<input type="hidden" name="crypt" value="'.$md5sum.'" />'."\n".
                       &mt('Type in the letters/numbers shown below').'&nbsp;'.                        &mt('Type in the letters/numbers shown below').'&nbsp;'.
                      '<input type="text" size="5" name="code" value="" /><br />'.                       '<input type="text" size="5" name="code" value="" /><br />'.
                      '<img src="'.$captcha_params{'www_output_dir'}.'/'.$md5sum.'.png">';                       '<img src="'.$captcha_params{'www_output_dir'}.'/'.$md5sum.'.png" />';
             last;              last;
         }          }
     }      }
Line 1191  sub serverform { Line 1220  sub serverform {
    <input type="hidden" name="serverid" value="$lonhost" />     <input type="hidden" name="serverid" value="$lonhost" />
    <input type="hidden" name="uname" value="" />     <input type="hidden" name="uname" value="" />
    <input type="hidden" name="upass" value="" />     <input type="hidden" name="upass" value="" />
      <input type="hidden" name="udom" value="" />
    <input type="hidden" name="phase" value="$phase" />     <input type="hidden" name="phase" value="$phase" />
    <input type="hidden" name="courseid" value="$courseid" />     <input type="hidden" name="courseid" value="$courseid" />
    $catalog_elements     $catalog_elements

Removed from v.1.30  
changed lines
  Added in v.1.48


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