AlexanderZ has asked for the wisdom of the Perl Monks concerning the following question:

Hello All!
I canīt get my "top refferers" script to work, it simply
doesnt write to the file it should, it doesnt write at
all actually.. :(

Does anyone has any tip on what to change?

The script is pasted in below (it does exist of multiple
files, this is the part that doesnt work).

Would be really happy for any advice!! :)

AlexanderZ

This is the code I use:
#!/usr/bin/perl require 'settings.conf'; require 'exclude.conf'; require 'include.conf'; $data = ""; $template_file = "template.txt"; @html_file = @pages; print "Content-type: text/html\n\n"; print "Updating the HTML file(s)<br>;\n"; print "Please Hold\n"; $|=1; $time = time(); if ($uniqe eq '1') { open(SESAME,"$referer_log.backup") || die "Could not open Referer Log" +; @filecontents = <SESAME>; close(SESAME); @hash{@filecontents}=(); @filecontents=keys %hash; open(SESAME,">$referer_log.backup") || die "Could not open Referer Log +"; foreach $line(@filecontents){ print SESAME "$line";} close(SESAME); chmod (0666, "$referer_log.backup"); } open(LOG,"$referer_log.backup") || die "Could not open Referer Log"; while(<LOG>){ $ref = $_; foreach$skip(@skip_pages) { if($ref =~ /$skip/) { $bad =1; } } if(!$bad) { ($test,$testbogus) = split(/\|/,$ref); study($test); $test =~ s/:80//g; $test =~ s/%7E/~/g; $sitecount ="0"; foreach $line(@siteurl) { if($test =~ /$line/) { $test = "$sitedesc[$sitecount]"; $test .= "||$sitename[$sitecount]"; } $sitecount++; } $HASH{"$test"}++; $grandtotal++; } undef($bad); print ".\n"; } close(LOG); sub bynumber { $b <=> $a; } foreach$key(keys %HASH) { $line = "$HASH{$key}\::$key"; push(@array,$line); } undef(%HASH); @array = sort bynumber @array; $time = time() - $time; open(SESAME,"header.txt"); @filecontents = <SESAME>; close(SESAME); foreach $line(@filecontents) { $line =~ s/\"/\"/; $line =~ s/\#/\#/; $line =~ s/\?/\?/; $header .= "$line"; } open(SESAME,"footer.txt"); @filecontents = <SESAME>; close(SESAME); foreach $line(@filecontents) { $line =~ s/\"/\"/; $line =~ s/\#/\#/; $line =~ s/\?/\?/; $footer .= "$line"; } $antal ="0"; $rank ="1"; while ($antal < $top) { $part = @array[$antal]; ($total,$referer) = split(/::/,$part); if($total >= $minumum_referals) { if($referer !~ /^http:\/\//){ $data = "$rank"; $data .= "||$referer"; $data .= "||$total"; } else { $data = "$rank"; $data .= "||$referer"; $data .= "||$total"; } push(@Ref_Info,"$data"); } $antal++; $rank++; } if ($userunners eq "1"){ $tempup = "||$runnersurl||Runners Up||?"; push(@Ref_Info,"$tempup"); } &amp;preview; if ($userunners eq "1"){ $runnersrank = ($#Ref_Info + 1); open(FH,">$runnerspath"); print FH "<html><head><title>Runners Up</title></head>\n"; print FH "<body bgcolor=#000000 text=#ffffff>\n"; print FH "<p align=center><b>Runners Up</p>\n"; print FH "<p align=left>\n"; do {print FH "<li>$array[$runnersrank]\n"; $runnersrank++; } until ($runnersrank > $#array); print FH "</p></body></html>\n"; close(FH); } print "<br>File(s) updated<br>You may close this window now..\n"; exit; #__________________________________________________________________ sub preview { &amp;Get_Template; &amp;Get_New_Links; foreach $pages(@html_file){ open(SESAME,"$pages"); @Old_HTML = <SESAME>; close(SESAME); @New_HTML = (""); do { $temp = shift(@Old_HTML); push(@New_HTML,"$temp"); } until ($temp =~ /<!-START->/); push(@New_HTML,"$header"); push(@New_HTML,@NewLines); do { $temp = shift(@Old_HTML); } until ($temp =~ /<!-END->/); push(@New_HTML,"$footer"); push(@New_HTML,"$temp"); push(@New_HTML,@Old_HTML); chmod (0666,$pages); open(SESAME,">$pages"); print SESAME "@New_HTML"; close(SESAME); chmod (0644,$pages); } } #------------------------------ sub Get_HTML { open(SESAME,"$html_file"); @Old_HTML = <SESAME>; close(SESAME); } #-------------------------------- sub Get_New_Links { foreach $line(@Ref_Info){ @content = split(/\|\|/,"$line"); $rank = $content[0]; if ($content[3] eq ""){$content[3] = $content[2]; $content[2] = $conte +nt[1];} $referer = "<a href=\"$content[1]\" target=\"$target\">$content[2]</a> +"; $total = $content[3]; $temp = $template; $temp =~ s/<RANK>/$rank/g; $temp =~ s/<REFERER>/$referer/g; $temp =~ s/<TOTAL>/$total/g; $temp .= "\n"; push(@NewLines,"$temp"); } } #---------------------------------- sub Get_Template { open(SESAME,"$template_file"); @temptemplate = <SESAME>; close(SESAME); foreach $line(@temptemplate){ $template .= "$line"; } } #---------------------------------------

BazB: added code and readmore tags, hopefully removed all HTML and HTML encoding from code section.

Replies are listed 'Best First'.
Re: perl cgi-bin script
by davido (Cardinal) on Nov 15, 2003 at 05:23 UTC
    I don't see where $unique is declared and defined. I have to assume it's part of one of the required files, and appears to behave as a safeguard against multiple entities of the script trying to write to the same files at the same time (otherwise known as a race condition, usually leading to file corruption).

    However, if you're not declaring and defining $unique in the .conf files, you're outta luck; the outfile never gets opened. That's one place to check.

    If that turns out to not be the problem, you need to get a little more clever about your approach.

    What happens if you run the script from the command line? Does it then work ok? If so, it's possible that you've got an issue where your outfile's permissions are set such that the script, when run as "nobody" (common for web applications), doesn't have permission to write to or create the outfile. That's a common pitfall.

    Another thing to try is to put a print here and there throughout the script that will output to the browser (or to a logfile if you wish) a sort of progress report, letting you know, this section executed, that section executed, etc. By carefully placing the prints, you can determine whether or not files have opened, etc.

    And for heaven's sake, consider using strict, warnings, taint mode, and CGI.pm for future CGI scripts.


    Dave


    "If I had my life to live over again, I'd be a plumber." -- Albert Einstein
Re: perl cgi-bin script
by sgifford (Prior) on Nov 15, 2003 at 08:50 UTC

    The most obvious problem would be that the user the Web server is running as doesn't have permission to write to the file, or doesn't have permission to do something else that is causing the error.

    Do you see errors in your log file when you're running this? Have you put error checking everywhere a permission problem could break things (for example, the chmod)? Have you checked that the file permissions look right?

Re: perl cgi-bin script
by Roger (Parson) on Nov 15, 2003 at 00:56 UTC
    You had
    $part = @array[$antal];
    in your code, which is a "no no". The correct syntax should be
    $part = $array[$antal];
    I double checked your code, and confirmed with my observation. Your original code of @array[$antal] created a slice, and you were assigning a list into a scalar.

      While you are correct in that it is a stylistic error, I'm quite certain that piece of code does what is expected. It is in fact returning an array slice, but since the expression in the brackets is a scalar the array slice is only one element and it is simply treated as a scalar.
      C:\WINNT\Fonts>perl -e"@x=qw/foo bar qux/; $_=@x[1]; print" bar
Re: perl cgi-bin script
by Anonymous Monk on Nov 16, 2003 at 01:01 UTC
    require 'settings.conf'; require 'exclude.conf'; require 'include.conf';
    Are we supposed to imagine what these contain?

    You should also read CGI Help Guide