WARNING: ".
+ 'Could not obtain exclusive lock in delenv: '.$!);
+ $fh->close();
+ return 'error: '.$!;
+ }
map {
unless ($_=~/^$delthis/) { print $fh $_; }
} @oldenv;
@@ -316,6 +437,44 @@ sub spareserver {
return $spareserver;
}
+# ----------------------- Try to determine user's current authentication scheme
+
+sub queryauthenticate {
+ my ($uname,$udom)=@_;
+ if (($perlvar{'lonRole'} eq 'library') &&
+ ($udom eq $perlvar{'lonDefDomain'})) {
+ my $answer=reply("encrypt:currentauth:$udom:$uname",
+ $perlvar{'lonHostID'});
+ unless ($answer eq 'unknown_user' or $answer eq 'refused') {
+ if (length($answer)) {
+ return $answer;
+ }
+ else {
+ &logthis("User $uname at $udom lacks an authentication mechanism");
+ return 'no_host';
+ }
+ }
+ }
+
+ my $tryserver;
+ foreach $tryserver (keys %libserv) {
+ if ($hostdom{$tryserver} eq $udom) {
+ my $answer=reply("encrypt:currentauth:$udom:$uname",$tryserver);
+ unless ($answer eq 'unknown_user' or $answer eq 'refused') {
+ if (length($answer)) {
+ return $answer;
+ }
+ else {
+ &logthis("User $uname at $udom lacks an authentication mechanism");
+ return 'no_host';
+ }
+ }
+ }
+ }
+ &logthis("User $uname at $udom lacks an authentication mechanism");
+ return 'no_host';
+}
+
# --------- Try to authenticate user from domain's lib servers (first this one)
sub authenticate {
@@ -588,52 +747,394 @@ sub log {
return critical("log:$dom:$nam:$what",$hom);
}
+# ------------------------------------------------------------------ Course Log
+
+sub flushcourselogs {
+ &logthis('Flushing course log buffers');
+ map {
+ my $crsid=$_;
+ if (&reply('log:'.$ENV{'course.'.$crsid.'.domain'}.':'.
+ $ENV{'course.'.$crsid.'.num'}.':'.
+ &escape($courselogs{$crsid}),
+ $ENV{'course.'.$crsid.'.home'}) eq 'ok') {
+ delete $courselogs{$crsid};
+ } else {
+ &logthis('Failed to flush log buffer for '.$crsid);
+ if (length($courselogs{$crsid})>40000) {
+ &logthis("WARNING: Buffer for ".$crsid.
+ " exceeded maximum size, deleting.");
+ delete $courselogs{$crsid};
+ }
+ }
+ } keys %courselogs;
+}
+
+sub courselog {
+ my $what=shift;
+ $what=time.':'.$what;
+ unless ($ENV{'request.course.id'}) { return ''; }
+ if (defined $courselogs{$ENV{'request.course.id'}}) {
+ $courselogs{$ENV{'request.course.id'}}.='&'.$what;
+ } else {
+ $courselogs{$ENV{'request.course.id'}}.=$what;
+ }
+ if (length($courselogs{$ENV{'request.course.id'}})>4048) {
+ &flushcourselogs();
+ }
+}
+
+sub courseacclog {
+ my $fnsymb=shift;
+ unless ($ENV{'request.course.id'}) { return ''; }
+ my $what=$fnsymb.':'.$ENV{'user.name'}.':'.$ENV{'user.domain'};
+ if ($what=~/(problem|exam|quiz|assess|survey|form)$/) {
+ map {
+ if ($_=~/^form\.(.*)/) {
+ $what.=':'.$1.'='.$ENV{$_};
+ }
+ } keys %ENV;
+ }
+ &courselog($what);
+}
+
+# ----------------------------------------------------------- Check out an item
+
+sub checkout {
+ my ($symb,$tuname,$tudom,$tcrsid)=@_;
+ my $now=time;
+ my $lonhost=$perlvar{'lonHostID'};
+ my $infostr=&escape(
+ $tuname.'&'.
+ $tudom.'&'.
+ $tcrsid.'&'.
+ $symb.'&'.
+ $now.'&'.$ENV{'REMOTE_ADDR'});
+ my $token=&reply('tmpput:'.$infostr,$lonhost);
+ if ($token=~/^error\:/) {
+ &logthis("WARNING: ".
+ "Checkout tmpput failed ".$tudom.' - '.$tuname.' - '.$symb.
+ "");
+ return '';
+ }
+
+ $token=~s/^(\d+)\_.*\_(\d+)$/$1\*$2\*$lonhost/;
+ $token=~tr/a-z/A-Z/;
+
+ my %infohash=('resource.0.outtoken' => $token,
+ 'resource.0.checkouttime' => $now,
+ 'resource.0.outremote' => $ENV{'REMOTE_ADDR'});
+
+ unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') {
+ return '';
+ } else {
+ &logthis("WARNING: ".
+ "Checkout cstore failed ".$tudom.' - '.$tuname.' - '.$symb.
+ "");
+ }
+
+ if (&log($tudom,$tuname,&homeserver($tuname,$tudom),
+ &escape('Checkout '.$infostr.' - '.
+ $token)) ne 'ok') {
+ return '';
+ } else {
+ &logthis("WARNING: ".
+ "Checkout log failed ".$tudom.' - '.$tuname.' - '.$symb.
+ "");
+ }
+ return $token;
+}
+
+# ------------------------------------------------------------ Check in an item
+
+sub checkin {
+ my $token=shift;
+ my $now=time;
+ my ($ta,$tb,$lonhost)=split(/\*/,$token);
+ $lonhost=~tr/A-Z/a-z/;
+ my $dtoken=$ta.'_'.$hostip{$lonhost}.'_'.$tb;
+ $dtoken=~s/\W/\_/g;
+ my ($tuname,$tudom,$tcrsid,$symb,$chtim,$rmaddr)=
+ split(/\&/,&unescape(&reply('tmpget:'.$dtoken,$lonhost)));
+
+ unless (($tuname) && ($tudom)) {
+ &logthis('Check in '.$token.' ('.$dtoken.') failed');
+ return '';
+ }
+
+ unless (&allowed('mgr',$tcrsid)) {
+ &logthis('Check in '.$token.' ('.$dtoken.') unauthorized: '.
+ $ENV{'user.name'}.' - '.$ENV{'user.domain'});
+ return '';
+ }
+
+ my %infohash=('resource.0.intoken' => $token,
+ 'resource.0.checkintime' => $now,
+ 'resource.0.inremote' => $ENV{'REMOTE_ADDR'});
+
+ unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') {
+ return '';
+ }
+
+ if (&log($tudom,$tuname,&homeserver($tuname,$tudom),
+ &escape('Checkin - '.$token)) ne 'ok') {
+ return '';
+ }
+
+ return ($symb,$tuname,$tudom,$tcrsid);
+}
+
+# --------------------------------------------- Set Expire Date for Spreadsheet
+
+sub expirespread {
+ my ($uname,$udom,$stype,$usymb)=@_;
+ my $cid=$ENV{'request.course.id'};
+ if ($cid) {
+ my $now=time;
+ my $key=$uname.':'.$udom.':'.$stype.':'.$usymb;
+ return &reply('put:'.$ENV{'course.'.$cid.'.domain'}.':'.
+ $ENV{'course.'.$cid.'.num'}.
+ ':nohist_expirationdates:'.
+ &escape($key).'='.$now,
+ $ENV{'course.'.$cid.'.home'})
+ }
+ return 'ok';
+}
+
+# ----------------------------------------------------- Devalidate Spreadsheets
+
+sub devalidate {
+ my $symb=shift;
+ my $cid=$ENV{'request.course.id'};
+ if ($cid) {
+ my $key=$ENV{'user.name'}.':'.$ENV{'user.domain'}.':';
+ my $status=
+ &del('nohist_calculatedsheet',
+ [$key.'studentcalc'],
+ $ENV{'course.'.$cid.'.domain'},
+ $ENV{'course.'.$cid.'.num'})
+ .' '.
+ &del('nohist_calculatedsheets_'.$cid,
+ [$key.'assesscalc:'.$symb]);
+ unless ($status eq 'ok ok') {
+ &logthis('Could not devalidate spreadsheet '.
+ $ENV{'user.name'}.' at '.$ENV{'user.domain'}.' for '.
+ $symb.': '.$status);
+ }
+ }
+}
+
+sub hash2str {
+ my (%hash)=@_;
+ my $result='';
+ map { $result.=escape($_).'='.escape($hash{$_}).'&'; } keys %hash;
+ $result=~s/\&$//;
+ return $result;
+}
+
+sub str2hash {
+ my ($string) = @_;
+ my %returnhash;
+ map {
+ my ($name,$value)=split(/\=/,$_);
+ $returnhash{&unescape($name)}=&unescape($value);
+ } split(/\&/,$string);
+ return %returnhash;
+}
+
+# -------------------------------------------------------------------Temp Store
+
+sub tmpreset {
+ my ($symb,$namespace,$domain,$stuname) = @_;
+ if (!$symb) {
+ $symb=&symbread();
+ if (!$symb) { $symb= $ENV{'REQUEST_URI'}; }
+ }
+ $symb=escape($symb);
+
+ if (!$namespace) { $namespace=$ENV{'request.state'}; }
+ $namespace=~s/\//\_/g;
+ $namespace=~s/\W//g;
+
+ #FIXME needs to do something for /pub resources
+ if (!$domain) { $domain=$ENV{'user.domain'}; }
+ if (!$stuname) { $stuname=$ENV{'user.name'}; }
+ my $path=$perlvar{'lonDaemons'}.'/tmp';
+ my %hash;
+ if (tie(%hash,'GDBM_File',
+ $path.'/tmpstore_'.$stuname.'_'.$domain.'_'.$namespace.'.db',
+ &GDBM_WRCREAT,0640)) {
+ foreach my $key (keys %hash) {
+ if ($key=~ /:$symb/) {
+ delete($hash{$key});
+ }
+ }
+ }
+}
+
+sub tmpstore {
+ my ($storehash,$symb,$namespace,$domain,$stuname) = @_;
+
+ if (!$symb) {
+ $symb=&symbread();
+ if (!$symb) { $symb= $ENV{'request.url'}; }
+ }
+ $symb=escape($symb);
+
+ if (!$namespace) {
+ # I don't think we would ever want to store this for a course.
+ # it seems this will only be used if we don't have a course.
+ #$namespace=$ENV{'request.course.id'};
+ #if (!$namespace) {
+ $namespace=$ENV{'request.state'};
+ #}
+ }
+ $namespace=~s/\//\_/g;
+ $namespace=~s/\W//g;
+#FIXME needs to do something for /pub resources
+ if (!$domain) { $domain=$ENV{'user.domain'}; }
+ if (!$stuname) { $stuname=$ENV{'user.name'}; }
+ my $now=time;
+ my %hash;
+ my $path=$perlvar{'lonDaemons'}.'/tmp';
+ if (tie(%hash,'GDBM_File',
+ $path.'/tmpstore_'.$stuname.'_'.$domain.'_'.$namespace.'.db',
+ &GDBM_WRCREAT,0640)) {
+ $hash{"version:$symb"}++;
+ my $version=$hash{"version:$symb"};
+ my $allkeys='';
+ foreach my $key (keys(%$storehash)) {
+ $allkeys.=$key.':';
+ $hash{"$version:$symb:$key"}=$$storehash{$key};
+ }
+ $hash{"$version:$symb:timestamp"}=$now;
+ $allkeys.='timestamp';
+ $hash{"$version:keys:$symb"}=$allkeys;
+ if (untie(%hash)) {
+ return 'ok';
+ } else {
+ return "error:$!";
+ }
+ } else {
+ return "error:$!";
+ }
+}
+
+# -----------------------------------------------------------------Temp Restore
+
+sub tmprestore {
+ my ($symb,$namespace,$domain,$stuname) = @_;
+
+ if (!$symb) {
+ $symb=&symbread();
+ if (!$symb) { $symb= $ENV{'request.url'}; }
+ }
+ $symb=escape($symb);
+
+ if (!$namespace) { $namespace=$ENV{'request.state'}; }
+ #FIXME needs to do something for /pub resources
+ if (!$domain) { $domain=$ENV{'user.domain'}; }
+ if (!$stuname) { $stuname=$ENV{'user.name'}; }
+
+ my %returnhash;
+ $namespace=~s/\//\_/g;
+ $namespace=~s/\W//g;
+ my %hash;
+ my $path=$perlvar{'lonDaemons'}.'/tmp';
+ if (tie(%hash,'GDBM_File',
+ $path.'/tmpstore_'.$stuname.'_'.$domain.'_'.$namespace.'.db',
+ &GDBM_READER,0640)) {
+ my $version=$hash{"version:$symb"};
+ $returnhash{'version'}=$version;
+ my $scope;
+ for ($scope=1;$scope<=$version;$scope++) {
+ my $vkeys=$hash{"$scope:keys:$symb"};
+ my @keys=split(/:/,$vkeys);
+ my $key;
+ $returnhash{"$scope:keys"}=$vkeys;
+ foreach $key (@keys) {
+ $returnhash{"$scope:$key"}=$hash{"$scope:$symb:$key"};
+ $returnhash{"$key"}=$hash{"$scope:$symb:$key"};
+ }
+ }
+ if (!(untie(%hash))) {
+ return "error:$!";
+ }
+ } else {
+ return "error:$!";
+ }
+ return %returnhash;
+}
+
# ----------------------------------------------------------------------- Store
sub store {
- my %storehash=@_;
- my $symb;
- unless ($symb=escape(&symbread())) { return ''; }
- my $namespace;
- unless ($namespace=$ENV{'request.course.id'}) { return ''; }
+ my ($storehash,$symb,$namespace,$domain,$stuname) = @_;
+ my $home='';
+
+ if ($stuname) { $home=&homeserver($stuname,$domain); }
+
+ if (!$symb) { unless ($symb=&symbread()) { return ''; } }
+
+ &devalidate($symb);
+
+ $symb=escape($symb);
+ if (!$namespace) { unless ($namespace=$ENV{'request.course.id'}) { return ''; } }
+ if (!$domain) { $domain=$ENV{'user.domain'}; }
+ if (!$stuname) { $stuname=$ENV{'user.name'}; }
+ if (!$home) { $home=$ENV{'user.home'}; }
my $namevalue='';
map {
- $namevalue.=escape($_).'='.escape($storehash{$_}).'&';
- } keys %storehash;
+ $namevalue.=escape($_).'='.escape($$storehash{$_}).'&';
+ } keys %$storehash;
$namevalue=~s/\&$//;
- return reply(
- "store:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$symb:$namevalue",
- "$ENV{'user.home'}");
+ return reply("store:$domain:$stuname:$namespace:$symb:$namevalue","$home");
}
# -------------------------------------------------------------- Critical Store
sub cstore {
- my %storehash=@_;
- my $symb;
- unless ($symb=escape(&symbread())) { return ''; }
- my $namespace;
- unless ($namespace=$ENV{'request.course.id'}) { return ''; }
+ my ($storehash,$symb,$namespace,$domain,$stuname) = @_;
+ my $home='';
+
+ if ($stuname) { $home=&homeserver($stuname,$domain); }
+
+ if (!$symb) { unless ($symb=&symbread()) { return ''; } }
+
+ &devalidate($symb);
+
+ $symb=escape($symb);
+ if (!$namespace) { unless ($namespace=$ENV{'request.course.id'}) { return ''; } }
+ if (!$domain) { $domain=$ENV{'user.domain'}; }
+ if (!$stuname) { $stuname=$ENV{'user.name'}; }
+ if (!$home) { $home=$ENV{'user.home'}; }
+
my $namevalue='';
map {
- $namevalue.=escape($_).'='.escape($storehash{$_}).'&';
- } keys %storehash;
+ $namevalue.=escape($_).'='.escape($$storehash{$_}).'&';
+ } keys %$storehash;
$namevalue=~s/\&$//;
- return critical(
- "store:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$symb:$namevalue",
- "$ENV{'user.home'}");
+ return critical("store:$domain:$stuname:$namespace:$symb:$namevalue","$home");
}
# --------------------------------------------------------------------- Restore
sub restore {
- my $symb;
- unless ($symb=escape(&symbread())) { return ''; }
- my $namespace;
- unless ($namespace=$ENV{'request.course.id'}) { return ''; }
- my $answer=reply(
- "restore:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$symb",
- "$ENV{'user.home'}");
+ my ($symb,$namespace,$domain,$stuname) = @_;
+ my $home='';
+
+ if ($stuname) { $home=&homeserver($stuname,$domain); }
+
+ if (!$symb) {
+ unless ($symb=escape(&symbread())) { return ''; }
+ } else {
+ $symb=&escape($symb);
+ }
+ if (!$namespace) { unless ($namespace=$ENV{'request.course.id'}) { return ''; } }
+ if (!$domain) { $domain=$ENV{'user.domain'}; }
+ if (!$stuname) { $stuname=$ENV{'user.name'}; }
+ if (!$home) { $home=$ENV{'user.home'}; }
+ my $answer=&reply("restore:$domain:$stuname:$namespace:$symb","$home");
+
my %returnhash=();
map {
my ($name,$value)=split(/\=/,$_);
@@ -655,23 +1156,18 @@ sub coursedescription {
$courseid=~s/^\///;
$courseid=~s/\_/\//g;
my ($cdomain,$cnum)=split(/\//,$courseid);
- my $chome=homeserver($cnum,$cdomain);
+ my $chome=&homeserver($cnum,$cdomain);
if ($chome ne 'no_host') {
- my $rep=reply("dump:$cdomain:$cnum:environment",$chome);
- if ($rep ne 'con_lost') {
- my $normalid=$courseid;
- $normalid=~s/\//\_/g;
+ my %returnhash=&dump('environment',$cdomain,$cnum);
+ if (!exists($returnhash{'con_lost'})) {
+ my $normalid=$cdomain.'_'.$cnum;
my %envhash=();
- my %returnhash=('home' => $chome,
- 'domain' => $cdomain,
- 'num' => $cnum);
- map {
- my ($name,$value)=split(/\=/,$_);
- $name=&unescape($name);
- $value=&unescape($value);
- $returnhash{$name}=$value;
+ $returnhash{'home'}= $chome;
+ $returnhash{'domain'} = $cdomain;
+ $returnhash{'num'} = $cnum;
+ while (my ($name,$value) = each %returnhash) {
$envhash{'course.'.$normalid.'.'.$name}=$value;
- } split(/\&/,$rep);
+ }
$returnhash{'url'}='/res/'.declutter($returnhash{'url'});
$returnhash{'fn'}=$perlvar{'lonDaemons'}.'/tmp/'.
$ENV{'user.name'}.'_'.$cdomain.'_'.$cnum;
@@ -686,7 +1182,7 @@ sub coursedescription {
return ();
}
-# -------------------------------------------------------- Get user priviledges
+# -------------------------------------------------------- Get user privileges
sub rolesinit {
my ($domain,$username,$authhost)=@_;
@@ -756,16 +1252,20 @@ sub rolesinit {
}
}
} split(/&/,$rolesdump);
+ my $adv=0;
+ my $author=0;
map {
%thesepriv=();
+ if (($_!~/^st/) && ($_!~/^ta/) && ($_!~/^cm/)) { $adv=1; }
+ if (($_=~/^au/) || ($_=~/^ca/)) { $author=1; }
map {
if ($_ ne '') {
- my ($priviledge,$restrictions)=split(/&/,$_);
+ my ($privilege,$restrictions)=split(/&/,$_);
if ($restrictions eq '') {
- $thesepriv{$priviledge}='F';
+ $thesepriv{$privilege}='F';
} else {
- if ($thesepriv{$priviledge} ne 'F') {
- $thesepriv{$priviledge}.=$restrictions;
+ if ($thesepriv{$privilege} ne 'F') {
+ $thesepriv{$privilege}.=$restrictions;
}
}
}
@@ -774,6 +1274,9 @@ sub rolesinit {
map { $thesestr.=':'.$_.'&'.$thesepriv{$_}; } keys %thesepriv;
$userroles.='user.priv.'.$_.'='.$thesestr."\n";
} keys %allroles;
+ $userroles.='user.adv='.$adv."\n".
+ 'user.author='.$author."\n";
+ $ENV{'user.adv'}=$adv;
}
return $userroles;
}
@@ -781,43 +1284,51 @@ sub rolesinit {
# --------------------------------------------------------------- get interface
sub get {
- my ($namespace,@storearr)=@_;
+ my ($namespace,$storearr,$udomain,$uname)=@_;
my $items='';
map {
$items.=escape($_).'&';
- } @storearr;
+ } @$storearr;
$items=~s/\&$//;
- my $rep=reply("get:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$items",
- $ENV{'user.home'});
+ if (!$udomain) { $udomain=$ENV{'user.domain'}; }
+ if (!$uname) { $uname=$ENV{'user.name'}; }
+ my $uhome=&homeserver($uname,$udomain);
+
+ my $rep=&reply("get:$udomain:$uname:$namespace:$items",$uhome);
my @pairs=split(/\&/,$rep);
my %returnhash=();
my $i=0;
map {
$returnhash{$_}=unescape($pairs[$i]);
$i++;
- } @storearr;
+ } @$storearr;
return %returnhash;
}
# --------------------------------------------------------------- del interface
sub del {
- my ($namespace,@storearr)=@_;
+ my ($namespace,$storearr,$udomain,$uname)=@_;
my $items='';
map {
$items.=escape($_).'&';
- } @storearr;
+ } @$storearr;
$items=~s/\&$//;
- return reply("del:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$items",
- $ENV{'user.home'});
+ if (!$udomain) { $udomain=$ENV{'user.domain'}; }
+ if (!$uname) { $uname=$ENV{'user.name'}; }
+ my $uhome=&homeserver($uname,$udomain);
+
+ return &reply("del:$udomain:$uname:$namespace:$items",$uhome);
}
# -------------------------------------------------------------- dump interface
sub dump {
- my $namespace=shift;
- my $rep=reply("dump:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace",
- $ENV{'user.home'});
+ my ($namespace,$udomain,$uname)=@_;
+ if (!$udomain) { $udomain=$ENV{'user.domain'}; }
+ if (!$uname) { $uname=$ENV{'user.name'}; }
+ my $uhome=&homeserver($uname,$udomain);
+ my $rep=reply("dump:$udomain:$uname:$namespace",$uhome);
my @pairs=split(/\&/,$rep);
my %returnhash=();
map {
@@ -830,55 +1341,62 @@ sub dump {
# --------------------------------------------------------------- put interface
sub put {
- my ($namespace,%storehash)=@_;
+ my ($namespace,$storehash,$udomain,$uname)=@_;
+ if (!$udomain) { $udomain=$ENV{'user.domain'}; }
+ if (!$uname) { $uname=$ENV{'user.name'}; }
+ my $uhome=&homeserver($uname,$udomain);
my $items='';
map {
- $items.=escape($_).'='.escape($storehash{$_}).'&';
- } keys %storehash;
+ $items.=&escape($_).'='.&escape($$storehash{$_}).'&';
+ } keys %$storehash;
$items=~s/\&$//;
- return reply("put:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$items",
- $ENV{'user.home'});
+ return &reply("put:$udomain:$uname:$namespace:$items",$uhome);
}
# ------------------------------------------------------ critical put interface
sub cput {
- my ($namespace,%storehash)=@_;
+ my ($namespace,$storehash,$udomain,$uname)=@_;
+ if (!$udomain) { $udomain=$ENV{'user.domain'}; }
+ if (!$uname) { $uname=$ENV{'user.name'}; }
+ my $uhome=&homeserver($uname,$udomain);
my $items='';
map {
- $items.=escape($_).'='.escape($storehash{$_}).'&';
- } keys %storehash;
+ $items.=escape($_).'='.escape($$storehash{$_}).'&';
+ } keys %$storehash;
$items=~s/\&$//;
- return critical
- ("put:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$items",
- $ENV{'user.home'});
+ return &critical("put:$udomain:$uname:$namespace:$items",$uhome);
}
# -------------------------------------------------------------- eget interface
sub eget {
- my ($namespace,@storearr)=@_;
+ my ($namespace,$storearr,$udomain,$uname)=@_;
my $items='';
map {
$items.=escape($_).'&';
- } @storearr;
+ } @$storearr;
$items=~s/\&$//;
- my $rep=reply("eget:$ENV{'user.domain'}:$ENV{'user.name'}:$namespace:$items",
- $ENV{'user.home'});
+ if (!$udomain) { $udomain=$ENV{'user.domain'}; }
+ if (!$uname) { $uname=$ENV{'user.name'}; }
+ my $uhome=&homeserver($uname,$udomain);
+ my $rep=&reply("eget:$udomain:$uname:$namespace:$items",$uhome);
my @pairs=split(/\&/,$rep);
my %returnhash=();
my $i=0;
map {
$returnhash{$_}=unescape($pairs[$i]);
$i++;
- } @storearr;
+ } @$storearr;
return %returnhash;
}
-# ------------------------------------------------- Check for a user priviledge
+# ------------------------------------------------- Check for a user privilege
sub allowed {
my ($priv,$uri)=@_;
+
+ my $orguri=$uri;
$uri=&declutter($uri);
# Free bre access to adm and meta resources
@@ -887,6 +1405,12 @@ sub allowed {
return 'F';
}
+# Free bre to public access
+
+ if ($priv eq 'bre') {
+ if (&metadata($uri,'copyright') eq 'public') { return 'F'; }
+ }
+
my $thisallowed='';
my $statecond=0;
my $courseprivid='';
@@ -922,11 +1446,11 @@ sub allowed {
# If this is generating or modifying users, exit with special codes
- if (':csu:cdc:ccc:cin:cta:cep:ccr:cst:cad:cli:cau:cdg:'=~/\:$priv\:/) {
+ if (':csu:cdc:ccc:cin:cta:cep:ccr:cst:cad:cli:cau:cdg:cca:'=~/\:$priv\:/) {
return $thisallowed;
}
#
-# Gathered so far: system, domain and course wide priviledges
+# Gathered so far: system, domain and course wide privileges
#
# Course: See if uri or referer is an individual resource that is part of
# the course
@@ -952,16 +1476,28 @@ sub allowed {
}
}
- if (($ENV{'HTTP_REFERER'}) && ($checkreferer)) {
- my $refuri=$ENV{'HTTP_REFERER'};
- $refuri=~s/^http\:\/\/$ENV{'request.host'}//i;
- $refuri=&declutter($refuri);
+ if ($checkreferer) {
+ my $refuri=$ENV{'httpref.'.$orguri};
+
+ unless ($refuri) {
+ map {
+ if ($_=~/^httpref\..*\*/) {
+ my $pattern=$_;
+ $pattern=~s/^httpref\.\/res\///;
+ $pattern=~s/\*/\[\^\/\]\+/g;
+ $pattern=~s/\//\\\//g;
+ if ($orguri=~/$pattern/) {
+ $refuri=$ENV{$_};
+ }
+ }
+ } keys %ENV;
+ }
+ if ($refuri) {
+ $refuri=&declutter($refuri);
my @uriparts=split(/\//,$refuri);
my $filename=$uriparts[$#uriparts];
my $pathname=$refuri;
$pathname=~s/\/$filename$//;
- my @filenameparts=split(/\./,$uri);
- if (&fileembstyle($filenameparts[$#filenameparts]) ne 'ssi') {
if ($ENV{'acc.res.'.$ENV{'request.course.id'}.'.'.$pathname}=~
/\&$filename\:([\d\|]+)\&/) {
my $refstatecond=$1;
@@ -971,13 +1507,13 @@ sub allowed {
$uri=$refuri;
$statecond=$refstatecond;
}
- }
}
+ }
}
}
#
-# Gathered now: all priviledges that could apply, and condition number
+# Gathered now: all privileges that could apply, and condition number
#
#
# Full or no access?
@@ -1009,6 +1545,7 @@ sub allowed {
if ($envkey=~/^user\.role\.(st|ta)\.([^\.]*)/) {
my $courseid=$2;
my $roleid=$1.'.'.$2;
+ $courseid=~s/^\///;
my $expiretime=600;
if ($ENV{'request.role'} eq $roleid) {
$expiretime=120;
@@ -1146,6 +1683,26 @@ sub definerole {
}
}
+# ---------------- Make a metadata query against the network of library servers
+
+sub metadata_query {
+ my ($query,$custom,$customshow)=@_;
+ my %rhash;
+ for my $server (keys %libserv) {
+ unless ($custom or $customshow) {
+ my $reply=&reply("querysend:".&escape($query),$server);
+ $rhash{$server}=$reply;
+ }
+ else {
+ my $reply=&reply("querysend:".&escape($query).':'.
+ &escape($custom).':'.&escape($customshow),
+ $server);
+ $rhash{$server}=$reply;
+ }
+ }
+ return \%rhash;
+}
+
# ------------------------------------------------------------------ Plain Text
sub plaintext {
@@ -1156,14 +1713,14 @@ sub plaintext {
# ------------------------------------------------------------------ Plain Text
sub fileembstyle {
- my $ending=shift;
+ my $ending=lc(shift);
return $fe{$ending};
}
# ------------------------------------------------------------ Description Text
sub filedescription {
- my $ending=shift;
+ my $ending=lc(shift);
return $fd{$ending};
}
@@ -1173,12 +1730,22 @@ sub assignrole {
my ($udom,$uname,$url,$role,$end,$start)=@_;
my $mrole;
if ($role =~ /^cr\//) {
- unless (&allowed('ccr',$url)) { return 'refused'; }
+ unless (&allowed('ccr',$url)) {
+ &logthis('Refused custom assignrole: '.
+ $udom.' '.$uname.' '.$url.' '.$role.' '.$end.' '.$start.' by '.
+ $ENV{'user.name'}.' at '.$ENV{'user.domain'});
+ return 'refused';
+ }
$mrole='cr';
} else {
my $cwosec=$url;
$cwosec=~s/^\/(\w+)\/(\w+)\/.*/$1\/$2/;
- unless (&allowed('c'.$role,$cwosec)) { return 'refused'; }
+ unless (&allowed('c'.$role,$cwosec)) {
+ &logthis('Refused assignrole: '.
+ $udom.' '.$uname.' '.$url.' '.$role.' '.$end.' '.$start.' by '.
+ $ENV{'user.name'}.' at '.$ENV{'user.domain'});
+ return 'refused';
+ }
$mrole=$role;
}
my $command="encrypt:rolesput:$ENV{'user.domain'}:$ENV{'user.name'}:".
@@ -1194,6 +1761,20 @@ sub assignrole {
return &reply($command,&homeserver($uname,$udom));
}
+# -------------------------------------------------- Modify user authentication
+sub modifyuserauth {
+ my ($udom,$uname,$umode,$upass)=@_;
+ my $uhome=&homeserver($uname,$udom);
+ &logthis('Call to modify user authentication'.$udom.', '.$uname.', '.
+ $umode.' by '.$ENV{'user.name'}.' at '.$ENV{'user.domain'});
+ my $reply=&reply('encrypt:changeuserauth:'.$udom.':'.$uname.':'.$umode.':'.
+ &escape($upass),$uhome);
+ unless ($reply eq 'ok') {
+ return 'error: '.$reply;
+ }
+ return 'ok';
+}
+
# --------------------------------------------------------------- Modify a user
@@ -1248,27 +1829,20 @@ sub modifyuser {
}
}
# -------------------------------------------------------------- Add names, etc
- my $names=&reply('get:'.$udom.':'.$uname.
- ':environment:firstname&middlename&lastname&generation',
- $uhome);
- my ($efirst,$emiddle,$elast,$egene)=split(/\&/,$names);
- if ($first) { $efirst = &escape($first); }
- if ($middle) { $emiddle = &escape($middle); }
- if ($last) { $elast = &escape($last); }
- if ($gene) { $egene = &escape($gene); }
- my $reply=&reply('put:'.$udom.':'.$uname.
- ':environment:firstname='.$efirst.
- '&middlename='.$emiddle.
- '&lastname='.$elast.
- '&generation='.$egene,$uhome);
- if ($reply ne 'ok') {
- return 'error: '.$reply;
- }
+ my %names=&get('environment',
+ ['firstname','middlename','lastname','generation'],
+ $udom,$uname);
+ if ($first) { $names{'firstname'} = $first; }
+ if ($middle) { $names{'middlename'} = $middle; }
+ if ($last) { $names{'lastname'} = $last; }
+ if ($gene) { $names{'generation'} = $gene; }
+ my $reply = &put('environment', \%names, $udom,$uname);
+ if ($reply ne 'ok') { return 'error: '.$reply; }
&logthis('Success modifying user '.$udom.', '.$uname.', '.$uid.', '.
$umode.', '.$first.', '.$middle.', '.
$last.', '.$gene.' by '.
$ENV{'user.name'}.' at '.$ENV{'user.domain'});
- return 'ok';
+ return 'ok';
}
# -------------------------------------------------------------- Modify student
@@ -1289,7 +1863,7 @@ sub modifystudent {
return 'error: no such user';
}
# -------------------------------------------------- Add student to course list
- my $reply=critical('put:'.$ENV{'course.'.$cid.'.domain'}.':'.
+ $reply=critical('put:'.$ENV{'course.'.$cid.'.domain'}.':'.
$ENV{'course.'.$cid.'.num'}.':classlist:'.
&escape($uname.':'.$udom).'='.
&escape($end.':'.$start),
@@ -1354,7 +1928,7 @@ sub createcourse {
my $reply=&reply('encrypt:makeuser:'.$udom.':'.$uname.':none::',
$ENV{'user.home'});
unless ($reply eq 'ok') { return 'error: '.$reply; }
- my $uhome=&homeserver($uname,$udom);
+ $uhome=&homeserver($uname,$udom);
if (($uhome eq '') || ($uhome eq 'no_host')) {
return 'error: no such course';
}
@@ -1493,7 +2067,7 @@ sub condval {
# --------------------------------------------------------- Value of a Variable
sub EXT {
- my $varname=shift;
+ my ($varname,$symbparm)=@_;
unless ($varname) { return ''; }
my ($realm,$space,$qualifier,@therest)=split(/\./,$varname);
my $rest;
@@ -1509,7 +2083,7 @@ sub EXT {
if ($realm eq 'user') {
# --------------------------------------------------------------- user.resource
if ($space eq 'resource') {
- my %restored=&restore;
+ my %restored=&restore();
return $restored{$qualifierrest};
# ----------------------------------------------------------------- user.access
} elsif ($space eq 'access') {
@@ -1537,7 +2111,7 @@ sub EXT {
# ---------------------------------------------------- Any other user namespace
} else {
my $item=($rest)?$qualifier.'.'.$rest:$qualifier;
- my %reply=&get($space,$item);
+ my %reply=&get($space,[$item]);
return $reply{$item};
}
} elsif ($realm eq 'request') {
@@ -1550,69 +2124,88 @@ sub EXT {
}
} elsif ($realm eq 'course') {
# ---------------------------------------------------------- course.description
- my $section='';
- if ($ENV{'request.course.sec'}) {
- $section='_'.$ENV{'request.course.sec'};
- }
- return $ENV{'course.'.$ENV{'request.course.id'}.$section.'.'.
+ return $ENV{'course.'.$ENV{'request.course.id'}.'.'.
$spacequalifierrest};
} elsif ($realm eq 'resource') {
- if ($ENV{'request.course.id'}) {
+ if ($ENV{'request.course.id'}) {
+
+# print '
'.$space.' - '.$qualifier.' - '.$spacequalifierrest;
+
+
# ----------------------------------------------------- Cascading lookup scheme
- my $symbp=&symbread();
- my $mapp=(split(/\_\_\_/,$symbp))[0];
+ my $symbp;
+ if ($symbparm) {
+ $symbp=$symbparm;
+ } else {
+ $symbp=&symbread();
+ }
+ my $mapp=(split(/\_\_\_/,$symbp))[0];
- my $symbparm=$symbp.'.'.$spacequalifierrest;
- my $mapparm=$mapp.'___(all).'.$spacequalifierrest;
+ my $symbparm=$symbp.'.'.$spacequalifierrest;
+ my $mapparm=$mapp.'___(all).'.$spacequalifierrest;
- my $seclevel=
+ my $seclevel=
$ENV{'request.course.id'}.'.['.
$ENV{'request.course.sec'}.'].'.$spacequalifierrest;
- my $seclevelr=
+ my $seclevelr=
$ENV{'request.course.id'}.'.['.
$ENV{'request.course.sec'}.'].'.$symbparm;
- my $seclevelm=
+ my $seclevelm=
$ENV{'request.course.id'}.'.['.
$ENV{'request.course.sec'}.'].'.$mapparm;
- my $courselevel=
+ my $courselevel=
$ENV{'request.course.id'}.'.'.$spacequalifierrest;
- my $courselevelr=
+ my $courselevelr=
$ENV{'request.course.id'}.'.'.$symbparm;
- my $courselevelm=
+ my $courselevelm=
$ENV{'request.course.id'}.'.'.$mapparm;
-
# ----------------------------------------------------------- first, check user
- my %resourcedata=get('resourcedata',
- ($courselevelr,$courselevelm,$courselevel));
- if ($resourcedata{$courselevelr}!~/^error\:/) {
-
- if ($resourcedata{$courselevelr}) {
- return $resourcedata{$courselevelr}; }
- if ($resourcedata{$courselevelm}) {
- return $resourcedata{$courselevelm}; }
- if ($resourcedata{$courselevel}) { return $resourcedata{$courselevel}; }
+ my %resourcedata=get('resourcedata',
+ [$courselevelr,$courselevelm,$courselevel]);
+ if (($resourcedata{$courselevelr}!~/^error\:/) &&
+ ($resourcedata{$courselevelr}!~/^con_lost/)) {
+
+ if ($resourcedata{$courselevelr}) {
+ return $resourcedata{$courselevelr}; }
+ if ($resourcedata{$courselevelm}) {
+ return $resourcedata{$courselevelm}; }
+ if ($resourcedata{$courselevel}) { return $resourcedata{$courselevel}; }
+ } else {
+ if ($resourcedata{$courselevelr}!~/No such file/) {
+ &logthis("WARNING:".
+ " Trying to get resource data for ".$ENV{'user.name'}." at "
+ .$ENV{'user.domain'}.": ".$resourcedata{$courselevelr}.
+ "");
+ }
}
+
# -------------------------------------------------------- second, check course
- my $section='';
- if ($ENV{'request.course.sec'}) {
- $section='_'.$ENV{'request.course.sec'};
- }
+
my $reply=&reply('get:'.
- $ENV{'course.'.$ENV{'request.course.id'}.$section.'.domain'}.':'.
- $ENV{'course.'.$ENV{'request.course.id'}.$section.'.num'}.
+ $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}.':'.
+ $ENV{'course.'.$ENV{'request.course.id'}.'.num'}.
':resourcedata:'.
&escape($seclevelr).'&'.&escape($seclevelm).'&'.&escape($seclevel).'&'.
&escape($courselevelr).'&'.&escape($courselevelm).'&'.&escape($courselevel),
- $ENV{'course.'.$ENV{'request.course.id'}.$section.'.home'});
+ $ENV{'course.'.$ENV{'request.course.id'}.'.home'});
if ($reply!~/^error\:/) {
map {
if ($_) { return &unescape($_); }
} split(/\&/,$reply);
}
-
+ if (($reply=~/^con_lost/) || ($reply=~/^error\:/)) {
+ &logthis("WARNING:".
+ " Getting ".$reply." asking for ".$varname." for ".
+ $ENV{'course.'.$ENV{'request.course.id'}.'.num'}.
+ ' at '.
+ $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}.
+ ' from '.
+ $ENV{'course.'.$ENV{'request.course.id'}.'.home'}.
+ "");
+ }
# ------------------------------------------------------ third, check map parms
my %parmhash=();
my $thisparm='';
@@ -1633,10 +2226,25 @@ sub EXT {
'parameter_'.$spacequalifierrest);
if ($metadata) { return $metadata; }
+# ------------------------------------------------------------------ Cascade up
+
+ unless ($space eq '0') {
+ my ($part,$id)=split(/\_/,$space);
+ if ($id) {
+ my $partgeneral=&EXT('resource.'.$part.'.'.$qualifierrest,
+ $symbparm);
+ if ($partgeneral) { return $partgeneral; }
+ } else {
+ my $resourcegeneral=&EXT('resource.0.'.$qualifierrest,
+ $symbparm);
+ if ($resourcegeneral) { return $resourcegeneral; }
+ }
+ }
+
# ---------------------------------------------------- Any other user namespace
} elsif ($realm eq 'environment') {
# ----------------------------------------------------------------- environment
- return $ENV{$spacequalifierrest};
+ return $ENV{'environment.'.$spacequalifierrest};
} elsif ($realm eq 'system') {
# ----------------------------------------------------------------- system.time
if ($space eq 'time') {
@@ -1649,31 +2257,112 @@ sub EXT {
# ---------------------------------------------------------------- Get metadata
sub metadata {
- my ($uri,$what)=@_;
+ my ($uri,$what,$liburi,$prefix,$depthcount)=@_;
$uri=&declutter($uri);
my $filename=$uri;
$uri=~s/\.meta$//;
- unless ($metacache{$uri.':keys'}) {
+#
+# Is the metadata already cached?
+# Look at timestamp of caching
+# Everything is cached by the main uri, libraries are never directly cached
+#
+ unless (abs($metacache{$uri.':cachedtimestamp'}-time)<600) {
+#
+# Is this a recursive call for a library?
+#
+ if ($liburi) {
+ $liburi=&declutter($liburi);
+ $filename=$liburi;
+ }
+ my %metathesekeys=();
unless ($filename=~/\.meta$/) { $filename.='.meta'; }
my $metastring=&getfile($perlvar{'lonDocRoot'}.'/res/'.$filename);
my $parser=HTML::TokeParser->new(\$metastring);
my $token;
+ undef %metathesekeys;
while ($token=$parser->get_token) {
if ($token->[0] eq 'S') {
- my $entry=$token->[1];
- my $unikey=$entry;
- if (defined($token->[2]->{'part'})) {
- $unikey.='_'.$token->[2]->{'part'};
+ if (defined($token->[2]->{'package'})) {
+#
+# This is a package - get package info
+#
+ my $package=$token->[2]->{'package'};
+ my $keyroot='';
+ if ($prefix) {
+ $keyroot.='_'.$prefix;
+ } else {
+ if (defined($token->[2]->{'part'})) {
+ $keyroot.='_'.$token->[2]->{'part'};
+ }
}
- if (defined($token->[2]->{'name'})) {
- $unikey.='_'.$token->[2]->{'name'};
+ if (defined($token->[2]->{'id'})) {
+ $keyroot.='_'.$token->[2]->{'id'};
+ }
+ if ($metacache{$uri.':packages'}) {
+ $metacache{$uri.':packages'}.=','.$package.$keyroot;
+ } else {
+ $metacache{$uri.':packages'}=$package.$keyroot;
}
- if ($metacache{$uri.':keys'}) {
- $metacache{$uri.':keys'}.=','.$unikey;
+ map {
+ if ($_=~/^$package\&/) {
+ my ($pack,$name,$subp)=split(/\&/,$_);
+ my $value=$packagetab{$_};
+ my $part=$keyroot;
+ $part=~s/^\_//;
+ if ($subp eq 'display') {
+ $value.=' [Part: '.$part.']';
+ }
+ my $unikey='parameter'.$keyroot.'_'.$name;
+ $metathesekeys{$unikey}=1;
+ $metacache{$uri.':'.$unikey.'.part'}=$part;
+ unless
+ (defined($metacache{$uri.':'.$unikey.'.'.$subp})) {
+ $metacache{$uri.':'.$unikey.'.'.$subp}=$value;
+ }
+ }
+ } keys %packagetab;
+ } else {
+#
+# This is not a package - some other kind of start tag
+#
+ my $entry=$token->[1];
+ my $unikey;
+ if ($entry eq 'import') {
+ $unikey='';
+ } else {
+ $unikey=$entry;
+ }
+ if ($prefix) {
+ $unikey.=$prefix;
} else {
- $metacache{$uri.':keys'}=$unikey;
+ if (defined($token->[2]->{'part'})) {
+ $unikey.='_'.$token->[2]->{'part'};
+ }
+ }
+ if (defined($token->[2]->{'id'})) {
+ $unikey.='_'.$token->[2]->{'id'};
}
+
+ if ($entry eq 'import') {
+#
+# Importing a library here
+#
+ if (defined($depthcount)) { $depthcount++; } else
+ { $depthcount=0; }
+ if ($depthcount<20) {
+ map {
+ $metathesekeys{$_}=1;
+ } split(/\,/,&metadata($uri,'keys',
+ $parser->get_text('/import'),$unikey,
+ $depthcount));
+ }
+ } else {
+
+ if (defined($token->[2]->{'name'})) {
+ $unikey.='_'.$token->[2]->{'name'};
+ }
+ $metathesekeys{$unikey}=1;
map {
$metacache{$uri.':'.$unikey.'.'.$_}=$token->[2]->{$_};
} @{$token->[3]};
@@ -1682,8 +2371,16 @@ sub metadata {
) { $metacache{$uri.':'.$unikey}=
$metacache{$uri.':'.$unikey.'.default'};
}
- }
+# end of not-a-package not-a-library import
+ }
+# end of not-a-package start tag
+ }
+# the next is the end of "start tag"
+ }
}
+ $metacache{$uri.':keys'}=join(',',keys %metathesekeys);
+ $metacache{$uri.':cachedtimestamp'}=time;
+# this is the end of "was not already recently cached
}
return $metacache{$uri.':'.$what};
}
@@ -1713,6 +2410,7 @@ sub symblist {
sub symbread {
my $thisfn=shift;
unless ($thisfn) {
+ if ($ENV{'request.symb'}) { return $ENV{'request.symb'}; }
$thisfn=$ENV{'request.filename'};
}
$thisfn=declutter($thisfn);
@@ -1793,18 +2491,27 @@ sub numval {
}
sub rndseed {
- my $symb;
- unless ($symb=&symbread()) { return time; }
- my $symbchck=unpack("%32C*",$symb);
- my $symbseed=numval($symb)%$symbchck;
- my $namechck=unpack("%32C*",$ENV{'user.name'});
- my $nameseed=numval($ENV{'user.name'})%$namechck;
- return int( $symbseed
- .$nameseed
- .unpack("%32C*",$ENV{'user.domain'})
- .unpack("%32C*",$ENV{'request.course.id'})
- .$namechck
- .$symbchck);
+ my ($symb,$courseid,$domain,$username)=@_;
+ if (!$symb) {
+ unless ($symb=&symbread()) { return time; }
+ }
+ if (!$courseid) { $courseid=$ENV{'request.course.id'};}
+ if (!$domain) {$domain=$ENV{'user.domain'};}
+ if (!$username) {$username=$ENV{'user.name'};}
+ {
+ use integer;
+ my $symbchck=unpack("%32C*",$symb) << 27;
+ my $symbseed=numval($symb) << 22;
+ my $namechck=unpack("%32C*",$username) << 17;
+ my $nameseed=numval($username) << 12;
+ my $domainseed=unpack("%32C*",$domain) << 7;
+ my $courseseed=unpack("%32C*",$courseid);
+ my $num=$symbseed+$nameseed+$domainseed+$courseseed+$namechck+$symbchck;
+ #uncommenting these lines can break things!
+ #&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
+ #&Apache::lonxml::debug("rndseed :$num:$symb");
+ return $num;
+ }
}
sub ireceipt {
@@ -1900,8 +2607,7 @@ sub unescape {
# ================================================================ Main Program
-sub BEGIN {
-if ($readit ne 'done') {
+BEGIN {
# ------------------------------------------------------------ Read access.conf
{
my $config=Apache::File->new("/etc/httpd/conf/access.conf");
@@ -1920,9 +2626,11 @@ if ($readit ne 'done') {
my $config=Apache::File->new("$perlvar{'lonTabDir'}/hosts.tab");
while (my $configline=<$config>) {
+ chomp($configline);
my ($id,$domain,$role,$name,$ip)=split(/:/,$configline);
$hostname{$id}=$name;
$hostdom{$id}=$domain;
+ $hostip{$id}=$ip;
if ($role eq 'library') { $libserv{$id}=$name; }
}
}
@@ -1944,8 +2652,10 @@ if ($readit ne 'done') {
while (my $configline=<$config>) {
chomp($configline);
+ if ($configline) {
my ($role,$perm)=split(/ /,$configline);
if ($perm ne '') { $pr{$role}=$perm; }
+ }
}
}
@@ -1955,8 +2665,25 @@ if ($readit ne 'done') {
while (my $configline=<$config>) {
chomp($configline);
+ if ($configline) {
my ($short,$plain)=split(/:/,$configline);
if ($plain ne '') { $prp{$short}=$plain; }
+ }
+ }
+}
+
+# ---------------------------------------------------------- Read package table
+{
+ my $config=Apache::File->new("$perlvar{'lonTabDir'}/packages.tab");
+
+ while (my $configline=<$config>) {
+ chomp($configline);
+ my ($short,$plain)=split(/:/,$configline);
+ my ($pack,$name)=split(/\&/,$short);
+ if ($plain ne '') {
+ $packagetab{$pack.'&'.$name.'&name'}=$name;
+ $packagetab{$short}=$plain;
+ }
}
}
@@ -1965,10 +2692,11 @@ if ($readit ne 'done') {
my $config=Apache::File->new("$perlvar{'lonTabDir'}/filetypes.tab");
while (my $configline=<$config>) {
+ next if (/^\#/);
chomp($configline);
my ($ending,$emb,@descr)=split(/\s+/,$configline);
if ($descr[0] ne '') {
- $fe{$ending}=$emb;
+ $fe{$ending}=lc($emb);
$fd{$ending}=join(' ',@descr);
}
}
@@ -1977,7 +2705,8 @@ if ($readit ne 'done') {
%metacache=();
$readit='done';
+&logtouch();
&logthis('INFO: Read configuration');
}
-}
+
1;
500 Internal Server Error
Internal Server Error
The server encountered an internal error or
misconfiguration and was unable to complete
your request.
Please contact the server administrator at
root@localhost to inform them of the time this error occurred,
and the actions you performed just before this error.
More information about this error may be available
in the server error log.