Diff for /loncom/lonnet/perl/lonnet.pm between versions 1.634 and 1.648

version 1.634, 2005/05/05 20:55:04 version 1.648, 2005/07/26 13:30:34
Line 47  use IO::Socket; Line 47  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 HTML::Parser;
 use Fcntl qw(:flock);  use Fcntl qw(:flock);
 use Apache::lonlocal;  use Apache::lonlocal;
 use Storable qw(lock_store lock_nstore lock_retrieve freeze thaw nfreeze);  use Storable qw(lock_store lock_nstore lock_retrieve freeze thaw nfreeze);
Line 258  sub critical { Line 259  sub critical {
   
 sub transfer_profile_to_env {  sub transfer_profile_to_env {
     my ($lonidsdir,$handle)=@_;      my ($lonidsdir,$handle)=@_;
     undef(%env);  
     my @profile;      my @profile;
     {      {
  open(my $idf,"$lonidsdir/$handle.id");   open(my $idf,"$lonidsdir/$handle.id");
Line 1132  sub allowuploaded { Line 1132  sub allowuploaded {
 }  }
   
 # --------- 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, home server for course, intended  # input: action, courseID, current domain, intended
 #        path to file, source of file.  #        path to file, source of file, instruction to parse file for objects,
   #        ref to hash for embedded objects,
   #        ref to hash for codebase of java objects.
   #
 # output: url to file (if action was uploaddoc),   # output: url to file (if action was uploaddoc), 
 #         ok if successful, or diagnostic message otherwise (if action was propagate or copy)  #         ok if successful, or diagnostic message otherwise (if action was propagate or copy)
 #  #
Line 1156  sub allowuploaded { Line 1159  sub allowuploaded {
 #         /home/httpd/html/userfiles/$domain/1/2/3/$course/$file  #         /home/httpd/html/userfiles/$domain/1/2/3/$course/$file
 #         and will then be copied to /home/httpd/lonUsers/1/2/3/$course/userfiles/$file  #         and will then be copied to /home/httpd/lonUsers/1/2/3/$course/userfiles/$file
 #         in course's home server.  #         in course's home server.
   #
   
 sub process_coursefile {  sub process_coursefile {
     my ($action,$docuname,$docudom,$docuhome,$file,$source)=@_;      my ($action,$docuname,$docudom,$file,$source,$parser,$allfiles,$codebase)=@_;
     my $fetchresult;      my $fetchresult;
       my $home=&homeserver($docuname,$docudom);
     if ($action eq 'propagate') {      if ($action eq 'propagate') {
         $fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file          $fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file,
                             ,$docuhome);       $home);
     } else {      } else {
         my $fetchresult = '';          my $fetchresult = '';
         my $fpath = '';          my $fpath = '';
         my $fname = $file;          my $fname = $file;
         ($fpath,$fname) = ($file =~ m|^(.*)/([^/]+)$|);          ($fpath,$fname) = ($file =~ m|^(.*)/([^/]+)$|);
         $fpath=$docudom.'/'.$docuname.'/'.$fpath;          $fpath=$docudom.'/'.$docuname.'/'.$fpath;
         my $filepath=$perlvar{'lonDocRoot'}.'/userfiles';          my $filepath = &build_filepath($fpath);
         unless ($fpath eq '') {  
             my @parts=split('/',$fpath);  
             foreach my $part (@parts) {  
                 $filepath.= '/'.$part;  
                 if ((-e $filepath)!=1) {  
                     mkdir($filepath,0777);  
                 }  
             }  
         }  
         if ($action eq 'copy') {          if ($action eq 'copy') {
             if ($source eq '') {              if ($source eq '') {
                 $fetchresult = 'no source file';                  $fetchresult = 'no source file';
Line 1188  sub process_coursefile { Line 1183  sub process_coursefile {
                 my $destination = $filepath.'/'.$fname;                  my $destination = $filepath.'/'.$fname;
                 rename($source,$destination);                  rename($source,$destination);
                 $fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file,                  $fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file,
                                  $docuhome);                                   $home);
             }              }
         } elsif ($action eq 'uploaddoc') {          } elsif ($action eq 'uploaddoc') {
             open(my $fh,'>'.$filepath.'/'.$fname);              open(my $fh,'>'.$filepath.'/'.$fname);
             print $fh $env{'form.'.$source};              print $fh $env{'form.'.$source};
             close($fh);              close($fh);
               if ($parser eq 'parse') {
                   my $parse_result = &extract_embedded_items($filepath,$fname,$allfiles,$codebase);
                   unless ($parse_result eq 'ok') {
                       &logthis('Failed to parse '.$filepath.'/'.$fname.' for embedded media: '.$parse_result);
                   }
               }
             $fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file,              $fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file,
                                  $docuhome);                                   $home);
             if ($fetchresult eq 'ok') {              if ($fetchresult eq 'ok') {
                 return '/uploaded/'.$fpath.'/'.$fname;                  return '/uploaded/'.$fpath.'/'.$fname;
             } else {              } else {
                 &logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file.                  &logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file.
                         ' to host '.$docuhome.': '.$fetchresult);                          ' to host '.$home.': '.$fetchresult);
                 return '/adm/notfound.html';                  return '/adm/notfound.html';
             }              }
         }          }
     }      }
     unless ( $fetchresult eq 'ok') {      unless ( $fetchresult eq 'ok') {
         &logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file.          &logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file.
              ' to host '.$docuhome.': '.$fetchresult);               ' to host '.$home.': '.$fetchresult);
     }      }
     return $fetchresult;      return $fetchresult;
 }  }
   
   sub build_filepath {
       my ($fpath) = @_;
       my $filepath=$perlvar{'lonDocRoot'}.'/userfiles';
       unless ($fpath eq '') {
           my @parts=split('/',$fpath);
           foreach my $part (@parts) {
               $filepath.= '/'.$part;
               if ((-e $filepath)!=1) {
                   mkdir($filepath,0777);
               }
           }
       }
       return $filepath;
   }
   
   sub store_edited_file {
       my ($primary_url,$content,$docudom,$docuname,$fetchresult) = @_;
       my $file = $primary_url;
       $file =~ s#^/uploaded/$docudom/$docuname/##;
       my $fpath = '';
       my $fname = $file;
       ($fpath,$fname) = ($file =~ m|^(.*)/([^/]+)$|);
       $fpath=$docudom.'/'.$docuname.'/'.$fpath;
       my $filepath = &build_filepath($fpath);
       open(my $fh,'>'.$filepath.'/'.$fname);
       print $fh $content;
       close($fh);
       my $home=&homeserver($docuname,$docudom);
       $$fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file,
     $home);
       if ($$fetchresult eq 'ok') {
           return '/uploaded/'.$fpath.'/'.$fname;
       } else {
           &logthis('Failed to transfer '.$docudom.'/'.$docuname.'/'.$file.
    ' to host '.$home.': '.$$fetchresult);
           return '/adm/notfound.html';
       }
   }
   
 sub clean_filename {  sub clean_filename {
     my ($fname)=@_;      my ($fname)=@_;
 # Replace Windows backslashes by forward slashes  # Replace Windows backslashes by forward slashes
Line 1234  sub clean_filename { Line 1274  sub clean_filename {
   
   
 sub userfileupload {  sub userfileupload {
     my ($formname,$coursedoc,$subdir)=@_;      my ($formname,$coursedoc,$subdir,$parser,$allfiles,$codebase)=@_;
     if (!defined($subdir)) { $subdir='unknown'; }      if (!defined($subdir)) { $subdir='unknown'; }
     my $fname=$env{'form.'.$formname.'.filename'};      my $fname=$env{'form.'.$formname.'.filename'};
     $fname=&clean_filename($fname);      $fname=&clean_filename($fname);
Line 1258  sub userfileupload { Line 1298  sub userfileupload {
         return $fullpath.'/'.$fname;           return $fullpath.'/'.$fname; 
     }      }
 # Create the directory if not present  # Create the directory if not present
     my $docuname='';  
     my $docudom='';  
     my $docuhome='';  
     $fname="$subdir/$fname";      $fname="$subdir/$fname";
     if ($coursedoc) {      if ($coursedoc) {
  $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};   my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
  $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};   my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
  $docuhome=$env{'course.'.$env{'request.course.id'}.'.home'};          if ($env{'form.folder'} =~ m/^(default|supplemental)/) {
         if ($env{'form.folder'} =~ m/^default/) {              return &finishuserfileupload($docuname,$docudom,
             return &finishuserfileupload($docuname,$docudom,$docuhome,$formname,$fname);   $formname,$fname,$parser,$allfiles,
    $codebase);
         } else {          } else {
             $fname=$env{'form.folder'}.'/'.$fname;              $fname=$env{'form.folder'}.'/'.$fname;
             return &process_coursefile('uploaddoc',$docuname,$docudom,$docuhome,$fname,$formname);              return &process_coursefile('uploaddoc',$docuname,$docudom,
          $fname,$formname,$parser,
          $allfiles,$codebase);
         }          }
     } else {      } else {
         $docuname=$env{'user.name'};          my $docuname=$env{'user.name'};
         $docudom=$env{'user.domain'};          my $docudom=$env{'user.domain'};
         $docuhome=$env{'user.home'};   return &finishuserfileupload($docuname,$docudom,$formname,
         return &finishuserfileupload($docuname,$docudom,$docuhome,$formname,$fname);       $fname,$parser,$allfiles,$codebase);
     }      }
 }  }
   
 sub finishuserfileupload {  sub finishuserfileupload {
     my ($docuname,$docudom,$docuhome,$formname,$fname)=@_;      my ($docuname,$docudom,$formname,$fname,$parser,$allfiles,$codebase) = @_;
     my $path=$docudom.'/'.$docuname.'/';      my $path=$docudom.'/'.$docuname.'/';
     my $filepath=$perlvar{'lonDocRoot'};      my $filepath=$perlvar{'lonDocRoot'};
     my ($fnamepath,$file);      my ($fnamepath,$file);
Line 1304  sub finishuserfileupload { Line 1344  sub finishuserfileupload {
  print FH $env{'form.'.$formname};   print FH $env{'form.'.$formname};
  close(FH);   close(FH);
     }      }
       if ($parser eq 'parse') {
           my $parse_result = &extract_embedded_items($filepath,$file,$allfiles,
      $codebase);
           unless ($parse_result eq 'ok') {
               &logthis('Failed to parse '.$filepath.$file.
        ' for embedded media: '.$parse_result); 
           }
       }
 # Notify homeserver to grep it  # Notify homeserver to grep it
 #  #
       my $docuhome=&homeserver($docuname,$docudom);
     my $fetchresult= &reply('fetchuserfile:'.$path.$file,$docuhome);      my $fetchresult= &reply('fetchuserfile:'.$path.$file,$docuhome);
     if ($fetchresult eq 'ok') {      if ($fetchresult eq 'ok') {
 #  #
Line 1318  sub finishuserfileupload { Line 1367  sub finishuserfileupload {
     }          }    
 }  }
   
   sub extract_embedded_items {
       my ($filepath,$file,$allfiles,$codebase,$content) = @_;
       my @state = ();
       my %javafiles = (
                         codebase => '',
                         code => '',
                         archive => ''
                       );
       my %mediafiles = (
                         src => '',
                         movie => '',
                        );
       my $p;
       if ($content) {
           $p = HTML::LCParser->new($content);
       } else {
           $p = HTML::LCParser->new($filepath.'/'.$file);
       }
       while (my $t=$p->get_token()) {
    if ($t->[0] eq 'S') {
       my ($tagname, $attr) = ($t->[1],$t->[2]);
       push (@state, $tagname);
               if (lc($tagname) eq 'allow') {
                   &add_filetype($allfiles,$attr->{'src'},'src');
               }
       if (lc($tagname) eq 'img') {
    &add_filetype($allfiles,$attr->{'src'},'src');
       }
               if (lc($tagname) eq 'script') {
                   if ($attr->{'archive'} =~ /\.jar$/i) {
                       &add_filetype($allfiles,$attr->{'archive'},'archive');
                   } else {
                       &add_filetype($allfiles,$attr->{'src'},'src');
                   }
               }
               if (lc($tagname) eq 'link') {
                   if (lc($attr->{'rel'}) eq 'stylesheet') { 
                       &add_filetype($allfiles,$attr->{'href'},'href');
                   }
               }
       if (lc($tagname) eq 'object' ||
    (lc($tagname) eq 'embed' && lc($state[-2]) ne 'object')) {
    foreach my $item (keys(%javafiles)) {
       $javafiles{$item} = '';
    }
       }
       if (lc($state[-2]) eq 'object' && lc($tagname) eq 'param') {
    my $name = lc($attr->{'name'});
    foreach my $item (keys(%javafiles)) {
       if ($name eq $item) {
    $javafiles{$item} = $attr->{'value'};
    last;
       }
    }
    foreach my $item (keys(%mediafiles)) {
       if ($name eq $item) {
    &add_filetype($allfiles, $attr->{'value'}, 'value');
    last;
       }
    }
       }
       if (lc($tagname) eq 'embed' || lc($tagname) eq 'applet') {
    foreach my $item (keys(%javafiles)) {
       if ($attr->{$item}) {
    $javafiles{$item} = $attr->{$item};
    last;
       }
    }
    foreach my $item (keys(%mediafiles)) {
       if ($attr->{$item}) {
    &add_filetype($allfiles,$attr->{$item},$item);
    last;
       }
    }
       }
    } elsif ($t->[0] eq 'E') {
       my ($tagname) = ($t->[1]);
       if ($javafiles{'codebase'} ne '') {
    $javafiles{'codebase'} .= '/';
       }  
       if (lc($tagname) eq 'applet' ||
    lc($tagname) eq 'object' ||
    (lc($tagname) eq 'embed' && lc($state[-2]) ne 'object')
    ) {
    foreach my $item (keys(%javafiles)) {
       if ($item ne 'codebase' && $javafiles{$item} ne '') {
    my $file=$javafiles{'codebase'}.$javafiles{$item};
    &add_filetype($allfiles,$file,$item);
       }
    }
       } 
       pop @state;
    }
       }
       return 'ok';
   }
   
   sub add_filetype {
       my ($allfiles,$file,$type)=@_;
       if (exists($allfiles->{$file})) {
    unless (grep/^\Q$type\E$/, @{$allfiles->{$file}}) {
       push(@{$allfiles->{$file}}, &escape($type));
    }
       } else {
    @{$allfiles->{$file}} = (&escape($type));
       }
   }
   
 sub removeuploadedurl {  sub removeuploadedurl {
     my ($url)=@_;      my ($url)=@_;
     my (undef,undef,$udom,$uname,$fname)=split('/',$url,5);      my (undef,undef,$udom,$uname,$fname)=split('/',$url,5);
Line 2744  sub allowed { Line 2901  sub allowed {
   
 # Free bre access to user's own portfolio contents  # Free bre access to user's own portfolio contents
     my ($space,$domain,$name,$dir)=split('/',$uri);      my ($space,$domain,$name,$dir)=split('/',$uri);
     if (($space=~/^(uploaded|ediupload)$/) && ($env{'user.name'} eq $name) &&       if (($space=~/^(uploaded|editupload)$/) && ($env{'user.name'} eq $name) && 
  ($env{'user.domain'} eq $domain) && ('portfolio' eq $dir)) {   ($env{'user.domain'} eq $domain) && ('portfolio' eq $dir)) {
         return 'F';          return 'F';
     }      }
Line 2831  sub allowed { Line 2988  sub allowed {
   
 # If this is generating or modifying users, exit with special codes  # If this is generating or modifying users, exit with special codes
   
     if (':csu:cdc:ccc:cin:cta:cep:ccr:cst:cad:cli:cau:cdg:cca:'=~/\:\Q$priv\E\:/) {      if (':csu:cdc:ccc:cin:cta:cep:ccr:cst:cad:cli:cau:cdg:cca:caa:'=~/\:\Q$priv\E\:/) {
    if (($priv eq 'cca') || ($priv eq 'caa')) {
       my ($audom,$auname)=split('/',$uri);
   # no author name given, so this just checks on the general right to make a co-author in this domain
       unless ($auname) { return $thisallowed; }
   # an author name is given, so we are about to actually make a co-author for a certain account
       if (($auname ne $env{'user.name'} && $env{'request.role'} !~ /^dc\./) ||
    (($audom ne $env{'user.domain'} && $env{'request.role'} !~ /^dc\./) &&
    ($audom ne $env{'request.role.domain'}))) { return ''; }
    }
  return $thisallowed;   return $thisallowed;
     }      }
 #  #
Line 3705  sub createcourse { Line 3871  sub createcourse {
 </map>  </map>
 ENDINITMAP  ENDINITMAP
         $topurl=&declutter(          $topurl=&declutter(
         &finishuserfileupload($uname,$udom,$uhome,'initmap','default.sequence')          &finishuserfileupload($uname,$udom,'initmap','default.sequence')
                           );                            );
     }      }
 # ----------------------------------------------------------- Write preferences  # ----------------------------------------------------------- Write preferences
Line 4177  sub get_userresdata { Line 4343  sub get_userresdata {
     } elsif ($tmp=~/error: 2 /) {      } elsif ($tmp=~/error: 2 /) {
  #&EXT_cache_set($udom,$uname);   #&EXT_cache_set($udom,$uname);
  &do_cache_new('userres',$hashid,undef,600);   &do_cache_new('userres',$hashid,undef,600);
    undef($tmp); # not really an error so don't send it back
     }      }
     return $tmp;      return $tmp;
 }  }
Line 4651  sub metadata { Line 4818  sub metadata {
  }   }
  my ($extension) = ($uri =~ /\.(\w+)$/);   my ($extension) = ($uri =~ /\.(\w+)$/);
  foreach my $key (sort(keys(%packagetab))) {   foreach my $key (sort(keys(%packagetab))) {
     #&logthis("extsion1 $extension $key !!");  
     #no specific packages #how's our extension      #no specific packages #how's our extension
     if ($key!~/^extension_\Q$extension\E&/) { next; }      if ($key!~/^extension_\Q$extension\E&/) { next; }
     &metadata_create_package_def($uri,$key,'extension_'.$extension,      &metadata_create_package_def($uri,$key,'extension_'.$extension,
Line 4739  sub metadata_generate_part0 { Line 4905  sub metadata_generate_part0 {
    '.type'};     '.type'};
       my $olddis=$$metacache{':parameter_'.$allnames{$name}.'_'.$name.        my $olddis=$$metacache{':parameter_'.$allnames{$name}.'_'.$name.
      '.display'};       '.display'};
       my $expr='\\[Part: '.$allnames{$name}.'\\]';        my $expr='[Part: '.$allnames{$name}.']';
       $olddis=~s/\Q$expr\E/\[Part: 0\]/;        $olddis=~s/\Q$expr\E/\[Part: 0\]/;
       $$metacache{"$key.display"}=$olddis;        $$metacache{"$key.display"}=$olddis;
     }      }
Line 4844  sub symbverify { Line 5010  sub symbverify {
         if ($ids) {          if ($ids) {
 # ------------------------------------------------------------------- Has ID(s)  # ------------------------------------------------------------------- Has ID(s)
     foreach (split(/\,/,$ids)) {      foreach (split(/\,/,$ids)) {
                my ($mapid,$resid)=split(/\./,$_);         my ($mapid,$resid)=split(/\./,$_);
                if (                 if (
   &symbclean(&declutter($bighash{'map_id_'.$mapid}).'___'.$resid.'___'.$thisfn)    &symbclean(&declutter($bighash{'map_id_'.$mapid}).'___'.$resid.'___'.$thisfn)
    eq $symb) {      eq $symb) { 
Line 6628  userspace, probably shouldn't be called Line 6794  userspace, probably shouldn't be called
   
   docuname: username or courseid of destination for the file    docuname: username or courseid of destination for the file
   docudom: domain of user/course of destination for the file    docudom: domain of user/course of destination for the file
   docuhome: loncapa id of the library server that is getting the file  
   formname: same as for userfileupload()    formname: same as for userfileupload()
   fname: filename (inculding subdirectories) for the file    fname: filename (inculding subdirectories) for the file
   

Removed from v.1.634  
changed lines
  Added in v.1.648


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>