We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

saving form results to a file - perl

morrie
morrie asked
on
Medium Priority
213 Views
Last Modified: 2013-12-25
This is the first in a series of perl scripts (survey1.cgi):

#! /usr/bin/perl

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

# This line generates a unique respondent ID #
$rid = $$ . "-" . $ENV{ 'REMOTE_ADDR' } . "-" . time();

print <<end;
<HTML><HEAD><TITLE>Survey Introduction</TITLE></HEAD>
<BODY background="whitebak.gif" bgcolor="#ffffff" text="#000080" link="#0064ff" vlink="#00a800" alink="#800000">

<FORM ACTION="demog.cgi" METHOD=POST>

<INPUT TYPE="hidden" NAME="respondent_id" VALUE="12345">

 [*HTML DELETED*]

<INPUT TYPE="submit" VALUE="START SURVEY">
</FORM>
</body>
</html>
end

This is the second script (demog.cgi):

#! /usr/bin/perl

$mailer = '/usr/lib/sendmail';

read(STDIN, $message, $ENV{'CONTENT_LENGTH'});

#code added
@pairs=split(/&/, $message);
foreach $pair (@pairs) {
($name,$value)=split(/=/,$pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("c",hex($1))/eg;
$FORM{$name} = $value;
}
$rid=$FORM{"respondent_id"};
#end

open(MAIL, "|$mailer -t") || die "Can't open $mailer!\n";
print MAIL "To: morrie\@fix.net\n";
print MAIL "From: Survey\n";
print MAIL "Subject: Survey Introduction\n\n";
print MAIL "$message\n";
close (MAIL);

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

print <<end;
<HTML><HEAD><TITLE>Demographics</TITLE></HEAD>
<BODY background="whitebak.gif" bgcolor="#ffffff"
text="#000080" link="#0064ff" vlink="#00a800" alink="#800000">

<FORM ACTION="fam_hx.cgi" METHOD=POST>

<INPUT TYPE="hidden" NAME="respondent_id" VALUE="$rid">

[*HTML DELETED*]

<INPUT TYPE="submit" VALUE="Go to the next section">
<INPUT TYPE="reset" VALUE="Reset/Re-enter data">
</FORM>
</body>
</html>
end

This is the third script (fam_hx.cgi):

#! /usr/bin/perl

$mailer = '/usr/lib/sendmail';

read(STDIN, $message, $ENV{'CONTENT_LENGTH'});

#code added
@pairs=split(/&/, $message);
foreach $pair (@pairs) {
($name,$value)=split(/=/,$pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("c",hex($1))/eg;
$FORM{$name} = $value;
}
$rid=$FORM{"respondent_id"};
#end

open(MAIL, "|$mailer -t") || die "Can't open $mailer!\n";
print MAIL "To: morrie\@fix.net\n";
print MAIL "From: Survey\n";
print MAIL "Subject: Demographics\n\n";
print MAIL "$message\n";
close (MAIL);

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

print <<end;
<HTML><HEAD><TITLE>Family History</TITLE></HEAD>
<BODY background="whitebak.gif" bgcolor="#ffffff"
text="#000080" link="#0064ff" vlink="#00a800" alink="#800000">

<FORM ACTION="dx1.cgi" METHOD=POST>

<INPUT TYPE="hidden" NAME="respondent_id" VALUE="$rid">

[*HTML DELETED*]

<INPUT TYPE="submit" VALUE="Go to the next section">
<INPUT TYPE="reset" VALUE="Reset/Re-enter data">
</FORM>
</body>
</html>
end

After much help from various experts these scripts work fine just as they are. Now, of course, I want to change them.

What I would like to do is eliminate the MAIL sequence and instead of mailing the survey results I want to create a file. I will create a sub-directory under cgi-bin called “survey_results” to put these files in.
Line 8 in the first script:
$rid = $$ . "-" . $ENV{ 'REMOTE_ADDR' } . "-" . time();
creates a respondent ID.
What I would like to do is create a file that is named this respondent ID number ($rid) and then append to that file each time an additional form in the series is submitted by the same respondent. I would then end up with one file for each respondent instead of  numerous separate emails that have to be converted to files anyway.

These scripts will actually become a part of a series of around 100 forms so it will be much easier to have this data in one file for each respondent.

I am not a programmer and have mostly cut and pasted these scripts together. I don’t know for sure if it is even possible to do what I’m asking here but it seems like it would be. I’m offering 250 points for this question because I would like the answer in a *very* simple format that might be a little extra work on your part. If you would take my scripts, that I have entered above, and copy and paste them into your answer, with your suggestions added, then I know I’ll have it exactly like you are suggesting.  

If it would help to check out the working pages go to:
http://www.fix.net/~morrie
and click on *survey*.
The first three forms are all that is configured as cgi scripts. The rest are still static html documents.

Thanks in advance for taking the time to help,
Morrie
Comment
Watch Question

Wayne LeisterSenior Integration Engineer

Commented:
Answer below.(I like to lock the question first)
Wayne LeisterSenior Integration Engineer

Commented:
In demog.cgi change "|$mailer -t"(in open) to ">survey_results/$rid" (this creates the file)
In fam_hx.cgi change "|$mailer -t" to
">>survey_results/$rid" (this appends to the file)
If you add on more surveys later change them like fam_hx.cgi so the new data gets appended to the file.

You can also delete the lines printing the to from and subject to  MAIL.  That will make the output to the files cleaner.
Also make sure you create the directory before running the new scripts.

Comment back if you have any questions.

Author

Commented:
Here are the changes made as you suggested:

New section of  demog.cgi:
open(MAIL, ">survey_results/$rid") || die "Can't open $mailer!\n";
print MAIL "$message\n";
close (MAIL);

New section of fam_hx.cgi:
open(MAIL, ">>survey_results/$rid") || die "Can't open $mailer!\n";
print MAIL "$message\n";
close (MAIL);

Don’t I also need to remove the MAIL references?

Then It would be??

New section of  demog.cgi:
open(">survey_results/$rid") || die "Can't open $mailer!\n";
print "$message\n";
close;

New section of fam_hx.cgi:
open(">>survey_results/$rid") || die "Can't open $mailer!\n";
print "$message\n";
close;

Please let me know the appropriate syntax.

Thanks, Morrie

Author

Commented:
> I’m offering 250 points for this question because I would like > the answer in a *very* simple format that might be a little > extra work on your part. If you would take my scripts, that I > have entered above, and copy and paste them into your answer, > with your suggestions added, then I know I’ll have it exactly > like you are suggesting.

This is quoted from my original question. Anyone who answeres this,  *please* post your answers in this format. I tried the above answer many differnt ways. I just don't have the expertise to figure out the details myself.
Commented:
Second script:

#! /usr/bin/perl

#remove the next line
#                  $mailer = '/usr/lib/sendmail';

                  read(STDIN, $message, $ENV{'CONTENT_LENGTH'});

                  #code added
                  @pairs=split(/&/, $message);
                  foreach $pair (@pairs) {
                  ($name,$value)=split(/=/,$pair);
                  $value =~ tr/+/ /;
                  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("c",hex($1))/eg;
                  $FORM{$name} = $value;
                  }
                  $rid=$FORM{"respondent_id"};
                  #end

                  open(LOGFILE, ">survey_results/$rid") || die "Can't open logfile!\n";
                  print LOGFILE "$message\n";
                  close (LOGFILE);

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

                  print <<end;


The 3rd:



                  #! /usr/bin/perl

#                  $mailer = '/usr/lib/sendmail';

                  read(STDIN, $message, $ENV{'CONTENT_LENGTH'});

                  #code added
                  @pairs=split(/&/, $message);
                  foreach $pair (@pairs) {
                  ($name,$value)=split(/=/,$pair);
                  $value =~ tr/+/ /;
                  $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("c",hex($1))/eg;
                  $FORM{$name} = $value;
                  }
                  $rid=$FORM{"respondent_id"};
                  #end

                  open(LOGFILE, ">survey_results/$rid") || die "Can't open logfile!\n";
                  print LOGFILE "$message\n";
                  close (LOGFILE);

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

                  print <<end;

I changed MAIL to LOGFILE, this is only for clarity and not a requirement.  Besides, make sure you have create the directory.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Commented:
Another point to remember is that the web server process must have the rights to open a file in the directory, you need to check this with your system administator (the script itself can do nothing to this)
Wayne LeisterSenior Integration Engineer

Commented:
You can get around the rights to open a file by setting the directory world writeable.(ask your administrator for help)
I would try it without first, alot of ISP's run scripts as your user; which would have access to write files.  Its less of a security risk that way.

Sorry I didn't get back to you, Experts Exchange messed up and I couldn't get in.

Author

Commented:
I was out of town for a few days so I just got a chance to check this out. Thanks for your answer. I think I'm beginning to understand this stuff.

In my second script above, in the change you suggested:
open(LOGFILE, ">survey_results/$rid") || die "Can't open logfile!\n";

In my third script above, in the change you suggested:
open(LOGFILE, ">survey_results/$rid") || die "Can't open logfile!\n";

The data from both scripts will have the same respondent ID. If I want the results from the third script to append to the results from the second, not overwrite it, shouldn't the line from the third one read:
open(LOGFILE, ">>survey_results/$rid") || die "Can't open logfile!\n";
with >> instead of >

????

Author

Commented:
No need to respond to my last comment. I tried it with the >> and it works. Thank you very much for the help.
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.