--- loncom/lonnet/perl/lonnet.pm	2005/09/13 19:43:01	1.656
+++ loncom/lonnet/perl/lonnet.pm	2005/11/01 21:34:04	1.675
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.656 2005/09/13 19:43:01 albertel Exp $
+# $Id: lonnet.pm,v 1.675 2005/11/01 21:34:04 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -37,7 +37,7 @@ use HTTP::Date;
 use vars 
 qw(%perlvar %hostname %badServerCache %iphost %spareid %hostdom 
    %libserv %pr %prp $memcache %packagetab 
-   %courselogs %accesshash %userrolehash $processmarker $dumpcount 
+   %courselogs %accesshash %userrolehash %domainrolehash $processmarker $dumpcount 
    %coursedombuf %coursenumbuf %coursehombuf %coursedescrbuf %courseinstcodebuf %courseownerbuf
    %domaindescription %domain_auth_def %domain_auth_arg_def 
    %domain_lang_def %domain_city %domain_longi %domain_lati $tmpdir $_64bit
@@ -166,7 +166,7 @@ sub reply {
     unless (defined($hostname{$server})) { return 'no_such_host'; }
     my $answer=subreply($cmd,$server);
     if (($answer=~/^refused/) || ($answer=~/^rejected/)) {
-       &logthis("<font color=blue>WARNING:".
+       &logthis("<font color=\"blue\">WARNING:".
                 " $cmd to $server returned $answer</font>");
     }
     return $answer;
@@ -190,14 +190,14 @@ sub reconlonc {
             sleep 5;
             if (-e "$peerfile") { return; }
             &logthis(
-  "<font color=blue>WARNING: $peerfile still not there, giving up</font>");
+  "<font color=\"blue\">WARNING: $peerfile still not there, giving up</font>");
         } else {
 	    &logthis(
-               "<font color=blue>WARNING:".
+               "<font color=\"blue\">WARNING:".
                " lonc at pid $loncpid not responding, giving up</font>");
         }
     } else {
-     &logthis('<font color=blue>WARNING: lonc not running, giving up</font>');
+     &logthis('<font color="blue">WARNING: lonc not running, giving up</font>');
     }
 }
 
@@ -206,7 +206,7 @@ sub reconlonc {
 sub critical {
     my ($cmd,$server)=@_;
     unless ($hostname{$server}) {
-        &logthis("<font color=blue>WARNING:".
+        &logthis("<font color=\"blue\">WARNING:".
                " Critical message to unknown server ($server)</font>");
         return 'no_such_host';
     }
@@ -240,12 +240,12 @@ sub critical {
             }
             chomp($wcmd);
             if ($wcmd eq $cmd) {
-		&logthis("<font color=blue>WARNING: ".
+		&logthis("<font color=\"blue\">WARNING: ".
                          "Connection buffer $dfilename: $cmd</font>");
                 &logperm("D:$server:$cmd");
 	        return 'con_delayed';
             } else {
-                &logthis("<font color=red>CRITICAL:"
+                &logthis("<font color=\"red\">CRITICAL:"
                         ." Critical connection failed: $server $cmd</font>");
                 &logperm("F:$server:$cmd");
                 return 'con_failed';
@@ -290,7 +290,7 @@ sub appenv {
     my %newenv=@_;
     foreach (keys %newenv) {
 	if (($newenv{$_}=~/^user\.role/) || ($newenv{$_}=~/^user\.priv/)) {
-            &logthis("<font color=blue>WARNING: ".
+            &logthis("<font color=\"blue\">WARNING: ".
                 "Attempt to modify environment ".$_." to ".$newenv{$_}
                 .'</font>');
 	    delete($newenv{$_});
@@ -304,7 +304,7 @@ sub appenv {
 	return 'error: '.$!;
     }
     unless (flock($lockfh,LOCK_EX)) {
-         &logthis("<font color=blue>WARNING: ".
+         &logthis("<font color=\"blue\">WARNING: ".
                   'Could not obtain exclusive lock in appenv: '.$!);
          close($lockfh);
          return 'error: '.$!;
@@ -349,7 +349,7 @@ sub delenv {
     my $delthis=shift;
     my %newenv=();
     if (($delthis=~/user\.role/) || ($delthis=~/user\.priv/)) {
-        &logthis("<font color=blue>WARNING: ".
+        &logthis("<font color=\"blue\">WARNING: ".
                 "Attempt to delete from environment ".$delthis);
         return 'error';
     }
@@ -360,7 +360,7 @@ sub delenv {
 	    return 'error';
 	}
 	unless (flock($fh,LOCK_SH)) {
-	    &logthis("<font color=blue>WARNING: ".
+	    &logthis("<font color=\"blue\">WARNING: ".
 		     'Could not obtain shared lock in delenv: '.$!);
 	    close($fh);
 	    return 'error: '.$!;
@@ -374,7 +374,7 @@ sub delenv {
 	    return 'error';
 	}
 	unless (flock($fh,LOCK_EX)) {
-	    &logthis("<font color=blue>WARNING: ".
+	    &logthis("<font color=\"blue\">WARNING: ".
 		     'Could not obtain exclusive lock in delenv: '.$!);
 	    close($fh);
 	    return 'error: '.$!;
@@ -443,15 +443,15 @@ sub overloaderror {
 # ------------------------------ Find server with least workload from spare.tab
 
 sub spareserver {
-    my ($loadpercent,$userloadpercent) = @_;
+    my ($loadpercent,$userloadpercent,$want_server_name) = @_;
     my $tryserver;
     my $spareserver='';
     if ($userloadpercent !~ /\d/) { $userloadpercent=0; }
     my $lowestserver=$loadpercent > $userloadpercent?
 	             $loadpercent :  $userloadpercent;
-    foreach $tryserver (keys %spareid) {
-	my $loadans=reply('load',$tryserver);
-	my $userloadans=reply('userload',$tryserver);
+    foreach $tryserver (keys(%spareid)) {
+	my $loadans=&reply('load',$tryserver);
+	my $userloadans=&reply('userload',$tryserver);
 	if ($loadans !~ /\d/ && $userloadans !~ /\d/) {
 	    next; #didn't get a number from the server
 	}
@@ -468,7 +468,11 @@ sub spareserver {
 	    $answer = $userloadans;
 	}
 	if (($answer =~ /\d/) && ($answer<$lowestserver)) {
-	    $spareserver="http://$hostname{$tryserver}";
+	    if ($want_server_name) {
+		$spareserver=$tryserver;
+	    } else {
+		$spareserver="http://$hostname{$tryserver}";
+	    }
 	    $lowestserver=$answer;
 	}
     }
@@ -1060,7 +1064,7 @@ sub repcopy {
            if ($response->is_error()) {
 	       unlink($transname);
                my $message=$response->status_line;
-               &logthis("<font color=blue>WARNING:"
+               &logthis("<font color=\"blue\">WARNING:"
                        ." LWP get: $message: $filename</font>");
                return 'unavailable';
            } else {
@@ -1070,7 +1074,7 @@ sub repcopy {
                   if ($mresponse->is_error()) {
 		      unlink($filename.'.meta');
                       &logthis(
-                     "<font color=yellow>INFO: No metadata: $filename</font>");
+                     "<font color=\"yellow\">INFO: No metadata: $filename</font>");
                   }
 	       }
                rename($transname,$filename);
@@ -1176,7 +1180,6 @@ sub process_coursefile {
         $fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file,
 			     $home);
     } else {
-        my $fetchresult = '';
         my $fpath = '';
         my $fname = $file;
         ($fpath,$fname) = ($file =~ m|^(.*)/([^/]+)$|);
@@ -1539,7 +1542,7 @@ sub flushcourselogs {
         } else {
             &logthis('Failed to flush log buffer for '.$crsid);
             if (length($courselogs{$crsid})>40000) {
-               &logthis("<font color=blue>WARNING: Buffer for ".$crsid.
+               &logthis("<font color=\"blue\">WARNING: Buffer for ".$crsid.
                         " exceeded maximum size, deleting.</font>");
                delete $courselogs{$crsid};
             }
@@ -1610,6 +1613,31 @@ sub flushcourselogs {
 	    delete $userrolehash{$entry};
         }
     }
+#
+# Reverse lookup of domain roles (dc, ad, li, sc, au)
+#
+    my %domrolebuffer = ();
+    foreach my $entry (keys %domainrolehash) {
+        my ($role,$uname,$udom,$runame,$rudom,$rsec)=split/:/,$entry;
+        if ($domrolebuffer{$rudom}) {
+            $domrolebuffer{$rudom}.='&'.&escape($entry).
+                      '='.&escape($domainrolehash{$entry});
+        } else {
+            $domrolebuffer{$rudom}.=&escape($entry).
+                      '='.&escape($domainrolehash{$entry});
+        }
+        delete $domainrolehash{$entry};
+    }
+    foreach my $dom (keys(%domrolebuffer)) {
+        foreach my $tryserver (keys %libserv) {
+            if ($hostdom{$tryserver} eq $dom) {
+                unless (&reply('domroleput:'.$dom.':'.
+                  $domrolebuffer{$dom},$tryserver) eq 'ok') {
+                    &logthis('Put of domain roles failed for '.$dom.' and  '.$tryserver);
+                }
+            }
+        }
+    }
     $dumpcount++;
 }
 
@@ -1643,7 +1671,7 @@ sub courseacclog {
     my $fnsymb=shift;
     unless ($env{'request.course.id'}) { return ''; }
     my $what=$fnsymb.':'.$env{'user.name'}.':'.$env{'user.domain'};
-    if ($fnsymb=~/(problem|exam|quiz|assess|survey|form|page)$/) {
+    if ($fnsymb=~/(problem|exam|quiz|assess|survey|form|task|page)$/) {
         $what.=':POST';
         # FIXME: Probably ought to escape things....
 	foreach (keys %env) {
@@ -1685,14 +1713,24 @@ sub linklog {
   
 sub userrolelog {
     my ($trole,$username,$domain,$area,$tstart,$tend)=@_;
-    if (($trole=~/^ca/) || ($trole=~/^in/) || 
-        ($trole=~/^cc/) || ($trole=~/^ep/) ||
-        ($trole=~/^cr/) || ($trole=~/^ta/)) {
+    if (($trole=~/^ca/) || ($trole=~/^aa/) ||
+        ($trole=~/^in/) || ($trole=~/^cc/) ||
+        ($trole=~/^ep/) || ($trole=~/^cr/) ||
+        ($trole=~/^ta/)) {
        my (undef,$rudom,$runame,$rsec)=split(/\//,$area);
        $userrolehash
          {$trole.':'.$username.':'.$domain.':'.$runame.':'.$rudom.':'.$rsec}
                     =$tend.':'.$tstart;
-   }
+    }
+    if (($trole=~/^dc/) || ($trole=~/^ad/) ||
+        ($trole=~/^li/) || ($trole=~/^li/) ||
+        ($trole=~/^au/) || ($trole=~/^dg/) ||
+        ($trole=~/^sc/)) {
+       my (undef,$rudom,$runame,$rsec)=split(/\//,$area);
+       $domainrolehash
+         {$trole.':'.$username.':'.$domain.':'.$runame.':'.$rudom.':'.$rsec}
+                    = $tend.':'.$tstart;
+    }
 }
 
 sub get_course_adv_roles {
@@ -1811,7 +1849,65 @@ sub courseiddump {
     return %returnhash;
 }
 
-#
+# ---------------------------------------------------------- DC e-mail
+
+sub dcmailput {
+    my ($domain,$msgid,$contents,$server)=@_;
+    my $status = &Apache::lonnet::critical(
+       'dcmailput:'.$domain.':'.&Apache::lonnet::escape($msgid).'='.
+       &Apache::lonnet::escape($$contents{$server}),$server);
+    return $status;
+}
+
+sub dcmaildump {
+    my ($dom,$startdate,$enddate,$senders) = @_;
+    my %returnhash=(); 
+    foreach my $tryserver (keys(%libserv)) {
+        if ($hostdom{$tryserver} eq $dom) {
+            %{$returnhash{$tryserver}}=();
+	    my $cmd='dcmaildump:'.$dom.':'.
+		&escape($startdate).':'.&escape($enddate).':';
+	    my @esc_senders=map { &escape($_)} @$senders;
+	    $cmd.=&escape(join('&',@esc_senders));
+	    foreach (split(/\&/,&reply($cmd,$tryserver))) {
+                my ($key,$value) = split(/\=/,$_);
+                if (($key) && ($value)) {
+                    $returnhash{$tryserver}{&unescape($key)} = &unescape($value);
+                }
+            }
+        }
+    }
+    return %returnhash;
+}
+# ---------------------------------------------------------- Domain roles
+
+sub get_domain_roles {
+    my ($dom,$roles,$startdate,$enddate)=@_;
+    if (undef($startdate) || $startdate eq '') {
+        $startdate = '.';
+    }
+    if (undef($enddate) || $enddate eq '') {
+        $enddate = '.';
+    }
+    my $rolelist = join(':',@{$roles});
+    my %personnel = ();
+    foreach my $tryserver (keys(%libserv)) {
+        if ($hostdom{$tryserver} eq $dom) {
+            %{$personnel{$tryserver}}=();
+            foreach (
+                split(/\&/,&reply('domrolesdump:'.$dom.':'.
+                   &escape($startdate).':'.&escape($enddate).':'.
+                   &escape($rolelist), $tryserver))) {
+                my($key,$value) = split(/\=/,$_);
+                if (($key) && ($value)) {
+                    $personnel{$tryserver}{&unescape($key)} = &unescape($value);
+                }
+            }
+        }
+    }
+    return %personnel;
+}
+
 # ----------------------------------------------------------- Check out an item
 
 sub get_first_access {
@@ -1857,7 +1953,7 @@ sub checkout {
 		 $now.'&'.$ENV{'REMOTE_ADDR'});
     my $token=&reply('tmpput:'.$infostr,$lonhost);
     if ($token=~/^error\:/) { 
-        &logthis("<font color=blue>WARNING: ".
+        &logthis("<font color=\"blue\">WARNING: ".
                 "Checkout tmpput failed ".$tudom.' - '.$tuname.' - '.$symb.
                  "</font>");
         return ''; 
@@ -1873,7 +1969,7 @@ sub checkout {
     unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') {
        return '';
     } else {
-        &logthis("<font color=blue>WARNING: ".
+        &logthis("<font color=\"blue\">WARNING: ".
                 "Checkout cstore failed ".$tudom.' - '.$tuname.' - '.$symb.
                  "</font>");
     }    
@@ -1883,7 +1979,7 @@ sub checkout {
                                                  $token)) ne 'ok') {
 	return '';
     } else {
-        &logthis("<font color=blue>WARNING: ".
+        &logthis("<font color=\"blue\">WARNING: ".
                 "Checkout log failed ".$tudom.' - '.$tuname.' - '.$symb.
                  "</font>");
     }
@@ -2486,7 +2582,6 @@ sub rolesinit {
 	  if ($_!~/^rolesdef_/) {
             my ($area,$role)=split(/=/,$_);
 	    $area=~s/\_\w\w$//;
-	    
             my ($trole,$tend,$tstart);
 	    if ($role=~/^cr/) { 
 		if ($role=~m|^(cr/\w+/\w+/[a-zA-Z0-9]+)_(.*)$|) {
@@ -2510,7 +2605,7 @@ sub rolesinit {
                     &standard_roleprivs(\%allroles,$trole,$tdomain,$spec,$trest,$area);
 		}
             }
-          } 
+          }
         }
         my ($author,$adv) = &set_userprivs(\$userroles,\%allroles);
         $userroles.='user.adv='.$adv."\n".
@@ -2863,6 +2958,29 @@ sub eget {
    return %returnhash;
 }
 
+# ------------------------------------------------------------ tmpput interface
+sub tmpput {
+    my ($storehash,$server)=@_;
+    my $items='';
+    foreach (keys(%$storehash)) {
+	$items.=&escape($_).'='.&freeze_escape($$storehash{$_}).'&';
+    }
+    $items=~s/\&$//;
+    return &reply("tmpput:$items",$server);
+}
+
+# ------------------------------------------------------------ tmpget interface
+sub tmpget {
+    my ($token)=@_;
+    my $rep=&reply("tmpget:$token",$perlvar{'lonHostID'});
+    my %returnhash;
+    foreach my $item (split(/\&/,$rep)) {
+	my ($key,$value)=split(/=/,$item);
+	$returnhash{&unescape($key)}=&thaw_unescape($value);
+    }
+    return %returnhash;
+}
+
 # ---------------------------------------------- Custom access rule evaluation
 
 sub customaccess {
@@ -2984,15 +3102,30 @@ sub allowed {
        $thisallowed.=$1;
     }
 
-# URI is an uploaded document for this course
+# URI is an uploaded document for this course, default permissions don't matter
 # not allowing 'edit' access (editupload) to uploaded course docs
     if (($priv eq 'bre') && ($uri=~m|^uploaded/|)) {
-	my $refuri=$env{'httpref.'.$orguri};
-	if ($refuri) {
-	    if ($refuri =~ m|^/adm/|) {
-		$thisallowed='F';
-	    }
-	}
+	$thisallowed='';
+        my ($match)=&is_on_map($uri);
+        if ($match) {
+            if ($env{'user.priv.'.$env{'request.role'}.'./'}
+                  =~/\Q$priv\E\&([^\:]*)/) {
+                $thisallowed.=$1;
+            }
+        } else {
+            my $refuri=$env{'httpref.'.$orguri};
+            if ($refuri) {
+                if ($refuri =~ m|^/adm/|) {
+                    $thisallowed='F';
+                } else {
+                    $refuri=&declutter($refuri);
+                    my ($match) = &is_on_map($refuri);
+                    if ($match) {
+                        $thisallowed='F';
+                    }
+                }
+            }
+        }
     }
 
 # Full access at system, domain or course-wide level? Exit.
@@ -3160,7 +3293,7 @@ sub allowed {
        my $unamedom=$env{'user.name'}.':'.$env{'user.domain'};
        if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.roles.denied'}
 	   =~/\Q$rolecode\E/) {
-           &log($env{'user.domain'},$env{'user.name'},$env{'user.host'},
+           &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'.
                 'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode.' in '.
                 $env{'request.course.id'});
            return '';
@@ -3168,7 +3301,7 @@ sub allowed {
 
        if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.users.denied'}
 	   =~/\Q$unamedom\E/) {
-           &log($env{'user.domain'},$env{'user.name'},$env{'user.host'},
+           &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.
                 'Denied by user: '.$priv.' for '.$uri.' as '.$unamedom.' in '.
                 $env{'request.course.id'});
            return '';
@@ -3180,8 +3313,8 @@ sub allowed {
    if ($thisallowed=~/R/) {
        my $rolecode=(split(/\./,$env{'request.role'}))[0];
        if (&metadata($uri,'roledeny')=~/\Q$rolecode\E/) {
-	  &log($env{'user.domain'},$env{'user.name'},$env{'user.host'},
-                    'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode);
+	   &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'.
+		'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode);
           return '';
        }
    }
@@ -3208,8 +3341,7 @@ sub allowed {
 # --------------------------------------------------- Is a resource on the map?
 
 sub is_on_map {
-    my $uri=&declutter(shift);
-    $uri=~s/\.\d+\.(\w+)$/\.$1/;
+    my $uri=&deversion(&declutter(shift));
     my @uriparts=split(/\//,$uri);
     my $filename=$uriparts[$#uriparts];
     my $pathname=$uri;
@@ -3579,7 +3711,7 @@ sub assignrole {
     my $answer=&reply($command,&homeserver($uname,$udom));
 # log new user role if status is ok
     if ($answer eq 'ok') {
-	&userrolelog($mrole,$uname,$udom,$url,$start,$end);
+	&userrolelog($role,$uname,$udom,$url,$start,$end);
     }
     return $answer;
 }
@@ -3842,7 +3974,9 @@ sub createcourse {
         return 'refused';
     }
 # ------------------------------------------------------------------- Create ID
-   my $uname=substr($$.time,0,5).unpack("H8",pack("I32",time)).
+   my $uname=int(1+rand(9)).
+       ('a'..'z','A'..'Z','0'..'9')[int(rand(62))].
+       substr($$.time,0,5).unpack("H8",pack("I32",time)).
        unpack("H2",pack("I32",int(rand(255)))).$perlvar{'lonHostID'};
 # ----------------------------------------------- Make sure that does not exist
    my $uhome=&homeserver($uname,$udom,'true');
@@ -4350,7 +4484,7 @@ sub get_userresdata {
     }
     #error 2 occurs when the .db doesn't exist
     if ($tmp!~/error: 2 /) {
-	&logthis("<font color=blue>WARNING:".
+	&logthis("<font color=\"blue\">WARNING:".
 		 " Trying to get resource data for ".
 		 $uname." at ".$udom.": ".
 		 $tmp."</font>");
@@ -5245,8 +5379,37 @@ sub numval3 {
     return $total;
 }
 
+sub digest {
+    my ($data)=@_;
+    my $digest=&Digest::MD5::md5($data);
+    my ($a,$b,$c,$d)=unpack("iiii",$digest);
+    my ($e,$f);
+    {
+        use integer;
+        $e=($a+$b);
+        $f=($c+$d);
+        if ($_64bit) {
+            $e=(($e<<32)>>32);
+            $f=(($f<<32)>>32);
+        }
+    }
+    if (wantarray) {
+	return ($e,$f);
+    } else {
+	my $g;
+	{
+	    use integer;
+	    $g=($e+$f);
+	    if ($_64bit) {
+		$g=(($g<<32)>>32);
+	    }
+	}
+	return $g;
+    }
+}
+
 sub latest_rnd_algorithm_id {
-    return '64bit4';
+    return '64bit5';
 }
 
 sub get_rand_alg {
@@ -5286,11 +5449,15 @@ sub rndseed {
     if (!$username) { $username=$wusername }
     my $which=&get_rand_alg();
     if (defined(&getCODE())) {
-	if ($which eq '64bit4') {
+	if ($which eq '64bit5') {
+	    return &rndseed_CODE_64bit5($symb,$courseid,$domain,$username);
+	} elsif ($which eq '64bit4') {
 	    return &rndseed_CODE_64bit4($symb,$courseid,$domain,$username);
 	} else {
 	    return &rndseed_CODE_64bit($symb,$courseid,$domain,$username);
 	}
+    } elsif ($which eq '64bit5') {
+	return &rndseed_64bit5($symb,$courseid,$domain,$username);
     } elsif ($which eq '64bit4') {
 	return &rndseed_64bit4($symb,$courseid,$domain,$username);
     } elsif ($which eq '64bit3') {
@@ -5413,6 +5580,12 @@ sub rndseed_64bit4 {
     }
 }
 
+sub rndseed_64bit5 {
+    my ($symb,$courseid,$domain,$username)=@_;
+    my ($num1,$num2)=&digest("$symb,$courseid,$domain,$username");
+    return "$num1:$num2";
+}
+
 sub rndseed_CODE_64bit {
     my ($symb,$courseid,$domain,$username)=@_;
     {
@@ -5451,6 +5624,13 @@ sub rndseed_CODE_64bit4 {
     }
 }
 
+sub rndseed_CODE_64bit5 {
+    my ($symb,$courseid,$domain,$username)=@_;
+    my $code = &getCODE();
+    my ($num1,$num2)=&digest("$symb,$courseid,$code");
+    return "$num1:$num2";
+}
+
 sub setup_random_from_rndseed {
     my ($rndseed)=@_;
     if ($rndseed =~/([,:])/) {
@@ -5695,14 +5875,15 @@ sub filelocation {
 sub hreflocation {
     my ($dir,$file)=@_;
     unless (($file=~m-^http://-i) || ($file=~m-^/-)) {
-	my $finalpath=filelocation($dir,$file);
-	$finalpath=~s-^/home/httpd/html--;
-	$finalpath=~s-^/home/(\w+)/public_html/-/~$1/-;
-	return $finalpath;
-    } elsif ($file=~m-^/home-) {
-	$file=~s-^/home/httpd/html--;
+	$file=filelocation($dir,$file);
+    }
+    if ($file=~m-^\Q$perlvar{'lonDocRoot'}\E-) {
+	$file=~s-^\Q$perlvar{'lonDocRoot'}\E--;
+    } elsif ($file=~m-/home/(\w+)/public_html/-) {
 	$file=~s-^/home/(\w+)/public_html/-/~$1/-;
-	return $file;
+    } elsif ($file=~m-^\Q$perlvar{'lonUsersDir'}\E-) {
+	$file=~s-^/home/httpd/lonUsers/([^/]*)/./././([^/]*)/userfiles/
+	    -/uploaded/$1/$2/-x;
     }
     return $file;
 }
@@ -5993,7 +6174,7 @@ $processmarker='_'.time.'_'.$perlvar{'lo
 $dumpcount=0;
 
 &logtouch();
-&logthis('<font color=yellow>INFO: Read configuration</font>');
+&logthis('<font color="yellow">INFO: Read configuration</font>');
 $readit=1;
     {
 	use integer;