version 1.229, 2002/05/21 13:06:07
|
version 1.327, 2003/02/13 21:35:50
|
Line 47
|
Line 47
|
# 09/01 Guy Albertelli |
# 09/01 Guy Albertelli |
# 09/01,10/01,11/01 Gerd Kortemeyer |
# 09/01,10/01,11/01 Gerd Kortemeyer |
# YEAR=2001 |
# YEAR=2001 |
# 02/27/01 Scott Harrison |
|
# 3/2 Gerd Kortemeyer |
# 3/2 Gerd Kortemeyer |
# 3/15,3/19 Scott Harrison |
|
# 3/19,3/20 Gerd Kortemeyer |
# 3/19,3/20 Gerd Kortemeyer |
# 3/22,3/27,4/2,4/16,4/17 Scott Harrison |
|
# 5/26,5/28 Gerd Kortemeyer |
# 5/26,5/28 Gerd Kortemeyer |
# 5/30 H. K. Ng |
# 5/30 H. K. Ng |
# 6/1 Gerd Kortemeyer |
# 6/1 Gerd Kortemeyer |
# July Guy Albertelli |
# July Guy Albertelli |
# 8/4,8/7,8/8,8/9,8/11,8/16,8/17,8/18,8/20,8/23,9/20,9/21,9/26, |
# 8/4,8/7,8/8,8/9,8/11,8/16,8/17,8/18,8/20,8/23,9/20,9/21,9/26, |
# 10/2 Gerd Kortemeyer |
# 10/2 Gerd Kortemeyer |
# 10/5,10/10,11/13,11/15 Scott Harrison |
|
# 11/17,11/20,11/22,11/29 Gerd Kortemeyer |
# 11/17,11/20,11/22,11/29 Gerd Kortemeyer |
# 12/5 Matthew Hall |
# 12/5 Matthew Hall |
# 12/5 Guy Albertelli |
# 12/5 Guy Albertelli |
# 12/6,12/7,12/12 Gerd Kortemeyer |
# 12/6,12/7,12/12 Gerd Kortemeyer |
# 12/18 Scott Harrison |
|
# 12/21,12/22,12/27,12/28 Gerd Kortemeyer |
# 12/21,12/22,12/27,12/28 Gerd Kortemeyer |
# YEAR=2002 |
# YEAR=2002 |
# 1/4,2/4,2/7 Gerd Kortemeyer |
# 1/4,2/4,2/7 Gerd Kortemeyer |
Line 77 use Apache::File;
|
Line 72 use Apache::File;
|
use LWP::UserAgent(); |
use LWP::UserAgent(); |
use HTTP::Headers; |
use HTTP::Headers; |
use vars |
use vars |
qw(%perlvar %hostname %homecache %badhomecache %hostip %spareid %hostdom |
qw(%perlvar %hostname %homecache %badServerCache %hostip %iphost %spareid %hostdom |
%libserv %pr %prp %metacache %packagetab |
%libserv %pr %prp %metacache %packagetab %titlecache |
%courselogs %accesshash $processmarker $dumpcount |
%courselogs %accesshash $processmarker $dumpcount |
%coursedombuf %coursehombuf %courseresdatacache); |
%coursedombuf %coursehombuf %courseresdatacache |
|
%domaindescription %domain_auth_def %domain_auth_arg_def); |
use IO::Socket; |
use IO::Socket; |
use GDBM_File; |
use GDBM_File; |
use Apache::Constants qw(:common :http); |
use Apache::Constants qw(:common :http); |
use HTML::LCParser; |
use HTML::LCParser; |
use Fcntl qw(:flock); |
use Fcntl qw(:flock); |
|
use Apache::loncoursedata; |
|
|
my $readit; |
my $readit; |
|
|
# --------------------------------------------------------------------- Logging |
# --------------------------------------------------------------------- Logging |
Line 140 sub reply {
|
Line 138 sub reply {
|
unless (defined($hostname{$server})) { return 'no_such_host'; } |
unless (defined($hostname{$server})) { return 'no_such_host'; } |
my $answer=subreply($cmd,$server); |
my $answer=subreply($cmd,$server); |
if ($answer eq 'con_lost') { |
if ($answer eq 'con_lost') { |
sleep 5; |
#sleep 5; |
$answer=subreply($cmd,$server); |
#$answer=subreply($cmd,$server); |
if ($answer eq 'con_lost') { |
#if ($answer eq 'con_lost') { |
&logthis("Second attempt con_lost on $server"); |
# &logthis("Second attempt con_lost on $server"); |
my $peerfile="$perlvar{'lonSockDir'}/$server"; |
# my $peerfile="$perlvar{'lonSockDir'}/$server"; |
my $client=IO::Socket::UNIX->new(Peer =>"$peerfile", |
# my $client=IO::Socket::UNIX->new(Peer =>"$peerfile", |
Type => SOCK_STREAM, |
# Type => SOCK_STREAM, |
Timeout => 10) |
# Timeout => 10) |
or return "con_lost"; |
# or return "con_lost"; |
&logthis("Killing socket"); |
# &logthis("Killing socket"); |
print $client "close_connection_exit\n"; |
# print $client "close_connection_exit\n"; |
sleep 5; |
#sleep 5; |
$answer=subreply($cmd,$server); |
# $answer=subreply($cmd,$server); |
} |
#} |
} |
} |
if (($answer=~/^refused/) || ($answer=~/^rejected/)) { |
if (($answer=~/^refused/) || ($answer=~/^rejected/)) { |
&logthis("<font color=blue>WARNING:". |
&logthis("<font color=blue>WARNING:". |
Line 213 sub critical {
|
Line 211 sub critical {
|
$middlename=substr($middlename,0,16); |
$middlename=substr($middlename,0,16); |
$middlename=~s/\W//g; |
$middlename=~s/\W//g; |
my $dfilename= |
my $dfilename= |
"$perlvar{'lonSockDir'}/delayed/$now.$middlename.$server"; |
"$perlvar{'lonSockDir'}/delayed/$now.$dumpcount.$$.$middlename.$server"; |
|
$dumpcount++; |
{ |
{ |
my $dfh; |
my $dfh; |
if ($dfh=Apache::File->new(">$dfilename")) { |
if ($dfh=Apache::File->new(">$dfilename")) { |
Line 348 sub delenv {
|
Line 347 sub delenv {
|
return 'ok'; |
return 'ok'; |
} |
} |
|
|
|
# ------------------------------------------ Fight off request when overloaded |
|
|
|
sub overloaderror { |
|
my ($r,$checkserver)=@_; |
|
unless ($checkserver) { $checkserver=$perlvar{'lonHostID'}; } |
|
my $loadavg; |
|
if ($checkserver eq $perlvar{'lonHostID'}) { |
|
my $loadfile=Apache::File->new('/proc/loadavg'); |
|
$loadavg=<$loadfile>; |
|
$loadavg =~ s/\s.*//g; |
|
$loadavg = 100*$loadavg/$perlvar{'lonLoadLim'}; |
|
} else { |
|
$loadavg=&reply('load',$checkserver); |
|
} |
|
my $overload=$loadavg-100; |
|
if ($overload>0) { |
|
$r->err_headers_out->{'Retry-After'}=$overload; |
|
$r->log_error('Overload of '.$overload.' on '.$checkserver); |
|
return 413; |
|
} |
|
return ''; |
|
} |
|
|
# ------------------------------ Find server with least workload from spare.tab |
# ------------------------------ Find server with least workload from spare.tab |
|
|
sub spareserver { |
sub spareserver { |
|
my $loadpercent = shift; |
my $tryserver; |
my $tryserver; |
my $spareserver=''; |
my $spareserver=''; |
my $lowestserver=100; |
my $lowestserver=$loadpercent; |
foreach $tryserver (keys %spareid) { |
foreach $tryserver (keys %spareid) { |
my $answer=reply('load',$tryserver); |
my $answer=reply('load',$tryserver); |
if (($answer =~ /\d/) && ($answer<$lowestserver)) { |
if (($answer =~ /\d/) && ($answer<$lowestserver)) { |
Line 481 sub authenticate {
|
Line 504 sub authenticate {
|
# ---------------------- Find the homebase for a user from domain's lib servers |
# ---------------------- Find the homebase for a user from domain's lib servers |
|
|
sub homeserver { |
sub homeserver { |
my ($uname,$udom, $cacheBadFlag)=@_; |
my ($uname,$udom,$ignoreBadCache)=@_; |
my $index="$uname:$udom"; |
my $index="$uname:$udom"; |
if ($homecache{$index}) { |
if ($homecache{$index}) { |
return "$homecache{$index}"; |
return "$homecache{$index}"; |
} |
} |
my $tryserver; |
my $tryserver; |
foreach $tryserver (keys %libserv) { |
foreach $tryserver (keys %libserv) { |
next if ($cacheBadFlag eq 'true' && |
next if ($ignoreBadCache ne 'true' && |
exists($badhomecache{$index}->{$tryserver})); |
exists($badServerCache{$tryserver})); |
if ($hostdom{$tryserver} eq $udom) { |
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') { |
$homecache{$index}=$tryserver; |
$homecache{$index}=$tryserver; |
return $tryserver; |
return $tryserver; |
} else { |
} elsif ($answer eq 'no_host') { |
$badhomecache{$index}->{$tryserver}=1; |
$badServerCache{$tryserver}=1; |
} |
} |
} else { |
|
$badhomecache{$index}->{$tryserver}=1; |
|
} |
} |
} |
} |
return 'no_host'; |
return 'no_host'; |
Line 569 sub idput {
|
Line 590 sub idput {
|
|
|
# ------------------------------------- Find the section of student in a course |
# ------------------------------------- Find the section of student in a course |
|
|
|
sub getsection { |
|
my ($udom,$unam,$courseid)=@_; |
|
$courseid=~s/\_/\//g; |
|
$courseid=~s/^(\w)/\/$1/; |
|
my %Pending; |
|
my %Expired; |
|
# |
|
# Each role can either have not started yet (pending), be active, |
|
# or have expired. |
|
# |
|
# If there is an active role, we are done. |
|
# |
|
# If there is more than one role which has not started yet, |
|
# choose the one which will start sooner |
|
# If there is one role which has not started yet, return it. |
|
# |
|
# If there is more than one expired role, choose the one which ended last. |
|
# If there is a role which has expired, return it. |
|
# |
|
foreach (split(/\&/,&reply('dump:'.$udom.':'.$unam.':roles', |
|
&homeserver($unam,$udom)))) { |
|
my ($key,$value)=split(/\=/,$_); |
|
$key=&unescape($key); |
|
next if ($key !~/^$courseid(?:\/)*(\w+)*\_st$/); |
|
my $section=$1; |
|
if ($key eq $courseid.'_st') { $section=''; } |
|
my ($dummy,$end,$start)=split(/\_/,&unescape($value)); |
|
my $now=time; |
|
if (defined($end) && ($now > $end)) { |
|
$Expired{$end}=$section; |
|
next; |
|
} |
|
if (defined($start) && ($now < $start)) { |
|
$Pending{$start}=$section; |
|
next; |
|
} |
|
return $section; |
|
} |
|
# |
|
# Presumedly there will be few matching roles from the above |
|
# loop and the sorting time will be negligible. |
|
if (scalar(keys(%Pending))) { |
|
my ($time) = sort {$a <=> $b} keys(%Pending); |
|
return $Pending{$time}; |
|
} |
|
if (scalar(keys(%Expired))) { |
|
my @sorted = sort {$a <=> $b} keys(%Expired); |
|
my $time = pop(@sorted); |
|
return $Expired{$time}; |
|
} |
|
return '-1'; |
|
} |
|
|
sub usection { |
sub usection { |
my ($udom,$unam,$courseid)=@_; |
my ($udom,$unam,$courseid)=@_; |
$courseid=~s/\_/\//g; |
$courseid=~s/\_/\//g; |
Line 610 sub userenvironment {
|
Line 684 sub userenvironment {
|
return %returnhash; |
return %returnhash; |
} |
} |
|
|
|
# -------------------------------------------------------------------- New chat |
|
|
|
sub chatsend { |
|
my ($newentry,$anon)=@_; |
|
my $cnum=$ENV{'course.'.$ENV{'request.course.id'}.'.num'}; |
|
my $cdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; |
|
my $chome=$ENV{'course.'.$ENV{'request.course.id'}.'.home'}; |
|
&reply('chatsend:'.$cdom.':'.$cnum.':'. |
|
&escape($ENV{'user.domain'}.':'.$ENV{'user.name'}.':'.$anon.':'. |
|
&escape($newentry)),$chome); |
|
} |
|
|
|
# ------------------------------------------ Find current version of a resource |
|
|
|
sub getversion { |
|
my $fname=&clutter(shift); |
|
unless ($fname=~/^\/res\//) { return -1; } |
|
return ¤tversion(&filelocation('',$fname)); |
|
} |
|
|
|
sub currentversion { |
|
my $fname=shift; |
|
my $author=$fname; |
|
$author=~s/\/home\/httpd\/html\/res\/([^\/]*)\/([^\/]*).*/$1\/$2/; |
|
my ($udom,$uname)=split(/\//,$author); |
|
my $home=homeserver($uname,$udom); |
|
if ($home eq 'no_host') { |
|
return -1; |
|
} |
|
my $answer=reply("currentversion:$fname",$home); |
|
if (($answer eq 'con_lost') || ($answer eq 'rejected')) { |
|
return -1; |
|
} |
|
return $answer; |
|
} |
|
|
# ----------------------------- Subscribe to a resource, return URL if possible |
# ----------------------------- Subscribe to a resource, return URL if possible |
|
|
sub subscribe { |
sub subscribe { |
my $fname=shift; |
my $fname=shift; |
|
if ($fname=~/\/(aboutme|syllabus|bulletinboard|smppg)$/) { return ''; } |
my $author=$fname; |
my $author=$fname; |
$author=~s/\/home\/httpd\/html\/res\/([^\/]*)\/([^\/]*).*/$1\/$2/; |
$author=~s/\/home\/httpd\/html\/res\/([^\/]*)\/([^\/]*).*/$1\/$2/; |
my ($udom,$uname)=split(/\//,$author); |
my ($udom,$uname)=split(/\//,$author); |
my $home=homeserver($uname,$udom); |
my $home=homeserver($uname,$udom); |
if (($home eq 'no_host') || ($home eq $perlvar{'lonHostID'})) { |
if ($home eq 'no_host') { |
return 'not_found'; |
return 'not_found'; |
} |
} |
my $answer=reply("sub:$fname",$home); |
my $answer=reply("sub:$fname",$home); |
Line 649 sub repcopy {
|
Line 760 sub repcopy {
|
} elsif ($remoteurl eq 'directory') { |
} elsif ($remoteurl eq 'directory') { |
return OK; |
return OK; |
} else { |
} else { |
|
my $author=$filename; |
|
$author=~s/\/home\/httpd\/html\/res\/([^\/]*)\/([^\/]*).*/$1\/$2/; |
|
my ($udom,$uname)=split(/\//,$author); |
|
my $home=homeserver($uname,$udom); |
|
unless ($home eq $perlvar{'lonHostID'}) { |
my @parts=split(/\//,$filename); |
my @parts=split(/\//,$filename); |
my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]"; |
my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]"; |
if ($path ne "$perlvar{'lonDocRoot'}/res") { |
if ($path ne "$perlvar{'lonDocRoot'}/res") { |
Line 684 sub repcopy {
|
Line 800 sub repcopy {
|
rename($transname,$filename); |
rename($transname,$filename); |
return OK; |
return OK; |
} |
} |
|
} |
} |
} |
} |
} |
|
|
Line 710 sub ssi {
|
Line 827 sub ssi {
|
return $response->content; |
return $response->content; |
} |
} |
|
|
|
sub externalssi { |
|
my ($url)=@_; |
|
my $ua=new LWP::UserAgent; |
|
my $request=new HTTP::Request('GET',$url); |
|
my $response=$ua->request($request); |
|
return $response->content; |
|
} |
|
|
|
# ------- Add a token to a remote URI's query string to vouch for access rights |
|
|
|
sub tokenwrapper { |
|
my $uri=shift; |
|
$uri=~s/^http\:\/\/([^\/]+)//; |
|
$uri=~s/^\///; |
|
$ENV{'user.environment'}=~/\/([^\/]+)\.id/; |
|
my $token=$1; |
|
if ($uri=~/^uploaded\/([^\/]+)\/([^\/]+)\/([^\/]+)(\?\.*)*$/) { |
|
&appenv('userfile.'.$1.'/'.$2.'/'.$3 => $ENV{'request.course.id'}); |
|
return 'http://'.$hostname{ &homeserver($2,$1)}.'/'.$uri. |
|
(($uri=~/\?/)?'&':'?').'token='.$token. |
|
'&tokenissued='.$perlvar{'lonHostID'}; |
|
} else { |
|
return '/adm/notfound.html'; |
|
} |
|
} |
|
|
|
# --------------- Take an uploaded file and put it into the userfiles directory |
|
# input: name of form element, coursedoc=1 means this is for the course |
|
# output: url of file in userspace |
|
|
|
sub userfileupload { |
|
my ($formname,$coursedoc)=@_; |
|
my $fname=$ENV{'form.'.$formname.'.filename'}; |
|
# Replace Windows backslashes by forward slashes |
|
$fname=~s/\\/\//g; |
|
# Get rid of everything but the actual filename |
|
$fname=~s/^.*\/([^\/]+)$/$1/; |
|
# Replace spaces by underscores |
|
$fname=~s/\s+/\_/g; |
|
# Replace all other weird characters by nothing |
|
$fname=~s/[^\w\.\-]//g; |
|
# See if there is anything left |
|
unless ($fname) { return 'error: no uploaded file'; } |
|
chop($ENV{'form.'.$formname}); |
|
# Create the directory if not present |
|
my $docuname=''; |
|
my $docudom=''; |
|
my $docuhome=''; |
|
if ($coursedoc) { |
|
$docuname=$ENV{'course.'.$ENV{'request.course.id'}.'.num'}; |
|
$docudom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; |
|
$docuhome=$ENV{'course.'.$ENV{'request.course.id'}.'.home'}; |
|
} else { |
|
$docuname=$ENV{'user.name'}; |
|
$docudom=$ENV{'user.domain'}; |
|
$docuhome=$ENV{'user.home'}; |
|
} |
|
return |
|
&finishuserfileupload($docuname,$docudom,$docuhome,$formname,$fname); |
|
} |
|
|
|
sub finishuserfileupload { |
|
my ($docuname,$docudom,$docuhome,$formname,$fname)=@_; |
|
my $path=$docudom.'/'.$docuname.'/'; |
|
my $filepath=$perlvar{'lonDocRoot'}; |
|
my @parts=split(/\//,$filepath.'/userfiles/'.$path); |
|
my $count; |
|
for ($count=4;$count<=$#parts;$count++) { |
|
$filepath.="/$parts[$count]"; |
|
if ((-e $filepath)!=1) { |
|
mkdir($filepath,0777); |
|
} |
|
} |
|
# Save the file |
|
{ |
|
my $fh=Apache::File->new('>'.$filepath.'/'.$fname); |
|
print $fh $ENV{'form.'.$formname}; |
|
} |
|
# Notify homeserver to grep it |
|
# |
|
|
|
my $fetchresult= |
|
&reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$fname,$docuhome); |
|
if ($fetchresult eq 'ok') { |
|
# |
|
# Return the URL to it |
|
return '/uploaded/'.$path.$fname; |
|
} else { |
|
&logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$fname. |
|
' to host '.$docuhome.': '.$fetchresult); |
|
return '/adm/notfound.html'; |
|
} |
|
} |
|
|
# ------------------------------------------------------------------------- Log |
# ------------------------------------------------------------------------- Log |
|
|
sub log { |
sub log { |
Line 741 sub flushcourselogs {
|
Line 952 sub flushcourselogs {
|
my $entry=$_; |
my $entry=$_; |
$entry=~/\_\_\_(\w+)\/(\w+)\/(.*)\_\_\_(\w+)$/; |
$entry=~/\_\_\_(\w+)\/(\w+)\/(.*)\_\_\_(\w+)$/; |
my %temphash=($entry => $accesshash{$entry}); |
my %temphash=($entry => $accesshash{$entry}); |
if (&Apache::lonnet::put('resevaldata',\%temphash,$1,$2) eq 'ok') { |
if (&Apache::lonnet::put('nohist_resevaldata',\%temphash,$1,$2) eq 'ok') { |
delete $accesshash{$entry}; |
delete $accesshash{$entry}; |
} |
} |
} |
} |
Line 786 sub countacc {
|
Line 997 sub countacc {
|
my $url=&declutter(shift); |
my $url=&declutter(shift); |
unless ($ENV{'request.course.id'}) { return ''; } |
unless ($ENV{'request.course.id'}) { return ''; } |
$accesshash{$ENV{'request.course.id'}.'___'.$url.'___course'}=1; |
$accesshash{$ENV{'request.course.id'}.'___'.$url.'___course'}=1; |
my $key=$processmarker.'_'.$dumpcount.'___'.$url.'___count'; |
my $key=$$.$processmarker.'_'.$dumpcount.'___'.$url.'___count'; |
if (defined($accesshash{$key})) { |
if (defined($accesshash{$key})) { |
$accesshash{$key}++; |
$accesshash{$key}++; |
} else { |
} else { |
Line 801 sub checkout {
|
Line 1012 sub checkout {
|
my $now=time; |
my $now=time; |
my $lonhost=$perlvar{'lonHostID'}; |
my $lonhost=$perlvar{'lonHostID'}; |
my $infostr=&escape( |
my $infostr=&escape( |
|
'CHECKOUTTOKEN&'. |
$tuname.'&'. |
$tuname.'&'. |
$tudom.'&'. |
$tudom.'&'. |
$tcrsid.'&'. |
$tcrsid.'&'. |
Line 850 sub checkin {
|
Line 1062 sub checkin {
|
$lonhost=~tr/A-Z/a-z/; |
$lonhost=~tr/A-Z/a-z/; |
my $dtoken=$ta.'_'.$hostip{$lonhost}.'_'.$tb; |
my $dtoken=$ta.'_'.$hostip{$lonhost}.'_'.$tb; |
$dtoken=~s/\W/\_/g; |
$dtoken=~s/\W/\_/g; |
my ($tuname,$tudom,$tcrsid,$symb,$chtim,$rmaddr)= |
my ($dummy,$tuname,$tudom,$tcrsid,$symb,$chtim,$rmaddr)= |
split(/\&/,&unescape(&reply('tmpget:'.$dtoken,$lonhost))); |
split(/\&/,&unescape(&reply('tmpget:'.$dtoken,$lonhost))); |
|
|
unless (($tuname) && ($tudom)) { |
unless (($tuname) && ($tudom)) { |
Line 900 sub expirespread {
|
Line 1112 sub expirespread {
|
# ----------------------------------------------------- Devalidate Spreadsheets |
# ----------------------------------------------------- Devalidate Spreadsheets |
|
|
sub devalidate { |
sub devalidate { |
my $symb=shift; |
my ($symb,$uname,$udom)=@_; |
my $cid=$ENV{'request.course.id'}; |
my $cid=$ENV{'request.course.id'}; |
if ($cid) { |
if ($cid) { |
my $key=$ENV{'user.name'}.':'.$ENV{'user.domain'}.':'; |
# delete the stored spreadsheets for |
|
# - the student level sheet of this user in course's homespace |
|
# - the assessment level sheet for this resource |
|
# for this user in user's homespace |
|
my $key=$uname.':'.$udom.':'; |
my $status= |
my $status= |
&del('nohist_calculatedsheet', |
&del('nohist_calculatedsheets', |
[$key.'studentcalc'], |
[$key.'studentcalc'], |
$ENV{'course.'.$cid.'.domain'}, |
$ENV{'course.'.$cid.'.domain'}, |
$ENV{'course.'.$cid.'.num'}) |
$ENV{'course.'.$cid.'.num'}) |
Line 914 sub devalidate {
|
Line 1130 sub devalidate {
|
[$key.'assesscalc:'.$symb]); |
[$key.'assesscalc:'.$symb]); |
unless ($status eq 'ok ok') { |
unless ($status eq 'ok ok') { |
&logthis('Could not devalidate spreadsheet '. |
&logthis('Could not devalidate spreadsheet '. |
$ENV{'user.name'}.' at '.$ENV{'user.domain'}.' for '. |
$uname.' at '.$udom.' for '. |
$symb.': '.$status); |
$symb.': '.$status); |
} |
} |
} |
} |
} |
} |
|
|
|
sub get_scalar { |
|
my ($string,$end) = @_; |
|
my $value; |
|
if ($$string =~ s/^([^&]*?)($end)/$2/) { |
|
$value = $1; |
|
} elsif ($$string =~ s/^([^&]*?)&//) { |
|
$value = $1; |
|
} |
|
return &unescape($value); |
|
} |
|
|
|
sub array2str { |
|
my (@array) = @_; |
|
my $result=&arrayref2str(\@array); |
|
$result=~s/^__ARRAY_REF__//; |
|
$result=~s/__END_ARRAY_REF__$//; |
|
return $result; |
|
} |
|
|
sub arrayref2str { |
sub arrayref2str { |
my ($arrayref) = @_; |
my ($arrayref) = @_; |
my $result='_ARRAY_REF__'; |
my $result='__ARRAY_REF__'; |
foreach my $elem (@$arrayref) { |
foreach my $elem (@$arrayref) { |
if (ref($elem) eq 'ARRAY') { |
if(ref($elem) eq 'ARRAY') { |
$result.=&escape(&arrayref2str($elem)).'&'; |
$result.=&arrayref2str($elem).'&'; |
} elsif (ref($elem) eq 'HASH') { |
} elsif(ref($elem) eq 'HASH') { |
$result.=&escape(&hashref2str($elem)).'&'; |
$result.=&hashref2str($elem).'&'; |
} elsif (ref($elem)) { |
} elsif(ref($elem)) { |
&logthis("Got a ref of ".(ref($elem))." skipping."); |
#print("Got a ref of ".(ref($elem))." skipping."); |
} else { |
} else { |
$result.=&escape($elem).'&'; |
$result.=&escape($elem).'&'; |
} |
} |
} |
} |
$result=~s/\&$//; |
$result=~s/\&$//; |
|
$result .= '__END_ARRAY_REF__'; |
return $result; |
return $result; |
} |
} |
|
|
sub hash2str { |
sub hash2str { |
my (%hash) = @_; |
my (%hash) = @_; |
my $result=&hashref2str(\%hash); |
my $result=&hashref2str(\%hash); |
$result=~s/^_HASH_REF__//; |
$result=~s/^__HASH_REF__//; |
|
$result=~s/__END_HASH_REF__$//; |
return $result; |
return $result; |
} |
} |
|
|
sub hashref2str { |
sub hashref2str { |
my ($hashref)=@_; |
my ($hashref)=@_; |
my $result='_HASH_REF__'; |
my $result='__HASH_REF__'; |
foreach (keys(%$hashref)) { |
foreach (keys(%$hashref)) { |
if (ref($_) eq 'ARRAY') { |
if (ref($_) eq 'ARRAY') { |
$result.=&escape(&arrayref2str($_)).'='; |
$result.=&arrayref2str($_).'='; |
} elsif (ref($_) eq 'HASH') { |
} elsif (ref($_) eq 'HASH') { |
$result.=&escape(&hashref2str($_)).'='; |
$result.=&hashref2str($_).'='; |
} elsif (ref($_)) { |
} elsif (ref($_)) { |
&logthis("Got a ref of ".(ref($_))." skipping."); |
$result.='='; |
|
#print("Got a ref of ".(ref($_))." skipping."); |
} else { |
} else { |
$result.=&escape($_).'='; |
if ($_) {$result.=&escape($_).'=';} else { last; } |
} |
} |
|
|
if (ref($$hashref{$_}) eq 'ARRAY') { |
if(ref($hashref->{$_}) eq 'ARRAY') { |
$result.=&escape(&arrayref2str($$hashref{$_})).'&'; |
$result.=&arrayref2str($hashref->{$_}).'&'; |
} elsif (ref($$hashref{$_}) eq 'HASH') { |
} elsif(ref($hashref->{$_}) eq 'HASH') { |
$result.=&escape(&hashref2str($$hashref{$_})).'&'; |
$result.=&hashref2str($hashref->{$_}).'&'; |
} elsif (ref($$hashref{$_})) { |
} elsif(ref($hashref->{$_})) { |
&logthis("Got a ref of ".(ref($$hashref{$_}))." skipping."); |
$result.='&'; |
|
#print("Got a ref of ".(ref($hashref->{$_}))." skipping."); |
} else { |
} else { |
$result.=&escape($$hashref{$_}).'&'; |
$result.=&escape($hashref->{$_}).'&'; |
} |
} |
} |
} |
$result=~s/\&$//; |
$result=~s/\&$//; |
|
$result .= '__END_HASH_REF__'; |
return $result; |
return $result; |
} |
} |
|
|
sub str2hash { |
sub str2hash { |
|
my ($string)=@_; |
|
my ($hash)=&str2hashref('__HASH_REF__'.$string.'__END_HASH_REF__'); |
|
return %$hash; |
|
} |
|
|
|
sub str2hashref { |
my ($string) = @_; |
my ($string) = @_; |
my %returnhash; |
|
foreach (split(/\&/,$string)) { |
my %hash; |
my ($name,$value)=split(/\=/,$_); |
|
$name=&unescape($name); |
if($string !~ /^__HASH_REF__/) { |
$value=&unescape($value); |
if (! ($string eq '' || !defined($string))) { |
if ($value =~ /^_HASH_REF__/) { |
$hash{'error'}='Not hash reference'; |
$value =~ s/^_HASH_REF__//; |
} |
my %hash=&str2hash($value); |
return (\%hash, $string); |
$value=\%hash; |
|
} elsif ($value =~ /^_ARRAY_REF__/) { |
|
$value =~ s/^_ARRAY_REF__//; |
|
my @array=&str2array($value); |
|
$value=\@array; |
|
} |
|
$returnhash{$name}=$value; |
|
} |
} |
return (%returnhash); |
|
|
$string =~ s/^__HASH_REF__//; |
|
|
|
while($string !~ /^__END_HASH_REF__/) { |
|
#key |
|
my $key=''; |
|
if($string =~ /^__HASH_REF__/) { |
|
($key, $string)=&str2hashref($string); |
|
if(defined($key->{'error'})) { |
|
$hash{'error'}='Bad data'; |
|
return (\%hash, $string); |
|
} |
|
} elsif($string =~ /^__ARRAY_REF__/) { |
|
($key, $string)=&str2arrayref($string); |
|
if($key->[0] eq 'Array reference error') { |
|
$hash{'error'}='Bad data'; |
|
return (\%hash, $string); |
|
} |
|
} else { |
|
$string =~ s/^(.*?)=//; |
|
$key=&unescape($1); |
|
} |
|
$string =~ s/^=//; |
|
|
|
#value |
|
my $value=''; |
|
if($string =~ /^__HASH_REF__/) { |
|
($value, $string)=&str2hashref($string); |
|
if(defined($value->{'error'})) { |
|
$hash{'error'}='Bad data'; |
|
return (\%hash, $string); |
|
} |
|
} elsif($string =~ /^__ARRAY_REF__/) { |
|
($value, $string)=&str2arrayref($string); |
|
if($value->[0] eq 'Array reference error') { |
|
$hash{'error'}='Bad data'; |
|
return (\%hash, $string); |
|
} |
|
} else { |
|
$value=&get_scalar(\$string,'__END_HASH_REF__'); |
|
} |
|
$string =~ s/^&//; |
|
|
|
$hash{$key}=$value; |
|
} |
|
|
|
$string =~ s/^__END_HASH_REF__//; |
|
|
|
return (\%hash, $string); |
} |
} |
|
|
sub str2array { |
sub str2array { |
|
my ($string)=@_; |
|
my ($array)=&str2arrayref('__ARRAY_REF__'.$string.'__END_ARRAY_REF__'); |
|
return @$array; |
|
} |
|
|
|
sub str2arrayref { |
my ($string) = @_; |
my ($string) = @_; |
my @returnarray; |
my @array; |
foreach my $value (split(/\&/,$string)) { |
|
$value=&unescape($value); |
if($string !~ /^__ARRAY_REF__/) { |
if ($value =~ /^_HASH_REF__/) { |
if (! ($string eq '' || !defined($string))) { |
$value =~ s/^_HASH_REF__//; |
$array[0]='Array reference error'; |
my %hash=&str2hash($value); |
} |
$value=\%hash; |
return (\@array, $string); |
} elsif ($value =~ /^_ARRAY_REF__/) { |
} |
$value =~ s/^_ARRAY_REF__//; |
|
my @array=&str2array($value); |
$string =~ s/^__ARRAY_REF__//; |
$value=\@array; |
|
} |
while($string !~ /^__END_ARRAY_REF__/) { |
push(@returnarray,$value); |
my $value=''; |
|
if($string =~ /^__HASH_REF__/) { |
|
($value, $string)=&str2hashref($string); |
|
if(defined($value->{'error'})) { |
|
$array[0] ='Array reference error'; |
|
return (\@array, $string); |
|
} |
|
} elsif($string =~ /^__ARRAY_REF__/) { |
|
($value, $string)=&str2arrayref($string); |
|
if($value->[0] eq 'Array reference error') { |
|
$array[0] ='Array reference error'; |
|
return (\@array, $string); |
|
} |
|
} else { |
|
$value=&get_scalar(\$string,'__END_ARRAY_REF__'); |
|
} |
|
$string =~ s/^&//; |
|
|
|
push(@array, $value); |
} |
} |
return (@returnarray); |
|
|
$string =~ s/^__END_ARRAY_REF__//; |
|
|
|
return (\@array, $string); |
} |
} |
|
|
# -------------------------------------------------------------------Temp Store |
# -------------------------------------------------------------------Temp Store |
Line 1034 sub tmpreset {
|
Line 1348 sub tmpreset {
|
my %hash; |
my %hash; |
if (tie(%hash,'GDBM_File', |
if (tie(%hash,'GDBM_File', |
$path.'/tmpstore_'.$stuname.'_'.$domain.'_'.$namespace.'.db', |
$path.'/tmpstore_'.$stuname.'_'.$domain.'_'.$namespace.'.db', |
&GDBM_WRCREAT,0640)) { |
&GDBM_WRCREAT(),0640)) { |
foreach my $key (keys %hash) { |
foreach my $key (keys %hash) { |
if ($key=~ /:$symb/) { |
if ($key=~ /:$symb/) { |
delete($hash{$key}); |
delete($hash{$key}); |
Line 1070 sub tmpstore {
|
Line 1384 sub tmpstore {
|
my $path=$perlvar{'lonDaemons'}.'/tmp'; |
my $path=$perlvar{'lonDaemons'}.'/tmp'; |
if (tie(%hash,'GDBM_File', |
if (tie(%hash,'GDBM_File', |
$path.'/tmpstore_'.$stuname.'_'.$domain.'_'.$namespace.'.db', |
$path.'/tmpstore_'.$stuname.'_'.$domain.'_'.$namespace.'.db', |
&GDBM_WRCREAT,0640)) { |
&GDBM_WRCREAT(),0640)) { |
$hash{"version:$symb"}++; |
$hash{"version:$symb"}++; |
my $version=$hash{"version:$symb"}; |
my $version=$hash{"version:$symb"}; |
my $allkeys=''; |
my $allkeys=''; |
Line 1114 sub tmprestore {
|
Line 1428 sub tmprestore {
|
my $path=$perlvar{'lonDaemons'}.'/tmp'; |
my $path=$perlvar{'lonDaemons'}.'/tmp'; |
if (tie(%hash,'GDBM_File', |
if (tie(%hash,'GDBM_File', |
$path.'/tmpstore_'.$stuname.'_'.$domain.'_'.$namespace.'.db', |
$path.'/tmpstore_'.$stuname.'_'.$domain.'_'.$namespace.'.db', |
&GDBM_READER,0640)) { |
&GDBM_READER(),0640)) { |
my $version=$hash{"version:$symb"}; |
my $version=$hash{"version:$symb"}; |
$returnhash{'version'}=$version; |
$returnhash{'version'}=$version; |
my $scope; |
my $scope; |
Line 1148 sub store {
|
Line 1462 sub store {
|
$symb=&symbclean($symb); |
$symb=&symbclean($symb); |
if (!$symb) { unless ($symb=&symbread()) { return ''; } } |
if (!$symb) { unless ($symb=&symbread()) { return ''; } } |
|
|
&devalidate($symb); |
if (!$domain) { $domain=$ENV{'user.domain'}; } |
|
if (!$stuname) { $stuname=$ENV{'user.name'}; } |
|
|
|
&devalidate($symb,$stuname,$domain); |
|
|
$symb=escape($symb); |
$symb=escape($symb); |
if (!$namespace) { |
if (!$namespace) { |
Line 1156 sub store {
|
Line 1473 sub store {
|
return ''; |
return ''; |
} |
} |
} |
} |
if (!$domain) { $domain=$ENV{'user.domain'}; } |
|
if (!$stuname) { $stuname=$ENV{'user.name'}; } |
|
if (!$home) { $home=$ENV{'user.home'}; } |
if (!$home) { $home=$ENV{'user.home'}; } |
my $namevalue=''; |
my $namevalue=''; |
foreach (keys %$storehash) { |
foreach (keys %$storehash) { |
Line 1179 sub cstore {
|
Line 1494 sub cstore {
|
$symb=&symbclean($symb); |
$symb=&symbclean($symb); |
if (!$symb) { unless ($symb=&symbread()) { return ''; } } |
if (!$symb) { unless ($symb=&symbread()) { return ''; } } |
|
|
&devalidate($symb); |
if (!$domain) { $domain=$ENV{'user.domain'}; } |
|
if (!$stuname) { $stuname=$ENV{'user.name'}; } |
|
|
|
&devalidate($symb,$stuname,$domain); |
|
|
$symb=escape($symb); |
$symb=escape($symb); |
if (!$namespace) { |
if (!$namespace) { |
Line 1187 sub cstore {
|
Line 1505 sub cstore {
|
return ''; |
return ''; |
} |
} |
} |
} |
if (!$domain) { $domain=$ENV{'user.domain'}; } |
|
if (!$stuname) { $stuname=$ENV{'user.name'}; } |
|
if (!$home) { $home=$ENV{'user.home'}; } |
if (!$home) { $home=$ENV{'user.home'}; } |
|
|
my $namevalue=''; |
my $namevalue=''; |
Line 1246 sub coursedescription {
|
Line 1562 sub coursedescription {
|
$courseid=~s/\_/\//g; |
$courseid=~s/\_/\//g; |
my ($cdomain,$cnum)=split(/\//,$courseid); |
my ($cdomain,$cnum)=split(/\//,$courseid); |
my $chome=&homeserver($cnum,$cdomain); |
my $chome=&homeserver($cnum,$cdomain); |
|
my $normalid=$cdomain.'_'.$cnum; |
|
# need to always cache even if we get errors otherwise we keep |
|
# trying and trying and trying to get the course description. |
|
my %envhash=(); |
|
my %returnhash=(); |
|
$envhash{'course.'.$normalid.'.last_cache'}=time; |
if ($chome ne 'no_host') { |
if ($chome ne 'no_host') { |
my %returnhash=&dump('environment',$cdomain,$cnum); |
%returnhash=&dump('environment',$cdomain,$cnum); |
if (!exists($returnhash{'con_lost'})) { |
if (!exists($returnhash{'con_lost'})) { |
my $normalid=$cdomain.'_'.$cnum; |
|
my %envhash=(); |
|
$returnhash{'home'}= $chome; |
$returnhash{'home'}= $chome; |
$returnhash{'domain'} = $cdomain; |
$returnhash{'domain'} = $cdomain; |
$returnhash{'num'} = $cnum; |
$returnhash{'num'} = $cnum; |
while (my ($name,$value) = each %returnhash) { |
while (my ($name,$value) = each %returnhash) { |
$envhash{'course.'.$normalid.'.'.$name}=$value; |
$envhash{'course.'.$normalid.'.'.$name}=$value; |
} |
} |
$returnhash{'url'}='/res/'.declutter($returnhash{'url'}); |
$returnhash{'url'}=&clutter($returnhash{'url'}); |
$returnhash{'fn'}=$perlvar{'lonDaemons'}.'/tmp/'. |
$returnhash{'fn'}=$perlvar{'lonDaemons'}.'/tmp/'. |
$ENV{'user.name'}.'_'.$cdomain.'_'.$cnum; |
$ENV{'user.name'}.'_'.$cdomain.'_'.$cnum; |
$envhash{'course.'.$normalid.'.last_cache'}=time; |
|
$envhash{'course.'.$normalid.'.home'}=$chome; |
$envhash{'course.'.$normalid.'.home'}=$chome; |
$envhash{'course.'.$normalid.'.domain'}=$cdomain; |
$envhash{'course.'.$normalid.'.domain'}=$cdomain; |
$envhash{'course.'.$normalid.'.num'}=$cnum; |
$envhash{'course.'.$normalid.'.num'}=$cnum; |
&appenv(%envhash); |
|
return %returnhash; |
|
} |
} |
} |
} |
return (); |
&appenv(%envhash); |
|
return %returnhash; |
} |
} |
|
|
# -------------------------------------------------------- Get user privileges |
# -------------------------------------------------------- Get user privileges |
Line 1385 sub get {
|
Line 1703 sub get {
|
|
|
my $rep=&reply("get:$udomain:$uname:$namespace:$items",$uhome); |
my $rep=&reply("get:$udomain:$uname:$namespace:$items",$uhome); |
my @pairs=split(/\&/,$rep); |
my @pairs=split(/\&/,$rep); |
|
if ( $#pairs==0 && $pairs[0] =~ /^(con_lost|error|no_such_host)/i) { |
|
return @pairs; |
|
} |
my %returnhash=(); |
my %returnhash=(); |
my $i=0; |
my $i=0; |
foreach (@$storearr) { |
foreach (@$storearr) { |
Line 1432 sub dump {
|
Line 1753 sub dump {
|
return %returnhash; |
return %returnhash; |
} |
} |
|
|
|
# --------------------------------------------------------------- currentdump |
|
sub currentdump { |
|
my ($sname,$sdom,$courseid)=@_; |
|
$courseid = $ENV{'request.course.id'} if (! defined($courseid)); |
|
$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); |
|
return if ($rep =~ /^(error:|no_such_host)/); |
|
# |
|
my %returnhash=(); |
|
# |
|
if ($rep eq "unknown_cmd") { |
|
# an old lond will not know currentdump |
|
# Do a dump and make it look like a currentdump |
|
my @tmp = &dump($courseid,$sdom,$sname,'.'); |
|
return if ($tmp[0] =~ /^(error:|no_such_host)/); |
|
my %hash = @tmp; |
|
@tmp=(); |
|
# Code ripped from lond, essentially. The only difference |
|
# here is the unescaping done by lonnet::dump(). Conceivably |
|
# we might run in to problems with parameter names =~ /^v\./ |
|
while (my ($key,$value) = each(%hash)) { |
|
my ($v,$symb,$param) = split(/:/,$key); |
|
next if ($v eq 'version' || $symb eq 'keys'); |
|
next if (exists($returnhash{$symb}) && |
|
exists($returnhash{$symb}->{$param}) && |
|
$returnhash{$symb}->{'v.'.$param} > $v); |
|
$returnhash{$symb}->{$param}=$value; |
|
$returnhash{$symb}->{'v.'.$param}=$v; |
|
} |
|
# |
|
# Remove all of the keys in the hashes which keep track of |
|
# the version of the parameter. |
|
while (my ($symb,$param_hash) = each(%returnhash)) { |
|
# use a foreach because we are going to delete from the hash. |
|
foreach my $key (keys(%$param_hash)) { |
|
delete($param_hash->{$key}) if ($key =~ /^v\./); |
|
} |
|
} |
|
} else { |
|
my @pairs=split(/\&/,$rep); |
|
foreach (@pairs) { |
|
my ($key,$value)=split(/=/,$_); |
|
my ($symb,$param) = split(/:/,$key); |
|
$returnhash{&unescape($symb)}->{&unescape($param)} = |
|
&unescape($value); |
|
} |
|
} |
|
return %returnhash; |
|
} |
|
|
# --------------------------------------------------------------- put interface |
# --------------------------------------------------------------- put interface |
|
|
sub put { |
sub put { |
Line 1502 sub allowed {
|
Line 1875 sub allowed {
|
# Free bre to public access |
# Free bre to public access |
|
|
if ($priv eq 'bre') { |
if ($priv eq 'bre') { |
if (&metadata($uri,'copyright') eq 'public') { return 'F'; } |
my $copyright=&metadata($uri,'copyright'); |
|
if (($copyright eq 'public') && (!$ENV{'request.course.id'})) { |
|
return 'F'; |
|
} |
|
if ($copyright eq 'priv') { |
|
$uri=~/([^\/]+)\/([^\/]+)\//; |
|
unless (($ENV{'user.name'} eq $2) && ($ENV{'user.domain'} eq $1)) { |
|
return ''; |
|
} |
|
} |
|
if ($copyright eq 'domain') { |
|
$uri=~/([^\/]+)\/([^\/]+)\//; |
|
unless (($ENV{'user.domain'} eq $1) || |
|
($ENV{'course.'.$ENV{'request.course.id'}.'.domain'} eq $1)) { |
|
return ''; |
|
} |
|
} |
|
if ($ENV{'request.role'}=~ /li\.\//) { |
|
# Library role, so allow browsing of resources in this domain. |
|
return 'F'; |
|
} |
|
} |
|
# Domain coordinator is trying to create a course |
|
if (($priv eq 'ccc') && ($ENV{'request.role'} =~ /^dc\./)) { |
|
# uri is the requested domain in this case. |
|
# comparison to 'request.role.domain' shows if the user has selected |
|
# a role of dc for the domain in question. |
|
return 'F' if ($uri eq $ENV{'request.role.domain'}); |
} |
} |
|
|
my $thisallowed=''; |
my $thisallowed=''; |
Line 1532 sub allowed {
|
Line 1932 sub allowed {
|
$thisallowed.=$1; |
$thisallowed.=$1; |
} |
} |
|
|
|
# URI is an uploaded document for this course |
|
|
|
if (($priv eq 'bre') && |
|
($uri=~/^uploaded\/$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}\/$ENV{'course.'.$ENV{'request.course.id'}.'.num'}/)) { |
|
return 'F'; |
|
} |
# Full access at system, domain or course-wide level? Exit. |
# Full access at system, domain or course-wide level? Exit. |
|
|
if ($thisallowed=~/F/) { |
if ($thisallowed=~/F/) { |
Line 1550 sub allowed {
|
Line 1956 sub allowed {
|
# the course |
# the course |
|
|
if ($ENV{'request.course.id'}) { |
if ($ENV{'request.course.id'}) { |
|
|
$courseprivid=$ENV{'request.course.id'}; |
$courseprivid=$ENV{'request.course.id'}; |
if ($ENV{'request.course.sec'}) { |
if ($ENV{'request.course.sec'}) { |
$courseprivid.='/'.$ENV{'request.course.sec'}; |
$courseprivid.='/'.$ENV{'request.course.sec'}; |
} |
} |
$courseprivid=~s/\_/\//; |
$courseprivid=~s/\_/\//; |
my $checkreferer=1; |
my $checkreferer=1; |
my @uriparts=split(/\//,$uri); |
my ($match,$cond)=&is_on_map($uri); |
my $filename=$uriparts[$#uriparts]; |
if ($match) { |
my $pathname=$uri; |
$statecond=$cond; |
$pathname=~s/\/$filename$//; |
|
if ($ENV{'acc.res.'.$ENV{'request.course.id'}.'.'.$pathname}=~ |
|
/\&$filename\:([\d\|]+)\&/) { |
|
$statecond=$1; |
|
if ($ENV{'user.priv.'.$ENV{'request.role'}.'./'.$courseprivid} |
if ($ENV{'user.priv.'.$ENV{'request.role'}.'./'.$courseprivid} |
=~/$priv\&([^\:]*)/) { |
=~/$priv\&([^\:]*)/) { |
$thisallowed.=$1; |
$thisallowed.=$1; |
Line 1572 sub allowed {
|
Line 1975 sub allowed {
|
|
|
if ($checkreferer) { |
if ($checkreferer) { |
my $refuri=$ENV{'httpref.'.$orguri}; |
my $refuri=$ENV{'httpref.'.$orguri}; |
|
|
unless ($refuri) { |
unless ($refuri) { |
foreach (keys %ENV) { |
foreach (keys %ENV) { |
if ($_=~/^httpref\..*\*/) { |
if ($_=~/^httpref\..*\*/) { |
Line 1586 sub allowed {
|
Line 1988 sub allowed {
|
} |
} |
} |
} |
} |
} |
|
|
if ($refuri) { |
if ($refuri) { |
$refuri=&declutter($refuri); |
$refuri=&declutter($refuri); |
my @uriparts=split(/\//,$refuri); |
my ($match,$cond)=&is_on_map($refuri); |
my $filename=$uriparts[$#uriparts]; |
if ($match) { |
my $pathname=$refuri; |
my $refstatecond=$cond; |
$pathname=~s/\/$filename$//; |
|
if ($ENV{'acc.res.'.$ENV{'request.course.id'}.'.'.$pathname}=~ |
|
/\&$filename\:([\d\|]+)\&/) { |
|
my $refstatecond=$1; |
|
if ($ENV{'user.priv.'.$ENV{'request.role'}.'./'.$courseprivid} |
if ($ENV{'user.priv.'.$ENV{'request.role'}.'./'.$courseprivid} |
=~/$priv\&([^\:]*)/) { |
=~/$priv\&([^\:]*)/) { |
$thisallowed.=$1; |
$thisallowed.=$1; |
Line 1653 sub allowed {
|
Line 2052 sub allowed {
|
|| ($ENV{$prefix.'res.'.$uri.'.lock.sections'} eq 'all')) { |
|| ($ENV{$prefix.'res.'.$uri.'.lock.sections'} eq 'all')) { |
if ($ENV{$prefix.'res.'.$uri.'.lock.expire'}>time) { |
if ($ENV{$prefix.'res.'.$uri.'.lock.expire'}>time) { |
&log($ENV{'user.domain'},$ENV{'user.name'}, |
&log($ENV{'user.domain'},$ENV{'user.name'}, |
$ENV{'user.host'}, |
$ENV{'user.home'}, |
'Locked by res: '.$priv.' for '.$uri.' due to '. |
'Locked by res: '.$priv.' for '.$uri.' due to '. |
$cdom.'/'.$cnum.'/'.$csec.' expire '. |
$cdom.'/'.$cnum.'/'.$csec.' expire '. |
$ENV{$prefix.'priv.'.$priv.'.lock.expire'}); |
$ENV{$prefix.'priv.'.$priv.'.lock.expire'}); |
Line 1664 sub allowed {
|
Line 2063 sub allowed {
|
|| ($ENV{$prefix.'priv.'.$priv.'.lock.sections'} eq 'all')) { |
|| ($ENV{$prefix.'priv.'.$priv.'.lock.sections'} eq 'all')) { |
if ($ENV{'priv.'.$priv.'.lock.expire'}>time) { |
if ($ENV{'priv.'.$priv.'.lock.expire'}>time) { |
&log($ENV{'user.domain'},$ENV{'user.name'}, |
&log($ENV{'user.domain'},$ENV{'user.name'}, |
$ENV{'user.host'}, |
$ENV{'user.home'}, |
'Locked by priv: '.$priv.' for '.$uri.' due to '. |
'Locked by priv: '.$priv.' for '.$uri.' due to '. |
$cdom.'/'.$cnum.'/'.$csec.' expire '. |
$cdom.'/'.$cnum.'/'.$csec.' expire '. |
$ENV{$prefix.'priv.'.$priv.'.lock.expire'}); |
$ENV{$prefix.'priv.'.$priv.'.lock.expire'}); |
Line 1692 sub allowed {
|
Line 2091 sub allowed {
|
|
|
if ($thisallowed=~/C/) { |
if ($thisallowed=~/C/) { |
my $rolecode=(split(/\./,$ENV{'request.role'}))[0]; |
my $rolecode=(split(/\./,$ENV{'request.role'}))[0]; |
|
my $unamedom=$ENV{'user.name'}.':'.$ENV{'user.domain'}; |
if ($ENV{'course.'.$ENV{'request.course.id'}.'.'.$priv.'.roles.denied'} |
if ($ENV{'course.'.$ENV{'request.course.id'}.'.'.$priv.'.roles.denied'} |
=~/$rolecode/) { |
=~/$rolecode/) { |
&log($ENV{'user.domain'},$ENV{'user.name'},$ENV{'user.host'}, |
&log($ENV{'user.domain'},$ENV{'user.name'},$ENV{'user.host'}, |
Line 1699 sub allowed {
|
Line 2099 sub allowed {
|
$ENV{'request.course.id'}); |
$ENV{'request.course.id'}); |
return ''; |
return ''; |
} |
} |
|
|
|
if ($ENV{'course.'.$ENV{'request.course.id'}.'.'.$priv.'.users.denied'} |
|
=~/$unamedom/) { |
|
&log($ENV{'user.domain'},$ENV{'user.name'},$ENV{'user.host'}, |
|
'Denied by user: '.$priv.' for '.$uri.' as '.$unamedom.' in '. |
|
$ENV{'request.course.id'}); |
|
return ''; |
|
} |
} |
} |
|
|
# Resource preferences |
# Resource preferences |
Line 1722 sub allowed {
|
Line 2130 sub allowed {
|
} |
} |
} |
} |
|
|
# Restricted by state? |
# Restricted by state or randomout? |
|
|
if ($thisallowed=~/X/) { |
if ($thisallowed=~/X/) { |
|
if ($ENV{'acc.randomout'}) { |
|
my $symb=&symbread($uri,1); |
|
if (($symb) && ($ENV{'acc.randomout'}=~/\&$symb\&/)) { |
|
return ''; |
|
} |
|
} |
if (&condval($statecond)) { |
if (&condval($statecond)) { |
return '2'; |
return '2'; |
} else { |
} else { |
Line 1735 sub allowed {
|
Line 2149 sub allowed {
|
return 'F'; |
return 'F'; |
} |
} |
|
|
|
# --------------------------------------------------- Is a resource on the map? |
|
|
|
sub is_on_map { |
|
my $uri=&declutter(shift); |
|
my @uriparts=split(/\//,$uri); |
|
my $filename=$uriparts[$#uriparts]; |
|
my $pathname=$uri; |
|
$pathname=~s|/\Q$filename\E$||; |
|
#Trying to find the conditional for the file |
|
my $match=($ENV{'acc.res.'.$ENV{'request.course.id'}.'.'.$pathname}=~ |
|
/\&\Q$filename\E\:([\d\|]+)\&/); |
|
if ($match) { |
|
return (1,$1); |
|
} else { |
|
return (0,0); |
|
} |
|
} |
|
|
# ----------------------------------------------------------------- Define Role |
# ----------------------------------------------------------------- Define Role |
|
|
sub definerole { |
sub definerole { |
Line 1780 sub definerole {
|
Line 2212 sub definerole {
|
# ---------------- Make a metadata query against the network of library servers |
# ---------------- Make a metadata query against the network of library servers |
|
|
sub metadata_query { |
sub metadata_query { |
my ($query,$custom,$customshow)=@_; |
my ($query,$custom,$customshow,$server_array)=@_; |
my %rhash; |
my %rhash; |
for my $server (keys %libserv) { |
my @server_list = (defined($server_array) ? @$server_array |
|
: keys(%libserv) ); |
|
for my $server (@server_list) { |
unless ($custom or $customshow) { |
unless ($custom or $customshow) { |
my $reply=&reply("querysend:".&escape($query),$server); |
my $reply=&reply("querysend:".&escape($query),$server); |
$rhash{$server}=$reply; |
$rhash{$server}=$reply; |
Line 1797 sub metadata_query {
|
Line 2231 sub metadata_query {
|
return \%rhash; |
return \%rhash; |
} |
} |
|
|
|
# ----------------------------------------- Send log queries and wait for reply |
|
|
|
sub log_query { |
|
my ($uname,$udom,$query,%filters)=@_; |
|
my $uhome=&homeserver($uname,$udom); |
|
if ($uhome eq 'no_host') { return 'error: no_host'; } |
|
my $uhost=$hostname{$uhome}; |
|
my $command=&escape(join(':',map{$_.'='.$filters{$_}} keys %filters)); |
|
my $queryid=&reply("querysend:".$query.':'.$udom.':'.$uname.':'.$command, |
|
$uhome); |
|
unless ($queryid=~/^$uhost\_/) { return 'error: '.$queryid; } |
|
return get_query_reply($queryid); |
|
} |
|
|
|
sub get_query_reply { |
|
my $queryid=shift; |
|
my $replyfile=$perlvar{'lonDaemons'}.'/tmp/'.$queryid; |
|
my $reply=''; |
|
for (1..100) { |
|
sleep 2; |
|
if (-e $replyfile.'.end') { |
|
if (my $fh=Apache::File->new($replyfile)) { |
|
$reply.=<$fh>; |
|
$fh->close; |
|
} else { return 'error: reply_file_error'; } |
|
return &unescape($reply); |
|
} |
|
} |
|
return 'timeout:'.$queryid; |
|
} |
|
|
|
sub courselog_query { |
|
# |
|
# possible filters: |
|
# url: url or symb |
|
# username |
|
# domain |
|
# action: view, submit, grade |
|
# start: timestamp |
|
# end: timestamp |
|
# |
|
my (%filters)=@_; |
|
unless ($ENV{'request.course.id'}) { return 'no_course'; } |
|
if ($filters{'url'}) { |
|
$filters{'url'}=&symbclean(&declutter($filters{'url'})); |
|
$filters{'url'}=~s/\.(\w+)$/(\\.\\d+)*\\.$1/; |
|
$filters{'url'}=~s/\.(\w+)\_\_\_/(\\.\\d+)*\\.$1/; |
|
} |
|
my $cname=$ENV{'course.'.$ENV{'request.course.id'}.'.num'}; |
|
my $cdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; |
|
return &log_query($cname,$cdom,'courselog',%filters); |
|
} |
|
|
|
sub userlog_query { |
|
my ($uname,$udom,%filters)=@_; |
|
return &log_query($uname,$udom,'userlog',%filters); |
|
} |
|
|
# ------------------------------------------------------------------ Plain Text |
# ------------------------------------------------------------------ Plain Text |
|
|
sub plaintext { |
sub plaintext { |
Line 1849 sub modifyuserauth {
|
Line 2341 sub modifyuserauth {
|
my $uhome=&homeserver($uname,$udom); |
my $uhome=&homeserver($uname,$udom); |
unless (&allowed('mau',$udom)) { return 'refused'; } |
unless (&allowed('mau',$udom)) { return 'refused'; } |
&logthis('Call to modify user authentication '.$udom.', '.$uname.', '. |
&logthis('Call to modify user authentication '.$udom.', '.$uname.', '. |
$umode.' by '.$ENV{'user.name'}.' at '.$ENV{'user.domain'}); |
$umode.' by '.$ENV{'user.name'}.' at '.$ENV{'user.domain'}. |
|
' in domain '.$ENV{'request.role.domain'}); |
my $reply=&reply('encrypt:changeuserauth:'.$udom.':'.$uname.':'.$umode.':'. |
my $reply=&reply('encrypt:changeuserauth:'.$udom.':'.$uname.':'.$umode.':'. |
&escape($upass),$uhome); |
&escape($upass),$uhome); |
&log($ENV{'user.domain'},$ENV{'user.name'},$ENV{'user.home'}, |
&log($ENV{'user.domain'},$ENV{'user.name'},$ENV{'user.home'}, |
Line 1880 sub modifyuser {
|
Line 2373 sub modifyuser {
|
$last.', '.$gene.'(forceid: '.$forceid.')'. |
$last.', '.$gene.'(forceid: '.$forceid.')'. |
(defined($desiredhome) ? ' desiredhome = '.$desiredhome : |
(defined($desiredhome) ? ' desiredhome = '.$desiredhome : |
' desiredhome not specified'). |
' desiredhome not specified'). |
' by '.$ENV{'user.name'}.' at '.$ENV{'user.domain'}); |
' by '.$ENV{'user.name'}.' at '.$ENV{'user.domain'}. |
my $uhome=&homeserver($uname,$udom); |
' in domain '.$ENV{'request.role.domain'}); |
|
my $uhome=&homeserver($uname,$udom,'true'); |
# ----------------------------------------------------------------- Create User |
# ----------------------------------------------------------------- Create User |
if (($uhome eq 'no_host') && ($umode) && ($upass)) { |
if (($uhome eq 'no_host') && ($umode) && ($upass)) { |
my $unhome=''; |
my $unhome=''; |
Line 1911 sub modifyuser {
|
Line 2405 sub modifyuser {
|
unless ($reply eq 'ok') { |
unless ($reply eq 'ok') { |
return 'error: '.$reply; |
return 'error: '.$reply; |
} |
} |
$uhome=&homeserver($uname,$udom); |
$uhome=&homeserver($uname,$udom,'true'); |
if (($uhome eq '') || ($uhome eq 'no_host') || ($uhome ne $unhome)) { |
if (($uhome eq '') || ($uhome eq 'no_host') || ($uhome ne $unhome)) { |
return 'error: verify home'; |
return 'error: verify home'; |
} |
} |
Line 1930 sub modifyuser {
|
Line 2424 sub modifyuser {
|
} |
} |
} |
} |
# -------------------------------------------------------------- Add names, etc |
# -------------------------------------------------------------- Add names, etc |
my %names=&get('environment', |
my @tmp=&get('environment', |
['firstname','middlename','lastname','generation'], |
['firstname','middlename','lastname','generation'], |
$udom,$uname); |
$udom,$uname); |
if ($names{'firstname'} =~ m/^error:.*/) { %names=(); } |
my %names; |
|
if ($tmp[0] =~ m/^error:.*/) { |
|
%names=(); |
|
} else { |
|
%names = @tmp; |
|
} |
if ($first) { $names{'firstname'} = $first; } |
if ($first) { $names{'firstname'} = $first; } |
if ($middle) { $names{'middlename'} = $middle; } |
if ($middle) { $names{'middlename'} = $middle; } |
if ($last) { $names{'lastname'} = $last; } |
if ($last) { $names{'lastname'} = $last; } |
Line 1961 sub modifystudent {
|
Line 2460 sub modifystudent {
|
($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$forceid, |
($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$forceid, |
$desiredhome); |
$desiredhome); |
unless ($reply eq 'ok') { return $reply; } |
unless ($reply eq 'ok') { return $reply; } |
|
# This will cause &modify_student_enrollment to get the uid from the |
|
# students environment |
|
$uid = undef if (!$forceid); |
|
$reply = &modify_student_enrollment($udom,$uname,$uid,$first,$middle, |
|
$last,$gene,$usec,$end,$start); |
|
return $reply; |
|
} |
|
|
|
sub modify_student_enrollment { |
|
my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start) = @_; |
|
# Get the course id from the environment |
|
my $cid=''; |
|
unless ($cid=$ENV{'request.course.id'}) { |
|
return 'not_in_class'; |
|
} |
|
# Make sure the user exists |
my $uhome=&homeserver($uname,$udom); |
my $uhome=&homeserver($uname,$udom); |
if (($uhome eq '') || ($uhome eq 'no_host')) { |
if (($uhome eq '') || ($uhome eq 'no_host')) { |
return 'error: no such user'; |
return 'error: no such user'; |
} |
} |
# -------------------------------------------------- Add student to course list |
# |
$reply=critical('put:'.$ENV{'course.'.$cid.'.domain'}.':'. |
# Get student data if we were not given enough information |
|
if (!defined($first) || $first eq '' || |
|
!defined($last) || $last eq '' || |
|
!defined($uid) || $uid eq '' || |
|
!defined($middle) || $middle eq '' || |
|
!defined($gene) || $gene eq '') { |
|
# They did not supply us with enough data to enroll the student, so |
|
# we need to pick up more information. |
|
my %tmp = &get('environment', |
|
['firstname','middlename','lastname', 'generation','id'] |
|
,$udom,$uname); |
|
|
|
foreach (keys(%tmp)) { |
|
&logthis("key $_ = ".$tmp{$_}); |
|
} |
|
$first = $tmp{'firstname'} if (!defined($first) || $first eq ''); |
|
$middle = $tmp{'middlename'} if (!defined($middle) || $middle eq ''); |
|
$last = $tmp{'lastname'} if (!defined($last) || $last eq ''); |
|
$gene = $tmp{'generation'} if (!defined($gene) || $gene eq ''); |
|
$uid = $tmp{'id'} if (!defined($uid) || $uid eq ''); |
|
} |
|
my $fullname = &Apache::loncoursedata::ProcessFullName($last,$gene, |
|
$first,$middle); |
|
my $reply=critical('put:'.$ENV{'course.'.$cid.'.domain'}.':'. |
$ENV{'course.'.$cid.'.num'}.':classlist:'. |
$ENV{'course.'.$cid.'.num'}.':classlist:'. |
&escape($uname.':'.$udom).'='. |
&escape($uname.':'.$udom).'='. |
&escape($end.':'.$start), |
&escape(join(':',$end,$start,$uid,$usec,$fullname)), |
$ENV{'course.'.$cid.'.home'}); |
$ENV{'course.'.$cid.'.home'}); |
unless (($reply eq 'ok') || ($reply eq 'delayed')) { |
unless (($reply eq 'ok') || ($reply eq 'delayed')) { |
return 'error: '.$reply; |
return 'error: '.$reply; |
} |
} |
# ---------------------------------------------------- Add student role to user |
# Add student role to user |
my $uurl='/'.$cid; |
my $uurl='/'.$cid; |
$uurl=~s/\_/\//g; |
$uurl=~s/\_/\//g; |
if ($usec) { |
if ($usec) { |
Line 2005 sub writecoursepref {
|
Line 2543 sub writecoursepref {
|
# ---------------------------------------------------------- Make/modify course |
# ---------------------------------------------------------- Make/modify course |
|
|
sub createcourse { |
sub createcourse { |
my ($udom,$description,$url)=@_; |
my ($udom,$description,$url,$course_server,$nonstandard)=@_; |
$url=&declutter($url); |
$url=&declutter($url); |
my $cid=''; |
my $cid=''; |
unless (&allowed('ccc',$ENV{'user.domain'})) { |
unless (&allowed('ccc',$udom)) { |
return 'refused'; |
|
} |
|
unless ($udom eq $ENV{'user.domain'}) { |
|
return 'refused'; |
return 'refused'; |
} |
} |
# ------------------------------------------------------------------- Create ID |
# ------------------------------------------------------------------- Create ID |
my $uname=substr($$.time,0,5).unpack("H8",pack("I32",time)). |
my $uname=substr($$.time,0,5).unpack("H8",pack("I32",time)). |
unpack("H2",pack("I32",int(rand(255)))).$perlvar{'lonHostID'}; |
unpack("H2",pack("I32",int(rand(255)))).$perlvar{'lonHostID'}; |
# ----------------------------------------------- Make sure that does not exist |
# ----------------------------------------------- Make sure that does not exist |
my $uhome=&homeserver($uname,$udom); |
my $uhome=&homeserver($uname,$udom,'true'); |
unless (($uhome eq '') || ($uhome eq 'no_host')) { |
unless (($uhome eq '') || ($uhome eq 'no_host')) { |
$uname=substr($$.time,0,5).unpack("H8",pack("I32",time)). |
$uname=substr($$.time,0,5).unpack("H8",pack("I32",time)). |
unpack("H2",pack("I32",int(rand(255)))).$perlvar{'lonHostID'}; |
unpack("H2",pack("I32",int(rand(255)))).$perlvar{'lonHostID'}; |
$uhome=&homeserver($uname,$udom); |
$uhome=&homeserver($uname,$udom,'true'); |
unless (($uhome eq '') || ($uhome eq 'no_host')) { |
unless (($uhome eq '') || ($uhome eq 'no_host')) { |
return 'error: unable to generate unique course-ID'; |
return 'error: unable to generate unique course-ID'; |
} |
} |
} |
} |
|
# ------------------------------------------------ Check supplied server name |
|
$course_server = $ENV{'user.homeserver'} if (! defined($course_server)); |
|
if (! exists($libserv{$course_server})) { |
|
return 'error:bad server name '.$course_server; |
|
} |
# ------------------------------------------------------------- Make the course |
# ------------------------------------------------------------- Make the course |
my $reply=&reply('encrypt:makeuser:'.$udom.':'.$uname.':none::', |
my $reply=&reply('encrypt:makeuser:'.$udom.':'.$uname.':none::', |
$ENV{'user.home'}); |
$course_server); |
unless ($reply eq 'ok') { return 'error: '.$reply; } |
unless ($reply eq 'ok') { return 'error: '.$reply; } |
$uhome=&homeserver($uname,$udom); |
$uhome=&homeserver($uname,$udom,'true'); |
if (($uhome eq '') || ($uhome eq 'no_host')) { |
if (($uhome eq '') || ($uhome eq 'no_host')) { |
return 'error: no such course'; |
return 'error: no such course'; |
} |
} |
|
# ----------------------------------------------------------------- Course made |
|
my $topurl=$url; |
|
unless ($nonstandard) { |
|
# ------------------------------------------ For standard courses, make top url |
|
my $mapurl=&clutter($url); |
|
if ($mapurl eq '/res/') { $mapurl=''; } |
|
$ENV{'form.initmap'}=(<<ENDINITMAP); |
|
<map> |
|
<resource id="1" type="start"></resource> |
|
<resource id="2" src="$mapurl"></resource> |
|
<resource id="3" type="finish"></resource> |
|
<link index="1" from="1" to="2"></link> |
|
<link index="2" from="2" to="3"></link> |
|
</map> |
|
ENDINITMAP |
|
$topurl=&declutter( |
|
&finishuserfileupload($uname,$udom,$uhome,'initmap','default.sequence') |
|
); |
|
} |
|
# ----------------------------------------------------------- Write preferences |
&writecoursepref($udom.'_'.$uname, |
&writecoursepref($udom.'_'.$uname, |
('description' => $description, |
('description' => $description, |
'url' => $url)); |
'url' => $topurl)); |
return '/'.$udom.'/'.$uname; |
return '/'.$udom.'/'.$uname; |
} |
} |
|
|
Line 2068 sub revokecustomrole {
|
Line 2628 sub revokecustomrole {
|
# ------------------------------------------------------------ Directory lister |
# ------------------------------------------------------------ Directory lister |
|
|
sub dirlist { |
sub dirlist { |
my $uri=shift; |
my ($uri,$userdomain,$username,$alternateDirectoryRoot)=@_; |
|
|
$uri=~s/^\///; |
$uri=~s/^\///; |
$uri=~s/\/$//; |
$uri=~s/\/$//; |
my ($res,$udom,$uname,@rest)=split(/\//,$uri); |
my ($udom, $uname); |
if ($udom) { |
(undef,$udom,$uname)=split(/\//,$uri); |
if ($uname) { |
if(defined($userdomain)) { |
my $listing=reply('ls:'.$perlvar{'lonDocRoot'}.'/'.$uri, |
$udom = $userdomain; |
homeserver($uname,$udom)); |
} |
return split(/:/,$listing); |
if(defined($username)) { |
} else { |
$uname = $username; |
my $tryserver; |
} |
my %allusers=(); |
|
foreach $tryserver (keys %libserv) { |
my $dirRoot = $perlvar{'lonDocRoot'}; |
if ($hostdom{$tryserver} eq $udom) { |
if(defined($alternateDirectoryRoot)) { |
my $listing=reply('ls:'.$perlvar{'lonDocRoot'}.'/res/'.$udom, |
$dirRoot = $alternateDirectoryRoot; |
$tryserver); |
$dirRoot =~ s/\/$//; |
if (($listing ne 'no_such_dir') && ($listing ne 'empty') |
} |
&& ($listing ne 'con_lost')) { |
|
foreach (split(/:/,$listing)) { |
if($udom) { |
my ($entry,@stat)=split(/&/,$_); |
if($uname) { |
$allusers{$entry}=1; |
my $listing=reply('ls:'.$dirRoot.'/'.$uri, |
|
homeserver($uname,$udom)); |
|
return split(/:/,$listing); |
|
} elsif(!defined($alternateDirectoryRoot)) { |
|
my $tryserver; |
|
my %allusers=(); |
|
foreach $tryserver (keys %libserv) { |
|
if($hostdom{$tryserver} eq $udom) { |
|
my $listing=reply('ls:'.$perlvar{'lonDocRoot'}.'/res/'. |
|
$udom, $tryserver); |
|
if (($listing ne 'no_such_dir') && ($listing ne 'empty') |
|
&& ($listing ne 'con_lost')) { |
|
foreach (split(/:/,$listing)) { |
|
my ($entry,@stat)=split(/&/,$_); |
|
$allusers{$entry}=1; |
|
} |
|
} |
} |
} |
} |
} |
} |
my $alluserstr=''; |
} |
foreach (sort keys %allusers) { |
my $alluserstr=''; |
$alluserstr.=$_.'&user:'; |
foreach (sort keys %allusers) { |
} |
$alluserstr.=$_.'&user:'; |
$alluserstr=~s/:$//; |
} |
return split(/:/,$alluserstr); |
$alluserstr=~s/:$//; |
} else { |
return split(/:/,$alluserstr); |
my @emptyResults = (); |
} |
push(@emptyResults, 'missing user name'); |
} else { |
return split(':',@emptyResults); |
my $tryserver; |
} |
my %alldom=(); |
} elsif(!defined($alternateDirectoryRoot)) { |
foreach $tryserver (keys %libserv) { |
my $tryserver; |
$alldom{$hostdom{$tryserver}}=1; |
my %alldom=(); |
} |
foreach $tryserver (keys %libserv) { |
my $alldomstr=''; |
$alldom{$hostdom{$tryserver}}=1; |
foreach (sort keys %alldom) { |
} |
$alldomstr.=$perlvar{'lonDocRoot'}.'/res/'.$_.'&domain:'; |
my $alldomstr=''; |
} |
foreach (sort keys %alldom) { |
$alldomstr=~s/:$//; |
$alldomstr.=$perlvar{'lonDocRoot'}.'/res/'.$_.'&domain:'; |
return split(/:/,$alldomstr); |
} |
} |
$alldomstr=~s/:$//; |
|
return split(/:/,$alldomstr); |
|
} else { |
|
my @emptyResults = (); |
|
push(@emptyResults, 'missing domain'); |
|
return split(':',@emptyResults); |
|
} |
|
} |
|
|
|
# --------------------------------------------- GetFileTimestamp |
|
# This function utilizes dirlist and returns the date stamp for |
|
# when it was last modified. It will also return an error of -1 |
|
# if an error occurs |
|
|
|
sub GetFileTimestamp { |
|
my ($studentDomain,$studentName,$filename,$root)=@_; |
|
$studentDomain=~s/\W//g; |
|
$studentName=~s/\W//g; |
|
my $subdir=$studentName.'__'; |
|
$subdir =~ s/(.)(.)(.).*/$1\/$2\/$3/; |
|
my $proname="$studentDomain/$subdir/$studentName"; |
|
$proname .= '/'.$filename; |
|
my @dir = &Apache::lonnet::dirlist($proname, $studentDomain, $studentName, |
|
$root); |
|
my $fileStat = $dir[0]; |
|
my @stats = split('&', $fileStat); |
|
if($stats[0] ne 'empty' && $stats[0] ne 'no_such_dir') { |
|
return $stats[9]; |
|
} else { |
|
return -1; |
|
} |
} |
} |
|
|
# -------------------------------------------------------- Value of a Condition |
# -------------------------------------------------------- Value of a Condition |
Line 2167 sub condval {
|
Line 2774 sub condval {
|
return $result; |
return $result; |
} |
} |
|
|
|
# ---------------------------------------------------- Devalidate courseresdata |
|
|
|
sub devalidatecourseresdata { |
|
my ($coursenum,$coursedomain)=@_; |
|
my $hashid=$coursenum.':'.$coursedomain; |
|
delete $courseresdatacache{$hashid.'.time'}; |
|
} |
|
|
# --------------------------------------------------- Course Resourcedata Query |
# --------------------------------------------------- Course Resourcedata Query |
|
|
sub courseresdata { |
sub courseresdata { |
my ($coursenum,$coursedomain,@which)=@_; |
my ($coursenum,$coursedomain,@which)=@_; |
my $coursehom=&homeserver($coursenum,$coursedomain); |
my $coursehom=&homeserver($coursenum,$coursedomain); |
my $hashid=$coursenum.':'.$coursedomain; |
my $hashid=$coursenum.':'.$coursedomain; |
unless (defined($courseresdatacache{$hashid.'.time'})) { |
my $dodump=0; |
unless (time-$courseresdatacache{$hashid.'.time'}<300) { |
if (!defined($courseresdatacache{$hashid.'.time'})) { |
my $coursehom=&homeserver($coursenum,$coursedomain); |
$dodump=1; |
if ($coursehom) { |
} else { |
my $dumpreply=&reply('dump:'.$coursedomain.':'.$coursenum. |
if (time-$courseresdatacache{$hashid.'.time'}>300) { $dodump=1; } |
':resourcedata:.',$coursehom); |
|
unless ($dumpreply=~/^error\:/) { |
|
$courseresdatacache{$hashid.'.time'}=time; |
|
$courseresdatacache{$hashid}=$dumpreply; |
|
} |
|
} |
|
} |
|
} |
} |
my @pairs=split(/\&/,$courseresdatacache{$hashid}); |
if ($dodump) { |
my %returnhash=(); |
my %dumpreply=&dump('resourcedata',$coursedomain,$coursenum); |
foreach (@pairs) { |
my ($tmp) = keys(%dumpreply); |
my ($key,$value)=split(/=/,$_); |
if ($tmp !~ /^(con_lost|error|no_such_host)/i) { |
$returnhash{unescape($key)}=unescape($value); |
$courseresdatacache{$hashid.'.time'}=time; |
} |
$courseresdatacache{$hashid}=\%dumpreply; |
my $item; |
} elsif ($tmp =~ /^(con_lost|no_such_host)/) { |
foreach $item (@which) { |
return $tmp; |
if ($returnhash{$item}) { return $returnhash{$item}; } |
} |
} |
} |
return ''; |
foreach my $item (@which) { |
|
if (defined($courseresdatacache{$hashid}->{$item})) { |
|
return $courseresdatacache{$hashid}->{$item}; |
|
} |
|
} |
|
return undef; |
} |
} |
|
|
# --------------------------------------------------------- Value of a Variable |
# --------------------------------------------------------- Value of a Variable |
|
|
sub EXT { |
sub EXT { |
my ($varname,$symbparm,$udom,$uname)=@_; |
my ($varname,$symbparm,$udom,$uname,)=@_; |
|
|
unless ($varname) { return ''; } |
unless ($varname) { return ''; } |
|
|
Line 2214 sub EXT {
|
Line 2827 sub EXT {
|
} else { |
} else { |
$courseid=$ENV{'request.course.id'}; |
$courseid=$ENV{'request.course.id'}; |
} |
} |
|
|
my ($realm,$space,$qualifier,@therest)=split(/\./,$varname); |
my ($realm,$space,$qualifier,@therest)=split(/\./,$varname); |
my $rest; |
my $rest; |
if ($therest[0]) { |
if (defined($therest[0])) { |
$rest=join('.',@therest); |
$rest=join('.',@therest); |
} else { |
} else { |
$rest=''; |
$rest=''; |
} |
} |
|
|
my $qualifierrest=$qualifier; |
my $qualifierrest=$qualifier; |
if ($rest) { $qualifierrest.='.'.$rest; } |
if ($rest) { $qualifierrest.='.'.$rest; } |
my $spacequalifierrest=$space; |
my $spacequalifierrest=$space; |
Line 2269 sub EXT {
|
Line 2882 sub EXT {
|
my %reply=&get($space,[$item]); |
my %reply=&get($space,[$item]); |
return $reply{$item}; |
return $reply{$item}; |
} |
} |
} elsif ($realm eq 'request') { |
} elsif ($realm eq 'query') { |
|
# ---------------------------------------------- pull stuff out of query string |
|
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},[$space]); |
|
return $ENV{'form.'.$space}; |
|
} elsif ($realm eq 'request') { |
# ------------------------------------------------------------- request.browser |
# ------------------------------------------------------------- request.browser |
if ($space eq 'browser') { |
if ($space eq 'browser') { |
return $ENV{'browser.'.$qualifier}; |
return $ENV{'browser.'.$qualifier}; |
Line 2297 sub EXT {
|
Line 2914 sub EXT {
|
my $section; |
my $section; |
if (($ENV{'user.name'} eq $uname) && |
if (($ENV{'user.name'} eq $uname) && |
($ENV{'user.domain'} eq $udom)) { |
($ENV{'user.domain'} eq $udom)) { |
$section={'request.course.sec'}; |
$section=$ENV{'request.course.sec'}; |
} else { |
} else { |
$section=&usection($udom,$uname,$courseid); |
$section=&usection($udom,$uname,$courseid); |
} |
} |
Line 2311 sub EXT {
|
Line 2928 sub EXT {
|
my $courselevelm=$courseid.'.'.$mapparm; |
my $courselevelm=$courseid.'.'.$mapparm; |
|
|
# ----------------------------------------------------------- first, check user |
# ----------------------------------------------------------- first, check user |
my %resourcedata=&get('resourcedata', |
#most student don't have any data set, check if there is some data |
[$courselevelr,$courselevelm,$courselevel], |
#every thirty minutes |
$udom,$uname); |
if (! |
if (($resourcedata{$courselevelr}!~/^error\:/) && |
(exists($ENV{'cache.studentresdata'}) |
($resourcedata{$courselevelr}!~/^con_lost/)) { |
&& (($ENV{'cache.studentresdata'}+1800) > time))) { |
|
my %resourcedata=&get('resourcedata', |
if ($resourcedata{$courselevelr}) { |
[$courselevelr,$courselevelm,$courselevel], |
return $resourcedata{$courselevelr}; } |
$udom,$uname); |
if ($resourcedata{$courselevelm}) { |
my ($tmp)=keys(%resourcedata); |
return $resourcedata{$courselevelm}; } |
if (($tmp!~/^error\:/) && ($tmp!~/^con_lost/)) { |
if ($resourcedata{$courselevel}) { |
if ($resourcedata{$courselevelr}) { |
return $resourcedata{$courselevel}; } |
return $resourcedata{$courselevelr}; } |
} else { |
if ($resourcedata{$courselevelm}) { |
if ($resourcedata{$courselevelr}!~/No such file/) { |
return $resourcedata{$courselevelm}; } |
&logthis("<font color=blue>WARNING:". |
if ($resourcedata{$courselevel}) { |
" Trying to get resource data for ". |
return $resourcedata{$courselevel}; } |
$uname." at ".$udom.": ". |
} else { |
$resourcedata{$courselevelr}."</font>"); |
if ($tmp!~/No such file/) { |
|
&logthis("<font color=blue>WARNING:". |
|
" Trying to get resource data for ". |
|
$uname." at ".$udom.": ". |
|
$tmp."</font>"); |
|
} elsif ($tmp=~/error:No such file/) { |
|
$ENV{'cache.studentresdata'}=time; |
|
&appenv(('cache.studentresdata'=> |
|
$ENV{'cache.studentresdata'})); |
|
} elsif ($tmp =~ /^(con_lost|no_such_host)/) { |
|
return $tmp; |
|
} |
} |
} |
} |
} |
|
|
Line 2339 sub EXT {
|
Line 2967 sub EXT {
|
($seclevelr,$seclevelm,$seclevel, |
($seclevelr,$seclevelm,$seclevel, |
$courselevelr,$courselevelm, |
$courselevelr,$courselevelm, |
$courselevel)); |
$courselevel)); |
if ($coursereply) { return $coursereply; } |
if (defined($coursereply)) { return $coursereply; } |
|
|
# ------------------------------------------------------ third, check map parms |
# ------------------------------------------------------ third, check map parms |
my %parmhash=(); |
my %parmhash=(); |
my $thisparm=''; |
my $thisparm=''; |
if (tie(%parmhash,'GDBM_File', |
if (tie(%parmhash,'GDBM_File', |
$ENV{'request.course.fn'}.'_parms.db', |
$ENV{'request.course.fn'}.'_parms.db', |
&GDBM_READER,0640)) { |
&GDBM_READER(),0640)) { |
$thisparm=$parmhash{$symbparm}; |
$thisparm=$parmhash{$symbparm}; |
untie(%parmhash); |
untie(%parmhash); |
} |
} |
Line 2355 sub EXT {
|
Line 2983 sub EXT {
|
# --------------------------------------------- last, look in resource metadata |
# --------------------------------------------- last, look in resource metadata |
|
|
$spacequalifierrest=~s/\./\_/; |
$spacequalifierrest=~s/\./\_/; |
my $metadata=&metadata($ENV{'request.filename'},$spacequalifierrest); |
my $filename; |
if ($metadata) { return $metadata; } |
if (!$symbparm) { $symbparm=&symbread(); } |
$metadata=&metadata($ENV{'request.filename'}, |
if ($symbparm) { |
'parameter_'.$spacequalifierrest); |
$filename=(split(/\_\_\_/,$symbparm))[2]; |
if ($metadata) { return $metadata; } |
} else { |
|
$filename=$ENV{'request.filename'}; |
|
} |
|
my $metadata=&metadata($filename,$spacequalifierrest); |
|
if (defined($metadata)) { return $metadata; } |
|
$metadata=&metadata($filename,'parameter_'.$spacequalifierrest); |
|
if (defined($metadata)) { return $metadata; } |
|
|
# ------------------------------------------------------------------ Cascade up |
# ------------------------------------------------------------------ Cascade up |
unless ($space eq '0') { |
unless ($space eq '0') { |
Line 2367 sub EXT {
|
Line 3001 sub EXT {
|
if ($id) { |
if ($id) { |
my $partgeneral=&EXT('resource.'.$part.'.'.$qualifierrest, |
my $partgeneral=&EXT('resource.'.$part.'.'.$qualifierrest, |
$symbparm,$udom,$uname); |
$symbparm,$udom,$uname); |
if ($partgeneral) { return $partgeneral; } |
if (defined($partgeneral)) { return $partgeneral; } |
} else { |
} else { |
my $resourcegeneral=&EXT('resource.0.'.$qualifierrest, |
my $resourcegeneral=&EXT('resource.0.'.$qualifierrest, |
$symbparm,$udom,$uname); |
$symbparm,$udom,$uname); |
if ($resourcegeneral) { return $resourcegeneral; } |
if (defined($resourcegeneral)) { return $resourcegeneral; } |
} |
} |
} |
} |
|
|
Line 2400 sub metadata {
|
Line 3034 sub metadata {
|
my ($uri,$what,$liburi,$prefix,$depthcount)=@_; |
my ($uri,$what,$liburi,$prefix,$depthcount)=@_; |
|
|
$uri=&declutter($uri); |
$uri=&declutter($uri); |
|
# if it is a non metadata possible uri return quickly |
|
if (($uri eq '') || (($uri =~ m|^/*adm/|) && ($uri !~ m|^adm/includes|)) || |
|
($uri =~ m|/$|) || ($uri =~ m|/.meta$|)) { |
|
return ''; |
|
} |
my $filename=$uri; |
my $filename=$uri; |
$uri=~s/\.meta$//; |
$uri=~s/\.meta$//; |
# |
# |
Line 2407 sub metadata {
|
Line 3046 sub metadata {
|
# Look at timestamp of caching |
# Look at timestamp of caching |
# Everything is cached by the main uri, libraries are never directly cached |
# Everything is cached by the main uri, libraries are never directly cached |
# |
# |
unless (abs($metacache{$uri.':cachedtimestamp'}-time)<600) { |
unless (abs($metacache{$uri.':cachedtimestamp'}-time)<600 && !defined($liburi)) { |
# |
# |
# Is this a recursive call for a library? |
# Is this a recursive call for a library? |
# |
# |
Line 2430 sub metadata {
|
Line 3069 sub metadata {
|
my $package=$token->[2]->{'package'}; |
my $package=$token->[2]->{'package'}; |
my $keyroot=''; |
my $keyroot=''; |
if ($prefix) { |
if ($prefix) { |
$keyroot.='_'.$prefix; |
$keyroot.=$prefix; |
} else { |
} else { |
if (defined($token->[2]->{'part'})) { |
if (defined($token->[2]->{'part'})) { |
$keyroot.='_'.$token->[2]->{'part'}; |
$keyroot.='_'.$token->[2]->{'part'}; |
Line 2456 sub metadata {
|
Line 3095 sub metadata {
|
my $unikey='parameter'.$keyroot.'_'.$name; |
my $unikey='parameter'.$keyroot.'_'.$name; |
$metathesekeys{$unikey}=1; |
$metathesekeys{$unikey}=1; |
$metacache{$uri.':'.$unikey.'.part'}=$part; |
$metacache{$uri.':'.$unikey.'.part'}=$part; |
unless |
unless (defined($metacache{$uri.':'.$unikey.'.'.$subp})) { |
(defined($metacache{$uri.':'.$unikey.'.'.$subp})) { |
$metacache{$uri.':'.$unikey.'.'.$subp}=$value; |
$metacache{$uri.':'.$unikey.'.'.$subp}=$value; |
} |
|
if (defined($metacache{$uri.':'.$unikey.'.default'})) { |
|
$metacache{$uri.':'.$unikey}= |
|
$metacache{$uri.':'.$unikey.'.default'} |
} |
} |
} |
} |
} |
} |
Line 2488 sub metadata {
|
Line 3130 sub metadata {
|
# |
# |
# Importing a library here |
# Importing a library here |
# |
# |
if (defined($depthcount)) { $depthcount++; } else |
|
{ $depthcount=0; } |
|
if ($depthcount<20) { |
if ($depthcount<20) { |
foreach (split(/\,/,&metadata($uri,'keys', |
my $location=$parser->get_text('/import'); |
$parser->get_text('/import'),$unikey, |
my $dir=$filename; |
$depthcount))) { |
$dir=~s|[^/]*$||; |
|
$location=&filelocation($dir,$location); |
|
foreach (sort(split(/\,/,&metadata($uri,'keys', |
|
$location,$unikey, |
|
$depthcount+1)))) { |
$metathesekeys{$_}=1; |
$metathesekeys{$_}=1; |
} |
} |
} |
} |
Line 2506 sub metadata {
|
Line 3150 sub metadata {
|
foreach (@{$token->[3]}) { |
foreach (@{$token->[3]}) { |
$metacache{$uri.':'.$unikey.'.'.$_}=$token->[2]->{$_}; |
$metacache{$uri.':'.$unikey.'.'.$_}=$token->[2]->{$_}; |
} |
} |
unless ( |
my $internaltext=&HTML::Entities::decode($parser->get_text('/'.$entry)); |
$metacache{$uri.':'.$unikey}=&HTML::Entities::decode($parser->get_text('/'.$entry)) |
my $default=$metacache{$uri.':'.$unikey.'.default'}; |
) { $metacache{$uri.':'.$unikey}= |
if ( $internaltext =~ /^\s*$/ && $default !~ /^\s*$/) { |
$metacache{$uri.':'.$unikey.'.default'}; |
# only ws inside the tag, and not in default, so use default |
} |
# as value |
|
$metacache{$uri.':'.$unikey}=$default; |
|
} else { |
|
# either something interesting inside the tag or default |
|
# uninteresting |
|
$metacache{$uri.':'.$unikey}=$internaltext; |
|
} |
# end of not-a-package not-a-library import |
# end of not-a-package not-a-library import |
} |
} |
# end of not-a-package start tag |
# end of not-a-package start tag |
Line 2519 sub metadata {
|
Line 3169 sub metadata {
|
} |
} |
} |
} |
$metacache{$uri.':keys'}=join(',',keys %metathesekeys); |
$metacache{$uri.':keys'}=join(',',keys %metathesekeys); |
|
&metadata_generate_part0(\%metathesekeys,\%metacache,$uri); |
|
$metacache{$uri.':allpossiblekeys'}=join(',',keys %metathesekeys); |
$metacache{$uri.':cachedtimestamp'}=time; |
$metacache{$uri.':cachedtimestamp'}=time; |
# this is the end of "was not already recently cached |
# this is the end of "was not already recently cached |
} |
} |
return $metacache{$uri.':'.$what}; |
return $metacache{$uri.':'.$what}; |
} |
} |
|
|
|
sub metadata_generate_part0 { |
|
my ($metadata,$metacache,$uri) = @_; |
|
my %allnames; |
|
foreach my $metakey (sort keys %$metadata) { |
|
if ($metakey=~/^parameter\_(.*)/) { |
|
my $part=$$metacache{$uri.':'.$metakey.'.part'}; |
|
my $name=$$metacache{$uri.':'.$metakey.'.name'}; |
|
if (! exists($$metadata{'parameter_0_'.$name})) { |
|
$allnames{$name}=$part; |
|
} |
|
} |
|
} |
|
foreach my $name (keys(%allnames)) { |
|
$$metadata{"parameter_0_$name"}=1; |
|
my $key="$uri:parameter_0_$name"; |
|
$$metacache{"$key.part"}='0'; |
|
$$metacache{"$key.name"}=$name; |
|
$$metacache{"$key.type"}=$$metacache{$uri.':parameter_'. |
|
$allnames{$name}.'_'.$name. |
|
'.type'}; |
|
my $olddis=$$metacache{$uri.':parameter_'.$allnames{$name}.'_'.$name. |
|
'.display'}; |
|
my $expr='\\[Part: '.$allnames{$name}.'\\]'; |
|
$olddis=~s/$expr/\[Part: 0\]/; |
|
$$metacache{"$key.display"}=$olddis; |
|
} |
|
} |
|
|
|
# ------------------------------------------------- Get the title of a resource |
|
|
|
sub gettitle { |
|
my $urlsymb=shift; |
|
my $symb=&symbread($urlsymb); |
|
unless ($symb) { |
|
unless ($urlsymb) { $urlsymb=$ENV{'request.filename'}; } |
|
return &metadata($urlsymb,'title'); |
|
} |
|
if ($titlecache{$symb}) { return $titlecache{$symb}; } |
|
my ($map,$resid,$url)=split(/\_\_\_/,$symb); |
|
my $title=''; |
|
my %bighash; |
|
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
|
&GDBM_READER(),0640)) { |
|
my $mapid=$bighash{'map_pc_'.&clutter($map)}; |
|
$title=$bighash{'title_'.$mapid.'.'.$resid}; |
|
untie %bighash; |
|
} |
|
if ($title) { |
|
$titlecache{$symb}=$title; |
|
return $title; |
|
} else { |
|
return &metadata($urlsymb,'title'); |
|
} |
|
} |
|
|
# ------------------------------------------------- Update symbolic store links |
# ------------------------------------------------- Update symbolic store links |
|
|
sub symblist { |
sub symblist { |
Line 2533 sub symblist {
|
Line 3240 sub symblist {
|
my %hash; |
my %hash; |
if (($ENV{'request.course.fn'}) && (%newhash)) { |
if (($ENV{'request.course.fn'}) && (%newhash)) { |
if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db', |
if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db', |
&GDBM_WRCREAT,0640)) { |
&GDBM_WRCREAT(),0640)) { |
foreach (keys %newhash) { |
foreach (keys %newhash) { |
$hash{declutter($_)}=$mapname.'___'.$newhash{$_}; |
$hash{declutter($_)}=$mapname.'___'.$newhash{$_}; |
} |
} |
Line 2561 sub symbverify {
|
Line 3268 sub symbverify {
|
my %bighash; |
my %bighash; |
my $okay=0; |
my $okay=0; |
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
&GDBM_READER,0640)) { |
&GDBM_READER(),0640)) { |
my $ids=$bighash{'ids_/res/'.$thisfn}; |
my $ids=$bighash{'ids_'.&clutter($thisfn)}; |
unless ($ids) { |
unless ($ids) { |
$ids=$bighash{'ids_/'.$thisfn}; |
$ids=$bighash{'ids_/'.$thisfn}; |
} |
} |
Line 2599 sub symbclean {
|
Line 3306 sub symbclean {
|
# ------------------------------------------------------ Return symb list entry |
# ------------------------------------------------------ Return symb list entry |
|
|
sub symbread { |
sub symbread { |
my $thisfn=shift; |
my ($thisfn,$donotrecurse)=@_; |
|
# no filename provided? try from environment |
unless ($thisfn) { |
unless ($thisfn) { |
if ($ENV{'request.symb'}) { return &symbclean($ENV{'request.symb'}); } |
if ($ENV{'request.symb'}) { return &symbclean($ENV{'request.symb'}); } |
$thisfn=$ENV{'request.filename'}; |
$thisfn=$ENV{'request.filename'}; |
} |
} |
|
# is that filename actually a symb? Verify, clean, and return |
|
if ($thisfn=~/\_\_\_\d+\_\_\_(.*)$/) { |
|
if (&symbverify($thisfn,$1)) { return &symbclean($thisfn); } |
|
} |
$thisfn=declutter($thisfn); |
$thisfn=declutter($thisfn); |
my %hash; |
my %hash; |
my %bighash; |
my %bighash; |
my $syval=''; |
my $syval=''; |
if (($ENV{'request.course.fn'}) && ($thisfn)) { |
if (($ENV{'request.course.fn'}) && ($thisfn)) { |
if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db', |
if (tie(%hash,'GDBM_File',$ENV{'request.course.fn'}.'_symb.db', |
&GDBM_READER,0640)) { |
&GDBM_READER(),0640)) { |
$syval=$hash{$thisfn}; |
$syval=$hash{$thisfn}; |
untie(%hash); |
untie(%hash); |
} |
} |
Line 2626 sub symbread {
|
Line 3338 sub symbread {
|
} else { |
} else { |
# ------------------------------------------------------- Was not in symb table |
# ------------------------------------------------------- Was not in symb table |
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
if (tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', |
&GDBM_READER,0640)) { |
&GDBM_READER(),0640)) { |
# ---------------------------------------------- Get ID(s) for current resource |
# ---------------------------------------------- Get ID(s) for current resource |
my $ids=$bighash{'ids_/res/'.$thisfn}; |
my $ids=$bighash{'ids_'.&clutter($thisfn)}; |
unless ($ids) { |
unless ($ids) { |
$ids=$bighash{'ids_/'.$thisfn}; |
$ids=$bighash{'ids_/'.$thisfn}; |
} |
} |
|
unless ($ids) { |
|
# alias? |
|
$ids=$bighash{'mapalias_'.$thisfn}; |
|
} |
if ($ids) { |
if ($ids) { |
# ------------------------------------------------------------------- Has ID(s) |
# ------------------------------------------------------------------- Has ID(s) |
my @possibilities=split(/\,/,$ids); |
my @possibilities=split(/\,/,$ids); |
Line 2639 sub symbread {
|
Line 3355 sub symbread {
|
# ----------------------------------------------- There is only one possibility |
# ----------------------------------------------- There is only one possibility |
my ($mapid,$resid)=split(/\./,$ids); |
my ($mapid,$resid)=split(/\./,$ids); |
$syval=declutter($bighash{'map_id_'.$mapid}).'___'.$resid; |
$syval=declutter($bighash{'map_id_'.$mapid}).'___'.$resid; |
} else { |
} elsif (!$donotrecurse) { |
# ------------------------------------------ There is more than one possibility |
# ------------------------------------------ There is more than one possibility |
my $realpossible=0; |
my $realpossible=0; |
foreach (@possibilities) { |
foreach (@possibilities) { |
Line 2654 sub symbread {
|
Line 3370 sub symbread {
|
} |
} |
} |
} |
if ($realpossible!=1) { $syval=''; } |
if ($realpossible!=1) { $syval=''; } |
|
} else { |
|
$syval=''; |
} |
} |
} |
} |
untie(%bighash) |
untie(%bighash) |
Line 2722 sub ireceipt {
|
Line 3440 sub ireceipt {
|
} |
} |
|
|
sub receipt { |
sub receipt { |
return &ireceipt($ENV{'user.name'},$ENV{'user.domain'}, |
my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser(); |
$ENV{'request.course.id'},&symbread()); |
return &ireceipt($name,$domain,$courseid,$symb); |
} |
} |
|
|
# ------------------------------------------------------------ Serves up a file |
# ------------------------------------------------------------ Serves up a file |
# returns either the contents of the file or a -1 |
# returns either the contents of the file or a -1 |
sub getfile { |
sub getfile { |
my $file=shift; |
my $file=shift; |
|
if ($file=~/^\/*uploaded\//) { # user file |
|
my $ua=new LWP::UserAgent; |
|
my $request=new HTTP::Request('GET',&tokenwrapper($file)); |
|
my $response=$ua->request($request); |
|
if ($response->is_success()) { |
|
return $response->content; |
|
} else { |
|
return -1; |
|
} |
|
} else { # normal file from res space |
&repcopy($file); |
&repcopy($file); |
if (! -e $file ) { return -1; }; |
if (! -e $file ) { return -1; }; |
my $fh=Apache::File->new($file); |
my $fh=Apache::File->new($file); |
my $a=''; |
my $a=''; |
while (<$fh>) { $a .=$_; } |
while (<$fh>) { $a .=$_; } |
return $a |
return $a; |
|
} |
} |
} |
|
|
sub filelocation { |
sub filelocation { |
Line 2745 sub filelocation {
|
Line 3474 sub filelocation {
|
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:; |
|
} elsif ($file=~/^\/*uploaded/) { # is an uploaded file |
|
$location=$file; |
} else { |
} else { |
$file=~s/^$perlvar{'lonDocRoot'}//; |
$file=~s/^$perlvar{'lonDocRoot'}//; |
$file=~s:^/*res::; |
$file=~s:^/*res::; |
Line 2778 sub declutter {
|
Line 3509 sub declutter {
|
$thisfn=~s/^$perlvar{'lonDocRoot'}//; |
$thisfn=~s/^$perlvar{'lonDocRoot'}//; |
$thisfn=~s/^\///; |
$thisfn=~s/^\///; |
$thisfn=~s/^res\///; |
$thisfn=~s/^res\///; |
|
$thisfn=~s/\?.+$//; |
|
return $thisfn; |
|
} |
|
|
|
# ------------------------------------------------------------- Clutter up URLs |
|
|
|
sub clutter { |
|
my $thisfn='/'.&declutter(shift); |
|
unless ($thisfn=~/^\/(uploaded|adm|userfiles|ext|raw|priv)\//) { |
|
$thisfn='/res'.$thisfn; |
|
} |
return $thisfn; |
return $thisfn; |
} |
} |
|
|
Line 2831 BEGIN {
|
Line 3573 BEGIN {
|
} |
} |
} |
} |
|
|
|
# ------------------------------------------------------------ Read domain file |
|
{ |
|
my $fh=Apache::File->new($Apache::lonnet::perlvar{'lonTabDir'}. |
|
'/domain.tab'); |
|
%domaindescription = (); |
|
%domain_auth_def = (); |
|
%domain_auth_arg_def = (); |
|
if ($fh) { |
|
while (<$fh>) { |
|
next if /^\#/; |
|
chomp; |
|
my ($domain, $domain_description, $def_auth, $def_auth_arg) |
|
= split(/:/,$_,4); |
|
$domain_auth_def{$domain}=$def_auth; |
|
$domain_auth_arg_def{$domain}=$def_auth_arg; |
|
$domaindescription{$domain}=$domain_description; |
|
# &logthis("Domain.tab: $domain, $domain_auth_def{$domain}, $domain_auth_arg_def{$domain},$domaindescription{$domain}"); |
|
# &logthis("Domain.tab: $domain ".$domaindescription{$domain} ); |
|
} |
|
} |
|
} |
|
|
|
|
# ------------------------------------------------------------- Read hosts file |
# ------------------------------------------------------------- Read hosts file |
{ |
{ |
my $config=Apache::File->new("$perlvar{'lonTabDir'}/hosts.tab"); |
my $config=Apache::File->new("$perlvar{'lonTabDir'}/hosts.tab"); |
|
|
while (my $configline=<$config>) { |
while (my $configline=<$config>) { |
|
next if ($configline =~ /^(\#|\s*$)/); |
chomp($configline); |
chomp($configline); |
my ($id,$domain,$role,$name,$ip)=split(/:/,$configline); |
my ($id,$domain,$role,$name,$ip,$domdescr)=split(/:/,$configline); |
$hostname{$id}=$name; |
if ($id && $domain && $role && $name && $ip) { |
$hostdom{$id}=$domain; |
$hostname{$id}=$name; |
$hostip{$id}=$ip; |
$hostdom{$id}=$domain; |
if ($role eq 'library') { $libserv{$id}=$name; } |
$hostip{$id}=$ip; |
|
$iphost{$ip}=$id; |
|
if ($role eq 'library') { $libserv{$id}=$name; } |
|
} else { |
|
if ($configline) { |
|
&logthis("Skipping hosts.tab line -$configline-"); |
|
} |
|
} |
} |
} |
} |
} |
|
|
Line 2851 BEGIN {
|
Line 3624 BEGIN {
|
|
|
while (my $configline=<$config>) { |
while (my $configline=<$config>) { |
chomp($configline); |
chomp($configline); |
if (($configline) && ($configline ne $perlvar{'lonHostID'})) { |
if ($configline) { |
$spareid{$configline}=1; |
$spareid{$configline}=1; |
} |
} |
} |
} |
Line 2899 BEGIN {
|
Line 3672 BEGIN {
|
|
|
%metacache=(); |
%metacache=(); |
|
|
$processmarker=$$.'_'.time.'_'.$perlvar{'lonHostID'}; |
$processmarker='_'.time.'_'.$perlvar{'lonHostID'}; |
$dumpcount=0; |
$dumpcount=0; |
|
|
&logtouch(); |
&logtouch(); |
Line 2911 $readit=1;
|
Line 3684 $readit=1;
|
1; |
1; |
__END__ |
__END__ |
|
|
|
=pod |
|
|
=head1 NAME |
=head1 NAME |
|
|
Apache::lonnet - TCP networking package |
Apache::lonnet - Subroutines to ask questions about things in the network. |
|
|
=head1 SYNOPSIS |
=head1 SYNOPSIS |
|
|
Invoked by other LON-CAPA modules. |
Invoked by other LON-CAPA modules, when they need to talk to or about objects in the network. |
|
|
&Apache::lonnet::SUBROUTINENAME(ARGUMENTS); |
&Apache::lonnet::SUBROUTINENAME(ARGUMENTS); |
|
|
|
Common parameters: |
|
|
|
=over 4 |
|
|
|
=item * |
|
|
|
$uname : an internal username (if $cname expecting a course Id specifically) |
|
|
|
=item * |
|
|
|
$udom : a domain (if $cdom expecting a course's domain specifically) |
|
|
|
=item * |
|
|
|
$symb : a resource instance identifier |
|
|
|
=item * |
|
|
|
$namespace : the name of a .db file that contains the data needed or |
|
being set. |
|
|
|
=back |
|
|
=head1 INTRODUCTION |
=head1 INTRODUCTION |
|
|
This module provides subroutines which interact with the |
This module provides subroutines which interact with the |
lonc/lond (TCP) network layer of LON-CAPA. |
lonc/lond (TCP) network layer of LON-CAPA. And Can be used to ask about |
|
- classes |
|
- users |
|
- resources |
|
|
|
For many of these objects you can also use this to store data about |
|
them or modify them in various ways. |
|
|
This is part of the LearningOnline Network with CAPA project |
This is part of the LearningOnline Network with CAPA project |
described at http://www.lon-capa.org. |
described at http://www.lon-capa.org. |
|
|
=head1 HANDLER SUBROUTINE |
=head1 RETURN MESSAGES |
|
|
There is no handler routine for this module. |
|
|
|
=head1 OTHER SUBROUTINES |
|
|
|
=over 4 |
=over 4 |
|
|
=item * |
=item * |
|
|
logtouch() : make sure the logfile, lonnet.log, exists |
con_lost : unable to contact remote host |
|
|
=item * |
=item * |
|
|
logthis() : append message to lonnet.log |
con_delayed : unable to contact remote host, message will be delivered |
|
when the connection is brought back up |
|
|
=item * |
=item * |
|
|
logperm() : append a permanent message to lonnet.perm.log |
con_failed : unable to contact remote host and unable to save message |
|
for later delivery |
|
|
=item * |
=item * |
|
|
subreply() : non-critical communication, called by &reply |
error: : an error a occured, a description of the error follows the : |
|
|
=item * |
=item * |
|
|
reply() : makes two attempts to pass message; logs refusals and rejections |
no_such_host : unable to fund a host associated with the user/domain |
|
that was requested |
|
|
=item * |
=back |
|
|
reconlonc() : tries to reconnect lonc client processes. |
=head1 PUBLIC SUBROUTINES |
|
|
=item * |
=head2 Session Environment Functions |
|
|
critical() : passes a critical message to another server; if cannot get |
=over 4 |
through then place message in connection buffer |
|
|
|
=item * |
=item * |
|
|
appenv(%hash) : read in current user environment, append new environment |
appenv(%hash) : the value of %hash is written to the user envirnoment |
values to make new user environment |
file, and will be restored for each access this user makes during this |
|
session, also modifies the %ENV for the current process |
|
|
=item * |
=item * |
|
|
delenv($varname) : read in current user environment, remove all values |
delenv($regexp) : removes all items from the session environment file that matches the regular expression in $regexp. The values are also delted from the current processes %ENV. |
beginning with $varname, write new user environment (note: flock is used |
|
to prevent conflicting shared read/writes with file) |
|
|
|
=item * |
=back |
|
|
spareserver() : find server with least workload from spare.tab |
=head2 User Information |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
Line 2989 authentication scheme
|
Line 3792 authentication scheme
|
=item * |
=item * |
|
|
authenticate($uname,$upass,$udom) : try to authenticate user from domain's lib |
authenticate($uname,$upass,$udom) : try to authenticate user from domain's lib |
servers (first use the current one) |
servers (first use the current one), $upass should be the users password |
|
|
=item * |
=item * |
|
|
homeserver($uname,$udom) : find the homebase for a user from domain's lib |
homeserver($uname,$udom) : find the server which has the user's |
servers |
directory and files (there must be only one), this caches the answer, |
|
and also caches if there is a borken connection. |
|
|
=item * |
=item * |
|
|
idget($udom,@ids) : find the usernames behind a list of IDs (returns hash: |
idget($udom,@ids) : find the usernames behind a list of IDs (IDs are a |
|
unique resource in a domain, there must be only 1 ID per username, and |
|
only 1 username per ID in a specific domain) (returns hash: |
id=>name,id=>name) |
id=>name,id=>name) |
|
|
=item * |
=item * |
Line 3012 idput($udom,%ids) : store away a list of
|
Line 3818 idput($udom,%ids) : store away a list of
|
|
|
=item * |
=item * |
|
|
usection($domain,$user,$courseid) : output of section name/number or '' for |
rolesinit($udom,$username,$authhost) : get user privileges |
"not in course" and '-1' for "no section" |
|
|
|
=item * |
=item * |
|
|
userenvironment($domain,$user,$what) : puts out any environment parameter |
usection($udom,$uname,$cname) : finds the section of student in the |
for a user |
course $cname, return section name/number or '' for "not in course" |
|
and '-1' for "no section" |
|
|
=item * |
=item * |
|
|
subscribe($fname) : subscribe to a resource, return URL if possible |
userenvironment($udom,$uname,@what) : gets the values of the keys |
|
passed in @what from the requested user's environment, returns a hash |
|
|
|
=back |
|
|
|
=head2 User Roles |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
repcopy($filename) : replicate file |
allowed($priv,$uri) : check for a user privilege; returns codes for allowed |
|
actions |
|
F: full access |
|
U,I,K: authentication modes (cxx only) |
|
'': forbidden |
|
1: user needs to choose course |
|
2: browse allowed |
|
|
=item * |
=item * |
|
|
ssi($url,%hash) : server side include, does a complete request cycle on url to |
definerole($rolename,$sysrole,$domrole,$courole) : define role; define a custom |
localhost, posts hash |
role rolename set privileges in format of lonTabs/roles.tab for system, domain, |
|
and course level |
|
|
=item * |
=item * |
|
|
log($domain,$name,$home,$message) : write to permanent log for user; use |
plaintext($short) : return value in %prp hash (rolesplain.tab); plain text |
critical subroutine |
explanation of a user role term |
|
|
|
=back |
|
|
|
=head2 User Modification |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
flushcourselogs() : flush (save) buffer logs and access logs |
assignrole($udom,$uname,$url,$role,$end,$start) : assign role; give a role to a |
|
user for the level given by URL. Optional start and end dates (leave empty |
|
string or zero for "no date") |
|
|
=item * |
=item * |
|
|
courselog($what) : save message for course in hash |
changepass($uname,$udom,$currentpass,$newpass,$server) : attempts to |
|
change a users, password, possible return values are: ok, |
|
pwchange_failure, non_authorized, auth_mode_error, unknown_user, |
|
refused |
|
|
=item * |
=item * |
|
|
courseacclog($what) : save message for course using &courselog(). Perform |
modifyuserauth($udom,$uname,$umode,$upass) : modify user authentication |
special processing for specific resource types (problems, exams, quizzes, etc). |
|
|
|
=item * |
=item * |
|
|
countacc($url) : count the number of accesses to a given URL |
modifyuser($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene) : |
|
modify user |
|
|
=item * |
=item * |
|
|
sub checkout($symb,$tuname,$tudom,$tcrsid) : check out an item |
modifystudent |
|
|
|
modify a students enrollment and identification information. |
|
The course id is resolved based on the current users environment. |
|
This means the envoking user must be a course coordinator or otherwise |
|
associated with a course. |
|
|
|
This call is essentially a wrapper for lonnet::modifyuser and |
|
lonnet::modify_student_enrollment |
|
|
|
Inputs: |
|
|
|
=over 4 |
|
|
|
=item B<$udom> Students loncapa domain |
|
|
|
=item B<$uname> Students loncapa login name |
|
|
|
=item B<$uid> Students id/student number |
|
|
|
=item B<$umode> Students authentication mode |
|
|
|
=item B<$upass> Students password |
|
|
|
=item B<$first> Students first name |
|
|
|
=item B<$middle> Students middle name |
|
|
|
=item B<$last> Students last name |
|
|
|
=item B<$gene> Students generation |
|
|
|
=item B<$usec> Students section in course |
|
|
|
=item B<$end> Unix time of the roles expiration |
|
|
|
=item B<$start> Unix time of the roles start date |
|
|
|
=item B<$forceid> If defined, allow $uid to be changed |
|
|
|
=item B<$desiredhome> server to use as home server for student |
|
|
|
=back |
|
|
=item * |
=item * |
|
|
sub checkin($token) : check in an item |
modify_student_enrollment |
|
|
|
Change a students enrollment status in a class. The environment variable |
|
'role.request.course' must be defined for this function to proceed. |
|
|
|
Inputs: |
|
|
|
=over 4 |
|
|
|
=item $udom, students domain |
|
|
|
=item $uname, students name |
|
|
|
=item $uid, students user id |
|
|
|
=item $first, students first name |
|
|
|
=item $middle |
|
|
|
=item $last |
|
|
|
=item $gene |
|
|
|
=item $usec |
|
|
|
=item $end |
|
|
|
=item $start |
|
|
|
=back |
|
|
|
|
=item * |
=item * |
|
|
sub expirespread($uname,$udom,$stype,$usymb) : set expire date for spreadsheet |
assigncustomrole($udom,$uname,$url,$rdom,$rnam,$rolename,$end,$start) : assign |
|
custom role; give a custom role to a user for the level given by URL. Specify |
|
name and domain of role author, and role name |
|
|
=item * |
=item * |
|
|
devalidate($symb) : devalidate spreadsheets |
revokerole($udom,$uname,$url,$role) : revoke a role for url |
|
|
=item * |
=item * |
|
|
hash2str(%hash) : convert a hash into a string complete with escaping and '=' |
revokecustomrole($udom,$uname,$url,$role) : revoke a custom role |
and '&' separators, supports elements that are arrayrefs and hashrefs |
|
|
=back |
|
|
|
=head2 Course Infomation |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
hashref2str($hashref) : convert a hashref into a string complete with |
coursedescription($courseid) : course description |
escaping and '=' and '&' separators, supports elements that are |
|
arrayrefs and hashrefs |
|
|
|
=item * |
=item * |
|
|
arrayref2str($arrayref) : convert an arrayref into a string complete |
courseresdata($coursenum,$coursedomain,@which) : request for current |
with escaping and '&' separators, supports elements that are arrayrefs |
parameter setting for a specific course, @what should be a list of |
and hashrefs |
parameters to ask about. This routine caches answers for 5 minutes. |
|
|
|
=back |
|
|
|
=head2 Course Modification |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
str2hash($string) : convert string to hash using unescaping and |
writecoursepref($courseid,%prefs) : write preferences (environment |
splitting on '=' and '&', supports elements that are arrayrefs and |
database) for a course |
hashrefs |
|
|
|
=item * |
=item * |
|
|
str2array($string) : convert string to hash using unescaping and |
createcourse($udom,$description,$url) : make/modify course |
splitting on '&', supports elements that are arrayrefs and hashrefs |
|
|
=back |
|
|
|
=head2 Resource Subroutines |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
tmpreset($symb,$namespace,$domain,$stuname) : temporary storage |
subscribe($fname) : subscribe to a resource, returns URL if possible (probably should use repcopy instead) |
|
|
=item * |
=item * |
|
|
tmprestore($symb,$namespace,$domain,$stuname) : temporary restore |
repcopy($filename) : subscribes to the requested file, and attempts to |
|
replicate from the owning library server, Might return |
|
HTTP_SERVICE_UNAVAILABLE, HTTP_NOT_FOUND, FORBIDDEN, OK, or |
|
HTTP_BAD_REQUEST, also attempts to grab the metadata for the |
|
resource. Expects the local filesystem pathname |
|
(/home/httpd/html/res/....) |
|
|
|
=back |
|
|
|
=head2 Resource Information |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
store($storehash,$symb,$namespace,$domain,$stuname) : stores hash permanently |
EXT($varname,$symb,$udom,$uname) : evaluates and returns the value of |
for this url; hashref needs to be given and should be a \%hashname; the |
a vairety of different possible values, $varname should be a request |
remaining args aren't required and if they aren't passed or are '' they will |
string, and the other parameters can be used to specify who and what |
be derived from the ENV |
one is asking about. |
|
|
|
Possible values for $varname are environment.lastname (or other item |
|
from the envirnment hash), user.name (or someother aspect about the |
|
user), resource.0.maxtries (or some other part and parameter of a |
|
resource) |
|
|
=item * |
=item * |
|
|
cstore($storehash,$symb,$namespace,$domain,$stuname) : same as store but |
directcondval($number) : get current value of a condition; reads from a state |
uses critical subroutine |
string |
|
|
=item * |
=item * |
|
|
restore($symb,$namespace,$domain,$stuname) : returns hash for this symb; |
condval($condidx) : value of condition index based on state |
all args are optional |
|
|
|
=item * |
=item * |
|
|
coursedescription($courseid) : course description |
metadata($uri,$what,$liburi,$prefix,$depthcount) : request a |
|
resource's metadata, $what should be either a specific key, or either |
|
'keys' (to get a list of possible keys) or 'packages' to get a list of |
|
packages that this resource currently uses, the last 3 arguments are only used internally for recursive metadata. |
|
|
|
this function automatically caches all requests |
|
|
=item * |
=item * |
|
|
rolesinit($domain,$username,$authhost) : get user privileges |
metadata_query($query,$custom,$customshow) : make a metadata query against the |
|
network of library servers; returns file handle of where SQL and regex results |
|
will be stored for query |
|
|
=item * |
=item * |
|
|
get($namespace,$storearr,$udomain,$uname) : returns hash with keys from array |
symbread($filename) : return symbolic list entry (filename argument optional); |
reference filled in from namesp ($udomain and $uname are optional) |
returns the data handle |
|
|
=item * |
=item * |
|
|
del($namespace,$storearr,$udomain,$uname) : deletes keys out of array from |
symbverify($symb,$thisfn) : verifies that $symb actually exists and is |
namesp ($udomain and $uname are optional) |
a possible symb for the URL in $thisfn, returns a 1 on success, 0 on |
|
failure, user must be in a course, as it assumes the existance of the |
|
course initi hash, and uses $ENV('request.course.id'} |
|
|
|
|
=item * |
=item * |
|
|
dump($namespace,$udomain,$uname,$regexp) : |
symbclean($symb) : removes versions numbers from a symb, returns the |
dumps the complete (or key matching regexp) namespace into a hash |
cleaned symb |
($udomain, $uname and $regexp are optional) |
|
|
|
=item * |
=item * |
|
|
put($namespace,$storehash,$udomain,$uname) : stores hash in namesp |
is_on_map($uri) : checks if the $uri is somewhere on the current |
($udomain and $uname are optional) |
course map, user must be in a course for it to work. |
|
|
=item * |
=item * |
|
|
cput($namespace,$storehash,$udomain,$uname) : critical put |
numval($salt) : return random seed value (addend for rndseed) |
($udomain and $uname are optional) |
|
|
|
=item * |
=item * |
|
|
eget($namespace,$storearr,$udomain,$uname) : returns hash with keys from array |
rndseed($symb,$courseid,$udom,$uname) : create a random sum; returns |
reference filled in from namesp (encrypts the return communication) |
a random seed, all arguments are optional, if they aren't sent it uses the |
($udomain and $uname are optional) |
environment to derive them. Note: if symb isn't sent and it can't get one |
|
from &symbread it will use the current time as its return value |
|
|
=item * |
=item * |
|
|
allowed($priv,$uri) : check for a user privilege; returns codes for allowed |
ireceipt($funame,$fudom,$fucourseid,$fusymb) : return unique, |
actions |
unfakeable, receipt |
F: full access |
|
U,I,K: authentication modes (cxx only) |
|
'': forbidden |
|
1: user needs to choose course |
|
2: browse allowed |
|
|
|
=item * |
=item * |
|
|
definerole($rolename,$sysrole,$domrole,$courole) : define role; define a custom |
receipt() : API to ireceipt working off of ENV values; given out to users |
role rolename set privileges in format of lonTabs/roles.tab for system, domain, |
|
and course level |
|
|
|
=item * |
=item * |
|
|
metadata_query($query,$custom,$customshow) : make a metadata query against the |
countacc($url) : count the number of accesses to a given URL |
network of library servers; returns file handle of where SQL and regex results |
|
will be stored for query |
|
|
|
=item * |
=item * |
|
|
plaintext($short) : return value in %prp hash (rolesplain.tab); plain text |
checkout($symb,$tuname,$tudom,$tcrsid) : creates a record of a user having looked at an item, most likely printed out or otherwise using a resource |
explanation of a user role term |
|
|
|
=item * |
=item * |
|
|
assignrole($udom,$uname,$url,$role,$end,$start) : assign role; give a role to a |
checkin($token) : updates that a resource has beeen returned (a hard copy version for instance) and returns the data that $token was Checkout with ($symb, $tuname, $tudom, and $tcrsid) |
user for the level given by URL. Optional start and end dates (leave empty |
|
string or zero for "no date") |
|
|
|
=item * |
=item * |
|
|
modifyuserauth($udom,$uname,$umode,$upass) : modify user authentication |
expirespread($uname,$udom,$stype,$usymb) : set expire date for spreadsheet |
|
|
=item * |
=item * |
|
|
modifyuser($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene) : |
devalidate($symb) : devalidate temporary spreadsheet calculations, |
modify user |
forcing spreadsheet to reevaluate the resource scores next time. |
|
|
|
=back |
|
|
|
=head2 Storing/Retreiving Data |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
modifystudent($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec, |
store($storehash,$symb,$namespace,$udom,$uname) : stores hash permanently |
$end,$start) : modify student |
for this url; hashref needs to be given and should be a \%hashname; the |
|
remaining args aren't required and if they aren't passed or are '' they will |
|
be derived from the ENV |
|
|
=item * |
=item * |
|
|
writecoursepref($courseid,%prefs) : write preferences for a course |
cstore($storehash,$symb,$namespace,$udom,$uname) : same as store but |
|
uses critical subroutine |
|
|
=item * |
=item * |
|
|
createcourse($udom,$description,$url) : make/modify course |
restore($symb,$namespace,$udom,$uname) : returns hash for this symb; |
|
all args are optional |
|
|
=item * |
=item * |
|
|
assigncustomrole($udom,$uname,$url,$rdom,$rnam,$rolename,$end,$start) : assign |
tmpstore($storehash,$symb,$namespace,$udom,$uname) : storage that |
custom role; give a custom role to a user for the level given by URL. Specify |
works very similar to store/cstore, but all data is stored in a |
name and domain of role author, and role name |
temporary location and can be reset using tmpreset, $storehash should |
|
be a hash reference, returns nothing on success |
|
|
=item * |
=item * |
|
|
revokerole($udom,$uname,$url,$role) : revoke a role for url |
tmprestore($symb,$namespace,$udom,$uname) : storage that works very |
|
similar to restore, but all data is stored in a temporary location and |
|
can be reset using tmpreset. Returns a hash of values on success, |
|
error string otherwise. |
|
|
=item * |
=item * |
|
|
revokecustomrole($udom,$uname,$url,$role) : revoke a custom role |
tmpreset($symb,$namespace,$udom,$uname) : temporary storage reset, |
|
deltes all keys for $symb form the temporary storage hash. |
|
|
|
=item * |
|
|
|
get($namespace,$storearr,$udom,$uname) : returns hash with keys from array |
|
reference filled in from namesp ($udom and $uname are optional) |
|
|
|
=item * |
|
|
|
del($namespace,$storearr,$udom,$uname) : deletes keys out of array from |
|
namesp ($udom and $uname are optional) |
|
|
|
=item * |
|
|
|
dump($namespace,$udom,$uname,$regexp) : |
|
dumps the complete (or key matching regexp) namespace into a hash |
|
($udom, $uname and $regexp are optional) |
|
|
|
=item * |
|
|
|
put($namespace,$storehash,$udom,$uname) : stores hash in namesp |
|
($udom and $uname are optional) |
|
|
|
=item * |
|
|
|
cput($namespace,$storehash,$udom,$uname) : critical put |
|
($udom and $uname are optional) |
|
|
|
=item * |
|
|
|
eget($namespace,$storearr,$udom,$uname) : returns hash with keys from array |
|
reference filled in from namesp (encrypts the return communication) |
|
($udom and $uname are optional) |
|
|
|
=item * |
|
|
|
log($udom,$name,$home,$message) : write to permanent log for user; use |
|
critical subroutine |
|
|
|
=back |
|
|
|
=head2 Network Status Functions |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
Line 3239 dirlist($uri) : return directory list ba
|
Line 4227 dirlist($uri) : return directory list ba
|
|
|
=item * |
=item * |
|
|
directcondval($number) : get current value of a condition; reads from a state |
spareserver() : find server with least workload from spare.tab |
string |
|
|
=back |
|
|
|
=head2 Apache Request |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
condval($condidx) : value of condition index based on state |
ssi($url,%hash) : server side include, does a complete request cycle on url to |
|
localhost, posts hash |
|
|
|
=back |
|
|
|
=head2 Data to String to Data |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
EXT($varname,$symbparm) : value of a variable |
hash2str(%hash) : convert a hash into a string complete with escaping and '=' |
|
and '&' separators, supports elements that are arrayrefs and hashrefs |
|
|
=item * |
=item * |
|
|
metadata($uri,$what,$liburi,$prefix,$depthcount) : get metadata; returns the |
hashref2str($hashref) : convert a hashref into a string complete with |
metadata entry for a file; entry='keys', returns a comma separated list of keys |
escaping and '=' and '&' separators, supports elements that are |
|
arrayrefs and hashrefs |
|
|
=item * |
=item * |
|
|
symblist($mapname,%newhash) : update symbolic storage links |
arrayref2str($arrayref) : convert an arrayref into a string complete |
|
with escaping and '&' separators, supports elements that are arrayrefs |
|
and hashrefs |
|
|
=item * |
=item * |
|
|
symbread($filename) : return symbolic list entry (filename argument optional); |
str2hash($string) : convert string to hash using unescaping and |
returns the data handle |
splitting on '=' and '&', supports elements that are arrayrefs and |
|
hashrefs |
|
|
=item * |
=item * |
|
|
numval($salt) : return random seed value (addend for rndseed) |
str2array($string) : convert string to hash using unescaping and |
|
splitting on '&', supports elements that are arrayrefs and hashrefs |
|
|
|
=back |
|
|
|
=head2 Logging Routines |
|
|
|
=over 4 |
|
|
|
These routines allow one to make log messages in the lonnet.log and |
|
lonnet.perm logfiles. |
|
|
=item * |
=item * |
|
|
rndseed($symb,$courseid,$domain,$username) : create a random sum; returns |
logtouch() : make sure the logfile, lonnet.log, exists |
a random seed, all arguments are optional, if they aren't sent it uses the |
|
environment to derive them. Note: if symb isn't sent and it can't get one |
|
from &symbread it will use the current time as its return value |
|
|
|
=item * |
=item * |
|
|
ireceipt($funame,$fudom,$fucourseid,$fusymb) : return unique, |
logthis() : append message to the normal lonnet.log file, it gets |
unfakeable, receipt |
preiodically rolled over and deleted. |
|
|
=item * |
=item * |
|
|
receipt() : API to ireceipt working off of ENV values; given out to users |
logperm() : append a permanent message to lonnet.perm.log, this log |
|
file never gets deleted by any automated portion of the system, only |
|
messages of critical importance should go in here. |
|
|
|
=back |
|
|
|
=head2 General File Helper Routines |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
getfile($file) : serves up a file, returns the contents of a file or -1; |
getfile($file) : returns the entire contents of a file or -1; it |
replicates and subscribes to the file |
properly subscribes to and replicates the file if neccessary. |
|
|
=item * |
=item * |
|
|
filelocation($dir,$file) : returns file system location of a file based on URI; |
filelocation($dir,$file) : returns file system location of a file |
meant to be "fairly clean" absolute reference, $dir is a directory that relative $file lookups are to looked in ($dir of /a/dir and a file of ../bob will become /a/bob) |
based on URI; meant to be "fairly clean" absolute reference, $dir is a |
|
directory that relative $file lookups are to looked in ($dir of /a/dir |
|
and a file of ../bob will become /a/bob) |
|
|
=item * |
=item * |
|
|
Line 3303 filelocation except for hrefs
|
Line 4325 filelocation except for hrefs
|
|
|
declutter() : declutters URLs (remove docroot, beginning slashes, 'res' etc) |
declutter() : declutters URLs (remove docroot, beginning slashes, 'res' etc) |
|
|
|
=back |
|
|
|
=head2 HTTP Helper Routines |
|
|
|
=over 4 |
|
|
=item * |
=item * |
|
|
escape() : unpack non-word characters into CGI-compatible hex codes |
escape() : unpack non-word characters into CGI-compatible hex codes |
Line 3311 escape() : unpack non-word characters in
|
Line 4339 escape() : unpack non-word characters in
|
|
|
unescape() : pack CGI-compatible hex codes into actual non-word ASCII character |
unescape() : pack CGI-compatible hex codes into actual non-word ASCII character |
|
|
|
=back |
|
|
|
=head1 PRIVATE SUBROUTINES |
|
|
|
=head2 Underlying communication routines (Shouldn't call) |
|
|
|
=over 4 |
|
|
|
=item * |
|
|
|
subreply() : tries to pass a message to lonc, returns con_lost if incapable |
|
|
|
=item * |
|
|
|
reply() : uses subreply to send a message to remote machine, logs all failures |
|
|
|
=item * |
|
|
|
critical() : passes a critical message to another server; if cannot |
|
get through then place message in connection buffer directory and |
|
returns con_delayed, if incapable of saving message, returns |
|
con_failed |
|
|
|
=item * |
|
|
|
reconlonc() : tries to reconnect lonc client processes. |
|
|
|
=back |
|
|
|
=head2 Resource Access Logging |
|
|
|
=over 4 |
|
|
|
=item * |
|
|
|
flushcourselogs() : flush (save) buffer logs and access logs |
|
|
|
=item * |
|
|
|
courselog($what) : save message for course in hash |
|
|
|
=item * |
|
|
|
courseacclog($what) : save message for course using &courselog(). Perform |
|
special processing for specific resource types (problems, exams, quizzes, etc). |
|
|
=item * |
=item * |
|
|
goodbye() : flush course logs and log shutting down; it is called in srm.conf |
goodbye() : flush course logs and log shutting down; it is called in srm.conf |
Line 3318 as a PerlChildExitHandler
|
Line 4392 as a PerlChildExitHandler
|
|
|
=back |
=back |
|
|
|
=head2 Other |
|
|
|
=over 4 |
|
|
|
=item * |
|
|
|
symblist($mapname,%newhash) : update symbolic storage links |
|
|
|
=back |
|
|
=cut |
=cut |