School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 307,103 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 2,028 people online right now. Registration is fast and FREE... Join Now!




perl & cgi - cannot write to a file

 

perl & cgi - cannot write to a file

blitzfx

12 Oct, 2009 - 05:44 AM
Post #1

New D.I.C Head
*

Joined: 16 Aug, 2009
Posts: 10

Hi guys,

I've got a cgi script written in perl and I'm attempting to write data to a file but it isn't working

CODE
#!/usr/bin/perl -w

&print_HTTP_header;
&print_head;
&print_body;
&print_tail;

sub print_HTTP_header
{
    print "Content-type: text/html\n\n";
}

#  ---- print HTML stuff at head
sub print_head
{
    print <<END;
    <HTML><HEAD>
    <TITLE>test script</TITLE>
    <BODY bgcolor="#ffffff" text="#000000">
    <H4>test script</H4>
END
}

sub print_body
{
    use IO::File;
    use Fcntl ":flock";
    
    open (MYFILE, ">>../data.txt");
    flock MYFILE, LOCK_SH;
    print MYFILE "Matthias\nLucius\nKadmiel\nAradiel\nEzekiel\nOctavius\n";
    close (MYFILE);

    open (INPUT, "<../data.txt");
    $variable = <INPUT>;
    while(<INPUT>)
    {
        print $_;
    }
}

sub print_tail
{
    print "<BR><BR>";
    print "</BODY></HTML>";
}



Basically I've got this script on my university server running unix, under my account. I've verified the perl address is correct as well.
It's located under the cgi-bin folder and all I need to do is just call http://WWW.....cgi-bin/test/write.cgi (is the name of the file) and it should keep appending the names into a file and then display the result.
I've uploaded an empty data.txt file one level up from the test folder (ie. placed into cgi-bin).
So now when I run the script, absolutely nothing happens to the file and all i get is "test script" printed out (in H4).
I've set every single file permission to 777 (highest possible for every user) and it still doesn't work.

I went and uploaded the same files to my own server and it works fine so now I have no idea what's going on.
Not sure if my script has been written correctly or not, so some help would be most appreciated.

User is offlineProfile CardPM
+Quote Post


winracer

RE: Perl & Cgi - Cannot Write To A File

12 Oct, 2009 - 06:47 PM
Post #2

D.I.C Head
**

Joined: 2 Mar, 2009
Posts: 103


My Contributions
QUOTE(blitzfx @ 12 Oct, 2009 - 05:44 AM) *

Hi guys,

I've got a cgi script written in perl and I'm attempting to write data to a file but it isn't working

CODE
#!/usr/bin/perl -w

&print_HTTP_header;
&print_head;
&print_body;
&print_tail;

sub print_HTTP_header
{
    print "Content-type: text/html\n\n";
}

#  ---- print HTML stuff at head
sub print_head
{
    print <<END;
    <HTML><HEAD>
    <TITLE>test script</TITLE>
    <BODY bgcolor="#ffffff" text="#000000">
    <H4>test script</H4>
END
}

sub print_body
{
    use IO::File;
    use Fcntl ":flock";
    
    open (MYFILE, ">>../data.txt");
    flock MYFILE, LOCK_SH;
    print MYFILE "Matthias\nLucius\nKadmiel\nAradiel\nEzekiel\nOctavius\n";
    close (MYFILE);

    open (INPUT, "<../data.txt");
    $variable = <INPUT>;
    while(<INPUT>)
    {
        print $_;
    }
}

sub print_tail
{
    print "<BR><BR>";
    print "</BODY></HTML>";
}



Basically I've got this script on my university server running unix, under my account. I've verified the perl address is correct as well.
It's located under the cgi-bin folder and all I need to do is just call http://WWW.....cgi-bin/test/write.cgi (is the name of the file) and it should keep appending the names into a file and then display the result.
I've uploaded an empty data.txt file one level up from the test folder (ie. placed into cgi-bin).
So now when I run the script, absolutely nothing happens to the file and all i get is "test script" printed out (in H4).
I've set every single file permission to 777 (highest possible for every user) and it still doesn't work.

I went and uploaded the same files to my own server and it works fine so now I have no idea what's going on.
Not sure if my script has been written correctly or not, so some help would be most appreciated.



have you tried to use the absoloute path to the file like

CODE


open (MYFILE, ">>/xxxxxxx/cgi-bin/test/data.txt");


This post has been edited by winracer: 12 Oct, 2009 - 06:48 PM
User is offlineProfile CardPM
+Quote Post

blitzfx

RE: Perl & Cgi - Cannot Write To A File

12 Oct, 2009 - 09:38 PM
Post #3

New D.I.C Head
*

Joined: 16 Aug, 2009
Posts: 10

just tried it and it doesn't work sad.gif
User is offlineProfile CardPM
+Quote Post

dsherohman

RE: Perl & Cgi - Cannot Write To A File

13 Oct, 2009 - 02:58 AM
Post #4

D.I.C Head
**

Joined: 29 Mar, 2009
Posts: 204



Thanked: 36 times
My Contributions
QUOTE(blitzfx @ 12 Oct, 2009 - 01:44 PM) *

CODE
#!/usr/bin/perl -w

&print_HTTP_header;
&print_head;
&print_body;
&print_tail;

Two side notes here:

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.

2) Good on you for using "-w" to enable warnings, but you should also include "use strict" at the beginning of your code. Stylistically, "use warnings" is generally preferred over "-w", but, in practice, they're generally equivalent, although "use warnings" does give you finer control over what warnings are emitted and where.

QUOTE(blitzfx @ 12 Oct, 2009 - 01:44 PM) *

CODE

    open (MYFILE, ">>../data.txt");
...
    open (INPUT, "<../data.txt");

This is where you need to start looking for the cause of your problem. One or both of your opens is (presumably) failing, but you don't know which one because you're not checking to see whether they succeed and you don't know why because you're not reporting the error messages when they fail.

Also, although it's not particularly significant when you're using a static filename with no user-entered data, you should get into the habit of using the three-argument form of "open":
CODE

open(my $my_file, '>>', '../data.txt')
  or die "Unable to open file for output: $!\n";
...
open(my $input, '<', '../data.txt')
  or die "Unable to open file for input: $!\n";

The error messages from "die" will be written to the web server's error log by default. That's also where any warnings emitted by your code will be sent, so watching the error log when developing/testing web-based code is extremely valuable. If you don't have (and can't get) read-only access to the error log, you can add "use CGI::Carp qw(fatalsToBrowser);" to your code and the messages from "die" will be sent to your browser. (If this were a real application, it would be important to remove that line before going into production, so that you wouldn't end up telling attackers how to break your code.)

Note that I also used lexical filehandles ($my_file) rather than glob filehandles (MYFILE). Like "use warnings" vs. "-w", either way works as well, but the lexical filehandle is more flexible. Perhaps more importantly, by being non-global, it saves you from having to worry that you might one day start getting strange errors if you use a module which also uses a filehandle called "MYFILE" or "INPUT".
User is offlineProfile CardPM
+Quote Post

blitzfx

RE: Perl & Cgi - Cannot Write To A File

14 Oct, 2009 - 02:43 AM
Post #5

New D.I.C Head
*

Joined: 16 Aug, 2009
Posts: 10

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...
I overlooked him using capitals when using <HTML> tags instead of lowercase but if there are other things in this course that aren't right...

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.

Changed how the file is opened.
CODE
open(my $my_file, '>>', '../data.txt') or errorFunction();

where errorFunction is
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.

one more thing:
CODE

├─Folder1
│  └─main.html
└─cgi-bin
    └─file.cgi

How do I specify the location of file.cgi from main.html ?

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'.

This post has been edited by blitzfx: 14 Oct, 2009 - 02:44 AM
User is offlineProfile CardPM
+Quote Post

dsherohman

RE: Perl & Cgi - Cannot Write To A File

14 Oct, 2009 - 05:38 AM
Post #6

D.I.C Head
**

Joined: 29 Mar, 2009
Posts: 204



Thanked: 36 times
My Contributions
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". smile.gif 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.
User is offlineProfile CardPM
+Quote Post

programble

RE: Perl & Cgi - Cannot Write To A File

14 Oct, 2009 - 11:35 AM
Post #7

D.I.C Regular
Group Icon

Joined: 21 Feb, 2009
Posts: 423



Thanked: 10 times
Dream Kudos: 50
My Contributions
Has no one suggested that the file is not writable?

chmod 666 filename
User is offlineProfile CardPM
+Quote Post

blitzfx

RE: Perl & Cgi - Cannot Write To A File

15 Oct, 2009 - 12:58 AM
Post #8

New D.I.C Head
*

Joined: 16 Aug, 2009
Posts: 10

QUOTE
Has no one suggested that the file is not writable?

chmod 666 filename

I had already set the file to chmod 777, and I have already fixed the problem but thanks.

QUOTE
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.

I appreciate the explanation(s) a lot. I found it was almost like java encapsulation where "my $var" is just like "this.var" or setting variables to "private" ensuring nothing else outside it's scope can write to it.

cheers!
User is offlineProfile CardPM
+Quote Post

dsherohman

RE: Perl & Cgi - Cannot Write To A File

15 Oct, 2009 - 01:34 AM
Post #9

D.I.C Head
**

Joined: 29 Mar, 2009
Posts: 204



Thanked: 36 times
My Contributions
QUOTE(blitzfx @ 15 Oct, 2009 - 08:58 AM) *

I appreciate the explanation(s) a lot. I found it was almost like java encapsulation where "my $var" is just like "this.var" or setting variables to "private" ensuring nothing else outside it's scope can write to it.

No problem - that's what I come here for. smile.gif

And it's good to hear that you've got your problems sorted out. Welcome to Perl; I hope you like it enough to stay. Happy hacking!
User is offlineProfile CardPM
+Quote Post

chorny_cpan

RE: Perl & Cgi - Cannot Write To A File

17 Oct, 2009 - 03:46 PM
Post #10

New D.I.C Head
Group Icon

Joined: 13 May, 2009
Posts: 36


Dream Kudos: 25
My Contributions
A good tutorial to read is Ovid's CGI Course.
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic

Time is now: 11/21/09 12:32PM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month