in reply to Re: IO::Socket and passed variables to functions
in thread IO::Socket and passed variables to functions

When I say weird, I mean I tried to print the variable .i.e.
The value passed to the $grp was CIC
print "START~" . $grp . "~END\n";
which should have produced an output of START~CIC~END but it did not...it printed something like ENDsCIC
As I stated earlier the block of code being used to query the database works if I just put it in a simple script and pass the value into say $grp = $ARGV[0];
The only real difference I see between what I am doing in the LISTENER and the straight perl script is assigning initial groups array to begin

push(@groups, $buf) versus @groups = $ARGV[0];


Here is the rest of the code from the SOCK_DBI.pl<br/><br/> # +--------------+ # | SUB ROUTINES | # +--------------+ # SOCK_DBI.p # sub declareGlobalVariables { $ORACLE_SID = "D0TALRT1"; $ORACLE_USERID = "dunnyuser"; $ORACLE_PASSWORD = "applesauce"; $ENV{'ORACLE_SID'} = "$ORACLE_SID"; $ENV{'ORACLE_HOME'} = "/opt/app/talertdb/oracle/9.2.0"; } sub getOracleLogin { local ($oracle_sid, $username, $password) = @_; local ($temp_dbh); local($tempID, $tempPassword, $tempKey); local $conn = "dbi:Oracle:HOST=windsordb.wdc.gdc.net;SID=D0TALRT1;po +rt=1521"; # unless ( $temp_dbh = DBI->connect( "DBI:Oracle:$oracle_sid" unless ( $temp_dbh = DBI->connect( $conn , "$username" , $password , {AutoCommit => 0}) ) { &programError( "Oracle Login Failed as $username" , "" , "$DBI::errstr" , "dba-mail" , "dba-pager"); exit; } } sub programError { $logfile = "/opt/app/telalert/tmp/dbi_error"; open(ELOG, ">>$logfile") || die "Can't open filename: $logfile - $!\ +n"; local($message, $sql_statement, $ora_errstr) = @_; print ELOG "+--------------------------+\n"; print ELOG "| SUB: programError |\n"; print ELOG "+--------------------------+\n"; print ELOG "\n"; unless($message) {$message = "No message provided from calling modul +e.";} print ELOG "+------------------------------------------------------- ++\n"; print ELOG "| ******************* PROGRAM ERROR ******************* +|\n"; print ELOG "+------------------------------------------------------- ++\n"; print ELOG "\n"; print ELOG "\n"; print ELOG "Message:\n"; print ELOG "-------------------------------------------------------- +\n"; print ELOG "$message\n"; print ELOG "\n"; if ($sql_statement) { print ELOG "SQL:\n"; print ELOG "------------------------------------------------------ +--\n"; print ELOG "$sql_statement\n"; print ELOG "\n"; } if ($ora_errstr) { print ELOG "Oracle Error:\n"; print ELOG "------------------------------------------------------ +--\n"; print ELOG "$ora_errstr\n"; } close(ELOG); } sub logoffOracle { ($dbh) = @_; unless ($dbh->disconnect) { 1; } } sub getGrpMembers { my ($groupName) = @_; my @members = (); $sql_statement = "SELECT b.DISPLAY_NAME, b.MEMBER_TYPE FROM GR +OUPS a, MEMBERS b WHERE a.NAME=\'$groupName\' AND a.ID=b.GROUP_ID"; unless ($cursor = $dbh->prepare("$sql_statement")) { &programError( "Could not prepare SELECT_getGrpMembers_DBI c +ursor" , "$sql_statement" , "$DBI::errstr"); $dbh->rollback; &logoffOracle($dbh); exit; } unless ($cursor->execute) { &programError( "Could not execute SELECT_getGrpMembe +rs_DBI cursor" , "$sql_statement" , "$DBI::errstr"); $dbh->rollback; &logoffOracle($dbh); exit; } while (($display_name, $member_type) = $cursor->fetchrow_array +) { push(@members, "$display_name~$member_type"); } unless ($cursor->finish) { &programError( "Could not finish SELECT_getGrpMember +s_DBI cursor" , "$sql_statement" , "$DBI::errstr"); $dbh->rollback; &logoffOracle($dbh); exit; } return (@members); } 1;


And if I take the same SOCK_DBI.pl and use the same functions in the next section of code it properly connects to the database and recursively extracts all the objects it is suppose to and therefore the ONLY difference I can determine is the fact that I am trying to use this function from within the IO::Socket object but for whatever reason it appears to be returning the value of the $grp variable in some weird way but I am not sure....

This code works well using the the exact same SOCK_DBI.pl

#!/opt/app/telalert/perl5.8.8/bin/perl use DBI; require "SOCK_DBI.pl"; &declareGlobalVariables; # DBI->trace(1,'/tmp/dbi.log'); $dbh = &getOracleLogin("$ORACLE_SID", "$ORACLE_USERID", "$ORACLE_PASSW +ORD"); $dbh->{LongReadLen} = 64000; @groups = $ARGV[0]; $scale = scalar(@groups); while( $scale > 0 ){ $grp = shift(@groups); @members = &getGrpMembers($grp); foreach $member (@members){ if( $member =~ /Destination/ ){($device, $trash) = split(/~/, +$member); push(@dest, $device);} if( $member =~ /User/ ){ ($user, $trash) = split(/~/, $member) +; push(@dest, $user);} if( $member =~ /Group/ ){($mem, $trash) = split(/~/, $member); + push(@groups, $mem);} } $scale = scalar(@groups); } $out = join("\n", @dest); print $out; &logoffOracle($dbh);

Replies are listed 'Best First'.
Re^3: IO::Socket and passed variables to functions
by ig (Vicar) on Dec 17, 2008 at 03:26 UTC

    A handy tool for checking weird output is the od command. If you pipe your output to od -c you will see all the non-printing characters. When I did this with your server (having added a print of what came in to $buf from the socket) I saw the following.

    0000000 L i s t e n i n g f o r c +o 0000020 n n e c t i o n s o n p o +r 0000040 t 8 8 8 8 \n b u f = " C +S 0000060 C \r " \n 0000064

    Applying the fix oshalla recommended solved the problem.

    The od command is usually installed on *nix systems and is available for Windows.

    I note also that you are interpolating whatever text you receive from the socket into your SQL statement without any validation. Consider what will happen if a nasty fragment of SQL was entered rather than a group name. You might lose data.

    A good habit is to always check your data from external sources to make sure it is valid. And you might use place holders in your SQL statement rather than interpolating the group name into the string to further reduce the risk.

      Solved using the substitution as opposed to the chomp.

      DOG GONE! Now I just feel stupid! Yes I assumed chomp would do what it obviously didn't do...and I was making the issue harder than it actually was...a lesson learned.

      I also change the interpolating directly into the SQL Statement to use a placeholder with a validation check of the initial passed groupName from the client.

      Thanks for y'alls help on this...I really appreciate it.

      Many thanks,
      Danny
Re^3: IO::Socket and passed variables to functions
by almut (Canon) on Dec 17, 2008 at 02:34 UTC
    should have produced an output of START~CIC~END but it did not...it printed something like ENDsCIC

    Looks like the typical sign of a stray carriage return (\r), i.e. the print cursor is re-positioned to the beginning of the line, with initial text thus being overprinted by subsequent characters...  For example

    my $grp = "CIC\r"; print "START~" . $grp . "~END\n";

    would show the seemingly weird "~ENDT~CIC".

    Have you tried what oshalla suggested, i.e. $buf =~ s/\s+$// instead of chomp?  It should fix such CRLF issues.