Annotation of loncom/publisher/lonupload.pm, revision 1.21
1.12 foxr 1:
1.1 www 2: # The LearningOnline Network with CAPA
3: # Handler to upload files into construction space
4: #
1.21 ! albertel 5: # $Id: lonupload.pm,v 1.20 2003/09/22 15:39:53 www Exp $
1.8 matthew 6: #
7: # Copyright Michigan State University Board of Trustees
8: #
9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
10: #
11: # LON-CAPA is free software; you can redistribute it and/or modify
12: # it under the terms of the GNU General Public License as published by
13: # the Free Software Foundation; either version 2 of the License, or
14: # (at your option) any later version.
15: #
16: # LON-CAPA is distributed in the hope that it will be useful,
17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19: # GNU General Public License for more details.
20: #
21: # You should have received a copy of the GNU General Public License
22: # along with LON-CAPA; if not, write to the Free Software
23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24: #
25: # /home/httpd/html/adm/gpl.txt
26: #
27: # http://www.lon-capa.org/
28: #
1.10 harris41 29: ###
1.1 www 30:
31: package Apache::lonupload;
32:
33: use strict;
34: use Apache::File;
35: use File::Copy;
1.13 foxr 36: use File::Basename;
1.1 www 37: use Apache::Constants qw(:common :http :methods);
1.3 www 38: use Apache::loncacc;
1.10 harris41 39: use Apache::loncommon();
1.12 foxr 40: use Apache::Log();
1.13 foxr 41: use Apache::lonnet;
1.14 foxr 42: use HTML::Entities();
1.20 www 43: use Apache::lonlocal;
1.12 foxr 44:
45: my $DEBUG=0;
46:
47: sub Debug {
48:
49: # Marshall the parameters.
50:
51: my $r = shift;
52: my $log = $r->log;
53: my $message = shift;
54:
55: # Put out the indicated message butonly if DEBUG is false.
56:
57: if ($DEBUG) {
58: $log->debug($message);
59: }
60: }
1.1 www 61:
1.2 www 62: sub upfile_store {
63: my $r=shift;
64:
65: my $fname=$ENV{'form.upfile.filename'};
66: $fname=~s/\W//g;
67:
1.18 www 68: chomp($ENV{'form.upfile'});
1.1 www 69:
1.2 www 70: my $datatoken=$ENV{'user.name'}.'_'.$ENV{'user.domain'}.
71: '_upload_'.$fname.'_'.time.'_'.$$;
72: {
73: my $fh=Apache::File->new('>'.$r->dir_config('lonDaemons').
74: '/tmp/'.$datatoken.'.tmp');
75: print $fh $ENV{'form.upfile'};
1.1 www 76: }
1.2 www 77: return $datatoken;
78: }
79:
80:
81: sub phaseone {
1.5 www 82: my ($r,$fn,$uname,$udom)=@_;
1.6 www 83: $ENV{'form.upfile.filename'}=~s/\\/\//g;
84: $ENV{'form.upfile.filename'}=~s/^.*\/([^\/]+)$/$1/;
1.5 www 85: if ($ENV{'form.upfile.filename'}) {
1.2 www 86: $fn=~s/\/[^\/]+$//;
87: $fn=~s/([^\/])$/$1\//;
88: $fn.=$ENV{'form.upfile.filename'};
1.3 www 89: $fn=~s/^\///;
90: $fn=~s/(\/)+/\//g;
1.13 foxr 91:
92: # Fn is the full path to the destination filename.
93: #
94:
1.12 foxr 95: &Debug($r, "Filename for upload: $fn");
1.3 www 96: if (($fn) && ($fn!~/\/$/)) {
97: $r->print(
1.2 www 98: '<form action=/adm/upload method=post>'.
99: '<input type=hidden name=phase value=two>'.
100: '<input type=hidden name=datatoken value="'.&upfile_store.'">'.
1.18 www 101: '<input type=hidden name=uploaduname value="'.$uname.'">'.
1.21 ! albertel 102: &mt('Store uploaded file as ')."<tt>/priv/$uname/</tt>".
1.18 www 103: '<input type=text size=50 name=filename value="'.$fn.'"><br>'.
1.20 www 104: '<input type=submit value="'.&mt('Store').'"></form>');
1.9 matthew 105: # Check for bad extension and warn user
1.8 matthew 106: if ($fn=~/\.(\w+)$/ &&
1.10 harris41 107: (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
1.8 matthew 108: $r->print(
109: '<font color=red>'.
1.20 www 110: &mt('The extension on this file,').' "'.$1.
111: '"'.&mt(', is reserved internally by LON-CAPA.').' <br \>'.
112: &mt('Please change the extension.').
1.8 matthew 113: '</font>');
1.9 matthew 114: } elsif($fn=~/\.(\w+)$/ &&
1.10 harris41 115: !defined(&Apache::loncommon::fileembstyle($1))) {
1.9 matthew 116: $r->print(
117: '<font color=red>'.
1.20 www 118: &mt('The extension on this file,').' "'.$1.
119: '"'.&mt(', is not recognized by LON-CAPA.').' <br \>'.
120: &mt('Please change the extension.').
1.9 matthew 121: '</font>');
122: }
1.3 www 123: } else {
1.20 www 124: $r->print('<font color=red>'.&mt('Illegal filename.').'</font>');
1.3 www 125: }
1.5 www 126: } else {
1.20 www 127: $r->print('<font color=red>'.&mt('No upload file specified.').'</font>');
1.5 www 128: }
1.1 www 129: }
130:
131: sub phasetwo {
1.18 www 132: my ($r,$tfn,$uname,$udom)=@_;
133: my $fn='/priv/'.$uname.'/'.$tfn;
134: $fn=~s/\/+/\//g;
135: &Debug($r, "Filename is ".$tfn);
136: if ($tfn) {
1.13 foxr 137: &Debug($r, "Filename for tfn = ".$tfn);
1.3 www 138: my $target='/home/'.$uname.'/public_html'.$tfn;
1.13 foxr 139: &Debug($r, "target -> ".$target);
140: # target is the full filesystem path of the destination file.
141: my $base = &File::Basename::basename($fn);
142: my $path = &File::Basename::dirname($fn);
1.14 foxr 143: $base = &HTML::Entities::encode($base);
1.13 foxr 144: my $url = $path."/".$base;
145: &Debug($r, "URL is now ".$url);
1.2 www 146: my $datatoken=$ENV{'form.datatoken'};
147: if (($fn) && ($datatoken)) {
148: if ((-e $target) && ($ENV{'form.override'} ne 'Yes')) {
149: $r->print(
150: '<form action=/adm/upload method=post>'.
1.20 www 151: &mt('File').' <tt>'.$fn.'</tt> '.&mt('exists. Overwrite?').' '.
1.2 www 152: '<input type=hidden name=phase value=two>'.
1.13 foxr 153: '<input type=hidden name=filename value="'."$url".'">'.
1.2 www 154: '<input type=hidden name=datatoken value="'.$datatoken.'">'.
1.20 www 155: '<input type=submit name=override value="'.&mt('Yes').'"></form>');
1.2 www 156: } else {
157: my $source=$r->dir_config('lonDaemons').
158: '/tmp/'.$datatoken.'.tmp';
1.9 matthew 159: # Check for bad extension and disallow upload
1.8 matthew 160: if ($fn=~/\.(\w+)$/ &&
1.10 harris41 161: (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
1.8 matthew 162: $r->print(
1.20 www 163: &mt('File').' <tt>'.$fn.'</tt> '.&mt('could not be copied.').'<br />'.
1.8 matthew 164: '<font color=red>'.
1.20 www 165: &mt('The extension on this file is reserved internally by LON-CAPA.').
1.9 matthew 166: '</font>');
1.19 www 167: $r->print('<p><font size=+2><a href="'.$path.
1.20 www 168: '">'.&mt('Back to Directory').'</a></font>');
1.9 matthew 169: } elsif ($fn=~/\.(\w+)$/ &&
1.10 harris41 170: !defined(&Apache::loncommon::fileembstyle($1))) {
1.9 matthew 171: $r->print(
1.20 www 172: &mt('File').' <tt>'.$fn.'</tt> '.&mt('could not be copied.').'<br />'.
1.9 matthew 173: '<font color=red>'.
1.20 www 174: &mt('The extension on this file is not recognized by LON-CAPA.').
1.8 matthew 175: '</font>');
1.19 www 176: $r->print('<p><font size=+2><a href="'.$path.
1.20 www 177: '">'.&mt('Back to Directory').'</a></font>');
1.19 www 178: } elsif (-d $target) {
179: $r->print(
180: 'File <tt>'.$fn.'</tt> could not be copied.<br />'.
181: '<font color=red>'.
1.20 www 182: &mt('The target is an existing directory.').
1.19 www 183: '</font>');
184: $r->print('<p><font size=+2><a href="'.$path.
1.20 www 185: '">'.&mt('Back to Directory').'</a></font>');
1.8 matthew 186: } elsif (copy($source,$target)) {
1.11 foxr 187: chmod(0660, $target); # Set permissions to rw-rw---.
1.20 www 188: $r->print(&mt('File copied.'));
1.13 foxr 189: $r->print('<p><font size=+2><a href="'.$url.
1.20 www 190: '">'.&mt('View file').'</a></font>');
1.16 albertel 191: $r->print('<p><font size=+2><a href="'.$path.
1.20 www 192: '">'.&mt('Back to Directory').'</a></font>');
1.2 www 193: } else {
194: $r->print('Failed to copy: '.$!);
1.19 www 195: $r->print('<p><font size=+2><a href="'.$path.
1.20 www 196: '">'.&mt('Back to Directory').'</a></font>');
1.2 www 197: }
198: }
1.1 www 199: } else {
200: $r->print(
1.20 www 201: '<font size=+1 color=red>'.
202: &mt('Please use browser "Back" button and pick a filename').'</font><p>');
1.1 www 203: }
1.4 www 204: } else {
205: $r->print(
1.20 www 206: '<font size=+1 color=red>'.&mt('Please use browser "Back" button and pick a filename').'</font><p>');
1.4 www 207: }
1.1 www 208: }
209:
1.10 harris41 210: # ---------------------------------------------------------------- Main Handler
1.1 www 211: sub handler {
212:
213: my $r=shift;
214:
1.3 www 215: my $uname;
216: my $udom;
1.18 www 217: #
218: # phase two: re-attach user
219: #
220: if ($ENV{'form.uploaduname'}) {
221: $ENV{'form.filename'}='/priv/'.$ENV{'form.uploaduname'}.'/'.
222: $ENV{'form.filename'};
223: }
224: #
1.3 www 225:
1.5 www 226: ($uname,$udom)=
1.3 www 227: &Apache::loncacc::constructaccess(
1.5 www 228: $ENV{'form.filename'},$r->dir_config('lonDefDomain'));
229: unless (($uname) && ($udom)) {
1.3 www 230: $r->log_reason($uname.' at '.$udom.
231: ' trying to publish file '.$ENV{'form.filename'}.
232: ' - not authorized',
233: $r->filename);
234: return HTTP_NOT_ACCEPTABLE;
235: }
236:
1.1 www 237: my $fn;
238: if ($ENV{'form.filename'}) {
239: $fn=$ENV{'form.filename'};
1.18 www 240: $fn=~s/^http\:\/\/[^\/]+\///;
241: $fn=~s/^\///;
242: $fn=~s/(\~|priv\/)(\w+)//;
243: $fn=~s/\/+/\//g;
1.1 www 244: } else {
245: $r->log_reason($ENV{'user.name'}.' at '.$ENV{'user.domain'}.
1.2 www 246: ' unspecified filename for upload', $r->filename);
1.1 www 247: return HTTP_NOT_FOUND;
248: }
249:
250: # ----------------------------------------------------------- Start page output
251:
252:
1.20 www 253: &Apache::loncommon::content_type($r,'text/html');
1.1 www 254: $r->send_http_header;
255:
256: $r->print('<html><head><title>LON-CAPA Construction Space</title></head>');
257:
1.17 www 258: $r->print(&Apache::loncommon::bodytag('Upload file to Construction Space'));
1.3 www 259:
260: if (($uname ne $ENV{'user.name'}) || ($udom ne $ENV{'user.domain'})) {
1.21 ! albertel 261: $r->print('<h3><font color=red>'.&mt('Co-Author').': '.$uname.
! 262: &mt(' at ').$udom.'</font></h3>');
1.3 www 263: }
1.1 www 264:
265: if ($ENV{'form.phase'} eq 'two') {
266: &phasetwo($r,$fn,$uname,$udom);
267: } else {
268: &phaseone($r,$fn,$uname,$udom);
269: }
270:
271: $r->print('</body></html>');
272: return OK;
273: }
1.7 www 274:
275: 1;
276: __END__
1.10 harris41 277:
278: =head1 NAME
279:
280: Apache::lonupload - upload files into construction space
281:
282: =head1 SYNOPSIS
283:
284: Invoked by /etc/httpd/conf/srm.conf:
285:
286: <Location /adm/upload>
287: PerlAccessHandler Apache::lonacc
288: SetHandler perl-script
289: PerlHandler Apache::lonupload
290: ErrorDocument 403 /adm/login
291: ErrorDocument 404 /adm/notfound.html
292: ErrorDocument 406 /adm/unauthorized.html
293: ErrorDocument 500 /adm/errorhandler
294: </Location>
295:
296: =head1 INTRODUCTION
297:
298: This module uploads a file sitting on a client computer into
299: library server construction space.
300:
301: This is part of the LearningOnline Network with CAPA project
302: described at http://www.lon-capa.org.
303:
304: =head1 HANDLER SUBROUTINE
305:
306: This routine is called by Apache and mod_perl.
307:
308: =over 4
309:
310: =item *
311:
312: Initialize variables
313:
314: =item *
315:
316: Start page output
317:
318: =item *
319:
320: output relevant interface phase (phaseone or phasetwo)
321:
322: =item *
323:
324: (phase one is to specify upload file; phase two is to handle conditions
325: subsequent to specification--like overwriting an existing file)
326:
327: =back
328:
329: =head1 OTHER SUBROUTINES
330:
331: =over 4
332:
333: =item *
334:
335: phaseone() : Interface for specifying file to upload.
336:
337: =item *
338:
339: phasetwo() : Interface for handling post-conditions about uploading (such
340: as overwriting an existing file).
341:
342: =item *
343:
344: upfile_store() : Store contents of uploaded file into temporary space. Invoked
345: by phaseone subroutine.
346:
347: =back
348:
349: =cut
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>