#!/usr/bin/perl ############################################################################## $VERSION='getit.pl v1.21'; # Feb 3 97 dale@bewley.net # v1.1 Dec 19 96, v1.0 Sep 96 #----------------------------------------------------------------------------# # Select files from a specified sub dir. Instead of just opening in browser # users may download, view or mail it to themselves. # # this program is not finished! be careful! # # Copyright (C) 1996 Dale Bewley # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # ############################################################################## #- User Config --------------------------------------------------------------# # your webserver's base URL $HTTP_SERVER = "http://www.bewley.net/"; # note trailing slash /. Keep it! # Todo: maybe make this an array and call the program with d=0 or d=1 etc to # select different file areas. Will have revisit what I'm doing with doc_root. # set this to the dir you want browsed $QUEUE_DIR = "/httpd/htdocs/bewley/perl"; # users may not go above here # set this to your web server's document root. ie /usr/local/etc/httpd/htdocs/ $DOC_ROOT = "/httpd/htdocs/bewley/"; # will strip this from queue_dir later # program used to send mail on your system $MAILPROG="/usr/lib/sendmail -oi -t"; $TAR ='/bin/tar'; $GZIP='/bin/gzip'; $ZIP ='/usr/bin/zip'; # ignore this $AUTHOR = 'dale@bewley.net'; # goes in html head and email # ignore this $MIME_TYPES="/extra/WWW/httpd.1.4.2/conf/mime.types"; # unused so far... # ignore this $BOUNDARY="--start-new-page-here--"; # leave alone. don't change! # that's it. you're done. run it! #----------------------------------------------------------------------------# #- Main ---------------------------------------------------------------------# $|=1; # you'll have some odd problems without this use CGI; # list dirs in queue_dir, get names of all queued files in selected subdir & # list them for selection, then read/download that file if (! ($ENV{'CONTENT_LENGTH'} || $ENV{'QUERY_STRING'})) { # no arguments yet. show first default listing &listFiles($QUEUE_DIR); } else { # we have submitted a file or directory name $FORM = new CGI; @files = $FORM->param('submission'); foreach $file (@files) { # restore full path $file =~ s/^(.*)/$DOC_ROOT$1/; # avoid ../ and ; also don't show an .files like .htpasswd or such # fix this for .files if (($file =~ /\.\.|;/) || ($file !~ m#^$QUEUE_DIR[^\.]#o)) { # avoid stuff like ../../ &error("500 Internal Server Error", "Can't open file \'$file\'. No dot dots."); } if (-d $file) { # for a directory, just list the files in it &listFiles($file) && exit; } # branch based on the submit button text if ($FORM->param(submit) =~ /Get|Down|Save/) { # I'm guessing you just want to DOWNLOAD the file? # if ($FORM->param(tar)) { # ($FORM->param(gzip) && &tarIt(@files, gzip)) || &tarIt(@files); # } else { &downloadIt($file); # } } elsif ($FORM->param(submit) =~ /Mail/) { # I'm guessing you just want to MAIL the file? &mailIt($file); } elsif ($FORM->param(submit) =~ /View|Show/) { # I'm guessing you just want to SEE the file? &showIt($file); } } } #----------------------------------------------------------------------------# #- Read names from tmp ------------------------------------------------------# sub listFiles { my($query) = new CGI; my($queue_dir) = shift(@_); my($DIR)=$queue_dir; $DIR =~ s/^$DOC_ROOT(.*)/$1/; my($title) = "File listing for $HTTP_SERVER$DIR"; my($fileList); print $query->header; print $query->start_html(-title=>$title, -author=>$AUTHOR); print "

$title

\n
\n"; if(@fileList = &getFileList($queue_dir)) { print $query->startform; # I plan to change this to a multi select box print $query->popup_menu('submission', [@fileList]); print "
\n"; print "These check boxes don't work for mail yet!
\n"; print $query->checkbox(-name=>'tar',-label=>'Tar'); print $query->checkbox(-name=>'gzip',-label=>'Gzip'); print $query->checkbox(-name=>'zip',-label=>'Zip'); print $query->checkbox(-name=>'uuencode',-label=>'Uuencode'); print "
\n"; print $query->submit(-name=>'submit', -value=>'View It'); print "\n", $query->submit(-name=>'submit', -value=>'Get It!'); print "\n", $query->submit(-name=>'submit', -value=>'Mail It!'); print $query->textfield(-name=>'recipient', -default=>'Enter Email'); print "\n", $query->endform; } else { print "

No files in this directory

\n"; } print "\n", $query->end_html; } #----------------------------------------------------------------------------# #- Send the file ------------------------------------------------------------# sub showIt { # add options to read and print files that are out of the doc_root. # once multi select and tar options are added this may be a little clumsy # you will only be able to view one file at a time. # hrmm... good enough for now. my($file)=shift; $url = $HTTP_SERVER; $file =~ s/^$DOC_ROOT//; $url .= $file; print $FORM->redirect($url); } #----------------------------------------------------------------------------# #----------------------------------------------------------------------------# sub downloadIt { my($file) = shift; my($description) = shift; my($filename)=$file; $filename =~ s/^$DOC_ROOT(.*)/$1/; my($title) = "$HTTP_SERVER$filename"; # $title |= $file; $description |= $title; print "Content-type: multipart/x-mixed-replace;boundary=$BOUNDARY\n\n"; print "--$BOUNDARY\n"; # account for different MIME types? or print location? # print "Content-type: application/x-perl\n" if ($file =~ /\.pl$/); print $FORM->header(); print $FORM->start_html(-title=>$title, -author=>$AUTHOR); print "

Downloading $title

\n
\n"; print "Please choose 'Save-As' and select a location to save the file."; print "\n
\n"; print "$VERSION"; print "\n"; print "$BOUNDARY\n"; print "Content-type: application/x-download\n"; print "Content-Disposition: attachment; filename=$file"; if ($FORM->param('tar')) { print ".tar"; } if ($FORM->param('gzip')) { print ".gz"; } if ($FORM->param('zip')) { print ".zip"; } print "\n"; print "Content-Description: $description\n\n"; # this stuff isn't done yet. if ($FORM->param('tar')) { exec($TAR, " -cf", $FORM->param('gzip') ? 'z':'', "f - $file"); exit; # well, exec will exit for you anyway. } if ($FORM->param('gzip')) { exec($GZIP, "-c", $file); exit; # well, exec will exit for you anyway. } if ($FORM->param('zip')) { exec($ZIP, "-l -", $file); exit; # well, exec will exit for you anyway. } open(FILE, "$file") || &error("500 Internal Server Error", "Cannot open $file $!"); print ; close FILE; } #----------------------------------------------------------------------------# #- Read submissions in QUEUE_DIR --------------------------------------------# sub getFileList { my($dir) = shift @_; my(@fileList); # don't open a symlink!!! that could be bad. return "Nice try, but we don't allow symlinks here!" if (-l $dir); # read in files while ignoring symlinks opendir(DIR,"$dir") || return; foreach $_ (grep(! /^\.|~/, readdir(DIR))) { $dir =~ s/^$DOC_ROOT(.*)/$1/o; push(@fileList,"$dir/$_") unless (-l "$DOC_ROOT$dir/$_"); # push(@fileList,("$dir/" . $_)) unless (-l "$dir/$DOC_ROOT$_"); } close(DIR); return @fileList; } #----------------------------------------------------------------------------# #----------------------------------------------------------------------------# sub mailIt { # do we have an email address? if (! $FORM->param(recipient)) { print "Content-type: multipart/x-mixed-replace;boundary=$BOUNDARY\n\n"; print "--$BOUNDARY\n"; print $query->header; print $query->start_html(-title=>'Enter email address!', -author=>$AUTHOR); print $FORM->startform; print "Enter your Email address:"; print $FORM->textfield('recipient'), "\n"; print $FORM->hidden(-name=>'submission', -value=>$file), "\n"; print $FORM->submit(-name=>'submit', -value=>'Mail It!'), "\n"; print $FORM->endform, "\n"; print $FORM->end_html; return; } my($file)=shift; print "Content-type: multipart/x-mixed-replace;boundary=$BOUNDARY\n\n"; print "--$BOUNDARY\n"; print $FORM->header(); print $FORM->start_html(-title=>$title, -author=>$AUTHOR); print "

Mailing $file

\n
\n"; print "

$file

\n"; print "
\n"; print "$VERSION\n"; open(MAIL, "|$MAILPROG") || &error("500 Internal Server Error", "Can't open $MAILPROG $!"); print MAIL "MIME-Version: 1.0 ($VERSION)\n"; $recipient = $FORM->param(recipient); print MAIL "To: $recipient\n"; print MAIL "From: $AUTHOR\n"; print MAIL "Subject: $file\n"; print MAIL "Content-type: multipart/mixed;\n\tboundary=$BOUNDARY\n\n"; print MAIL "--$BOUNDARY\n"; print MAIL "Content-type: text/plain; charset=US-ASCII\n\n"; print MAIL "\nHere is the file you requested from\n"; print MAIL "$ENV{HTTP_REFERER}\n\n"; # just junk foreach (sort keys %ENV) { print MAIL "$_ = $ENV{$_}\n"; } print MAIL "--$BOUNDARY\n"; print MAIL "Content-type: text/plain; charset=US-ASCII\n\n"; # print MAIL "Content-Disposition: attachment; filename=dale-perl.tar.gz\n "; # print MAIL "Content-Description: Dale Bewley's perl archive\n\n"; # restore full path open(FILE, "$file") || &error("500 Internal Server Error", "Can't open $file $!"); print MAIL ; close MAIL, FILE; print $query->header; print $query->start_html(-title=>$title, -author=>$AUTHOR); } #----------------------------------------------------------------------------# #- Send error to browser and admin ------------------------------------------# sub error { # this could help you catch hack attempts my($status,$msg)=@_; print $FORM->header(-type=>'text/html' -status=>$status); print $FORM->start_html(-title=>$status, -author=>$AUTHOR); print "

$status

\n"; print $msg; print "
\n

Please direct questions to "; print "$AUTHOR."; print $FORM->end_html; open (MAIL, "|$MAILPROG") || die "Can't open $MAILPROG $! "; print MAIL "To: $WEBMASTER,$AUTHOR\n"; print MAIL "From: $VERSION - <", $FORM->param('email'), ">\n"; print MAIL "Subject: $VERSION - $status\n\n"; print MAIL "$msg\n\n"; my(@values,$key); foreach $key ($FORM->param) { print MAIL "$key -> "; @values = $FORM->param($key); print MAIL join(", ",@values),"\n"; } foreach (sort keys %ENV) { print MAIL "$_ = $ENV{$_}\n"; } close MAIL; exit; } #----------------------------------------------------------------------------# __END__