--- loncom/lonnet/perl/lonnet.pm	2014/04/23 10:50:53	1.1172.2.44
+++ loncom/lonnet/perl/lonnet.pm	2014/10/24 00:37:15	1.1172.2.56
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1172.2.44 2014/04/23 10:50:53 raeburn Exp $
+# $Id: lonnet.pm,v 1.1172.2.56 2014/10/24 00:37:15 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -956,13 +956,30 @@ sub has_user_session {
 # --------- determine least loaded server in a user's domain which allows login
 
 sub choose_server {
-    my ($udom,$checkloginvia,$required) = @_;
+    my ($udom,$checkloginvia,$required,$skiploadbal) = @_;
     my %domconfhash = &Apache::loncommon::get_domainconf($udom);
     my %servers = &get_servers($udom);
     my $lowest_load = 30000;
-    my ($login_host,$hostname,$portal_path,$isredirect);
+    my ($login_host,$hostname,$portal_path,$isredirect,$balancers);
+    if ($skiploadbal) {
+        ($balancers,my $cached)=&is_cached_new('loadbalancing',$udom);
+        unless (defined($cached)) {
+            my $cachetime = 60*60*24;
+            my %domconfig =
+                &Apache::lonnet::get_dom('configuration',['loadbalancing'],$udom);
+            if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
+                $balancers = &do_cache_new('loadbalancing',$udom,$domconfig{'loadbalancing'},
+                                           $cachetime);
+            }
+        }
+    }
     foreach my $lonhost (keys(%servers)) {
         my $loginvia;
+        if ($skiploadbal) {
+            if (ref($balancers) eq 'HASH') {
+                next if (exists($balancers->{$lonhost}));
+            }
+        }
         if ($checkloginvia) {
             $loginvia = $domconfhash{$udom.'.login.loginvia_'.$lonhost};
             if ($loginvia) {
@@ -2006,7 +2023,8 @@ sub get_domain_defaults {
          &Apache::lonnet::get_dom('configuration',['defaults','quotas',
                                   'requestcourses','inststatus',
                                   'coursedefaults','usersessions',
-                                  'requestauthor','selfenrollment'],$domain);
+                                  'requestauthor','selfenrollment',
+                                  'coursecategories'],$domain);
     my @coursetypes = ('official','unofficial','community','textbook');
     if (ref($domconfig{'defaults'}) eq 'HASH') {
         $domdefaults{'lang_def'} = $domconfig{'defaults'}{'lang_def'}; 
@@ -2097,6 +2115,16 @@ sub get_domain_defaults {
             }
         }
     }
+    if (ref($domconfig{'coursecategories'}) eq 'HASH') {
+        $domdefaults{'catauth'} = 'std';
+        $domdefaults{'catunauth'} = 'std';
+        if ($domconfig{'coursecategories'}{'auth'}) {
+            $domdefaults{'catauth'} = $domconfig{'coursecategories'}{'auth'};
+        }
+        if ($domconfig{'coursecategories'}{'unauth'}) {
+            $domdefaults{'catunauth'} = $domconfig{'coursecategories'}{'unauth'};
+        }
+    }
     &do_cache_new('domdefaults',$domain,\%domdefaults,$cachetime);
     return %domdefaults;
 }
@@ -5676,18 +5704,17 @@ sub dump {
     if (!$uname) { $uname=$env{'user.name'}; }
     my $uhome=&homeserver($uname,$udomain);
 
-    my $reply;
+    if ($regexp) {
+        $regexp=&escape($regexp);
+    } else {
+        $regexp='.';
+    }
     if (grep { $_ eq $uhome } &current_machine_ids()) {
         # user is hosted on this machine
-        $reply = LONCAPA::Lond::dump_with_regexp(join(':', ($udomain,
+        my $reply = LONCAPA::Lond::dump_with_regexp(join(':', ($udomain,
                     $uname, $namespace, $regexp, $range)), $perlvar{'lonVersion'});
         return %{&unserialize($reply, $escapedkeys)};
     }
-    if ($regexp) {
-	$regexp=&escape($regexp);
-    } else {
-	$regexp='.';
-    }
     my $rep=&reply("dump:$udomain:$uname:$namespace:$regexp:$range",$uhome);
     my @pairs=split(/\&/,$rep);
     my %returnhash=();
@@ -5735,7 +5762,15 @@ sub currentdump {
    $sdom     = $env{'user.domain'}       if (! defined($sdom));
    $sname    = $env{'user.name'}         if (! defined($sname));
    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)/);
    #
    my %returnhash=();
@@ -6028,10 +6063,15 @@ sub get_timebased_id {
         my %inuse = &Apache::lonnet::dump('nohist_'.$namespace,$cdom,$cnum,$prefix);
         my $id = time;
         $newid = $id;
+        if ($idtype eq 'addcode') {
+            $newid .= &sixnum_code();
+        }
         my $idtries = 0;
         while (exists($inuse{$prefix."\0".$newid}) && $idtries < $maxtries) {
             if ($idtype eq 'concat') {
                 $newid = $id.$idtries;
+            } elsif ($idtype eq 'addcode') {
+                $newid = $newid.&sixnum_code();
             } else {
                 $newid ++;
             }
@@ -6048,6 +6088,7 @@ sub get_timebased_id {
                 $error = 'error saving new item: '.$putresult;
             }
         } else {
+             undef($newid);
              $error = ('error: no unique suffix available for the new item ');
         }
 #  remove lock
@@ -6060,6 +6101,14 @@ sub get_timebased_id {
     return ($newid,$dellock,$error);
 }
 
+sub sixnum_code {
+    my $code;
+    for (0..6) {
+        $code .= int( rand(9) );
+    }
+    return $code;
+}
+
 # -------------------------------------------------- portfolio access checking
 
 sub portfolio_access {
@@ -7960,7 +8009,7 @@ sub auto_validate_class_sec {
 
 sub auto_crsreq_update {
     my ($cdom,$cnum,$crstype,$action,$ownername,$ownerdomain,$fullname,$title,
-        $code,$inbound) = @_;
+        $code,$accessstart,$accessend,$inbound) = @_;
     my ($homeserver,%crsreqresponse);
     if ($cdom =~ /^$match_domain$/) {
         $homeserver = &domain($cdom,'primary');
@@ -7973,7 +8022,8 @@ sub auto_crsreq_update {
         my $response=&reply('autocrsrequpdate:'.$cdom.':'.$cnum.':'.&escape($crstype).
                             ':'.&escape($action).':'.&escape($ownername).':'.
                             &escape($ownerdomain).':'.&escape($fullname).':'.
-                            &escape($title).':'.&escape($code).':'.$info,$homeserver);
+                            &escape($title).':'.&escape($code).':'.
+                            &escape($accessstart).':'.&escape($accessend).':'.$info,$homeserver);
         unless ($response =~ /(con_lost|error|no_such_host|refused)/) {
             my @items = split(/&/,$response);
             foreach my $item (@items) {
@@ -10260,7 +10310,7 @@ sub metadata {
         ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ m{^/*uploaded/.+\.sequence$})) {
 	return undef;
     }
-    if (($uri =~ /^priv/ || $uri=~/home\/httpd\/html\/priv/) 
+    if (($uri =~ /^priv/ || $uri=~m{^home/httpd/html/priv}) 
 	&& &Apache::lonxml::get_state('target') =~ /^(|meta)$/) {
 	return undef;
     }
@@ -10893,14 +10943,10 @@ sub deversion {
 
 sub symbread {
     my ($thisfn,$donotrecurse)=@_;
-    my $cache_str;
-    if ($thisfn ne '') {
-        $cache_str='request.symbread.cached.'.$thisfn;
-        if ($env{$cache_str} ne '') {
-            return $env{$cache_str};
-        }
-   } else {
+    my $cache_str='request.symbread.cached.'.$thisfn;
+    if (defined($env{$cache_str})) { return $env{$cache_str}; }
 # no filename provided? try from environment
+    unless ($thisfn) {
         if ($env{'request.symb'}) {
             return $env{$cache_str}=&symbclean($env{'request.symb'});
         }
@@ -11317,8 +11363,12 @@ sub rndseed_CODE_64bit5 {
 sub setup_random_from_rndseed {
     my ($rndseed)=@_;
     if ($rndseed =~/([,:])/) {
-	my ($num1,$num2)=split(/[,:]/,$rndseed);
-	&Math::Random::random_set_seed(abs($num1),abs($num2));
+	my ($num1,$num2) = map { abs($_); } (split(/[,:]/,$rndseed));
+        if ((!$num1) || (!$num2) || ($num1 > 2147483562) || ($num2 > 2147483398)) {
+            &Math::Random::random_set_seed_from_phrase($rndseed);
+        } else {
+            &Math::Random::random_set_seed($num1,$num2);
+        }
     } else {
 	&Math::Random::random_set_seed_from_phrase($rndseed);
     }
@@ -11709,7 +11759,9 @@ sub default_login_domain {
 sub declutter {
     my $thisfn=shift;
     if ($thisfn=~m|^/enc/|) { $thisfn=&Apache::lonenc::unencrypted($thisfn); }
-    $thisfn=~s/^\Q$perlvar{'lonDocRoot'}\E//;
+    unless ($thisfn=~m{^/home/httpd/html/priv/}) {
+        $thisfn=~s{^/home/httpd/html}{};
+    }
     $thisfn=~s/^\///;
     $thisfn=~s|^adm/wrapper/||;
     $thisfn=~s|^adm/coursedocs/showdoc/||;
@@ -11836,7 +11888,7 @@ sub get_dns {
 	$alldns{$host} = $protocol;
     }
     while (%alldns) {
-	my ($dns) = keys(%alldns);
+	my ($dns) = sort { $b cmp $a } keys(%alldns);
 	my $ua=new LWP::UserAgent;
         $ua->timeout(30);
 	my $request=new HTTP::Request('GET',"$alldns{$dns}://$dns$url");
@@ -11862,8 +11914,22 @@ sub get_dns {
 # ------------------------------------------------------Get DNS checksums file
 sub parse_dns_checksums_tab {
     my ($lines,$hashref) = @_;
-    my $machine_dom = &Apache::lonnet::host_domain($perlvar{'lonHostID'});
+    my $lonhost = $perlvar{'lonHostID'};
+    my $machine_dom = &Apache::lonnet::host_domain($lonhost);
     my $loncaparev = &get_server_loncaparev($machine_dom);
+    my $distro = (split(/\:/,&get_server_distarch($lonhost)))[0];
+    my $webconfdir = '/etc/httpd/conf';
+    if ($distro =~ /^(ubuntu|debian)(\d+)$/) {
+        $webconfdir = '/etc/apache2';
+    } elsif ($distro =~ /^sles(\d+)$/) {
+        if ($1 >= 10) {
+            $webconfdir = '/etc/apache2';
+        }
+    } elsif ($distro =~ /^suse(\d+\.\d+)$/) {
+        if ($1 >= 10.0) {
+            $webconfdir = '/etc/apache2';
+        }
+    }
     my ($release,$timestamp) = split(/\-/,$loncaparev);
     my (%chksum,%revnum);
     if (ref($lines) eq 'ARRAY') {
@@ -11872,6 +11938,11 @@ sub parse_dns_checksums_tab {
         if ($version eq $release) {
             foreach my $line (@{$lines}) {
                 my ($file,$version,$shasum) = split(/,/,$line);
+                if ($file =~ m{^/etc/httpd/conf}) {
+                    if ($webconfdir eq '/etc/apache2') {
+                        $file =~ s{^\Q/etc/httpd/conf/\E}{$webconfdir/};
+                    }
+                }
                 $chksum{$file} = $shasum;
                 $revnum{$file} = $version;
             }
@@ -11889,7 +11960,7 @@ sub parse_dns_checksums_tab {
 sub fetch_dns_checksums {
     my %checksums;
     my $machine_dom = &Apache::lonnet::host_domain($perlvar{'lonHostID'});
-    my $loncaparev = &get_server_loncaparev($machine_dom);
+    my $loncaparev = &get_server_loncaparev($machine_dom,$perlvar{'lonHostID'});
     my ($release,$timestamp) = split(/\-/,$loncaparev);
     &get_dns("/adm/dns/checksums/$release",\&parse_dns_checksums_tab,1,1,
              \%checksums);
@@ -13677,7 +13748,8 @@ filelocation except for hrefs
 
 =item *
 
-declutter() : declutters URLs (remove docroot, beginning slashes, 'res' etc)
+declutter() : declutters URLs -- remove beginning slashes, 'res' etc.
+also removes beginning /home/httpd/html unless /priv/ follows it.
 
 =back