PDA

View Full Version : Unable to update a file


nightshift
11-07-2002, 09:11 PM
Hi,
I'm a complete newbie to Perl and CGI. To help me out I downloaded a script that I inserted into a page.

a.) Counter for downloads:
The script has two parts, a ADMIN and actual counter part. I setup both of them to the T. The admin part works fine in the sence that I could administer and view everything.

Now I added the coded to the shtml file that does the download which it does but the script NEVER update the counter nor does it create the file.

What I've done is to check that the directory where the file should be created is CHMOD to 777. The administrator activated SSI for me. The perl directive in the download is the same as the one in the admin.

I would dearly like this script to work as I would like to track the file download.

Below follow the script:

#!/usr/bin/perl

############################################################
# Configuration - Edit below
############################################################

# Directory where data & download counts should be stored. You also
# need to chmod this directory to 777. This directory location would
# be best where users of your website cannot access it. Maybe
# password protect the directory or use a directory that is out
# of reach of the webserver.
$data_dir = "/usr/local/apache/htdocs/dlMonitor";

# URL Location of download files
$download_files = "http://www.nightshift.co.za/download";

# Server location of files to be downloaded
$download_loc = "/home/htdocs/download";


###############################################################
# No more editing below - Unless you know what's happening here
###############################################################

if ($ENV{'QUERY_STRING'} ne "") {
$temp = $ENV{'QUERY_STRING'};
}
else
{
read(STDIN, $temp, $ENV{'CONTENT_LENGTH'});
}


@pairs=split(/&/,$temp);

foreach $item(@pairs)
{
($key,$content)=split (/=/,$item,2);
$content=~tr/+/ /;
$content=~ s/%(..)/pack("c",hex($1))/ge;
$fields{$key}=$content;
}

$fields{'comment'}=~s/\cM//g;
$fields{'comment'}=~s/\n\n/<p>/g;
$fields{'comment'}=~s/\n/<br>/g;

$fields{'download'} =~ s/\;//g;
$fields{'download'} =~ s/^\s+//g;
$fields{'download'} =~ s/\s+$//g;

############################################################
############################################################
############################################################
############################################################

### ERROR CHECKING

$file_exists = (-e "$download_loc/$fields{'download'}");

if ($file_exists > 0)
##if ($file_exists < 1)
{
&file_not_exist;
exit;
}



### OPERATIONS
#print "Content-type: text/html\n\n";

$exists1 = (-e "$data_dir/index.idx");
if ($exists1 > 0)
{
open (DNL, "$data_dir/index.idx");
while (defined($line=<DNL>))
{
####### filename, Number of Downloads
($filename, $counter, $tmp) = split (/:-:/,$line, 3);

#print "$filename __ $counter __ $tmp <br>";

if ($filename eq "$fields{'download'}")
{
$counter++;
$towrite = $towrite . $filename . ":-:" . $counter . ":-:" . "\n";
$written = "true";
}
else
{
$towrite = $towrite . "$line"; #. "\n";
}

}
close (DNL);

if ($written ne "true")
{
open (DNL, ">> $data_dir/index.idx");
print DNL $fields{'download'} . ":-:" . "1" . ":-:" . "\n";
close (DNL);
}
else
{
open (DNL, "> $data_dir/index.idx");
print DNL $towrite;
close (DNL);
}
}
else
{
$counter = 1;

if ($written ne "true")
{
open (DNL, "> $data_dir/index.idx");
print DNL $fields{'download'} . ":-:" . "1" . ":-:" . "\n";
close (DNL);
}

}


##### RECORD INFO
$rfile = $fields{'download'};

$fields{'download'} =~ tr/./_/;
$fields{'download'} = $fields{'download'} . ".txt";

$ip_address = $ENV{'REMOTE_ADDR'};
$browser = $ENV{'HTTP_USER_AGENT'};

($sec,$min,$hour,$mday,$mon,$year,$wday,$ydat,$isdst) = localtime();
$mon++;
$year = 1900 + $year;
$today = $year . "-" . $mon . "-" . $mday . " " . $hour . ":" . $min . ":" . $sec;


open (DLD, ">> $data_dir/$fields{'download'}");
######### WEBURL HEAR OF NAME
print DLD $fields{'weburl'} . ":-:" . $fields{'where'} . ":-:" . $fields{'name'} . ":-:" .
#EMAIL MAILING LIST IP
$fields{'email'} . ":-:" . $fields{'ml'} . ":-:" . $ip_address . ":-:" . $browser . ":-:" .
#TODAY
$today . ":-:\n";
close (DLD);

print "Location: $download_files/$rfile\n\n";
exit;






sub file_not_exist
{

print "Content-type: text/html\n\n";

print <<End_of_nexist;

<html>

<head>
<title>File Not Found</title>
</head>

<body>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
<div align="center"><center>

<table border="0" cellspacing="0" cellpadding="0" width="400">
<tr>
<td bgcolor="#000000"><table border="0" cellspacing="1" width="100%" cellpadding="6">
<tr>
<td width="100%" bgcolor="#FFCC00" valign="top"><p align="center"><font face="Verdana"
size="2"><b>404 File Not Found</b></font></td>
</tr>
<tr>
<td width="100%" bgcolor="#FFFFFF" valign="top"><font face="Verdana" size="2"><b></b>
&nbsp;&nbsp;&nbsp; <br>
The file you requested could not be found. Please use the back button of your browser to
go back.<br>
&nbsp;&nbsp;&nbsp; <b></b></font></td>
</tr>
</table>
</td>
</tr>
</table>
</center></div>
</body>
</html>

End_of_nexist

}

Mouldy_Goat
11-07-2002, 11:10 PM
Hi nightshift,

I don't mean to be rude, but the download script you've got is a little rough around the edges. For instance, this bit:

$file_exists = (-e "$download_loc/$fields{'download'}");

if ($file_exists > 0)
##if ($file_exists < 1)
{
&file_not_exist;
exit;
}

Could be replaced with:

if (!-e "$download_loc/$fields{'download'}") { file_not_exist() && exit; }

Still, the code itself actually looks OK security-wise, but dodgy anyway (for instance he doesn't remove null-bytes from the parameters sent to it). To use it though, it seems as though you should be using a form with input boxes named 'download'. Or at least using a link like

http://www.mysite.com/cgi-bin/download.pl?download=monkey.jpg
instead of SSI.

For example, if you had a file named car.mpg and book.doc stored in your download directory, you could make a form like this:

<html>
<head>
<title>Wonderful download page thing</title>
</head>
<body>
<form action="/cgi-bin/download.pl" method="POST">
Please select a file to download:<BR>
<input type="radio" name="download" value="car.mpg">Car movie<BR>
<input type="radio" name="download" value="book.doc">Book<BR>
<input type="submit" name="submit" value="Download">
</form>
</body>
</html>

Just a suggestion, but I hope it clears things up a bit.

nightshift
11-08-2002, 07:24 AM
Checkout the URL mentioned in the code. Go to Software, Financial Calculator, Download. You will see it in action downloading there.

About the code. whatever you say goes as I'm only a VB/SQL expert and NOT Perl or CGI. I would dearly like to see the code working or maybe get a refference to another that I might try.

mercurus
11-09-2002, 05:29 PM
G'day

That script looks well... clunky and old to say the least.

There are much better and faster ways of doing some of that...

I haven't looked closely at it, but it appears to be something like a top 50 portal script ? That counts as users click through or download stuff ?
If so, then you're going to need to set it up with forms as Mouldy_Goat suggested

Hope that helps

Cheers
mercurus