ElkArte Community

General => Chit Chat => Topic started by: ahrasis on April 21, 2015, 03:03:19 am

Title: General Coding Discussion?
Post by: ahrasis on April 21, 2015, 03:03:19 am
I don't find any General Coding Discussion board which can be used to discuss this topic, so I opened it here instead.

I am running a test server using Ubuntu Thrusty & ISPConfig 3 for ElkArte Malaysia site but facing one problem i.e. IP address problem since I am using a dynamic IP instead of static one.

I have configured ddclient to update the IP in zoneedit so that it will be kept updated from time to time, if there is an IP change. However, ISPConfig has its own database where each domain's IP is kept.

I need a script to update this database with the current IP for each domain there is any change to it. I guess some php script with cron job can do this. What I will do is study ddclient scripts first and see whether they can make changes to the ISPConfig database at the same time it updates zoneedit if the IP change.

If anybody can throw any suggestions or codes, they will be highly appreciated.

Thank you in advance.
Title: Re: General Coding Discussion?
Post by: Spuds on April 21, 2015, 05:13:12 pm
Can't help out on this one as I have not done server configs with dynamic IP addressing.  I  would like to hear about the solution you come up with.
Title: Re: General Coding Discussion?
Post by: IchBin on April 23, 2015, 12:31:32 pm
Should be a fairly easy thing to do. Just run a cron every so often to check if the IP is changed and update it. Biggest issue is probably finding out where ISPConfig stores the info.  Using a dynamic IP for a website has to suck. Considering how long it takes DNS to update sometimes.
Title: Re: General Coding Discussion?
Post by: emanuele on April 23, 2015, 03:03:49 pm
How do you run ddclient when the IP changes?
Title: Re: General Coding Discussion?
Post by: meetdilip on April 24, 2015, 05:21:22 pm
@ahrasis  are you using your PC to run the server ? How is it connected ?
Title: Re: General Coding Discussion?
Post by: ahrasis on April 25, 2015, 01:19:26 am
It is a pc server with 1TB storage and 8GB ram. Setting up ddclient is easy but the setting must be right though. Just apt-get ddclient and edit /etc/ddclient.conf accordingly. If anybody need a working configuration for ubuntu thrusty 14.04, post a request here.

I believe @IchBin is right. Cron job is how to resolve this. But definitely with a code to access ispconfig database which luckily I know what and how.

I need to create a proper working php script and access that database, add it to ispconfig folder, check the current ip every 5 minutes, find and replace that ip table if the ip has changed. In other words, ddclient handles ip change to zoneedit while this php script handles ip change to ispconfig database.

A sync from ispconfig cp may be necessary (or may be possible with the same php script), so email should be sent to admin to remind this. Plus, zoneedit may some time need checking too.
Title: Re: General Coding Discussion?
Post by: meetdilip on April 25, 2015, 06:02:04 am
Have you checked noip (http://www.noip.com/) ?
Title: Re: General Coding Discussion?
Post by: ahrasis on April 25, 2015, 08:20:49 am
I have used noip before but I prefer zoneedit for now. If settings are correct, ddclient would check your public ip every ten minutes and update it at zoneedit if there is any ip change. This is my working configuration for ddclient:
daemon=600
pid=/var/run/ddclient.pid
ssl=yes
protocol=zoneedit1
use=web, web=dnspark
server=dynamic.zoneedit.com
login=loginid
password='password'
domain.tld

You can follow the steps in here (http://stealcode.blogspot.com/2009/02/howto-setup-ddclient-zoneedit-ubuntu.html) to install and test run ddclient on your server.

Edited: Zoneedit requires minimum of ten minutes now.i
Title: Re: General Coding Discussion?
Post by: ahrasis on April 27, 2015, 12:03:56 am
I have been thinking and formulating this php code named IP Updater to update stored ip into current public if there is any ip changes. Cron job has to be set for it to work accordingly.

I am moving this code for a test but am not sure whether it will work. This code will be shared later on in HowToForge. If you have any feedback on this, please feel free to do so.
Title: Re: General Coding Discussion?
Post by: ahrasis on April 27, 2015, 11:15:50 am
I thought I have uploaded the php file but as you can see, I forgot. Lol.

The ip_updater.php (attached) is still not working. I troubleshooted it with 'everything I know'
[1] but can't get it to work. Right now the file ownership is ispconfig:ispconfig.[2] No errors but the ispconfig  database tables are not updated.

Code: [Select]
// Get access by using ispconfig default
require_once '/usr/local/ispconfig/interface/lib/config.inc.php';
require_once '/usr/local/ispconfig/interface/lib/app.inc.php';
// Create connection
$ip_updater = mysql_connect($conf['db_host'], $conf['db_user'], $conf['db_password'], $conf['db_database']);
// Check connection
if (!$ip_updater) {
    die("Connection failed: " . mysql_connect_error());
}
$db_selection = mysql_select_db('dbispconfig', $ip_updater);
if (!$db_selection) {
    die ('Can\'t use selected database : ' . mysql_error());
}
// Current server public ip
$public_ip = file_get_contents('http://phihag.de/ip/'); // Can use different ip checker
// Server stored ip
$select_ip = "SELECT ip_address FROM server_ip WHERE sys_userid =1";
$query_ip = mysql_query($select_ip);
$fetched_ip = mysql_fetch_assoc($query_ip);
$stored_ip = $fetched_ip['ip_address'];
// Update stored ip if there is changes
if ($public_ip != $stored_ip) {
        $update_ip = "UPDATE [icode]dns_rr[/icode] SET [icode]data[/icode] = replace([icode]data[/icode], '.$stored_ip.', '.$public_ip.')";
        $update_ip2 = "UPDATE [icode]sys_datalog[/icode] SET [icode]data[/icode] = replace([icode]data[/icode], '.$stored_ip.', '.$public_ip.')";
        $update_ip3 = "UPDATE [icode]server_ip[/icode] SET [icode]ip_address[/icode] = replace([icode]ip_address[/icode], '.$stored_ip.', '.$public_ip.')";
}
mysql_close($ip_updater);

I need to find and replace but I am guessing that the last UPDATE code is somehow wrong.

Can anybody see this code and give me some feedbacks?
I surely don't know much.
I can chown it to root if needed but is this necessary?
Title: Re: General Coding Discussion?
Post by: emanuele on April 27, 2015, 12:09:25 pm
What I can see in the code you posted is that none of the UPDATE queries are actually run, you assign the string to the variable, but then you don't do anything with that. ;)
Title: Re: General Coding Discussion?
Post by: ahrasis on April 27, 2015, 09:05:07 pm
Thanks for the feedback @emanuele . So, I should run mysql_query for update_ip 1-3? Let me see... I will add the following code right after the update and see its output.

Code: [Select]
$run_update_ip = mysql_query($update_ip);
$run_update_ip2 = mysql_query($update_ip2);
$run_update_ip3 = mysql_query($update_ip3);

Anyway, can I simplify any of the above code?
Title: Re: General Coding Discussion?
Post by: emanuele on April 28, 2015, 03:07:53 am
It may even just be the query without assigning it to another variable:
Code: [Select]
mysql_query($update_ip);
mysql_query($update_ip2);
mysql_query($update_ip3);
unless you want to verify everything went smooth.

There isn't much to simplify, the only one I can think of it:
Code: [Select]
$fetched_ip = mysql_fetch_assoc($query_ip);
$stored_ip = $fetched_ip['ip_address'];
to something like:
Code: [Select]
list ($stored_ip) = mysql_fetch_row($query_ip);
but that's all.

I would, instead, add some more complexity, for example a check to verify that $public_ip is actually an IP and not some random error, for example with:
Code: [Select]
if (filter_var($public_ip), FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
{
    // do your stuff here
}
see:
http://php.net/manual/en/function.filter-var.php
http://php.net/manual/en/filter.filters.validate.php
Title: Re: General Coding Discussion?
Post by: ahrasis on April 28, 2015, 11:01:11 pm
I have updated the code and simplify it as much as I can.[1] It seems like running mysql_query for the updates is not working at all.[2]

I reproduce the current updated code:
Code: [Select]
<?php
// Get access by using ispconfig default
require_once '/usr/local/ispconfig/interface/lib/config.inc.php';
// I think the following is only needed if this is run from control panel
// require_once '/usr/local/ispconfig/interface/lib/app.inc.php';
// Create and check connection to proceed
$ip_updater = mysql_connect($conf['db_host'], $conf['db_user'], $conf['db_password']);
if (!$ip_updater) {
echo "Connection failed! \r\n"; die(mysql_connect_error());
} else {
// Connection is fine. Select the database
$db_selection = mysql_select_db($conf['db_database'], $ip_updater);
if (!$db_selection) {
echo "Can\'t use selected database! \r\n"; die(mysql_error());
} else {
// Databse is selected. Get public ip. Use others if this not working.
$public_ip = file_get_contents('http://phihag.de/ip/');
if (!filter_var($public_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === true) {
echo "Filtering failed!";  die (mysql_error());
} else {
// IPv4 is true. Extract stored ip.
echo "Comparing public IP " . $public_ip . " with ";
$select_ip = "SELECT ip_address FROM server_ip WHERE sys_userid =1";
$query_ip = mysql_query($select_ip);
list ($stored_ip) = mysql_fetch_row($query_ip);
echo "stored IP " . $stored_ip . ". \r\n";
// Update stored ip only if there is a change
if ($public_ip == $stored_ip) {
echo "Same IP address. No changes is made." . "\r\n"; die (mysql_error());
} else {
echo "Different IP address. Attempting updates..." . "\r\n";
$update_ip = mysql_query("UPDATE [icode]dns_rr[/icode] SET [icode]data[/icode] = replace([icode]data[/icode], '.$stored_ip.', '.$public_ip.')");
$update_ip2 = mysql_query("UPDATE [icode]sys_datalog[/icode] SET [icode]data[/icode] = replace([icode]data[/icode], '.$stored_ip.', '.$public_ip.')");
$update_ip3 = mysql_query("UPDATE [icode]server_ip[/icode] SET [icode]ip_address[/icode] = replace([icode]ip_address[/icode], '.$stored_ip.', '.$public_ip.')");
}
// Check the updates mysql_query
if(!$update_ip3) {
echo "Public ip should now be the same with stored ip. :( \r\n"; die (mysql_error());
} else {
// Double check stored ip as update mysql_query always returns successful :(
$select_new_ip = "SELECT ip_address FROM server_ip WHERE sys_userid =1";
$query_new_ip = mysql_query($select_new_ip);
$fetched_new_ip = mysql_fetch_assoc($query_new_ip);
$new_stored_ip = $fetched_new_ip['ip_address'];
echo "Stored ip is ";
if ($new_stored_ip = $stored_ip) {
echo "still " . $new_stored_ip . ". Updates failed! \r\n"; die (mysql_error());
} else {
echo "now " . $new_stored_ip . ". Updates are successful! Thanks God." . "\r\n";
}
}
}
}
}
// Close connection
mysql_close($ip_updater);
echo "Closing connection..." . "\r\n";
?>

I already checked the database and its user has update privilege to update from localhost. What else could be wrong?[3]
Or as much as I know. Lol.
Sighed...
I was wondering whether ispconfig itself does not allow any updates to its database. Hmmm...
Title: Re: General Coding Discussion?
Post by: emanuele on April 29, 2015, 03:06:35 am
Why do you use the "." around $stored_ip and $public_ip in the update queries?
Since you are not doing concatenation I would expect:
Code: [Select]
"UPDATE [icode]dns_rr[/icode] SET [icode]data[/icode] = replace([icode]data[/icode], '$stored_ip', '$public_ip')"
Title: Re: General Coding Discussion?
Post by: ahrasis on April 29, 2015, 03:55:32 am
A million thanks @emanuele . I am glad that is settled for now. The updates are now fully working. Attached is the working ip_updater.php file.

However, Till @ howtoforge (https://www.howtoforge.com/community/threads/ispconfig-server-ip-updater.69910/#post-329224) said this way is not advisable.

QuoteThe procedure that you use above will not result in a proper IP update for several reasons:

1) Data in sys_datalog may never be modified. The data there is transaction data, so you can not modify a existing transaction.
[1]
2) You dont update the serial of the zone, so your change will get ignored by all external dns servers and clients.

To do a dynamic IP update corrrectly, use the ispconfig remote apt function dns_a_update.

There seems to be two files that I need to use but I am not so clear with. [2]For using remote apt function, I have created a remote user that I put into the soap_config file.

The API is as follows:
Code: [Select]
dns_a_update($session_id, $client_id, $primary_id, $params);

Description:
Updates an IPv4 record if type is a.

Input Variables:
$session_id, $client_id, $primary_id, $params

Parameters (in $params):
server_id  (int(11))
zone  (int(11))
name  (varchar(64))
type  (enum('a','aaaa','alias','cname','hinfo','mx''naptr','ns','ptr','rp','srv','txt'))
data  (varchar(255))
aux  (int(11))
ttl  (int(11))
active  (enum('n','y'))
stamp  (timestamp)
serial  (int(10))

Output:
Returns the number of affected rows.

But, then, how do I supposed to add my working code inside dns_a_update file? :(

Edited: The attached ip_updater.php is removed as it is not the latest. Do get it from the github.
Data is updated as I checked it. Hmmm...
Both sample files are attached.
Title: Re: General Coding Discussion?
Post by: ahrasis on May 02, 2015, 11:09:47 pm
The latest working code is already updated in the github. Change server_id (two occurrence to chosen server id). Copy two other files mentioned in that code and make changes as stated (ask if you are not sure). ip_updater.php should be place in tools folder.
Title: Re: General Coding Discussion?
Post by: emanuele on May 04, 2015, 02:34:09 am
Glad you worked it out! :D
Title: Re: General Coding Discussion?
Post by: ahrasis on December 03, 2015, 08:06:14 am
I have updated my github on ip_updater (https://github.com/ahrasis/IP_Updater) with details of how to guides for those who have created or wish to try / create their own server using dynamic IP. Just follow howtoforge guides (https://www.howtoforge.com/) on creating your preferred ispconfig perfect server and use this ip_updater (https://github.com/ahrasis/IP_Updater/blob/master/ip_updater.php) after following all its guides (http://ipupdater.sch.my). Instructions, link and code for ddclient settings are in reply#7 above. Feel free to ask.
Title: Re: General Coding Discussion?
Post by: ahrasis on May 19, 2016, 09:47:09 pm
Hi, I need some help again. This time is to convert this code to mysqli[1]:

Code: [Select]
// Get access by using ispconfig default
require_once '/usr/local/ispconfig/interface/lib/config.inc.php';
// Create and check connection to proceed
$ip_updater = mysql_connect($conf['db_host'], $conf['db_user'], $conf['db_password']);
if(!$ip_updater) {
 echo "Connection failed! \r\n"; die(mysql_connect_error());
} else { // Connection is fine. Select the database
 $db_selection = mysql_select_db($conf['db_database'], $ip_updater);
 if(!$db_selection) {
 echo "Can\'t use selected database! \r\n"; die(mysql_error());
 } else { // Database is selected. Get updated public ip from reliable source OR
 $public_ip = file_get_contents('http://ip.sch.my/'); //  Get it from your own updated nameserver ip e.g. $public_ip = gethostbyname('ns1.sch.my');
 if(!filter_var($public_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === true) {
 echo "Filtering failed!";  die (mysql_error());
 } else { // IPv4 is true. Important! Change to your intended server_id.
 $select_ip = "SELECT ip_address FROM server_ip WHERE server_id =1";
 $query_ip = mysql_query($select_ip);
 list ($stored_ip) = mysql_fetch_row($query_ip); // Get current stored ip
 if($public_ip == $stored_ip) { // Compare the ip addresses
 echo "Same IP address. No changes is made." . "\r\n"; die (mysql_error());
 } else { // Update database if there is a change
 $update_ip = mysql_query("UPDATE [icode]dns_rr[/icode] SET [icode]data[/icode] = replace([icode]data[/icode], '$stored_ip', '$public_ip')");
 $update_ip3 = mysql_query("UPDATE [icode]server_ip[/icode] SET [icode]ip_address[/icode] = replace([icode]ip_address[/icode], '$stored_ip', '$public_ip')");// Check the above process updates
 // Check the above process updates
 if(!($update_ip || $update_ip3)) {
 echo "Public ip should now be the same with stored ip. :( \r\n"; die (mysql_error());
 } // Now we update ip address in soa zone files
 foreach (glob("/etc/bind/pri.*") as $filename) {
 $file = file_get_contents($filename);
 file_put_contents($filename, preg_replace("/$stored_ip/","$public_ip",$file));
 }
 } // Resynce data. Important! Copy resync.php to ipu_resync and app.inc.php to ipu_app.inc.php
 // Disable admin check and tpl in ipu_resync.php and start_session() in ipu_app.inc.php.
 // Change require once in ipu_resync.php is now changed to ipu_app.inc.php.
 require_once 'ipu_resync.php';
 echo "Check and resync database and soa zone files. Restart apache. \r\n";
 // Double check to confirm stored ipis updated  as update mysql_query always returns successful :(
 $select_new_ip = "SELECT ip_address FROM server_ip WHERE server_id =1"; // Define this similar as above
 $query_new_ip = mysql_query($select_new_ip);
 list ($new_stored_ip) = mysql_fetch_row($query_new_ip); // Get currrent stored_ip
 if ($new_stored_ip != $public_ip) { echo "Updates failed! \r\n"; die (mysql_error()); }
 else { echo "Updates are successful! Thanks God." . "\r\n"; }
 }
 }
}
// Lastly, we close connection and restart apache.
mysql_close($ip_updater);
echo "Closing connection... \r\n";
exec('service apache2 restart'); // Smile...
?>
Preparing to comply with php7, sighed...
Title: Re: General Coding Discussion?
Post by: emanuele on May 20, 2016, 06:16:49 am
I feel like giving you some reference would be better than re-writing the script for you. O:-)
http://php.net/manual/en/mysqli.summary.php
In general, you just replace "mysql" with "mysqli". In some cases (like mysqli_query) the order of the parameters changed.
Honestly I don't remember mysql all the changes, so your best bet is to have a look at the functions in the php manual and compare. :)
Title: Re: General Coding Discussion?
Post by: ahrasis on May 20, 2016, 07:44:41 am
I guess I can adapt though it will take some time for older folk like me. In the meantime I find a nice tool which I intend to try later.[1]
https://github.com/philip/MySQLConverterTool/blob/master/README
Title: Re: General Coding Discussion?
Post by: ahrasis on July 31, 2016, 09:42:31 pm
It has been two months and I finally get my hands on this, again. I managed to convert the code to mysqli which supposedly should run fine in php 5.6 and 7. The following is the latest code:

Code: [Select]
<?php
/*
Copyright (c) 2015, Ahmad Rasyid Ismail, ahrasis@gmail.com
Project IP Updater for ubuntu, ispconfig 3 and dynamic ip users.
BSD3 License. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
 this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following disclaimer in the documentation
 and/or other materials provided with the distribution.
* Neither the name of ISPConfig nor the names of its contributors
 may be used to endorse or promote products derived from this software without
 specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* Get database access by using ispconfig default configuration so no
   user and its password are disclosed. Exit if its connection failed */

require_once 'config.inc.php';
$ip_updater = mysqli_connect($conf['db_host'], $conf['db_user'], $conf['db_password'], $conf['db_database']);
if (mysqli_connect_errno()) {
    printf("Connection failed! \r\n", mysqli_connect_error());
    exit();
}

/* Else, it works. Now get public ip from a reliable source.
   We are using this but you can define your own. But We just
   need ipv4. So we exit if its filetering failed */

$public_ip = file_get_contents('http://ip.sch.my/');
if(!filter_var($public_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === true) {
    printf("IPV4 for public IP filtering failed! \r\n");
    exit();
}

/* Else, it's truly ipv4. Now we obtain the server ip address,
   based on server id. So change your server id accordingly.
   Exit if the server public ip address matches i.e. the same.  */

$query_ip = mysqli_query($ip_updater, 'SELECT ip_address FROM server_ip WHERE server_id =1');
list($stored_ip) = mysqli_fetch_row($query_ip);

if($public_ip == $stored_ip) {
    printf("\r\nThe server and its public ip addresses match. \r\nNo changes is therefore necesary.\r\n\r\n");
    exit();
}

/* Else, update database and soa zone files with the new ip address */

$update1 = mysqli_query($ip_updater, 'UPDATE dns_rr SET data = replace(data, $stored_ip, $public_ip)');
$update2 = mysqli_query($ip_updater, 'UPDATE server_ip SET ip_address = replace(ip_address, $stored_ip, $public_ip)');
foreach (glob('/etc/bind/pri.*') as $filename) {
$file = file_get_contents($filename);
file_put_contents($filename, preg_replace('/$stored_ip/', '$public_ip', $file));
}

/* Now resync so that above changes updated properly. Important!
   Refer to http://ipupdater.sch.my and download or copy
   resync.php to ipu_resync,php and app.inc.php to
   ipu_app.inc.php. Disable admin check and tpl in ipu_resync.php
   and start_session() in  ipu_app.inc.php and change require
   once in ipu_resync.php to ipu_app.inc.php.
   Then double check if the update truly works */

require_once 'ipu_resync.php';
$query_new_ip = mysqli_query($ip_updater, 'SELECT ip_address FROM server_ip WHERE server_id =1');
list($new_stored_ip) = mysqli_fetch_row($query_new_ip);
if ($new_stored_ip != $public_ip) {
    printf("\r\nUpdates failed! \r\nUpdates failed! \r\nUpdates failed! \r\n\r\n");
    exit();
} else { printf("\r\n Database updates are successful! Thanks God. \r\n\r\n"); }

/* Lastly, close database connection and restart apache. */
printf("\r\nClosing connection and restarting apache... \r\n\r\n");
mysqli_close($ip_updater);
exec('service apache2 restart');
?>

Partly the code works except to this part:
Code: [Select]
$update1 = mysqli_query($ip_updater, 'UPDATE dns_rr SET data = replace(data, $stored_ip, $public_ip)');
$update2 = mysqli_query($ip_updater, 'UPDATE server_ip SET ip_address = replace(ip_address, $stored_ip, $public_ip)');
foreach (glob('/etc/bind/pri.*') as $filename) {
$file = file_get_contents($filename);
file_put_contents($filename, preg_replace('/$stored_ip/', '$public_ip', $file));
}

So far that I have checked, based on what I know,  ::) it seems like the above code is correct, but it does not work.  :(  I would highly appreciate if anybody could give me some clues or ideas on how to find what is wrong with the code and fix it.  O:-)
Title: Re: General Coding Discussion?
Post by: ahrasis on July 31, 2016, 10:56:59 pm
Managed to fix the above. Tested with php5.6 and 7.0. The new working code, if anybody is interested, can be obtained from the above mentioned links which are as follows:

Code: [Select]
<?php
/*
Copyright (c) 2015, Ahmad Rasyid Ismail, ahrasis@gmail.com
Project IP Updater for ubuntu, ispconfig 3 and dynamic ip users.
BSD3 License. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
* Neither the name of ISPConfig nor the names of its contributors
  may be used to endorse or promote products derived from this software without
  specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* Get database access by using ispconfig default configuration so no
   user and its password are disclosed. Exit if its connection failed */

require_once 'config.inc.php';
$ip_updater = mysqli_connect($conf['db_host'], $conf['db_user'], $conf['db_password'], $conf['db_database']);
if (mysqli_connect_errno()) {
    printf("\r\nConnection failed! \r\n\r\n", mysqli_connect_error());
    exit();
}

/* Else, it works. Now get public ip from a reliable source.
   We are using this but you can define your own. But We just
   need ipv4. So we exit if its filetering failed */

$public_ip = file_get_contents('http://ip.sch.my/');
if(!filter_var($public_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === true) {
    printf("\r\nIPV4 for public IP filtering failed! \r\nYou may need to use other ip source.\r\n\r\n");
    exit();
}

/* Else, it's truly ipv4. Now we obtain the server ip address,
   based on server id. So change your server id accordingly.
   Exit if the server public ip address matches i.e. the same.  */

$query_ip = mysqli_query($ip_updater, 'SELECT ip_address FROM server_ip WHERE server_id =1');
list($stored_ip) = mysqli_fetch_row($query_ip);
if($public_ip == $stored_ip) {
    printf("\r\nThe server and its public ip addresses match. \r\nNo changes is deemed necesary.\r\n\r\n");
    exit();
}

/* Else, update database with the new ip address */

$update1 = mysqli_query($ip_updater, "UPDATE dns_rr SET data = replace(data, '$stored_ip', '$public_ip')");
$update2 = mysqli_query($ip_updater, "UPDATE server_ip SET ip_address = replace(ip_address, '$stored_ip', '$public_ip')");
$query_new_ip = mysqli_query($ip_updater, 'SELECT ip_address FROM server_ip WHERE server_id =1');
list($new_stored_ip) = mysqli_fetch_row($query_new_ip);

if ($new_stored_ip != $public_ip) {
    printf("\r\nDatabase updates failed! \r\nDatabase updating code may need a fix or update. \r\n\r\n");
    exit();
}

/* Next we change soa zone files with the new ip address
   i.e. only when the above updates are successful */

foreach (glob('/etc/bind/pri.*') as $filename) {
        $file = file_get_contents($filename);
        file_put_contents($filename, preg_replace("/$stored_ip/", "$public_ip", $file));

        /* Exit if SOA zone files are not updated */
        foreach(file($filename) as $fli=>$fl) {
                if(strpos($fl, "/$stored_ip/")!==false) {
                        printf("\r\nSOA zone files updates failed! \r\nZone files updating code may need a fix or update. \r\n\r\n");
                        exit();
                }
        }
}

/* Now resync so that above changes updated properly. Important!
   Do refer to http://ipupdater.sch.my and download or copy
   resync.php to ipu_resync,php and app.inc.php to
   ipu_app.inc.php. Disable admin check and tpl in ipu_resync.php
   and start_session() in ipu_app.inc.php and change require
   once in ipu_resync.php to ipu_app.inc.php. */

require_once 'ipu_resync.php';

/* Lastly, congratulations! All updates are successful.
   Log it then close database connection and restart apache. */
printf("\r\nDatabase and SOA zone files updates are successful! \r\nThanks God. Closing connection and restarting apache. \r\n\r\n");
mysqli_close($ip_updater);
exec('service apache2 restart');
?>