<?php
/*
dv at josheli.com
3/4/2004

What it does:
It will request cpanel make full backups of all accounts under a reseller.
It uses cURL, optionally over SSL.

How it works:
Reads all accounts (domain, cpanel and username specifically) from the listaccts page in WHM
Uses cUrl over SSL to call the dofullbackup script of cpanel for each account, using the
account's username and the reseller's password

This script doesn't require cron, but could use it. 
Cron for Windows:
http://www.kalab.com/freeware/cron/cron.htm

Instructions:
1. Make sure you have the curl extension for PHP available
2. Modify "config" variables below, to suit
3. From the command prompt:
    >php bkup_full.php
4. ([Or] Optionally) Set up a cron job to call this script
5. If you're going to have it ftp somewhere, make sure that server is setup correctly
6. Since it could take several minutes to generate the backup and ftp it, 
   and you can't have this request script just waiting around trying to 
   figure out if the backup/ftp cycle is complete, it might be beneficial 
   to have another script check for completion, and delete the generated 
   backup if there was success.

*/

/*** BEGIN CONFIG ***/

$reseller 'www.reseller.com';//your reseller url
$whmUser 'whmuser';//your web host manager user name
$whmPass 'whmpass';//your web host manager password
$bkUpReseller false;//backup the reseller account also? (it's not in the listaccts page)
$resellerCpTheme 'bluelagoon';//if you want to back up reseller, we need the reseller cpanel theme

/*
Destination for the backup...

$destType = 'homedir';// Home Directory
$destType = 'ftp';// Remote FTP Server
$destType = 'passiveftp'; //Remove FTP Server (Passive mode transfer)
*/
$destType 'ftp';//^^^
$destServer 'ftp.someftpserver.com';//only if $destServer = 'ftp' or 'passiveftp'
$destUser 'ftpuser';//only if $destServer = 'ftp' or 'passiveftp'
$destPass 'ftppass';//only if $destServer = 'ftp' or 'passiveftp'
$destEmail '';//optional; cpanel will send an email when generation is complete

$logType 'echo';//output a log to 'file' or 'echo' or 'none'(no log)
$logFileName 'bkup_full_log.txt';//can include a path too; only makes sense if $logType = 'file'
$useSsl false;//if true, requires SSL on your site, or modify this script to use the shared SSL; this hasn't really been tested

/*
A comma-separated list of domain names to backup;
Leave blank to backup all domains found in reseller WHM
If not blank, ONLY the domains listed will be backed up.
If listed, the domains must be listed EXACTLY like they appear on the
list accounts page in WHM, i.e. usually without 'www.'
$domains = 'example1.com,example2.net';
*/
$domains '';

/*** END CONFIG ***/

/*** BEGIN MAIN ***/
set_time_limit(0);
$time_start getMicroTime();

if (!
extension_loaded('curl')) {
  
dl('php_curl.' .PHP_SHLIB_SUFFIX) or die("Could not load curl extension");
}

if(
$useSsl) {
  
$protocol 'https://';
  
$cpPort '2083';
  
$whmPort '2087';
  
writeLog("Using SSL.\n");
}
else {
  
$protocol 'http://';
  
$cpPort '2082';
  
$whmPort '2086';
  
writeLog("Not using SSL.\n");


$domains trim($domains);
if(!empty(
$domains)){
  
$chkDoms true;
  
$domains explode(',',$domains);
  foreach(
$domains as $d){
    
$domains[] = trim($d);
  }
}
else {
  
$chkDoms false;
  
$domains = array();
}
//$postFields = urlencode("dest=$destType&server=$destServer&user=$destPass&pass=$destPass&email=$destEmail");
$postFields '';
$postArray = array();
$postArray['dest'] = $destType;
$postArray['server'] = $destServer;
$postArray['user'] = $destUser;
$postArray['pass'] = $destPass;
$postArray['email'] = $destEmail;

$thingy '';
foreach (
$postArray as $k=>$v)
{
  
$thingy.= "$k=".utf8_encode($v).'&';
}
$postFields substr($thingy,0,-1);


//get the WHM 'list accounts' page
writeLog("Retrieving WHM accounts page...\n");
$acctsPage getByCurl("$protocol$reseller:$whmPort/scripts2/listaccts?viewall=1",$whmUser,$whmPass);
//get each accounts table row
$int2 preg_match_all("/<tr class=(?:tdshade2|tdshade1)>(.*?)<\/tr>/is"$acctsPage$matches);

$accounts = array();
if(
$int2 && is_array($matches[1])) {
  
writeLog("Parsing accounts...\n");
  foreach(
$matches[1] as $match) {

    
$accDom '';
    
$accUser '';
    
$accTheme '';
    
$r '';
    
$fullUrl '';

    
$account explode('</td><td>',$match);
    
$accDom strip_tags(trim($account[0]));//domain
    
if($chkDoms)
      if(!
in_array($accDom,$domains)) continue;
    
$accUser strip_tags(trim($account[2]));//username
    
$accTheme strip_tags(trim($account[9]));//cpanel theme
    
    
$fullUrl "$protocol$accDom:$cpPort/frontend/$accTheme/backup/dofullbackup.html";
    
writeLog("Requesting backup of $accDom...\n");
    
$r =& getByCurl($fullUrl,$accUser,$whmPass,array('CURLOPT_POST'=>$postFields));
    if(
$r === false){
      
writeLog("Backup request of $accDom caused an unknown error.\n");
    }
    else {
      
writeLog("Backup request of $accDom complete.\n");
    }
    
//writeLog("\n\n--$accDom--\n\n$r\n\n------\n\n");
  
}
}

if(
$bkUpReseller){
  
$fullUrl "$protocol$reseller:$cpPort/frontend/$resellerCpTheme/backup/dofullbackup.html";
  
writeLog("Requesting backup of $reseller...\n");
  
$r =& getByCurl($fullUrl,$accUser,$whmPass,array('CURLOPT_POST'=>$postFields));
}

$time_end getMicroTime();
$time $time_end $time_start;
writeLog("Elapsed time: ".round($time,2)." seconds.\n");

/*** BEGIN FUNCTIONS ***/

function getByCurl($url$user ''$pass '',$extra '') {
  global 
$useSsl;

  
$ch curl_init();
  
//tells curl to save result in a variable instead of outputing to page
  
curl_setopt($chCURLOPT_RETURNTRANSFER1);
  
curl_setopt($chCURLOPT_URL$url);  
  
curl_setopt($chCURLOPT_USERPWD"$user:$pass");
  
curl_setopt ($chCURLOPT_COOKIEJAR'./cookie.txt');
  
curl_setopt ($chCURLOPT_FOLLOWLOCATION,1);
  if(!empty(
$extra) && is_array($extra)){
    foreach(
$extra as $opt=>$val){
      switch(
$opt){
        case 
'CURLOPT_REFERER':
          
curl_setopt($ch,CURLOPT_REFERER,$val);
        break;
        case 
'CURLOPT_POST':
        case 
'CURLOPT_POSTFIELDS':
          
curl_setopt($ch,CURLOPT_POST,1);
          
curl_setopt($ch,CURLOPT_POSTFIELDS,$val);
        break;
      }
    }
  }
  if(
$useSsl){
    
curl_setopt ($chCURLOPT_SSL_VERIFYPEER0);
    
curl_setopt ($chCURLOPT_SSL_VERIFYHOST0);
  }
  
$result curl_exec($ch);
  
curl_close($ch);

  return 
$result;
}

function 
writeLog($entry) {
  global 
$logType,$logFileName;

  
$method strtolower($logType);

  
$entry date('r').' - '.$entry;
  
  if(
$method == 'file') {
    
$fp fopen($logFileName,'ab');
  }
  elseif(
$method == 'echo'){
    if(isset(
$_SERVER['REQUEST_METHOD'])) {
      echo 
nl2br($entry);//browser
      
flush();
      return;
    }
    else {
      
$fp STDOUT;//cli
    
}
  }
  else {
    return;
  }
  
  
fwrite($fp$entry);

  if(
$method == 'file')
    
fclose($fp);

  return;
}

function 
getMicroTime(){
  list(
$usec$sec) = explode(" ",microtime());
  return ((float)
$usec + (float)$sec);
}

?>