--- loncom/lond 2013/10/06 20:33:38 1.503
+++ loncom/lond 2014/11/24 02:36:16 1.512
@@ -2,7 +2,7 @@
# The LearningOnline Network
# lond "LON Daemon" Server (port "LOND" 5663)
#
-# $Id: lond,v 1.503 2013/10/06 20:33:38 raeburn Exp $
+# $Id: lond,v 1.512 2014/11/24 02:36:16 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -61,7 +61,7 @@ my $DEBUG = 0; # Non zero to ena
my $status='';
my $lastlog='';
-my $VERSION='$Revision: 1.503 $'; #' stupid emacs
+my $VERSION='$Revision: 1.512 $'; #' stupid emacs
my $remoteVERSION;
my $currenthostid="default";
my $currentdomainid;
@@ -621,7 +621,7 @@ sub ConfigFileFromSelector {
# String to send to client ("ok" or "refused" if bad file).
#
sub PushFile {
- my $request = shift;
+ my $request = shift;
my ($command, $filename, $contents) = split(":", $request, 3);
&Debug("PushFile");
@@ -651,6 +651,44 @@ sub PushFile {
if($filename eq "host") {
$contents = AdjustHostContents($contents);
+ } elsif ($filename eq 'dns_host' || $filename eq 'dns_domain') {
+ if ($contents eq '') {
+ &logthis(' Pushfile: unable to install '
+ .$tablefile." - no data received from push. ");
+ return 'error: push had no data';
+ }
+ if (&Apache::lonnet::get_host_ip($clientname)) {
+ my $clienthost = &Apache::lonnet::hostname($clientname);
+ if ($managers{$clientip} eq $clientname) {
+ my $clientprotocol = $Apache::lonnet::protocol{$clientname};
+ $clientprotocol = 'http' if ($clientprotocol ne 'https');
+ my $url = '/adm/'.$filename;
+ $url =~ s{_}{/};
+ my $ua=new LWP::UserAgent;
+ $ua->timeout(60);
+ my $request=new HTTP::Request('GET',"$clientprotocol://$clienthost$url");
+ my $response=$ua->request($request);
+ if ($response->is_error()) {
+ &logthis(' Pushfile: unable to install '
+ .$tablefile." - error attempting to pull data. ");
+ return 'error: pull failed';
+ } else {
+ my $result = $response->content;
+ chomp($result);
+ unless ($result eq $contents) {
+ &logthis(' Pushfile: unable to install '
+ .$tablefile." - pushed data and pulled data differ. ");
+ my $pushleng = length($contents);
+ my $pullleng = length($result);
+ if ($pushleng != $pullleng) {
+ return "error: $pushleng vs $pullleng bytes";
+ } else {
+ return "error: mismatch push and pull";
+ }
+ }
+ }
+ }
+ }
}
# Install the new file:
@@ -3284,6 +3322,9 @@ sub dump_with_regexp {
# namespace - Name of the database being modified
# rid - Resource keyword to modify.
# what - new value associated with rid.
+# laststore - (optional) version=timestamp
+# for most recent transaction for rid
+# in namespace, when cstore was called
#
# $client - Socket open on the client.
#
@@ -3292,23 +3333,45 @@ sub dump_with_regexp {
# 1 (keep on processing).
# Side-Effects:
# Writes to the client
+# Successful storage will cause either 'ok', or, if $laststore was included
+# in the tail of the request, and the version number for the last transaction
+# is larger than the version in $laststore, delay:$numtrans , where $numtrans
+# is the number of store evevnts recorded for rid in namespace since
+# lonnet::store() was called by the client.
+#
sub store_handler {
my ($cmd, $tail, $client) = @_;
my $userinput = "$cmd:$tail";
-
- my ($udom,$uname,$namespace,$rid,$what) =split(/:/,$tail);
+ chomp($tail);
+ my ($udom,$uname,$namespace,$rid,$what,$laststore) =split(/:/,$tail);
if ($namespace ne 'roles') {
- chomp($what);
my @pairs=split(/\&/,$what);
my $hashref = &tie_user_hash($udom, $uname, $namespace,
&GDBM_WRCREAT(), "S",
"$rid:$what");
if ($hashref) {
my $now = time;
- my @previouskeys=split(/&/,$hashref->{"keys:$rid"});
- my $key;
+ my $numtrans;
+ if ($laststore) {
+ my ($previousversion,$previoustime) = split(/\=/,$laststore);
+ my ($lastversion,$lasttime) = (0,0);
+ $lastversion = $hashref->{"version:$rid"};
+ if ($lastversion) {
+ $lasttime = $hashref->{"$lastversion:$rid:timestamp"};
+ }
+ if (($previousversion) && ($previousversion !~ /\D/)) {
+ if (($lastversion > $previousversion) && ($lasttime >= $previoustime)) {
+ $numtrans = $lastversion - $previousversion;
+ }
+ } elsif ($lastversion) {
+ $numtrans = $lastversion;
+ }
+ if ($numtrans) {
+ $numtrans =~ s/D//g;
+ }
+ }
$hashref->{"version:$rid"}++;
my $version=$hashref->{"version:$rid"};
my $allkeys='';
@@ -3321,7 +3384,11 @@ sub store_handler {
$allkeys.='timestamp';
$hashref->{"$version:keys:$rid"}=$allkeys;
if (&untie_user_hash($hashref)) {
- &Reply($client, "ok\n", $userinput);
+ my $msg = 'ok';
+ if ($numtrans) {
+ $msg = 'delay:'.$numtrans;
+ }
+ &Reply($client, "$msg\n", $userinput);
} else {
&Failure($client, "error: ".($!+0)." untie(GDBM) Failed ".
"while attempting store\n", $userinput);
@@ -3837,7 +3904,9 @@ sub put_course_id_hash_handler {
# creationcontext - include courses created in specified context
#
# domcloner - flag to indicate if user can create CCs in course's domain.
-# If so, ability to clone course is automatic.
+# If so, ability to clone course is automatic.
+# hasuniquecode - filter by courses for which a six character unique code has
+# been set.
#
# $client - The socket open on the client.
# Returns:
@@ -3862,7 +3931,7 @@ sub dump_course_id_handler {
my ($udom,$since,$description,$instcodefilter,$ownerfilter,$coursefilter,
$typefilter,$regexp_ok,$rtn_as_hash,$selfenrollonly,$catfilter,$showhidden,
$caller,$cloner,$cc_clone_list,$cloneonly,$createdbefore,$createdafter,
- $creationcontext,$domcloner) =split(/:/,$tail);
+ $creationcontext,$domcloner,$hasuniquecode) =split(/:/,$tail);
my $now = time;
my ($cloneruname,$clonerudom,%cc_clone);
if (defined($description)) {
@@ -3935,6 +4004,9 @@ sub dump_course_id_handler {
} else {
$creationcontext = '.';
}
+ unless ($hasuniquecode) {
+ $hasuniquecode = '.';
+ }
my $unpack = 1;
if ($description eq '.' && $instcodefilter eq '.' && $ownerfilter eq '.' &&
$typefilter eq '.') {
@@ -4023,6 +4095,9 @@ sub dump_course_id_handler {
$selfenroll_end = $items->{'selfenroll_end_date'};
$created = $items->{'created'};
$context = $items->{'context'};
+ if ($hasuniquecode ne '.') {
+ next unless ($items->{'uniquecode'});
+ }
if ($selfenrollonly) {
next if (!$selfenroll_types);
if (($selfenroll_end > 0) && ($selfenroll_end <= $now)) {
@@ -5255,7 +5330,7 @@ sub crsreq_checks_handler {
my $userinput = "$cmd:$tail";
my $dom = $tail;
my $result;
- my @reqtypes = ('official','unofficial','community');
+ my @reqtypes = ('official','unofficial','community','textbook');
eval {
local($SIG{__DIE__})='DEFAULT';
my %validations;
@@ -5282,19 +5357,20 @@ sub crsreq_checks_handler {
sub validate_crsreq_handler {
my ($cmd, $tail, $client) = @_;
my $userinput = "$cmd:$tail";
- my ($dom,$owner,$crstype,$inststatuslist,$instcode,$instseclist) = split(/:/, $tail);
+ my ($dom,$owner,$crstype,$inststatuslist,$instcode,$instseclist,$customdata) = split(/:/, $tail);
$instcode = &unescape($instcode);
$owner = &unescape($owner);
$crstype = &unescape($crstype);
$inststatuslist = &unescape($inststatuslist);
$instcode = &unescape($instcode);
$instseclist = &unescape($instseclist);
+ my $custominfo = &Apache::lonnet::thaw_unescape($customdata);
my $outcome;
eval {
local($SIG{__DIE__})='DEFAULT';
$outcome = &localenroll::validate_crsreq($dom,$owner,$crstype,
$inststatuslist,$instcode,
- $instseclist);
+ $instseclist,$custominfo);
};
if (!$@) {
&Reply($client, \$outcome, $userinput);
@@ -5305,6 +5381,53 @@ sub validate_crsreq_handler {
}
®ister_handler("autocrsreqvalidation", \&validate_crsreq_handler, 0, 1, 0);
+sub crsreq_update_handler {
+ my ($cmd, $tail, $client) = @_;
+ my $userinput = "$cmd:$tail";
+ my ($cdom,$cnum,$crstype,$action,$ownername,$ownerdomain,$fullname,$title,$code,
+ $accessstart,$accessend,$infohashref) =
+ split(/:/, $tail);
+ $crstype = &unescape($crstype);
+ $action = &unescape($action);
+ $ownername = &unescape($ownername);
+ $ownerdomain = &unescape($ownerdomain);
+ $fullname = &unescape($fullname);
+ $title = &unescape($title);
+ $code = &unescape($code);
+ $accessstart = &unescape($accessstart);
+ $accessend = &unescape($accessend);
+ my $incoming = &Apache::lonnet::thaw_unescape($infohashref);
+ my ($result,$outcome);
+ eval {
+ local($SIG{__DIE__})='DEFAULT';
+ my %rtnhash;
+ $outcome = &localenroll::crsreq_updates($cdom,$cnum,$crstype,$action,
+ $ownername,$ownerdomain,$fullname,
+ $title,$code,$accessstart,$accessend,
+ $incoming,\%rtnhash);
+ if ($outcome eq 'ok') {
+ my @posskeys = qw(createdweb createdmsg queuedweb queuedmsg formitems reviewweb);
+ foreach my $key (keys(%rtnhash)) {
+ if (grep(/^\Q$key\E/,@posskeys)) {
+ $result .= &escape($key).'='.&Apache::lonnet::freeze_escape($rtnhash{$key}).'&';
+ }
+ }
+ $result =~ s/\&$//;
+ }
+ };
+ if (!$@) {
+ if ($outcome eq 'ok') {
+ &Reply($client, \$result, $userinput);
+ } else {
+ &Reply($client, "format_error\n", $userinput);
+ }
+ } else {
+ &Failure($client,"unknown_cmd\n",$userinput);
+ }
+ return 1;
+}
+®ister_handler("autocrsrequpdate", \&crsreq_update_handler, 0, 1, 0);
+
#
# Read and retrieve institutional code format (for support form).
# Formal Parameters:
@@ -6500,9 +6623,22 @@ sub make_new_child {
# my $tmpsnum=0; # Now global
#---------------------------------------------------- kerberos 5 initialization
&Authen::Krb5::init_context();
- unless (($dist eq 'fedora5') || ($dist eq 'fedora4') ||
- ($dist eq 'fedora6') || ($dist eq 'suse9.3') ||
- ($dist eq 'suse12.2') || ($dist eq 'suse12.3')) {
+
+ my $no_ets;
+ if ($dist =~ /^(?:centos|rhes)(\d+)$/) {
+ if ($1 >= 7) {
+ $no_ets = 1;
+ }
+ } elsif ($dist =~ /^suse(\d+\.\d+)$/) {
+ if (($1 eq '9.3') || ($1 >= 12.2)) {
+ $no_ets = 1;
+ }
+ } elsif ($dist =~ /^fedora(\d+)$/) {
+ if ($1 < 7) {
+ $no_ets = 1;
+ }
+ }
+ unless ($no_ets) {
&Authen::Krb5::init_ets();
}