Diff for /loncom/lonnet/perl/lonnet.pm between versions 1.838 and 1.892

version 1.838, 2007/03/02 23:17:40 version 1.892, 2007/06/18 22:52:33
Line 31  package Apache::lonnet; Line 31  package Apache::lonnet;
   
 use strict;  use strict;
 use LWP::UserAgent();  use LWP::UserAgent();
 use HTTP::Headers;  
 use HTTP::Date;  use HTTP::Date;
 # use Date::Parse;  # use Date::Parse;
 use vars   use vars qw(%perlvar %spareid %pr %prp $memcache %packagetab $tmpdir
 qw(%perlvar %badServerCache %iphost %spareid %hostdom               $_64bit %env);
    %libserv %pr %prp $memcache %packagetab   
    %courselogs %accesshash %userrolehash %domainrolehash $processmarker $dumpcount   my (%badServerCache, $memcache, %courselogs, %accesshash, %domainrolehash,
    %coursedombuf %coursenumbuf %coursehombuf %coursedescrbuf %courseinstcodebuf %courseownerbuf %coursetypebuf      %userrolehash, $processmarker, $dumpcount, %coursedombuf,
    %domaindescription %domain_auth_def %domain_auth_arg_def       %coursenumbuf, %coursehombuf, %coursedescrbuf, %courseinstcodebuf,
    %domain_lang_def %domain_city %domain_longi %domain_lati %domain_primary      %courseownerbuf, %coursetypebuf);
    $tmpdir $_64bit %env);  
   
 use IO::Socket;  use IO::Socket;
 use GDBM_File;  use GDBM_File;
 use HTML::LCParser;  use HTML::LCParser;
 use HTML::Parser;  
 use Fcntl qw(:flock);  use Fcntl qw(:flock);
 use Storable qw(lock_store lock_nstore lock_retrieve freeze thaw nfreeze);  use Storable qw(thaw nfreeze);
 use Time::HiRes qw( gettimeofday tv_interval );  use Time::HiRes qw( gettimeofday tv_interval );
 use Cache::Memcached;  use Cache::Memcached;
 use Digest::MD5;  use Digest::MD5;
Line 146  sub logperm { Line 143  sub logperm {
     return 1;      return 1;
 }  }
   
   sub create_connection {
       my ($hostname,$lonid) = @_;
       my $client=IO::Socket::UNIX->new(Peer    => $perlvar{'lonSockCreate'},
        Type    => SOCK_STREAM,
        Timeout => 10);
       return 0 if (!$client);
       print $client (join(':',$hostname,$lonid,&machine_ids($hostname))."\n");
       my $result = <$client>;
       chomp($result);
       return 1 if ($result eq 'done');
       return 0;
   }
   
   
 # -------------------------------------------------- Non-critical communication  # -------------------------------------------------- Non-critical communication
 sub subreply {  sub subreply {
     my ($cmd,$server)=@_;      my ($cmd,$server)=@_;
Line 170  sub subreply { Line 181  sub subreply {
  $client=IO::Socket::UNIX->new(Peer    =>"$peerfile",   $client=IO::Socket::UNIX->new(Peer    =>"$peerfile",
       Type    => SOCK_STREAM,        Type    => SOCK_STREAM,
       Timeout => 10);        Timeout => 10);
  if($client) {   if ($client) {
     last; # Connected!      last; # Connected!
    } else {
       &create_connection(&hostname($server),$server);
  }   }
  sleep(1); # Try again later if failed connection.          sleep(1); # Try again later if failed connection.
     }      }
     my $answer;      my $answer;
     if ($client) {      if ($client) {
Line 201  sub reply { Line 214  sub reply {
 # ----------------------------------------------------------- Send USR1 to lonc  # ----------------------------------------------------------- Send USR1 to lonc
   
 sub reconlonc {  sub reconlonc {
       my ($lonid) = @_;
       my $hostname = &hostname($lonid);
       if ($lonid) {
    my $peerfile="$perlvar{'lonSockDir'}/$hostname";
    if ($hostname && -e $peerfile) {
       &logthis("Trying to reconnect lonc for $lonid ($hostname)");
       my $client=IO::Socket::UNIX->new(Peer    => $peerfile,
        Type    => SOCK_STREAM,
        Timeout => 10);
       if ($client) {
    print $client ("reset_retries\n");
    my $answer=<$client>;
    #reset just this one.
       }
    }
    return;
       }
   
     &logthis("Trying to reconnect lonc");      &logthis("Trying to reconnect lonc");
     my $loncfile="$perlvar{'lonDaemons'}/logs/lonc.pid";      my $loncfile="$perlvar{'lonDaemons'}/logs/lonc.pid";
     if (open(my $fh,"<$loncfile")) {      if (open(my $fh,"<$loncfile")) {
Line 640  sub homeserver { Line 671  sub homeserver {
     my $index="$uname:$udom";      my $index="$uname:$udom";
   
     if (exists($homecache{$index})) { return $homecache{$index}; }      if (exists($homecache{$index})) { return $homecache{$index}; }
     my $tryserver;  
     foreach $tryserver (keys %libserv) {      my %servers = &get_servers($udom,'library');
       foreach my $tryserver (keys(%servers)) {
         next if ($ignoreBadCache ne 'true' &&           next if ($ignoreBadCache ne 'true' && 
  exists($badServerCache{$tryserver}));   exists($badServerCache{$tryserver}));
  if ($hostdom{$tryserver} eq $udom) {  
            my $answer=reply("home:$udom:$uname",$tryserver);   my $answer=reply("home:$udom:$uname",$tryserver);
            if ($answer eq 'found') {   if ($answer eq 'found') {
                delete($badServerCache{$tryserver});       delete($badServerCache{$tryserver}); 
        return $homecache{$index}=$tryserver;      return $homecache{$index}=$tryserver;
            } elsif ($answer eq 'no_host') {   } elsif ($answer eq 'no_host') {
        $badServerCache{$tryserver}=1;      $badServerCache{$tryserver}=1;
            }   }
        }  
     }          }    
     return 'no_host';      return 'no_host';
 }  }
Line 663  sub idget { Line 694  sub idget {
     my ($udom,@ids)=@_;      my ($udom,@ids)=@_;
     my %returnhash=();      my %returnhash=();
           
     my $tryserver;      my %servers = &get_servers($udom,'library');
     foreach $tryserver (keys %libserv) {      foreach my $tryserver (keys(%servers)) {
        if ($hostdom{$tryserver} eq $udom) {   my $idlist=join('&',@ids);
   my $idlist=join('&',@ids);   $idlist=~tr/A-Z/a-z/; 
           $idlist=~tr/A-Z/a-z/;    my $reply=&reply("idget:$udom:".$idlist,$tryserver);
   my $reply=&reply("idget:$udom:".$idlist,$tryserver);   my @answer=();
           my @answer=();   if (($reply ne 'con_lost') && ($reply!~/^error\:/)) {
           if (($reply ne 'con_lost') && ($reply!~/^error\:/)) {      @answer=split(/\&/,$reply);
       @answer=split(/\&/,$reply);   }                    ;
           }                    ;   my $i;
           my $i;   for ($i=0;$i<=$#ids;$i++) {
           for ($i=0;$i<=$#ids;$i++) {      if ($answer[$i]) {
               if ($answer[$i]) {   $returnhash{$ids[$i]}=$answer[$i];
   $returnhash{$ids[$i]}=$answer[$i];      } 
               }    }
           }      } 
        }  
     }      
     return %returnhash;      return %returnhash;
 }  }
   
Line 722  sub idput { Line 751  sub idput {
 # ------------------------------------------- get items from domain db files     # ------------------------------------------- get items from domain db files   
   
 sub get_dom {  sub get_dom {
     my ($namespace,$storearr,$udom)=@_;      my ($namespace,$storearr,$udom,$uhome)=@_;
     my $items='';      my $items='';
     foreach my $item (@$storearr) {      foreach my $item (@$storearr) {
         $items.=&escape($item).'&';          $items.=&escape($item).'&';
     }      }
     $items=~s/\&$//;      $items=~s/\&$//;
     if (!$udom) { $udom=$env{'user.domain'}; }      if (!$udom) {
     if (exists($domain_primary{$udom})) {          $udom=$env{'user.domain'};
         my $uhome=$domain_primary{$udom};          if (defined(&domain($udom,'primary'))) {
               $uhome=&domain($udom,'primary');
           } else {
               undef($uhome);
           }
       } else {
           if (!$uhome) {
               if (defined(&domain($udom,'primary'))) {
                   $uhome=&domain($udom,'primary');
               }
           }
       }
       if ($udom && $uhome && ($uhome ne 'no_host')) {
         my $rep=&reply("getdom:$udom:$namespace:$items",$uhome);          my $rep=&reply("getdom:$udom:$namespace:$items",$uhome);
           my %returnhash;
           if ($rep eq '' || $rep =~ /^error: 2 /) {
               return %returnhash;
           }
         my @pairs=split(/\&/,$rep);          my @pairs=split(/\&/,$rep);
         if ( $#pairs==0 && $pairs[0] =~ /^(con_lost|error|no_such_host)/i) {          if ( $#pairs==0 && $pairs[0] =~ /^(con_lost|error|no_such_host)/i) {
             return @pairs;              return @pairs;
         }          }
         my %returnhash=();  
         my $i=0;          my $i=0;
         foreach my $item (@$storearr) {          foreach my $item (@$storearr) {
             $returnhash{$item}=&thaw_unescape($pairs[$i]);              $returnhash{$item}=&thaw_unescape($pairs[$i]);
Line 744  sub get_dom { Line 788  sub get_dom {
         }          }
         return %returnhash;          return %returnhash;
     } else {      } else {
         &logthis("get_dom failed - no primary domain server for $udom");          &logthis("get_dom failed - no homeserver and/or domain ($udom) ($uhome)");
     }      }
 }  }
   
 # -------------------------------------------- put items in domain db files   # -------------------------------------------- put items in domain db files 
   
 sub put_dom {  sub put_dom {
     my ($namespace,$storehash,$udom)=@_;      my ($namespace,$storehash,$udom,$uhome)=@_;
     if (!$udom) { $udom=$env{'user.domain'}; }      if (!$udom) {
     if (exists($domain_primary{$udom})) {          $udom=$env{'user.domain'};
         my $uhome=$domain_primary{$udom};          if (defined(&domain($udom,'primary'))) {
               $uhome=&domain($udom,'primary');
           } else {
               undef($uhome);
           }
       } else {
           if (!$uhome) {
               if (defined(&domain($udom,'primary'))) {
                   $uhome=&domain($udom,'primary');
               }
           }
       } 
       if ($udom && $uhome && ($uhome ne 'no_host')) {
         my $items='';          my $items='';
         foreach my $item (keys(%$storehash)) {          foreach my $item (keys(%$storehash)) {
             $items.=&escape($item).'='.&freeze_escape($$storehash{$item}).'&';              $items.=&escape($item).'='.&freeze_escape($$storehash{$item}).'&';
Line 762  sub put_dom { Line 818  sub put_dom {
         $items=~s/\&$//;          $items=~s/\&$//;
         return &reply("putdom:$udom:$namespace:$items",$uhome);          return &reply("putdom:$udom:$namespace:$items",$uhome);
     } else {      } else {
         &logthis("put_dom failed - no primary domain server for $udom");          &logthis("put_dom failed - no homeserver and/or domain");
     }      }
 }  }
   
 sub retrieve_inst_usertypes {  sub retrieve_inst_usertypes {
     my ($udom) = @_;      my ($udom) = @_;
     my (%returnhash,@order);      my (%returnhash,@order);
     if (exists($domain_primary{$udom})) {      if (defined(&domain($udom,'primary'))) {
         my $uhome=$domain_primary{$udom};          my $uhome=&domain($udom,'primary');
         my $rep=&reply("inst_usertypes:$udom",$uhome);          my $rep=&reply("inst_usertypes:$udom",$uhome);
         my ($hashitems,$orderitems) = split(/:/,$rep);           my ($hashitems,$orderitems) = split(/:/,$rep); 
         my @pairs=split(/\&/,$hashitems);          my @pairs=split(/\&/,$hashitems);
Line 790  sub retrieve_inst_usertypes { Line 846  sub retrieve_inst_usertypes {
     return (\%returnhash,\@order);      return (\%returnhash,\@order);
 }  }
   
   sub is_domainimage {
       my ($url) = @_;
       if ($url=~m-^/+res/+($match_domain)/+\1\-domainconfig/+(img|logo|domlogo)/+-) {
           if (&domain($1) ne '') {
               return '1';
           }
       }
       return;
   }
   
 # --------------------------------------------------- Assign a key to a student  # --------------------------------------------------- Assign a key to a student
   
 sub assign_access_key {  sub assign_access_key {
Line 1014  my %remembered; Line 1080  my %remembered;
 my %accessed;  my %accessed;
 my $kicks=0;  my $kicks=0;
 my $hits=0;  my $hits=0;
   sub make_key {
       my ($name,$id) = @_;
       if (length($id) > 65 
    && length(&escape($id)) > 200) {
    $id=length($id).':'.&Digest::MD5::md5_hex($id);
       }
       return &escape($name.':'.$id);
   }
   
 sub devalidate_cache_new {  sub devalidate_cache_new {
     my ($name,$id,$debug) = @_;      my ($name,$id,$debug) = @_;
     if ($debug) { &Apache::lonnet::logthis("deleting $name:$id"); }      if ($debug) { &Apache::lonnet::logthis("deleting $name:$id"); }
     $id=&escape($name.':'.$id);      $id=&make_key($name,$id);
     $memcache->delete($id);      $memcache->delete($id);
     delete($remembered{$id});      delete($remembered{$id});
     delete($accessed{$id});      delete($accessed{$id});
Line 1025  sub devalidate_cache_new { Line 1100  sub devalidate_cache_new {
   
 sub is_cached_new {  sub is_cached_new {
     my ($name,$id,$debug) = @_;      my ($name,$id,$debug) = @_;
     $id=&escape($name.':'.$id);      $id=&make_key($name,$id);
     if (exists($remembered{$id})) {      if (exists($remembered{$id})) {
  if ($debug) { &Apache::lonnet::logthis("Earyl return $id of $remembered{$id} "); }   if ($debug) { &Apache::lonnet::logthis("Earyl return $id of $remembered{$id} "); }
  $accessed{$id}=[&gettimeofday()];   $accessed{$id}=[&gettimeofday()];
Line 1048  sub is_cached_new { Line 1123  sub is_cached_new {
   
 sub do_cache_new {  sub do_cache_new {
     my ($name,$id,$value,$time,$debug) = @_;      my ($name,$id,$value,$time,$debug) = @_;
     $id=&escape($name.':'.$id);      $id=&make_key($name,$id);
     my $setvalue=$value;      my $setvalue=$value;
     if (!defined($setvalue)) {      if (!defined($setvalue)) {
  $setvalue='__undef__';   $setvalue='__undef__';
Line 1057  sub do_cache_new { Line 1132  sub do_cache_new {
  $time=600;   $time=600;
     }      }
     if ($debug) { &Apache::lonnet::logthis("Setting $id to $value"); }      if ($debug) { &Apache::lonnet::logthis("Setting $id to $value"); }
     $memcache->set($id,$setvalue,$time);      if (!($memcache->set($id,$setvalue,$time))) {
    &logthis("caching of id -> $id  failed");
       }
     # need to make a copy of $value      # need to make a copy of $value
     #&make_room($id,$value,$debug);      #&make_room($id,$value,$debug);
     return $value;      return $value;
Line 1498  sub clean_filename { Line 1575  sub clean_filename {
 #        $coursedoc - if true up to the current course  #        $coursedoc - if true up to the current course
 #                     if false  #                     if false
 #        $subdir - directory in userfile to store the file into  #        $subdir - directory in userfile to store the file into
 #        $parser, $allfiles, $codebase - unknown  #        $parser - instruction to parse file for objects ($parser = parse)    
 #  #        $allfiles - reference to hash for embedded objects
   #        $codebase - reference to hash for codebase of java objects
   #        $desuname - username for permanent storage of uploaded file
   #        $dsetudom - domain for permanaent storage of uploaded file
   #        $thumbwidth - width (pixels) of thumbnail to make for uploaded image 
   #        $thumbheight - height (pixels) of thumbnail to make for uploaded image
   # 
 # output: url of file in userspace, or error: <message>   # output: url of file in userspace, or error: <message> 
 #             or /adm/notfound.html if failure to upload occurse  #             or /adm/notfound.html if failure to upload occurse
   
   
 sub userfileupload {  sub userfileupload {
     my ($formname,$coursedoc,$subdir,$parser,$allfiles,$codebase,$destuname,$destudom)=@_;      my ($formname,$coursedoc,$subdir,$parser,$allfiles,$codebase,$destuname,
           $destudom,$thumbwidth,$thumbheight)=@_;
     if (!defined($subdir)) { $subdir='unknown'; }      if (!defined($subdir)) { $subdir='unknown'; }
     my $fname=$env{'form.'.$formname.'.filename'};      my $fname=$env{'form.'.$formname.'.filename'};
     $fname=&clean_filename($fname);      $fname=&clean_filename($fname);
Line 1552  sub userfileupload { Line 1636  sub userfileupload {
         if ($env{'form.folder'} =~ m/^(default|supplemental)/) {          if ($env{'form.folder'} =~ m/^(default|supplemental)/) {
             return &finishuserfileupload($docuname,$docudom,              return &finishuserfileupload($docuname,$docudom,
  $formname,$fname,$parser,$allfiles,   $formname,$fname,$parser,$allfiles,
  $codebase);   $codebase,$thumbwidth,$thumbheight);
         } else {          } else {
             $fname=$env{'form.folder'}.'/'.$fname;              $fname=$env{'form.folder'}.'/'.$fname;
             return &process_coursefile('uploaddoc',$docuname,$docudom,              return &process_coursefile('uploaddoc',$docuname,$docudom,
Line 1562  sub userfileupload { Line 1646  sub userfileupload {
     } elsif (defined($destuname)) {      } elsif (defined($destuname)) {
         my $docuname=$destuname;          my $docuname=$destuname;
         my $docudom=$destudom;          my $docudom=$destudom;
  return &finishuserfileupload($docuname,$docudom,$formname,   return &finishuserfileupload($docuname,$docudom,$formname,$fname,
      $fname,$parser,$allfiles,$codebase);       $parser,$allfiles,$codebase,
                                        $thumbwidth,$thumbheight);
                   
     } else {      } else {
         my $docuname=$env{'user.name'};          my $docuname=$env{'user.name'};
Line 1572  sub userfileupload { Line 1657  sub userfileupload {
             $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'};
         }          }
  return &finishuserfileupload($docuname,$docudom,$formname,   return &finishuserfileupload($docuname,$docudom,$formname,$fname,
      $fname,$parser,$allfiles,$codebase);       $parser,$allfiles,$codebase,
                                        $thumbwidth,$thumbheight);
     }      }
 }  }
   
 sub finishuserfileupload {  sub finishuserfileupload {
     my ($docuname,$docudom,$formname,$fname,$parser,$allfiles,$codebase) = @_;      my ($docuname,$docudom,$formname,$fname,$parser,$allfiles,$codebase,
           $thumbwidth,$thumbheight) = @_;
     my $path=$docudom.'/'.$docuname.'/';      my $path=$docudom.'/'.$docuname.'/';
     my $filepath=$perlvar{'lonDocRoot'};      my $filepath=$perlvar{'lonDocRoot'};
     my ($fnamepath,$file);      my ($fnamepath,$file,$fetchthumb);
     $file=$fname;      $file=$fname;
     if ($fname=~m|/|) {      if ($fname=~m|/|) {
         ($fnamepath,$file) = ($fname =~ m|^(.*)/([^/]+)$|);          ($fnamepath,$file) = ($fname =~ m|^(.*)/([^/]+)$|);
Line 1617  sub finishuserfileupload { Line 1704  sub finishuserfileupload {
      ' for embedded media: '.$parse_result);        ' for embedded media: '.$parse_result); 
         }          }
     }      }
       if (($thumbwidth =~ /^\d+$/) && ($thumbheight =~ /^\d+$/)) {
           my $input = $filepath.'/'.$file;
           my $output = $filepath.'/'.'tn-'.$file;
           my $thumbsize = $thumbwidth.'x'.$thumbheight;
           system("convert -sample $thumbsize $input $output");
           if (-e $filepath.'/'.'tn-'.$file) {
               $fetchthumb  = 1; 
           }
       }
    
 # Notify homeserver to grep it  # Notify homeserver to grep it
 #  #
     my $docuhome=&homeserver($docuname,$docudom);      my $docuhome=&homeserver($docuname,$docudom);
     my $fetchresult= &reply('fetchuserfile:'.$path.$file,$docuhome);      my $fetchresult= &reply('fetchuserfile:'.$path.$file,$docuhome);
     if ($fetchresult eq 'ok') {      if ($fetchresult eq 'ok') {
           if ($fetchthumb) {
               my $thumbresult= &reply('fetchuserfile:'.$path.'tn-'.$file,$docuhome);
               if ($thumbresult ne 'ok') {
                   &logthis('Failed to transfer '.$path.'tn-'.$file.' to host '.
                            $docuhome.': '.$thumbresult);
               }
           }
 #  #
 # Return the URL to it  # Return the URL to it
         return '/uploaded/'.$path.$file;          return '/uploaded/'.$path.$file;
Line 1629  sub finishuserfileupload { Line 1733  sub finishuserfileupload {
         &logthis('Failed to transfer '.$path.$file.' to host '.$docuhome.          &logthis('Failed to transfer '.$path.$file.' to host '.$docuhome.
  ': '.$fetchresult);   ': '.$fetchresult);
         return '/adm/notfound.html';          return '/adm/notfound.html';
     }          }
 }  }
   
 sub extract_embedded_items {  sub extract_embedded_items {
Line 1653  sub extract_embedded_items { Line 1757  sub extract_embedded_items {
     while (my $t=$p->get_token()) {      while (my $t=$p->get_token()) {
  if ($t->[0] eq 'S') {   if ($t->[0] eq 'S') {
     my ($tagname, $attr) = ($t->[1],$t->[2]);      my ($tagname, $attr) = ($t->[1],$t->[2]);
     push (@state, $tagname);      push(@state, $tagname);
             if (lc($tagname) eq 'allow') {              if (lc($tagname) eq 'allow') {
                 &add_filetype($allfiles,$attr->{'src'},'src');                  &add_filetype($allfiles,$attr->{'src'},'src');
             }              }
     if (lc($tagname) eq 'img') {      if (lc($tagname) eq 'img') {
  &add_filetype($allfiles,$attr->{'src'},'src');   &add_filetype($allfiles,$attr->{'src'},'src');
     }      }
       if (lc($tagname) eq 'a') {
    &add_filetype($allfiles,$attr->{'href'},'href');
       }
             if (lc($tagname) eq 'script') {              if (lc($tagname) eq 'script') {
                 if ($attr->{'archive'} =~ /\.jar$/i) {                  if ($attr->{'archive'} =~ /\.jar$/i) {
                     &add_filetype($allfiles,$attr->{'archive'},'archive');                      &add_filetype($allfiles,$attr->{'archive'},'archive');
Line 1843  sub flushcourselogs { Line 1950  sub flushcourselogs {
 # Write course id database (reverse lookup) to homeserver of courses   # Write course id database (reverse lookup) to homeserver of courses 
 # Is used in pickcourse  # Is used in pickcourse
 #  #
     foreach my $crsid (keys(%courseidbuffer)) {      foreach my $crs_home (keys(%courseidbuffer)) {
         &courseidput($hostdom{$crsid},$courseidbuffer{$crsid},$crsid);          &courseidput(&host_domain($crs_home),$courseidbuffer{$crs_home},
        $crs_home);
     }      }
 #  #
 # File accesses  # File accesses
Line 1911  sub flushcourselogs { Line 2019  sub flushcourselogs {
         delete $domainrolehash{$entry};          delete $domainrolehash{$entry};
     }      }
     foreach my $dom (keys(%domrolebuffer)) {      foreach my $dom (keys(%domrolebuffer)) {
         foreach my $tryserver (keys %libserv) {   my %servers = &get_servers($dom,'library');
             if ($hostdom{$tryserver} eq $dom) {   foreach my $tryserver (keys(%servers)) {
                 unless (&reply('domroleput:'.$dom.':'.      unless (&reply('domroleput:'.$dom.':'.
                   $domrolebuffer{$dom},$tryserver) eq 'ok') {     $domrolebuffer{$dom},$tryserver) eq 'ok') {
                     &logthis('Put of domain roles failed for '.$dom.' and  '.$tryserver);   &logthis('Put of domain roles failed for '.$dom.' and  '.$tryserver);
                 }      }
             }  
         }          }
     }      }
     $dumpcount++;      $dumpcount++;
Line 2051  sub get_course_adv_roles { Line 2158  sub get_course_adv_roles {
 }  }
   
 sub get_my_roles {  sub get_my_roles {
     my ($uname,$udom,$types,$roles,$roledoms)=@_;      my ($uname,$udom,$context,$types,$roles,$roledoms)=@_;
     unless (defined($uname)) { $uname=$env{'user.name'}; }      unless (defined($uname)) { $uname=$env{'user.name'}; }
     unless (defined($udom)) { $udom=$env{'user.domain'}; }      unless (defined($udom)) { $udom=$env{'user.domain'}; }
     my %dumphash=      my %dumphash;
       if ($context eq 'userroles') { 
           %dumphash = &dump('roles',$udom,$uname);
       } else {
           %dumphash=
             &dump('nohist_userroles',$udom,$uname);              &dump('nohist_userroles',$udom,$uname);
       }
     my %returnhash=();      my %returnhash=();
     my $now=time;      my $now=time;
     foreach my $entry (keys(%dumphash)) {      foreach my $entry (keys(%dumphash)) {
  my ($tend,$tstart)=split(/\:/,$dumphash{$entry});          my ($role,$tend,$tstart);
           if ($context eq 'userroles') {
       ($role,$tend,$tstart)=split(/_/,$dumphash{$entry});
           } else {
               ($tend,$tstart)=split(/\:/,$dumphash{$entry});
           }
         if (($tstart) && ($tstart<0)) { next; }          if (($tstart) && ($tstart<0)) { next; }
         my $status = 'active';          my $status = 'active';
         if (($tend) && ($tend<$now)) {          if (($tend) && ($tend<$now)) {
Line 2077  sub get_my_roles { Line 2194  sub get_my_roles {
                 next;                  next;
             }              }
         }          }
         my ($role,$username,$domain,$section)=split(/\:/,$entry);          my ($rolecode,$username,$domain,$section,$area);
           if ($context eq 'userroles') {
               ($area,$rolecode) = split(/_/,$entry);
               (undef,$domain,$username,$section) = split(/\//,$area);
           } else {
               ($role,$username,$domain,$section) = split(/\:/,$entry);
           }
         if (ref($roledoms) eq 'ARRAY') {          if (ref($roledoms) eq 'ARRAY') {
             if (!grep(/^\Q$domain\E$/,@{$roledoms})) {              if (!grep(/^\Q$domain\E$/,@{$roledoms})) {
                 next;                  next;
Line 2087  sub get_my_roles { Line 2210  sub get_my_roles {
             if (!grep(/^\Q$role\E$/,@{$roles})) {              if (!grep(/^\Q$role\E$/,@{$roles})) {
                 next;                  next;
             }              }
         }           }
  $returnhash{$username.':'.$domain.':'.$role}=$tstart.':'.$tend;   $returnhash{$username.':'.$domain.':'.$role}=$tstart.':'.$tend;
     }      }
     return %returnhash;      return %returnhash;
Line 2099  sub get_my_roles { Line 2222  sub get_my_roles {
   
 sub postannounce {  sub postannounce {
     my ($server,$text)=@_;      my ($server,$text)=@_;
     unless (&allowed('psa',$hostdom{$server})) { return 'refused'; }      unless (&allowed('psa',&host_domain($server))) { return 'refused'; }
     unless ($text=~/\w/) { $text=''; }      unless ($text=~/\w/) { $text=''; }
     return &reply('setannounce:'.&escape($text),$server);      return &reply('setannounce:'.&escape($text),$server);
 }  }
Line 2135  sub courseiddump { Line 2258  sub courseiddump {
     my ($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter,$coursefilter,$hostidflag,$hostidref,$typefilter,$regexp_ok)=@_;      my ($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter,$coursefilter,$hostidflag,$hostidref,$typefilter,$regexp_ok)=@_;
     my %returnhash=();      my %returnhash=();
     unless ($domfilter) { $domfilter=''; }      unless ($domfilter) { $domfilter=''; }
     foreach my $tryserver (keys %libserv) {      my %libserv = &all_library();
         if ( ($hostidflag == 1 && grep/^$tryserver$/,@{$hostidref}) || (!defined($hostidflag)) ) {      foreach my $tryserver (keys(%libserv)) {
     if ((!$domfilter) || ($hostdom{$tryserver} eq $domfilter)) {          if ( (  $hostidflag == 1 
           && grep(/^\Q$tryserver\E$/,@{$hostidref}) ) 
        || (!defined($hostidflag)) ) {
   
       if ($domfilter eq ''
    || (&host_domain($tryserver) eq $domfilter)) {
         foreach my $line (          foreach my $line (
                  split(/\&/,&reply('courseiddump:'.$hostdom{$tryserver}.':'.                   split(/\&/,&reply('courseiddump:'.&host_domain($tryserver).':'.
        $sincefilter.':'.&escape($descfilter).':'.         $sincefilter.':'.&escape($descfilter).':'.
                                &escape($instcodefilter).':'.&escape($ownerfilter).':'.&escape($coursefilter).':'.&escape($typefilter).':'.&escape($regexp_ok),                                 &escape($instcodefilter).':'.&escape($ownerfilter).':'.&escape($coursefilter).':'.&escape($typefilter).':'.&escape($regexp_ok),
                                $tryserver))) {                                 $tryserver))) {
Line 2167  sub dcmailput { Line 2295  sub dcmailput {
 sub dcmaildump {  sub dcmaildump {
     my ($dom,$startdate,$enddate,$senders) = @_;      my ($dom,$startdate,$enddate,$senders) = @_;
     my %returnhash=();      my %returnhash=();
     if (exists($domain_primary{$dom})) {  
       if (defined(&domain($dom,'primary'))) {
         my $cmd='dcmaildump:'.$dom.':'.&escape($startdate).':'.          my $cmd='dcmaildump:'.$dom.':'.&escape($startdate).':'.
                                                          &escape($enddate).':';                                                           &escape($enddate).':';
  my @esc_senders=map { &escape($_)} @$senders;   my @esc_senders=map { &escape($_)} @$senders;
  $cmd.=&escape(join('&',@esc_senders));   $cmd.=&escape(join('&',@esc_senders));
  foreach my $line (split(/\&/,&reply($cmd,$domain_primary{$dom}))) {   foreach my $line (split(/\&/,&reply($cmd,&domain($dom,'primary')))) {
             my ($key,$value) = split(/\=/,$line,2);              my ($key,$value) = split(/\=/,$line,2);
             if (($key) && ($value)) {              if (($key) && ($value)) {
                 $returnhash{&unescape($key)} = &unescape($value);                  $returnhash{&unescape($key)} = &unescape($value);
Line 2193  sub get_domain_roles { Line 2322  sub get_domain_roles {
     }      }
     my $rolelist = join(':',@{$roles});      my $rolelist = join(':',@{$roles});
     my %personnel = ();      my %personnel = ();
     foreach my $tryserver (keys(%libserv)) {  
         if ($hostdom{$tryserver} eq $dom) {      my %servers = &get_servers($dom,'library');
             %{$personnel{$tryserver}}=();      foreach my $tryserver (keys(%servers)) {
             foreach my $line (   %{$personnel{$tryserver}}=();
                 split(/\&/,&reply('domrolesdump:'.$dom.':'.   foreach my $line (split(/\&/,&reply('domrolesdump:'.$dom.':'.
                    &escape($startdate).':'.&escape($enddate).':'.      &escape($startdate).':'.
                    &escape($rolelist), $tryserver))) {      &escape($enddate).':'.
                 my ($key,$value) = split(/\=/,$line,2);      &escape($rolelist), $tryserver))) {
                 if (($key) && ($value)) {      my ($key,$value) = split(/\=/,$line,2);
                     $personnel{$tryserver}{&unescape($key)} = &unescape($value);      if (($key) && ($value)) {
                 }   $personnel{$tryserver}{&unescape($key)} = &unescape($value);
             }      }
         }   }
     }      }
     return %personnel;      return %personnel;
 }  }
Line 3025  sub set_userprivs { Line 3154  sub set_userprivs {
     if (keys(%{$allgroups}) > 0) {      if (keys(%{$allgroups}) > 0) {
         foreach my $role (keys %{$allroles}) {          foreach my $role (keys %{$allroles}) {
             my ($trole,$area,$sec,$extendedarea);              my ($trole,$area,$sec,$extendedarea);
             if ($role =~ m-^(\w+|cr/$match_domain/$match_username/\w+)\.(/$match_domain/$match_courseid)(/?\w*)-) {              if ($role =~ m-^(\w+|cr/$match_domain/$match_username/\w+)\.(/$match_domain/$match_courseid)(/?\w*)\.-) {
                 $trole = $1;                  $trole = $1;
                 $area = $2;                  $area = $2;
                 $sec = $3;                  $sec = $3;
Line 3506  sub get_portfolio_access { Line 3635  sub get_portfolio_access {
             }              }
             if (@users > 0) {              if (@users > 0) {
                 foreach my $userkey (@users) {                  foreach my $userkey (@users) {
                     if (exists($access_hash->{$userkey}{'users'}{$env{'user.name'}.':'.$env{'user.domain'}})) {                      if (ref($access_hash->{$userkey}{'users'}) eq 'ARRAY') {
                         return 'ok';                          foreach my $item (@{$access_hash->{$userkey}{'users'}}) {
                     }                              if (ref($item) eq 'HASH') {
                                   if (($item->{'uname'} eq $env{'user.name'}) &&
                                       ($item->{'udom'} eq $env{'user.domain'})) {
                                       return 'ok';
                                   }
                               }
                           }
                       } 
                 }                  }
             }              }
             my %roleshash;              my %roleshash;
Line 4172  sub definerole { Line 4308  sub definerole {
 sub metadata_query {  sub metadata_query {
     my ($query,$custom,$customshow,$server_array)=@_;      my ($query,$custom,$customshow,$server_array)=@_;
     my %rhash;      my %rhash;
       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) {
Line 4324  sub courselog_query { Line 4461  sub courselog_query {
 }  }
   
 sub userlog_query {  sub userlog_query {
   #
   # possible filters:
   # action: log check role
   # start: timestamp
   # end: timestamp
   #
     my ($uname,$udom,%filters)=@_;      my ($uname,$udom,%filters)=@_;
     return &log_query($uname,$udom,'userlog',%filters);      return &log_query($uname,$udom,'userlog',%filters);
 }  }
Line 4332  sub userlog_query { Line 4475  sub userlog_query {
   
 sub auto_run {  sub auto_run {
     my ($cnum,$cdom) = @_;      my ($cnum,$cdom) = @_;
     my $homeserver = &homeserver($cnum,$cdom);      my $response = 0;
     my $response = &reply('autorun:'.$cdom,$homeserver);      my $settings;
       my %domconfig = &get_dom('configuration',['autoenroll'],$cdom);
       if (ref($domconfig{'autoenroll'}) eq 'HASH') {
           $settings = $domconfig{'autoenroll'};
           if ($settings->{'run'} eq '1') {
               $response = 1;
           }
       } else {
           my $homeserver = &homeserver($cnum,$cdom);
           $response = &reply('autorun:'.$cdom,$homeserver);
       }
     return $response;      return $response;
 }  }
   
Line 4363  sub auto_validate_courseID { Line 4516  sub auto_validate_courseID {
 }  }
   
 sub auto_create_password {  sub auto_create_password {
     my ($cnum,$cdom,$authparam) = @_;      my ($cnum,$cdom,$authparam,$udom) = @_;
     my $homeserver = &homeserver($cnum,$cdom);       my ($homeserver,$response);
     my $create_passwd = 0;      my $create_passwd = 0;
     my $authchk = '';      my $authchk = '';
     my $response=&unescape(&reply('autocreatepassword:'.$authparam.':'.$cdom,$homeserver));      if ($udom =~ /^$match_domain$/) {
     if ($response eq 'refused') {          $homeserver = &domain($udom,'primary');
         $authchk = 'refused';      }
       if ($homeserver eq '') {
           if (($cdom =~ /^$match_domain$/) && ($cnum =~ /^$match_courseid$/)) {
               $homeserver = &homeserver($cnum,$cdom);
           }
       }
       if ($homeserver eq '') {
           $authchk = 'nodomain';
     } else {      } else {
         ($authparam,$create_passwd,$authchk) = split/:/,$response;          $response=&unescape(&reply('autocreatepassword:'.$authparam.':'.$cdom,$homeserver));
           if ($response eq 'refused') {
               $authchk = 'refused';
           } else {
               ($authparam,$create_passwd,$authchk) = split/:/,$response;
           }
     }      }
     return ($authparam,$create_passwd,$authchk);      return ($authparam,$create_passwd,$authchk);
 }  }
Line 4458  sub auto_instcode_format { Line 4623  sub auto_instcode_format {
     my $courses = '';      my $courses = '';
     my @homeservers;      my @homeservers;
     if ($caller eq 'global') {      if ($caller eq 'global') {
         foreach my $tryserver (keys(%libserv)) {   my %servers = &get_servers($codedom,'library');
             if ($hostdom{$tryserver} eq $codedom) {   foreach my $tryserver (keys(%servers)) {
                 if (!grep(/^\Q$tryserver\E$/,@homeservers)) {      if (!grep(/^\Q$tryserver\E$/,@homeservers)) {
                     push(@homeservers,$tryserver);   push(@homeservers,$tryserver);
                 }      }
             }  
         }          }
     } else {      } else {
         push(@homeservers,&homeserver($caller,$codedom));          push(@homeservers,&homeserver($caller,$codedom));
Line 4497  sub auto_instcode_format { Line 4661  sub auto_instcode_format {
 sub auto_instcode_defaults {  sub auto_instcode_defaults {
     my ($domain,$returnhash,$code_order) = @_;      my ($domain,$returnhash,$code_order) = @_;
     my @homeservers;      my @homeservers;
     foreach my $tryserver (keys(%libserv)) {  
         if ($hostdom{$tryserver} eq $domain) {      my %servers = &get_servers($domain,'library');
             if (!grep(/^\Q$tryserver\E$/,@homeservers)) {      foreach my $tryserver (keys(%servers)) {
                 push(@homeservers,$tryserver);   if (!grep(/^\Q$tryserver\E$/,@homeservers)) {
             }      push(@homeservers,$tryserver);
         }   }
     }      }
     my $ok_response = 0;  
     my $response;      my $response;
     while (@homeservers > 0 && $ok_response == 0) {      foreach my $server (@homeservers) {
         my $server = shift(@homeservers);  
         $response=&reply('autoinstcodedefaults:'.$domain,$server);          $response=&reply('autoinstcodedefaults:'.$domain,$server);
         if ($response !~ /(con_lost|error|no_such_host|refused)/) {          next if ($response =~ /(con_lost|error|no_such_host|refused)/);
             foreach my $pair (split(/\&/,$response)) {  
                 my ($name,$value)=split(/\=/,$pair);   foreach my $pair (split(/\&/,$response)) {
                 if ($name eq 'code_order') {      my ($name,$value)=split(/\=/,$pair);
                     @{$code_order} = split(/\&/,&unescape($value));      if ($name eq 'code_order') {
                 } else {   @{$code_order} = split(/\&/,&unescape($value));
                     $returnhash->{&unescape($name)}=&unescape($value);      } else {
                 }   $returnhash->{&unescape($name)}=&unescape($value);
             }      }
             $ok_response = 1;   }
         }   return 'ok';
     }  
     if ($ok_response) {  
         return 'ok';  
     } else {  
         return $response;  
     }      }
   
       return $response;
 }   } 
   
 sub auto_validate_class_sec {  sub auto_validate_class_sec {
Line 4818  sub modifyuser { Line 4978  sub modifyuser {
     if (($uhome eq 'no_host') &&       if (($uhome eq 'no_host') && 
  (($umode && $upass) || ($umode eq 'localauth'))) {   (($umode && $upass) || ($umode eq 'localauth'))) {
         my $unhome='';          my $unhome='';
         if (defined($desiredhome) && $hostdom{$desiredhome} eq $udom) {           if (defined($desiredhome) && &host_domain($desiredhome) eq $udom) { 
             $unhome = $desiredhome;              $unhome = $desiredhome;
  } elsif($env{'course.'.$env{'request.course.id'}.'.domain'} eq $udom) {   } elsif($env{'course.'.$env{'request.course.id'}.'.domain'} eq $udom) {
     $unhome=$env{'course.'.$env{'request.course.id'}.'.home'};      $unhome=$env{'course.'.$env{'request.course.id'}.'.home'};
         } else { # load balancing routine for determining $unhome          } else { # load balancing routine for determining $unhome
             my $tryserver;  
             my $loadm=10000000;              my $loadm=10000000;
             foreach $tryserver (keys %libserv) {      my %servers = &get_servers($udom,'library');
        if ($hostdom{$tryserver} eq $udom) {      foreach my $tryserver (keys(%servers)) {
                   my $answer=reply('load',$tryserver);   my $answer=reply('load',$tryserver);
                   if (($answer=~/\d+/) && ($answer<$loadm)) {   if (($answer=~/\d+/) && ($answer<$loadm)) {
       $loadm=$answer;      $loadm=$answer;
                       $unhome=$tryserver;      $unhome=$tryserver;
                   }   }
        }  
     }      }
         }          }
         if (($unhome eq '') || ($unhome eq 'no_host')) {          if (($unhome eq '') || ($unhome eq 'no_host')) {
Line 5047  sub createcourse { Line 5205  sub createcourse {
    }     }
 # ------------------------------------------------ Check supplied server name  # ------------------------------------------------ Check supplied server name
     $course_server = $env{'user.homeserver'} if (! defined($course_server));      $course_server = $env{'user.homeserver'} if (! defined($course_server));
     if (! exists($libserv{$course_server})) {      if (! &is_library($course_server)) {
         return 'error:bad server name '.$course_server;          return 'error:bad server name '.$course_server;
     }      }
 # ------------------------------------------------------------- Make the course  # ------------------------------------------------------------- Make the course
Line 5183  sub save_selected_files { Line 5341  sub save_selected_files {
     my ($user, $path, @files) = @_;      my ($user, $path, @files) = @_;
     my $filename = $user."savedfiles";      my $filename = $user."savedfiles";
     my @other_files = &files_not_in_path($user, $path);      my @other_files = &files_not_in_path($user, $path);
     open (OUT, '>'.$Apache::lonnet::perlvar{'lonDaemons'}.'/tmp/'.$filename);      open (OUT, '>'.$tmpdir.$filename);
     foreach my $file (@files) {      foreach my $file (@files) {
         print (OUT $env{'form.currentpath'}.$file."\n");          print (OUT $env{'form.currentpath'}.$file."\n");
     }      }
Line 5580  sub dirlist { Line 5738  sub dirlist {
             return @listing_results;              return @listing_results;
         } elsif(!defined($alternateDirectoryRoot)) {          } elsif(!defined($alternateDirectoryRoot)) {
             my %allusers;              my %allusers;
             foreach my $tryserver (keys(%libserv)) {      my %servers = &get_servers($udom,'library');
                 if($hostdom{$tryserver} eq $udom) {      foreach my $tryserver (keys(%servers)) {
                     my $listing = &reply('ls2:'.$perlvar{'lonDocRoot'}.'/res/'.   my $listing = &reply('ls2:'.$perlvar{'lonDocRoot'}.'/res/'.
  $udom, $tryserver);       $udom, $tryserver);
                     my @listing_results;   my @listing_results;
                     if ($listing eq 'unknown_cmd') {   if ($listing eq 'unknown_cmd') {
                         $listing = &reply('ls:'.$perlvar{'lonDocRoot'}.'/res/'.      $listing = &reply('ls:'.$perlvar{'lonDocRoot'}.'/res/'.
   $udom, $tryserver);        $udom, $tryserver);
                         @listing_results = split(/:/,$listing);      @listing_results = split(/:/,$listing);
                     } else {   } else {
                         @listing_results =      @listing_results =
                             map { &unescape($_); } split(/:/,$listing);   map { &unescape($_); } split(/:/,$listing);
                     }   }
                     if ($listing_results[0] ne 'no_such_dir' &&    if ($listing_results[0] ne 'no_such_dir' && 
                         $listing_results[0] ne 'empty'       &&      $listing_results[0] ne 'empty'       &&
                         $listing_results[0] ne 'con_lost') {      $listing_results[0] ne 'con_lost') {
                         foreach my $line (@listing_results) {      foreach my $line (@listing_results) {
                             my ($entry) = split(/&/,$line,2);   my ($entry) = split(/&/,$line,2);
                             $allusers{$entry} = 1;   $allusers{$entry} = 1;
                         }      }
                     }   }
                 }  
             }              }
             my $alluserstr='';              my $alluserstr='';
             foreach my $user (sort(keys(%allusers))) {              foreach my $user (sort(keys(%allusers))) {
Line 5613  sub dirlist { Line 5770  sub dirlist {
             return ('missing user name');              return ('missing user name');
         }          }
     } elsif(!defined($alternateDirectoryRoot)) {      } elsif(!defined($alternateDirectoryRoot)) {
         my $tryserver;          my @all_domains = sort(&all_domains());
         my %alldom=();           foreach my $domain (@all_domains) {
         foreach $tryserver (keys(%libserv)) {               $domain = $perlvar{'lonDocRoot'}.'/res/'.$domain.'/&domain';
             $alldom{$hostdom{$tryserver}}=1;           }
         }           return @all_domains;
         my $alldomstr='';       } else {
         foreach my $domain (sort(keys(%alldom))) {  
             $alldomstr.=$perlvar{'lonDocRoot'}.'/res/'.$domain.'/&domain:';  
         }  
         $alldomstr=~s/:$//;  
         return split(/:/,$alldomstr);         
     } else {  
         return ('missing domain');          return ('missing domain');
     }      }
 }  }
Line 5782  sub devalidatecourseresdata { Line 5933  sub devalidatecourseresdata {
   
   
 # --------------------------------------------------- Course Resourcedata Query  # --------------------------------------------------- Course Resourcedata Query
   #
   #  Parameters:
   #      $coursenum    - Number of the course.
   #      $coursedomain - Domain at which the course was created.
   #  Returns:
   #     A hash of the course parameters along (I think) with timestamps
   #     and version info.
   
 sub get_courseresdata {  sub get_courseresdata {
     my ($coursenum,$coursedomain)=@_;      my ($coursenum,$coursedomain)=@_;
Line 5840  sub get_userresdata { Line 5998  sub get_userresdata {
     }      }
     return $tmp;      return $tmp;
 }  }
   #----------------------------------------------- resdata - return resource data
   #  Purpose:
   #    Return resource data for either users or for a course.
   #  Parameters:
   #     $name      - Course/user name.
   #     $domain    - Name of the domain the user/course is registered on.
   #     $type      - Type of thing $name is (must be 'course' or 'user'
   #     @which     - Array of names of resources desired.
   #  Returns:
   #     The value of the first reasource in @which that is found in the
   #     resource hash.
   #  Exceptional Conditions:
   #     If the $type passed in is not valid (not the string 'course' or 
   #     'user', an undefined  reference is returned.
   #     If none of the resources are found, an undef is returned
 sub resdata {  sub resdata {
     my ($name,$domain,$type,@which)=@_;      my ($name,$domain,$type,@which)=@_;
     my $result;      my $result;
Line 6187  sub packages_tab_default { Line 6359  sub packages_tab_default {
     $do_default=1;      $do_default=1;
  } elsif ($pack_type eq 'extension') {   } elsif ($pack_type eq 'extension') {
     push(@extension,[$package,$pack_type,$pack_part]);      push(@extension,[$package,$pack_type,$pack_part]);
  } else {   } elsif ($pack_part eq $part || $pack_type eq 'part') {
       # only look at packages defaults for packages that this id is
     push(@specifics,[$package,$pack_type,$pack_part]);      push(@specifics,[$package,$pack_type,$pack_part]);
  }   }
     }      }
Line 6403  sub metadata { Line 6576  sub metadata {
     }      }
  }   }
  my ($extension) = ($uri =~ /\.(\w+)$/);   my ($extension) = ($uri =~ /\.(\w+)$/);
    $extension = lc($extension);
    if ($extension eq 'htm') { $extension='html'; }
   
  foreach my $key (keys(%packagetab)) {   foreach my $key (keys(%packagetab)) {
     #no specific packages #how's our extension      #no specific packages #how's our extension
     if ($key!~/^extension_\Q$extension\E&/) { next; }      if ($key!~/^extension_\Q$extension\E&/) { next; }
     &metadata_create_package_def($uri,$key,'extension_'.$extension,      &metadata_create_package_def($uri,$key,'extension_'.$extension,
  \%metathesekeys);   \%metathesekeys);
  }   }
  if (!exists($metaentry{':packages'})) {  
    if (!exists($metaentry{':packages'})
       || $packagetab{"import_defaults&extension_$extension"}) {
     foreach my $key (keys(%packagetab)) {      foreach my $key (keys(%packagetab)) {
  #no specific packages well let's get default then   #no specific packages well let's get default then
  if ($key!~/^default&/) { next; }   if ($key!~/^default&/) { next; }
Line 6905  sub getCODE { Line 7083  sub getCODE {
   
 sub rndseed {  sub rndseed {
     my ($symb,$courseid,$domain,$username)=@_;      my ($symb,$courseid,$domain,$username)=@_;
   
     my ($wsymb,$wcourseid,$wdomain,$wusername)=&whichuser();      my ($wsymb,$wcourseid,$wdomain,$wusername)=&whichuser();
     if (!$symb) {      if (!$symb) {
  unless ($symb=$wsymb) { return time; }   unless ($symb=$wsymb) { return time; }
Line 7359  sub filelocation { Line 7536  sub filelocation {
  $file=~s-^/adm/wrapper/-/-;   $file=~s-^/adm/wrapper/-/-;
  $file=~s-^/adm/coursedocs/showdoc/-/-;   $file=~s-^/adm/coursedocs/showdoc/-/-;
     }      }
   
     if ($file=~m:^/~:) { # is a contruction space reference      if ($file=~m:^/~:) { # is a contruction space reference
         $location = $file;          $location = $file;
         $location =~ s:/~(.*?)/(.*):/home/$1/public_html/$2:;          $location =~ s:/~(.*?)/(.*):/home/$1/public_html/$2:;
Line 7379  sub filelocation { Line 7557  sub filelocation {
    $location=$Apache::lonnet::perlvar{'lonDocRoot'}.'/userfiles/'.     $location=$Apache::lonnet::perlvar{'lonDocRoot'}.'/userfiles/'.
        $udom.'/'.$uname.'/'.$filename;         $udom.'/'.$uname.'/'.$filename;
         }          }
       } elsif ($file =~ m-^/adm/-) {
    $location = $perlvar{'lonDocRoot'}.'/'.$file;
     } else {      } else {
         $file=~s/^\Q$perlvar{'lonDocRoot'}\E//;          $file=~s/^\Q$perlvar{'lonDocRoot'}\E//;
         $file=~s:^/res/:/:;          $file=~s:^/res/:/:;
Line 7414  sub hreflocation { Line 7594  sub hreflocation {
 }  }
   
 sub current_machine_domains {  sub current_machine_domains {
     my $hostname=&hostname($perlvar{'lonHostID'});      return &machine_domains(&hostname($perlvar{'lonHostID'}));
   }
   
   sub machine_domains {
       my ($hostname) = @_;
     my @domains;      my @domains;
     my %hostname = &all_hostnames();      my %hostname = &all_hostnames();
     while( my($id, $name) = each(%hostname)) {      while( my($id, $name) = each(%hostname)) {
 # &logthis("-$id-$name-$hostname-");  # &logthis("-$id-$name-$hostname-");
  if ($hostname eq $name) {   if ($hostname eq $name) {
     push(@domains,$hostdom{$id});      push(@domains,&host_domain($id));
  }   }
     }      }
     return @domains;      return @domains;
 }  }
   
 sub current_machine_ids {  sub current_machine_ids {
     my $hostname=&hostname($perlvar{'lonHostID'});      return &machine_ids(&hostname($perlvar{'lonHostID'}));
   }
   
   sub machine_ids {
       my ($hostname) = @_;
       $hostname ||= &hostname($perlvar{'lonHostID'});
     my @ids;      my @ids;
     my %hostname = &all_hostnames();      my %name_to_host = &all_names();
     while( my($id, $name) = each(%hostname)) {      if (ref($name_to_host{$hostname}) eq 'ARRAY') {
 # &logthis("-$id-$name-$hostname-");   return @{ $name_to_host{$hostname} };
  if ($hostname eq $name) {  
     push(@ids,$id);  
  }  
     }      }
     return @ids;      return;
 }  }
   
 sub additional_machine_domains {  sub additional_machine_domains {
Line 7480  sub declutter { Line 7666  sub declutter {
   
 sub clutter {  sub clutter {
     my $thisfn='/'.&declutter(shift);      my $thisfn='/'.&declutter(shift);
     unless ($thisfn=~/^\/(uploaded|editupload|adm|userfiles|ext|raw|priv|public)\//) {       if ($thisfn !~ m{^/(uploaded|editupload|adm|userfiles|ext|raw|priv|public)/}
    || $thisfn =~ m{^/adm/(includes|pages)} ) { 
        $thisfn='/res'.$thisfn;          $thisfn='/res'.$thisfn; 
     }      }
     if ($thisfn !~m|/adm|) {      if ($thisfn !~m|/adm|) {
Line 7549  sub correct_line_ends { Line 7736  sub correct_line_ends {
 sub goodbye {  sub goodbye {
    &logthis("Starting Shut down");     &logthis("Starting Shut down");
 #not converted to using infrastruture and probably shouldn't be  #not converted to using infrastruture and probably shouldn't be
    &logthis(sprintf("%-20s is %s",'%badServerCache',length(&freeze(\%badServerCache))));     &logthis(sprintf("%-20s is %s",'%badServerCache',length(&nfreeze(\%badServerCache))));
 #converted  #converted
 #   &logthis(sprintf("%-20s is %s",'%metacache',scalar(%metacache)));  #   &logthis(sprintf("%-20s is %s",'%metacache',scalar(%metacache)));
    &logthis(sprintf("%-20s is %s",'%homecache',length(&freeze(\%homecache))));     &logthis(sprintf("%-20s is %s",'%homecache',length(&nfreeze(\%homecache))));
 #   &logthis(sprintf("%-20s is %s",'%titlecache',length(&freeze(\%titlecache))));  #   &logthis(sprintf("%-20s is %s",'%titlecache',length(&nfreeze(\%titlecache))));
 #   &logthis(sprintf("%-20s is %s",'%courseresdatacache',length(&freeze(\%courseresdatacache))));  #   &logthis(sprintf("%-20s is %s",'%courseresdatacache',length(&nfreeze(\%courseresdatacache))));
 #1.1 only  #1.1 only
 #   &logthis(sprintf("%-20s is %s",'%userresdatacache',length(&freeze(\%userresdatacache))));  #   &logthis(sprintf("%-20s is %s",'%userresdatacache',length(&nfreeze(\%userresdatacache))));
 #   &logthis(sprintf("%-20s is %s",'%getsectioncache',length(&freeze(\%getsectioncache))));  #   &logthis(sprintf("%-20s is %s",'%getsectioncache',length(&nfreeze(\%getsectioncache))));
 #   &logthis(sprintf("%-20s is %s",'%courseresversioncache',length(&freeze(\%courseresversioncache))));  #   &logthis(sprintf("%-20s is %s",'%courseresversioncache',length(&nfreeze(\%courseresversioncache))));
 #   &logthis(sprintf("%-20s is %s",'%resversioncache',length(&freeze(\%resversioncache))));  #   &logthis(sprintf("%-20s is %s",'%resversioncache',length(&nfreeze(\%resversioncache))));
    &logthis(sprintf("%-20s is %s",'%remembered',length(&freeze(\%remembered))));     &logthis(sprintf("%-20s is %s",'%remembered',length(&nfreeze(\%remembered))));
    &logthis(sprintf("%-20s is %s",'kicks',$kicks));     &logthis(sprintf("%-20s is %s",'kicks',$kicks));
    &logthis(sprintf("%-20s is %s",'hits',$hits));     &logthis(sprintf("%-20s is %s",'hits',$hits));
    &flushcourselogs();     &flushcourselogs();
    &logthis("Shutting down");     &logthis("Shutting down");
 }  }
   
 BEGIN {  sub get_dns {
 # ----------------------------------- Read loncapa.conf and loncapa_apache.conf      my ($url,$func,$ignore_cache) = @_;
     unless ($readit) {      if (!$ignore_cache) {
 {   my ($content,$cached)=
     my $configvars = LONCAPA::Configuration::read_conf('loncapa.conf');      &Apache::lonnet::is_cached_new('dns',$url);
     %perlvar = (%perlvar,%{$configvars});   if ($cached) {
 }      &$func($content);
       return;
    }
       }
   
       my %alldns;
       open(my $config,"<$perlvar{'lonTabDir'}/hosts.tab");
       foreach my $dns (<$config>) {
    next if ($dns !~ /^\^(\S*)/x);
    $alldns{$1} = 1;
       }
       while (%alldns) {
    my ($dns) = keys(%alldns);
    delete($alldns{$dns});
    my $ua=new LWP::UserAgent;
    my $request=new HTTP::Request('GET',"http://$dns$url");
    my $response=$ua->request($request);
    next if ($response->is_error());
    my @content = split("\n",$response->content);
    &Apache::lonnet::do_cache_new('dns',$url,\@content,30*24*60*60);
    &$func(\@content);
    return;
       }
       close($config);
       my $which = (split('/',$url))[3];
       &logthis("unable to contact DNS defaulting to on disk file dns_$which.tab\n");
       open($config,"<$perlvar{'lonTabDir'}/dns_$which.tab");
       my @content = <$config>;
       &$func(\@content);
       return;
   }
 # ------------------------------------------------------------ Read domain file  # ------------------------------------------------------------ Read domain file
 {  {
     %domaindescription = ();      my $loaded;
     %domain_auth_def = ();      my %domain;
     %domain_auth_arg_def = ();  
     my $fh;      sub parse_domain_tab {
     if (open($fh,"<".$Apache::lonnet::perlvar{'lonTabDir'}.'/domain.tab')) {   my ($lines) = @_;
  while (my $line = <$fh>) {   foreach my $line (@$lines) {
            next if ($line =~ /^(\#|\s*$)/);      next if ($line =~ /^(\#|\s*$ )/x);
 #           next if /^\#/;  
            chomp $line;      chomp($line);
            my ($domain, $domain_description, $def_auth, $def_auth_arg,      my ($name,@elements) = split(/:/,$line,9);
        $def_lang, $city, $longi, $lati, $primary) = split(/:/,$line,9);      my %this_domain;
    $domain_auth_def{$domain}=$def_auth;      foreach my $field ('description', 'auth_def', 'auth_arg_def',
            $domain_auth_arg_def{$domain}=$def_auth_arg;         'lang_def', 'city', 'longi', 'lati',
    $domaindescription{$domain}=$domain_description;         'primary') {
    $domain_lang_def{$domain}=$def_lang;   $this_domain{$field} = shift(@elements);
    $domain_city{$domain}=$city;      }
    $domain_longi{$domain}=$longi;      $domain{$name} = \%this_domain;
    $domain_lati{$domain}=$lati;   }
            $domain_primary{$domain}=$primary;      }
   
       sub reset_domain_info {
    undef($loaded);
    undef(%domain);
       }
   
  #         &logthis("Domain.tab: $domain, $domain_auth_def{$domain}, $domain_auth_arg_def{$domain},$domaindescription{$domain}");      sub load_domain_tab {
 #          &logthis("Domain.tab: $domain ".$domaindescription{$domain} );   my ($ignore_cache) = @_;
    &get_dns('/adm/dns/domain',\&parse_domain_tab,$ignore_cache);
    my $fh;
    if (open($fh,"<".$perlvar{'lonTabDir'}.'/domain.tab')) {
       my @lines = <$fh>;
       &parse_domain_tab(\@lines);
  }   }
    close($fh);
    $loaded = 1;
       }
   
       sub domain {
    &load_domain_tab() if (!$loaded);
   
    my ($name,$what) = @_;
    return if ( !exists($domain{$name}) );
   
    if (!$what) {
       return $domain{$name}{'description'};
    }
    return $domain{$name}{$what};
     }      }
     close ($fh);  
 }  }
   
   
 # ------------------------------------------------------------- Read hosts file  # ------------------------------------------------------------- Read hosts file
 {  {
     my %hostname;      my %hostname;
     open(my $config,"<$perlvar{'lonTabDir'}/hosts.tab");      my %hostdom;
       my %libserv;
     while (my $configline=<$config>) {      my $loaded;
        next if ($configline =~ /^(\#|\s*$)/);      my %name_to_host;
        chomp($configline);  
        my ($id,$domain,$role,$name)=split(/:/,$configline);      sub parse_hosts_tab {
        $name=~s/\s//g;   my ($file) = @_;
        if ($id && $domain && $role && $name) {   foreach my $configline (@$file) {
  $hostname{$id}=$name;      next if ($configline =~ /^(\#|\s*$ )/x);
  $hostdom{$id}=$domain;      next if ($configline =~ /^\^/);
  if ($role eq 'library') { $libserv{$id}=$name; }      chomp($configline);
        }      my ($id,$domain,$role,$name)=split(/:/,$configline);
       $name=~s/\s//g;
       if ($id && $domain && $role && $name) {
    $hostname{$id}=$name;
    push(@{$name_to_host{$name}}, $id);
    $hostdom{$id}=$domain;
    if ($role eq 'library') { $libserv{$id}=$name; }
       }
    }
       }
       
       sub reset_hosts_info {
    &reset_domain_info();
    &reset_hosts_ip_info();
    undef(%name_to_host);
    undef(%hostname);
    undef(%hostdom);
    undef(%libserv);
    undef($loaded);
       }
   
       sub load_hosts_tab {
    my ($ignore_cache) = @_;
    &get_dns('/adm/dns/hosts',\&parse_hosts_tab,$ignore_cache);
    open(my $config,"<$perlvar{'lonTabDir'}/hosts.tab");
    my @config = <$config>;
    &parse_hosts_tab(\@config);
    close($config);
    $loaded=1;
     }      }
     close($config);  
     # FIXME: dev server don't want this, production servers _do_ want this  
     #&get_iphost();  
   
     sub hostname {      sub hostname {
    &load_hosts_tab() if (!$loaded);
   
  my ($lonid) = @_;   my ($lonid) = @_;
  return $hostname{$lonid};   return $hostname{$lonid};
     }      }
   
     sub all_hostnames {      sub all_hostnames {
    &load_hosts_tab() if (!$loaded);
   
  return %hostname;   return %hostname;
     }      }
   
       sub all_names {
    &load_hosts_tab() if (!$loaded);
   
    return %name_to_host;
       }
   
       sub is_library {
    &load_hosts_tab() if (!$loaded);
   
    return exists($libserv{$_[0]});
       }
   
       sub all_library {
    &load_hosts_tab() if (!$loaded);
   
    return %libserv;
       }
   
       sub get_servers {
    &load_hosts_tab() if (!$loaded);
   
    my ($domain,$type) = @_;
    my %possible_hosts = ($type eq 'library') ? %libserv
                                             : %hostname;
    my %result;
    if (ref($domain) eq 'ARRAY') {
       while ( my ($host,$hostname) = each(%possible_hosts)) {
    if (grep(/^\Q$hostdom{$host}\E$/,@$domain)) {
       $result{$host} = $hostname;
    }
       }
    } else {
       while ( my ($host,$hostname) = each(%possible_hosts)) {
    if ($hostdom{$host} eq $domain) {
       $result{$host} = $hostname;
    }
       }
    }
    return %result;
       }
   
       sub host_domain {
    &load_hosts_tab() if (!$loaded);
   
    my ($lonid) = @_;
    return $hostdom{$lonid};
       }
   
       sub all_domains {
    &load_hosts_tab() if (!$loaded);
   
    my %seen;
    my @uniq = grep(!$seen{$_}++, values(%hostdom));
    return @uniq;
       }
 }  }
   
 sub get_iphost {  { 
     if (%iphost) { return %iphost; }      my %iphost;
     my %name_to_ip;      my %name_to_ip;
     my %hostname = &all_hostnames();      my %lonid_to_ip;
     foreach my $id (keys(%hostname)) {  
  my $name=$hostname{$id};      sub get_hosts_from_ip {
  my $ip;   my ($ip) = @_;
  if (!exists($name_to_ip{$name})) {   my %iphosts = &get_iphost();
     $ip = gethostbyname($name);   if (ref($iphosts{$ip})) {
     if (!$ip || length($ip) ne 4) {      return @{$iphosts{$ip}};
  &logthis("Skipping host $id name $name no IP found");   }
  next;   return;
       }
       
       sub reset_hosts_ip_info {
    undef(%iphost);
    undef(%name_to_ip);
    undef(%lonid_to_ip);
       }
   
       sub get_host_ip {
    my ($lonid) = @_;
    if (exists($lonid_to_ip{$lonid})) {
       return $lonid_to_ip{$lonid};
    }
    my $name=&hostname($lonid);
       my $ip = gethostbyname($name);
    return if (!$ip || length($ip) ne 4);
    $ip=inet_ntoa($ip);
    $name_to_ip{$name}   = $ip;
    $lonid_to_ip{$lonid} = $ip;
    return $ip;
       }
       
       sub get_iphost {
    my ($ignore_cache) = @_;
    if (!$ignore_cache) {
       if (%iphost) {
    return %iphost;
     }      }
     $ip=inet_ntoa($ip);      my ($ip_info,$cached)=
     $name_to_ip{$name} = $ip;   &Apache::lonnet::is_cached_new('iphost','iphost');
  } else {      if ($cached) {
     $ip = $name_to_ip{$name};   %iphost      = %{$ip_info->[0]};
    %name_to_ip  = %{$ip_info->[1]};
    %lonid_to_ip = %{$ip_info->[2]};
    return %iphost;
       }
    }
    my %name_to_host = &all_names();
    foreach my $name (keys(%name_to_host)) {
       my $ip;
       if (!exists($name_to_ip{$name})) {
    $ip = gethostbyname($name);
    if (!$ip || length($ip) ne 4) {
       &logthis("Skipping name $name no IP found");
       next;
    }
    $ip=inet_ntoa($ip);
    $name_to_ip{$name} = $ip;
       } else {
    $ip = $name_to_ip{$name};
       }
       foreach my $id (@{ $name_to_host{$name} }) {
    $lonid_to_ip{$id} = $ip;
       }
       push(@{$iphost{$ip}},@{$name_to_host{$name}});
  }   }
  push(@{$iphost{$ip}},$id);   &Apache::lonnet::do_cache_new('iphost','iphost',
         [\%iphost,\%name_to_ip,\%lonid_to_ip],
         24*60*60);
   
    return %iphost;
     }      }
     return %iphost;  
 }  }
   
   BEGIN {
   
   # ----------------------------------- Read loncapa.conf and loncapa_apache.conf
       unless ($readit) {
   {
       my $configvars = LONCAPA::Configuration::read_conf('loncapa.conf');
       %perlvar = (%perlvar,%{$configvars});
   }
   
   
 # ------------------------------------------------------ Read spare server file  # ------------------------------------------------------ Read spare server file
 {  {
     open(my $config,"<$perlvar{'lonTabDir'}/spare.tab");      open(my $config,"<$perlvar{'lonTabDir'}/spare.tab");
Line 7988  X<userenvironment()> Line 8376  X<userenvironment()>
 B<userenvironment($udom,$uname,@what)>: gets the values of the keys  B<userenvironment($udom,$uname,@what)>: gets the values of the keys
 passed in @what from the requested user's environment, returns a hash  passed in @what from the requested user's environment, returns a hash
   
   =item * 
   X<userlog_query()>
   B<userlog_query($uname,$udom,%filters)>: retrieves data from a user's
   activity.log file. %filters defines filters applied when parsing the
   log file. These can be start or end timestamps, or the type of action
   - log to look for Login or Logout events, check for Checkin or
   Checkout, role for role selection. The response is in the form
   timestamp1:hostid1:event1&timestamp2:hostid2:event2 where events are
   escaped strings of the action recorded in the activity.log file.
   
 =back  =back
   
 =head2 User Roles  =head2 User Roles
Line 8017  explanation of a user role term Line 8415  explanation of a user role term
   
 =item *  =item *
   
 get_my_roles($uname,$udom,$types,$roles,$roledoms) : All arguments are  get_my_roles($uname,$udom,$context,$types,$roles,$roledoms) :
 optional.  Returns a hash of a user's roles, with keys set to  All arguments are optional. Returns a hash of a roles, either for
 colon-sparated $uname,$udom,and $role, and value set to  co-author/assistant author roles for a user's Construction Space
 colon-separated start and end times for the role. If no username and  (default), or if $context is 'user', roles for the user himself,
 domain are specified, will default to current user/domain. Types,  In the hash, keys are set to colon-sparated $uname,$udom,and $role,
 roles, and roledoms are references to arrays, of role statuses  and value is set to colon-separated start and end times for the role.
 (active, future or previous), roles (e.g., cc,in, st etc.) and domains  If no username and domain are specified, will default to current
 of the roles which can be used to restrict the list if roles  user/domain. Types, roles, and roledoms are references to arrays,
 reported. If no array ref is provided for types, will default to  of role statuses (active, future or previous), roles 
 return only active roles.  (e.g., cc,in, st etc.) and domains of the roles which can be used
   to restrict the list of roles reported. If no array ref is 
   provided for types, will default to return only active roles.
   
 =back  =back
   
Line 8170  setting for a specific $type, where $typ Line 8570  setting for a specific $type, where $typ
 @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 5 minutes.
   
   =item *
   
   get_courseresdata($courseid, $domain) : dump the entire course resource
   data base, returning a hash that is keyed by the resource name and has
   values that are the resource value.  I believe that the timestamps and
   versions are also returned.
   
   
 =back  =back
   
 =head2 Course Modification  =head2 Course Modification
Line 8451  critical subroutine Line 8859  critical subroutine
   
 =item *  =item *
   
 get_dom($namespace,$storearr,$udomain) : returns hash with keys from array  get_dom($namespace,$storearr,$udom,$uhome) : returns hash with keys from
 reference filled in from namespace found in domain level on primary domain server ($udomain is optional)  array reference filled in from namespace found in domain level on either
   specified domain server ($uhome) or primary domain server ($udom and $uhome are optional).
   
 =item *  =item *
   
 put_dom($namespace,$storehash,$udomain) :  stores hash in namespace at domain level on primary domain server ($udomain is optional)  put_dom($namespace,$storehash,$udom,$uhome) :  stores hash in namespace at 
   domain level either on specified domain server ($uhome) or primary domain 
   server ($udom and $uhome are optional)
   
 =back  =back
   
Line 8849  symblist($mapname,%newhash) : update sym Line 9260  symblist($mapname,%newhash) : update sym
 =back  =back
   
 =cut  =cut
   

Removed from v.1.838  
changed lines
  Added in v.1.892


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