when i try to run this script to send my ip to cpanel…
#!/usr/bin/perl
# -------------------------------------------------------------------------------
# dns_update_script.pl
#
# Version 1.0 - 16.01.2012
#
# PERL script to dynamically update the IP of a host via the cPanel-API. This
# script was written to work with the Finnish hoster Neobitti but it might work
# with other hosters which use cPanel too.
#
# Copyright (C) 2012 Stefan Gofferje - http://stefan.gofferje.net/
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# -------------------------------------------------------------------------------
use strict;
use LWP::UserAgent;
use MIME::Base64;
use XML::Simple;
use Data::Dumper;
# --- Command line parameters ------------------------------------------------
my $param_domain=$ARGV[0];
my $param_host=$ARGV[1];
my $param_ip=$ARGV[2];
# --- cPanel information -----------------------------------------------------
# Storing passwords in clear text is ugly!
my $cpanel_domain = "yourdomain.com";
my $user = "yourcpaneluser";
my $pass = "yourcpanelpassword";
my $auth = "Basic " . MIME::Base64::encode( $user . ":" . $pass );
# --- Deactivate SSL certificate validation ----------------------------------
# This is ugly but neccessary because Neobitti uses self-signed SSL
# certificates which will fail validation
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
# --- Find out the linenumber for the A-record we want to change -------------
sub getlinenumber_a {
my $domain=$_[0];
my $hostname=$_[1].".";
my $xml = new XML::Simple;
my $request = HTTP::Request->new( GET => "https://$cpanel_domain:2083/xml-api/cpanel?cpanel_xmlapi_module=ZoneEdit&cpanel_xmlapi_func=fetchzon
e&domain=$domain" );
$request->header( Authorization => $auth );
my $response = $ua->request($request);
my $zone = $xml->XMLin($response->content);
my $linenumber="";
if ($zone->{'data'}->{'status'} eq "1") {
my $count = @{$zone->{'data'}->{'record'}};
my $oldip="";
for (my $item=0;$item<=$count;$item++) {
my $name=$zone->{'data'}->{'record'}[$item]->{'name'};
my $type=$zone->{'data'}->{'record'}[$item]->{'type'};
if ( ($name eq $hostname) && ($type eq "A") ) {
$linenumber=$zone->{'data'}->{'record'}[$item]->{'Line'};
$oldip=$zone->{'data'}->{'record'}[$item]->{'record'};
print "Found $hostname in line $linenumber with IP $oldip.n"; # DEBUG
}
}
} else {
$linenumber="0";
print $zone->{'event'}->{'data'}->{'statusmsg;'}
}
return($linenumber);
}
# --- Change the IP address record for a certain linenumber ------------------
sub setip {
my $domain=$_[0];
my $linenumber=$_[1];
my $newip=$_[2];
my $result="";
my $xml = new XML::Simple;
my $request = HTTP::Request->new( GET => "https://$cpanel_domain:2083/xml-api/cpanel?cpanel_xmlapi_module=ZoneEdit&cpanel_xmlapi_func=edit_zone_record&domain=$domain&line=$linenumber&address=$newip" );
$request->header( Authorization => $auth );
my $response = $ua->request($request);
my $reply = $xml->XMLin($response->content);
if ($reply->{'data'}->{'status'} eq "1") {
$result="1";
} else {
$result=$reply->{'data'}->{'statusmsg'};
}
return($result);
}
# --- Main procedure ---------------------------------------------------------
print "Trying to find the linenumber for $param_host in $param_domain...n";
my $line=getlinenumber_a($param_domain,$param_host);
if ( ($line ne "0") && ($line ne "") ) {
print "Trying to update IP...n";
my $result=setip ($param_domain,$line,$param_ip);
if ($result eq "1") {
print "Update successful!n";
} else {
print "$resultn";
}
} else {
print "Error - check domain and hostname!n";
}
… I get this error:
mismatched tag at line 37, column 2, byte 4634 at /usr/lib/arm-linux-gnueabihf/perl5/5.28/XML/Parser.pm line 187.
XML::Simple called at dns_update_script.pl line 55.
in the cPanel information section I have filled in my cpanel username, password and domain in my file (not this one). I have filled this in in open text like a noob and ignored this thing:
my $auth = "Basic " . MIME::Base64::encode( $user . ":" . $pass );
but i dont think this is the problem.
I think the problem is in the XML::Simple module because the script stops when that module is called it seems like to me but idk. pls help.
2
Answers
I just used this shell script instead and hooked it up to my crontab and now it runs the script every hour and it works fine.
https://github.com/CpanelInc/cpanel-dynamicdns-tools
for my raspberry pi web server
You are getting that error because the string you pass to
XMLin
isn’t valid XML. You will need to fix the input to be valid XML.While I strongly recommend against using XML::Simple, it’s not because of problems parsing XML. The underlying parser used in this situation (
expat
via XML::Parser) isn’t known for wrongly claiming valid XML is invalid.Your program should be checking if the request is successful (
$response->is_success
). I suspect you are getting some kind of error (e.g. 403 Forbidden).$response->status_line
is useful to add to your error message.(If the request is successful, perhaps you should print out
$response->as_string
to examine the response to get a better idea of what is happening.)