Backup php script as a user level, could someone update this script?

500 Internal Server Error?? Does you use it from a browser???

It has been created to be run from SSH using php SCRIPTNAME or using (as described in the same file) with a cronjob

Regards
 
Firstly I tried with cronjobs, but it didin't work, then I tried with browser. Are you sure, that this script should work with newest directadmin?
 
Well i did not analyze the code, but im sure it has no to be run with a browser....

How did you set the cron? Have you customized the script with correct required data?

Regards
 
Definitly wrong.

set it to be

/usr/local/bin/php /home/USER/domains/DOMAIN/public_html/backup.php

Or, way better, move the .php file to a different path, not accessible by web (ex. /usr/local/directadmin/scripts/custom/) and set

/usr/local/bin/php /usr/local/directadmin/scripts/custom/backup.php

Regards
 
Definitly wrong.

set it to be

/usr/local/bin/php /home/USER/domains/DOMAIN/public_html/backup.php

Or, way better, move the .php file to a different path, not accessible by web (ex. /usr/local/directadmin/scripts/custom/) and set

/usr/local/bin/php /usr/local/directadmin/scripts/custom/backup.php

Regards

http://puu.sh/85FLS.png still doesn't work, I think it's really script fault, it could be outdated or maybe I'm just wrong..

I don't have access to /usr/local/bin/php /usr/local/directadmin/scripts/custom/ I'm only at User level with access to /home
 
Yoi dont need to set cron url

apparently you cant run the cron as i thot...

i suppose it should run with /usr/local/bin/php /home/mcprison/domains/mcprison.lt/public_html/backup.php

But since you cant set that way maybe your hoster is blocking it somehow.

Someone else maybe know how to do that, or, you can consider ask your hosting.. or either.. use the directadmin backup function (if you got it enabled by your hoster).

Regards
 
Hello,
I'd test this script because one of my user need something like this.
And, like Luke say it, i found some bug in it, specialy in httpsocket class, in sock->query array and sock->connect.

I put mine here, that can help you, this one save all, if you not need some just remove it from array, ex: remove " 'select5' => 'vacation', " but dont change select number.

P.S: for test it do this: ./backup.php in dir where you put it after had made chmod 700 backup.php
P.S2: for cron just put "/home/USER/backup.php" in command line, and configure when you want launch it (replace USER by you username)
P.S3: for 'supress_message' => 1 check http://www.directadmin.com/features.php?id=665


Code:
#!/usr/local/bin/php -n
<?php

//User backup script, allowing DA Users to create backups via a cronjob.

/*******************************
**  Set your variables here
*******************************/

$username = "youruserame";
$password = "yourpassword";

// you must specify one of your domain names. (Any one of them will be fine)
$domain = "yourdomain.com";

// These usually dont require modification
// if you use https to connect to DA, set $ssl = 1;
$host = "localhost";
$ssl = 0;
$port = 2222;

/*******************************
**  Install Instructions
*******************************

1) Place this file somewhere under your home directory.
A good place might be:
/home/username/backup.php

From the File Manager in DA, that would be:
/backup.php

2) Chmod the file to 700.  This is very important for security.

3) Edit the above variables.
Most likely, you''ll only need to change the username and password.
If your system uses ssl to connect to DA (https) then you'll need to set $ssl = 1;

4) Create the cronjob to execute:

/home/username/backup.php

as often as you wish. Usually once per day is the most you'll want to run it.
To create the cronjob, see:
http://www.site-helper.com/misc.html#cron

Usually a very early morning hour, say 5am is best as the load is usually lowest then.

Note that we do not need to add /usr/local/bin/php in front of this php script because of the
#!/usr/local/bin/php -n
line at the very top.

5) check your 'username' account.  Any emails will be delivered there if it doesn't work.
If needed, you can test manually via ssh by running:

/home/username/bacukp.php

6) Optional:  If you wish to have an ftp upload along with the bacukp, create a
cronjob to run about an hour later than the backup, and use the command:

/usr/bin/ncftpput -f /home/username/ftp.conf -V -t 25 -m "/ftp/path/" "/home/username/backups/backup-`date +%b-%e-%Y`-1.tar.gz"

and in the ftp.conf, put:

host 1.2.3.4
user ftpuser
pass ftppass

Then chmod the ftp.conf to 700.
Note this assumes you've only got 1 bacukp per day since it uses -1.tar.gz and doesn't take into account possible -2.tar.gz, etc.

********************************
*******************************/

$sock = newSock();
$sock->query('/CMD_API_SITE_BACKUP',
	array(
		'action' => 'backup',
                'domain' => $domain,
                'form_version' => 3,
                'supress_message' => 1,
                'select0' => 'domain',
                'select1' => 'subdomain',
                'select2' => 'email',
                'select3' => 'forwarder',
                'select4' => 'autoresponder',
                'select5' => 'vacation',
                'select6' => 'list',
                'select7' => 'emailsettings',
                'select8' => 'ftp',
                'select9' => 'ftpsettings',
                'select10' => 'database',
                'select11' => 'database_data',
                'select12' => 'email_data'
	));

$result = $sock->fetch_parsed_body();

if ( $result['error'] != "0" )
{
	echo "Error issuing backup creation: ".$result['details']."\n";
	exit(1);
}

//all should be fine.
exit(0);

function newSock()
{
        global $host;
        global $port;
        global $ssl;
        global $username;
	global $password;

        $tsock = new HTTPSocket;
        $tsock->set_method('POST');

        if ($ssl)
        {
                $tsock->connect("ssl://".$host, $port);
        }
        else
        {
                $tsock->connect($host, $port);
        }

        $tsock->set_login($username, $password);

        return $tsock;
}

/**
 * Socket communication class.
 *
 * Originally designed for use with DirectAdmin's API, this class will fill any HTTP socket need.
 *
 * Very, very basic usage:
 *   $Socket = new HTTPSocket;
 *   echo $Socket->get('http://user:[email protected]/somedir/some.file?query=string&this=that');
 *
 * @author Phi1 'l0rdphi1' Stier <[email protected]>
 * @package HTTPSocket
 * @version 2.6
 */
class HTTPSocket {

    var $version = '2.6';
    
    /* all vars are private except $error, $query_cache, and $doFollowLocationHeader */

    var $method = 'GET';

    var $remote_host;
    var $remote_port;
    var $remote_uname;
    var $remote_passwd;

    var $result;
    var $result_header;
    var $result_body;
    var $result_status_code;

    var $lastTransferSpeed;

    var $bind_host;

    var $error = array();
    var $warn = array();
    var $query_cache = array();

    var $doFollowLocationHeader = TRUE;
    var $redirectURL;

    var $extra_headers = array();

    /**
     * Create server "connection".
     *
     */
    function connect($host, $port = '' )
    {
        if (!is_numeric($port))
        {
            $port = 80;
        }

        $this->remote_host = $host;
        $this->remote_port = $port;
    }

    function bind( $ip = '' )
    {
        if ( $ip == '' )
        {
            $ip = $_SERVER['SERVER_ADDR'];
        }

        $this->bind_host = $ip;
    }

    /**
     * Change the method being used to communicate.
     *
     * @param string|null request method. supports GET, POST, and HEAD. default is GET
     */
    function set_method( $method = 'GET' )
    {
        $this->method = strtoupper($method);
    }

    /**
     * Specify a username and password.
     *
     * @param string|null username. defualt is null
     * @param string|null password. defualt is null
     */
    function set_login( $uname = '', $passwd = '' )
    {
        if ( strlen($uname) > 0 )
        {
            $this->remote_uname = $uname;
        }

        if ( strlen($passwd) > 0 )
        {
            $this->remote_passwd = $passwd;
        }

    }

    /**
     * Query the server
     *
     * @param string containing properly formatted server API. See DA API docs and examples. Http:// URLs O.K. too.
     * @param string|array query to pass to url
     * @param int if connection KB/s drops below value here, will drop connection
     */
    function query( $request, $content = '', $doSpeedCheck = 0 )
    {
        $this->error = $this->warn = array();
        $this->result_status_code = NULL;

        // is our request a http:// ... ?
        if (preg_match('!^http://!i',$request))
        {
            $location = parse_url($request);
            $this->connect($location['host'],$location['port']);
            $this->set_login($location['user'],$location['pass']);
            
            $request = $location['path'];
            $content = $location['query'];

            if ( strlen($request) < 1 )
            {
                $request = '/';
            }

        }

        $array_headers = array(
            'User-Agent' => "HTTPSocket/$this->version",
            'Host' => ( $this->remote_port == 80 ? $this->remote_host : "$this->remote_host:$this->remote_port" ),
            'Accept' => '*/*',
            'Connection' => 'Close' );

        foreach ( $this->extra_headers as $key => $value )
        {
            $array_headers[$key] = $value;
        }

        $this->result = $this->result_header = $this->result_body = '';

        // was content sent as an array? if so, turn it into a string
        if (is_array($content))
        {
            $pairs = array();

            foreach ( $content as $key => $value )
            {
                $pairs[] = "$key=".urlencode($value);
            }

            $content = join('&',$pairs);
            unset($pairs);
        }

        $OK = TRUE;

        // instance connection
        if ($this->bind_host)
        {
            $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
            socket_bind($socket,$this->bind_host);

            if (!@socket_connect($socket,$this->remote_host,$this->remote_port))
            {
                $OK = FALSE;
            }

        }
        else
        {
            $socket = @fsockopen( $this->remote_host, $this->remote_port, $sock_errno, $sock_errstr, 10 );
        }

        if ( !$socket || !$OK )
        {
            $this->error[] = "Can't create socket connection to $this->remote_host:$this->remote_port.";
            return 0;
        }

        // if we have a username and password, add the header
        if ( isset($this->remote_uname) && isset($this->remote_passwd) )
        {
            $array_headers['Authorization'] = 'Basic '.base64_encode("$this->remote_uname:$this->remote_passwd");
        }

        // for DA skins: if $this->remote_passwd is NULL, try to use the login key system
        if ( isset($this->remote_uname) && $this->remote_passwd == NULL )
        {
            $array_headers['Cookie'] = "session={$_SERVER['SESSION_ID']}; key={$_SERVER['SESSION_KEY']}";
        }

        // if method is POST, add content length & type headers
        if ( $this->method == 'POST' )
        {
            $array_headers['Content-type'] = 'application/x-www-form-urlencoded';
            $array_headers['Content-length'] = strlen($content);
        }
        // else method is GET or HEAD. we don't support anything else right now.
        else
        {
            if ($content)
            {
                $request .= "?$content";
            }
        }

        // prepare query
        $query = "$this->method $request HTTP/1.0\r\n";
        foreach ( $array_headers as $key => $value )
        {
            $query .= "$key: $value\r\n";
        }
        $query .= "\r\n";

        // if POST we need to append our content
        if ( $this->method == 'POST' && $content )
        {
            $query .= "$content\r\n\r\n";
        }

        // query connection
        if ($this->bind_host)
        {
            socket_write($socket,$query);

            // now load results
            while ( $out = socket_read($socket,2048) )
            {
                $this->result .= $out;
            }
        }
        else
        {
            fwrite( $socket, $query, strlen($query) );

            // now load results
            $this->lastTransferSpeed = 0;
            $status = socket_get_status($socket);
            $startTime = time();
            $length = 0;
            $prevSecond = 0;
            while ( !feof($socket) && !$status['timed_out'] )
            {
                $chunk = fgets($socket,1024);
                $length += strlen($chunk);
                $this->result .= $chunk;

                $elapsedTime = time() - $startTime;

                if ( $elapsedTime > 0 )
                {
                    $this->lastTransferSpeed = ($length/1024)/$elapsedTime;
                }

                if ( $doSpeedCheck > 0 && $elapsedTime > 5 && $this->lastTransferSpeed < $doSpeedCheck )
                {
                    $this->warn[] = "kB/s for last 5 seconds is below 50 kB/s (~".( ($length/1024)/$elapsedTime )."), dropping connection...";
                    $this->result_status_code = 503;
                    break;
                }

            }

            if ( $this->lastTransferSpeed == 0 )
            {
                $this->lastTransferSpeed = $length/1024;
            }

        }
        
        list($this->result_header,$this->result_body) = split("\r\n\r\n",$this->result,2);

        if ($this->bind_host)
        {
            socket_close($socket);
        }
        else
        {
            fclose($socket);
        }

        $this->query_cache[] = $query;


        $headers = $this->fetch_header();

        // what return status did we get?
        if (!$this->result_status_code)
        {
            preg_match("#HTTP/1\.. (\d+)#",$headers[0],$matches);
            $this->result_status_code = $matches[1];
        }

        // did we get the full file?
        if ( !empty($headers['content-length']) && $headers['content-length'] != strlen($this->result_body) )
        {
            $this->result_status_code = 206;
        }

        // now, if we're being passed a location header, should we follow it?
        if ($this->doFollowLocationHeader)
        {
            if (isset($headers['location']))
            {
				if ($headers['location'])
            	{
                	$this->redirectURL = $headers['location'];
                	$this->query($headers['location']);
				}
            }
        }
        
    }

    function getTransferSpeed()
    {
        return $this->lastTransferSpeed;
    }

    /**
     * The quick way to get a URL's content :)
     *
     * @param string URL
     * @param boolean return as array? (like PHP's file() command)
     * @return string result body
     */
    function get($location, $asArray = FALSE )
    {
        $this->query($location);

        if ( $this->get_status_code() == 200 )
        {
            if ($asArray)
            {
                return split("\n",$this->fetch_body());
            }

            return $this->fetch_body();
        }

        return FALSE;
    }

    /**
     * Returns the last status code.
     * 200 = OK;
     * 403 = FORBIDDEN;
     * etc.
     *
     * @return int status code
     */
    function get_status_code()
    {
        return $this->result_status_code;
    }

    /**
     * Adds a header, sent with the next query.
     *
     * @param string header name
     * @param string header value
     */
    function add_header($key,$value)
    {
        $this->extra_headers[$key] = $value;
    }

    /**
     * Clears any extra headers.
     *
     */
    function clear_headers()
    {
        $this->extra_headers = array();
    }

    /**
     * Return the result of a query.
     *
     * @return string result
     */
    function fetch_result()
    {
        return $this->result;
    }

    /**
     * Return the header of result (stuff before body).
     *
     * @param string (optional) header to return
     * @return array result header
     */
    function fetch_header( $header = '' )
    {
        $array_headers = split("\r\n",$this->result_header);
        
        $array_return = array( 0 => $array_headers[0] );
        unset($array_headers[0]);

        foreach ( $array_headers as $pair )
        {
            list($key,$value) = split(": ",$pair,2);
            $array_return[strtolower($key)] = $value;
        }

        if ( $header != '' )
        {
            return $array_return[strtolower($header)];
        }

        return $array_return;
    }

    /**
     * Return the body of result (stuff after header).
     *
     * @return string result body
     */
    function fetch_body()
    {
        return $this->result_body;
    }

    /**
     * Return parsed body in array format.
     *
     * @return array result parsed
     */
    function fetch_parsed_body()
    {
        parse_str($this->result_body,$x);
        return $x;
    }
	

}
?>
 
Last edited:
Back
Top