I have to switch my webserver (internal use only) to a more recent version and so I have also new perl and new DBD:Sybase instead of DBD:ASAny I used before.
I use statements with bind variables regulary, they worked fine, but with DBD:Sybase I get the following error:
AH01215: DBD::Sybase::st execute failed: Server >message number=12006 severity=16 state=0 line=0 text=SQL Anywhere-Fehler >-110: Element 'DBD1' ist bereits vorhanden
The versions:
New: DBD::Sybase
/usr/local/lib/x86_64-linux-gnu/perl/5.22.1/DBD/Sybase.pm
Installed: 1.15
Old: DBD::ASAny
DBD::ASAny version 1.14.
#!/usr/bin/perl
use DBI;
print "Content-type: text/html\n\n";
$dbh = DBI->connect( "DBI:Sybase:server=tl", 'xxx', 'yyy', {PrintError => 1, AutoCommit => 0} ) or die "Connection failed\n Connection string: $connstr\n Error message : $DBI::errstr\n";
$dbh2 = DBI->connect( "DBI:Sybase:server=tl", 'xxx', 'yyy', {PrintError => 1, AutoCommit => 0} ) or die "Connection failed\n Connection string: $connstr\n Error message : $DBI::errstr\n";
$select="select artnr, bez1, bez2 from art where artnr like 'F%12%.00'";
$sth_t=$dbh->prepare($select);
$sth_t->execute();
$select="select lager_nr, bestand from bestand where art_nr = ? and coalesce(bestand,0) > 0 ";
$sth_lager=$dbh2->prepare($select) or die "Prep sthlager nix:".$dbh2->errstr()."\n";
while ( ($artnr, $gtnr, $bez)=$sth_t->fetchrow())
{
print $artnr."; ".$gtnr."; ".$bez;
$sth_lager->execute($artnr) or die "exec sthlager nix:".$dbh2->errstr()."\n";
while ( ($lager,$bestand) = $sth_lager->fetchrow())
{
print $lager." : ".$bestand." || ";
}
$sth_lager->finish();
print "\n<br>";
}
The offending line is "$sth_lager->execute($artnr)"
Thanks to You all, especially simbabque, he was on the right track. The answer is simple:
DBD::ASAny was written to handle SQL Anywhere, whereas DBD::Sybase is for Sybase Adaptive Server Enterprise, and these two systems are actually quite different.
I used the wrong tool. Mist.
Related
I want to send an email using perl ,but when i execute the command as follows:
#./sendmail.sh "par1" "par2" "par3"
i got the error msg "connect to localhost failed (Connection refused) no (more) retries"
sendmail.sh:
/usr/bin/perl /code/sendmail.pl "$1" "$2" "$3";
sendmail.pl:
#!/usr/bin/perl -w
use Mail::Sendmail;
my $event1 = shift(#ARGV);
my $event2 = shift(#ARGV);
my $time = shift(#ARGV);
#my $info = shift(#ARGV);
my $datetime = `/bin/date "+20%y-%m-%d %H:%M:%S"`;
chomp $datetime;
$msg = "This is Monitor System speak:\n
The system discovers the events at $datetime.
Something may be abnormal, please check it. The detail is below:\n";
$msg = $msg."$event1 and $event2 at $time\n";
$msg = $msg."\n";
$msg = $msg."Any problem, check it from http://map_test.php\n\n\n";
$mail_subject = "Abnormal";
sendmail(
From => 'localhost',
To => 'test#mail.com',
Subject => $mail_subject,
Message => $msg,
);
Any help appreciated.
smtp stands for simple mail transfer protocol.
When you need to send an email your mail client needs to talk to an smtp server which will accept the message. Normally your internet service provider will provide an smtp host. If you look at your mail client it will need to have an smtp server configured to be able to send mail.
Ok so when you install the Mail::Sendmail module, it doesn't know what your smtp server will be. It is up to you to tell it. It provides a default of localhost which would often be true if your server is running a sendmail daemon.
The configuration of Mail::Sendmail is stored in a variable called
%Mail::Sendmail::mailcfg
You can change the value of the sendmail server using this snippet of code:
unshift #{$Mail::Sendmail::mailcfg{'smtp'}} , 'my.smtp.server';
You need to add this line of code to your script to set the smtp server.
It adds this server to an array which also includes localhost.
So if neither of the hosts work it will still print an error message about localhost which is slightly confusing.
If you use Data::Dumper to print the contents of the mailcfg variable it will look something like this:
#!/usr/bin/perl
use Mail::Sendmail;
use Data::Dumper;
unshift #{$Mail::Sendmail::mailcfg{'smtp'}} , 'my.smtp.server';
print Dumper(\%Mail::Sendmail::mailcfg);
Should return:
$VAR1 = {
'retries' => 1,
'smtp' => [
'my.smtp.server',
'localhost'
],
'delay' => 1,
'port' => 25,
'from' => '',
'debug' => 0,
'tz' => '',
'mime' => 1
};
I'm create database
sqlite3 database
create table if not exists entries (
id integer primary key autoincrement,
title string not null,
text string not null
);
^D
Where should i put this database ?
After
sub connect_db {
my $dbh = DBI->connect("dbi:SQLite:dbname=".setting('database')) or
die $DBI::errstr;
return $dbh;
}
sub init_db {
my $db = connect_db();
my $schema = read_file('./schema.sql');
$db->do($schema) or die $db->errstr;
}
get '/' => sub {
my $db = connect_db();
my $sql = 'select id, title, text from entries order by id desc';
my $sth = $db->prepare($sql) or die $db->errstr;
$sth->execute or die $sth->errstr;
template 'show_entries.tt', {
'msg' => get_flash(),
'add_entry_url' => uri_for('/add'),
'entries' => $sth->fetchall_hashref('id'),
};
};
Recieve an Error
Runtime Error
near "desk" : syntax error at /home/ultramozg/App/lib/App.pm line 40, line 16
What it's my mistake ?
I highly recommend you use Dancer::Plugin::Database instead of the connect_db routine you're proposing. The way you're doing it will probably create leftover open connections and therefore all sorts of problems. Dancer::Plugin::Database handles persistent connections for you. Doc for plugin:
https://metacpan.org/pod/Dancer::Plugin::Database
Once you install Dancer::Plugin::Database and configure it in config.yml, then whenever you need to a database handle, you just:
my $dbh => database('my_database_name');
and don't bother disconnecting when done.
If you're using ubuntu, just:
apt-get install libdancer-plugin-database-perl
Good luck on your project!
You have a ^D character for starters - last line in the first section. Please learn to read output. It tells you line 16.
Check where the word "desk" appears in your code as well.
I tried the following to access a router via a central admin server as "ssh hop" server
#!/usr/bin/perl -X
use strict;
use Net::OpenSSH;
use Net::Telnet;
my $lhost = "linuxserver";
my $luser = "linuxuser";
my $lpass = "linuxpassword";
my $chost = "routername";
my $cpass = "Routerpassword";
my $prompt = '/(?:Password: |[>])/m';
my #commands = ("show users\r");
my $ssh = Net::OpenSSH->new($lhost,
'user' => $luser,
'password' => $lpass,
'master_opts' => [ '-t' ],
#'async' => 1 # if enabled then password cannot be set here
);
my ($pty, $err, $pid) = $ssh->open2pty("telnet $chost");
my $t = new Net::Telnet(
-telnetmode => 0,
-fhopen => $pty,
-prompt => $prompt,
-cmd_remove_mode => 1,
-output_record_separator => "\r",
#-dump_log => "debug.log",
);
my $end = 0;
while (!$end) {
my ($pre, $post) = $t->waitfor($prompt);
if ($post =~ /Password: /m) {
# send password
$t->print("$cpass");
}
elsif ($post =~ /[>#]/ && #commands) {
my $cmd = shift(#commands);
if ($cmd !~ /[\r\n]/) {
$t->print($cmd);
}
else {
print $t->cmd($cmd);
}
}
else {
$end = 1;
$t->cmd("exit");
}
}
#close $pty;
$t->close();
Unfortunately I always get the following error:
read error: Input/output error at test.pl line 71
Can somebody help me please or is there a better solution only to test if a telnet connection via the "hop" server is possible or not?
The connection looks like:
workstation --ssh-> server --telnet-> router
Thanks in advance.
I think best option is to make an SSH-tunnel to your admin server and use it for telnetting to the router.
Getting Net::Telnet to work over Net::OpenSSH sometimes is not as easy as it should be and it requires some experimentation to get to the right combination of flags and calls that make it work.
For instance, instead of telneting to the target host, use netcat to open a raw connection (or Net::OpenSSH support for TCP forwarding if tunnels are allowed on the proxy).
Expect + Net::OpenSSH may be a better option.
I am trying to send a SMPP message using the Net::SMPP module, but it's giving the error below:
Message state is 2
Response indicated error: Message ID is invalid (ESME_RINVMSGID=0x0000000C) at send.pl line 28.
#!/usr/bin/perl
#use strict;
#use warnings;
use Net::SMPP;
my $host = 'iphost';
my $port = 2345;
my $smpp = Net::SMPP->new_transmitter(
$host,
port => $port,
system_id => 'username',
password => 'pass',
) or die;
$resp_pdu = $smpp->submit_sm(
destination_addr => '+44206064379',
short_message => 'test message'
) or die;
die "Response indicated error: " . $resp_pdu->explain_status()
if $resp_pdu->status;
$msg_id = $resp_pdu->{message_id};
$resp_pdu = $smpp->query_sm(message_id => $msg_id) or die;
die "Response indicated error: " . $resp_pdu->explain_status()
if $resp_pdu->status;
print "Message state is $resp_pdu->{message_state}\n";
$resp_pdu = $smpp->replace_sm(
message_id => $msg_id,
short_message => 'another test'
) or die;
die "Response indicated error: " . $resp_pdu->explain_status()
if $resp_pdu->status;
$resp_pdu = $smpp->cancel_sm(message_id => $msg_id) or die;
die "Response indicated error: " . $resp_pdu->explain_status()
if $resp_pdu->status;
If you are trying to send a message then you are succeeding. The message is sent using the submit_sm method.
The first line of the output is showing the result from the query_sm, which returns the state of the message. The state 2 corresponds to a status of DELIVERED (from SMPP v3.4 spec). This means the SMSC has delivered the message to the mobile device.
The error is being generated by the replace_sm method. The replace_sm method will only replace a message that is still on the SMSC, i.e. still awaiting delivery. If the message is already delivered, the SMSC returns an error in the response PDU. The same thing applies to the cancel_sm method. It only works on messages that are still awaiting delivery.
I have the following code:
...
sub setImage {
my $self=shift;
my $filename=shift;
unless(-r $filename) {
warn "File $filename not found";
return;
}
my $imgn=shift;
my $operation=&URI::Escape::uri_escape_utf8(
(shift) ? "Удалить! (Delete)" : "Сохранить! (Store)");
my $FH=&::File::open($filename, 0, 0);
my $image;
# &utf8::downgrade($image);
sysread($FH, $image, 102400, 0);
close $FH;
my $imginfo=eval{&Image::Info::image_info(\$image)};
if($# or $imginfo->{"error"}) {
warn "Invalid image: ".($# || $imginfo->{"error"});
return undef;
}
my $fields=[
DIR => $self->url("fl"),
OPERATION => $operation,
FILE_NAME => ".photo$imgn",
# FILE => [$filename],
FILE => [undef, "image.".$imginfo->{"file_ext"},
# Content_Type => $imginfo->{"file_media_type"},
# Content_Type => 'application/octet-stream',
Content => $image,
],
];
my $response=&ZLR::UA::post(
&ZLR::UA::absURL("/cgi-bin/file_manager")."",
$fields,
Content_Type => "form-data",
);
print $response->decoded_content;
}
...
When I try to use function setImage it fails with error HTTP::Message content must be bytes at /usr/lib64/perl5/vendor_perl/5.8.8/HTTP/Request/Common.pm line 91. Worse that I can't reproduce this error without using all of my code and upgrading libwww-perl does nothing. What can cause it?
Versions of libww-perl: dev-perl/libwww-perl-5.836. HTTP::Request and HTTP::Request::Common came from libwww-perl package, versions: 5.827 and 5.824.
Trace:
HTTP::Message content must be bytes at /usr/lib64/perl5/vendor_perl/5.8.8/HTTP/Request/Common.pm line 91
at Carp::croak(unknown source)
at HTTP::Message::__ANON__(/usr/lib64/perl5/vendor_perl/5.8.8/HTTP/Message.pm:16)
at HTTP::Message::_set_content(/usr/lib64/perl5/vendor_perl/5.8.8/HTTP/Message.pm:136)
at HTTP::Message::content(/usr/lib64/perl5/vendor_perl/5.8.8/HTTP/Message.pm:125)
at HTTP::Request::Common::POST(/usr/lib64/perl5/vendor_perl/5.8.8/HTTP/Request/Common.pm:91)
at LWP::UserAgent::post(/usr/lib64/perl5/vendor_perl/5.8.8/LWP/UserAgent.pm:397)
at ZLR::UA::post(./zlrchecker.pl:71)
at ZLR::Info::setImage(./zlrchecker.pl:1754)
at main::main(./zlrchecker.pl:3893)
at main::(./zlrchecker.pl:4148)
Use Devel::SimpleTrace and paste the trace. Install the module with cpan. Then run your program with -MDevel::SimpleTrace like perl -MDevel::SimpleTrace ./myapp_run.pl
And paste the version of HTTP::Request:Common, HTTP::Message, and LWP.
My guess is you'll see this in the stack trace:
This seems to be the code likely causing the error:
*_utf8_downgrade = defined(&utf8::downgrade) ?
sub {
utf8::downgrade($_[0], 1) or
Carp::croak("HTTP::Message content must be bytes")
}
:
sub {
};
The docs in utf8 say this:
Fails if the original UTF-X sequence
cannot be represented in the native 8
bit encoding. On failure dies or, if
the value of FAIL_OK is true, returns
false.
You should be able to make a test case by running utf8::downgrade($http_message_content)
One effective solution I found to this problem was to parse any text we put into HTTP::Message, during a HTTP request, through unidecode() from Text::Unidecode.