version 1.1190, 2012/09/04 20:48:05
|
version 1.1230, 2013/07/09 00:17:27
|
Line 78 use Image::Magick;
|
Line 78 use Image::Magick;
|
|
|
use Encode; |
use Encode; |
|
|
use vars qw(%perlvar %spareid %pr %prp $memcache %packagetab $tmpdir |
use vars qw(%perlvar %spareid %pr %prp $memcache %packagetab $tmpdir $apache |
$_64bit %env %protocol %loncaparevs %serverhomeIDs %needsrelease |
$_64bit %env %protocol %loncaparevs %serverhomeIDs %needsrelease |
%managerstab); |
%managerstab); |
|
|
Line 634 sub check_for_valid_session {
|
Line 634 sub check_for_valid_session {
|
|| !defined($disk_env{'user.domain'})) { |
|| !defined($disk_env{'user.domain'})) { |
return undef; |
return undef; |
} |
} |
|
if (($r->user() eq '') && ($apache >= 2.4)) { |
|
if ($disk_env{'user.domain'} eq $r->dir_config('lonDefDomain')) { |
|
$r->user($disk_env{'user.name'}); |
|
} else { |
|
$r->user($disk_env{'user.name'}.':'.$disk_env{'user.domain'}); |
|
} |
|
} |
return $handle; |
return $handle; |
} |
} |
|
|
Line 1240 sub get_lonbalancer_config {
|
Line 1247 sub get_lonbalancer_config {
|
|
|
sub check_loadbalancing { |
sub check_loadbalancing { |
my ($uname,$udom) = @_; |
my ($uname,$udom) = @_; |
my ($is_balancer,$dom_in_use,$homeintdom,$rule_in_effect, |
my ($is_balancer,$currtargets,$currrules,$dom_in_use,$homeintdom, |
$offloadto,$otherserver); |
$rule_in_effect,$offloadto,$otherserver); |
my $lonhost = $perlvar{'lonHostID'}; |
my $lonhost = $perlvar{'lonHostID'}; |
my @hosts = ¤t_machine_ids(); |
my @hosts = ¤t_machine_ids(); |
my $uprimary_id = &Apache::lonnet::domain($udom,'primary'); |
my $uprimary_id = &Apache::lonnet::domain($udom,'primary'); |
Line 1266 sub check_loadbalancing {
|
Line 1273 sub check_loadbalancing {
|
} |
} |
} |
} |
if (ref($result) eq 'HASH') { |
if (ref($result) eq 'HASH') { |
my $currbalancer = $result->{'lonhost'}; |
($is_balancer,$currtargets,$currrules) = |
my $currtargets = $result->{'targets'}; |
&check_balancer_result($result,@hosts); |
my $currrules = $result->{'rules'}; |
|
if ($currbalancer ne '') { |
|
if (grep(/^\Q$currbalancer\E$/,@hosts)) { |
|
$is_balancer = 1; |
|
} |
|
} |
|
if ($is_balancer) { |
if ($is_balancer) { |
if (ref($currrules) eq 'HASH') { |
if (ref($currrules) eq 'HASH') { |
if ($homeintdom) { |
if ($homeintdom) { |
Line 1331 sub check_loadbalancing {
|
Line 1332 sub check_loadbalancing {
|
} |
} |
} |
} |
if (ref($result) eq 'HASH') { |
if (ref($result) eq 'HASH') { |
my $currbalancer = $result->{'lonhost'}; |
($is_balancer,$currtargets,$currrules) = |
my $currtargets = $result->{'targets'}; |
&check_balancer_result($result,@hosts); |
my $currrules = $result->{'rules'}; |
if ($is_balancer) { |
|
|
if ($currbalancer eq $lonhost) { |
|
$is_balancer = 1; |
|
if (ref($currrules) eq 'HASH') { |
if (ref($currrules) eq 'HASH') { |
if ($currrules->{'_LC_internetdom'} ne '') { |
if ($currrules->{'_LC_internetdom'} ne '') { |
$rule_in_effect = $currrules->{'_LC_internetdom'}; |
$rule_in_effect = $currrules->{'_LC_internetdom'}; |
Line 1400 sub check_loadbalancing {
|
Line 1398 sub check_loadbalancing {
|
return ($is_balancer,$otherserver); |
return ($is_balancer,$otherserver); |
} |
} |
|
|
|
sub check_balancer_result { |
|
my ($result,@hosts) = @_; |
|
my ($is_balancer,$currtargets,$currrules); |
|
if (ref($result) eq 'HASH') { |
|
if ($result->{'lonhost'} ne '') { |
|
my $currbalancer = $result->{'lonhost'}; |
|
if (grep(/^\Q$currbalancer\E$/,@hosts)) { |
|
$is_balancer = 1; |
|
$currtargets = $result->{'targets'}; |
|
$currrules = $result->{'rules'}; |
|
} |
|
} else { |
|
foreach my $key (keys(%{$result})) { |
|
if (($key ne '') && (grep(/^\Q$key\E$/,@hosts)) && |
|
(ref($result->{$key}) eq 'HASH')) { |
|
$is_balancer = 1; |
|
$currrules = $result->{$key}{'rules'}; |
|
$currtargets = $result->{$key}{'targets'}; |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
return ($is_balancer,$currtargets,$currrules); |
|
} |
|
|
sub get_loadbalancer_targets { |
sub get_loadbalancer_targets { |
my ($rule_in_effect,$currtargets,$uname,$udom) = @_; |
my ($rule_in_effect,$currtargets,$uname,$udom) = @_; |
my $offloadto; |
my $offloadto; |
Line 1961 sub get_domain_defaults {
|
Line 1985 sub get_domain_defaults {
|
$domdefaults{'defaultquota'} = $domconfig{'quotas'}{'defaultquota'}; |
$domdefaults{'defaultquota'} = $domconfig{'quotas'}{'defaultquota'}; |
} else { |
} else { |
$domdefaults{'defaultquota'} = $domconfig{'quotas'}; |
$domdefaults{'defaultquota'} = $domconfig{'quotas'}; |
} |
} |
my @usertools = ('aboutme','blog','webdav','portfolio'); |
my @usertools = ('aboutme','blog','webdav','portfolio'); |
foreach my $item (@usertools) { |
foreach my $item (@usertools) { |
if (ref($domconfig{'quotas'}{$item}) eq 'HASH') { |
if (ref($domconfig{'quotas'}{$item}) eq 'HASH') { |
$domdefaults{$item} = $domconfig{'quotas'}{$item}; |
$domdefaults{$item} = $domconfig{'quotas'}{$item}; |
} |
} |
} |
} |
|
if (ref($domconfig{'quotas'}{'authorquota'}) eq 'HASH') { |
|
$domdefaults{'authorquota'} = $domconfig{'quotas'}{'authorquota'}; |
|
} |
} |
} |
if (ref($domconfig{'requestcourses'}) eq 'HASH') { |
if (ref($domconfig{'requestcourses'}) eq 'HASH') { |
foreach my $item ('official','unofficial','community') { |
foreach my $item ('official','unofficial','community') { |
Line 1983 sub get_domain_defaults {
|
Line 2010 sub get_domain_defaults {
|
} |
} |
} |
} |
if (ref($domconfig{'coursedefaults'}) eq 'HASH') { |
if (ref($domconfig{'coursedefaults'}) eq 'HASH') { |
foreach my $item ('canuse_pdfforms') { |
$domdefaults{'canuse_pdfforms'} = $domconfig{'coursedefaults'}{'canuse_pdfforms'}; |
$domdefaults{$item} = $domconfig{'coursedefaults'}{$item}; |
if (ref($domconfig{'coursedefaults'}{'coursecredits'}) eq 'HASH') { |
|
$domdefaults{'officialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'official'}; |
|
$domdefaults{'unofficialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'}; |
|
} |
|
if (ref($domconfig{'coursedefaults'}{'uploadquota'}) eq 'HASH') { |
|
$domdefaults{'officialquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'official'}; |
|
$domdefaults{'unofficialquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'unofficial'}; |
|
$domdefaults{'communityquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'community'}; |
} |
} |
} |
} |
if (ref($domconfig{'usersessions'}) eq 'HASH') { |
if (ref($domconfig{'usersessions'}) eq 'HASH') { |
Line 1995 sub get_domain_defaults {
|
Line 2029 sub get_domain_defaults {
|
$domdefaults{'hostedsessions'} = $domconfig{'usersessions'}{'hosted'}; |
$domdefaults{'hostedsessions'} = $domconfig{'usersessions'}{'hosted'}; |
} |
} |
} |
} |
&Apache::lonnet::do_cache_new('domdefaults',$domain,\%domdefaults, |
&do_cache_new('domdefaults',$domain,\%domdefaults,$cachetime); |
$cachetime); |
|
return %domdefaults; |
return %domdefaults; |
} |
} |
|
|
Line 2628 sub allowuploaded {
|
Line 2661 sub allowuploaded {
|
&Apache::lonnet::appenv(\%httpref); |
&Apache::lonnet::appenv(\%httpref); |
} |
} |
|
|
|
# |
|
# Determine if the current user should be able to edit a particular resource, |
|
# when viewing in course context. |
|
# (a) When viewing resource used to determine if "Edit" item is included in |
|
# Functions. |
|
# (b) When displaying folder contents in course editor, used to determine if |
|
# "Edit" link will be displayed alongside resource. |
|
# |
|
# input: six args -- filename (decluttered), course number, course domain, |
|
# url, symb (if registered) and group (if this is a group |
|
# item -- e.g., bulletin board, group page etc.). |
|
# output: array of five scalars -- |
|
# $cfile -- url for file editing if editable on current server |
|
# $home -- homeserver of resource (i.e., for author if published, |
|
# or course if uploaded.). |
|
# $switchserver -- 1 if server switch will be needed. |
|
# $forceedit -- 1 if icon/link should be to go to edit mode |
|
# $forceview -- 1 if icon/link should be to go to view mode |
|
# |
|
|
|
sub can_edit_resource { |
|
my ($file,$cnum,$cdom,$resurl,$symb,$group) = @_; |
|
my ($cfile,$home,$switchserver,$forceedit,$forceview,$uploaded,$incourse); |
|
# |
|
# For aboutme pages user can only edit his/her own. |
|
# |
|
if ($resurl =~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) { |
|
my ($sdom,$sname) = ($1,$2); |
|
if (($sdom eq $env{'user.domain'}) && ($sname eq $env{'user.name'})) { |
|
$home = $env{'user.home'}; |
|
$cfile = $resurl; |
|
if ($env{'form.forceedit'}) { |
|
$forceview = 1; |
|
} else { |
|
$forceedit = 1; |
|
} |
|
return ($cfile,$home,$switchserver,$forceedit,$forceview); |
|
} else { |
|
return; |
|
} |
|
} |
|
|
|
if ($env{'request.course.id'}) { |
|
my $crsedit = &Apache::lonnet::allowed('mdc',$env{'request.course.id'}); |
|
if ($group ne '') { |
|
# if this is a group homepage or group bulletin board, check group privs |
|
my $allowed = 0; |
|
if ($resurl =~ m{^/?adm/$cdom/$cnum/$group/smppg$}) { |
|
if ((&allowed('mdg',$env{'request.course.id'}. |
|
($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) || |
|
(&allowed('mgh',$env{'request.course.id'}.'/'.$group)) || $crsedit) { |
|
$allowed = 1; |
|
} |
|
} elsif ($resurl =~ m{^/?adm/$cdom/$cnum/\d+/bulletinboard$}) { |
|
if ((&allowed('mdg',$env{'request.course.id'}.($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))) || |
|
(&allowed('cgb',$env{'request.course.id'}.'/'.$group)) || $crsedit) { |
|
$allowed = 1; |
|
} |
|
} |
|
if ($allowed) { |
|
$home=&homeserver($cnum,$cdom); |
|
if ($env{'form.forceedit'}) { |
|
$forceview = 1; |
|
} else { |
|
$forceedit = 1; |
|
} |
|
$cfile = $resurl; |
|
} else { |
|
return; |
|
} |
|
} else { |
|
if ($resurl =~ m{^/?adm/viewclasslist$}) { |
|
unless (&Apache::lonnet::allowed('opa',$env{'request.course.id'})) { |
|
return; |
|
} |
|
} elsif (!$crsedit) { |
|
# |
|
# No edit allowed where CC has switched to student role. |
|
# |
|
return; |
|
} |
|
} |
|
} |
|
|
|
if ($file ne '') { |
|
if (($cnum =~ /$match_courseid/) && ($cdom =~ /$match_domain/)) { |
|
if (&is_course_upload($file,$cnum,$cdom)) { |
|
$uploaded = 1; |
|
$incourse = 1; |
|
if ($file =~/\.(htm|html|css|js|txt)$/) { |
|
$cfile = &hreflocation('',$file); |
|
if ($env{'form.forceedit'}) { |
|
$forceview = 1; |
|
} else { |
|
$forceedit = 1; |
|
} |
|
} |
|
} elsif ($resurl =~ m{^/public/$cdom/$cnum/syllabus}) { |
|
$incourse = 1; |
|
if ($env{'form.forceedit'}) { |
|
$forceview = 1; |
|
} else { |
|
$forceedit = 1; |
|
} |
|
$cfile = $resurl; |
|
} elsif (($resurl ne '') && (&is_on_map($resurl))) { |
|
if ($resurl =~ m{^/adm/$match_domain/$match_username/\d+/smppg|bulletinboard$}) { |
|
$incourse = 1; |
|
if ($env{'form.forceedit'}) { |
|
$forceview = 1; |
|
} else { |
|
$forceedit = 1; |
|
} |
|
$cfile = $resurl; |
|
} elsif ($resurl eq '/res/lib/templates/simpleproblem.problem') { |
|
$incourse = 1; |
|
$cfile = $resurl.'/smpedit'; |
|
} elsif ($resurl =~ m{^/adm/wrapper/ext/}) { |
|
$incourse = 1; |
|
if ($env{'form.forceedit'}) { |
|
$forceview = 1; |
|
} else { |
|
$forceedit = 1; |
|
} |
|
$cfile = $resurl; |
|
} elsif ($resurl =~ m{^/?adm/viewclasslist$}) { |
|
$incourse = 1; |
|
if ($env{'form.forceedit'}) { |
|
$forceview = 1; |
|
} else { |
|
$forceedit = 1; |
|
} |
|
$cfile = ($resurl =~ m{^/} ? $resurl : "/$resurl"); |
|
} |
|
} elsif ($resurl eq '/res/lib/templates/simpleproblem.problem/smpedit') { |
|
my $template = '/res/lib/templates/simpleproblem.problem'; |
|
if (&is_on_map($template)) { |
|
$incourse = 1; |
|
$forceview = 1; |
|
$cfile = $template; |
|
} |
|
} elsif (($resurl =~ m{^/adm/wrapper/ext/}) && ($env{'form.folderpath'} =~ /^supplemental/)) { |
|
$incourse = 1; |
|
if ($env{'form.forceedit'}) { |
|
$forceview = 1; |
|
} else { |
|
$forceedit = 1; |
|
} |
|
$cfile = $resurl; |
|
} elsif (($resurl eq '/adm/extresedit') && ($symb || $env{'form.folderpath'})) { |
|
$incourse = 1; |
|
$forceview = 1; |
|
if ($symb) { |
|
my ($map,$id,$res)=&decode_symb($symb); |
|
$env{'request.symb'} = $symb; |
|
$cfile = &clutter($res); |
|
} else { |
|
$cfile = $env{'form.suppurl'}; |
|
$cfile =~ s{^http://}{}; |
|
$cfile = '/adm/wrapper/ext/'.$cfile; |
|
} |
|
} |
|
} |
|
if ($uploaded || $incourse) { |
|
$home=&homeserver($cnum,$cdom); |
|
} elsif ($file !~ m{/$}) { |
|
$file=~s{^(priv/$match_domain/$match_username)}{/$1}; |
|
$file=~s{^($match_domain/$match_username)}{/priv/$1}; |
|
# Check that the user has permission to edit this resource |
|
my $setpriv = 1; |
|
my ($cfuname,$cfudom)=&constructaccess($file,$setpriv); |
|
if (defined($cfudom)) { |
|
$home=&homeserver($cfuname,$cfudom); |
|
$cfile=$file; |
|
} |
|
} |
|
if (($cfile ne '') && (!$incourse || $uploaded) && |
|
(($home ne '') && ($home ne 'no_host'))) { |
|
my @ids=¤t_machine_ids(); |
|
unless (grep(/^\Q$home\E$/,@ids)) { |
|
$switchserver=1; |
|
} |
|
} |
|
} |
|
return ($cfile,$home,$switchserver,$forceedit,$forceview); |
|
} |
|
|
|
sub is_course_upload { |
|
my ($file,$cnum,$cdom) = @_; |
|
my $uploadpath = &LONCAPA::propath($cdom,$cnum); |
|
$uploadpath =~ s{^\/}{}; |
|
if (($file =~ m{^\Q$uploadpath\E/userfiles/(docs|supplemental)/}) || |
|
($file =~ m{^userfiles/\Q$cdom\E/\Q$cnum\E/(docs|supplemental)/})) { |
|
return 1; |
|
} |
|
return; |
|
} |
|
|
|
sub in_course { |
|
my ($udom,$uname,$cdom,$cnum,$type,$hideprivileged) = @_; |
|
if ($hideprivileged) { |
|
my $skipuser; |
|
my %coursehash = &coursedescription($cdom.'_'.$cnum); |
|
my @possdoms = ($cdom); |
|
if ($coursehash{'checkforpriv'}) { |
|
push(@possdoms,split(/,/,$coursehash{'checkforpriv'})); |
|
} |
|
if (&privileged($uname,$udom,\@possdoms)) { |
|
$skipuser = 1; |
|
if ($coursehash{'nothideprivileged'}) { |
|
foreach my $item (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) { |
|
my $user; |
|
if ($item =~ /:/) { |
|
$user = $item; |
|
} else { |
|
$user = join(':',split(/[\@]/,$item)); |
|
} |
|
if ($user eq $uname.':'.$udom) { |
|
undef($skipuser); |
|
last; |
|
} |
|
} |
|
} |
|
if ($skipuser) { |
|
return 0; |
|
} |
|
} |
|
} |
|
$type ||= 'any'; |
|
if (!defined($cdom) || !defined($cnum)) { |
|
my $cid = $env{'request.course.id'}; |
|
$cdom = $env{'course.'.$cid.'.domain'}; |
|
$cnum = $env{'course.'.$cid.'.num'}; |
|
} |
|
my $typesref; |
|
if (($type eq 'any') || ($type eq 'all')) { |
|
$typesref = ['active','previous','future']; |
|
} elsif ($type eq 'previous' || $type eq 'future') { |
|
$typesref = [$type]; |
|
} |
|
my %roles = &get_my_roles($uname,$udom,'userroles', |
|
$typesref,undef,[$cdom]); |
|
my ($tmp) = keys(%roles); |
|
return 0 if ($tmp =~ /^(con_lost|error|no_such_host)/i); |
|
my @course_roles = grep(/^\Q$cnum\E:\Q$cdom\E:/, keys(%roles)); |
|
if (@course_roles > 0) { |
|
return 1; |
|
} |
|
return 0; |
|
} |
|
|
# --------- File operations in /home/httpd/html/userfiles/$domain/1/2/3/$course |
# --------- File operations in /home/httpd/html/userfiles/$domain/1/2/3/$course |
# input: action, courseID, current domain, intended |
# input: action, courseID, current domain, intended |
# path to file, source of file, instruction to parse file for objects, |
# path to file, source of file, instruction to parse file for objects, |
Line 2918 sub userfileupload {
|
Line 3202 sub userfileupload {
|
$codebase,$thumbwidth,$thumbheight, |
$codebase,$thumbwidth,$thumbheight, |
$resizewidth,$resizeheight,$context,$mimetype); |
$resizewidth,$resizeheight,$context,$mimetype); |
} else { |
} else { |
$fname=$env{'form.folder'}.'/'.$fname; |
if ($env{'form.folder'}) { |
|
$fname=$env{'form.folder'}.'/'.$fname; |
|
} |
return &process_coursefile('uploaddoc',$docuname,$docudom, |
return &process_coursefile('uploaddoc',$docuname,$docudom, |
$fname,$formname,$parser, |
$fname,$formname,$parser, |
$allfiles,$codebase,$mimetype); |
$allfiles,$codebase,$mimetype); |
Line 2933 sub userfileupload {
|
Line 3219 sub userfileupload {
|
} else { |
} else { |
my $docuname=$env{'user.name'}; |
my $docuname=$env{'user.name'}; |
my $docudom=$env{'user.domain'}; |
my $docudom=$env{'user.domain'}; |
if (exists($env{'form.group'})) { |
if ((exists($env{'form.group'})) || ($context eq 'syllabus')) { |
$docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; |
$docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; |
$docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; |
$docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; |
} |
} |
Line 3083 sub extract_embedded_items {
|
Line 3369 sub extract_embedded_items {
|
&add_filetype($allfiles,$attr->{'src'},'src'); |
&add_filetype($allfiles,$attr->{'src'},'src'); |
} |
} |
if (lc($tagname) eq 'a') { |
if (lc($tagname) eq 'a') { |
&add_filetype($allfiles,$attr->{'href'},'href'); |
unless (($attr->{'href'} =~ /^#/) || ($attr->{'href'} eq '')) { |
|
&add_filetype($allfiles,$attr->{'href'},'href'); |
|
} |
} |
} |
if (lc($tagname) eq 'script') { |
if (lc($tagname) eq 'script') { |
my $src; |
my $src; |
Line 3614 sub get_course_adv_roles {
|
Line 3902 sub get_course_adv_roles {
|
$nothide{$user}=1; |
$nothide{$user}=1; |
} |
} |
} |
} |
|
my @possdoms = ($coursehash{'domain'}); |
|
if ($coursehash{'checkforpriv'}) { |
|
push(@possdoms,split(/,/,$coursehash{'checkforpriv'})); |
|
} |
my %returnhash=(); |
my %returnhash=(); |
my %dumphash= |
my %dumphash= |
&dump('nohist_userroles',$coursehash{'domain'},$coursehash{'num'}); |
&dump('nohist_userroles',$coursehash{'domain'},$coursehash{'num'}); |
Line 3626 sub get_course_adv_roles {
|
Line 3918 sub get_course_adv_roles {
|
if (($tstart) && ($now<$tstart)) { next; } |
if (($tstart) && ($now<$tstart)) { next; } |
my ($role,$username,$domain,$section)=split(/\:/,$entry); |
my ($role,$username,$domain,$section)=split(/\:/,$entry); |
if ($username eq '' || $domain eq '') { next; } |
if ($username eq '' || $domain eq '') { next; } |
unless (ref($privileged{$domain}) eq 'HASH') { |
if ((&privileged($username,$domain,\@possdoms)) && |
my %dompersonnel = |
|
&Apache::lonnet::get_domain_roles($domain,['dc'],$now,$now); |
|
$privileged{$domain} = {}; |
|
foreach my $server (keys(%dompersonnel)) { |
|
if (ref($dompersonnel{$server}) eq 'HASH') { |
|
foreach my $user (keys(%{$dompersonnel{$server}})) { |
|
my ($trole,$uname,$udom) = split(/:/,$user); |
|
$privileged{$udom}{$uname} = 1; |
|
} |
|
} |
|
} |
|
} |
|
if ((exists($privileged{$domain}{$username})) && |
|
(!$nothide{$username.':'.$domain})) { next; } |
(!$nothide{$username.':'.$domain})) { next; } |
if ($role eq 'cr') { next; } |
if ($role eq 'cr') { next; } |
if ($codes) { |
if ($codes) { |
Line 3670 sub get_my_roles {
|
Line 3949 sub get_my_roles {
|
if ($context eq 'userroles') { |
if ($context eq 'userroles') { |
%dumphash = &dump('roles',$udom,$uname); |
%dumphash = &dump('roles',$udom,$uname); |
} else { |
} else { |
%dumphash= |
%dumphash = &dump('nohist_userroles',$udom,$uname); |
&dump('nohist_userroles',$udom,$uname); |
|
if ($hidepriv) { |
if ($hidepriv) { |
my %coursehash=&coursedescription($udom.'_'.$uname); |
my %coursehash=&coursedescription($udom.'_'.$uname); |
foreach my $user (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) { |
foreach my $user (split(/\s*\,\s*/,$coursehash{'nothideprivileged'})) { |
Line 3739 sub get_my_roles {
|
Line 4017 sub get_my_roles {
|
} |
} |
} |
} |
if ($hidepriv) { |
if ($hidepriv) { |
|
my @privroles = ('dc','su'); |
if ($context eq 'userroles') { |
if ($context eq 'userroles') { |
if ((&privileged($username,$domain)) && |
next if (grep(/^\Q$role\E$/,@privroles)); |
(!$nothide{$username.':'.$domain})) { |
|
next; |
|
} |
|
} else { |
} else { |
unless (ref($privileged{$domain}) eq 'HASH') { |
my $possdoms = [$domain]; |
my %dompersonnel = |
if (ref($roledoms) eq 'ARRAY') { |
&Apache::lonnet::get_domain_roles($domain,['dc'],$now,$now); |
push(@{$possdoms},@{$roledoms}); |
$privileged{$domain} = {}; |
|
if (keys(%dompersonnel)) { |
|
foreach my $server (keys(%dompersonnel)) { |
|
if (ref($dompersonnel{$server}) eq 'HASH') { |
|
foreach my $user (keys(%{$dompersonnel{$server}})) { |
|
my ($trole,$uname,$udom) = split(/:/,$user); |
|
$privileged{$udom}{$uname} = $trole; |
|
} |
|
} |
|
} |
|
} |
|
} |
} |
if (exists($privileged{$domain}{$username})) { |
if (&privileged($username,$domain,$possdoms,\@privroles)) { |
if (!$nothide{$username.':'.$domain}) { |
if (!$nothide{$username.':'.$domain}) { |
next; |
next; |
} |
} |
Line 3995 sub get_domain_roles {
|
Line 4260 sub get_domain_roles {
|
} |
} |
my $rolelist; |
my $rolelist; |
if (ref($roles) eq 'ARRAY') { |
if (ref($roles) eq 'ARRAY') { |
$rolelist = join(':',@{$roles}); |
$rolelist = join('&',@{$roles}); |
} |
} |
my %personnel = (); |
my %personnel = (); |
|
|
Line 4537 sub restore {
|
Line 4802 sub restore {
|
if ($stuname) { $home=&homeserver($stuname,$domain); } |
if ($stuname) { $home=&homeserver($stuname,$domain); } |
|
|
if (!$symb) { |
if (!$symb) { |
unless ($symb=escape(&symbread())) { return ''; } |
return if ($namespace eq 'courserequests'); |
|
unless ($symb=escape(&symbread())) { return ''; } |
} else { |
} else { |
$symb=&escape(&symbclean($symb)); |
unless ($namespace eq 'courserequests') { |
|
$symb=&escape(&symbclean($symb)); |
|
} |
} |
} |
if (!$namespace) { |
if (!$namespace) { |
unless ($namespace=$env{'request.course.id'}) { |
unless ($namespace=$env{'request.course.id'}) { |
Line 4674 sub update_released_required {
|
Line 4942 sub update_released_required {
|
# -------------------------------------------------See if a user is privileged |
# -------------------------------------------------See if a user is privileged |
|
|
sub privileged { |
sub privileged { |
my ($username,$domain)=@_; |
my ($username,$domain,$possdomains,$possroles)=@_; |
|
|
my %rolesdump = &dump("roles", $domain, $username) or return 0; |
|
my $now = time; |
my $now = time; |
|
my $roles; |
|
if (ref($possroles) eq 'ARRAY') { |
|
$roles = $possroles; |
|
} else { |
|
$roles = ['dc','su']; |
|
} |
|
if (ref($possdomains) eq 'ARRAY') { |
|
my %privileged = &privileged_by_domain($possdomains,$roles); |
|
foreach my $dom (@{$possdomains}) { |
|
if (($username =~ /^$match_username$/) && ($domain =~ /^$match_domain$/) && |
|
(ref($privileged{$dom}) eq 'HASH')) { |
|
foreach my $role (@{$roles}) { |
|
if (ref($privileged{$dom}{$role}) eq 'HASH') { |
|
if (exists($privileged{$dom}{$role}{$username.':'.$domain})) { |
|
my ($end,$start) = split(/:/,$privileged{$dom}{$role}{$username.':'.$domain}); |
|
return 1 unless (($end && $end < $now) || |
|
($start && $start > $now)); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
my %rolesdump = &dump("roles", $domain, $username) or return 0; |
|
my $now = time; |
|
|
for my $role (@rolesdump{grep { ! /^rolesdef_/ } keys %rolesdump}) { |
for my $role (@rolesdump{grep { ! /^rolesdef_/ } keys %rolesdump}) { |
my ($trole, $tend, $tstart) = split(/_/, $role); |
my ($trole, $tend, $tstart) = split(/_/, $role); |
if (($trole eq 'dc') || ($trole eq 'su')) { |
if (grep(/^\Q$trole\E$/,@{$roles})) { |
return 1 unless ($tend && $tend < $now) |
return 1 unless ($tend && $tend < $now) |
or ($tstart && $tstart > $now); |
or ($tstart && $tstart > $now); |
} |
} |
} |
} |
|
} |
return 0; |
return 0; |
} |
} |
|
|
|
sub privileged_by_domain { |
|
my ($domains,$roles) = @_; |
|
my %privileged = (); |
|
my $cachetime = 60*60*24; |
|
my $now = time; |
|
unless ((ref($domains) eq 'ARRAY') && (ref($roles) eq 'ARRAY')) { |
|
return %privileged; |
|
} |
|
foreach my $dom (@{$domains}) { |
|
next if (ref($privileged{$dom}) eq 'HASH'); |
|
my $needroles; |
|
foreach my $role (@{$roles}) { |
|
my ($result,$cached)=&is_cached_new('priv_'.$role,$dom); |
|
if (defined($cached)) { |
|
if (ref($result) eq 'HASH') { |
|
$privileged{$dom}{$role} = $result; |
|
} |
|
} else { |
|
$needroles = 1; |
|
} |
|
} |
|
if ($needroles) { |
|
my %dompersonnel = &get_domain_roles($dom,$roles); |
|
$privileged{$dom} = {}; |
|
foreach my $server (keys(%dompersonnel)) { |
|
if (ref($dompersonnel{$server}) eq 'HASH') { |
|
foreach my $item (keys(%{$dompersonnel{$server}})) { |
|
my ($trole,$uname,$udom,$rest) = split(/:/,$item,4); |
|
my ($end,$start) = split(/:/,$dompersonnel{$server}{$item}); |
|
next if ($end && $end < $now); |
|
$privileged{$dom}{$trole}{$uname.':'.$udom} = |
|
$dompersonnel{$server}{$item}; |
|
} |
|
} |
|
} |
|
if (ref($privileged{$dom}) eq 'HASH') { |
|
foreach my $role (@{$roles}) { |
|
if (ref($privileged{$dom}{$role}) eq 'HASH') { |
|
&do_cache_new('priv_'.$role,$dom,$privileged{$dom}{$role},$cachetime); |
|
} else { |
|
my %hash = (); |
|
&do_cache_new('priv_'.$role,$dom,\%hash,$cachetime); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return %privileged; |
|
} |
|
|
# -------------------------------------------------------- Get user privileges |
# -------------------------------------------------------- Get user privileges |
|
|
sub rolesinit { |
sub rolesinit { |
Line 4799 sub rolesinit {
|
Line 5140 sub rolesinit {
|
} |
} |
|
|
sub set_arearole { |
sub set_arearole { |
my ($trole,$area,$tstart,$tend,$domain,$username) = @_; |
my ($trole,$area,$tstart,$tend,$domain,$username,$nolog) = @_; |
|
unless ($nolog) { |
# log the associated role with the area |
# log the associated role with the area |
&userrolelog($trole,$username,$domain,$area,$tstart,$tend); |
&userrolelog($trole,$username,$domain,$area,$tstart,$tend); |
|
} |
return ('user.role.'.$trole.'.'.$area => $tstart.'.'.$tend); |
return ('user.role.'.$trole.'.'.$area => $tstart.'.'.$tend); |
} |
} |
|
|
Line 5070 sub set_adhoc_privileges {
|
Line 5413 sub set_adhoc_privileges {
|
my $area = '/'.$dcdom.'/'.$pickedcourse; |
my $area = '/'.$dcdom.'/'.$pickedcourse; |
my $spec = $role.'.'.$area; |
my $spec = $role.'.'.$area; |
my %userroles = &set_arearole($role,$area,'','',$env{'user.domain'}, |
my %userroles = &set_arearole($role,$area,'','',$env{'user.domain'}, |
$env{'user.name'}); |
$env{'user.name'},1); |
my %ccrole = (); |
my %ccrole = (); |
&standard_roleprivs(\%ccrole,$role,$dcdom,$spec,$pickedcourse,$area); |
&standard_roleprivs(\%ccrole,$role,$dcdom,$spec,$pickedcourse,$area); |
my ($author,$adv)= &set_userprivs(\%userroles,\%ccrole); |
my ($author,$adv)= &set_userprivs(\%userroles,\%ccrole); |
Line 5161 sub dump {
|
Line 5504 sub dump {
|
if (grep { $_ eq $uhome } current_machine_ids()) { |
if (grep { $_ eq $uhome } current_machine_ids()) { |
# user is hosted on this machine |
# user is hosted on this machine |
$reply = LONCAPA::Lond::dump_with_regexp(join(":", ($udomain, |
$reply = LONCAPA::Lond::dump_with_regexp(join(":", ($udomain, |
$uname, $namespace, $regexp, $range)), $loncaparevs{$uhome}); |
$uname, $namespace, $regexp, $range)), $perlvar{'lonVersion'}); |
return %{unserialize($reply, $escapedkeys)}; |
return %{unserialize($reply, $escapedkeys)}; |
} |
} |
if ($regexp) { |
if ($regexp) { |
Line 5468 sub tmpdel {
|
Line 5811 sub tmpdel {
|
return &reply("tmpdel:$token",$server); |
return &reply("tmpdel:$token",$server); |
} |
} |
|
|
|
# ------------------------------------------------------------ get_timebased_id |
|
|
|
sub get_timebased_id { |
|
my ($prefix,$keyid,$namespace,$cdom,$cnum,$idtype,$who,$locktries, |
|
$maxtries) = @_; |
|
my ($newid,$error,$dellock); |
|
unless (($prefix =~ /^\w+$/) && ($keyid =~ /^\w+$/) && ($namespace ne '')) { |
|
return ('','ok','invalid call to get suffix'); |
|
} |
|
|
|
# set defaults for any optional args for which values were not supplied |
|
if ($who eq '') { |
|
$who = $env{'user.name'}.':'.$env{'user.domain'}; |
|
} |
|
if (!$locktries) { |
|
$locktries = 3; |
|
} |
|
if (!$maxtries) { |
|
$maxtries = 10; |
|
} |
|
|
|
if (($cdom eq '') || ($cnum eq '')) { |
|
if ($env{'request.course.id'}) { |
|
$cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
$cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
} |
|
if (($cdom eq '') || ($cnum eq '')) { |
|
return ('','ok','call to get suffix not in course context'); |
|
} |
|
} |
|
|
|
# construct locking item |
|
my $lockhash = { |
|
$prefix."\0".'locked_'.$keyid => $who, |
|
}; |
|
my $tries = 0; |
|
|
|
# attempt to get lock on nohist_$namespace file |
|
my $gotlock = &Apache::lonnet::newput('nohist_'.$namespace,$lockhash,$cdom,$cnum); |
|
while (($gotlock ne 'ok') && $tries <$locktries) { |
|
$tries ++; |
|
sleep 1; |
|
$gotlock = &Apache::lonnet::newput('nohist_'.$namespace,$lockhash,$cdom,$cnum); |
|
} |
|
|
|
# attempt to get unique identifier, based on current timestamp |
|
if ($gotlock eq 'ok') { |
|
my %inuse = &Apache::lonnet::dump('nohist_'.$namespace,$cdom,$cnum,$prefix); |
|
my $id = time; |
|
$newid = $id; |
|
my $idtries = 0; |
|
while (exists($inuse{$prefix."\0".$newid}) && $idtries < $maxtries) { |
|
if ($idtype eq 'concat') { |
|
$newid = $id.$idtries; |
|
} else { |
|
$newid ++; |
|
} |
|
$idtries ++; |
|
} |
|
if (!exists($inuse{$prefix."\0".$newid})) { |
|
my %new_item = ( |
|
$prefix."\0".$newid => $who, |
|
); |
|
my $putresult = &Apache::lonnet::put('nohist_'.$namespace,\%new_item, |
|
$cdom,$cnum); |
|
if ($putresult ne 'ok') { |
|
undef($newid); |
|
$error = 'error saving new item: '.$putresult; |
|
} |
|
} else { |
|
$error = ('error: no unique suffix available for the new item '); |
|
} |
|
# remove lock |
|
my @del_lock = ($prefix."\0".'locked_'.$keyid); |
|
$dellock = &Apache::lonnet::del('nohist_'.$namespace,\@del_lock,$cdom,$cnum); |
|
} else { |
|
$error = "error: could not obtain lockfile\n"; |
|
$dellock = 'ok'; |
|
} |
|
return ($newid,$dellock,$error); |
|
} |
|
|
# -------------------------------------------------- portfolio access checking |
# -------------------------------------------------- portfolio access checking |
|
|
sub portfolio_access { |
sub portfolio_access { |
Line 6494 sub allowed {
|
Line 6919 sub allowed {
|
return 'F'; |
return 'F'; |
} |
} |
|
|
|
# ------------------------------------------- Check construction space access |
|
|
|
sub constructaccess { |
|
my ($url,$setpriv)=@_; |
|
|
|
# We do not allow editing of previous versions of files |
|
if ($url=~/\.(\d+)\.(\w+)$/) { return ''; } |
|
|
|
# Get username and domain from URL |
|
my ($ownername,$ownerdomain,$ownerhome); |
|
|
|
($ownerdomain,$ownername) = |
|
($url=~ m{^(?:\Q$perlvar{'lonDocRoot'}\E|)/priv/($match_domain)/($match_username)/}); |
|
|
|
# The URL does not really point to any authorspace, forget it |
|
unless (($ownername) && ($ownerdomain)) { return ''; } |
|
|
|
# Now we need to see if the user has access to the authorspace of |
|
# $ownername at $ownerdomain |
|
|
|
if (($ownername eq $env{'user.name'}) && ($ownerdomain eq $env{'user.domain'})) { |
|
# Real author for this? |
|
$ownerhome = $env{'user.home'}; |
|
if (exists($env{'user.priv.au./'.$ownerdomain.'/./'})) { |
|
return ($ownername,$ownerdomain,$ownerhome); |
|
} |
|
} else { |
|
# Co-author for this? |
|
if (exists($env{'user.priv.ca./'.$ownerdomain.'/'.$ownername.'./'}) || |
|
exists($env{'user.priv.aa./'.$ownerdomain.'/'.$ownername.'./'}) ) { |
|
$ownerhome = &homeserver($ownername,$ownerdomain); |
|
return ($ownername,$ownerdomain,$ownerhome); |
|
} |
|
} |
|
|
|
# We don't have any access right now. If we are not possibly going to do anything about this, |
|
# we might as well leave |
|
unless ($setpriv) { return ''; } |
|
|
|
# Backdoor access? |
|
my $allowed=&allowed('eco',$ownerdomain); |
|
# Nope |
|
unless ($allowed) { return ''; } |
|
# Looks like we may have access, but could be locked by the owner of the construction space |
|
if ($allowed eq 'U') { |
|
my %blocked=&get('environment',['domcoord.author'], |
|
$ownerdomain,$ownername); |
|
# Is blocked by owner |
|
if ($blocked{'domcoord.author'} eq 'blocked') { return ''; } |
|
} |
|
if (($allowed eq 'F') || ($allowed eq 'U')) { |
|
# Grant temporary access |
|
my $then=$env{'user.login.time'}; |
|
my $update=$env{'user.update.time'}; |
|
if (!$update) { $update = $then; } |
|
my $refresh=$env{'user.refresh.time'}; |
|
if (!$refresh) { $refresh = $update; } |
|
my $now = time; |
|
&check_adhoc_privs($ownerdomain,$ownername,$update,$refresh, |
|
$now,'ca','constructaccess'); |
|
$ownerhome = &homeserver($ownername,$ownerdomain); |
|
return($ownername,$ownerdomain,$ownerhome); |
|
} |
|
# No business here |
|
return ''; |
|
} |
|
|
sub get_comm_blocks { |
sub get_comm_blocks { |
my ($cdom,$cnum) = @_; |
my ($cdom,$cnum) = @_; |
if ($cdom eq '' || $cnum eq '') { |
if ($cdom eq '' || $cnum eq '') { |
Line 7019 sub auto_validate_instcode {
|
Line 7511 sub auto_validate_instcode {
|
} |
} |
$response=&unescape(&reply('autovalidateinstcode:'.$cdom.':'. |
$response=&unescape(&reply('autovalidateinstcode:'.$cdom.':'. |
&escape($instcode).':'.&escape($owner),$homeserver)); |
&escape($instcode).':'.&escape($owner),$homeserver)); |
my ($outcome,$description) = map { &unescape($_); } split('&',$response,2); |
my ($outcome,$description,$defaultcredits) = map { &unescape($_); } split('&',$response,3); |
return ($outcome,$description); |
return ($outcome,$description,$defaultcredits); |
} |
} |
|
|
sub auto_create_password { |
sub auto_create_password { |
Line 7642 sub assignrole {
|
Line 8134 sub assignrole {
|
# log new user role if status is ok |
# log new user role if status is ok |
if ($answer eq 'ok') { |
if ($answer eq 'ok') { |
&userrolelog($role,$uname,$udom,$url,$start,$end); |
&userrolelog($role,$uname,$udom,$url,$start,$end); |
# for course roles, perform group memberships changes triggered by role change. |
|
unless ($role =~ /^gr/) { |
|
&Apache::longroup::group_changes($udom,$uname,$url,$role,$origend, |
|
$origstart,$selfenroll,$context); |
|
} |
|
if (($role eq 'cc') || ($role eq 'in') || |
if (($role eq 'cc') || ($role eq 'in') || |
($role eq 'ep') || ($role eq 'ad') || |
($role eq 'ep') || ($role eq 'ad') || |
($role eq 'ta') || ($role eq 'st') || |
($role eq 'ta') || ($role eq 'st') || |
($role=~/^cr/) || ($role eq 'gr') || |
($role=~/^cr/) || ($role eq 'gr') || |
($role eq 'co')) { |
($role eq 'co')) { |
|
# for course roles, perform group memberships changes triggered by role change. |
|
unless ($role =~ /^gr/) { |
|
&Apache::longroup::group_changes($udom,$uname,$url,$role,$origend, |
|
$origstart,$selfenroll,$context); |
|
} |
&courserolelog($role,$uname,$udom,$url,$origstart,$origend,$delflag, |
&courserolelog($role,$uname,$udom,$url,$origstart,$origend,$delflag, |
$selfenroll,$context); |
$selfenroll,$context); |
} elsif (($role eq 'li') || ($role eq 'dg') || ($role eq 'sc') || |
} elsif (($role eq 'li') || ($role eq 'dg') || ($role eq 'sc') || |
Line 7960 sub modifyuser {
|
Line 8452 sub modifyuser {
|
sub modifystudent { |
sub modifystudent { |
my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec, |
my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec, |
$end,$start,$forceid,$desiredhome,$email,$type,$locktype,$cid, |
$end,$start,$forceid,$desiredhome,$email,$type,$locktype,$cid, |
$selfenroll,$context,$inststatus)=@_; |
$selfenroll,$context,$inststatus,$credits)=@_; |
if (!$cid) { |
if (!$cid) { |
unless ($cid=$env{'request.course.id'}) { |
unless ($cid=$env{'request.course.id'}) { |
return 'not_in_class'; |
return 'not_in_class'; |
Line 7975 sub modifystudent {
|
Line 8467 sub modifystudent {
|
# students environment |
# students environment |
$uid = undef if (!$forceid); |
$uid = undef if (!$forceid); |
$reply = &modify_student_enrollment($udom,$uname,$uid,$first,$middle,$last, |
$reply = &modify_student_enrollment($udom,$uname,$uid,$first,$middle,$last, |
$gene,$usec,$end,$start,$type,$locktype,$cid,$selfenroll,$context); |
$gene,$usec,$end,$start,$type,$locktype, |
|
$cid,$selfenroll,$context,$credits); |
return $reply; |
return $reply; |
} |
} |
|
|
sub modify_student_enrollment { |
sub modify_student_enrollment { |
my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type,$locktype,$cid,$selfenroll,$context) = @_; |
my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type, |
|
$locktype,$cid,$selfenroll,$context,$credits) = @_; |
my ($cdom,$cnum,$chome); |
my ($cdom,$cnum,$chome); |
if (!$cid) { |
if (!$cid) { |
unless ($cid=$env{'request.course.id'}) { |
unless ($cid=$env{'request.course.id'}) { |
Line 8027 sub modify_student_enrollment {
|
Line 8521 sub modify_student_enrollment {
|
my %old_entry = &Apache::lonnet::get('classlist',[$user],$cdom,$cnum); |
my %old_entry = &Apache::lonnet::get('classlist',[$user],$cdom,$cnum); |
my $reply=cput('classlist', |
my $reply=cput('classlist', |
{$user => |
{$user => |
join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype) }, |
join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype,$credits) }, |
$cdom,$cnum); |
$cdom,$cnum); |
if (($reply eq 'ok') || ($reply eq 'delayed')) { |
if (($reply eq 'ok') || ($reply eq 'delayed')) { |
&devalidate_getsection_cache($udom,$uname,$cid); |
&devalidate_getsection_cache($udom,$uname,$cid); |
Line 8256 sub is_course {
|
Line 8750 sub is_course {
|
my %courses = &courseiddump($cdom, '.', 1, '.', '.', $cnum, undef, undef, |
my %courses = &courseiddump($cdom, '.', 1, '.', '.', $cnum, undef, undef, |
'.'); |
'.'); |
|
|
return unless exists($courses{$cdom.'_'.$cnum}); |
return unless(exists($courses{$cdom.'_'.$cnum})); |
return wantarray ? ($cdom, $cnum) : $cdom.'_'.$cnum; |
return wantarray ? ($cdom, $cnum) : $cdom.'_'.$cnum; |
} |
} |
|
|
Line 8281 sub store_userdata {
|
Line 8775 sub store_userdata {
|
$namevalue.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&'; |
$namevalue.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&'; |
} |
} |
$namevalue=~s/\&$//; |
$namevalue=~s/\&$//; |
|
unless ($namespace eq 'courserequests') { |
|
$datakey = &escape($datakey); |
|
} |
$result = &reply("store:$udom:$uname:$namespace:$datakey:". |
$result = &reply("store:$udom:$uname:$namespace:$datakey:". |
$namevalue,$uhome); |
$namevalue,$uhome); |
} |
} |
Line 9131 sub EXT_cache_set {
|
Line 9628 sub EXT_cache_set {
|
# --------------------------------------------------------- Value of a Variable |
# --------------------------------------------------------- Value of a Variable |
sub EXT { |
sub EXT { |
|
|
my ($varname,$symbparm,$udom,$uname,$usection,$recurse)=@_; |
my ($varname,$symbparm,$udom,$uname,$usection,$recurse,$cid)=@_; |
unless ($varname) { return ''; } |
unless ($varname) { return ''; } |
#get real user name/domain, courseid and symb |
#get real user name/domain, courseid and symb |
my $courseid; |
my $courseid; |
Line 9264 sub EXT {
|
Line 9761 sub EXT {
|
|
|
my ($section, $group, @groups); |
my ($section, $group, @groups); |
my ($courselevelm,$courselevel); |
my ($courselevelm,$courselevel); |
if ($symbparm && defined($courseid) && |
if (($courseid eq '') && ($cid)) { |
$courseid eq $env{'request.course.id'}) { |
$courseid = $cid; |
|
} |
|
if (($symbparm && $courseid) && |
|
(($courseid eq $env{'request.course.id'}) || ($courseid eq $cid))) { |
|
|
#print '<br>'.$space.' - '.$qualifier.' - '.$spacequalifierrest; |
#print '<br>'.$space.' - '.$qualifier.' - '.$spacequalifierrest; |
|
|
Line 9512 sub metadata {
|
Line 10012 sub metadata {
|
# if it is a non metadata possible uri return quickly |
# if it is a non metadata possible uri return quickly |
if (($uri eq '') || |
if (($uri eq '') || |
(($uri =~ m|^/*adm/|) && |
(($uri =~ m|^/*adm/|) && |
($uri !~ m|^adm/includes|) && ($uri !~ m|/bulletinboard$|)) || |
($uri !~ m|^adm/includes|) && ($uri !~ m{/(smppg|bulletinboard)$})) || |
($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ m{^/*uploaded/.+\.sequence$})) { |
($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ m{^/*uploaded/.+\.sequence$})) { |
return undef; |
return undef; |
} |
} |
Line 9943 sub get_course_slots {
|
Line 10443 sub get_course_slots {
|
my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); |
my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); |
my ($tmp) = keys(%slots); |
my ($tmp) = keys(%slots); |
if ($tmp !~ /^(con_lost|error|no_such_host)/i) { |
if ($tmp !~ /^(con_lost|error|no_such_host)/i) { |
&Apache::lonnet::do_cache_new('allslots',$hashid,\%slots,600); |
&do_cache_new('allslots',$hashid,\%slots,600); |
return %slots; |
return %slots; |
} |
} |
} |
} |
Line 10037 sub symbverify {
|
Line 10537 sub symbverify {
|
|
|
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 $noclutter; |
if (($thisurl =~ m{^/adm/wrapper/ext/}) || ($thisurl =~ m{^ext/})) { |
if (($thisurl =~ m{^/adm/wrapper/ext/}) || ($thisurl =~ m{^ext/})) { |
$thisurl =~ s/\?.+$//; |
$thisurl =~ s/\?.+$//; |
|
if ($map =~ m{^uploaded/.+\.page$}) { |
|
$thisurl =~ s{^(/adm/wrapper|)/ext/}{http://}; |
|
$thisurl =~ s{^\Qhttp://https://\E}{https://}; |
|
$noclutter = 1; |
|
} |
|
} |
|
my $ids; |
|
if ($noclutter) { |
|
$ids=$bighash{'ids_'.$thisurl}; |
|
} else { |
|
$ids=$bighash{'ids_'.&clutter($thisurl)}; |
} |
} |
my $ids=$bighash{'ids_'.&clutter($thisurl)}; |
|
unless ($ids) { |
unless ($ids) { |
my $idkey = 'ids_'.($thisurl =~ m{^/}? '' : '/').$thisurl; |
my $idkey = 'ids_'.($thisurl =~ m{^/}? '' : '/').$thisurl; |
$ids=$bighash{$idkey}; |
$ids=$bighash{$idkey}; |
} |
} |
if ($ids) { |
if ($ids) { |
# ------------------------------------------------------------------- Has ID(s) |
# ------------------------------------------------------------------- Has ID(s) |
|
if ($thisfn =~ m{^/adm/wrapper/ext/}) { |
|
$symb =~ s/\?.+$//; |
|
} |
foreach my $id (split(/\,/,$ids)) { |
foreach my $id (split(/\,/,$ids)) { |
my ($mapid,$resid)=split(/\./,$id); |
my ($mapid,$resid)=split(/\./,$id); |
if ($thisfn =~ m{^/adm/wrapper/ext/}) { |
|
$symb =~ s/\?.+$//; |
|
} |
|
if ( |
if ( |
&symbclean(&declutter($bighash{'map_id_'.$mapid}).'___'.$resid.'___'.$thisfn) |
&symbclean(&declutter($bighash{'map_id_'.$mapid}).'___'.$resid.'___'.$thisfn) |
eq $symb) { |
eq $symb) { |
Line 10062 sub symbverify {
|
Line 10573 sub symbverify {
|
($bighash{'encrypted_'.$id} eq $env{'request.enc'}) || |
($bighash{'encrypted_'.$id} eq $env{'request.enc'}) || |
($thisurl eq '/adm/navmaps')) { |
($thisurl eq '/adm/navmaps')) { |
$okay=1; |
$okay=1; |
|
last; |
} |
} |
} |
} |
} |
} |
Line 10137 sub deversion {
|
Line 10649 sub deversion {
|
|
|
sub symbread { |
sub symbread { |
my ($thisfn,$donotrecurse)=@_; |
my ($thisfn,$donotrecurse)=@_; |
my $cache_str='request.symbread.cached.'.$thisfn; |
my $cache_str; |
if (defined($env{$cache_str})) { |
if ($thisfn ne '') { |
if (($thisfn) || ($env{$cache_str} ne '')) { |
$cache_str='request.symbread.cached.'.$thisfn; |
|
if ($env{$cache_str} ne '') { |
return $env{$cache_str}; |
return $env{$cache_str}; |
} |
} |
} |
} else { |
# no filename provided? try from environment |
# no filename provided? try from environment |
unless ($thisfn) { |
|
if ($env{'request.symb'}) { |
if ($env{'request.symb'}) { |
return $env{$cache_str}=&symbclean($env{'request.symb'}); |
return $env{$cache_str}=&symbclean($env{'request.symb'}); |
} |
} |
Line 11059 sub goodbye {
|
Line 11571 sub goodbye {
|
} |
} |
|
|
sub get_dns { |
sub get_dns { |
my ($url,$func,$ignore_cache) = @_; |
my ($url,$func,$ignore_cache,$nocache,$hashref) = @_; |
if (!$ignore_cache) { |
if (!$ignore_cache) { |
my ($content,$cached)= |
my ($content,$cached)= |
&Apache::lonnet::is_cached_new('dns',$url); |
&Apache::lonnet::is_cached_new('dns',$url); |
if ($cached) { |
if ($cached) { |
&$func($content); |
&$func($content,$hashref); |
return; |
return; |
} |
} |
} |
} |
Line 11089 sub get_dns {
|
Line 11601 sub get_dns {
|
delete($alldns{$dns}); |
delete($alldns{$dns}); |
next if ($response->is_error()); |
next if ($response->is_error()); |
my @content = split("\n",$response->content); |
my @content = split("\n",$response->content); |
&Apache::lonnet::do_cache_new('dns',$url,\@content,30*24*60*60); |
unless ($nocache) { |
&$func(\@content); |
&do_cache_new('dns',$url,\@content,30*24*60*60); |
|
} |
|
&$func(\@content,$hashref); |
return; |
return; |
} |
} |
close($config); |
close($config); |
Line 11098 sub get_dns {
|
Line 11612 sub get_dns {
|
&logthis("unable to contact DNS defaulting to on disk file dns_$which.tab\n"); |
&logthis("unable to contact DNS defaulting to on disk file dns_$which.tab\n"); |
open($config,"<$perlvar{'lonTabDir'}/dns_$which.tab"); |
open($config,"<$perlvar{'lonTabDir'}/dns_$which.tab"); |
my @content = <$config>; |
my @content = <$config>; |
&$func(\@content); |
&$func(\@content,$hashref); |
return; |
return; |
} |
} |
|
|
|
# ------------------------------------------------------Get DNS checksums file |
|
sub parse_dns_checksums_tab { |
|
my ($lines,$hashref) = @_; |
|
my $machine_dom = &Apache::lonnet::host_domain($perlvar{'lonHostID'}); |
|
my $loncaparev = &get_server_loncaparev($machine_dom); |
|
my ($release,$timestamp) = split(/\-/,$loncaparev); |
|
my (%chksum,%revnum); |
|
if (ref($lines) eq 'ARRAY') { |
|
chomp(@{$lines}); |
|
my $versions = shift(@{$lines}); |
|
my %supported; |
|
if ($versions =~ /^VERSIONS\:([\w\.\,]+)$/) { |
|
my $releaseslist = $1; |
|
if ($releaseslist =~ /,/) { |
|
map { $supported{$_} = 1; } split(/,/,$releaseslist); |
|
} elsif ($releaseslist) { |
|
$supported{$releaseslist} = 1; |
|
} |
|
} |
|
if ($supported{$release}) { |
|
my $matchthis = 0; |
|
foreach my $line (@{$lines}) { |
|
if ($line =~ /^(\d[\w\.]+)$/) { |
|
if ($matchthis) { |
|
last; |
|
} elsif ($1 eq $release) { |
|
$matchthis = 1; |
|
} |
|
} elsif ($matchthis) { |
|
my ($file,$version,$shasum) = split(/,/,$line); |
|
$chksum{$file} = $shasum; |
|
$revnum{$file} = $version; |
|
} |
|
} |
|
if (ref($hashref) eq 'HASH') { |
|
%{$hashref} = ( |
|
sums => \%chksum, |
|
versions => \%revnum, |
|
); |
|
} |
|
} |
|
} |
|
return; |
|
} |
|
|
|
sub fetch_dns_checksums { |
|
my %checksums; |
|
&get_dns('/adm/dns/checksums',\&parse_dns_checksums_tab,1,1, |
|
\%checksums); |
|
return \%checksums; |
|
} |
|
|
# ------------------------------------------------------------ Read domain file |
# ------------------------------------------------------------ Read domain file |
{ |
{ |
my $loaded; |
my $loaded; |
Line 11410 sub get_dns {
|
Line 11977 sub get_dns {
|
} |
} |
push(@{$iphost{$ip}},@{$name_to_host{$name}}); |
push(@{$iphost{$ip}},@{$name_to_host{$name}}); |
} |
} |
&Apache::lonnet::do_cache_new('iphost','iphost', |
&do_cache_new('iphost','iphost', |
[\%iphost,\%name_to_ip,\%lonid_to_ip], |
[\%iphost,\%name_to_ip,\%lonid_to_ip], |
48*60*60); |
48*60*60); |
|
|
return %iphost; |
return %iphost; |
} |
} |
Line 11468 sub get_dns {
|
Line 12035 sub get_dns {
|
} |
} |
$seen{$prim_ip} = 1; |
$seen{$prim_ip} = 1; |
} |
} |
return &Apache::lonnet::do_cache_new('internetnames',$lonid,\@idns,12*60*60); |
return &do_cache_new('internetnames',$lonid,\@idns,12*60*60); |
} |
} |
|
|
} |
} |
Line 11477 sub all_loncaparevs {
|
Line 12044 sub all_loncaparevs {
|
return qw(1.1 1.2 1.3 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10); |
return qw(1.1 1.2 1.3 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10); |
} |
} |
|
|
|
# ---------------------------------------------------------- Read loncaparev table |
|
{ |
|
sub load_loncaparevs { |
|
if (-e "$perlvar{'lonTabDir'}/loncaparevs.tab") { |
|
if (open(my $config,"<$perlvar{'lonTabDir'}/loncaparevs.tab")) { |
|
while (my $configline=<$config>) { |
|
chomp($configline); |
|
my ($hostid,$loncaparev)=split(/:/,$configline); |
|
$loncaparevs{$hostid}=$loncaparev; |
|
} |
|
close($config); |
|
} |
|
} |
|
} |
|
} |
|
|
|
# ---------------------------------------------------------- Read serverhostID table |
|
{ |
|
sub load_serverhomeIDs { |
|
if (-e "$perlvar{'lonTabDir'}/serverhomeIDs.tab") { |
|
if (open(my $config,"<$perlvar{'lonTabDir'}/serverhomeIDs.tab")) { |
|
while (my $configline=<$config>) { |
|
chomp($configline); |
|
my ($name,$id)=split(/:/,$configline); |
|
$serverhomeIDs{$name}=$id; |
|
} |
|
close($config); |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
BEGIN { |
BEGIN { |
|
|
# ----------------------------------- Read loncapa.conf and loncapa_apache.conf |
# ----------------------------------- Read loncapa.conf and loncapa_apache.conf |
Line 11553 BEGIN {
|
Line 12153 BEGIN {
|
} |
} |
|
|
# ---------------------------------------------------------- Read loncaparev table |
# ---------------------------------------------------------- Read loncaparev table |
{ |
|
if (-e "$perlvar{'lonTabDir'}/loncaparevs.tab") { |
&load_loncaparevs(); |
if (open(my $config,"<$perlvar{'lonTabDir'}/loncaparevs.tab")) { |
|
while (my $configline=<$config>) { |
|
chomp($configline); |
|
my ($hostid,$loncaparev)=split(/:/,$configline); |
|
$loncaparevs{$hostid}=$loncaparev; |
|
} |
|
close($config); |
|
} |
|
} |
|
} |
|
|
|
# ---------------------------------------------------------- Read serverhostID table |
# ---------------------------------------------------------- Read serverhostID table |
{ |
|
if (-e "$perlvar{'lonTabDir'}/serverhomeIDs.tab") { |
|
if (open(my $config,"<$perlvar{'lonTabDir'}/serverhomeIDs.tab")) { |
|
while (my $configline=<$config>) { |
|
chomp($configline); |
|
my ($name,$id)=split(/:/,$configline); |
|
$serverhomeIDs{$name}=$id; |
|
} |
|
close($config); |
|
} |
|
} |
|
} |
|
|
|
|
&load_serverhomeIDs(); |
|
|
|
# ---------------------------------------------------------- Read releaseslist XML |
{ |
{ |
my $file = $Apache::lonnet::perlvar{'lonTabDir'}.'/releaseslist.xml'; |
my $file = $Apache::lonnet::perlvar{'lonTabDir'}.'/releaseslist.xml'; |
if (-e $file) { |
if (-e $file) { |
Line 11638 $readit=1;
|
Line 12219 $readit=1;
|
if ($test != 0) { $_64bit=1; } else { $_64bit=0; } |
if ($test != 0) { $_64bit=1; } else { $_64bit=0; } |
&logthis(" Detected 64bit platform ($_64bit)"); |
&logthis(" Detected 64bit platform ($_64bit)"); |
} |
} |
|
|
|
{ |
|
eval { |
|
($apache) = |
|
(Apache2::ServerUtil::get_server_version() =~ m{Apache/(\d+\.\d+)}); |
|
}; |
|
if ($@) { |
|
$apache = 1.3; |
|
} |
|
} |
|
|
} |
} |
} |
} |
|
|
Line 11778 were new keys. I.E. 1:foo will become 1:
|
Line 12370 were new keys. I.E. 1:foo will become 1:
|
|
|
Calling convention: |
Calling convention: |
|
|
my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$uname,$home); |
my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$uname); |
&Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$uname,$home); |
&Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$uname); |
|
|
For more detailed information, see lonnet specific documentation. |
For more detailed information, see lonnet specific documentation. |
|
|
Line 11925 allowed($priv,$uri,$symb,$role) : check
|
Line 12517 allowed($priv,$uri,$symb,$role) : check
|
|
|
=item * |
=item * |
|
|
|
constructaccess($url,$setpriv) : check for access to construction space URL |
|
|
|
See if the owner domain and name in the URL match those in the |
|
expected environment. If so, return three element list |
|
($ownername,$ownerdomain,$ownerhome). |
|
|
|
Otherwise return the null string. |
|
|
|
If second argument 'setpriv' is true, it assigns the privileges, |
|
and returns the same three element list, unless the owner has |
|
blocked "ad hoc" Domain Coordinator access to the Author Space, |
|
in which case the null string is returned. |
|
|
|
=item * |
|
|
definerole($rolename,$sysrole,$domrole,$courole) : define role; define a custom |
definerole($rolename,$sysrole,$domrole,$courole) : define role; define a custom |
role rolename set privileges in format of lonTabs/roles.tab for system, domain, |
role rolename set privileges in format of lonTabs/roles.tab for system, domain, |
and course level |
and course level |
Line 11941 environment). If no custom name is defi
|
Line 12548 environment). If no custom name is defi
|
|
|
=item * |
=item * |
|
|
get_my_roles($uname,$udom,$context,$types,$roles,$roledoms,$withsec) : |
get_my_roles($uname,$udom,$context,$types,$roles,$roledoms,$withsec,$hidepriv) : |
All arguments are optional. Returns a hash of a roles, either for |
All arguments are optional. Returns a hash of a roles, either for |
co-author/assistant author roles for a user's Construction Space |
co-author/assistant author roles for a user's Construction Space |
(default), or if $context is 'userroles', roles for the user himself, |
(default), or if $context is 'userroles', roles for the user himself, |
Line 11955 of role statuses (active, future or prev
|
Line 12562 of role statuses (active, future or prev
|
to restrict the list of roles reported. If no array ref is |
to restrict the list of roles reported. If no array ref is |
provided for types, will default to return only active roles. |
provided for types, will default to return only active roles. |
|
|
|
=item * |
|
|
|
in_course($udom,$uname,$cdom,$cnum,$type,$hideprivileged) : determine if |
|
user: $uname:$udom has a role in the course: $cdom_$cnum. |
|
|
|
Additional optional arguments are: $type (if role checking is to be restricted |
|
to certain user status types -- previous (expired roles), active (currently |
|
available roles) or future (roles available in the future), and |
|
$hideprivileged -- if true will not report course roles for users who |
|
have active Domain Coordinator role in course's domain or in additional |
|
domains (specified in 'Domains to check for privileged users' in course |
|
environment -- set via: Course Settings -> Classlists and staff listing). |
|
|
|
=item * |
|
|
|
privileged($username,$domain,$possdomains,$possroles) : returns 1 if user |
|
$username:$domain is a privileged user (e.g., Domain Coordinator or Super User) |
|
$possdomains and $possroles are optional array refs -- to domains to check and |
|
roles to check. If $possdomains is not specified, a dump will be done of the |
|
users' roles.db to check for a dc or su role in any domain. This can be |
|
time consuming if &privileged is called repeatedly (e.g., when displaying a |
|
classlist), so in such cases, supplying a $possdomains array is preferred, as |
|
this then allows &privileged_by_domain() to be used, which caches the identity |
|
of privileged users, eliminating the need for repeated calls to &dump(). |
|
|
|
=item * |
|
|
|
privileged_by_domain($possdomains,$roles) : returns a hash of a hash of a hash, |
|
where the outer hash keys are domains specified in the $possdomains array ref, |
|
next inner hash keys are privileged roles specified in the $roles array ref, |
|
and the innermost hash contains key = value pairs for username:domain = end:start |
|
for active or future "privileged" users with that role in that domain. To avoid |
|
repeated dumps of domain roles -- via &get_domain_roles() -- contents of the |
|
innerhash are cached using priv_$role and $dom as the identifiers. |
|
|
=back |
=back |
|
|
=head2 User Modification |
=head2 User Modification |
Line 12047 Inputs:
|
Line 12689 Inputs:
|
|
|
=item B<$context> role change context (shown in User Management Logs display in a course) |
=item B<$context> role change context (shown in User Management Logs display in a course) |
|
|
=item B<$inststatus> institutional status of user - : separated string of escaped status types |
=item B<$inststatus> institutional status of user - : separated string of escaped status types |
|
|
|
=item B<$credits> Number of credits student will earn from this class - only needs to be supplied if value needs to be different from default credits for class. |
|
|
=back |
=back |
|
|
Line 12092 Inputs:
|
Line 12736 Inputs:
|
|
|
=item $context |
=item $context |
|
|
|
=item $credits, number of credits student will earn from this class |
|
|
=back |
=back |
|
|
|
|
Line 12157 data base, returning a hash that is keye
|
Line 12803 data base, returning a hash that is keye
|
values that are the resource value. I believe that the timestamps and |
values that are the resource value. I believe that the timestamps and |
versions are also returned. |
versions are also returned. |
|
|
|
|
=back |
=back |
|
|
=head2 Course Modification |
=head2 Course Modification |
Line 12217 resource. Expects the local filesystem p
|
Line 12862 resource. Expects the local filesystem p
|
|
|
=item * |
=item * |
|
|
EXT($varname,$symb,$udom,$uname) : evaluates and returns the value of |
EXT($varname,$symb,$udom,$uname,$usection,$recurse,$cid) : evaluates |
a vairety of different possible values, $varname should be a request |
and returns the value of a variety of different possible values, |
string, and the other parameters can be used to specify who and what |
$varname should be a request string, and the other parameters can be |
one is asking about. |
used to specify who and what one is asking about. Ordinarily, $cid |
|
does not need to be specified, as it is retrived from |
|
$env{'request.course.id'}, but &Apache::lonnet::EXT() is called |
|
within lonuserstate::loadmap() when initializing a course, before |
|
$env{'request.course.id'} has been set, so it needs to be provided |
|
in that one case. |
|
|
Possible values for $varname are environment.lastname (or other item |
Possible values for $varname are environment.lastname (or other item |
from the envirnment hash), user.name (or someother aspect about the |
from the envirnment hash), user.name (or someother aspect about the |
Line 12318 expirespread($uname,$udom,$stype,$usymb)
|
Line 12968 expirespread($uname,$udom,$stype,$usymb)
|
devalidate($symb) : devalidate temporary spreadsheet calculations, |
devalidate($symb) : devalidate temporary spreadsheet calculations, |
forcing spreadsheet to reevaluate the resource scores next time. |
forcing spreadsheet to reevaluate the resource scores next time. |
|
|
|
=item * |
|
|
|
can_edit_resource($file,$cnum,$cdom,$resurl,$symb,$group) : determine if current user can edit a particular resource, |
|
when viewing in course context. |
|
|
|
input: six args -- filename (decluttered), course number, course domain, |
|
url, symb (if registered) and group (if this is a |
|
group item -- e.g., bulletin board, group page etc.). |
|
|
|
output: array of five scalars -- |
|
$cfile -- url for file editing if editable on current server |
|
$home -- homeserver of resource (i.e., for author if published, |
|
or course if uploaded.). |
|
$switchserver -- 1 if server switch will be needed. |
|
$forceedit -- 1 if icon/link should be to go to edit mode |
|
$forceview -- 1 if icon/link should be to go to view mode |
|
|
|
=item * |
|
|
|
is_course_upload($file,$cnum,$cdom) |
|
|
|
Used in course context to determine if current file was uploaded to |
|
the course (i.e., would be found in /userfiles/docs on the course's |
|
homeserver. |
|
|
|
input: 3 args -- filename (decluttered), course number and course domain. |
|
output: boolean -- 1 if file was uploaded. |
|
|
=back |
=back |
|
|
=head2 Storing/Retreiving Data |
=head2 Storing/Retreiving Data |
Line 12873 Internal notes:
|
Line 13551 Internal notes:
|
|
|
Locks on files (resulting from submission of portfolio file to a homework problem stored in array of arrays. |
Locks on files (resulting from submission of portfolio file to a homework problem stored in array of arrays. |
|
|
|
=item * |
|
|
modify_access_controls(): |
modify_access_controls(): |
|
|
Modifies access controls for a portfolio file |
Modifies access controls for a portfolio file |
Line 12890 Returns:
|
Line 13570 Returns:
|
3. reference to hash of any new or updated access controls. |
3. reference to hash of any new or updated access controls. |
4. reference to hash used to map incoming IDs to uniqueIDs assigned to control. |
4. reference to hash used to map incoming IDs to uniqueIDs assigned to control. |
key = integer (inbound ID) |
key = integer (inbound ID) |
value = uniqueID |
value = uniqueID |
|
|
|
=item * |
|
|
|
get_timebased_id(): |
|
|
|
Attempts to get a unique timestamp-based suffix for use with items added to a |
|
course via the Course Editor (e.g., folders, composite pages, |
|
group bulletin boards). |
|
|
|
Args: (first three required; six others optional) |
|
|
|
1. prefix (alphanumeric): of keys in hash, e.g., suppsequence, docspage, |
|
docssequence, or name of group |
|
|
|
2. keyid (alphanumeric): name of temporary locking key in hash, |
|
e.g., num, boardids |
|
|
|
3. namespace: name of gdbm file used to store suffixes already assigned; |
|
file will be named nohist_namespace.db |
|
|
|
4. cdom: domain of course; default is current course domain from %env |
|
|
|
5. cnum: course number; default is current course number from %env |
|
|
|
6. idtype: set to concat if an additional digit is to be appended to the |
|
unix timestamp to form the suffix, if the plain timestamp is already |
|
in use. Default is to not do this, but simply increment the unix |
|
timestamp by 1 until a unique key is obtained. |
|
|
|
7. who: holder of locking key; defaults to user:domain for user. |
|
|
|
8. locktries: number of attempts to obtain a lock (sleep of 1s before |
|
retrying); default is 3. |
|
|
|
9. maxtries: number of attempts to obtain a unique suffix; default is 20. |
|
|
|
Returns: |
|
|
|
1. suffix obtained (numeric) |
|
|
|
2. result of deleting locking key (ok if deleted, or lock never obtained) |
|
|
|
3. error: contains (localized) error message if an error occurred. |
|
|
|
|
=back |
=back |
|
|