#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    5
    Rep Power
    0

    Question To run a perl script after a button is clicked on a GUI which is created using PERL C


    have created a GUI using Perl CGI on which some buttons are there like "OFF" and "ON". And I have created a .pl file. The pl file is working perfectly fine when I run it on CLI. But when I program the buttons of the cgi file to call the pl file. It is not even opening on the GUI.

    My approach is:
    1. A cgi file is there. On which OFF/ON buttons are there.
    2. A text file is there which has information of some certain parameters of a resource like: Name, IP, ON/OFF etc.
    3. A change.pl file is there which when called will change ON/OFF parameter of a particular resource.
    4. Now what I want is that when I call the ON/OFF button in front of a Resource named A, the change.pl file is called and then it will change the text.txt file by replacing ON to OFF or vice versa.

    What I am able to do: When I call the button it prints the name of the resource and the value to be changed and value which I want to be used by change.pl and change the value in .txt file.'
    But I not able to run the .pl file whenever a certain button is pressed. The page just hungs and no changes are made in the text file.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,940
    Rep Power
    1225
    The problem is on line 43.

    We can't troubleshoot code which we haven't see. You need to post both scripts.

    Did you check the error log to see if it gives any clues to your problem?
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    5
    Rep Power
    0

    Code


    One text file is present:
    system1,10.111.23.45,OFF,powered-off
    system2,10.111.23.46,ON,used
    system3,10.111.23.47,OFF,idle

    One CGI file is written which reads the above text file and prints on the GUI. If for system1 OFF is present in text file on GUI one button should be shown as "POWER ON" for this system and if ON is present one button is shown as "POWER OFF".

    Below is the cgi file:

    #!/usr/bin/perl
    use strict;
    #use CGI qw/:standard/;
    #use CGI qw( :html *p);
    use CGI qw(:cgi-lib :standard);
    &ReadParse(*input);
    use CGI qw( :html *p);
    use CGI::Pretty;
    print header,
    start_html('Utilization');
    my $cgi_obj = new CGI();
    my $power_on = $cgi_obj->param('power_on');
    my $power_off = $cgi_obj->param('power_off');
    if($power_off){
    Change::change_file("INFO", "$power_off", "POWER_STATUS", "OFF");
    }
    if($power_on){
    Change::change_file("INFO", "$power_on", "POWER_STATUS", "ON");
    }

    my $h = "<h3><font color=\"#0B0B61\"><center><b>System Management Page</b></center></font color> </h3>";

    $h .= "<table border=\"1\">\n<tr>\n";

    $h .= "<td WIDTH=50 bgcolor=\"#0101DF\"><font color=\"#FFFFFF\"><strong><center>Serial No.</center></strong></td>\n";
    $h .= "<td WIDTH=200 bgcolor=\"#0101DF\"><font color=\"#FFFFFF\"><strong><center>NAME</center></strong></td>\n";
    $h .= "<td WIDTH=200 bgcolor=\"#0101DF\"><font color=\"#FFFFFF\"><strong><center>IP</center></strong></td>\n";
    $h .= "<td WIDTH=200 bgcolor=\"#0101DF\"><font color=\"#FFFFFF\"><strong><center>State_ON_OFF</center></strong></td>\n";
    $h .= "<td WIDTH=200 bgcolor=\"#0101DF\"><font color=\"#FFFFFF\"><strong><center>Used state</center></strong></td>\n";
    $h .= "</tr>";
    open(my $FH,"INFO") or die ("$!");
    my $ref={};
    my $i = 1;
    while(<$FH>){
    my ($NAME,$IP,$POWER_OFF_ON,$USED_STATE)=split(/,/);
    $h .= "<tr>";
    $h .= "<td WIDTH=50 bgcolor=\"#BCF5A9\"><center>$i.</center></td>";
    $h .= "<td WIDTH=150 bgcolor=\"#BCF5A9\"><center>$NAME</center></td>";
    $h .= "<td WIDTH=150 bgcolor=\"#BCF5A9\"><center>$IP</center></td>";
    if ( $POWER_OFF_ON eq "OFF"){
    $h .= "<form name=\"ON\" method=\"get\" action=\"tool.cgi\"><br>";
    $h .= "<td WIDTH=250 bgcolor=\"#BCF5A9\"><center>$POWER_OFF_ON<br>";
    $h .= "<input type=\"hidden\" name=\"power_off\" value=\"$NAME\">";
    $h .= "<center><input type=\"submit\" value=\"SWITCH ON\"></center</td>";
    $h .= "</form>";
    }
    else {
    $h .= "<form name=\"OFF\" method=\"get\" action=\"tool.cgi\"><br>";
    $h .= "<td WIDTH=250 bgcolor=\"#BCF5A9\"><center>$POWER_OFF_ON<br>";
    $h .= "<input type=\"hidden\" name=\"power_off\" value=\"$NAME\">";
    $h .= "<center><input type=\"submit\" value=\"SWITCH OFF\"></center</td>";
    $h .= "</form>";
    }


    $h .= "<td WIDTH=150 bgcolor=\"#BCF5A9\"><center>$USED_STATE</center></td>";
    $h .= "</tr>";

    $i++;
    }

    print "$h";
    print $cgi_obj->end_html();

    exit;


    I want that if "POWER ON" button is pressed. It changes the INFO file and corresponding to that system it replaces OFF ny ON and the display the same cgi file with update data.
    Now as written in line 15 and line 18. one subroutine called change_file is called if "POWER ON" or "POWER OFF" buttons are pressed which changes the value as asked.

    Subroutine from the Change.pl



    my ($name, $selected_system, $value_to_change, $new_val) = @_;
    my $ref;
    my ($NAME,$IP,$POWER_OFF_ON,$USED_STATE);
    rename $name, "$name~"
    or die "Cannot rename: $!";
    open FH1, "<$name~"
    or die "Cannot open: $!";
    open FH2, ">$name"
    or die "Cannot create: $!";
    while (<FH1>) {

    ($NAME,$IP,$POWER_OFF_ON,$USED_STATE)=split(/;/);
    $ref->{$NAME}{FILER_IP}=$FILER_IP;
    $ref->{$NAME}{FILER_RLM_IP}=$FILER_RLM_IP;
    $ref->{$NAME}{POWER_OFF_ON}=$POWER_OFF_ON;
    $ref->{$NAME}{OWNER}=$OWNER;
    $ref->{$NAME}{DETAILS}=$DETAILS;
    $ref->{$NAME}{RESERVED_BY}=$RESERVED_BY;
    print "$NAME",";","$ref->{$NAME}{FILER_IP}",";","$ref->{$NAME}{FILER_RLM_IP}",";","$ref->{$NAME}{POWER_OFF_ON}",";","$ref->{$NAME}{OWNER}",";","$ref->{$FILER_NAME}{DETAILS}",";","$ref->{$FILER_NAME}{RESERVED_BY}";

    print "$NAME",";","$ref->{$NAME}{FILER_IP}",";","$ref->{$NAME}{FILER_RLM_IP}",";","$ref->{$NAME}{POWER_OFF_ON}",";","$ref->{$NAME}{OWNER}",";","$ref->{$FILER_NAME}{DETAILS}",";","$ref->{$FILER_NAME}{RESERVED_BY}";

    if (!($NAME eq "$selected_system")){
    print FH2 $_;
    }
    elsif ($value_to_change eq "POWER_STATUS"){
    print FH2 "$NAME",",","$ref->{$NAME}{IP}",",","$new_val",",","$ref->{$NAME}{USED_STATE}","\n";

    }
    }
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,940
    Rep Power
    1225
    Wow, it looks like we've time-warped back to 1990.

    There are so many problems with that code I don't know where to begin and won't spend the time going over all of them, but I will briefly touch on a some of them.

    Why do you have 2 use CGI qw(...); statements? You only need 1 CGI statement and it wouldn't be either of the ones you've used.

    Why are you using ReadParse()? That is meant to be used temporarily while porting 20 year old code. It should never be used in new scripts.

    Why are you intermixing the functional and OO interface styles of the CGI module? Use one or the other, but never both in the same script.

    You need to learn about the different quoting methods that are available so that you can avoid the sloppy and the unnecessary "leaning tower" escapes.

    You need to get rid of the depreciated html formatting tags and instead use css.

    Using a csv file is "ok", but a far better approach would be to store the data in a properly formatted config file and use one of the many config modules to parse and update the file instead of using that change_file() sub.

    The changing of the form input buttons could easily be accomplish by using a simple hash as a lookup table that is used to reverse the ON/OFF status.

    In summary, my suggestion is to throw away both of those scripts and start fresh.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,940
    Rep Power
    1225
    Here's the initial skeleton of the new script.

    I left out the portion that does the hash lookup and I can help you with that if you don't understand how.

    Your current script is creating a separate form for each host, which is clunky. Instead, it would be best to have a single form that passes back which host needs to by updated.

    Code:
    #!/usr/bin/perl
    
    use strict;
    use CGI;
    use Config::Tiny;
    use CGI::Pretty;
    use Data::Dumper;
    
    # this debugging module should be removed when the script goes into production
    # and all error reporting is being handled properly via html error page(s)
    use CGI::Carp qw(fatalsToBrowser);
    
    my $cgi = CGI->new;
    print $cgi->header, $cgi->start_html('Utilization');
    
    # this is a replacement for the &ReadParse(*input);
    my %params = $cgi->Vars;
    
    # this is a simple example of the hash lookup table definition
    # the key represents the current power state and the the value will be the new state.
    my %power = (
        ON  => 'OFF',
        OFF => 'ON',
    );
    
    # read-in the config data into a hash ref
    my $config = Config::Tiny->read( 'file.conf' );
    
    # for debugging purposes, lets dump it out to see its structure
    print $cgi->pre(Dumper $config);
    
    
    print $cgi->h3({-class => 'title'}, 'System Management Page'),
          $cgi->start_table({-border => 1}),
          $cgi->Tr(
                   $cgi->th(['Serial No.', 'NAME', 'IP', 'State_ON_OFF', 'Used state'])
                );
    
    my $i = 1;
    foreach my $host (sort keys %$config) {
        print $cgi->Tr(
            $cgi->td([$i++, $host, $config->{$host}{IP}, $config->{$host}{Power}, $config->{$host}{State}])
        );
    }
    print $cgi->end_table;
    
    print $cgi->end_html;
    Here's the format I used for the config file.
    [system1]
    IP = 10.111.23.45
    Power = OFF
    State = powered-off

    [system2]
    IP = 10.111.23.46
    Power = ON
    State = used

    [system3]
    IP = 10.111.23.47
    Power = OFF
    State = idle
    Config::Tiny - Read/Write .ini style files with as little code as possible
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    5
    Rep Power
    0

    Thanks to FishMonger


    Hi FishMonger,

    Thanks for your valuable time and efforts.
    I used the method suggested by you.
    I was able to use Config::Tiny and change the configuration file.

IMN logo majestic logo threadwatch logo seochat tools logo