QUOTE(blitzfx @ 14 Oct, 2009 - 10:43 AM)

QUOTE
1) You should be calling your subs with "print_HTTP_header()" rather than "&print_HTTP_header". Using an & prefix on sub calls is a holdover from Perl 4 and, in addition to no longer being necessary in Perl 5, it has side effects which are generally not what you intended.
Oh dear. I've been using & to call sub routines because all the examples my
lecturer are showing us have an &. Someone's being lazy and not updating his examples it seems...
It's not that uncommon, unfortunately. Perl has been around for 22 years and had a
lot of online tutorials published in the mid-90s when CGI and Perl were the backbone of dynamic web content. Most of those examples were sloppy and poorly-engineered at the time and they tend to rely on structures which are obsolete today, but they still run, so the examples continue circulating and promoting obsolete, sloppy, and even grievously insecure practices.
One of the things I like about Perl is its tradition of maintaining backwards compatibility, but this is one area in which the lack of any real deprecation policy has probably harmed the language.
QUOTE(blitzfx @ 14 Oct, 2009 - 10:43 AM)

I used strict; and it threw, mostly, errors saying Global symbol "[something]" requires explicit package name. So I chucked 'my' infront of every single variable, not knowing what it does....and still dont.
In this immediate case, using strict and declaring your variables properly (with "my", "our", or "use vars" - but "my" is the one you want 99% of the time, so just use that until you hit a case where it won't work for you) protects you from accidentally creating a new variable because of a typo when you meant to access an existing one.
In the broader picture, "my" creates lexically-scoped variables, which is (more or less) just a fancy way of saying variables that stop existing at the end of the block they were defined in:
CODE
use strict;
use warnings;
sub foo {
my $x = 1;
print "$x\n"; # prints 1
if ($x) {
my $x = 2; # we're in a different block, so this is a different $x
print "$x\n"; # prints 2
}
print "$x\n"; # prints 1 because we're back in the first block, with the first $x
}
print "$x\n"; # $x no longer exists, so strict throws an error and dies
Like glob-style filehandles, global variables can cause problems that are extremely difficult to debug because changing $x in one part of the program (if it's global) will also change $x in any other parts of the program that use $x, even if they're completely unrelated. Using "my" to create lexical variables protects you against this and using strict ensures that you won't accidentally use globals if you don't really need to.
QUOTE(blitzfx @ 14 Oct, 2009 - 10:43 AM)

CODE
sub errorFunction
{
print header(),
start_html(ERROR),
"ERROR - file could not be opened <br/ > ",
a({-href => "http://....../index.html"}, "Click here to go to main site"),
end_html();
}
and it's throwing an error saying "Bareword "ERROR" not allowed while "strict subs in use". I don't know how to fix this so i've disabled strict in the mean time.
You forgot the quotes around "ERROR".

You might also want to assign the string passed in to a variable and include a description of what went wrong on the error page:
CODE
sub errorFunction
{
my $error = shift;
print header(),
start_html('ERROR'),
"ERROR - file could not be opened:<br/ >$error",
a({-href => "http://....../index.html"}, "Click here to go to main site"),
end_html();
}
QUOTE(blitzfx @ 14 Oct, 2009 - 10:43 AM)

one more thing:
CODE
├─Folder1
│ └─main.html
└─cgi-bin
└─file.cgi
How do I specify the location of file.cgi from main.html ?
The same way you'd specify it in your browser's address bar. With that type of setup, it would most often be /cgi-bin/file.cgi, but I personally never segregate my code into a separate cgi-bin directory, so it's not something I normally need to deal with.
QUOTE(blitzfx @ 14 Oct, 2009 - 10:43 AM)

Thanks for the advice. I also found out the file writing issue was due to some strange permission thing due to the university server using apache and the scripts being called under a user called 'apache'.
That's a pretty common practice for limiting the amount of damage that can be done if an attacker is able to compromise the web server process or any subprocesses it might start up (like, say, CGI scripts). Creating the output file (using "touch filename") and then setting it to be world-writable ("chmod a+w filename") should allow the apache user to write to it.