Diff for /loncom/lonnet/perl/lonnet.pm between versions 1.481 and 1.507

version 1.481, 2004/03/31 19:25:08 version 1.507, 2004/06/09 14:57:30
Line 32  package Apache::lonnet; Line 32  package Apache::lonnet;
 use strict;  use strict;
 use LWP::UserAgent();  use LWP::UserAgent();
 use HTTP::Headers;  use HTTP::Headers;
 use Date::Parse;  use HTTP::Date;
   # use Date::Parse;
 use vars   use vars 
 qw(%perlvar %hostname %homecache %badServerCache %hostip %iphost %spareid %hostdom   qw(%perlvar %hostname %homecache %badServerCache %hostip %iphost %spareid %hostdom 
    %libserv %pr %prp %metacache %packagetab %titlecache %courseresversioncache %resversioncache     %libserv %pr %prp %metacache %packagetab %titlecache %courseresversioncache %resversioncache
Line 433  sub overloaderror { Line 434  sub overloaderror {
     if ($overload>0) {      if ($overload>0) {
  $r->err_headers_out->{'Retry-After'}=$overload;   $r->err_headers_out->{'Retry-After'}=$overload;
         $r->log_error('Overload of '.$overload.' on '.$checkserver);          $r->log_error('Overload of '.$overload.' on '.$checkserver);
         return 413;          return 409;
     }          }    
     return '';      return '';
 }  }
Line 616  sub idput { Line 617  sub idput {
     my ($udom,%ids)=@_;      my ($udom,%ids)=@_;
     my %servers=();      my %servers=();
     foreach (keys %ids) {      foreach (keys %ids) {
    &cput('environment',{'id'=>$ids{$_}},$udom,$_);
         my $uhom=&homeserver($_,$udom);          my $uhom=&homeserver($_,$udom);
         if ($uhom ne 'no_host') {          if ($uhom ne 'no_host') {
             my $id=&escape($ids{$_});              my $id=&escape($ids{$_});
Line 626  sub idput { Line 628  sub idput {
             } else {              } else {
                 $servers{$uhom}=$id.'='.$unam;                  $servers{$uhom}=$id.'='.$unam;
             }              }
             &critical('put:'.$udom.':'.$unam.':environment:id='.$id,$uhom);  
         }          }
     }      }
     foreach (keys %servers) {      foreach (keys %servers) {
Line 641  sub assign_access_key { Line 642  sub assign_access_key {
 # a valid key looks like uname:udom#comments  # a valid key looks like uname:udom#comments
 # comments are being appended  # comments are being appended
 #  #
     my ($ckey,$cdom,$cnum,$udom,$uname,$logentry)=@_;      my ($ckey,$kdom,$knum,$cdom,$cnum,$udom,$uname,$logentry)=@_;
       $kdom=
      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($kdom));
       $knum=
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($knum));
     $cdom=      $cdom=
    $ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($cdom));     $ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($cdom));
     $cnum=      $cnum=
    $ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($cnum));     $ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($cnum));
     $udom=$ENV{'user.name'} unless (defined($udom));      $udom=$ENV{'user.name'} unless (defined($udom));
     $uname=$ENV{'user.domain'} unless (defined($uname));      $uname=$ENV{'user.domain'} unless (defined($uname));
     my %existing=&get('accesskeys',[$ckey],$cdom,$cnum);      my %existing=&get('accesskeys',[$ckey],$kdom,$knum);
     if (($existing{$ckey}=~/^\#(.*)$/) || # - new key      if (($existing{$ckey}=~/^\#(.*)$/) || # - new key
         ($existing{$ckey}=~/^\Q$uname\E\:\Q$udom\E\#(.*)$/)) {           ($existing{$ckey}=~/^\Q$uname\E\:\Q$udom\E\#(.*)$/)) { 
                                                   # assigned to this person                                                    # assigned to this person
Line 657  sub assign_access_key { Line 662  sub assign_access_key {
                                                   # the first time around                                                    # the first time around
 # ready to assign  # ready to assign
         $logentry=$1.'; '.$logentry;          $logentry=$1.'; '.$logentry;
         if (&put('accesskey',{$ckey=>$uname.':'.$udom.'#'.$logentry},          if (&put('accesskeys',{$ckey=>$uname.':'.$udom.'#'.$logentry},
                                                  $cdom,$cnum) eq 'ok') {                                                   $kdom,$knum) eq 'ok') {
 # key now belongs to user  # key now belongs to user
     my $envkey='key.'.$cdom.'_'.$cnum;      my $envkey='key.'.$cdom.'_'.$cnum;
             if (&put('environment',{$envkey => $ckey}) eq 'ok') {              if (&put('environment',{$envkey => $ckey}) eq 'ok') {
Line 754  sub validate_access_key { Line 759  sub validate_access_key {
    $ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($cdom));     $ENV{'course.'.$ENV{'request.course.id'}.'.domain'} unless (defined($cdom));
     $cnum=      $cnum=
    $ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($cnum));     $ENV{'course.'.$ENV{'request.course.id'}.'.num'} unless (defined($cnum));
     $udom=$ENV{'user.name'} unless (defined($udom));      $udom=$ENV{'user.domain'} unless (defined($udom));
     $uname=$ENV{'user.domain'} unless (defined($uname));      $uname=$ENV{'user.name'} unless (defined($uname));
     my %existing=&get('accesskeys',[$ckey],$cdom,$cnum);      my %existing=&get('accesskeys',[$ckey],$cdom,$cnum);
     return ($existing{$ckey}=~/^\Q$uname\E\:\Q$udom\E\#/);      return ($existing{$ckey}=~/^\Q$uname\E\:\Q$udom\E\#/);
 }  }
Line 1164  sub externalssi { Line 1169  sub externalssi {
     return $response->content;      return $response->content;
 }  }
   
 # ------- Add a token to a remote URI's query string to vouch for access rights  # -------------------------------- Allow a /uploaded/ URI to be vouched for
   
 sub tokenwrapper {  sub allowuploaded {
     my $uri=shift;      my ($srcurl,$url)=@_;
     $uri=~s/^http\:\/\/([^\/]+)//;      $url=&clutter(&declutter($url));
     $uri=~s/^\///;      my $dir=$url;
     $ENV{'user.environment'}=~/\/([^\/]+)\.id/;      $dir=~s/\/[^\/]+$//;
     my $token=$1;      my %httpref=();
 #    if ($uri=~/^uploaded\/([^\/]+)\/([^\/]+)\/([^\/]+)(\?\.*)*$/) {      my $httpurl=&hreflocation('',$url);
     if ($uri=~m|^uploaded/([^/]+)/([^/]+)/(.+)(\?\.*)*$|) {      $httpref{'httpref.'.$httpurl}=$srcurl;
  &appenv('userfile.'.$1.'/'.$2.'/'.$3 => $ENV{'request.course.id'});      &Apache::lonnet::appenv(%httpref);
         return 'http://'.$hostname{ &homeserver($2,$1)}.'/'.$uri.  
                (($uri=~/\?/)?'&':'?').'token='.$token.  
                                '&tokenissued='.$perlvar{'lonHostID'};  
     } else {  
  return '/adm/notfound.html';  
     }  
 }  }
   
 # --------- File operations in /home/httpd/html/userfiles/$domain/1/2/3/$course  # --------- File operations in /home/httpd/html/userfiles/$domain/1/2/3/$course
 # input: action, courseID, current domain, home server for course, intended  # input: action, courseID, current domain, home server for course, intended
 #        path to file, source of file.  #        path to file, source of file.
 # output: ok if successful, diagnostic message otherwise  # output: url to file (if action was uploaddoc), 
   #         ok if successful, or diagnostic message otherwise (if action was propagate or copy)
 #  #
 # Allows directory structure to be used within lonUsers/../userfiles/ for a   # Allows directory structure to be used within lonUsers/../userfiles/ for a 
 # course.  # course.
Line 1201  sub tokenwrapper { Line 1201  sub tokenwrapper {
 #         and will then be copied to  #         and will then be copied to
 #          /home/httpd/lonUsers/$domain/1/2/3/$course/userfiles/$file in  #          /home/httpd/lonUsers/$domain/1/2/3/$course/userfiles/$file in
 #         course's home server.  #         course's home server.
   #
 # action = uploaddoc - /home/httpd/html/userfiles/$domain/1/2/3/$course/$file  # action = uploaddoc - /home/httpd/html/userfiles/$domain/1/2/3/$course/$file
 #         will be retrived from $ENV{form.$source} via DOCS interface to  #         will be retrived from $ENV{form.uploaddoc} (from DOCS interface) to
 #         /home/httpd/html/userfiles/$domain/1/2/3/$course/$file  #         /home/httpd/html/userfiles/$domain/1/2/3/$course/$file
 #         and will then be copied to /home/httpd/lonUsers/1/2/3/$course/userfiles/$file  #         and will then be copied to /home/httpd/lonUsers/1/2/3/$course/userfiles/$file
 #         in course's home server.  #         in course's home server.
Line 1255  sub process_coursefile { Line 1256  sub process_coursefile {
             }              }
         }          }
     }      }
     unless ( ($fetchresult eq 'ok') || ($fetchresult eq 'no source file') ) {      unless ( $fetchresult eq 'ok') {
         &logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file.          &logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file.
              ' to host '.$docuhome.': '.$fetchresult);               ' to host '.$docuhome.': '.$fetchresult);
     }      }
Line 1267  sub process_coursefile { Line 1268  sub process_coursefile {
 # output: url of file in userspace  # output: url of file in userspace
   
 sub userfileupload {  sub userfileupload {
     my ($formname,$coursedoc)=@_;      my ($formname,$coursedoc,$subdir)=@_;
       if (!defined($subdir)) { $subdir='unknown'; }
     my $fname=$ENV{'form.'.$formname.'.filename'};      my $fname=$ENV{'form.'.$formname.'.filename'};
 # Replace Windows backslashes by forward slashes  # Replace Windows backslashes by forward slashes
     $fname=~s/\\/\//g;      $fname=~s/\\/\//g;
Line 1280  sub userfileupload { Line 1282  sub userfileupload {
 # See if there is anything left  # See if there is anything left
     unless ($fname) { return 'error: no uploaded file'; }      unless ($fname) { return 'error: no uploaded file'; }
     chop($ENV{'form.'.$formname});      chop($ENV{'form.'.$formname});
     my $url = '';  
 # Create the directory if not present  # Create the directory if not present
     my $docuname='';      my $docuname='';
     my $docudom='';      my $docudom='';
     my $docuhome='';      my $docuhome='';
       $fname="$subdir/$fname";
     if ($coursedoc) {      if ($coursedoc) {
  $docuname=$ENV{'course.'.$ENV{'request.course.id'}.'.num'};   $docuname=$ENV{'course.'.$ENV{'request.course.id'}.'.num'};
  $docudom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};   $docudom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
  $docuhome=$ENV{'course.'.$ENV{'request.course.id'}.'.home'};   $docuhome=$ENV{'course.'.$ENV{'request.course.id'}.'.home'};
         if ($ENV{'form.folder'} =~ m/^default/) {          if ($ENV{'form.folder'} =~ m/^default/) {
             $url = &finishuserfileupload($docuname,$docudom,$docuhome,$formname,$fname);              return &finishuserfileupload($docuname,$docudom,$docuhome,$formname,$fname);
         } else {          } else {
             $fname=$ENV{'form.folder'}.'/'.$fname;              $fname=$ENV{'form.folder'}.'/'.$fname;
             $url = &process_coursefile('uploaddoc',$docuname,$docudom,$docuhome,$fname,$formname);              return &process_coursefile('uploaddoc',$docuname,$docudom,$docuhome,$fname,$formname);
         }          }
     } else {      } else {
         $docuname=$ENV{'user.name'};          $docuname=$ENV{'user.name'};
         $docudom=$ENV{'user.domain'};          $docudom=$ENV{'user.domain'};
         $docuhome=$ENV{'user.home'};          $docuhome=$ENV{'user.home'};
           return &finishuserfileupload($docuname,$docudom,$docuhome,$formname,$fname);
     }      }
     return   
         &finishuserfileupload($docuname,$docudom,$docuhome,$formname,$fname);  
 }  }
   
 sub finishuserfileupload {  sub finishuserfileupload {
     my ($docuname,$docudom,$docuhome,$formname,$fname)=@_;      my ($docuname,$docudom,$docuhome,$formname,$fname)=@_;
     my $path=$docudom.'/'.$docuname.'/';      my $path=$docudom.'/'.$docuname.'/';
     my $filepath=$perlvar{'lonDocRoot'};      my $filepath=$perlvar{'lonDocRoot'};
       my ($fnamepath,$file);
       $file=$fname;
       if ($fname=~m|/|) {
           ($fnamepath,$file) = ($fname =~ m|^(.*)/([^/]+)$|);
    $path.=$fnamepath.'/';
       }
     my @parts=split(/\//,$filepath.'/userfiles/'.$path);      my @parts=split(/\//,$filepath.'/userfiles/'.$path);
     my $count;      my $count;
     for ($count=4;$count<=$#parts;$count++) {      for ($count=4;$count<=$#parts;$count++) {
Line 1318  sub finishuserfileupload { Line 1325  sub finishuserfileupload {
     }      }
 # Save the file  # Save the file
     {      {
        open(my $fh,'>'.$filepath.'/'.$fname);   #&Apache::lonnet::logthis("Saving to $filepath $file");
          open(my $fh,'>'.$filepath.'/'.$file);
        print $fh $ENV{'form.'.$formname};         print $fh $ENV{'form.'.$formname};
        close($fh);         close($fh);
     }      }
 # Notify homeserver to grep it  # Notify homeserver to grep it
 #  #
     my $fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$fname,      my $fetchresult= &reply('fetchuserfile:'.$path.$file,$docuhome);
     $docuhome);  
     if ($fetchresult eq 'ok') {      if ($fetchresult eq 'ok') {
 #  #
 # Return the URL to it  # Return the URL to it
         return '/uploaded/'.$path.$fname;          return '/uploaded/'.$path.$file;
     } else {      } else {
         &logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$fname.          &logthis('Failed to transfer '.$path.$file.' to host '.$docuhome.
          ' to host '.$docuhome.': '.$fetchresult);   ': '.$fetchresult);
         return '/adm/notfound.html';          return '/adm/notfound.html';
     }          }    
 }  }
   
   sub removeuploadedurl {
       my ($url)=@_;
       my (undef,undef,$udom,$uname,$fname)=split('/',$url,5);
       return &Apache::lonnet::removeuserfile($uname,$udom,$fname);
   }
   
   sub removeuserfile {
       my ($docuname,$docudom,$fname)=@_;
       my $home=&homeserver($docuname,$docudom);
       return &reply("removeuserfile:$docudom/$docuname/$fname",$home);
   }
   
 # ------------------------------------------------------------------------- Log  # ------------------------------------------------------------------------- Log
   
 sub log {  sub log {
Line 1596  sub courseidput { Line 1615  sub courseidput {
 }  }
   
 sub courseiddump {  sub courseiddump {
     my ($domfilter,$descfilter,$sincefilter)=@_;      my ($domfilter,$descfilter,$sincefilter,$hostid)=@_;
     my %returnhash=();      my %returnhash=();
     unless ($domfilter) { $domfilter=''; }      unless ($domfilter) { $domfilter=''; }
     foreach my $tryserver (keys %libserv) {      foreach my $tryserver (keys %libserv) {
  if ((!$domfilter) || ($hostdom{$tryserver} eq $domfilter)) {          if (($hostid && $tryserver eq $hostid) || (!$hostid)) {
     foreach (      if ((!$domfilter) || ($hostdom{$tryserver} eq $domfilter)) {
              split(/\&/,&reply('courseiddump:'.$hostdom{$tryserver}.':'.          foreach (
                    split(/\&/,&reply('courseiddump:'.$hostdom{$tryserver}.':'.
        $sincefilter.':'.&escape($descfilter),         $sincefilter.':'.&escape($descfilter),
                                $tryserver))) {                                 $tryserver))) {
  my ($key,$value)=split(/\=/,$_);      my ($key,$value)=split(/\=/,$_);
                 if (($key) && ($value)) {                      if (($key) && ($value)) {
     $returnhash{&unescape($key)}=&unescape($value);          $returnhash{&unescape($key)}=&unescape($value);
                       }
                 }                  }
             }              }
   
         }          }
     }      }
     return %returnhash;      return %returnhash;
Line 1619  sub courseiddump { Line 1639  sub courseiddump {
 #  #
 # ----------------------------------------------------------- Check out an item  # ----------------------------------------------------------- Check out an item
   
   sub get_first_access {
       my ($type,$argsymb)=@_;
       my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser();
       if ($argsymb) { $symb=$argsymb; }
       my ($map,$id,$res)=&decode_symb($symb);
       if ($type eq 'map') { $res=$map; }
       my %times=&get('firstaccesstimes',[$res],$udom,$uname);
       return $times{$res};
   }
   
   sub set_first_access {
       my ($type)=@_;
       my ($symb,$courseid,$udom,$uname)=&Apache::lonxml::whichuser();
       my ($map,$id,$res)=&decode_symb($symb);
       if ($type eq 'map') { $res=$map; }
       my $firstaccess=&get_first_access($type);
       if (!$firstaccess) {
    return &put('firstaccesstimes',{$res=>time},$udom,$uname);
       }
       return 'already_set';
   }
   
 sub checkout {  sub checkout {
     my ($symb,$tuname,$tudom,$tcrsid)=@_;      my ($symb,$tuname,$tudom,$tcrsid)=@_;
     my $now=time;      my $now=time;
Line 1797  sub hash2str { Line 1839  sub hash2str {
 sub hashref2str {  sub hashref2str {
   my ($hashref)=@_;    my ($hashref)=@_;
   my $result='__HASH_REF__';    my $result='__HASH_REF__';
   foreach (keys(%$hashref)) {    foreach (sort(keys(%$hashref))) {
     if (ref($_) eq 'ARRAY') {      if (ref($_) eq 'ARRAY') {
       $result.=&arrayref2str($_).'=';        $result.=&arrayref2str($_).'=';
     } elsif (ref($_) eq 'HASH') {      } elsif (ref($_) eq 'HASH') {
Line 2681  sub allowed { Line 2723  sub allowed {
   
 # URI is an uploaded document for this course  # URI is an uploaded document for this course
   
     if (($priv eq 'bre') &&       if (($priv eq 'bre') && ($uri=~m|^uploaded/|)) {
         ($uri=~/^uploaded\/$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}\/$ENV{'course.'.$ENV{'request.course.id'}.'.num'}/)) {   my $refuri=$ENV{'httpref.'.$orguri};
         return 'F';   if ($refuri) {
       if ($refuri =~ m|^/adm/|) {
    $thisallowed='F';
       }
    }
     }      }
   
 # Full access at system, domain or course-wide level? Exit.  # Full access at system, domain or course-wide level? Exit.
   
     if ($thisallowed=~/F/) {      if ($thisallowed=~/F/) {
Line 3007  sub log_query { Line 3054  sub log_query {
     return get_query_reply($queryid);      return get_query_reply($queryid);
 }  }
   
   # ------- Request retrieval of institutional classlists from course homerserver
   
   sub fetch_enrollment_query {
       my ($homeserver,$dom,$affiliatesref,$replyref) = @_;
       my $host=$hostname{$homeserver};
       my $cmd = '';
       foreach (keys %{$affiliatesref}) {
           $cmd .= $_.'='.join(",",@{$$affiliatesref{$_}}).'%%'; 
       }
       $cmd =~ s/%%$//;
       $cmd = &escape($cmd);
       my $query = 'fetchenrollment';
       my $queryid=&reply("querysend:".$query.':'.$dom.':'.$ENV{'user.name'}.':'.$cmd,$homeserver);
       unless ($queryid=~/^\Q$host\E\_/) { return 'error: '.$queryid; }
       my $reply = &get_query_reply($queryid);
       unless ( ($reply =~/^timeout/) || ($reply =~/^error/) ) {
           unless ($homeserver eq $perlvar{'lonHostID'}) {
               my @responses = split/:/,$reply;
               my $pathname = $perlvar{'lonDaemons'}.'/tmp';
               foreach (@responses) {
                   my ($key,$value) = split/=/,$_;
                   $$replyref{$key} = $value;
                   if ($value > 0) {
                       foreach (@{$$affiliatesref{$key}}) {
                           my $filename = $dom.'_'.$key.'_'.$_.'_classlist.xml';
                           my $destname = $pathname.'/'.$filename;
                           my $xml_classlist = &reply("autoretrieve:".$filename,$homeserver);
                           unless ($xml_classlist =~ /^error/) {
                               if ( open(FILE,">$destname") ) {
                                   print FILE &unescape($xml_classlist);
                                   close(FILE);
                               }
                           }
                       }
                   }
               }
           }
           return 'ok';
       }
       return 'error';
   }
   
 sub get_query_reply {  sub get_query_reply {
     my $queryid=shift;      my $queryid=shift;
     my $replyfile=$perlvar{'lonDaemons'}.'/tmp/'.$queryid;      my $replyfile=$perlvar{'lonDaemons'}.'/tmp/'.$queryid;
Line 3051  sub userlog_query { Line 3140  sub userlog_query {
     return &log_query($uname,$udom,'userlog',%filters);      return &log_query($uname,$udom,'userlog',%filters);
 }  }
   
   #--------- Call auto-enrollment subs in localenroll.pm for homeserver for course 
   
   sub auto_run {
       my $homeserver = shift;
       my $response = &reply('autorun',$homeserver);
       return $response;
   }
                                                                                      
   sub auto_get_sections {
       my ($homeserver,$coursecode) = @_;
       my @secs = ();
       my $response=&unescape(&reply('autogetsections:'.$coursecode,$homeserver));
       unless ($response eq 'refused') {
           @secs = split/:/,$response;
       }
       return @secs;
   }
                                                                                      
   sub auto_new_course {
       my ($homeserver,$course_id,$owner) = @_;
       my $response=&unescape(&reply('autonewcourse:'.$course_id.':'.$owner,$homeserver));
       return $response;
   }
                                                                                      
   sub auto_validate_courseID {
       my ($homeserver,$course_id) = @_;
       my $response=&unescape(&reply('autovalidatecourse:'.$course_id,$homeserver));
       return $response;
   }
                                                                                      
   sub auto_create_password {
       my ($homeserver,$authparam) = @_;
       my $create_passwd = 0;
       my $authchk = '';
       my $response=&unescape(&reply('autocreatepassword:'.$authparam,$homeserver));
       if ($response eq 'refused') {
           $authchk = 'refused';
       } else {
           ($authparam,$create_passwd,$authchk) = split/:/,$response;
       }
       return ($authparam,$create_passwd,$authchk);
   }
   
 # ------------------------------------------------------------------ Plain Text  # ------------------------------------------------------------------ Plain Text
   
 sub plaintext {  sub plaintext {
Line 3306  sub modify_student_enrollment { Line 3438  sub modify_student_enrollment {
     }      }
     my $fullname = &Apache::loncoursedata::ProcessFullName($last,$gene,      my $fullname = &Apache::loncoursedata::ProcessFullName($last,$gene,
                                                            $first,$middle);                                                             $first,$middle);
     my $value=&escape($uname.':'.$udom).'='.      my $reply=cput('classlist',
  &escape(join(':',$end,$start,$uid,$usec,$fullname,$type));     {"$uname:$udom" => 
     my $reply=critical('put:'.$cdom.':'.$cnum.':classlist:'.$value,$chome);   join(':',$end,$start,$uid,$usec,$fullname,$type) },
      $cdom,$cnum);
     unless (($reply eq 'ok') || ($reply eq 'delayed')) {      unless (($reply eq 'ok') || ($reply eq 'delayed')) {
  return 'error: '.$reply;   return 'error: '.$reply;
     }      }
Line 3936  sub metadata { Line 4069  sub metadata {
     # if it is a non metadata possible uri return quickly      # if it is a non metadata possible uri return quickly
     if (($uri eq '') || (($uri =~ m|^/*adm/|) && ($uri !~ m|^adm/includes|)) ||      if (($uri eq '') || (($uri =~ m|^/*adm/|) && ($uri !~ m|^adm/includes|)) ||
         ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ /^~/) ||          ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ /^~/) ||
  ($uri =~ m|home/[^/]+/public_html/|) || ($uri =~ m|^uploaded/|)) {   ($uri =~ m|home/[^/]+/public_html/|)) {
  return undef;   return undef;
     }      }
     my $filename=$uri;      my $filename=$uri;
Line 3965  sub metadata { Line 4098  sub metadata {
  }   }
         my %metathesekeys=();          my %metathesekeys=();
         unless ($filename=~/\.meta$/) { $filename.='.meta'; }          unless ($filename=~/\.meta$/) { $filename.='.meta'; }
  my $metastring=&getfile(&filelocation('',&clutter($filename)));   my $metastring;
    if ($uri !~ m|^uploaded/|) {
       $metastring=&getfile(&filelocation('',&clutter($filename)));
    }
         my $parser=HTML::LCParser->new(\$metastring);          my $parser=HTML::LCParser->new(\$metastring);
         my $token;          my $token;
         undef %metathesekeys;          undef %metathesekeys;
Line 4076  sub metadata { Line 4212  sub metadata {
 # the next is the end of "start tag"  # the next is the end of "start tag"
     }      }
  }   }
    my ($extension) = ($uri =~ /\.(\w+)$/);
    foreach my $key (sort(keys(%packagetab))) {
       #&logthis("extsion1 $extension $key !!");
       #no specific packages #how's our extension
       if ($key!~/^extension_\Q$extension\E&/) { next; }
       &metadata_create_package_def($uri,$key,'extension_'.$extension,
    \%metathesekeys);
    }
    if (!exists($metacache{$uri}->{':packages'})) {
       foreach my $key (sort(keys(%packagetab))) {
    #no specific packages well let's get default then
    if ($key!~/^default&/) { next; }
    &metadata_create_package_def($uri,$key,'default',
        \%metathesekeys);
       }
    }
 # are there custom rights to evaluate  # are there custom rights to evaluate
  if ($metacache{$uri}->{':copyright'} eq 'custom') {   if ($metacache{$uri}->{':copyright'} eq 'custom') {
   
Line 4104  sub metadata { Line 4256  sub metadata {
     return $metacache{$uri}->{':'.$what};      return $metacache{$uri}->{':'.$what};
 }  }
   
   sub metadata_create_package_def {
       my ($uri,$key,$package,$metathesekeys)=@_;
       my ($pack,$name,$subp)=split(/\&/,$key);
       if ($subp eq 'default') { next; }
       
       if (defined($metacache{$uri}->{':packages'})) {
    $metacache{$uri}->{':packages'}.=','.$package;
       } else {
    $metacache{$uri}->{':packages'}=$package;
       }
       my $value=$packagetab{$key};
       my $unikey;
       $unikey='parameter_0_'.$name;
       $metacache{$uri}->{':'.$unikey.'.part'}=0;
       $$metathesekeys{$unikey}=1;
       unless (defined($metacache{$uri}->{':'.$unikey.'.'.$subp})) {
    $metacache{$uri}->{':'.$unikey.'.'.$subp}=$value;
       }
       if (defined($metacache{$uri}->{':'.$unikey.'.default'})) {
    $metacache{$uri}->{':'.$unikey}=
       $metacache{$uri}->{':'.$unikey.'.default'};
       }
   }
   
 sub metadata_generate_part0 {  sub metadata_generate_part0 {
     my ($metadata,$metacache,$uri) = @_;      my ($metadata,$metacache,$uri) = @_;
     my %allnames;      my %allnames;
Line 4231  sub symbclean { Line 4407  sub symbclean {
 # remove version from URL  # remove version from URL
     $symb=~s/\.(\d+)\.(\w+)$/\.$2/;      $symb=~s/\.(\d+)\.(\w+)$/\.$2/;
   
   # remove wrapper
   
       $symb=~s/(\_\_\_\d+\_\_\_)adm\/wrapper\//$1/;
     return $symb;      return $symb;
 }  }
   
Line 4378  sub numval { Line 4557  sub numval {
     return int($txt);      return int($txt);
 }  }
   
   sub numval2 {
       my $txt=shift;
       $txt=~tr/A-J/0-9/;
       $txt=~tr/a-j/0-9/;
       $txt=~tr/K-T/0-9/;
       $txt=~tr/k-t/0-9/;
       $txt=~tr/U-Z/0-5/;
       $txt=~tr/u-z/0-5/;
       $txt=~s/\D//g;
       my @txts=split(/(\d\d\d\d\d\d\d\d\d)/,$txt);
       my $total;
       foreach my $val (@txts) { $total+=$val; }
       return int($total);
   }
   
 sub latest_rnd_algorithm_id {  sub latest_rnd_algorithm_id {
     return '64bit2';      return '64bit3';
   }
   
   sub get_rand_alg {
       my ($courseid)=@_;
       if (!$courseid) { $courseid=(&Apache::lonxml::whichuser())[1]; }
       if ($courseid) {
    return $ENV{"course.$courseid.rndseed"};
       }
       return &latest_rnd_algorithm_id();
   }
   
   sub getCODE {
       if (defined($ENV{'form.CODE'})) { return $ENV{'form.CODE'}; }
       if (defined($Apache::lonhomework::parsing_a_problem) &&
    defined($Apache::lonhomework::history{'resource.CODE'})) {
    return $Apache::lonhomework::history{'resource.CODE'};
       }
       return undef;
 }  }
   
 sub rndseed {  sub rndseed {
Line 4392  sub rndseed { Line 4604  sub rndseed {
     if (!$courseid) { $courseid=$wcourseid; }      if (!$courseid) { $courseid=$wcourseid; }
     if (!$domain) { $domain=$wdomain; }      if (!$domain) { $domain=$wdomain; }
     if (!$username) { $username=$wusername }      if (!$username) { $username=$wusername }
     my $which=$ENV{"course.$courseid.rndseed"};      my $which=&get_rand_alg();
     my $CODE=$ENV{'scantron.CODE'};      if (defined(&getCODE())) {
     if (defined($CODE)) {   return &rndseed_CODE_64bit($symb,$courseid,$domain,$username);
  &rndseed_CODE_64bit($symb,$courseid,$domain,$username);      } elsif ($which eq '64bit3') {
    return &rndseed_64bit3($symb,$courseid,$domain,$username);
     } elsif ($which eq '64bit2') {      } elsif ($which eq '64bit2') {
  return &rndseed_64bit2($symb,$courseid,$domain,$username);   return &rndseed_64bit2($symb,$courseid,$domain,$username);
     } elsif ($which eq '64bit') {      } elsif ($which eq '64bit') {
Line 4463  sub rndseed_64bit2 { Line 4676  sub rndseed_64bit2 {
     }      }
 }  }
   
   sub rndseed_64bit3 {
       my ($symb,$courseid,$domain,$username)=@_;
       {
    use integer;
    # strings need to be an even # of cahracters long, it it is odd the
           # last characters gets thrown away
    my $symbchck=unpack("%32S*",$symb.' ') << 21;
    my $symbseed=numval2($symb) << 10;
    my $namechck=unpack("%32S*",$username.' ');
   
    my $nameseed=numval2($username) << 21;
    my $domainseed=unpack("%32S*",$domain.' ') << 10;
    my $courseseed=unpack("%32S*",$courseid.' ');
   
    my $num1=$symbchck+$symbseed+$namechck;
    my $num2=$nameseed+$domainseed+$courseseed;
    #&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
    #&Apache::lonxml::debug("rndseed :$num:$symb");
    return "$num1:$num2";
       }
   }
   
 sub rndseed_CODE_64bit {  sub rndseed_CODE_64bit {
     my ($symb,$courseid,$domain,$username)=@_;      my ($symb,$courseid,$domain,$username)=@_;
     {      {
  use integer;   use integer;
  my $symbchck=unpack("%32S*",$symb.' ') << 16;   my $symbchck=unpack("%32S*",$symb.' ') << 16;
  my $symbseed=numval($symb);   my $symbseed=numval2($symb);
  my $CODEseed=numval($ENV{'scantron.CODE'}) << 16;   my $CODEchck=unpack("%32S*",&getCODE().' ') << 16;
    my $CODEseed=numval(&getCODE());
  my $courseseed=unpack("%32S*",$courseid.' ');   my $courseseed=unpack("%32S*",$courseid.' ');
  my $num1=$symbseed+$CODEseed;   my $num1=$symbseed+$CODEchck;
  my $num2=$courseseed+$symbchck;   my $num2=$CODEseed+$courseseed+$symbchck;
  #&Apache::lonxml::debug("$symbseed:$CODEseed|$courseseed:$symbchck");   #&Apache::lonxml::debug("$symbseed:$CODEchck|$CODEseed:$courseseed:$symbchck");
  #&Apache::lonxml::debug("rndseed :$num1:$num2:$symb");   #&Apache::lonxml::debug("rndseed :$num1:$num2:$symb");
  return "$num1,$num2";   return "$num1:$num2";
     }      }
 }  }
   
 sub setup_random_from_rndseed {  sub setup_random_from_rndseed {
     my ($rndseed)=@_;      my ($rndseed)=@_;
     if ($rndseed =~/,/) {      if ($rndseed =~/([,:])/) {
  my ($num1,$num2)=split(/,/,$rndseed);   my ($num1,$num2)=split(/[,:]/,$rndseed);
  &Math::Random::random_set_seed(abs($num1),abs($num2));   &Math::Random::random_set_seed(abs($num1),abs($num2));
     } else {      } else {
  &Math::Random::random_set_seed_from_phrase($rndseed);   &Math::Random::random_set_seed_from_phrase($rndseed);
Line 4566  sub receipt { Line 4802  sub receipt {
   
 sub getfile {  sub getfile {
     my ($file,$caller) = @_;      my ($file,$caller) = @_;
     if ($file=~ m|^/*uploaded/(\w+)/(\w+)/(.+)$|) { # user file  
         my $info;      if ($file !~ m|^/*uploaded/(\w+)/(\w+)/(.+)$|) {
         my $cdom = $1;   # normal file from res space
         my $cnum = $2;  
         my $filename = $3;  
         my $path = $Apache::lonnet::perlvar{'lonDocRoot'}.'/userfiles';  
         my ($lwpresp,$rtncode);  
         my $localfile = $path.'/'.$cdom.'/'.$cnum.'/'.$filename;  
         if (-e "$localfile") {  
             my @fileinfo = stat($localfile);  
             $lwpresp = &getuploaded('HEAD',$file,$cdom,$cnum,\$info,\$rtncode);  
             if ($lwpresp eq 'ok') {  
                 if ($info > $fileinfo[9]) {  
                     $info = '';  
                     $lwpresp = &getuploaded('GET',$file,$cdom,$cnum,\$info,\$rtncode);  
                     if ($lwpresp eq 'ok') {  
                         open (FILE,">$localfile");  
                         print FILE $info;  
                         close(FILE);  
                         if ($caller eq 'uploadrep') {  
                             return 'ok';  
                         } else {  
                             return $info;  
                         }  
                     } else {  
                         return -1;  
                     }  
         } else {  
                     return &readfile($localfile);  
                 }  
             } else {  
                 if ($rtncode eq '404') {  
                     unlink($localfile);  
                 }  
                 return -1;  
             }  
  } else {  
             $lwpresp = &getuploaded('GET',$file,$cdom,$cnum,\$info,\$rtncode);  
             if ($lwpresp eq 'ok') {  
                 my @parts = ($cdom,$cnum);   
                 if ($filename =~ m|^(.+)/[^/]+$|) {  
                     push @parts, split(/\//,$1);  
                 }  
                 foreach my $part (@parts) {  
                     $path .= '/'.$part;  
                     if (!-e $path) {  
                         mkdir($path,0770);  
                     }  
                 }  
                 open (FILE,">$localfile");  
                 print FILE $info;  
                 close(FILE);  
                 if ($caller eq 'uploadrep') {  
                     return 'ok';  
                 } else {  
                     return $info;  
                 }  
             } else {  
                 return -1;  
             }  
         }  
     } else { # normal file from res space  
  &repcopy($file);   &repcopy($file);
         return &readfile($file);          return &readfile($file);
     }      }
   
       my $info;
       my $cdom = $1;
       my $cnum = $2;
       my $filename = $3;
       my $path = $Apache::lonnet::perlvar{'lonDocRoot'}.'/userfiles';
       my ($lwpresp,$rtncode);
       my $localfile = $path.'/'.$cdom.'/'.$cnum.'/'.$filename;
       if (-e "$localfile") {
    my @fileinfo = stat($localfile);
    $lwpresp = &getuploaded('HEAD',$file,$cdom,$cnum,\$info,\$rtncode);
    if ($lwpresp ne 'ok') {
       if ($rtncode eq '404') {
    unlink($localfile);
       }
       return -1;
    }
    if ($info < $fileinfo[9]) {
       return &readfile($localfile);
    }
    $info = '';
    $lwpresp = &getuploaded('GET',$file,$cdom,$cnum,\$info,\$rtncode);
    if ($lwpresp ne 'ok') {
       return -1;
    }
       } else {
    $lwpresp = &getuploaded('GET',$file,$cdom,$cnum,\$info,\$rtncode);
    if ($lwpresp ne 'ok') {
       return -1;
    }
    my @parts = ($cdom,$cnum); 
    if ($filename =~ m|^(.+)/[^/]+$|) {
       push @parts, split(/\//,$1);
       }
    foreach my $part (@parts) {
       $path .= '/'.$part;
       if (!-e $path) {
    mkdir($path,0770);
       }
    }
       }
       open (FILE,">$localfile");
       print FILE $info;
       close(FILE);
       if ($caller eq 'uploadrep') {
    return 'ok';
       }
       return $info;
 }  }
   
 sub getuploaded {  sub getuploaded {
Line 4641  sub getuploaded { Line 4866  sub getuploaded {
     my $request=new HTTP::Request($reqtype,$uri);      my $request=new HTTP::Request($reqtype,$uri);
     my $response=$ua->request($request);      my $response=$ua->request($request);
     $$rtncode = $response->code;      $$rtncode = $response->code;
     if ($response->is_success()) {      if (! $response->is_success()) {
         if ($reqtype eq 'HEAD') {   return 'failed';
             $$info = &Date::Parse::str2time( $response->header('Last-modified') );      }      
         } elsif ($reqtype eq 'GET') {      if ($reqtype eq 'HEAD') {
             $$info = $response->content;   $$info = &HTTP::Date::str2time( $response->header('Last-modified') );
         }      } elsif ($reqtype eq 'GET') {
         return 'ok';   $$info = $response->content;
     } else {  
         return 'failed';  
     }      }
       return 'ok';
 }  }
   
 sub readfile {  sub readfile {
Line 4803  BEGIN { Line 5027  BEGIN {
     open(my $config,"</etc/httpd/conf/loncapa.conf");      open(my $config,"</etc/httpd/conf/loncapa.conf");
   
     while (my $configline=<$config>) {      while (my $configline=<$config>) {
         if ($configline =~ /^[^\#]*PerlSetVar/) {          if ($configline=~/\S/ && $configline =~ /^[^\#]*PerlSetVar/) {
    my ($dummy,$varname,$varvalue)=split(/\s+/,$configline);     my ($dummy,$varname,$varvalue)=split(/\s+/,$configline);
            chomp($varvalue);             chomp($varvalue);
            $perlvar{$varname}=$varvalue;             $perlvar{$varname}=$varvalue;
Line 4921  BEGIN { Line 5145  BEGIN {
     open(my $config,"<$perlvar{'lonTabDir'}/packages.tab");      open(my $config,"<$perlvar{'lonTabDir'}/packages.tab");
   
     while (my $configline=<$config>) {      while (my $configline=<$config>) {
    if ($configline !~ /\S/ || $configline=~/^#/) { next; }
  chomp($configline);   chomp($configline);
  my ($short,$plain)=split(/:/,$configline);   my ($short,$plain)=split(/:/,$configline);
  my ($pack,$name)=split(/\&/,$short);   my ($pack,$name)=split(/\&/,$short);

Removed from v.1.481  
changed lines
  Added in v.1.507


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