0
votes

I need to use form data in another cgi script where another form also exists.Basically I need to create a filename from previous form data and need to rename the file which is uploaded in another form.

#!/usr/bin/perl
use CGI qw(:standard);
use CGI::Carp qw( fatalsToBrowser );
use File::Basename;

use Exporter qw(import);
our @EXPORT = qw(copyToTarget);
$newfilename='';
sub xyz()
{
        local ($buffer, @pairs, $pair, $name, $value, %FORM);
        $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;

        if ($ENV{'REQUEST_METHOD'} eq "POST")
        {
                read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
        }
        else
        {
                $buffer = $ENV{'QUERY_STRING'};
        }

        @pairs = split(/&/, $buffer);

        foreach $pair (@pairs)
        {
                ($name, $value) = split(/=/, $pair);
                $value =~ tr/+/ /;
                $value =~ s/%(..)/pack("C", hex($1))/eg;
                $FORM{$name} = $value;
        }

        $Circle = $FORM{Circle};
        $Techno  = $FORM{Techno};
        $newfilename = $Circle.'_'.$Techno.'.csv';
        #print ("Content-type: text/html\n\n");
        #print "$newfilename";
}

sub print_page()
{
                xyz();
        print ("Content-type: text/html\n\n");
        print <<__HTML__;
        <form style="margin:20px 0" action="Maintenance_Framework.cgi" method="post" enctype="multipart/form-data">
        <p>
        <h3 align='center'> Maintenance File Upload </h3>
        <p>File to Upload: <input type="file" name="filecsv" /></p>
        <p><input type="submit" name="Submit" value="Upload" >&nbsp&nbsp&nbsp
        <input type="button"  value="Cancel" onClick="javascript:window.close();">
        </body>
        </html>
        </form>
__HTML__

}



sub main()
{
        $CGI::POST_MAX = 1024 * 5000;
        my $safe_filename_characters = "a-zA-Z0-9_.-";
        my $upload_dir = "/opt/IBM/Maintenance/tmp";
        my $query = new CGI;

        print_page();


        my $filename = $query->param("filecsv");
        #my $ctext = $query->param("Circle");
        if ( !$filename )
        {
                exit;
        }

        my ( $name, $path, $extension ) = fileparse ( $filename, '.csv' );
        $filename = $name . $extension;
        $filename =~ tr/ /_/;
        $filename =~ s/[^$safe_filename_characters]//g;

        if ( $filename =~ /^([$safe_filename_characters]+)$/ )
        {
                $filename = $1;
        }
        else
        {
                die "Filename contains invalid characters";
        }

        my $upload_filehandle = $query->upload("filecsv");

        open ( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!";
                binmode UPLOADFILE;

        while ( <$upload_filehandle> )
        {
                print UPLOADFILE;
        }

        close UPLOADFILE;
        `mv /opt/IBM/Maintenance/tmp/*.csv /opt/IBM/Maintenance/tmp/$newfilename.csv`;
print <<END_HTML;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thanks!</title>
<style type="text/css">
img {border: none;}
</style>
</head>
<body>
<p>Thanks for uploading your file!</p>
</body>
</html>
END_HTML

}
#xyz();
main();

For Eg : If Circle contains Gabon and Techno contains RAN and user upload a file xyz.csv ,it should be rename to Gabon_RAN.csv

1

1 Answers

0
votes

You forgot to declare the circle and techno form elements in the HTML. Also it's pointless and dangerous to parse the form data yourself when you already have the CGI module which does it for you.

Be careful about a potential data loss: have you thought about what should happen when the same name is generated again from the input? As the code is now, the old file with the same name just gets overwritten.

#!/usr/bin/env perl
use strict;
use warnings;
use CGI qw();
use HTTP::Status qw(HTTP_UNPROCESSABLE_ENTITY HTTP_METHOD_NOT_ALLOWED HTTP_INTERNAL_SERVER_ERROR);
use File::Copy qw(copy);

$CGI::POST_MAX = 1024 * 5000;
my $cgi = CGI->new;
if ('GET' eq $cgi->request_method) {
    STDOUT->print($cgi->header('text/html'));
    STDOUT->print(<<~'');
    <!DOCTYPE html>
    <html>
        <body>
            <form method="post" enctype="multipart/form-data">
            <h3>Maintenance File Upload</h3>
            <p><label for="circle">Circle</label>:
            <input type="text" name="circle" id="circle" /></p>
            <p><label for="techno">Techno</label>:
            <input type="text" name="techno" id="techno" /></p>
            <p><label for="filecsv">File to Upload</label>:
            <input type="file" name="filecsv" id="filecsv" /></p>
            <p><input type="submit" name="Submit" value="Upload" />
            <input type="button" value="Cancel" onClick="javascript:window.close();"></p>
            </form>
        </body>
    </html>

} elsif ('POST' eq $cgi->request_method) {
    my %names = (
        circle => scalar $cgi->param('circle'),
        techno => scalar $cgi->param('techno'),
    );
    for my $key (keys %names) {
        my $val = $names{$key};
        if (not length $val or $val =~ /[^a-zA-Z0-9_.-]/) {
            STDOUT->print($cgi->header(-status => HTTP_UNPROCESSABLE_ENTITY));
            STDOUT->print("parameter '$key' validation error: must be any of a-zA-Z0-9_.-");
            exit;
        }
    }
    my $upload = $cgi->upload('filecsv');
    unless ($upload) {
        STDOUT->print($cgi->header(-status => HTTP_UNPROCESSABLE_ENTITY));
        STDOUT->print("upload error: no data for field 'filecsv'");
        exit;
    }
    my $temporary_name = $cgi->tmpFileName($upload);
    my $new_name = sprintf '/opt/IBM/Maintenance/tmp/%s_%s.csv', $names{circle}, $names{techno};
    my $result = copy $temporary_name, $new_name;
    my $error = $!;
    unless ($result) {
        STDOUT->print($cgi->header(-status => HTTP_INTERNAL_SERVER_ERROR));
        STDOUT->print("copy error: from '$temporary_name', to '$new_name', error '$error'");
        exit;
    }
    STDOUT->print($cgi->header);
    STDOUT->print("Thanks for uploading your file!");
} else {
    STDOUT->print($cgi->header(-status => HTTP_METHOD_NOT_ALLOWED));
}