Quoth
(Mark Constant):
> I have pre-made code that deletes a line from a flat file database. I
> am trying to pass an argument through a link to give the name of the
> line to delete.
>
> Here is my database.txt
> image020.jpg | 6/4/2004 | 10:19:59 | | rena
>
> Here is how I use the link
> delete.cgi?filedelete=$filename
>
> Now here is what prints out
> image020.jpg
> File image020.jpg not found!
>
> It is obvious that it is grabbing the argument because it prints out
> image020.jpg. The thing I don't understand is why it is not matching
> with the image020.jpg in the database.txt.
>
> Here is my code
> #!c:/perl/bin/perl
>
> use strict;
> use warnings;
> use CGI;
> use CGI::Carp qw(fatalsToBrowser);
> my $q = new CGI;
> print $q->header, $q->start_html('Delete File');
>
> my $action = new CGI;
> my @temp=split(/=/,$ENV{'QUERY_STRING'});
DON'T EVER DO THIS AGAIN. Use CGI.
> my $filedelete = $temp[1];
my $filedelete = $action->param('filedelete');
> my $file = 'C:/Program Files/Apache
> Group/Apache2/htdocs/quickbooks/database.txt';
> my $found = undef;
my $found;
> my (@ary);
my @ary;
> my $line;
>
> open( OLD, $file ) or die "Couldn't open old file $file: $! \n";
Don't put "\n" on the end of die messages.
Use lexical filehandles.
Specify the mode to open the file in, for safety.
open my $OLD, '<', $file
or die "can't open $file: $!";
> print $temp[1];
> foreach $line (@ary) {
for my $line (@ary) {
Create variables in the smallest possible scope.
> chomp($line);
> (my $filename, my $filedate, my $filetime, my $notes, my $user) =
my ($filename, $filedate, $filetime, $notes, $user) =
But anyway, why do you need more than
my ($filename) =
?
> split(/\|/,$line);
You are splitting on /\|/. This will leave whitespace all round your
filename. Try
.... = split /\s* \| \s*/x, $line;
> push( @ary, $line ) unless ( $filedelete eq $filename );
> $found = 1 if ( $filedelete eq $filename );
None of those parens are necessary.
> }
>
> close OLD or die "Couldn't close old file $file: $! \n";
>
> unless ($found) {
> print $action->h2("File $filedelete not found!");
> exit;
No. This will not correctly end the HTML.
> }
>
> open( NEW, ">$file" ) or die "Couldn't open new file $file: $!\n";
> foreach (@ary) {
> print NEW $_, "\n"
> }
>
> close NEW or "Couldn't close new file $file: $! \n";;
>
> exit;
Nor will this.
if ($found) {
open my $NEW, '>', $file or die "couldn't create $file: $!";
print $NEW "$_\n" for @ary;
}
else {
print $action->h2("File $filedelete not found!");
}
> print $q->end_html;
You *must* use locking in a situation like this, or you will end up with
a corrupted database. Something like:
use Fcntl qw/:flock/;
{
open my $OLD, '<', ...;
flock $OLD, LOCK_SH or die "can't acquire read lock: $!";
# read stuff
}
# $OLD closes here, lock is released
if ($found) {
open my $NEW, '>', ...;
flock $NEW, LOCK_EX or die "can't acquire write lock: $!";
# write stuff
}
# ditto for $NEW
Alternatively, you could open the file '+<' and then lock it LOCK_EX,
and truncate it rather than closing/reopening.
Ben
--
It will be seen that the Erwhonians are a meek and long-suffering people,
easily led by the nose, and quick to offer up common sense at the shrine of
logic, when a philosopher convinces them that their institutions are not based
on the strictest morality. [Samuel Butler, paraphrased]