Diff for /loncom/interface/Attic/lonspreadsheet.pm between versions 1.104 and 1.105

version 1.104, 2002/08/30 19:47:47 version 1.105, 2002/08/30 20:56:08
Line 1461  sub readsheet { Line 1461  sub readsheet {
   
 sub makenewsheet {  sub makenewsheet {
     my ($uname,$udom,$stype,$usymb)=@_;      my ($uname,$udom,$stype,$usymb)=@_;
       my %sheetdata=();
       $sheetdata{'uname'} = $uname;
       $sheetdata{'udom'}  = $udom;
       $sheetdata{'sheettype'} = $stype;
       $sheetdata{'usymb'} = $usymb;
       $sheetdata{'cid'}   = $ENV{'request.course.id'};
       $sheetdata{'csec'}  = &Apache::lonnet::usection
                                  ($udom,$uname,$ENV{'request.course.id'});
       $sheetdata{'cfn'}   = $ENV{'request.course.fn'};
       $sheetdata{'cnum'}  = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
       $sheetdata{'cdom'}  = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
       $sheetdata{'chome'} = $ENV{'course.'.$ENV{'request.course.id'}.'.home'};
       $sheetdata{'uhome'} = &Apache::lonnet::homeserver($uname,$udom);
       
     my $safeeval=initsheet($stype);      my $safeeval=initsheet($stype);
     $safeeval->reval(      my $initstring = '';
        '$uname="'.$uname.      foreach (keys(%sheetdata)) {
       '";$udom="'.$udom.          $initstring.= qq{\$$_="$sheetdata{$_}";};
       '";$uhome="'.&Apache::lonnet::homeserver($uname,$udom).      }
       '";$sheettype="'.$stype.      $safeeval->reval($initstring);
       '";$usymb="'.$usymb.      return $safeeval,\%sheetdata;
       '";$csec="'.&Apache::lonnet::usection($udom,$uname,  
                                             $ENV{'request.course.id'}).  
       '";$cid="'.$ENV{'request.course.id'}.  
       '";$cfn="'.$ENV{'request.course.fn'}.  
       '";$cnum="'.$ENV{'course.'.$ENV{'request.course.id'}.'.num'}.  
       '";$cdom="'.$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}.  
       '";$chome="'.$ENV{'course.'.$ENV{'request.course.id'}.'.home'}.'";');  
     return $safeeval;  
 }  }
   
 # ------------------------------------------------------------ Save spreadsheet  # ------------------------------------------------------------ Save spreadsheet
Line 1615  this user and course. Line 1621  this user and course.
 ##################################################  ##################################################
 ##################################################  ##################################################
 sub parmval {  sub parmval {
     my ($what,$safeeval)=@_;      my ($what,$safeeval,$sheetdata)=@_;
     my $symb  = &getusymb($safeeval);      my $symb  = $sheetdata->{'usymb'};
     unless ($symb) { return ''; }      unless ($symb) { return ''; }
     #      #
     my $cid   = &getcid($safeeval);      my $cid   = $sheetdata->{'cid'};
     my $csec  = &getcsec($safeeval);      my $csec  = $sheetdata->{'csec'};
     my $uname = &getuname($safeeval);      my $uname = $sheetdata->{'uname'};
     my $udom  = &getudom($safeeval);      my $udom  = $sheetdata->{'udom'};
     my $result='';      my $result='';
     #      #
     my ($mapname,$id,$fn)=split(/\_\_\_/,$symb);      my ($mapname,$id,$fn)=split(/\_\_\_/,$symb);
Line 1646  sub parmval { Line 1652  sub parmval {
     if ($uname) {       if ($uname) { 
         return $useropt{$courselevelr} if ($useropt{$courselevelr});          return $useropt{$courselevelr} if ($useropt{$courselevelr});
         return $useropt{$courselevelm} if ($useropt{$courselevelm});          return $useropt{$courselevelm} if ($useropt{$courselevelm});
         return $useropt{$courselevel} if ($useropt{$courselevel});          return $useropt{$courselevel}  if ($useropt{$courselevel});
     }      }
     # third, check course      # third, check course
     if ($csec) {      if ($csec) {
         return $courseopt{$seclevelr} if ($courseopt{$seclevelr});          return $courseopt{$seclevelr} if ($courseopt{$seclevelr});
         return $courseopt{$seclevelm} if ($courseopt{$seclevelm});          return $courseopt{$seclevelm} if ($courseopt{$seclevelm});
         return $courseopt{$seclevel} if ($courseopt{$seclevel});          return $courseopt{$seclevel}  if ($courseopt{$seclevel});
     }      }
     #      #
     return $courseopt{$courselevelr} if ($courseopt{$courselevelr});      return $courseopt{$courselevelr} if ($courseopt{$courselevelr});
     return $courseopt{$courselevelm} if ($courseopt{$courselevelm});      return $courseopt{$courselevelm} if ($courseopt{$courselevelm});
     return $courseopt{$courselevel} if ($courseopt{$courselevel});      return $courseopt{$courselevel}  if ($courseopt{$courselevel});
     # second, check map parms      # second, check map parms
     my $thisparm = $parmhash{$symbparm};      my $thisparm = $parmhash{$symbparm};
     return $thisparm if ($thisparm);      return $thisparm if ($thisparm);
Line 1894  sub updatestudentassesssheet { Line 1900  sub updatestudentassesssheet {
 # ------------------------------------------------ Load data for one assessment  # ------------------------------------------------ Load data for one assessment
   
 sub loadstudent {  sub loadstudent {
     my $safeeval=shift;      my ($safeeval,$sheetdata)=@_;
     my %c=();      my %c=();
     my %f=&getformulas($safeeval);      my %f=&getformulas($safeeval);
     $cachedassess=&getuname($safeeval).':'.&getudom($safeeval);      $cachedassess=$sheetdata->{'uname'}.':'.$sheetdata->{'udom'};
     # Get ALL the student preformance data      # Get ALL the student preformance data
     my @tmp = &Apache::lonnet::dump(&getcid($safeeval),      my @tmp = &Apache::lonnet::dump($sheetdata->{'cid'},
                                     &getudom($safeeval),                                      $sheetdata->{'udom'},
                                     &getuname($safeeval),                                      $sheetdata->{'uname'},
                                     undef);                                      undef);
     if ($tmp[0] !~ /^error:/) {      if ($tmp[0] !~ /^error:/) {
         %cachedstores = @tmp;          %cachedstores = @tmp;
Line 1914  sub loadstudent { Line 1920  sub loadstudent {
         my $row=$1;          my $row=$1;
         next if (($f{$_}=~/^[\!\~\-]/) || ($row==0));          next if (($f{$_}=~/^[\!\~\-]/) || ($row==0));
         my ($usy,$ufn)=split(/__&&&\__/,$f{$_});          my ($usy,$ufn)=split(/__&&&\__/,$f{$_});
         @assessdata=&exportsheet(&getuname($safeeval),          @assessdata=&exportsheet($sheetdata->{'uname'},
                                  &getudom($safeeval),                                   $sheetdata->{'udom'},
                                  'assesscalc',$usy,$ufn);                                   'assesscalc',$usy,$ufn);
         my $index=0;          my $index=0;
         foreach ('A','B','C','D','E','F','G','H','I','J','K','L','M',          foreach ('A','B','C','D','E','F','G','H','I','J','K','L','M',
Line 1943  sub loadstudent { Line 1949  sub loadstudent {
 # --------------------------------------------------- Load data for one student  # --------------------------------------------------- Load data for one student
   
 sub loadcourse {  sub loadcourse {
     my ($safeeval,$r)=@_;      my ($safeeval,$sheetdata,$r)=@_;
     my %c=();      my %c=();
     my %f=&getformulas($safeeval);      my %f=&getformulas($safeeval);
     my $total=0;      my $total=0;
Line 2005  ENDPOP Line 2011  ENDPOP
 # ------------------------------------------------ Load data for one assessment  # ------------------------------------------------ Load data for one assessment
   
 sub loadassessment {  sub loadassessment {
     my $safeeval=shift;      my ($safeeval,$sheetdata)=@_;
   
     my $uhome = &getuhome($safeeval);      my $uhome = $sheetdata->{'uhome'};
     my $uname = &getuname($safeeval);      my $uname = $sheetdata->{'uname'};
     my $udom  = &getudom($safeeval);      my $udom  = $sheetdata->{'udom'};
     my $symb  = &getusymb($safeeval);      my $symb  = $sheetdata->{'usymb'};
     my $cid   = &getcid($safeeval);      my $cid   = $sheetdata->{'cid'};
     my $cnum  = &getcnum($safeeval);      my $cnum  = $sheetdata->{'cnum'};
     my $cdom  = &getcdom($safeeval);      my $cdom  = $sheetdata->{'cdom'};
     my $chome = &getchome($safeeval);      my $chome = $sheetdata->{'chome'};
   
     my $namespace;      my $namespace;
     unless ($namespace=$cid) { return ''; }      unless ($namespace=$cid) { return ''; }
Line 2070  sub loadassessment { Line 2076  sub loadassessment {
           
     unless ($uhome eq 'no_host') {       unless ($uhome eq 'no_host') { 
         # Get coursedata          # Get coursedata
         unless          unless ((time-$courserdatas{$cid.'.last_cache'})<240) {
             ((time-$courserdatas{$cid.'.last_cache'})<240) {              my $reply=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum.
                 my $reply=&Apache::lonnet::reply('dump:'.$cdom.':'.$cnum.                                               ':resourcedata',$chome);
                                                  ':resourcedata',$chome);              if ($reply!~/^error\:/) {
                 if ($reply!~/^error\:/) {                  $courserdatas{$cid}=$reply;
                     $courserdatas{$cid}=$reply;                  $courserdatas{$cid.'.last_cache'}=time;
                     $courserdatas{$cid.'.last_cache'}=time;  
                 }  
             }              }
           }
         foreach (split(/\&/,$courserdatas{$cid})) {          foreach (split(/\&/,$courserdatas{$cid})) {
             my ($name,$value)=split(/\=/,$_);              my ($name,$value)=split(/\=/,$_);
             $courseopt{$userprefix.&Apache::lonnet::unescape($name)}=              $courseopt{$userprefix.&Apache::lonnet::unescape($name)}=
Line 2122  sub loadassessment { Line 2127  sub loadassessment {
             next if  ($f{$_}=~/^[\!\~\-]/);              next if  ($f{$_}=~/^[\!\~\-]/);
             if ($f{$_}=~/^parameter/) {              if ($f{$_}=~/^parameter/) {
                 if ($thisassess{$f{$_}}) {                  if ($thisassess{$f{$_}}) {
                     my $val=&parmval($f{$_},$safeeval);                      my $val=&parmval($f{$_},$safeeval,$sheetdata);
                     $c{$_}=$val;                      $c{$_}=$val;
                     $c{$f{$_}}=$val;                      $c{$f{$_}}=$val;
                 }                  }
Line 2170  sub selectbox { Line 2175  sub selectbox {
 #  #
   
 sub updatesheet {  sub updatesheet {
     my $safeeval=shift;      my ($safeeval,$sheetdata)=@_;
     my $stype=&gettype($safeeval);      my $stype=$sheetdata->{'sheettype'};
     if ($stype eq 'classcalc') {      if ($stype eq 'classcalc') {
  return &updateclasssheet($safeeval);   return &updateclasssheet($safeeval);
     } else {      } else {
Line 2185  sub updatesheet { Line 2190  sub updatesheet {
 #  #
   
 sub loadrows {  sub loadrows {
     my ($safeeval,$r)=@_;      my ($safeeval,$sheetdata,$r)=@_;
     my $stype=&gettype($safeeval);      my $stype=$sheetdata->{'sheettype'};
     if ($stype eq 'classcalc') {      if ($stype eq 'classcalc') {
  &loadcourse($safeeval,$r);   &loadcourse($safeeval,$sheetdata,$r);
     } elsif ($stype eq 'studentcalc') {      } elsif ($stype eq 'studentcalc') {
         &loadstudent($safeeval);          &loadstudent($safeeval,$sheetdata);
     } else {      } else {
         &loadassessment($safeeval);          &loadassessment($safeeval,$sheetdata);
     }      }
 }  }
   
Line 2280  sub exportsheet { Line 2285  sub exportsheet {
         #          #
         # Not cached          # Not cached
         #                  #        
         my $thissheet=&makenewsheet($uname,$udom,$stype,$usymb);          my ($thissheet,$sheetdata)=&makenewsheet($uname,$udom,$stype,$usymb);
         &readsheet($thissheet,$fn);          &readsheet($thissheet,$fn);
         &updatesheet($thissheet);          &updatesheet($thissheet,$sheetdata);
         &loadrows($thissheet);          &loadrows($thissheet,$sheetdata);
         &calcsheet($thissheet);           &calcsheet($thissheet,$sheetdata); 
         @exportarr=&exportdata($thissheet);          @exportarr=&exportdata($thissheet,$sheetdata);
         #          #
         # Store now          # Store now
         #          #
Line 2299  sub exportsheet { Line 2304  sub exportsheet {
                                             &Apache::lonnet::escape($key),                                              &Apache::lonnet::escape($key),
                                             $ENV{'course.'.$cid.'.home'});                                              $ENV{'course.'.$cid.'.home'});
         } else {          } else {
             $current=&Apache::lonnet::reply('get:'.              $current=&Apache::lonnet::reply('get:'.$sheetdata->{'udom'}.':'.
                                             &getudom($thissheet).':'.                                              $sheetdata->{'uname'}.
                                             &getuname($thissheet).  
                                             ':nohist_calculatedsheets_'.                                              ':nohist_calculatedsheets_'.
                                             $ENV{'request.course.id'}.':'.                                              $ENV{'request.course.id'}.':'.
                                             &Apache::lonnet::escape($key),                                              &Apache::lonnet::escape($key),
                                             &getuhome($thissheet));                                              $sheetdata->{'uhome'});
         }          }
         my %currentlystored=();          my %currentlystored=();
         unless ($current=~/^error\:/) {          unless ($current=~/^error\:/) {
Line 2333  sub exportsheet { Line 2337  sub exportsheet {
                                    $ENV{'course.'.$cid.'.home'});                                     $ENV{'course.'.$cid.'.home'});
         } else {          } else {
             &Apache::lonnet::reply('put:'.              &Apache::lonnet::reply('put:'.
                                    &getudom($thissheet).':'.                                     $sheetdata->{'udom'}.':'.
                                    &getuname($thissheet).                                     $sheetdata->{'uname'}.
                                    ':nohist_calculatedsheets_'.                                     ':nohist_calculatedsheets_'.
                                    $ENV{'request.course.id'}.':'.                                     $ENV{'request.course.id'}.':'.
                                    &Apache::lonnet::escape($key).'='.                                     &Apache::lonnet::escape($key).'='.
                                    &Apache::lonnet::escape($newstore).'&'.                                     &Apache::lonnet::escape($newstore).'&'.
                                    &Apache::lonnet::escape($key).'.time='.$now,                                     &Apache::lonnet::escape($key).'.time='.$now,
                                    &getuhome($thissheet));                                     $sheetdata->{'uhome'});
         }          }
     }      }
     return @exportarr;      return @exportarr;
Line 2510  ENDSCRIPT Line 2514  ENDSCRIPT
         }          }
         # Read new sheet or modified worksheet          # Read new sheet or modified worksheet
         $r->uri=~/\/(\w+)$/;          $r->uri=~/\/(\w+)$/;
         my $asheet=&makenewsheet($aname,$adom,$1,$ENV{'form.usymb'});          my ($asheet,$asheetdata)=&makenewsheet
                                         ($aname,$adom,$1,$ENV{'form.usymb'});
         # If a new formula had been entered, go from work copy          # If a new formula had been entered, go from work copy
         if ($ENV{'form.unewfield'}) {          if ($ENV{'form.unewfield'}) {
             $r->print('<h2>Modified Workcopy</h2>');              $r->print('<h2>Modified Workcopy</h2>');
Line 2528  ENDSCRIPT Line 2533  ENDSCRIPT
             &readsheet($asheet,$ENV{'form.ufn'});              &readsheet($asheet,$ENV{'form.ufn'});
         }          }
         # Print out user information          # Print out user information
         unless (&gettype($asheet) eq 'classcalc') {          unless ($asheetdata->{'sheettype'} eq 'classcalc') {
             $r->print('<p><b>User:</b> '.&getuname($asheet).              $r->print('<p><b>User:</b> '.$asheetdata->{'uname'}.
                       '<br><b>Domain:</b> '.&getudom($asheet));                        '<br><b>Domain:</b> '.$asheetdata->{'udom'});
             if (&getcsec($asheet) eq '-1') {              if (&getcsec($asheet) eq '-1') {
                 $r->print('<h3><font color=red>'.                  $r->print('<h3><font color=red>'.
                           'Not a student in this course</font></h3>');                            'Not a student in this course</font></h3>');
             } else {              } else {
                 $r->print('<br><b>Section/Group:</b> '.&getcsec($asheet));                  $r->print('<br><b>Section/Group:</b> '.$asheetdata->{'csec'});
             }              }
             if ($ENV{'form.usymb'}) {              if ($ENV{'form.usymb'}) {
                 $r->print('<br><b>Assessment:</b> <tt>'.                  $r->print('<br><b>Assessment:</b> <tt>'.
Line 2543  ENDSCRIPT Line 2548  ENDSCRIPT
             }              }
         }          }
         # See if user can see this          # See if user can see this
         if ((&gettype($asheet) eq 'classcalc') ||           if (($asheetdata->{'sheettype'} eq 'classcalc'       ) || 
             (&getuname($asheet) ne $ENV{'user.name'}) ||              ($asheetdata->{'uname'}     ne $ENV{'user.name'} ) ||
             (&getudom($asheet) ne $ENV{'user.domain'})) {              ($asheetdata->{'udom'}      ne $ENV{'user.domain'})) {
             unless (&Apache::lonnet::allowed('vgr',&getcid($asheet))) {              unless (&Apache::lonnet::allowed('vgr',$asheetdata->{'cid'})) {
                 $r->print('<h1>Access Permission Denied</h1>'.                  $r->print('<h1>Access Permission Denied</h1>'.
                           '</form></body></html>');                            '</form></body></html>');
                 return OK;                  return OK;
Line 2556  ENDSCRIPT Line 2561  ENDSCRIPT
         $r->print(          $r->print(
  '<input type=submit name=forcerecalc value="Completely Recalculate Sheet"><p>'   '<input type=submit name=forcerecalc value="Completely Recalculate Sheet"><p>'
                   );                    );
         if (&gettype($asheet) eq 'assesscalc') {          if ($asheetdata->{'sheettype'} eq 'assesscalc') {
             $r->print ('<p><font size=+2><a href="/adm/studentcalc?uname='.              $r->print('<p><font size=+2>'.
                        &getuname($asheet).'&udom='.&getudom($asheet).'">'.                        '<a href="/adm/studentcalc?'.
                        'Level up: Student Sheet</a></font><p>');                        'uname='.$asheetdata->{'uname'}.
                         '&udom='.$asheetdata->{'udom'}.'">'.
                         'Level up: Student Sheet</a></font><p>');
         }          }
         if ((&gettype($asheet) eq 'studentcalc') &&           if (($asheetdata->{'sheettype'} eq 'studentcalc') && 
             (&Apache::lonnet::allowed('vgr',&getcid($asheet)))) {              (&Apache::lonnet::allowed('vgr',$asheetdata->{'cid'}))) {
             $r->print (              $r->print (
                        '<p><font size=+2><a href="/adm/classcalc">'.                         '<p><font size=+2><a href="/adm/classcalc">'.
                        'Level up: Course Sheet</a></font><p>');                         'Level up: Course Sheet</a></font><p>');
Line 2583  ENDSCRIPT Line 2590  ENDSCRIPT
             $r->print('<p><input type=submit name=load value="Load ...">'.              $r->print('<p><input type=submit name=load value="Load ...">'.
                       '<select name="loadthissheet">'.                        '<select name="loadthissheet">'.
                       '<option name="default">Default</option>');                        '<option name="default">Default</option>');
             foreach (&othersheets($asheet,&gettype($asheet))) {              foreach (&othersheets($asheet,$asheetdata->{'sheettype'})) {
                 $r->print('<option name="'.$_.'"');                  $r->print('<option name="'.$_.'"');
                 if ($ENV{'form.ufn'} eq $_) {                  if ($ENV{'form.ufn'} eq $_) {
                     $r->print(' selected');                      $r->print(' selected');
Line 2599  ENDSCRIPT Line 2606  ENDSCRIPT
         &expirationdates();          &expirationdates();
         undef %oldsheets;          undef %oldsheets;
         undef %loadedcaches;          undef %loadedcaches;
         if (&gettype($asheet) eq 'classcalc') {          if ($asheetdata->{'sheettype'} eq 'classcalc') {
             $r->print              $r->print
                 ("Loading previously calculated student sheets ...<br>\n");                  ("Loading previously calculated student sheets ...<br>\n");
             $r->rflush();              $r->rflush();
             &cachedcsheets();              &cachedcsheets();
         } elsif (&gettype($asheet) eq 'studentcalc') {          } elsif ($asheetdata->{'sheettype'} eq 'studentcalc') {
             $r->print              $r->print
                 ("Loading previously calculated assessment sheets ...<br>\n");                  ("Loading previously calculated assessment sheets ...<br>\n");
             $r->rflush();              $r->rflush();
             &cachedssheets(&getuname($asheet),&getudom($asheet),              &cachedssheets($asheetdata->{'uname'},$asheetdata->{'udom'},
                            &getuhome($asheet));                             $asheetdata->{'uhome'});
         }          }
         # Update sheet, load rows          # Update sheet, load rows
         $r->print("Loaded sheet(s), updating rows ...<br>\n");          $r->print("Loaded sheet(s), updating rows ...<br>\n");
         $r->rflush();          $r->rflush();
         #          #
         &updatesheet($asheet);          &updatesheet($asheet,$asheetdata);
         $r->print("Updated rows, loading row data ...<br>\n");          $r->print("Updated rows, loading row data ...<br>\n");
         $r->rflush();          $r->rflush();
         #          #
         &loadrows($asheet,$r);          &loadrows($asheet,$asheetdata,$r);
         $r->print("Loaded row data, calculating sheet ...<br>\n");          $r->print("Loaded row data, calculating sheet ...<br>\n");
         $r->rflush();          $r->rflush();
         #          #
Line 2631  ENDSCRIPT Line 2638  ENDSCRIPT
             if ($ENV{'form.saveas'} && ($fname=$ENV{'form.newfn'})) {              if ($ENV{'form.saveas'} && ($fname=$ENV{'form.newfn'})) {
                 $fname=~s/\W/\_/g;                  $fname=~s/\W/\_/g;
                 if ($fname eq 'default') { $fname='course_default'; }                  if ($fname eq 'default') { $fname='course_default'; }
                 $fname.='_'.&gettype($asheet);                  $fname.='_'.$asheetdata->{'sheettype'};
                 &setfilename($asheet,$fname);                  &setfilename($asheet,$fname);
                 $ENV{'form.ufn'}=$fname;                  $ENV{'form.ufn'}=$fname;
                 $r->print('<p>Saving spreadsheet: '.                  $r->print('<p>Saving spreadsheet: '.
Line 2640  ENDSCRIPT Line 2647  ENDSCRIPT
         }          }
         #Write the modified worksheet          #Write the modified worksheet
   
    $r->print('<b>Current sheet:</b> '.&getfilename($asheet).'<p>');              $r->print('<b>Current sheet:</b> '.&getfilename($asheet).'<p>');
   
    &tmpwrite($asheet);              &tmpwrite($asheet);
   
     if (&gettype($asheet) eq 'studentcalc') {      if ($asheetdata->{'sheettype'} eq 'studentcalc') {
  $r->print('<br>Show rows with empty A column: ');   $r->print('<br>Show rows with empty A column: ');
     } else {      } else {
         $r->print('<br>Show empty rows: ');          $r->print('<br>Show empty rows: ');
Line 2666  ENDSCRIPT Line 2673  ENDSCRIPT
     }      }
     $r->print('>');      $r->print('>');
   
     if (&gettype($asheet) eq 'classcalc') {      if ($asheetdata->{'sheettype'} eq 'classcalc') {
        $r->print(         $r->print(
    ' Output CSV format: <input type=checkbox name=showcsv onClick="submit()"');     ' Output CSV format: <input type=checkbox name=showcsv onClick="submit()"');
        if ($ENV{'form.showcsv'}) { $r->print(' checked'); }         if ($ENV{'form.showcsv'}) { $r->print(' checked'); }

Removed from v.1.104  
changed lines
  Added in v.1.105


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