Diff for /loncom/lonnet/perl/lonnet.pm between versions 1.1172.2.21 and 1.1172.2.34

version 1.1172.2.21, 2013/03/18 00:30:46 version 1.1172.2.34, 2013/09/02 14:41:53
Line 97  use File::MMagic; Line 97  use File::MMagic;
 use LONCAPA qw(:DEFAULT :match);  use LONCAPA qw(:DEFAULT :match);
 use LONCAPA::Configuration;  use LONCAPA::Configuration;
 use LONCAPA::lonmetadata;  use LONCAPA::lonmetadata;
   use LONCAPA::Lond;
   
 use File::Copy;  use File::Copy;
   
Line 1575  sub idput { Line 1576  sub idput {
     }      }
 }  }
   
   # ---------------------------------------- Delete unwanted IDs from ids.db file
   
   sub iddel {
       my ($udom,$idshashref,$uhome)=@_;
       my %result=();
       unless (ref($idshashref) eq 'HASH') {
           return %result;
       }
       my %servers=();
       while (my ($id,$uname) = each(%{$idshashref})) {
           my $uhom;
           if ($uhome) {
               $uhom = $uhome;
           } else {
               $uhom=&homeserver($uname,$udom);
           }
           if ($uhom ne 'no_host') {
               if ($servers{$uhom}) {
                   $servers{$uhom}.='&'.&escape($id);
               } else {
                   $servers{$uhom}=&escape($id);
               }
           }
       }
       foreach my $server (keys(%servers)) {
           $result{$server} = &critical('iddel:'.$udom.':'.$servers{$server},$uhome);
       }
       return %result;
   }
   
 # ------------------------------dump from db file owned by domainconfig user  # ------------------------------dump from db file owned by domainconfig user
 sub dump_dom {  sub dump_dom {
     my ($namespace, $udom, $regexp) = @_;      my ($namespace, $udom, $regexp) = @_;
Line 1982  sub get_domain_defaults { Line 2013  sub get_domain_defaults {
             $domdefaults{'defaultquota'} = $domconfig{'quotas'}{'defaultquota'};              $domdefaults{'defaultquota'} = $domconfig{'quotas'}{'defaultquota'};
         } else {          } else {
             $domdefaults{'defaultquota'} = $domconfig{'quotas'};              $domdefaults{'defaultquota'} = $domconfig{'quotas'};
         }           }
         my @usertools = ('aboutme','blog','webdav','portfolio');          my @usertools = ('aboutme','blog','webdav','portfolio');
         foreach my $item (@usertools) {          foreach my $item (@usertools) {
             if (ref($domconfig{'quotas'}{$item}) eq 'HASH') {              if (ref($domconfig{'quotas'}{$item}) eq 'HASH') {
                 $domdefaults{$item} = $domconfig{'quotas'}{$item};                  $domdefaults{$item} = $domconfig{'quotas'}{$item};
             }              }
         }          }
           if (ref($domconfig{'quotas'}{'authorquota'}) eq 'HASH') {
               $domdefaults{'authorquota'} = $domconfig{'quotas'}{'authorquota'};
           }
     }      }
     if (ref($domconfig{'requestcourses'}) eq 'HASH') {      if (ref($domconfig{'requestcourses'}) eq 'HASH') {
         foreach my $item ('official','unofficial','community') {          foreach my $item ('official','unofficial','community') {
Line 2008  sub get_domain_defaults { Line 2042  sub get_domain_defaults {
             $domdefaults{'officialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'official'};              $domdefaults{'officialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'official'};
             $domdefaults{'unofficialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'};              $domdefaults{'unofficialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'};
         }          }
           if (ref($domconfig{'coursedefaults'}{'uploadquota'}) eq 'HASH') {
               $domdefaults{'officialquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'official'};
               $domdefaults{'unofficialquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'unofficial'};
               $domdefaults{'communityquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'community'};
           }
     }      }
     if (ref($domconfig{'usersessions'}) eq 'HASH') {      if (ref($domconfig{'usersessions'}) eq 'HASH') {
         if (ref($domconfig{'usersessions'}{'remote'}) eq 'HASH') {          if (ref($domconfig{'usersessions'}{'remote'}) eq 'HASH') {
Line 2017  sub get_domain_defaults { Line 2056  sub get_domain_defaults {
             $domdefaults{'hostedsessions'} = $domconfig{'usersessions'}{'hosted'};              $domdefaults{'hostedsessions'} = $domconfig{'usersessions'}{'hosted'};
         }          }
     }      }
     &Apache::lonnet::do_cache_new('domdefaults',$domain,\%domdefaults,      &do_cache_new('domdefaults',$domain,\%domdefaults,$cachetime);
                                   $cachetime);  
     return %domdefaults;      return %domdefaults;
 }  }
   
Line 2808  sub can_edit_resource { Line 2846  sub can_edit_resource {
                     $cfile =~ s{^http://}{};                      $cfile =~ s{^http://}{};
                     $cfile = '/adm/wrapper/ext/'.$cfile;                      $cfile = '/adm/wrapper/ext/'.$cfile;
                 }                  }
               } elsif ($resurl =~ m{^/?adm/viewclasslist$}) {
                   if ($env{'form.forceedit'}) {
                       $forceview = 1;
                   } else {
                       $forceedit = 1;
                   }
                   $cfile = ($resurl =~ m{^/} ? $resurl : "/$resurl");
             }              }
         }          }
         if ($uploaded || $incourse) {          if ($uploaded || $incourse) {
Line 2849  sub in_course { Line 2894  sub in_course {
     my ($udom,$uname,$cdom,$cnum,$type,$hideprivileged) = @_;      my ($udom,$uname,$cdom,$cnum,$type,$hideprivileged) = @_;
     if ($hideprivileged) {      if ($hideprivileged) {
         my $skipuser;          my $skipuser;
         if (&privileged($uname,$udom)) {          my %coursehash = &coursedescription($cdom.'_'.$cnum);
           my @possdoms = ($cdom);
           if ($coursehash{'checkforpriv'}) {
               push(@possdoms,split(/,/,$coursehash{'checkforpriv'}));
           }
           if (&privileged($uname,$udom,\@possdoms)) {
             $skipuser = 1;              $skipuser = 1;
             my %coursehash = &coursedescription($cdom.'_'.$cnum);  
             if ($coursehash{'nothideprivileged'}) {              if ($coursehash{'nothideprivileged'}) {
                 foreach my $item (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) {                  foreach my $item (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) {
                     my $user;                      my $user;
Line 3201  sub userfileupload { Line 3250  sub userfileupload {
     } else {      } else {
         my $docuname=$env{'user.name'};          my $docuname=$env{'user.name'};
         my $docudom=$env{'user.domain'};          my $docudom=$env{'user.domain'};
         if (exists($env{'form.group'})) {          if ((exists($env{'form.group'})) || ($context eq 'syllabus')) {
             $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'};
         }          }
Line 3351  sub extract_embedded_items { Line 3400  sub extract_embedded_items {
  &add_filetype($allfiles,$attr->{'src'},'src');   &add_filetype($allfiles,$attr->{'src'},'src');
     }      }
     if (lc($tagname) eq 'a') {      if (lc($tagname) eq 'a') {
  &add_filetype($allfiles,$attr->{'href'},'href');                  unless (($attr->{'href'} =~ /^#/) || ($attr->{'href'} eq '')) {
       &add_filetype($allfiles,$attr->{'href'},'href');
                   }
     }      }
             if (lc($tagname) eq 'script') {              if (lc($tagname) eq 'script') {
                 my $src;                  my $src;
Line 3882  sub get_course_adv_roles { Line 3933  sub get_course_adv_roles {
             $nothide{$user}=1;              $nothide{$user}=1;
         }          }
     }      }
       my @possdoms = ($coursehash{'domain'});
       if ($coursehash{'checkforpriv'}) {
           push(@possdoms,split(/,/,$coursehash{'checkforpriv'}));
       }
     my %returnhash=();      my %returnhash=();
     my %dumphash=      my %dumphash=
             &dump('nohist_userroles',$coursehash{'domain'},$coursehash{'num'});              &dump('nohist_userroles',$coursehash{'domain'},$coursehash{'num'});
Line 3894  sub get_course_adv_roles { Line 3949  sub get_course_adv_roles {
         if (($tstart) && ($now<$tstart)) { next; }          if (($tstart) && ($now<$tstart)) { next; }
         my ($role,$username,$domain,$section)=split(/\:/,$entry);          my ($role,$username,$domain,$section)=split(/\:/,$entry);
  if ($username eq '' || $domain eq '') { next; }   if ($username eq '' || $domain eq '') { next; }
         unless (ref($privileged{$domain}) eq 'HASH') {          if ((&privileged($username,$domain,\@possdoms)) &&
             my %dompersonnel =  
                 &Apache::lonnet::get_domain_roles($domain,['dc'],$now,$now);  
             $privileged{$domain} = {};  
             foreach my $server (keys(%dompersonnel)) {  
                 if (ref($dompersonnel{$server}) eq 'HASH') {  
                     foreach my $user (keys(%{$dompersonnel{$server}})) {  
                         my ($trole,$uname,$udom) = split(/:/,$user);  
                         $privileged{$udom}{$uname} = 1;  
                     }  
                 }  
             }  
         }  
         if ((exists($privileged{$domain}{$username})) &&   
             (!$nothide{$username.':'.$domain})) { next; }              (!$nothide{$username.':'.$domain})) { next; }
  if ($role eq 'cr') { next; }   if ($role eq 'cr') { next; }
         if ($codes) {          if ($codes) {
Line 3938  sub get_my_roles { Line 3980  sub get_my_roles {
     if ($context eq 'userroles') {      if ($context eq 'userroles') {
         %dumphash = &dump('roles',$udom,$uname);          %dumphash = &dump('roles',$udom,$uname);
     } else {      } else {
         %dumphash=          %dumphash = &dump('nohist_userroles',$udom,$uname);
             &dump('nohist_userroles',$udom,$uname);  
         if ($hidepriv) {          if ($hidepriv) {
             my %coursehash=&coursedescription($udom.'_'.$uname);              my %coursehash=&coursedescription($udom.'_'.$uname);
             foreach my $user (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) {              foreach my $user (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) {
Line 4007  sub get_my_roles { Line 4048  sub get_my_roles {
             }              }
         }          }
         if ($hidepriv) {          if ($hidepriv) {
               my @privroles = ('dc','su');
             if ($context eq 'userroles') {              if ($context eq 'userroles') {
                 if ((&privileged($username,$domain)) &&                  next if (grep(/^\Q$role\E$/,@privroles));
                     (!$nothide{$username.':'.$domain})) {  
                     next;  
                 }  
             } else {              } else {
                 unless (ref($privileged{$domain}) eq 'HASH') {                  my $possdoms = [$domain];
                     my %dompersonnel =                  if (ref($roledoms) eq 'ARRAY') {
                         &Apache::lonnet::get_domain_roles($domain,['dc'],$now,$now);                     push(@{$possdoms},@{$roledoms});
                     $privileged{$domain} = {};  
                     if (keys(%dompersonnel)) {  
                         foreach my $server (keys(%dompersonnel)) {  
                             if (ref($dompersonnel{$server}) eq 'HASH') {  
                                 foreach my $user (keys(%{$dompersonnel{$server}})) {  
                                     my ($trole,$uname,$udom) = split(/:/,$user);  
                                     $privileged{$udom}{$uname} = $trole;  
                                 }  
                             }  
                         }  
                     }  
                 }                  }
                 if (exists($privileged{$domain}{$username})) {                  if (&privileged($username,$domain,$possdoms,\@privroles)) {
                     if (!$nothide{$username.':'.$domain}) {                      if (!$nothide{$username.':'.$domain}) {
                         next;                          next;
                     }                      }
Line 4132  sub courseiddump { Line 4160  sub courseiddump {
   
     if (($domfilter eq '') ||      if (($domfilter eq '') ||
  (&host_domain($tryserver) eq $domfilter)) {   (&host_domain($tryserver) eq $domfilter)) {
                 my $rep =                   my $rep;
                   &reply('courseiddump:'.&host_domain($tryserver).':'.                  if (grep { $_ eq $tryserver } &current_machine_ids()) {
                          $sincefilter.':'.&escape($descfilter).':'.                      $rep = &LONCAPA::Lond::dump_course_id_handler(
                          &escape($instcodefilter).':'.&escape($ownerfilter).                          join(":", (&host_domain($tryserver), $sincefilter,
                          ':'.&escape($coursefilter).':'.&escape($typefilter).                                  &escape($descfilter), &escape($instcodefilter),
                          ':'.&escape($regexp_ok).':'.$as_hash.':'.                                  &escape($ownerfilter), &escape($coursefilter),
                          &escape($selfenrollonly).':'.&escape($catfilter).':'.                                  &escape($typefilter), &escape($regexp_ok),
                          $showhidden.':'.$caller.':'.&escape($cloner).':'.                                  $as_hash, &escape($selfenrollonly),
                          &escape($cc_clone).':'.$cloneonly.':'.                                  &escape($catfilter), $showhidden, $caller,
                          &escape($createdbefore).':'.&escape($createdafter).':'.                                  &escape($cloner), &escape($cc_clone), $cloneonly,
                          &escape($creationcontext).':'.$domcloner,                                  &escape($createdbefore), &escape($createdafter),
                          $tryserver);                                  &escape($creationcontext), $domcloner)));
                   } else {
                       $rep = &reply('courseiddump:'.&host_domain($tryserver).':'.
                                $sincefilter.':'.&escape($descfilter).':'.
                                &escape($instcodefilter).':'.&escape($ownerfilter).
                                ':'.&escape($coursefilter).':'.&escape($typefilter).
                                ':'.&escape($regexp_ok).':'.$as_hash.':'.
                                &escape($selfenrollonly).':'.&escape($catfilter).':'.
                                $showhidden.':'.$caller.':'.&escape($cloner).':'.
                                &escape($cc_clone).':'.$cloneonly.':'.
                                &escape($createdbefore).':'.&escape($createdafter).':'.
                                &escape($creationcontext).':'.$domcloner,
                                $tryserver);
                   }
   
                 my @pairs=split(/\&/,$rep);                  my @pairs=split(/\&/,$rep);
                 foreach my $item (@pairs) {                  foreach my $item (@pairs) {
                     my ($key,$value)=split(/\=/,$item,2);                      my ($key,$value)=split(/\=/,$item,2);
Line 4249  sub get_domain_roles { Line 4291  sub get_domain_roles {
     }      }
     my $rolelist;      my $rolelist;
     if (ref($roles) eq 'ARRAY') {      if (ref($roles) eq 'ARRAY') {
         $rolelist = join(':',@{$roles});          $rolelist = join('&',@{$roles});
     }      }
     my %personnel = ();      my %personnel = ();
   
Line 4342  sub set_first_access { Line 4384  sub set_first_access {
     return 'already_set';      return 'already_set';
 }  }
 }  }
   
   sub checkout {
       my ($symb,$tuname,$tudom,$tcrsid)=@_;
       my $now=time;
       my $lonhost=$perlvar{'lonHostID'};
       my $infostr=&escape(
                    'CHECKOUTTOKEN&'.
                    $tuname.'&'.
                    $tudom.'&'.
                    $tcrsid.'&'.
                    $symb.'&'.
                    $now.'&'.$ENV{'REMOTE_ADDR'});
       my $token=&reply('tmpput:'.$infostr,$lonhost);
       if ($token=~/^error\:/) {
           &logthis("<font color=\"blue\">WARNING: ".
                   "Checkout tmpput failed ".$tudom.' - '.$tuname.' - '.$symb.
                    "</font>");
           return '';
       }
   
       $token=~s/^(\d+)\_.*\_(\d+)$/$1\*$2\*$lonhost/;
       $token=~tr/a-z/A-Z/;
   
       my %infohash=('resource.0.outtoken' => $token,
                     'resource.0.checkouttime' => $now,
                     'resource.0.outremote' => $ENV{'REMOTE_ADDR'});
   
       unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') {
          return '';
       } else {
           &logthis("<font color=\"blue\">WARNING: ".
                   "Checkout cstore failed ".$tudom.' - '.$tuname.' - '.$symb.
                    "</font>");
       }
   
       if (&log($tudom,$tuname,&homeserver($tuname,$tudom),
                            &escape('Checkout '.$infostr.' - '.
                                                    $token)) ne 'ok') {
           return '';
       } else {
           &logthis("<font color=\"blue\">WARNING: ".
                   "Checkout log failed ".$tudom.' - '.$tuname.' - '.$symb.
                    "</font>");
       }
       return $token;
   }
   
   # ------------------------------------------------------------ Check in an item
   
   sub checkin {
       my $token=shift;
       my $now=time;
       my ($ta,$tb,$lonhost)=split(/\*/,$token);
       $lonhost=~tr/A-Z/a-z/;
       my $dtoken=$ta.'_'.&hostname($lonhost).'_'.$tb;
       $dtoken=~s/\W/\_/g;
       my ($dummy,$tuname,$tudom,$tcrsid,$symb,$chtim,$rmaddr)=
                    split(/\&/,&unescape(&reply('tmpget:'.$dtoken,$lonhost)));
   
       unless (($tuname) && ($tudom)) {
           &logthis('Check in '.$token.' ('.$dtoken.') failed');
           return '';
       }
   
       unless (&allowed('mgr',$tcrsid)) {
           &logthis('Check in '.$token.' ('.$dtoken.') unauthorized: '.
                    $env{'user.name'}.' - '.$env{'user.domain'});
           return '';
       }
   
       my %infohash=('resource.0.intoken' => $token,
                     'resource.0.checkintime' => $now,
                     'resource.0.inremote' => $ENV{'REMOTE_ADDR'});
   
       unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') {
          return '';
       }
   
       if (&log($tudom,$tuname,&homeserver($tuname,$tudom),
                            &escape('Checkin - '.$token)) ne 'ok') {
           return '';
       }
   
       return ($symb,$tuname,$tudom,$tcrsid);
   }
   
 # --------------------------------------------- Set Expire Date for Spreadsheet  # --------------------------------------------- Set Expire Date for Spreadsheet
   
 sub expirespread {  sub expirespread {
Line 4791  sub restore { Line 4919  sub restore {
     if ($stuname) { $home=&homeserver($stuname,$domain); }      if ($stuname) { $home=&homeserver($stuname,$domain); }
   
     if (!$symb) {      if (!$symb) {
       unless ($symb=escape(&symbread())) { return ''; }          return if ($namespace eq 'courserequests');
           unless ($symb=escape(&symbread())) { return ''; }
     } else {      } else {
       $symb=&escape(&symbclean($symb));          unless ($namespace eq 'courserequests') {
               $symb=&escape(&symbclean($symb));
           }
     }      }
     if (!$namespace) {       if (!$namespace) { 
        unless ($namespace=$env{'request.course.id'}) {          unless ($namespace=$env{'request.course.id'}) { 
Line 4928  sub update_released_required { Line 5059  sub update_released_required {
 # -------------------------------------------------See if a user is privileged  # -------------------------------------------------See if a user is privileged
   
 sub privileged {  sub privileged {
     my ($username,$domain)=@_;      my ($username,$domain,$possdomains,$possroles)=@_;
   
     my %rolesdump = &dump("roles", $domain, $username) or return 0;  
     my $now = time;      my $now = time;
       my $roles;
       if (ref($possroles) eq 'ARRAY') {
           $roles = $possroles;
       } else {
           $roles = ['dc','su'];
       }
       if (ref($possdomains) eq 'ARRAY') {
           my %privileged = &privileged_by_domain($possdomains,$roles);
           foreach my $dom (@{$possdomains}) {
               if (($username =~ /^$match_username$/) && ($domain =~ /^$match_domain$/) &&
                   (ref($privileged{$dom}) eq 'HASH')) {
                   foreach my $role (@{$roles}) {
                       if (ref($privileged{$dom}{$role}) eq 'HASH') {
                           if (exists($privileged{$dom}{$role}{$username.':'.$domain})) {
                               my ($end,$start) = split(/:/,$privileged{$dom}{$role}{$username.':'.$domain});
                               return 1 unless (($end && $end < $now) ||
                                                ($start && $start > $now));
                           }
                       }
                   }
               }
           }
       } else {
           my %rolesdump = &dump("roles", $domain, $username) or return 0;
           my $now = time;
   
     for my $role (@rolesdump{grep { ! /^rolesdef_/ } keys %rolesdump}) {          for my $role (@rolesdump{grep { ! /^rolesdef_/ } keys %rolesdump}) {
             my ($trole, $tend, $tstart) = split(/_/, $role);              my ($trole, $tend, $tstart) = split(/_/, $role);
             if (($trole eq 'dc') || ($trole eq 'su')) {              if (grep(/^\Q$trole\E$/,@{$roles})) {
                 return 1 unless ($tend && $tend < $now)                   return 1 unless ($tend && $tend < $now)
                     or ($tstart && $tstart > $now);                          or ($tstart && $tstart > $now);
             }              }
  }          }
       }
     return 0;      return 0;
 }  }
   
   sub privileged_by_domain {
       my ($domains,$roles) = @_;
       my %privileged = ();
       my $cachetime = 60*60*24;
       my $now = time;
       unless ((ref($domains) eq 'ARRAY') && (ref($roles) eq 'ARRAY')) {
           return %privileged;
       }
       foreach my $dom (@{$domains}) {
           next if (ref($privileged{$dom}) eq 'HASH');
           my $needroles;
           foreach my $role (@{$roles}) {
               my ($result,$cached)=&is_cached_new('priv_'.$role,$dom);
               if (defined($cached)) {
                   if (ref($result) eq 'HASH') {
                       $privileged{$dom}{$role} = $result;
                   }
               } else {
                   $needroles = 1;
               }
           }
           if ($needroles) {
               my %dompersonnel = &get_domain_roles($dom,$roles);
               $privileged{$dom} = {};
               foreach my $server (keys(%dompersonnel)) {
                   if (ref($dompersonnel{$server}) eq 'HASH') {
                       foreach my $item (keys(%{$dompersonnel{$server}})) {
                           my ($trole,$uname,$udom,$rest) = split(/:/,$item,4);
                           my ($end,$start) = split(/:/,$dompersonnel{$server}{$item});
                           next if ($end && $end < $now);
                           $privileged{$dom}{$trole}{$uname.':'.$udom} =
                               $dompersonnel{$server}{$item};
                       }
                   }
               }
               if (ref($privileged{$dom}) eq 'HASH') {
                   foreach my $role (@{$roles}) {
                       if (ref($privileged{$dom}{$role}) eq 'HASH') {
                           &do_cache_new('priv_'.$role,$dom,$privileged{$dom}{$role},$cachetime);
                       } else {
                           my %hash = ();
                           &do_cache_new('priv_'.$role,$dom,\%hash,$cachetime);
                       }
                   }
               }
           }
       }
       return %privileged;
   }
   
 # -------------------------------------------------------- Get user privileges  # -------------------------------------------------------- Get user privileges
   
 sub rolesinit {  sub rolesinit {
Line 5389  sub del { Line 5593  sub del {
   
 # -------------------------------------------------------------- dump interface  # -------------------------------------------------------------- dump interface
   
   sub unserialize {
       my ($rep, $escapedkeys) = @_;
   
       return {} if $rep =~ /^error/;
   
       my %returnhash=();
       foreach my $item (split(/\&/,$rep)) {
           my ($key, $value) = split(/=/, $item, 2);
           $key = unescape($key) unless $escapedkeys;
           next if $key =~ /^error: 2 /;
           $returnhash{$key} = &thaw_unescape($value);
       }
       return \%returnhash;
   }
   
   # see Lond::dump_with_regexp
   # if $escapedkeys hash keys won't get unescaped.
 sub dump {  sub dump {
     my ($namespace,$udomain,$uname,$regexp,$range)=@_;      my ($namespace,$udomain,$uname,$regexp,$range,$escapedkeys)=@_;
     if (!$udomain) { $udomain=$env{'user.domain'}; }      if (!$udomain) { $udomain=$env{'user.domain'}; }
     if (!$uname) { $uname=$env{'user.name'}; }      if (!$uname) { $uname=$env{'user.name'}; }
     my $uhome=&homeserver($uname,$udomain);      my $uhome=&homeserver($uname,$udomain);
   
       my $reply;
       if (grep { $_ eq $uhome } &current_machine_ids()) {
           # user is hosted on this machine
           $reply = LONCAPA::Lond::dump_with_regexp(join(':', ($udomain,
                       $uname, $namespace, $regexp, $range)), $perlvar{'lonVersion'});
           return %{&unserialize($reply, $escapedkeys)};
       }
     if ($regexp) {      if ($regexp) {
  $regexp=&escape($regexp);   $regexp=&escape($regexp);
     } else {      } else {
Line 5406  sub dump { Line 5634  sub dump {
     if (!($rep =~ /^error/ )) {      if (!($rep =~ /^error/ )) {
  foreach my $item (@pairs) {   foreach my $item (@pairs) {
     my ($key,$value)=split(/=/,$item,2);      my ($key,$value)=split(/=/,$item,2);
     $key = &unescape($key);              $key = &unescape($key) unless ($escapedkeys);
     next if ($key =~ /^error: 2 /);      next if ($key =~ /^error: 2 /);
     $returnhash{$key}=&thaw_unescape($value);      $returnhash{$key}=&thaw_unescape($value);
  }   }
Line 5419  sub dump { Line 5647  sub dump {
   
 sub dumpstore {  sub dumpstore {
    my ($namespace,$udomain,$uname,$regexp,$range)=@_;     my ($namespace,$udomain,$uname,$regexp,$range)=@_;
    if (!$udomain) { $udomain=$env{'user.domain'}; }     # same as dump but keys must be escaped. They may contain colon separated
    if (!$uname) { $uname=$env{'user.name'}; }     # lists of values that may themself contain colons (e.g. symbs).
    my $uhome=&homeserver($uname,$udomain);     return &dump($namespace, $udomain, $uname, $regexp, $range, 1);
    if ($regexp) {  
        $regexp=&escape($regexp);  
    } else {  
        $regexp='.';  
    }  
    my $rep=&reply("dump:$udomain:$uname:$namespace:$regexp:$range",$uhome);  
    my @pairs=split(/\&/,$rep);  
    my %returnhash=();  
    foreach my $item (@pairs) {  
        my ($key,$value)=split(/=/,$item,2);  
        next if ($key =~ /^error: 2 /);  
        $returnhash{$key}=&thaw_unescape($value);  
    }  
    return %returnhash;  
 }  }
   
 # -------------------------------------------------------------- keys interface  # -------------------------------------------------------------- keys interface
Line 7146  sub definerole { Line 7360  sub definerole {
 # ---------------- Make a metadata query against the network of library servers  # ---------------- Make a metadata query against the network of library servers
   
 sub metadata_query {  sub metadata_query {
     my ($query,$custom,$customshow,$server_array)=@_;      my ($query,$custom,$customshow,$server_array,$domains_hash)=@_;
     my %rhash;      my %rhash;
     my %libserv = &all_library();      my %libserv = &all_library();
     my @server_list = (defined($server_array) ? @$server_array      my @server_list = (defined($server_array) ? @$server_array
                                               : keys(%libserv) );                                                : keys(%libserv) );
     for my $server (@server_list) {      for my $server (@server_list) {
           my $domains = '';
           if (ref($domains_hash) eq 'HASH') {
               $domains = $domains_hash->{$server};    
           }
  unless ($custom or $customshow) {   unless ($custom or $customshow) {
     my $reply=&reply("querysend:".&escape($query),$server);      my $reply=&reply("querysend:".&escape($query).':::'.&escape($domains),$server);
     $rhash{$server}=$reply;      $rhash{$server}=$reply;
  }   }
  else {   else {
     my $reply=&reply("querysend:".&escape($query).':'.      my $reply=&reply("querysend:".&escape($query).':'.
      &escape($custom).':'.&escape($customshow),       &escape($custom).':'.&escape($customshow).':'.&escape($domains),
      $server);       $server);
     $rhash{$server}=$reply;      $rhash{$server}=$reply;
  }   }
Line 8357  sub modifystudent { Line 8575  sub modifystudent {
          $desiredhome,$email,$inststatus);           $desiredhome,$email,$inststatus);
     unless ($reply eq 'ok') { return $reply; }      unless ($reply eq 'ok') { return $reply; }
     # This will cause &modify_student_enrollment to get the uid from the      # This will cause &modify_student_enrollment to get the uid from the
     # students environment      # student's environment
     $uid = undef if (!$forceid);      $uid = undef if (!$forceid);
     $reply = &modify_student_enrollment($udom,$uname,$uid,$first,$middle,$last,      $reply = &modify_student_enrollment($udom,$uname,$uid,$first,$middle,$last,
  $gene,$usec,$end,$start,$type,$locktype,   $gene,$usec,$end,$start,$type,$locktype,
Line 8366  sub modifystudent { Line 8584  sub modifystudent {
 }  }
   
 sub modify_student_enrollment {  sub modify_student_enrollment {
     my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type,$locktype,$cid,$selfenroll,$context,$credits) = @_;      my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type,
           $locktype,$cid,$selfenroll,$context,$credits) = @_;
     my ($cdom,$cnum,$chome);      my ($cdom,$cnum,$chome);
     if (!$cid) {      if (!$cid) {
  unless ($cid=$env{'request.course.id'}) {   unless ($cid=$env{'request.course.id'}) {
Line 8642  sub is_course { Line 8861  sub is_course {
     my %courses = &courseiddump($cdom, '.', 1, '.', '.', $cnum, undef, undef,      my %courses = &courseiddump($cdom, '.', 1, '.', '.', $cnum, undef, undef,
         '.');          '.');
   
     return unless exists($courses{$cdom.'_'.$cnum});      return unless(exists($courses{$cdom.'_'.$cnum}));
     return wantarray ? ($cdom, $cnum) : $cdom.'_'.$cnum;      return wantarray ? ($cdom, $cnum) : $cdom.'_'.$cnum;
 }  }
   
Line 8667  sub store_userdata { Line 8886  sub store_userdata {
                     $namevalue.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&';                      $namevalue.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&';
                 }                  }
                 $namevalue=~s/\&$//;                  $namevalue=~s/\&$//;
                   unless ($namespace eq 'courserequests') {
                       $datakey = &escape($datakey);
                   }
                 $result =  &reply("store:$udom:$uname:$namespace:$datakey:".                  $result =  &reply("store:$udom:$uname:$namespace:$datakey:".
                                   $namevalue,$uhome);                                    $namevalue,$uhome);
             }              }
Line 9489  sub resdata { Line 9711  sub resdata {
     return undef;      return undef;
 }  }
   
   sub get_numsuppfiles {
       my ($cnum,$cdom,$ignorecache)=@_;
       my $hashid=$cnum.':'.$cdom;
       my ($suppcount,$cached);
       unless ($ignorecache) {
           ($suppcount,$cached) = &is_cached_new('suppcount',$hashid);
       }
       unless (defined($cached)) {
           my $chome=&homeserver($cnum,$cdom);
           unless ($chome eq 'no_host') {
               ($suppcount,my $errors) = (0,0);
               my $suppmap = 'supplemental.sequence';
               ($suppcount,$errors) =
                   &Apache::loncommon::recurse_supplemental($cnum,$cdom,$suppmap,$suppcount,$errors);
           }
           &do_cache_new('suppcount',$hashid,$suppcount,600);
       }
       return $suppcount;
   }
   
 #  #
 # EXT resource caching routines  # EXT resource caching routines
 #  #
Line 9517  sub EXT_cache_set { Line 9759  sub EXT_cache_set {
 # --------------------------------------------------------- Value of a Variable  # --------------------------------------------------------- Value of a Variable
 sub EXT {  sub EXT {
   
     my ($varname,$symbparm,$udom,$uname,$usection,$recurse)=@_;      my ($varname,$symbparm,$udom,$uname,$usection,$recurse,$cid)=@_;
     unless ($varname) { return ''; }      unless ($varname) { return ''; }
     #get real user name/domain, courseid and symb      #get real user name/domain, courseid and symb
     my $courseid;      my $courseid;
Line 9632  sub EXT { Line 9874  sub EXT {
     if (!$symbparm) { $symbparm=&symbread(); }      if (!$symbparm) { $symbparm=&symbread(); }
  }   }
   
  if ($space eq 'title') {          if ($qualifier eq '') {
     if (!$symbparm) { $symbparm = $env{'request.filename'}; }      if ($space eq 'title') {
     return &gettitle($symbparm);          if (!$symbparm) { $symbparm = $env{'request.filename'}; }
  }          return &gettitle($symbparm);
       }
   
  if ($space eq 'map') {      if ($space eq 'map') {
     my ($map) = &decode_symb($symbparm);          my ($map) = &decode_symb($symbparm);
     return &symbread($map);          return &symbread($map);
  }      }
  if ($space eq 'filename') {              if ($space eq 'maptitle') {
     if ($symbparm) {                  my ($map) = &decode_symb($symbparm);
  return &clutter((&decode_symb($symbparm))[2]);                  return &gettitle($map);
               }
       if ($space eq 'filename') {
           if ($symbparm) {
       return &clutter((&decode_symb($symbparm))[2]);
           }
           return &hreflocation('',$env{'request.filename'});
     }      }
     return &hreflocation('',$env{'request.filename'});  
  }              if ((defined($courseid)) && ($courseid eq $env{'request.course.id'}) && $symbparm) {
                   if ($space eq 'visibleparts') {
                       my $navmap = Apache::lonnavmaps::navmap->new();
                       my $item;
                       if (ref($navmap)) {
                           my $res = $navmap->getBySymb($symbparm);
                           my $parts = $res->parts();
                           if (ref($parts) eq 'ARRAY') {
                               $item = join(',',@{$parts});
                           }
                           undef($navmap);
                       }
                       return $item;
                   }
               }
           }
   
  my ($section, $group, @groups);   my ($section, $group, @groups);
  my ($courselevelm,$courselevel);   my ($courselevelm,$courselevel);
  if ($symbparm && defined($courseid) &&           if (($courseid eq '') && ($cid)) {
     $courseid eq $env{'request.course.id'}) {              $courseid = $cid;
           }
    if (($symbparm && $courseid) && 
       (($courseid eq $env{'request.course.id'}) || ($courseid eq $cid))) {
   
     #print '<br>'.$space.' - '.$qualifier.' - '.$spacequalifierrest;      #print '<br>'.$space.' - '.$qualifier.' - '.$spacequalifierrest;
   
Line 10276  sub gettitle { Line 10543  sub gettitle {
     return $title;      return $title;
 }  }
   
 sub getdocspath {  
     my ($symb) = @_;  
     my $path;  
     if ($symb) {  
         my ($mapurl,$id,$resurl) = &decode_symb($symb);  
         if ($resurl=~/\.(sequence|page)$/) {  
             $mapurl=$resurl;  
         } elsif ($resurl eq 'adm/navmaps') {  
             $mapurl=$env{'course.'.$env{'request.course.id'}.'.url'};  
         }  
         my $mapresobj;  
         my $navmap = Apache::lonnavmaps::navmap->new();  
         if (ref($navmap)) {  
             $mapresobj = $navmap->getResourceByUrl($mapurl);  
         }  
         $mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1};  
         my $type=$2;  
         if (ref($mapresobj)) {  
             my $pcslist = $mapresobj->map_hierarchy();  
             if ($pcslist ne '') {  
                 foreach my $pc (split(/,/,$pcslist)) {  
                     next if ($pc <= 1);  
                     my $res = $navmap->getByMapPc($pc);  
                     if (ref($res)) {  
                         my $thisurl = $res->src();  
                         $thisurl=~s{^.*/([^/]+)\.\w+$}{$1};  
                         my $thistitle = $res->title();  
                         $path .= '&'.  
                                  &Apache::lonhtmlcommon::entity_encode($thisurl).'&'.  
                                  &Apache::lonhtmlcommon::entity_encode($thistitle).  
                                  ':'.$res->randompick().  
                                  ':'.$res->randomout().  
                                  ':'.$res->encrypted().  
                                  ':'.$res->randomorder().  
                                  ':'.$res->is_page();  
                     }  
                 }  
             }  
             $path =~ s/^\&//;  
             my $maptitle = $mapresobj->title();  
             if ($mapurl eq 'default') {  
                 $maptitle = 'Main Course Documents';  
             }  
             $path .= ($path ne '')? '&' : ''.  
                     &Apache::lonhtmlcommon::entity_encode($mapurl).'&'.  
                     &Apache::lonhtmlcommon::entity_encode($maptitle).  
                     ':'.$mapresobj->randompick().  
                     ':'.$mapresobj->randomout().  
                     ':'.$mapresobj->encrypted().  
                     ':'.$mapresobj->randomorder().  
                     ':'.$mapresobj->is_page();  
         } else {  
             my $maptitle = &gettitle($mapurl);  
             my $ispage;  
             if ($mapurl =~ /\.page$/) {  
                 $ispage = 1;  
             }  
             if ($mapurl eq 'default') {  
                 $maptitle = 'Main Course Documents';  
             }  
             $path = &Apache::lonhtmlcommon::entity_encode($mapurl).'&'.  
                     &Apache::lonhtmlcommon::entity_encode($maptitle).':::::'.$ispage;  
         }  
         unless ($mapurl eq 'default') {  
             $path = 'default&'.  
                     &Apache::lonhtmlcommon::entity_encode('Main Course Documents').  
                     ':::::&'.$path;  
         }  
     }  
     return $path;  
 }  
   
 sub get_slot {  sub get_slot {
     my ($which,$cnum,$cdom)=@_;      my ($which,$cnum,$cdom)=@_;
     if (!$cnum || !$cdom) {      if (!$cnum || !$cdom) {
Line 10401  sub get_course_slots { Line 10596  sub get_course_slots {
         my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);          my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum);
         my ($tmp) = keys(%slots);          my ($tmp) = keys(%slots);
         if ($tmp !~ /^(con_lost|error|no_such_host)/i) {          if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
             &Apache::lonnet::do_cache_new('allslots',$hashid,\%slots,600);              &do_cache_new('allslots',$hashid,\%slots,600);
             return %slots;              return %slots;
         }          }
     }      }
Line 11559  sub get_dns { Line 11754  sub get_dns {
  next if ($response->is_error());   next if ($response->is_error());
  my @content = split("\n",$response->content);   my @content = split("\n",$response->content);
         unless ($nocache) {          unless ($nocache) {
     &Apache::lonnet::do_cache_new('dns',$url,\@content,30*24*60*60);      &do_cache_new('dns',$url,\@content,30*24*60*60);
         }          }
  &$func(\@content,$hashref);   &$func(\@content,$hashref);
  return;   return;
Line 11582  sub parse_dns_checksums_tab { Line 11777  sub parse_dns_checksums_tab {
     my (%chksum,%revnum);      my (%chksum,%revnum);
     if (ref($lines) eq 'ARRAY') {      if (ref($lines) eq 'ARRAY') {
         chomp(@{$lines});          chomp(@{$lines});
         my $versions = shift(@{$lines});          my $version = shift(@{$lines});
         my %supported;          if ($version eq $release) {
         if ($versions =~ /^VERSIONS\:([\w\.\,]+)$/) {  
             my $releaseslist = $1;  
             if ($releaseslist =~ /,/) {  
                 map { $supported{$_} = 1; } split(/,/,$releaseslist);  
             } elsif ($releaseslist) {  
                 $supported{$releaseslist} = 1;  
             }  
         }  
         if ($supported{$release}) {  
             my $matchthis = 0;  
             foreach my $line (@{$lines}) {              foreach my $line (@{$lines}) {
                 if ($line =~ /^(\d[\w\.]+)$/) {                  my ($file,$version,$shasum) = split(/,/,$line);
                     if ($matchthis) {                  $chksum{$file} = $shasum;
                         last;                  $revnum{$file} = $version;
                     } elsif ($1 eq $release) {  
                         $matchthis = 1;  
                     }  
                 } elsif ($matchthis) {  
                     my ($file,$version,$shasum) = split(/,/,$line);  
                     $chksum{$file} = $shasum;  
                     $revnum{$file} = $version;  
                 }  
             }              }
             if (ref($hashref) eq 'HASH') {              if (ref($hashref) eq 'HASH') {
                 %{$hashref} = (                  %{$hashref} = (
Line 11620  sub parse_dns_checksums_tab { Line 11797  sub parse_dns_checksums_tab {
   
 sub fetch_dns_checksums {  sub fetch_dns_checksums {
     my %checksums;      my %checksums;
     &get_dns('/adm/dns/checksums',\&parse_dns_checksums_tab,1,1,      my $machine_dom = &Apache::lonnet::host_domain($perlvar{'lonHostID'});
       my $loncaparev = &get_server_loncaparev($machine_dom);
       my ($release,$timestamp) = split(/\-/,$loncaparev);
       &get_dns("/adm/dns/checksums/$release",\&parse_dns_checksums_tab,1,1,
              \%checksums);               \%checksums);
     return \%checksums;      return \%checksums;
 }  }
Line 11934  sub fetch_dns_checksums { Line 12114  sub fetch_dns_checksums {
     }      }
     push(@{$iphost{$ip}},@{$name_to_host{$name}});      push(@{$iphost{$ip}},@{$name_to_host{$name}});
  }   }
  &Apache::lonnet::do_cache_new('iphost','iphost',   &do_cache_new('iphost','iphost',
       [\%iphost,\%name_to_ip,\%lonid_to_ip],        [\%iphost,\%name_to_ip,\%lonid_to_ip],
       48*60*60);        48*60*60);
   
  return %iphost;   return %iphost;
     }      }
Line 11992  sub fetch_dns_checksums { Line 12172  sub fetch_dns_checksums {
             }              }
             $seen{$prim_ip} = 1;              $seen{$prim_ip} = 1;
         }          }
         return &Apache::lonnet::do_cache_new('internetnames',$lonid,\@idns,12*60*60);          return &do_cache_new('internetnames',$lonid,\@idns,12*60*60);
     }      }
   
 }  }
Line 12001  sub all_loncaparevs { Line 12181  sub all_loncaparevs {
     return qw(1.1 1.2 1.3 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10);      return qw(1.1 1.2 1.3 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10);
 }  }
   
   # ------------------------------------------------------- Read loncaparev table
   {
       sub load_loncaparevs {
           if (-e "$perlvar{'lonTabDir'}/loncaparevs.tab") {
               if (open(my $config,"<$perlvar{'lonTabDir'}/loncaparevs.tab")) {
                   while (my $configline=<$config>) {
                       chomp($configline);
                       my ($hostid,$loncaparev)=split(/:/,$configline);
                       $loncaparevs{$hostid}=$loncaparev;
                   }
                   close($config);
               }
           }
       }
   }
   
   # ----------------------------------------------------- Read serverhostID table
   {
       sub load_serverhomeIDs {
           if (-e "$perlvar{'lonTabDir'}/serverhomeIDs.tab") {
               if (open(my $config,"<$perlvar{'lonTabDir'}/serverhomeIDs.tab")) {
                   while (my $configline=<$config>) {
                       chomp($configline);
                       my ($name,$id)=split(/:/,$configline);
                       $serverhomeIDs{$name}=$id;
                   }
                   close($config);
               }
           }
       }
   }
   
   
 BEGIN {  BEGIN {
   
 # ----------------------------------- Read loncapa.conf and loncapa_apache.conf  # ----------------------------------- Read loncapa.conf and loncapa_apache.conf
Line 12076  BEGIN { Line 12289  BEGIN {
     close($config);      close($config);
 }  }
   
 # ---------------------------------------------------------- Read loncaparev table  # --------------------------------------------------------- Read loncaparev table
 {  
     if (-e "$perlvar{'lonTabDir'}/loncaparevs.tab") {  
         if (open(my $config,"<$perlvar{'lonTabDir'}/loncaparevs.tab")) {  
             while (my $configline=<$config>) {  
                 chomp($configline);  
                 my ($hostid,$loncaparev)=split(/:/,$configline);  
                 $loncaparevs{$hostid}=$loncaparev;  
             }  
             close($config);  
         }  
     }  
 }  
   
 # ---------------------------------------------------------- Read serverhostID table  &load_loncaparevs();
 {  
     if (-e "$perlvar{'lonTabDir'}/serverhomeIDs.tab") {  
         if (open(my $config,"<$perlvar{'lonTabDir'}/serverhomeIDs.tab")) {  
             while (my $configline=<$config>) {  
                 chomp($configline);  
                 my ($name,$id)=split(/:/,$configline);  
                 $serverhomeIDs{$name}=$id;  
             }  
             close($config);  
         }  
     }  
 }  
   
   # ------------------------------------------------------- Read serverhostID table
   
   &load_serverhomeIDs();
   
   # ---------------------------------------------------------- Read releaseslist XML
 {  {
     my $file = $Apache::lonnet::perlvar{'lonTabDir'}.'/releaseslist.xml';      my $file = $Apache::lonnet::perlvar{'lonTabDir'}.'/releaseslist.xml';
     if (-e $file) {      if (-e $file) {
Line 12313  were new keys. I.E. 1:foo will become 1: Line 12507  were new keys. I.E. 1:foo will become 1:
   
 Calling convention:  Calling convention:
   
  my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$uname,$home);   my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$uname);
  &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$uname,$home);   &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$uname);
   
 For more detailed information, see lonnet specific documentation.  For more detailed information, see lonnet specific documentation.
   
Line 12491  environment).  If no custom name is defi Line 12685  environment).  If no custom name is defi
         
 =item *  =item *
   
 get_my_roles($uname,$udom,$context,$types,$roles,$roledoms,$withsec) :  get_my_roles($uname,$udom,$context,$types,$roles,$roledoms,$withsec,$hidepriv) :
 All arguments are optional. Returns a hash of a roles, either for  All arguments are optional. Returns a hash of a roles, either for
 co-author/assistant author roles for a user's Construction Space  co-author/assistant author roles for a user's Construction Space
 (default), or if $context is 'userroles', roles for the user himself,  (default), or if $context is 'userroles', roles for the user himself,
Line 12514  Additional optional arguments are: $type Line 12708  Additional optional arguments are: $type
 to certain user status types -- previous (expired roles), active (currently  to certain user status types -- previous (expired roles), active (currently
 available roles) or future (roles available in the future), and  available roles) or future (roles available in the future), and
 $hideprivileged -- if true will not report course roles for users who  $hideprivileged -- if true will not report course roles for users who
 have active Domain Coordinator or Super User roles.  have active Domain Coordinator role in course's domain or in additional
   domains (specified in 'Domains to check for privileged users' in course
   environment -- set via:  Course Settings -> Classlists and staff listing).
   
   =item *
   
   privileged($username,$domain,$possdomains,$possroles) : returns 1 if user
   $username:$domain is a privileged user (e.g., Domain Coordinator or Super User)
   $possdomains and $possroles are optional array refs -- to domains to check and
   roles to check.  If $possdomains is not specified, a dump will be done of the
   users' roles.db to check for a dc or su role in any domain. This can be
   time consuming if &privileged is called repeatedly (e.g., when displaying a
   classlist), so in such cases, supplying a $possdomains array is preferred, as
   this then allows &privileged_by_domain() to be used, which caches the identity
   of privileged users, eliminating the need for repeated calls to &dump().
   
   =item *
   
   privileged_by_domain($possdomains,$roles) : returns a hash of a hash of a hash,
   where the outer hash keys are domains specified in the $possdomains array ref,
   next inner hash keys are privileged roles specified in the $roles array ref,
   and the innermost hash contains key = value pairs for username:domain = end:start
   for active or future "privileged" users with that role in that domain. To avoid
   repeated dumps of domain roles -- via &get_domain_roles() -- contents of the
   innerhash are cached using priv_$role and $dom as the identifiers.
   
 =back  =back
   
Line 12557  or when Autoupdate.pl is run by cron in Line 12775  or when Autoupdate.pl is run by cron in
 modifystudent  modifystudent
   
 modify a student's enrollment and identification information.  modify a student's enrollment and identification information.
 The course id is resolved based on the current users environment.    The course id is resolved based on the current user's environment.  
 This means the envoking user must be a course coordinator or otherwise  This means the invoking user must be a course coordinator or otherwise
 associated with a course.  associated with a course.
   
 This call is essentially a wrapper for lonnet::modifyuser and  This call is essentially a wrapper for lonnet::modifyuser and
Line 12618  Inputs: Line 12836  Inputs:
   
 modify_student_enrollment  modify_student_enrollment
   
 Change a students enrollment status in a class.  The environment variable  Change a student's enrollment status in a class.  The environment variable
 'role.request.course' must be defined for this function to proceed.  'role.request.course' must be defined for this function to proceed.
   
 Inputs:  Inputs:
   
 =over 4  =over 4
   
 =item $udom, students domain  =item $udom, student's domain
   
 =item $uname, students name  =item $uname, student's name
   
 =item $uid, students user id  =item $uid, student's user id
   
 =item $first, students first name  =item $first, student's first name
   
 =item $middle  =item $middle
   
Line 12713  If defined, the supplied username is use Line 12931  If defined, the supplied username is use
 resdata($name,$domain,$type,@which) : request for current parameter  resdata($name,$domain,$type,@which) : request for current parameter
 setting for a specific $type, where $type is either 'course' or 'user',  setting for a specific $type, where $type is either 'course' or 'user',
 @what should be a list of parameters to ask about. This routine caches  @what should be a list of parameters to ask about. This routine caches
 answers for 5 minutes.  answers for 10 minutes.
   
 =item *  =item *
   
Line 12722  data base, returning a hash that is keye Line 12940  data base, returning a hash that is keye
 values that are the resource value.  I believe that the timestamps and  values that are the resource value.  I believe that the timestamps and
 versions are also returned.  versions are also returned.
   
   get_numsuppfiles($cnum,$cdom) : retrieve number of files in a course's
   supplemental content area. This routine caches the number of files for
   10 minutes.
   
 =back  =back
   
 =head2 Course Modification  =head2 Course Modification
Line 12781  resource. Expects the local filesystem p Line 13003  resource. Expects the local filesystem p
   
 =item *  =item *
   
 EXT($varname,$symb,$udom,$uname) : evaluates and returns the value of  EXT($varname,$symb,$udom,$uname,$usection,$recurse,$cid) : evaluates 
 a vairety of different possible values, $varname should be a request  and returns the value of a variety of different possible values,
 string, and the other parameters can be used to specify who and what  $varname should be a request string, and the other parameters can be
 one is asking about.  used to specify who and what one is asking about. Ordinarily, $cid 
   does not need to be specified, as it is retrived from 
   $env{'request.course.id'}, but &Apache::lonnet::EXT() is called
   within lonuserstate::loadmap() when initializing a course, before
   $env{'request.course.id'} has been set, so it needs to be provided
   in that one case.
   
 Possible values for $varname are environment.lastname (or other item  Possible values for $varname are environment.lastname (or other item
 from the envirnment hash), user.name (or someother aspect about the  from the envirnment hash), user.name (or someother aspect about the

Removed from v.1.1172.2.21  
changed lines
  Added in v.1.1172.2.34


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