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

version 1.1172.2.21, 2013/03/18 00:30:46 version 1.1195, 2012/11/09 17:27:18
Line 75  use LWP::UserAgent(); Line 75  use LWP::UserAgent();
 use HTTP::Date;  use HTTP::Date;
 use Image::Magick;  use Image::Magick;
   
 use vars qw(%perlvar %spareid %pr %prp $memcache %packagetab $tmpdir $apache  
   use Encode;
   
   use vars qw(%perlvar %spareid %pr %prp $memcache %packagetab $tmpdir
             $_64bit %env %protocol %loncaparevs %serverhomeIDs %needsrelease              $_64bit %env %protocol %loncaparevs %serverhomeIDs %needsrelease
             %managerstab);              %managerstab);
   
Line 97  use File::MMagic; Line 100  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 108  require Exporter; Line 112  require Exporter;
 our @ISA = qw (Exporter);  our @ISA = qw (Exporter);
 our @EXPORT = qw(%env);  our @EXPORT = qw(%env);
   
   
 # ------------------------------------ Logging (parameters, docs, slots, roles)  # ------------------------------------ Logging (parameters, docs, slots, roles)
 {  {
     my $logid;      my $logid;
Line 122  our @EXPORT = qw(%env); Line 127  our @EXPORT = qw(%env);
  $logid ++;   $logid ++;
         my $now = time();          my $now = time();
  my $id=$now.'00000'.$$.'00000'.$logid;   my $id=$now.'00000'.$$.'00000'.$logid;
         my $logentry = {          my $logentry = { 
                          $id => {                            $id => {
                                   'exe_uname' => $env{'user.name'},                                     'exe_uname' => $env{'user.name'},
                                   'exe_udom'  => $env{'user.domain'},                                     'exe_udom'  => $env{'user.domain'},
                                   'exe_time'  => $now,                                     'exe_time'  => $now,
                                   'exe_ip'    => $ENV{'REMOTE_ADDR'},                                     'exe_ip'    => $ENV{'REMOTE_ADDR'},
                                   'delflag'   => $delflag,                                     'delflag'   => $delflag,
                                   'logentry'  => $storehash,                                     'logentry'  => $storehash,
                                   'uname'     => $uname,                                     'uname'     => $uname,
                                   'udom'      => $udom,                                     'udom'      => $udom,
                                 }                                    }
                        };                         };
         return &put('nohist_'.$hash_name,$logentry,$cdom,$cnum);   return &put('nohist_'.$hash_name,$logentry,$cdom,$cnum);
     }      }
 }  }
   
Line 629  sub check_for_valid_session { Line 634  sub check_for_valid_session {
  || !defined($disk_env{'user.domain'})) {   || !defined($disk_env{'user.domain'})) {
  return undef;   return undef;
     }      }
   
     if (($r->user() eq '') && ($apache >= 2.4)) {  
         if ($disk_env{'user.domain'} eq $r->dir_config('lonDefDomain')) {  
             $r->user($disk_env{'user.name'});  
         } else {  
             $r->user($disk_env{'user.name'}.':'.$disk_env{'user.domain'});  
         }  
     }  
   
     return $handle;      return $handle;
 }  }
   
Line 1270  sub check_loadbalancing { Line 1266  sub check_loadbalancing {
         }          }
     }      }
     if (ref($result) eq 'HASH') {      if (ref($result) eq 'HASH') {
         ($is_balancer,$currtargets,$currrules) =          ($is_balancer,$currtargets,$currrules) = 
             &check_balancer_result($result,@hosts);              &check_balancer_result($result,@hosts);
         if ($is_balancer) {          if ($is_balancer) {
             if (ref($currrules) eq 'HASH') {              if (ref($currrules) eq 'HASH') {
Line 1329  sub check_loadbalancing { Line 1325  sub check_loadbalancing {
             }              }
         }          }
         if (ref($result) eq 'HASH') {          if (ref($result) eq 'HASH') {
             ($is_balancer,$currtargets,$currrules) =              ($is_balancer,$currtargets,$currrules) = 
                 &check_balancer_result($result,@hosts);                  &check_balancer_result($result,@hosts);
             if ($is_balancer) {              if ($is_balancer) {
                 if (ref($currrules) eq 'HASH') {                  if (ref($currrules) eq 'HASH') {
Line 1385  sub check_loadbalancing { Line 1381  sub check_loadbalancing {
             $is_balancer = 0;              $is_balancer = 0;
             if ($uname ne '' && $udom ne '') {              if ($uname ne '' && $udom ne '') {
                 if (($env{'user.name'} eq $uname) && ($env{'user.domain'} eq $udom)) {                  if (($env{'user.name'} eq $uname) && ($env{'user.domain'} eq $udom)) {
                       
                     &appenv({'user.loadbalexempt'     => $lonhost,                      &appenv({'user.loadbalexempt'     => $lonhost,  
                              'user.loadbalcheck.time' => time});                               'user.loadbalcheck.time' => time});
                 }                  }
             }              }
Line 2004  sub get_domain_defaults { Line 2000  sub get_domain_defaults {
         }          }
     }      }
     if (ref($domconfig{'coursedefaults'}) eq 'HASH') {      if (ref($domconfig{'coursedefaults'}) eq 'HASH') {
         if (ref($domconfig{'coursedefaults'}{'coursecredits'}) eq 'HASH') {          foreach my $item ('canuse_pdfforms') {
             $domdefaults{'officialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'official'};              $domdefaults{$item} = $domconfig{'coursedefaults'}{$item};
             $domdefaults{'unofficialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'};  
         }          }
     }      }
     if (ref($domconfig{'usersessions'}) eq 'HASH') {      if (ref($domconfig{'usersessions'}) eq 'HASH') {
Line 2615  sub ssi { Line 2610  sub ssi {
   
     $request->header(Cookie => $ENV{'HTTP_COOKIE'});      $request->header(Cookie => $ENV{'HTTP_COOKIE'});
     my $response= $ua->request($request);      my $response= $ua->request($request);
       my $content = $response->content;
   
   
     if (wantarray) {      if (wantarray) {
  return ($response->content, $response);   return ($content, $response);
     } else {      } else {
  return $response->content;   return $content;
     }      }
 }  }
   
Line 2650  sub allowuploaded { Line 2648  sub allowuploaded {
 #  #
 # Determine if the current user should be able to edit a particular resource,  # Determine if the current user should be able to edit a particular resource,
 # when viewing in course context.  # when viewing in course context.
 # (a) When viewing resource used to determine if "Edit" item is included in  # (a) When viewing resource used to determine if "Edit" item is included in 
 #     Functions.  #     Functions.
 # (b) When displaying folder contents in course editor, used to determine if  # (b) When displaying folder contents in course editor, used to determine if
 #     "Edit" link will be displayed alongside resource.  #     "Edit" link will be displayed alongside resource.
 #  #
 #  input: six args -- filename (decluttered), course number, course domain,  #  input: 3 args -- filename (decluttered), course number and course domain.
 #                   url, symb (if registered) and group (if this is a group  #  output: array of four scalars -- 
 #                   item -- e.g., bulletin board, group page etc.).  
 #  output: array of five scalars --  
 #          $cfile -- url for file editing if editable on current server  #          $cfile -- url for file editing if editable on current server
 #          $home -- homeserver of resource (i.e., for author if published,  #          $home -- homeserver of resource (i.e., for author if published,
 #                                           or course if uploaded.).  #                                           or course if uploaded.).
 #          $switchserver --  1 if server switch will be needed.  #          $switchserver --  1 if server switch will be needed.
 #          $forceedit -- 1 if icon/link should be to go to edit mode  #          $uploaded -- 1 if resource is a file uploaded to a course.
 #          $forceview -- 1 if icon/link should be to go to view mode  
 #  #
   
 sub can_edit_resource {  sub can_edit_resource {
Line 2673  sub can_edit_resource { Line 2668  sub can_edit_resource {
 #  #
 # For aboutme pages user can only edit his/her own.  # For aboutme pages user can only edit his/her own.
 #  #
     if ($resurl =~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) {      if ($resurl =~ m{^/adm/($match_domain)/($match_username)/aboutme$}) {
         my ($sdom,$sname) = ($1,$2);          my ($sdom,$sname) = ($1,$2);
         if (($sdom eq $env{'user.domain'}) && ($sname eq $env{'user.name'})) {          if (($sdom eq $env{'user.domain'}) && ($sname eq $env{'user.name'})) {
             $home = $env{'user.home'};              $home = $env{'user.home'};
Line 2694  sub can_edit_resource { Line 2689  sub can_edit_resource {
         if ($group ne '') {          if ($group ne '') {
 # if this is a group homepage or group bulletin board, check group privs  # if this is a group homepage or group bulletin board, check group privs
             my $allowed = 0;              my $allowed = 0;
             if ($resurl =~ m{^/?adm/$cdom/$cnum/$group/smppg$}) {              if ($resurl =~ m{^/adm/$cdom/$cnum/$group/smppg$}) {
                 if ((&allowed('mdg',$env{'request.course.id'}.                  if ((&Apache::lonnet::allowed('mdg',$env{'request.course.id'}.
                               ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) ||                              ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) ||
                         (&allowed('mgh',$env{'request.course.id'}.'/'.$group)) || $crsedit) {                          (&allowed('mgh',$env{'request.course.id'}.'/'.$group)) || $crsedit) {
                     $allowed = 1;                      $allowed = 1;
                 }                  }
             } elsif ($resurl =~ m{^/?adm/$cdom/$cnum/\d+/bulletinboard$}) {              } elsif ($resurl =~ m{^/adm/$cdom/$cnum/\d+/bulletinboard$}) {
                 if ((&allowed('mdg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) ||                  unless ((&allowed(&Apache::lonnet::allowed('mdg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')))) ||
                         (&allowed('cgb',$env{'request.course.id'}.'/'.$group)) || $crsedit) {                          (&allowed('cgb',$env{'request.course.id'}.$group)) || $crsedit) {
                     $allowed = 1;                      $allowed = 1;
                 }                  }
             }              }
Line 2718  sub can_edit_resource { Line 2713  sub can_edit_resource {
                 return;                  return;
             }              }
         } else {          } else {
             if ($resurl =~ m{^/?adm/viewclasslist$}) {  
                 unless (&Apache::lonnet::allowed('opa',$env{'request.course.id'})) {  
                     return;  
                 }  
             } elsif (!$crsedit) {  
 #  #
 # No edit allowed where CC has switched to student role.  # No edit allowed where CC has switched to student role.
 #  #
               unless ($crsedit) {
                 return;                  return;
             }              }
         }          }
Line 2738  sub can_edit_resource { Line 2729  sub can_edit_resource {
                 $incourse = 1;                  $incourse = 1;
                 if ($file =~/\.(htm|html|css|js|txt)$/) {                  if ($file =~/\.(htm|html|css|js|txt)$/) {
                     $cfile = &hreflocation('',$file);                      $cfile = &hreflocation('',$file);
                     if ($env{'form.forceedit'}) {                      $forceedit = 1;
                         $forceview = 1;  
                     } else {  
                         $forceedit = 1;  
                     }  
                 }                  }
             } elsif ($resurl =~ m{^/public/$cdom/$cnum/syllabus}) {              } elsif ($resurl =~ m{^/public/$cdom/$cnum/syllabus}) {
                 $incourse = 1;                  $incourse = 1;
Line 2752  sub can_edit_resource { Line 2739  sub can_edit_resource {
                     $forceedit = 1;                      $forceedit = 1;
                 }                  }
                 $cfile = $resurl;                  $cfile = $resurl;
             } elsif (($resurl ne '') && (&is_on_map($resurl))) {              } elsif (($resurl ne '') && (&is_on_map($resurl))) { 
                 if ($resurl =~ m{^/adm/$match_domain/$match_username/\d+/smppg|bulletinboard$}) {                  if ($resurl =~ m{^/adm/$match_domain/$match_username/\d+/smppg|bulletinboard$}) {
                     $incourse = 1;                      $incourse = 1;
                     if ($env{'form.forceedit'}) {                      if ($env{'form.forceedit'}) {
Line 2761  sub can_edit_resource { Line 2748  sub can_edit_resource {
                         $forceedit = 1;                          $forceedit = 1;
                     }                      }
                     $cfile = $resurl;                      $cfile = $resurl;
                 } elsif ($resurl eq '/res/lib/templates/simpleproblem.problem') {                  } elsif (($resurl eq '/res/lib/templates/simpleproblem.problem')) {
                     $incourse = 1;                      $incourse = 1;
                     $cfile = $resurl.'/smpedit';                      $cfile = $resurl.'/smpedit';
                 } elsif ($resurl =~ m{^/adm/wrapper/ext/}) {                  } elsif ($resurl =~ /ext/) {
                     $incourse = 1;  
                     if ($env{'form.forceedit'}) {  
                         $forceview = 1;  
                     } else {  
                         $forceedit = 1;  
                     }  
                     $cfile = $resurl;  
                 } elsif ($resurl =~ m{^/?adm/viewclasslist$}) {  
                     $incourse = 1;                      $incourse = 1;
                     if ($env{'form.forceedit'}) {                      # is external
                         $forceview = 1;  
                     } else {  
                         $forceedit = 1;  
                     }  
                     $cfile = ($resurl =~ m{^/} ? $resurl : "/$resurl");  
                 }                  }
             } elsif ($resurl eq '/res/lib/templates/simpleproblem.problem/smpedit') {              } elsif ($resurl eq '/res/lib/templates/simpleproblem.problem/smpedit') {
                 my $template = '/res/lib/templates/simpleproblem.problem';                  my $template = '/res/lib/templates/simpleproblem.problem';
                 if (&is_on_map($template)) {                  if (&is_on_map($template)) { 
                     $incourse = 1;                      $incourse = 1;
                     $forceview = 1;                      $forceview = 1;
                     $cfile = $template;                      $cfile = $template;
                 }                  }
             } elsif (($resurl =~ m{^/adm/wrapper/ext/}) && ($env{'form.folderpath'} =~ /^supplemental/)) {  
                     $incourse = 1;  
                     if ($env{'form.forceedit'}) {  
                         $forceview = 1;  
                     } else {  
                         $forceedit = 1;  
                     }  
                     $cfile = $resurl;  
             } elsif (($resurl eq '/adm/extresedit') && ($symb || $env{'form.folderpath'})) {  
                 $incourse = 1;  
                 $forceview = 1;  
                 if ($symb) {  
                     my ($map,$id,$res)=&decode_symb($symb);  
                     $env{'request.symb'} = $symb;  
                     $cfile = &clutter($res);  
                 } else {  
                     $cfile = $env{'form.suppurl'};  
                     $cfile =~ s{^http://}{};  
                     $cfile = '/adm/wrapper/ext/'.$cfile;  
                 }  
             }              }
         }          }
         if ($uploaded || $incourse) {          if ($uploaded || $incourse) {
             $home=&homeserver($cnum,$cdom);              $home=&homeserver($cnum,$cdom);
         } elsif ($file !~ m{/$}) {          } else {
             $file=~s{^(priv/$match_domain/$match_username)}{/$1};              $file=~s{^(priv/$match_domain/$match_username)}{/$1};
             $file=~s{^($match_domain/$match_username)}{/priv/$1};              $file=~s{^($match_domain/$match_username)}{/priv/$1};
             # Check that the user has permission to edit this resource              # Check that the user has permission to edit this resource
Line 2823  sub can_edit_resource { Line 2777  sub can_edit_resource {
                 $cfile=$file;                  $cfile=$file;
             }              }
         }          }
         if (($cfile ne '') && (!$incourse || $uploaded) &&          if (($cfile ne '') && (!$incourse || $uploaded) && 
             (($home ne '') && ($home ne 'no_host'))) {              (($home ne '') && ($home ne 'no_host'))) {
             my @ids=&current_machine_ids();              my @ids=&current_machine_ids();
             unless (grep(/^\Q$home\E$/,@ids)) {              unless (grep(/^\Q$home\E$/,@ids)) {
Line 2838  sub is_course_upload { Line 2792  sub is_course_upload {
     my ($file,$cnum,$cdom) = @_;      my ($file,$cnum,$cdom) = @_;
     my $uploadpath = &LONCAPA::propath($cdom,$cnum);      my $uploadpath = &LONCAPA::propath($cdom,$cnum);
     $uploadpath =~ s{^\/}{};      $uploadpath =~ s{^\/}{};
     if (($file =~ m{^\Q$uploadpath\E/userfiles/(docs|supplemental)/}) ||      if (($file =~ m{^\Q$uploadpath\E/userfiles/docs/}) ||
         ($file =~ m{^userfiles/\Q$cdom\E/\Q$cnum\E/(docs|supplemental)/})) {          ($file =~ m{^userfiles/\Q$cdom\E/\Q$cnum\E/docs/})) {
         return 1;          return 1;
     }      }
     return;      return;
Line 3184  sub userfileupload { Line 3138  sub userfileupload {
  $codebase,$thumbwidth,$thumbheight,   $codebase,$thumbwidth,$thumbheight,
                                          $resizewidth,$resizeheight,$context,$mimetype);                                           $resizewidth,$resizeheight,$context,$mimetype);
         } else {          } else {
             if ($env{'form.folder'}) {              $fname=$env{'form.folder'}.'/'.$fname;
                 $fname=$env{'form.folder'}.'/'.$fname;  
             }  
             return &process_coursefile('uploaddoc',$docuname,$docudom,              return &process_coursefile('uploaddoc',$docuname,$docudom,
        $fname,$formname,$parser,         $fname,$formname,$parser,
        $allfiles,$codebase,$mimetype);         $allfiles,$codebase,$mimetype);
Line 4132  sub courseiddump { Line 4084  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 5053  sub rolesinit { Line 5019  sub rolesinit {
 }  }
   
 sub set_arearole {  sub set_arearole {
     my ($trole,$area,$tstart,$tend,$domain,$username,$nolog) = @_;      my ($trole,$area,$tstart,$tend,$domain,$username) = @_;
     unless ($nolog) {  
 # log the associated role with the area  # log the associated role with the area
         &userrolelog($trole,$username,$domain,$area,$tstart,$tend);      &userrolelog($trole,$username,$domain,$area,$tstart,$tend);
     }  
     return ('user.role.'.$trole.'.'.$area => $tstart.'.'.$tend);      return ('user.role.'.$trole.'.'.$area => $tstart.'.'.$tend);
 }  }
   
Line 5326  sub set_adhoc_privileges { Line 5290  sub set_adhoc_privileges {
     my $area = '/'.$dcdom.'/'.$pickedcourse;      my $area = '/'.$dcdom.'/'.$pickedcourse;
     my $spec = $role.'.'.$area;      my $spec = $role.'.'.$area;
     my %userroles = &set_arearole($role,$area,'','',$env{'user.domain'},      my %userroles = &set_arearole($role,$area,'','',$env{'user.domain'},
                                   $env{'user.name'},1);                                    $env{'user.name'});
     my %ccrole = ();      my %ccrole = ();
     &standard_roleprivs(\%ccrole,$role,$dcdom,$spec,$pickedcourse,$area);      &standard_roleprivs(\%ccrole,$role,$dcdom,$spec,$pickedcourse,$area);
     my ($author,$adv)= &set_userprivs(\%userroles,\%ccrole);      my ($author,$adv)= &set_userprivs(\%userroles,\%ccrole);
Line 5389  sub del { Line 5353  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} = Apache::lonnet::thaw_unescape($value);
    }
       #return %returnhash;
       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)), $loncaparevs{$uhome});
           return %{unserialize($reply, $escapedkeys)};
       }
     if ($regexp) {      if ($regexp) {
  $regexp=&escape($regexp);   $regexp=&escape($regexp);
     } else {      } else {
Line 5406  sub dump { Line 5395  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;
           #$key = &unescape($key);
     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 5409  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 5461  sub currentdump { Line 5437  sub currentdump {
    $sdom     = $env{'user.domain'}       if (! defined($sdom));     $sdom     = $env{'user.domain'}       if (! defined($sdom));
    $sname    = $env{'user.name'}         if (! defined($sname));     $sname    = $env{'user.name'}         if (! defined($sname));
    my $uhome = &homeserver($sname,$sdom);     my $uhome = &homeserver($sname,$sdom);
    my $rep=reply('currentdump:'.$sdom.':'.$sname.':'.$courseid,$uhome);     my $rep;
   
      if (grep { $_ eq $uhome } current_machine_ids()) {
          $rep = LONCAPA::Lond::dump_profile_database(join(":", ($sdom, $sname, 
                      $courseid)));
      } else {
          $rep = reply('currentdump:'.$sdom.':'.$sname.':'.$courseid,$uhome);
      }
   
    return if ($rep =~ /^(error:|no_such_host)/);     return if ($rep =~ /^(error:|no_such_host)/);
    #     #
    my %returnhash=();     my %returnhash=();
Line 5704  sub tmpdel { Line 5688  sub tmpdel {
     return &reply("tmpdel:$token",$server);      return &reply("tmpdel:$token",$server);
 }  }
   
 # ------------------------------------------------------------ get_timebased_id  
   
 sub get_timebased_id {  
     my ($prefix,$keyid,$namespace,$cdom,$cnum,$idtype,$who,$locktries,  
         $maxtries) = @_;  
     my ($newid,$error,$dellock);  
     unless (($prefix =~ /^\w+$/) && ($keyid =~ /^\w+$/) && ($namespace ne '')) {  
         return ('','ok','invalid call to get suffix');  
     }  
   
 # set defaults for any optional args for which values were not supplied  
     if ($who eq '') {  
         $who = $env{'user.name'}.':'.$env{'user.domain'};  
     }  
     if (!$locktries) {  
         $locktries = 3;  
     }  
     if (!$maxtries) {  
         $maxtries = 10;  
     }  
   
     if (($cdom eq '') || ($cnum eq '')) {  
         if ($env{'request.course.id'}) {  
             $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};  
             $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};  
         }  
         if (($cdom eq '') || ($cnum eq '')) {  
             return ('','ok','call to get suffix not in course context');  
         }  
     }  
   
 # construct locking item  
     my $lockhash = {  
                       $prefix."\0".'locked_'.$keyid => $who,  
                    };  
     my $tries = 0;  
   
 # attempt to get lock on nohist_$namespace file  
     my $gotlock = &Apache::lonnet::newput('nohist_'.$namespace,$lockhash,$cdom,$cnum);  
     while (($gotlock ne 'ok') && $tries <$locktries) {  
         $tries ++;  
         sleep 1;  
         $gotlock = &Apache::lonnet::newput('nohist_'.$namespace,$lockhash,$cdom,$cnum);  
     }  
   
 # attempt to get unique identifier, based on current timestamp  
     if ($gotlock eq 'ok') {  
         my %inuse = &Apache::lonnet::dump('nohist_'.$namespace,$cdom,$cnum,$prefix);  
         my $id = time;  
         $newid = $id;  
         my $idtries = 0;  
         while (exists($inuse{$prefix."\0".$newid}) && $idtries < $maxtries) {  
             if ($idtype eq 'concat') {  
                 $newid = $id.$idtries;  
             } else {  
                 $newid ++;  
             }  
             $idtries ++;  
         }  
         if (!exists($inuse{$prefix."\0".$newid})) {  
             my %new_item =  (  
                               $prefix."\0".$newid => $who,  
                             );  
             my $putresult = &Apache::lonnet::put('nohist_'.$namespace,\%new_item,  
                                                  $cdom,$cnum);  
             if ($putresult ne 'ok') {  
                 undef($newid);  
                 $error = 'error saving new item: '.$putresult;  
             }  
         } else {  
              $error = ('error: no unique suffix available for the new item ');  
         }  
 #  remove lock  
         my @del_lock = ($prefix."\0".'locked_'.$keyid);  
         $dellock = &Apache::lonnet::del('nohist_'.$namespace,\@del_lock,$cdom,$cnum);  
     } else {  
         $error = "error: could not obtain lockfile\n";  
         $dellock = 'ok';  
     }  
     return ($newid,$dellock,$error);  
 }  
   
 # -------------------------------------------------- portfolio access checking  # -------------------------------------------------- portfolio access checking
   
 sub portfolio_access {  sub portfolio_access {
Line 6074  sub usertools_access { Line 5976  sub usertools_access {
   
     my ($toolstatus,$inststatus,$envkey);      my ($toolstatus,$inststatus,$envkey);
     if ($context eq 'requestauthor') {      if ($context eq 'requestauthor') {
         $envkey = $context;          $envkey = $context; 
     } else {      } else {
         $envkey = $context.'.'.$tool;          $envkey = $context.'.'.$tool;
     }      }
Line 6865  sub constructaccess { Line 6767  sub constructaccess {
     if (($allowed eq 'F') || ($allowed eq 'U')) {      if (($allowed eq 'F') || ($allowed eq 'U')) {
 # Grant temporary access  # Grant temporary access
         my $then=$env{'user.login.time'};          my $then=$env{'user.login.time'};
         my $update=$env{'user.update.time'};          my $update==$env{'user.update.time'};
         if (!$update) { $update = $then; }          if (!$update) { $update = $then; }
         my $refresh=$env{'user.refresh.time'};          my $refresh=$env{'user.refresh.time'};
         if (!$refresh) { $refresh = $update; }          if (!$refresh) { $refresh = $update; }
Line 7404  sub auto_validate_instcode { Line 7306  sub auto_validate_instcode {
     }      }
     $response=&unescape(&reply('autovalidateinstcode:'.$cdom.':'.      $response=&unescape(&reply('autovalidateinstcode:'.$cdom.':'.
                         &escape($instcode).':'.&escape($owner),$homeserver));                          &escape($instcode).':'.&escape($owner),$homeserver));
     my ($outcome,$description,$defaultcredits) = map { &unescape($_); } split('&',$response,3);      my ($outcome,$description) = map { &unescape($_); } split('&',$response,2);
     return ($outcome,$description,$defaultcredits);      return ($outcome,$description);
 }  }
   
 sub auto_create_password {  sub auto_create_password {
Line 7944  sub assignrole { Line 7846  sub assignrole {
                         }                          }
                     }                      }
                 } elsif ($context eq 'requestauthor') {                  } elsif ($context eq 'requestauthor') {
                     if (($udom eq $env{'user.domain'}) && ($uname eq $env{'user.name'}) &&                      if (($udom eq $env{'user.domain'}) && ($uname eq $env{'user.name'}) && 
                         ($url eq '/'.$udom.'/') && ($role eq 'au')) {                          ($url eq '/'.$udom.'/') && ($role eq 'au')) {
                         if ($env{'environment.requestauthor'} eq 'automatic') {                          if ($env{'environment.requestauthor'} eq 'automatic') {
                             $refused = '';                              $refused = '';
Line 7952  sub assignrole { Line 7854  sub assignrole {
                             my %domdefaults = &get_domain_defaults($udom);                              my %domdefaults = &get_domain_defaults($udom);
                             if (ref($domdefaults{'requestauthor'}) eq 'HASH') {                              if (ref($domdefaults{'requestauthor'}) eq 'HASH') {
                                 my $checkbystatus;                                  my $checkbystatus;
                                 if ($env{'user.adv'}) {                                  if ($env{'user.adv'}) { 
                                     my $disposition = $domdefaults{'requestauthor'}{'_LC_adv'};                                      my $disposition = $domdefaults{'requestauthor'}{'_LC_adv'};
                                     if ($disposition eq 'automatic') {                                      if ($disposition eq 'automatic') {
                                         $refused = '';                                          $refused = '';
                                     } elsif ($disposition eq '') {                                      } elsif ($disposition eq '') {
                                         $checkbystatus = 1;                                          $checkbystatus = 1;
                                     }                                      } 
                                 } else {                                  } else {
                                     $checkbystatus = 1;                                      $checkbystatus = 1;
                                 }                                  }
Line 8027  sub assignrole { Line 7929  sub assignrole {
 # log new user role if status is ok  # log new user role if status is ok
     if ($answer eq 'ok') {      if ($answer eq 'ok') {
  &userrolelog($role,$uname,$udom,$url,$start,$end);   &userrolelog($role,$uname,$udom,$url,$start,$end);
   # for course roles, perform group memberships changes triggered by role change.
           unless ($role =~ /^gr/) {
               &Apache::longroup::group_changes($udom,$uname,$url,$role,$origend,
                                                $origstart,$selfenroll,$context);
           }
         if (($role eq 'cc') || ($role eq 'in') ||          if (($role eq 'cc') || ($role eq 'in') ||
             ($role eq 'ep') || ($role eq 'ad') ||              ($role eq 'ep') || ($role eq 'ad') ||
             ($role eq 'ta') || ($role eq 'st') ||              ($role eq 'ta') || ($role eq 'st') ||
             ($role=~/^cr/) || ($role eq 'gr') ||              ($role=~/^cr/) || ($role eq 'gr') ||
             ($role eq 'co')) {              ($role eq 'co')) {
 # for course roles, perform group memberships changes triggered by role change.  
             unless ($role =~ /^gr/) {  
                 &Apache::longroup::group_changes($udom,$uname,$url,$role,$origend,  
                                                  $origstart,$selfenroll,$context);  
             }  
             &courserolelog($role,$uname,$udom,$url,$origstart,$origend,$delflag,              &courserolelog($role,$uname,$udom,$url,$origstart,$origend,$delflag,
                            $selfenroll,$context);                             $selfenroll,$context);
         } elsif (($role eq 'li') || ($role eq 'dg') || ($role eq 'sc') ||          } elsif (($role eq 'li') || ($role eq 'dg') || ($role eq 'sc') ||
Line 8045  sub assignrole { Line 7947  sub assignrole {
                            $context);                             $context);
         } elsif (($role eq 'ca') || ($role eq 'aa')) {          } elsif (($role eq 'ca') || ($role eq 'aa')) {
             &coauthorrolelog($role,$uname,$udom,$url,$origstart,$origend,$delflag,              &coauthorrolelog($role,$uname,$udom,$url,$origstart,$origend,$delflag,
                              $context);                               $context); 
         }          }
         if ($role eq 'cc') {          if ($role eq 'cc') {
             &autoupdate_coowners($url,$end,$start,$uname,$udom);              &autoupdate_coowners($url,$end,$start,$uname,$udom);
Line 8345  sub modifyuser { Line 8247  sub modifyuser {
 sub modifystudent {  sub modifystudent {
     my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec,      my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec,
         $end,$start,$forceid,$desiredhome,$email,$type,$locktype,$cid,          $end,$start,$forceid,$desiredhome,$email,$type,$locktype,$cid,
         $selfenroll,$context,$inststatus,$credits)=@_;          $selfenroll,$context,$inststatus)=@_;
     if (!$cid) {      if (!$cid) {
  unless ($cid=$env{'request.course.id'}) {   unless ($cid=$env{'request.course.id'}) {
     return 'not_in_class';      return 'not_in_class';
Line 8360  sub modifystudent { Line 8262  sub modifystudent {
     # students environment      # students 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,$cid,$selfenroll,$context);
                                         $cid,$selfenroll,$context,$credits);  
     return $reply;      return $reply;
 }  }
   
 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) = @_;
     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 8413  sub modify_student_enrollment { Line 8314  sub modify_student_enrollment {
     my %old_entry = &Apache::lonnet::get('classlist',[$user],$cdom,$cnum);      my %old_entry = &Apache::lonnet::get('classlist',[$user],$cdom,$cnum);
     my $reply=cput('classlist',      my $reply=cput('classlist',
    {$user =>      {$user => 
  join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype,$credits) },   join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype) },
    $cdom,$cnum);     $cdom,$cnum);
     if (($reply eq 'ok') || ($reply eq 'delayed')) {      if (($reply eq 'ok') || ($reply eq 'delayed')) {
         &devalidate_getsection_cache($udom,$uname,$cid);          &devalidate_getsection_cache($udom,$uname,$cid);
Line 9898  sub metadata { Line 9799  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 '') ||       if (($uri eq '') || 
  (($uri =~ m|^/*adm/|) &&    (($uri =~ m|^/*adm/|) && 
      ($uri !~ m|^adm/includes|) && ($uri !~ m{/(smppg|bulletinboard)$})) ||       ($uri !~ m|^adm/includes|) && ($uri !~ m|/bulletinboard$|)) ||
         ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ m{^/*uploaded/.+\.sequence$})) {          ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ m{^/*uploaded/.+\.sequence$})) {
  return undef;   return undef;
     }      }
Line 10276  sub gettitle { Line 10177  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 10495  sub symbverify { Line 10324  sub symbverify {
   
     if (tie(%bighash,'GDBM_File',$env{'request.course.fn'}.'.db',      if (tie(%bighash,'GDBM_File',$env{'request.course.fn'}.'.db',
                             &GDBM_READER(),0640)) {                              &GDBM_READER(),0640)) {
         my $noclutter;  
         if (($thisurl =~ m{^/adm/wrapper/ext/}) || ($thisurl =~ m{^ext/})) {          if (($thisurl =~ m{^/adm/wrapper/ext/}) || ($thisurl =~ m{^ext/})) {
             $thisurl =~ s/\?.+$//;              $thisurl =~ s/\?.+$//;
             if ($map =~ m{^uploaded/.+\.page$}) {  
                 $thisurl =~ s{^(/adm/wrapper|)/ext/}{http://};  
                 $thisurl =~ s{^\Qhttp://https://\E}{https://};  
                 $noclutter = 1;  
             }  
         }  
         my $ids;  
         if ($noclutter) {  
             $ids=$bighash{'ids_'.$thisurl};  
         } else {  
             $ids=$bighash{'ids_'.&clutter($thisurl)};  
         }          }
           my $ids=$bighash{'ids_'.&clutter($thisurl)};
         unless ($ids) {          unless ($ids) {
             my $idkey = 'ids_'.($thisurl =~ m{^/}? '' : '/').$thisurl;              my $idkey = 'ids_'.($thisurl =~ m{^/}? '' : '/').$thisurl;  
             $ids=$bighash{$idkey};              $ids=$bighash{$idkey};
         }          }
         if ($ids) {          if ($ids) {
 # ------------------------------------------------------------------- Has ID(s)  # ------------------------------------------------------------------- Has ID(s)
             if ($thisfn =~ m{^/adm/wrapper/ext/}) {  
                 $symb =~ s/\?.+$//;  
             }  
     foreach my $id (split(/\,/,$ids)) {      foreach my $id (split(/\,/,$ids)) {
        my ($mapid,$resid)=split(/\./,$id);         my ($mapid,$resid)=split(/\./,$id);
                  if ($thisfn =~ m{^/adm/wrapper/ext/}) {
                      $symb =~ s/\?.+$//;
                  }
                if (                 if (
   &symbclean(&declutter($bighash{'map_id_'.$mapid}).'___'.$resid.'___'.$thisfn)    &symbclean(&declutter($bighash{'map_id_'.$mapid}).'___'.$resid.'___'.$thisfn)
    eq $symb) {     eq $symb) {
                    if (ref($encstate)) {                     if (ref($encstate)) {
                        $$encstate = $bighash{'encrypted_'.$id};                         $$encstate = $bighash{'encrypted_'.$id};
                    }                     }
                    if (($env{'request.role.adv'}) ||     if (($env{'request.role.adv'}) ||
                        ($bighash{'encrypted_'.$id} eq $env{'request.enc'}) ||         ($bighash{'encrypted_'.$id} eq $env{'request.enc'}) ||
                        ($thisurl eq '/adm/navmaps')) {                         ($thisurl eq '/adm/navmaps')) {
                        $okay=1;         $okay=1;
                        last;     }
                    }         }
                }     }
            }  
         }          }
  untie(%bighash);   untie(%bighash);
     }      }
Line 10607  sub deversion { Line 10424  sub deversion {
   
 sub symbread {  sub symbread {
     my ($thisfn,$donotrecurse)=@_;      my ($thisfn,$donotrecurse)=@_;
     my $cache_str;      my $cache_str='request.symbread.cached.'.$thisfn;
     if ($thisfn ne '') {      if (defined($env{$cache_str})) {
         $cache_str='request.symbread.cached.'.$thisfn;          if (($thisfn) || ($env{$cache_str} ne '')) {
         if ($env{$cache_str} ne '') {  
             return $env{$cache_str};              return $env{$cache_str};
         }          }
    } else {      }
 # no filename provided? try from environment  # no filename provided? try from environment
       unless ($thisfn) {
         if ($env{'request.symb'}) {          if ($env{'request.symb'}) {
             return $env{$cache_str}=&symbclean($env{'request.symb'});      return $env{$cache_str}=&symbclean($env{'request.symb'});
         }   }
         $thisfn=$env{'request.filename'};   $thisfn=$env{'request.filename'};
     }      }
     if ($thisfn=~m|^/enc/|) { $thisfn=&Apache::lonenc::unencrypted($thisfn); }      if ($thisfn=~m|^/enc/|) { $thisfn=&Apache::lonenc::unencrypted($thisfn); }
 # is that filename actually a symb? Verify, clean, and return  # is that filename actually a symb? Verify, clean, and return
Line 10846  sub rndseed { Line 10663  sub rndseed {
  $which =&get_rand_alg($courseid);   $which =&get_rand_alg($courseid);
     }      }
     if (defined(&getCODE())) {      if (defined(&getCODE())) {
   
  if ($which eq '64bit5') {   if ($which eq '64bit5') {
     return &rndseed_CODE_64bit5($symb,$courseid,$domain,$username);      return &rndseed_CODE_64bit5($symb,$courseid,$domain,$username);
  } elsif ($which eq '64bit4') {   } elsif ($which eq '64bit4') {
Line 11528  sub goodbye { Line 11346  sub goodbye {
 }  }
   
 sub get_dns {  sub get_dns {
     my ($url,$func,$ignore_cache,$nocache,$hashref) = @_;      my ($url,$func,$ignore_cache) = @_;
     if (!$ignore_cache) {      if (!$ignore_cache) {
  my ($content,$cached)=   my ($content,$cached)=
     &Apache::lonnet::is_cached_new('dns',$url);      &Apache::lonnet::is_cached_new('dns',$url);
  if ($cached) {   if ($cached) {
     &$func($content,$hashref);      &$func($content);
     return;      return;
  }   }
     }      }
Line 11558  sub get_dns { Line 11376  sub get_dns {
         delete($alldns{$dns});          delete($alldns{$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) {   &Apache::lonnet::do_cache_new('dns',$url,\@content,30*24*60*60);
     &Apache::lonnet::do_cache_new('dns',$url,\@content,30*24*60*60);   &$func(\@content);
         }  
  &$func(\@content,$hashref);  
  return;   return;
     }      }
     close($config);      close($config);
Line 11569  sub get_dns { Line 11385  sub get_dns {
     &logthis("unable to contact DNS defaulting to on disk file dns_$which.tab\n");      &logthis("unable to contact DNS defaulting to on disk file dns_$which.tab\n");
     open($config,"<$perlvar{'lonTabDir'}/dns_$which.tab");      open($config,"<$perlvar{'lonTabDir'}/dns_$which.tab");
     my @content = <$config>;      my @content = <$config>;
     &$func(\@content,$hashref);      &$func(\@content);
     return;  
 }  
   
 # ------------------------------------------------------Get DNS checksums file  
 sub parse_dns_checksums_tab {  
     my ($lines,$hashref) = @_;  
     my $machine_dom = &Apache::lonnet::host_domain($perlvar{'lonHostID'});  
     my $loncaparev = &get_server_loncaparev($machine_dom);  
     my ($release,$timestamp) = split(/\-/,$loncaparev);  
     my (%chksum,%revnum);  
     if (ref($lines) eq 'ARRAY') {  
         chomp(@{$lines});  
         my $versions = shift(@{$lines});  
         my %supported;  
         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}) {  
                 if ($line =~ /^(\d[\w\.]+)$/) {  
                     if ($matchthis) {  
                         last;  
                     } 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') {  
                 %{$hashref} = (  
                                 sums     => \%chksum,  
                                 versions => \%revnum,  
                               );  
             }  
         }  
     }  
     return;      return;
 }  }
   
 sub fetch_dns_checksums {  
     my %checksums;  
     &get_dns('/adm/dns/checksums',\&parse_dns_checksums_tab,1,1,  
              \%checksums);  
     return \%checksums;  
 }  
   
 # ------------------------------------------------------------ Read domain file  # ------------------------------------------------------------ Read domain file
 {  {
     my $loaded;      my $loaded;
Line 12162  $readit=1; Line 11925  $readit=1;
  if ($test != 0) { $_64bit=1; } else { $_64bit=0; }   if ($test != 0) { $_64bit=1; } else { $_64bit=0; }
  &logthis(" Detected 64bit platform ($_64bit)");   &logthis(" Detected 64bit platform ($_64bit)");
     }      }
   
     {  
         eval {  
             ($apache) =  
                 (Apache2::ServerUtil::get_server_version() =~ m{Apache/(\d+\.\d+)});  
         };  
         if ($@) {  
            $apache = 1.3;  
         }  
     }  
   
 }  }
 }  }
   
Line 12508  provided for types, will default to retu Line 12260  provided for types, will default to retu
 =item *  =item *
   
 in_course($udom,$uname,$cdom,$cnum,$type,$hideprivileged) : determine if  in_course($udom,$uname,$cdom,$cnum,$type,$hideprivileged) : determine if
 user: $uname:$udom has a role in the course: $cdom_$cnum.  user: $uname:$udom has a role in the course: $cdom_$cnum. Additional
   optional arguments are: $type (if role checking is to be restricted to
 Additional optional arguments are: $type (if role checking is to be restricted  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 or Super User roles.
Line 12608  Inputs: Line 12359  Inputs:
   
 =item B<$context> role change context (shown in User Management Logs display in a course)  =item B<$context> role change context (shown in User Management Logs display in a course)
   
 =item B<$inststatus> institutional status of user - : separated string of escaped status types  =item B<$inststatus> institutional status of user - : separated string of escaped status types  
   
 =item B<$credits> Number of credits student will earn from this class - only needs to be supplied if value needs to be different from default credits for class.  
   
 =back  =back
   
Line 12655  Inputs: Line 12404  Inputs:
   
 =item $context  =item $context
   
 =item $credits, number of credits student will earn from this class  
   
 =back  =back
   
   
Line 12827  and is a possible symb for the URL in $t Line 12574  and is a possible symb for the URL in $t
 resource that the user accessed using /enc/ returns a 1 on success, 0  resource that the user accessed using /enc/ returns a 1 on success, 0
 on failure, user must be in a course, as it assumes the existence of  on failure, user must be in a course, as it assumes the existence of
 the course initial hash, and uses $env('request.course.id'}.  The third  the course initial hash, and uses $env('request.course.id'}.  The third
 arg is an optional reference to a scalar.  If this arg is passed in the  arg is an optional reference to a scalar.  If this arg is passed in the 
 call to symbverify, it will be set to 1 if the symb has been set to be   call to symbverify, it will be set to 1 if the symb has been set to be 
 encrypted; otherwise it will be null.  encrypted; otherwise it will be null.  
   
 =item *  =item *
   
Line 12882  expirespread($uname,$udom,$stype,$usymb) Line 12629  expirespread($uname,$udom,$stype,$usymb)
 devalidate($symb) : devalidate temporary spreadsheet calculations,  devalidate($symb) : devalidate temporary spreadsheet calculations,
 forcing spreadsheet to reevaluate the resource scores next time.  forcing spreadsheet to reevaluate the resource scores next time.
   
 =item *  =item * 
   
 can_edit_resource($file,$cnum,$cdom,$resurl,$symb,$group) : determine if current user can edit a particular resource,  can_edit_resource($file,$cnum,$cdom,$resurl,$symb,$group)
 when viewing in course context.  
   
  input: six args -- filename (decluttered), course number, course domain,  Determine if the current user should be able to edit a particular resource,
                     url, symb (if registered) and group (if this is a  when viewing in course context.
                     group item -- e.g., bulletin board, group page etc.).  (a) When viewing resource used to determine if "Edit" item is included in
        Functions.
   (b) When displaying folder contents in course editor, used to determine if
       "Edit" link will be displayed alongside resource.
   
  output: array of five scalars --   input: 3 args -- filename (decluttered), course number and course domain.
    output: array of four scalars --
          $cfile -- url for file editing if editable on current server           $cfile -- url for file editing if editable on current server
          $home -- homeserver of resource (i.e., for author if published,           $home -- homeserver of resource (i.e., for author if published,
                                           or course if uploaded.).                                            or course if uploaded.).
          $switchserver --  1 if server switch will be needed.           $switchserver --  1 if server switch will be needed.
          $forceedit -- 1 if icon/link should be to go to edit mode           $uploaded -- 1 if resource is a file uploaded to a course.
          $forceview -- 1 if icon/link should be to go to view mode  
   
 =item *  =item *
   
 is_course_upload($file,$cnum,$cdom)  is_course_upload($file,$cnum,$cdom)
   
 Used in course context to determine if current file was uploaded to  Used in course context to determine if current file was uploaded to 
 the course (i.e., would be found in /userfiles/docs on the course's  the course (i.e., would be found in /userfiles/docs on the course's 
 homeserver.  homeserver.
   
   input: 3 args -- filename (decluttered), course number and course domain.    input: 3 args -- filename (decluttered), course number and course domain.
Line 13465  Internal notes: Line 13214  Internal notes:
     
  Locks on files (resulting from submission of portfolio file to a homework problem stored in array of arrays.   Locks on files (resulting from submission of portfolio file to a homework problem stored in array of arrays.
   
 =item *  
   
 modify_access_controls():  modify_access_controls():
   
 Modifies access controls for a portfolio file  Modifies access controls for a portfolio file
Line 13484  Returns: Line 13231  Returns:
 3. reference to hash of any new or updated access controls.  3. reference to hash of any new or updated access controls.
 4. reference to hash used to map incoming IDs to uniqueIDs assigned to control.  4. reference to hash used to map incoming IDs to uniqueIDs assigned to control.
    key = integer (inbound ID)     key = integer (inbound ID)
    value = uniqueID     value = uniqueID  
   
 =item *  
   
 get_timebased_id():  
   
 Attempts to get a unique timestamp-based suffix for use with items added to a  
 course via the Course Editor (e.g., folders, composite pages,  
 group bulletin boards).  
   
 Args: (first three required; six others optional)  
   
 1. prefix (alphanumeric): of keys in hash, e.g., suppsequence, docspage,  
    docssequence, or name of group  
   
 2. keyid (alphanumeric): name of temporary locking key in hash,  
    e.g., num, boardids  
   
 3. namespace: name of gdbm file used to store suffixes already assigned;  
    file will be named nohist_namespace.db  
   
 4. cdom: domain of course; default is current course domain from %env  
   
 5. cnum: course number; default is current course number from %env  
   
 6. idtype: set to concat if an additional digit is to be appended to the  
    unix timestamp to form the suffix, if the plain timestamp is already  
    in use.  Default is to not do this, but simply increment the unix  
    timestamp by 1 until a unique key is obtained.  
   
 7. who: holder of locking key; defaults to user:domain for user.  
   
 8. locktries: number of attempts to obtain a lock (sleep of 1s before  
    retrying); default is 3.  
   
 9. maxtries: number of attempts to obtain a unique suffix; default is 20.  
   
 Returns:  
   
 1. suffix obtained (numeric)  
   
 2. result of deleting locking key (ok if deleted, or lock never obtained)  
   
 3. error: contains (localized) error message if an error occurred.  
   
   
 =back  =back
   

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


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