The Community Forums

Interact with an entire community of cPanel & WHM users!
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Direct API binary usage.

Discussion in 'cPanel Developers' started by charsleysa, Feb 2, 2012.

  1. charsleysa

    charsleysa Active Member

    Joined:
    Jul 18, 2011
    Messages:
    41
    Likes Received:
    0
    Trophy Points:
    6
    Location:
    Palmerston North, New Zealand
    cPanel Access Level:
    Root Administrator
    Hello Forum

    I have just finished testing out the JSON API script I wrote basing it off the XML API script.
    I changed it so if only used JSON API and that it would access the xml-api binary itself instead
    of going through authentication and http packets.

    My query is if there is any real security issue when using this script local-only (so not outside access)?

    I would really like to use it as I was able to get a simple 'listresellers' query down to 8 milliseconds,
    even though every time a query is run the server load spikes just a little which is fine by me.

    Regards
    Stefan Andres Charsley
     
  2. KostonConsulting

    KostonConsulting Well-Known Member

    Joined:
    Jun 17, 2010
    Messages:
    255
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    San Francisco, CA
    cPanel Access Level:
    Root Administrator
    The XML API binary is root owned so there's no issues with other users gaining access to it:

    -rwx------ 1 root root 32650752 Feb 1 04:12 xml-api*


    Unless you're using privilege escalation to call the binary, you should be safe.
     
  3. charsleysa

    charsleysa Active Member

    Joined:
    Jul 18, 2011
    Messages:
    41
    Likes Received:
    0
    Trophy Points:
    6
    Location:
    Palmerston North, New Zealand
    cPanel Access Level:
    Root Administrator
    Thanks!

    Now my only problem is figuring out why PHP doesn't want to pipe the variables to the binary.
    I can successfully do it in a ConfigServer Explorer when I use the test command:

    echo -ne "reseller=root" | ./xml-api -json ./resellerstats

    but when I try to execute the command from PHP, the API returns a failed request.

    stdClass Object ( [result] => stdClass Object ( [reseller] => [status] => 0 [statusmsg] => Reseller Does Not Exist ) )

    I have tried everything I can think of!!
    Its driving me nuts!!
    If anyone has any ideas I would gladly try them!
     
  4. charsleysa

    charsleysa Active Member

    Joined:
    Jul 18, 2011
    Messages:
    41
    Likes Received:
    0
    Trophy Points:
    6
    Location:
    Palmerston North, New Zealand
    cPanel Access Level:
    Root Administrator
    I'v copied the code below to show you how I'v tried to get it working.
    This was just one way I tried it so please don't assume I haven't tried any other way.
    I hope this helps someone figure out how to pipe the variables to the binary.

    Code:
    <?php
    /**
    * The JSON-API class
    *
    * The JSON-API class allows for easy execution of cPanel JSON-API calls.  The goal of this script is to execute 
    * JSON-API functions directly from the api binary therefore incresing response time.  This class relies on PHP5.
    *
    * Making Calls with this class are done in the following steps:
    *
    * 1.) Instaniating the class:
    * $jsonapi = new jsonapi();
    * 
    * 2.) Execute a function
    * $jsonapi->listaccts();
    *
    * @category Cpanel
    * @package jsonapi
    * @copyright 2012 ROCK Software
    * @license GNU General Public License V3
    * @version Release: 1.0.0
    * @since Class available since release 1.0.0
    **/
    
    class jsonapi {
    	
    	// should debugging statements be printed?
    	private $debug			= false;
    	
    	// output that should be given by the json-api
    	private $output		=	'json';
    	
    	/**
    	* Instantiate the JSON-API Object
    	*
    	* @return jsonapi object
    	*/
    	public function __construct() {}
    	
    	/**
    	* Accessor Functions
    	**/
    	/**
    	* Return whether the debug option is set within the object
    	*
    	* @return boolean
    	* @see set_debug()
    	*/
    	public function get_debug() {
    		return $this->debug;
    	}
    	
    	/**
    	* Turn on debug mode
    	*
    	* Enabling this option will cause this script to print debug information such as
    	* the queries made, the response JSON and other such pertinent information.
    	* Calling this function without any parameters will enable debug mode.
    	*
    	* @param bool $debug turn on or off debug mode
    	* @see get_debug()
    	*/
    	public function set_debug( $debug = 1 ) {
    		$this->debug = $debug;
    	}
    	
    	/** 
    	* Return what format calls with be returned in
    	*
    	* This function will return the currently set output format
    	* @see set_output()
    	* @return string
    	*/
    	public function get_output() {
    		return $this->output;
    	}
    
    	/**
    	* Set the output format for call functions
    	*
    	* This class is capable of returning data in numerous formats including:
    	*   - Decoded JSON Object
    	*	- Associative Arrays
    	*
    	* These can be set by passing this class any of the following values:
    	*   - json - Return Decoded JSON Object
    	*   - array - Return Associative Array
    	*
    	* Passing any value other than these to this class will cause an Exception to be thrown.
    	* @param string $output the output type to be set
    	* @see get_output()
    	*/
    	public function set_output( $output ) {
    		if ( $output != 'json' && $output != 'array' ) {
    				throw new Exception('json and array are the only allowed values for set_output');
    		}
    		$this->output = $output;
    	}
    	
     	/*	
    	*	Query Functions
    	*	--
    	*	This is where the actual calling of the JSON-API, building API1 & API2 calls happens
    	*/
    	
    	/**
    	* Perform an JSON-API Query
    	*
    	* This function will perform an JSON-API Query and return the specified output format of the call being made
    	*
    	* @param string $function The JSON-API call to execute
    	* @param array $vars An associative array of the parameters to be passed to the JSON-API Calls
    	* @return mixed
    	*/
    	public function jsonapi_query( $function, $vars = array() ) {
    		
    		// Check to make sure all the data needed to perform the query is in place
    		if (!$function) {
    			throw new Exception('jsonapi_query() requires a function to be passed to it');
    		}
    
    		// Build the query:
    		$args = http_build_query($vars, '', '&');
    		
    		// print out the query if debug mode is enabled.
    		if ($this->debug) {
    			error_log("FUNCTION: " . $function);
    			error_log("ARGUMENTS: " . $args);
    		}
    		
    		// Open process
    		$args = escapeshellarg($args);
    		$function = escapeshellarg($function);
    		$response = `echo -ne "$args" | /usr/local/cpanel/whostmgr/bin/xml-api -json ./$function`;
    				
    		/*
    		*	Post-Query Block
    		* Handle response, return proper data types, debug, etc
    		*/
    		
    		// Correct the response by stripping out the first 3 lines
    		$response = str_replace("HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n", '', $response);
    		
    		// print out the response if debug mode is enabled.
    		if ($this->debug) {
    			error_log("RESPONSE:\n " . $response);
    		}
    		
    		// parse the response and create an associative array
    		if ($this->output == 'json')
    		{
    			$response = json_decode($response, false);
    		}
    		else if ($this->output == 'array')
    		{
    			$response = json_decode($response, true);
    		}
    		
    		return $response;
    	}
    	
    	/**
    	* Call an API1 function
    	*
    	* This function allows you to call API1 from within the JSON-API,  This allowes a user to peform actions
    	* such as adding ftp accounts, etc
    	*
    	* @param string $user The username of the account to perform API1 actions on
    	* @param string $module The module of the API1 call to use
    	* @param string $function The function of the API1 call
    	* @param array $args The arguments for the API1 function, this should be a non-associative array
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/CallingApiOne API1 Call documentation
    	* @link http://docs.cpanel.net/twiki/bin/view/ApiDocs/Api1/WebHome API1 Function Reference
    	*/
    	public function api1_query($user, $module, $function, $args = array() ) {
    		if ( !isset($module) || !isset($function) || !isset($user) ) {
    			error_log("api1_query requires that a module and function are passed to it");
    			return false;
    		}
    		
    		if (!is_array($args)) {
    			error_log('api1_query requires that it is passed an array as the 4th parameter');
    			return false;
    		}
    		
    		$cpuser = 'cpanel_jsonapi_user';
    		$module_type = 'cpanel_jsonapi_module';
    		$func_type = 'cpanel_jsonapi_func';
    		$api_type = 'cpanel_jsonapi_apiversion';
    		
    		$call = array(
    				$cpuser => $user,
    				$module_type => $module,
    				$func_type => $function,
    				$api_type => '1'
    			);
    		for ($int = 0; $int < count($args);  $int++) {
    			$call['arg-' . $int] = $args[$int];
    		}
    		return $this->jsonapi_query('cpanel', $call);
    	}
    	
    	/**
    	* Call an API2 Function
    	*
    	* This function allows you to call an API2 function, this is the modern API for cPanel and should be used in preference over
    	* API1 when possible
    	*
    	* @param string $user The username of the account to perform API2 actions on
    	* @param string $module The module of the API2 call to use
    	* @param string $function The function of the API2 call
    	* @param array $args An associative array containing the arguments for the API2 call
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/CallingApiTwo API2 Call documentation
    	* @link http://docs.cpanel.net/twiki/bin/view/ApiDocs/Api1/WebHome API2 Function Reference
    	*/ 
    	
    	public function api2_query($user, $module, $function, $args = array()) {
    		if (!isset($user) || !isset($module) || !isset($function) ) {
    			error_log("api2_query requires that a username, module and function are passed to it");
    			return false;
    		}
    		if (!is_array($args)) {
    			error_log("api2_query requires that an array is passed to it as the 4th parameter");
    			return false;
    		}
    		
    		$cpuser = 'cpanel_jsonapi_user';
    		$module_type = 'cpanel_jsonapi_module';
    		$func_type = 'cpanel_jsonapi_func';
    		$api_type = 'cpanel_jsonapi_apiversion';
    		
    		$args[$cpuser] = $user;
    		$args[$module_type] = $module;
    		$args[$func_type] = $function;
    		$args[$api_type] = '2';
    		return $this->jsonapi_query('cpanel', $args);
    	}
    	
    	####
    	#  JSON API Functions
    	####
    
    	/**
    	* Return a list of available JSON-API calls
    	*
    	* This function will return an array containing all applications available within the JSON-API
    	*
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ListAvailableCalls JSON API Call documentation
    	*/
    	public function applist() {
    		return $this->jsonapi_query('applist');
    	}
    
    	####
    	# Account functions
    	####
    
    	/**
    	* Create a cPanel Account
    	*
    	* This function will allow one to create an account, the $acctconf parameter requires that the follow 
    	* three associations are defined:
    	*	- username
    	*	- password
    	*	- domain
    	*
    	* Failure to prive these will cause an error to be logged.  Any other key/value pairs as defined by the createaccount call 
    	* documentation are allowed parameters for this call.
    	* 
    	* @param array $acctconf
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/CreateAccount
    	*/
    	
    	public function createacct($acctconf) {
    		if (!is_array($acctconf)) {
    			error_log("createacct requires that first parameter passed to it is an array");
    			return false;
    		}
    		if (!isset($acctconf['username']) || !isset($acctconf['password']) || !isset($acctconf['domain'])) {
    			error_log("createacct requires that username, password & domain elements are in the array passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('createacct', $acctconf);
    	}
    
    	/**
    	* Change a cPanel Account's Password
    	* 
    	* This function will allow you to change the password of a cpanel account
    	*
    	* @param string $username The username to change the password of
    	* @param string $pass The new password for the cPanel Account
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ChangePassword
    	*/
    	public function passwd($username, $pass){
    		if (!isset($username) || !isset($pass)) {
    			error_log("passwd requires that an username and password are passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('passwd', array('user' => $username, 'pass' => $pass));
    	}
    
    	/**
    	* Limit an account's monthly bandwidth usage
    	*
    	* This function will set an account's bandwidth limit.
    	*
    	* @param string $username The username of the cPanel account to modify
    	* @param int $bwlimit The new bandwidth limit in megabytes
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/LimitBandwidth
    	*/
    	public function limitbw($username, $bwlimit) {
    		if (!isset($username) || !isset($bwlimit)) {
    			error_log("limitbw requires that an username and bwlimit are passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('limitbw', array('user' => $username, 'bwlimit' => $bwlimit));
    	}
    
    	/**
    	* List accounts on Server
    	*
    	* This call will return a list of account on a server, either no parameters or both parameters may be passed to this function.
    	*
    	* @param string $searchtype Type of account search to use, allowed values: domain, owner, user, ip or package
    	* @param string $search the string to search against
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ListAccounts
    	*/
    	public function listaccts($searchtype = null, $search = null) {
    		if ($search) {
    			return $this->jsonapi_query('listaccts', array('searchtype' => $searchtype, 'search' => $search ));
    		}
    		return $this->jsonapi_query('listaccts');
    	}
    
    	/**
    	* Modify a cPanel account
    	*
    	* This call will allow you to change limitations and information about an account.  See the JSON API call documentation for a list of
    	* acceptable values for args.
    	*
    	* @param string $username The username to modify
    	* @param array $args the new values for the modified account (see documentation)
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ModifyAccount
    	*/
    	public function modifyacct($username, $args = array()) {
    		if (!isset($username)) {
    			error_log("modifyacct requires that username is passed to it");
    			return false;
    		}
    		$args['user'] = $username;
    		if (sizeof($args) < 2) {
    			error_log("modifyacct requires that at least one attribute is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('modifyacct', $args);
    	}
    
    	/**
    	* Edit a cPanel Account's Quota
    	*
    	* This call will allow you to change a cPanel account's quota
    	*
    	* @param string $username The username of the account to modify the quota.
    	* @param int $quota the new quota in megabytes
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/EditQuota
    	*/
    	public function editquota($username, $quota) {
    		if (!isset($username) || !isset($quota)) {
    			error_log("editquota requires that an username and quota are passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('editquota', array('user' => $username, 'quota' => $quota));
    	}
    
    	/**
    	* Return a summary of the account's information
    	*
    	* This call will return a brief report of information about an account, such as:
    	*	- Disk Limit
    	*	- Disk Used
    	*	- Domain
    	*	- Account Email
    	*	- Theme
    	* 	- Start Data
    	*
    	* Please see the JSON API Call documentation for more information on what is returned by this call
    	*
    	* @param string $username The username to retrieve a summary of
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ShowAccountInformation
    	*/
    	public function accountsummary($username) {
    		if (!isset($username)) {
    			error_log("accountsummary requires that an username is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('accountsummary', array('user' => $username));
    	}
    
    	/**
    	* Suspend a User's Account
    	*
    	* This function will suspend the specified cPanel users account.
    	* The $reason parameter is optional, but can contain a string of any length
    	*
    	* @param string $username The username to suspend
    	* @param string $reason The reason for the suspension
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SuspendAccount
    	*/
    	public function suspendacct($username, $reason = null) {
    		if (!isset($username)) {
    			error_log("suspendacct requires that an username is passed to it");
    			return false;
    		}
    		if ($reason) {
    			return $this->jsonapi_query('suspendacct', array('user' => $username, 'reason' => $reason ));
    		}
    		return $this->jsonapi_query('suspendacct', array('user' => $username));
    	}
    
    	/**
    	* List suspended accounts on a server
    	*
    	* This function will return an array containing all the suspended accounts on a server
    	*
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ListSuspended
    	*/
    	public function listsuspended() {
    		return $this->jsonapi_query('listsuspended');
    	}
    
    	/**
    	* Remove an Account
    	*
    	* This JSON API call will remove an account on the server
    	* The $keepdns parameter is optional, when enabled this will leave the DNS zone on the server
    	*
    	* @param string $username The usename to delete
    	* @param bool $keepdns When pass a true value, the DNS zone will be retained
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/TerminateAccount
    	*/ 
    	public function removeacct($username, $keepdns = false) {
    		if (!isset($username)) {
    			error_log("removeacct requires that a username is passed to it");
    			return false;
    		}
    		if ($keepdns) {
    			return $this->jsonapi_query('removeacct', array('user' => $username, 'keepdns' => '1'));
    		}
    		return $this->jsonapi_query('removeacct', array('user' => $username));
    	}
    
    	/**
    	* Unsuspend an Account
    	*
    	* This JSON API call will unsuspend an account
    	*
    	* @param string $username The username to unsuspend
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/UnsuspendAcount
     	*/
    	public function unsuspendacct($username){
    		if (!isset($username)) {
    			error_log("unsuspendacct requires that a username is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('unsuspendacct', array('user' => $username));
    	}
    
    	/**
    	* Change an Account's Package
    	*
    	* This JSON API will change the package associated account.
    	*
    	* @param string $username the username to change the package of
    	* @param string $pkg The package to change the account to.
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ChangePackage
    	*/ 
    	public function changepackage($username, $pkg) {
    		if (!isset($username) || !isset($pkg)) {
    			error_log("changepackage requires that username and pkg are passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('changepackage', array('user' => $username, 'pkg' => $pkg));
    	}
    
    	/**
    	* Return the privileges a reseller has in WHM
    	*
    	* This will return a list of the privileges that a reseller has to WHM
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ViewPrivileges
    	*/
    	public function myprivs() {
    		return $this->jsonapi_query('myprivs');
    	}
    
    
    	/**
    	* Display Data about a Virtual Host
    	* 
    	* This function will return information about a specific domain.  This data is essentially a representation of the data
    	* Contained in the httpd.conf VirtualHost for the domain.
    	*
    	* @return mixed
    	* @param string $domain The domain to fetch information for
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/DomainUserData
    	*/
    
    	public function domainuserdata( $domain ) {
    		if (!isset( $domain ) ) {
    			error_log("domainuserdata requires that domain is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query("domainuserdata", array( 'domain' => $domain ) );
    	}
    
    	/**
    	* Change a site's IP Address
    	* 
    	* This function will allow you to change the IP address that a domain listens on.
    	* In order to properly call this function Either $user or $domain parameters must be defined
    	* @param string $ip The $ip address to change the account or domain to
    	* @param string $user The username to change the IP of
    	* @param string $domain The domain to change the IP of
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SetSiteIp
    	*/
    	public function setsiteip ( $ip, $user = null, $domain = null ) {
    
    		if ( !isset($ip) ) {
    			error_log("setsiteip requires that ip is passed to it");
    			return false;
    		}
    
    		if ( $user == null && $domain == null ) {
    			error_log("setsiteip requires that either domain or user is passed to it");
    			return false;
    		}
    
    		if ($user == null ) {
    			return $this->jsonapi_query( "setsiteip", array( "ip" => $ip, "domain" => $domain ) );
    		} else {
    			return $this->jsonapi_query( "setsiteip", array( "ip" => $ip, "user" => $user ) );
    		}
    	}
    
    	####
    	# DNS Functions
    	####
    
    	// This API function lets you create a DNS zone.
    	/**
    	* Add a DNS Zone
    	*
    	* This JSON API function will create a DNS Zone.  This will use the "standard" template when
    	* creating the zone.
    	*
    	* @param string $domain The DNS Domain that you wish to create a zone for
    	* @param string $ip The IP you want the domain to resolve to
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/AddDNSZone
    	*/
    	public function adddns($domain, $ip) {
    		if (!isset($domain) || !isset($ip)) {
    			error_log("adddns require that domain, ip are passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('adddns', array('domain' => $domain, 'ip' => $ip));
    	}
    
    	/**
    	* Add a record to a zone
    	*
    	* This will append a record to a DNS Zone.  The $args argument to this function 
    	* must be an associative array containing information about the DNS zone, please 
    	* see the for more info
    	*
    	* @param string $zone The DNS zone that you want to add the record to
    	* @param array $args Associative array representing the record to be added
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/AddZoneRecord
    	*/
    	public function addzonerecord( $zone, $args ) {
    		if (!is_array($args)) {
    			error_log("addzonerecord requires that $args passed to it is an array");
    			return;
    		}
    		
    		$args['zone'] = $zone;
    		return $this->jsonapi_query('addzonerecord', $args);
    	}
    
    	/**
    	* Edit a Zone Record
    	*
    	* This JSON API Function will allow you to edit an existing DNS Zone Record.
    	* This works by passing in the line number of the record you wish to edit.
    	* Line numbers can be retrieved with dumpzone()
    	*
    	* @param string $zone The zone to edit
    	* @param int $line The line number of the zone to edit
    	* @param array $args An associative array representing the zone record
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/EditZoneRecord
    	* @see dumpzone()
    	*/
    	
    	public function editzonerecord( $zone, $line, $args ) {
    		if (!is_array($args)) {
    			error_log("editzone requires that $args passed to it is an array");
    			return;
    		}
    		
    		$args['domain'] = $zone;
    		$args['Line'] = $line;
    		return $this->jsonapi_query('editzonerecord', $args);
    	}
    
    	/**
    	* Retrieve a DNS Record
    	*
    	* This function will return a data structure representing a DNS record, to 
    	* retrieve all lines see dumpzone.
    	* @param string $zone The zone that you want to retrieve a record from
    	* @param string $line The line of the zone that you want to retrieve
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/GetZoneRecord
    	*/
    	public function getzonerecord( $zone, $line ) {
    		return $this->jsonapi_query('getzonerecord', array( 'domain' => $zone, 'Line' => $line ) );
    	}
    
    	/**
    	* Remove a DNS Zone
    	*
    	* This function will remove a DNS Zone from the server
    	*
    	* @param string $domain The domain to be remove
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/DeleteDNSZone
    	*/
    	public function killdns($domain) {
    		if (!isset($domain)) {
    			error_log("killdns requires that domain is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('killdns', array('domain' => $domain));
    	}
    
    	/**
    	* Return a List of all DNS Zones on the server
    	* 
    	* This JSON API function will return an array containing all the DNS Zones on the server
    	*
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ListDNSZone
    	*/
    	public function listzones() {
    		return $this->jsonapi_query('listzones');
    	}
    
    	/**
    	* Return all records in a zone
    	*
    	* This function will return all records within a zone.
    	* @param string $domain The domain to return the records from.
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ListOneZone
    	* @see editdnsrecord()
    	* @see getdnsrecord()
    	*/
    	public function dumpzone($domain) {
    		if (!isset($domain)) {
    			error_log("dumpzone requires that a domain is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('dumpzone', array('domain' => $domain));
    	}
    	
    	/**
    	* Return a Nameserver's IP
    	*
    	* This function will return a nameserver's IP
    	*
    	* @param string $nameserver The nameserver to lookup
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/LookupIP
    	*/
    	public function lookupnsip($nameserver) {
    		if (!isset($nameserver)) {
    			error_log("lookupnsip requres that a nameserver is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('lookupnsip', array('nameserver' => $nameserver));
    	}
    
    	/**
    	* Remove a line from a zone
    	*
    	* This function will remove the specified line from a zone
    	* @param string $zone The zone to remove a line from
    	* @param int $line The line to remove from the zone
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/RemoveZone
    	*/
    	public function removezonerecord($zone, $line) {
    		if ( !isset($zone) || !isset($line) ) {
    			error_log("removezone record requires that a zone and line number is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('removezonerecord', array('zone' => $zone, 'Line' => $line) );
    	}
    	
    	/**
    	* Reset a zone
    	*
    	* This function will reset a zone removing all custom records.  Subdomain records will be readded by scanning the userdata datastore.
    	* @param string $domain the domain name of the zone to reset
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ResetZone
    	*/
    	public function resetzone($domain) {
    		if ( !isset($domain) ) {
    			error_log("resetzone requires that a domain name is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('resetzone', array('domain' => $domain));
    	}
    
    	####
    	# Package Functions
    	####
    
    	/**
    	* Add a new package
    	* 
    	* This function will allow you to add a new package
    	* This function should be passed an associative array containing elements that define package parameters.
    	* These variables map directly to the parameters for the XML-API Call, please refer to the link below for a complete 
    	* list of possible variable.  The "name" element is required.
    	* @param array $pkg an associative array containing package parameters
    	* @return mixed 
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/AddPackage
    	*/
    	public function addpkg($pkg) {
    		if (!isset($pkg['name'])) {
    			error_log("addpkg requires that name is defined in the array passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('addpkg', $pkg);
    	}
    
    	/**
    	* Remove a package
    	* 
    	* This function allow you to delete a package
    	* @param string $pkgname The package you wish to delete
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/DeletePackage
    	*/
    	public function killpkg($pkgname) {
    		if(!isset($pkgname)) {
    			error_log("killpkg requires that the package name is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('killpkg', array('pkg' => $pkgname));
    	}
    
    	/**
    	* Edit a package
    	*
    	* This function allows you to change a package's paremeters.  This is passed an associative array defining
    	* the parameters for the package.  The keys within this array map directly to the XML-API call, please see the link
    	* below for a list of possible keys within this package.  The name element is required.
    	* @param array $pkg An associative array containing new parameters for the package
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/EditPackage
    	*/
    	public function editpkg($pkg) {
    		if (!$isset($pkg['name'])) {
    			error_log("editpkg requires that name is defined in the array passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('editpkg', $pkg);
    	}
    
    	/**
    	* List Packages
    	*
    	* This function will list all packages available to the user
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ListPackages
    	*/
    	public function listpkgs() {
    		return $this->jsonapi_query('listpkgs');
    	}
    
    	####
    	# Reseller functions
    	####
    
    	/**
    	* Make a user a reseller
    	*
    	* This function will allow you to mark an account as having reseller privileges
    	* @param string $username The username of the account you wish to add reseller privileges to
    	* @param int $makeowner Boolean 1 or 0 defining whether the account should own itself or not
    	* @see setacls()
    	* @see setresellerlimits()
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/AddResellerPrivileges
    	*/
    	public function setupreseller($username, $makeowner = true) {
    		if (!isset($username)) {
    			error_log("setupreseller requires that username is passed to it");
    			return false;
    		}
    		if ($makeowner) {
    			return $this->jsonapi_query('setupreseller', array('user' => $username, 'makeowner' => '1'));
    		}
    		return $this->jsonapi_query('setupreseller', array('user' => $username, 'makeowner' => '0'));
    	}
    
    	/**
    	* Create a New ACL List
    	*
    	* This function allows you to create a new privilege set for reseller accounts.  This is passed an
    	* Associative Array containing the configuration information for this variable.  Please see the
    	* For more information.  "acllist" is a required element within this array
    	* @param array $acl an associative array describing the parameters for the ACL to be create
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/CreateResellerACLList
    	*/
    	public function saveacllist($acl) {
    		if (!isset($acl['acllist'])) {
    			error_log("saveacllist requires that acllist is defined in the array passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('saveacllist', $acl);
    	}
    
    	
    	/**
    	* List available saved ACLs
    	*
    	* This function will return a list of Saved ACLs for reseller accounts
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ListCurrentResellerACLLists
    	*/
    	public function listacls() {
    		return $this->jsonapi_query('listacls');
    	}
    
    	/**
    	* List Resellers
    	*
    	* This function will return a list of resellers on the server
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ListResellerAccounts
    	*/
    	public function listresellers() {
    		return $this->jsonapi_query('listresellers');
    	}
    
    	/**
    	* Get a reseller's statistics
    	*
    	* This function will return general information on a reseller and all it's account individually such as disk usage and bandwidth usage
    	*
    	* @param string $username The reseller to be checked
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ListResellersAccountsInformation
    	*/
    	public function resellerstats($username) {
    		if (!isset($username)) {
    			error_log("resellerstats requires that a username is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('resellerstats', array('reseller' => $username));
    	}
    
    	/**
    	* Remove Reseller Privileges
    	*
    	* This function will remove an account's reseller privileges, this does not remove the account.
    	*
    	* @param string $username The username to remove reseller privileges from
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/RemoveResellerPrivileges
    	*/
    	public function unsetupreseller($username) {
    		if (!isset($username)) {
    			error_log("unsetupreseller requires that a username is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('unsetupreseller', array('user' => $username));
    	}
    
    	/**
    	* Set a reseller's privileges
    	*
    	* This function will allow you to set what parts of WHM a reseller has access to.  This is passed an associative array
    	* containing the privleges that this reseller should have access to.  These map directly to the parameters passed to the JSON API Call
    	* Please view the for more information.  "reseller" is the only required element within this array
    	* @param array $acl An associative array containing all the ACL information for the reseller
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SetResellersACLList
    	*/
    	public function setacls($acl) {
    		if (!isset($acl['reseller'])) {
    			error_log("setacls requires that reseller is defined in the array passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('setacls', $acl);
    	}
    
    	/**
    	* Terminate a Reseller's Account
    	*
    	* This function will terminate a reseller's account and all accounts owned by the reseller
    	*
    	* @param string $reseller the name of the reseller to terminate
    	* @param boolean $terminatereseller Passing this as true will terminate the the reseller's account as well as all the accounts owned by the reseller
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/TerminateResellerandAccounts
    	*
    	**/
    	public function terminatereseller($reseller, $terminatereseller = true) {
    		if (!isset($reseller)) {
    			error_log("terminatereseller requires that username is passed to it");
    			return false;
    		}
    		$verify = 'I understand this will irrevocably remove all the accounts owned by the reseller ' . $reseller;
    		if ($terminatereseller) {
    			return $this->jsonapi_query('terminatereseller', array('reseller' => $reseller, 'terminatereseller' => '1', 'verify' => $verify));
    		}
    		return $this->jsonapi_query('terminatereseller', array('reseller' => $reseller, 'terminatereseller' => '0', 'verify' => $verify));
    	}
    
    	/**
    	* Set a reseller's dedicated IP addresses
    	*
    	* This function will set a reseller's dedicated IP addresses.  If an IP is not passed to this function, 
    	* it will reset the reseller to use the server's main shared IP address.
    	* @param string $user The username of the reseller to change dedicated IPs for
    	* @param string $ip The IP to assign to the  reseller, this can be a comma-seperated list of IPs to allow for multiple IP addresses
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SetResellerIps
    	*/
    	public function setresellerips($user, $ip = null) {
    		if (!isset($user) ) {
    			error_log("setresellerips requires that a username is passed to it");
    			return false;
    		}
    		$params = array("user" => $user);
    		if ( $ip != null ) {
    			$params['ip'] = $ip;
    		}
    		return $this->jsonapi_query('setresellerips',$params);
    	}
    	
    	/**
    	* Set Accounting Limits for a reseller account
    	*
    	* This function allows you to define limits for reseller accounts not included with in access control such as
    	* the number of accounts a reseller is allowed to create, the amount of disk space to use.
    	* This function is passed an associative array defining these limits, these map directly to the parameters for the JSON API
    	* Call, please refer to the for more information.  The only required parameters is "user"
    	*
    	* @param array $reseller_cfg An associative array containing configuration information for the specified reseller
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SetResellerLimits
    	*
    	*/
    	public function setresellerlimits( $reseller_cfg ) {
    		if ( !isset($reseller_cfg['user'] ) ) {
    			error_log("setresellerlimits requires that a user is defined in the array passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('setresellerlimits',$reseller_cfg);
    	}
    	
    	/**
    	* Set a reseller's main IP
    	*
    	* This function will allow you to set a reseller's main IP.  By default all accounts created by this reseller
    	* will be created on this IP
    	* @param string $reseller the username of the reseller to change the main IP of
    	* @param string $ip The ip you would like this reseller to create accounts on by default
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SetResellerMainIp
    	*/
    	public function setresellermainip($reseller, $ip) {
    		if ( !isset($reseller) || !isset($ip) ) {
    			error_log("setresellermainip requires that an reseller and ip are passed to it");
    			return false;
    		}
    		return $this->jsonapi_query("setresellermainip", array('user' => $reseller, 'ip' => $ip));
    	}
    
    	/**
    	* Set reseller package limits
    	*
    	* This function allows you to define which packages a reseller has access to use
    	* @param string $user The reseller you wish to define package limits for
    	* @param boolean $no_limit Whether or not you wish this reseller to have packages limits
    	* @param string $package if $no_limit is false, then the package you wish to modify privileges for
    	* @param boolean $allowed if $no_limit is false, then defines if the reseller should have access to the package or not
    	* @param int $number if $no_limit is false, then defines the number of account a reseller can create of a specific package
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SetResellerPkgLimit
    	*/
    	public function setresellerpackagelimits($user, $no_limit, $package = null, $allowed = null, $number = null) {
    		if (!isset($user) || !isset($no_limit) ) {
    			error_log("setresellerpackagelimits requires that a username and no_limit are passed to it by default");
    			return false;
    		}
    		if ($no_limit) {
    			return $this->jsonapi_query("setresellerpackagelimits", array( 'user' => $user, "no_limit" => '1') );
    		} else {
    			if ( is_null($package) || is_null($allowed) ) {
    				error_log('setresellerpackagelimits requires that package and allowed are passed to it if no_limit eq 0');
    				return false;
    			}
    			$params = array(
    				'user' => $user,
    				'no_limit' => '0',
    				'package' => $package
    			);
    			if ($allowed) {
    				$params['allowed'] = 1;
    			} else {
    				$params['allowed'] = 0;
    			}
    			if ( !is_null($number) ) {
    				$params['number'] = $number;
    			}
    			return $this->jsonapi_query('setresellerpackagelimits', $params);
    		}
    	}
    	
    	/**
    	* Suspend a reseller and all accounts owned by a reseller
    	*
    	* This function, when called will suspend a reseller account and all account owned by said reseller
    	* @param string $reseller The reseller account to be suspended
    	* @param string $reason (optional) The reason for suspending the reseller account
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SuspendReseller
    	*/
    	public function suspendreseller($reseller, $reason = null) {
    		if (!isset($reseller) ) { 
    			error_log("suspendreseller requires that the reseller's username is passed to it");
    			return false;
    		}
    		$params = array("user" => $reseller);
    		if ($reason) {
    			$params['reason'] = $reason;
    		}
    		return $this->jsonapi_query('suspendreseller', $params);
    	}
    	
    	
    	/**
    	* Unsuspend a Reseller Account
    	*
    	* This function will unsuspend a reseller account and all accounts owned by the reseller in question
    	* @param string $user The username of the reseller to be unsuspended
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/UnsuspendReseller
    	*/
    	public function unsuspendreseller($user) {
    		if (!isset($user) ) {
    			error_log("unsuspendreseller requires that a username is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('unsuspendreseller', array('user' => $user));
    	}
    	
    	/**
    	* Get the number of accounts owned by a reseller
    	*
    	* This function will return the number of accounts owned by a reseller account, along with information such as the number of active, suspended and accounting limits
    	* @param string $user The username of the reseller to get account information from
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/AcctCounts
    	*/
    	public function acctcounts($user) {
    		if (!isset($user)) {
    			error_log('acctcounts requires that a username is passed to it');
    			return false;
    		}
    		return $this->jsonapi_query('acctcounts', array('user' => $user) );
    	}
    	
    	/**
    	* Set a reseller's nameservers
    	*
    	* This function allows you to change the nameservers that account created by a specific reseller account will use.
    	* If this function is not passed a $nameservers parameter, it will reset the nameservers for the reseller to the servers's default
    	* @param string $user The username of the reseller account to grab reseller accounts from
    	* @param string $nameservers A comma seperate list of nameservers
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SetResellerNameservers
    	*/
    	public function setresellernameservers($user, $nameservers = null) {
    		if (!isset($user)) {
    			error_log("setresellernameservers requires that a username is passed to it");
    			return false;
    		}
    		$params = array('user' => $user);
    		if($nameservers) {
    			$params['nameservers'] = $nameservers;
    		}
    		return $this->jsonapi_query('setresellernameservers', $params);
    	}
    	
    	####
    	# Server information
    	####
    
    	/**
    	* Get a server's hostname
    	*
    	* This function will return a server's hostname
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/DisplayServerHostname
    	*/
    	public function gethostname() {
    		return $this->jsonapi_query('gethostname');
    	}
    
    	/**
    	* Get the version of cPanel running on the server
    	*
    	* This function will return the version of cPanel/WHM running on the remote system
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/DisplaycPanelWHMVersion
    	*/
    	public function version() {
    		return $this->jsonapi_query('version');
    	}
    
    
    	/**
    	* Get Load Average
    	*
    	* This function will return the loadavg of the remote system
    	*
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/LoadAvg
    	*/
    	public function loadavg() {
    		return $this->jsonapi_query('loadavg');
    	}
    
    	/**
    	* Get a list of languages on the remote system
    	*
    	* This function will return a list of available langauges for the cPanel interface
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/GetLangList
    	*
    	*/
    	public function getlanglist() {
    		return $this->jsonapi_query('getlanglist');
    	}
    
    	####
    	# Server administration
    	####
    
    	/**
    	* Reboot server
    	*
    	* This function will reboot the server
    	* @param boolean $force This will determine if the server should be given a graceful or forceful reboot
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/RebootServer
    	*/
    	public function reboot($force = false) {
    		if ($force) {
    			return $this->jsonapi_query('reboot', array('force' => '1'));
    		}
    		return $this->jsonapi_query('reboot');
    	}
    
    	/**
    	* Add an IP to a server
    	*
    	* This function will add an IP alias to your server
    	* @param string $ip The IP to be added
    	* @param string $netmask The netmask of the IP to be added
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/AddIPAddress
    	*/
    	public function addip($ip, $netmask) {
    		if (!isset($ip) || !isset($netmask)) {
    			error_log("addip requires that an IP address and Netmask are passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('addip', array('ip' => $ip, 'netmask' => $netmask));
    	}
    
    	// This function allows you to delete an IP address from your server.
    	/**
    	* Delete an IP from a server
    	*
    	* Remove an IP from the server
    	* @param string $ip The IP to remove
    	* @param string $ethernetdev The ethernet device that the IP is bound to
    	* @param bool $skipifshutdown Whether the function should remove the IP even if the ethernet interface is down
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/DeleteIPAddress
    	*/
    	public function delip($ip, $ethernetdev = null, $skipifshutdown = false) {
    		$args = array();
    		if (!isset($ip)) {
    			error_log("delip requires that an IP is defined in the array passed to it");
    			return false;
    		}
    		$args['ip'] = $ip;
    		if ($ethernetdev) {
    			$args['ethernetdev'] = $ethernetdev;
    		}
    		$args['skipifshutdown'] = ($skipifshutdown) ? '1' : '0';
    		return $this->jsonapi_query('delip', $args);
    	}
    
    	/**
    	* List IPs
    	*
    	* This should return a list of IPs on a server
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/DeleteIPAddress
    	*/
    	public function listips() {
    		return $this->jsonapi_query('listips');
    	}
    
    	/**
    	* Set Hostname
    	*
    	* This function will allow you to set the hostname of the server
    	* @param string $hostname the hostname that should be assigned to the serve
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SetHostname
    	*/
    	public function sethostname($hostname) {
    		if (!isset($hostname)) {
    			error_log("sethostname requires that hostname is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('sethostname', array('hostname' => $hostname));
    	}
    
    	/**
    	* Set the resolvers used by the server
    	* 
    	* This function will set the resolvers in /etc/resolv.conf for the server
    	* @param string $nameserver1 The IP of the first nameserver to use
    	* @param string $nameserver2 The IP of the second namesever to use
    	* @param string $nameserver3 The IP of the third nameserver to use
    	* @param string $nameserver4 The IP of the forth nameserver to use
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/SetResolvers
    	*/
    	public function setresolvers($nameserver1, $nameserver2 = null, $nameserver3 = null) {
    		$args = array();
    		if (!isset($nameserver1)) {
    			error_log("setresolvers requires that nameserver1 is defined in the array passed to it");
    			return false;
    		}
    		$args['nameserver1'] = $nameserver1;
    		if ($nameserver2) {
    			$args['nameserver2'] = $nameserver2;
    		}
    		if ($nameserver3) {
    			$args['nameserver3'] = $nameserver3;
    		}
    		return $this->jsonapi_query('setresolvers', $args);
    	}
    
    	/**
    	* Display bandwidth Usage
    	*
    	* This function will return all bandwidth usage information for the server,
    	* The arguments for this can be passed in via an associative array, the elements of this array map directly to the
    	* parameters of the call, please see the for more information
    	* @param array $args The configuration for what bandwidth information to display
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ShowBw
    	*/
    	public function showbw($args = null) {
    		if (is_array($args)) {
    			return $this->jsonapi_query('showbw', $args);
    		}
    		return $this->jsonapi_query('showbw');
    	}
    
    	public function nvset($key, $value) {
    		if (!isset($key) || !isset($value)) {
    			error_log("nvset requires that key and value are passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('nvset', array('key' => $key, 'value' => $value));
    	}
    
    	// This function allows you to retrieve and view a non-volatile variable's value.
    	public function nvget($key) {
    		if (!isset($key)) {
    			error_log("nvget requires that key is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('nvget', array('key' => $key));
    	}
    
    	####
    	# Service functions
    	####
    
    	/**
    	* Restart a Service
    	*
    	* This function allows you to restart a service on the server
    	* @param string $service the service that you wish to restart please view the for acceptable values to this parameters
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/RestartService
    	*/
    	public function restartsrv($service) {
    		if (!isset($service)) {
    			error_log("restartsrv requires that service is passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('restartservice', array('service' => $service));
    	}
    
    	/**
    	* Service Status
    	*
    	* This function will return the status of all services on the and whether they are running or not
    	* @param string $service A single service to filter for.
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ServiceStatus
    	*/
    	public function servicestatus($args=array())
    	{
    		if(!empty($args) && !is_array($args)){
    			$args = array('service'=>$args);
    		} elseif (!is_array($args)) {
    			$args = array();
    		}
    			return $this->jsonapi_query('servicestatus', $args);
    	}
    
    	/**
    	* Configure A Service
    	*
    	* This function will allow you to enabled or disable services along with their monitoring by chkservd
    	* @param string $service The service to be monitored
    	* @param bool $enabled Whether the service should be enabled or not
    	* @param bool $monitored Whether the service should be monitored or not
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ConfigureService
    	*/
    	public function configureservice($service, $enabled = true, $monitored = true) {
    		if (!isset($service)) {
    			error_log("configure service requires that a service is passed to it");
    			return false;
    		}
    		$params = array('service' => $service);
    	
    		if ($enabled) {
    			$params['enabled'] = 1;
    		} else {
    			$params['enabled'] = 0;
    		}
    		
    		if ($monitored) {
    			$params['monitored'] = 1;
    		} else {
    			$params['monitored'] = 0;
    		}
    		
    		return $this->jsonapi_query('configureservice', $params);
    		
    	}
    
    	####
    	# SSL functions
    	####
    
    	/**
    	* Display information on an SSL host
    	*
    	* This function will return information on an SSL Certificate, CSR, cabundle and SSL key for a specified domain
    	* @param array $args Configuration information for the SSL certificate, please see for required values
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/FetchSSL
    	*/
    	public function fetchsslinfo($args) {
    		if ( (isset($args['domain']) && isset($args['crtdata'])) || (!isset($args['domain']) && !isset($args['crtdata'])) ) {
    			error_log("fetchsslinfo requires domain OR crtdata is passed to it");
    		}
    		if (isset($args['crtdata'])) {
    			// crtdata must be URL-encoded!
    			$args['crtdata'] = urlencode(trim($args['crtdata']));
    		}
    		return $this->jsonapi_query('fetchsslinfo', $args);
    	}
    
    	/**
    	* Generate an SSL Certificate
    	*
    	* This function will generate an SSL Certificate, the arguments for this map directly to the call for the JSON API call.  Please consult the for more information
    	* @param array $args the configuration for the SSL Certificate being generated
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/GenerateSSL
    	*/
    	public function generatessl($args) {
    		if (!isset($args['xemail']) || !isset($args['host']) || !isset($args['country']) || !isset($args['state']) || !isset($args['city']) || !isset($args['co']) || !isset($args['cod']) || !isset($args['email']) || !isset($args['pass'])) {
    			error_log("generatessl requires that xemail, host, country, state, city, co, cod, email and pass are defined in the array passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('generatessl', $args);
    	}
    
    	/**
    	* Install an SSL certificate
    	*
    	* This function will allow you to install an SSL certificate that is uploaded via the $argument parameter to this call.  The arguments for this call map directly to the parameters for the JSON API call, 
    	* please consult the for more information.
    	* @param array $args The configuration for the SSL certificate
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/InstallSSL
    	*/
    	public function installssl($args) {
    		if (!isset($args['user']) || !isset($args['domain']) || !isset($args['cert']) || !isset($args['key']) || !isset($args['cab']) || !isset($args['ip'])) {
    			error_log("installssl requires that user, domain, cert, key, cab and ip are defined in the array passed to it");
    			return false;
    		}
    		return $this->jsonapi_query('installssl', $args);
    	}
    
    	/**
    	* List SSL Certs
    	*
    	* This function will list all SSL certificates installed on the server
    	* @return mixed
    	* @link http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/ListSSL
    	*/
    	public function listcrts() {
    		return $this->jsonapi_query('listcrts');
    	}
    
    	####
    	# cPanel API1/2 functions
    	# Note: A cPanel account username is required
    	# Some cPanel features must be enabled to be able to use some function (f.e. park, unpark)
    	####
    
    	// This API1 function adds a emailaccount for a specific user.
    	public function addpop($username, $args) {
    		if (!isset($username) || !isset($args)) {
    			error_log("addpop requires that a user and args are passed to it");
    			return false;
    		}
    		if (is_array($args) && (sizeof($args) < 3)) {
    			error_log("addpop requires that args at least contains an email_username, email_password and email_domain");
    			return false;
    		}
    		return $this->api1_query($username, 'Email', 'addpop', $args);
    	}
    
    	// This API2 function displays a list of all parked domains for a specific user.
    	public function park($username, $newdomain, $topdomain) {
    		$args = array();
    		if ( (!isset($username)) && (!isset($newdomain)) ) {
    			error_log("park requires that a username and new domain are passed to it");
    			return false;
    		}
    		$args['domain'] = $newdomain;
    		if ($topdomain)
    		{
    			$args['topdomain'] = $topdomain;
    		}
    		return $this->api2_query($username, 'Park', 'park', $args);
    	}
    
    	// This API2 function displays a list of all parked domains for a specific user.
    	public function unpark($username, $domain) {
    		$args = array();
    		if ( (!isset($username)) && (!isset($domain)) ) {
    			error_log("unpark requires that a username and domain are passed to it");
    			return false;
    		}
    		$args['domain'] = $domain;
    		return $this->api2_query($username, 'Park', 'unpark', $args);
    	}
    
    	// This API2 function allows you to view the diskusage of a emailaccount.
    	public function getdiskusage($username, $args) {
    		if (!isset($username) || !isset($args)) {
    			error_log("getdiskusage requires that a username and args are passed to it");
    			return false;
    		}
    		if (is_array($args) && (!isset($args['domain']) || !isset($args['login']))) {
    			error_log("getdiskusage requires that args at least contains an email_domain and email_username");
    			return false;
    		}
    		return $this->api2_query($username, 'Email', 'getdiskusage', $args);
    	}
    
    	// This API2 function allows you to list ftp-users associated with a cPanel account including disk information.
    	public function listftpwithdisk($username) {
    		if (!isset($username)) {
    			error_log("listftpwithdisk requires that user is passed to it");
    			return false;
    		}
    		return $this->api2_query($username, 'Ftp', 'listftpwithdisk');
    	}
    
    	// This API2 function allows you to list ftp-users associated with a cPanel account.
    	public function listftp($username) {
    		if (!isset($username)) {
    			error_log("listftp requires that user is passed to it");
    			return false;
    		}
    		return $this->api2_query($username, 'Ftp', 'listftp');
    	}
    
    	// This API2 function displays a list of all parked domains for a specific user.
    	public function listparkeddomains($username, $domain = null) {
    		$args = array();
    		if (!isset($username)) {
    				error_log("listparkeddomains requires that a user is passed to it");
    				return false;
    			}
    			if (isset($domain)) {
    				$args['regex'] = $domain;
    				return $this->api2_query($username, 'Park', 'listparkeddomains', $args);
    			}
    			return $this->api2_query($username, 'Park', 'listparkeddomains');
    		}
    
    		// This API2 function displays a list of all addon domains for a specific user.
    		public function listaddondomains($username, $domain = null) {
    			$args = array();
    			if (!isset($username)) {
    				error_log("listaddondomains requires that a user is passed to it");
    				return false;
    			}
    			if (isset($domain)) {
    				$args['regex'] = $domain;
    				return $this->api2_query($username, 'AddonDomain', 'listaddondomains', $args);
    			}
    			return $this->api2_query($username, 'Park', 'listaddondomains');
    		}
    
    		// This API2 function displays a list of all selected stats for a specific user.
    		public function stat($username, $args = null) {
    			if ( (!isset($username)) || (!isset($args)) ) {
    				error_log("stat requires that a username and options are passed to it");
    				return false;
    			}
    			if (is_array($args)) {
    				$display = '';
    				foreach($args as $key => $value){
    					$display .= $value . '|';
    				}
    				$values['display'] = substr($display, 0, -1);
    			}
    			else {
    				$values['display'] = substr($args, 0, -1);
    			}
    			return $this->api2_query($username, 'StatsBar', 'stat', $values);
    		}
    		
    }
    
     
  5. KostonConsulting

    KostonConsulting Well-Known Member

    Joined:
    Jun 17, 2010
    Messages:
    255
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    San Francisco, CA
    cPanel Access Level:
    Root Administrator
    I'm actually not able to connect to that binary without a permission denied error on EDGE (11.31.4.4) so you may have problems in the future with that method. Switching the the JSON API via a connection to https://127.0.0.1:2087/json-api/resellerstats?reseller=root may have more overhead but will keep your code future proof.

    What function are you using to call the API? shell_exec should work with pipes:

    Code:
    <?php
      echo shell_exec('echo -ne "reseller=root" | /usr/local/cpanel/whostmgr/bin/xml-api -json ./resellerstats');
    ?>
    
     
  6. charsleysa

    charsleysa Active Member

    Joined:
    Jul 18, 2011
    Messages:
    41
    Likes Received:
    0
    Trophy Points:
    6
    Location:
    Palmerston North, New Zealand
    cPanel Access Level:
    Root Administrator
    Direct access to the xml-api binary via Terminal is disallowed, it must be executed in a web environment.
    I learnt that the hard way and that is why this is harder to debug, no direct terminal access.

    The code is future proof as your permission denied error is explained above.

    I tried shell_exec, still no luck, cPanel parses the form data in PERL in such a way that it executes fine.
    I cant even replicate the PERL environment that successfully executes this command!

    And the problem with overhead is that it slows down the calls by up to hundredths of a second which is too slow.
    Especially when I need to make a few hundred calls per second (depending on how many accounts are on the server).
     
  7. KostonConsulting

    KostonConsulting Well-Known Member

    Joined:
    Jun 17, 2010
    Messages:
    255
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    San Francisco, CA
    cPanel Access Level:
    Root Administrator
    Ah, I see the same when executing under cpsrvd in WHM.



    Not sure what stats you need but this should grab you with about the minimum amount of overhead you'll find. Optimize to your needs:

    Code:
    #!/usr/bin/perl
    
    BEGIN{
    	unshift(@INC, '/usr/local/cpanel');
    }
    use Whostmgr::Resellers ();
    use Data::Dumper ();
    
    print "Content-type: text/html\n\n";
    
    
    my $resellers = Whostmgr::Resellers::list();
    my %resellers = %{$resellers};
    
    while ( ($name, $value) = each %resellers )
    {
    	my %OPTS = ( res => $name );
    	my ( $total_disk_used, $total_bandwidth_used, $total_disk_limit, $total_bandwidth_limit, $ACCTLIST ) = Whostmgr::Resellers::statres(0,0, %OPTS );
    	
      	print "<br />RESELLER: $name<br />";
    	print "disk usage: $total_disk_used / $total_disk_limit <br />";
    	print "bandwidth: $total_bandwidth_used / $total_bandwidth_limit <br />";
    	print "accounts: " . Data::Dumper::Dumper($ACCTLIST) . "<br />";
    }
    
     
  8. charsleysa

    charsleysa Active Member

    Joined:
    Jul 18, 2011
    Messages:
    41
    Likes Received:
    0
    Trophy Points:
    6
    Location:
    Palmerston North, New Zealand
    cPanel Access Level:
    Root Administrator
    Thanks for the help but I'm trying to stay away from PERL and build this completely in PHP and show how much power PHP has.
    I have been able to build my software entirely out of PHP so far, so I want to keep going, I want to keep trying.
    Also I am using a lot of functions in the XML-API so creating a PERL script for each would not be feasible, sorry.
     
Loading...

Share This Page