2010-09-27 01:14:42 +02:00
#!/usr/bin/php
< ? php
2018-02-27 22:16:54 +01:00
2010-09-27 01:14:42 +02:00
/**
* Command - line code generation utility to automate administrator tasks .
*
* Shell dispatcher class
*
* PHP versions 4 and 5
*
* CakePHP ( tm ) : Rapid Development Framework < http :// www . cakephp . org />
* Copyright 2005 - 2008 , Cake Software Foundation , Inc .
* 1785 E . Sahara Avenue , Suite 490 - 204
* Las Vegas , Nevada 89104
2013-11-13 20:17:05 +01:00
* Modified for PostfixAdmin by Valkum 2011
* Modified for PostfixAdmin by Christian Boltz 2011 - 2013
2010-09-27 01:14:42 +02:00
*
* Copyright 2010
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice .
*
* @ filesource
* @ copyright Copyright 2005 - 2008 , Cake Software Foundation , Inc .
* @ link http :// postfixadmin . sourceforge . net / Postfixadmin on Sourceforge
* @ package postfixadmin
* @ subpackage -
* @ since -
* @ version $Revision $
* @ modifiedby $LastChangedBy $
* @ lastmodified $Date $
* @ license http :// www . opensource . org / licenses / mit - license . php The MIT License
*/
2021-03-22 10:28:28 +01:00
class PostfixAdmin
{
2016-05-20 21:55:55 +02:00
/**
2016-05-20 22:58:13 +02:00
* Version
2016-05-20 21:55:55 +02:00
*
* @ var string
*/
2024-04-22 22:02:01 +02:00
public $version = '0.3' ;
2016-05-20 21:55:55 +02:00
/**
* Standard input stream .
*
2018-06-18 22:35:20 +02:00
* @ var resource
2016-05-20 21:55:55 +02:00
*/
public $stdin ;
/**
* Standard output stream .
*
2018-06-18 22:35:20 +02:00
* @ var resource
2016-05-20 21:55:55 +02:00
*/
public $stdout ;
/**
* Standard error stream .
*
2018-06-18 22:35:20 +02:00
* @ var resource
2016-05-20 21:55:55 +02:00
*/
public $stderr ;
/**
* Contains command switches parsed from the command line .
*
* @ var array
*/
public $params = array ();
/**
* Contains arguments parsed from the command line .
*
* @ var array
*/
public $args = array ();
/**
* The file name of the shell that was invoked .
*
* @ var string
*/
2018-12-27 14:55:41 +01:00
public $shell ;
2016-05-20 21:55:55 +02:00
/**
* The class name of the shell that was invoked .
*
* @ var string
*/
2018-12-27 14:55:41 +01:00
public $shellClass ;
2016-05-20 21:55:55 +02:00
/**
* The command called if public methods are available .
*
* @ var string
*/
2018-12-27 14:55:41 +01:00
public $shellCommand ;
2016-05-20 21:55:55 +02:00
/**
* The name of the shell in camelized .
*
* @ var string
*/
2018-12-27 14:55:41 +01:00
public $shellName ;
2016-05-20 21:55:55 +02:00
/**
* Constructor
*
* @ param array $args the argv .
*/
2021-04-13 22:19:16 +02:00
public function __construct ( $args = array ())
{
2016-05-20 21:55:55 +02:00
set_time_limit ( 0 );
$this -> __initConstants ();
$this -> parseParams ( $args );
$this -> __initEnvironment ();
}
/**
* Defines core configuration .
*/
2021-04-13 22:19:16 +02:00
private function __initConstants ()
{
2016-05-20 21:55:55 +02:00
ini_set ( 'display_errors' , '1' );
2018-12-27 14:55:41 +01:00
ini_set ( 'error_reporting' , '' . E_ALL );
ini_set ( 'html_errors' , " 0 " );
ini_set ( 'implicit_flush' , " 1 " );
ini_set ( 'max_execution_time' , " 0 " );
2016-05-20 21:55:55 +02:00
}
/**
* Defines current working environment .
*/
2021-04-13 22:19:16 +02:00
private function __initEnvironment ()
{
2018-06-18 22:35:20 +02:00
$this -> stdin = fopen ( 'php://stdin' , 'r' );
2016-05-20 21:55:55 +02:00
$this -> stdout = fopen ( 'php://stdout' , 'w' );
$this -> stderr = fopen ( 'php://stderr' , 'w' );
if ( basename ( __FILE__ ) != basename ( $this -> args [ 0 ])) {
$this -> stderr ( 'Warning: the dispatcher may have been loaded incorrectly, which could lead to unexpected results...' );
if ( $this -> getInput ( 'Continue anyway?' , array ( 'y' , 'n' ), 'y' ) == 'n' ) {
exit ( 1 );
}
2010-09-27 01:14:42 +02:00
}
2016-05-20 21:55:55 +02:00
$this -> shiftArgs ();
}
/**
2020-06-23 22:14:29 +02:00
* postfixadmin - cli admin view admin @ example . com
* - Create AdminHandler .
* - and then a CliView object ( Shell class )
* - call CliView -> view () ... which under the covers uses AdminHandler *
2016-05-20 21:55:55 +02:00
*/
2021-04-13 22:19:16 +02:00
public function dispatch ()
{
2016-05-22 21:58:54 +02:00
check_db_version (); # ensure the database layout is up to date
2016-05-20 21:55:55 +02:00
if ( ! isset ( $this -> args [ 0 ])) {
$this -> help ();
2019-09-14 21:09:56 +02:00
return 1 ;
2016-05-20 21:55:55 +02:00
}
$this -> shell = $this -> args [ 0 ];
$this -> shiftArgs ();
$this -> shellName = ucfirst ( $this -> shell );
$this -> shellClass = $this -> shellName . 'Handler' ;
2010-09-27 01:14:42 +02:00
2016-05-20 21:55:55 +02:00
if ( $this -> shell == 'help' ) {
$this -> help ();
2019-09-14 21:09:56 +02:00
return 1 ;
2016-05-20 21:55:55 +02:00
}
2018-03-25 21:44:42 +02:00
2019-09-17 21:55:14 +02:00
$command = $this -> args [ 0 ];
2013-11-14 22:48:52 +01:00
2016-05-20 21:55:55 +02:00
$this -> shellCommand = $command ;
$this -> shellClass = 'Cli' . ucfirst ( $command );
2011-10-18 01:19:57 +02:00
2016-05-20 21:55:55 +02:00
if ( ucfirst ( $command ) == 'Add' || ucfirst ( $command ) == 'Update' ) {
$this -> shellClass = 'CliEdit' ;
2010-09-27 01:14:42 +02:00
}
2016-05-20 21:55:55 +02:00
if ( ! class_exists ( $this -> shellClass )) {
$this -> stderr ( 'Unknown task ' . $this -> shellCommand );
2019-09-14 21:09:56 +02:00
return 1 ;
2016-05-20 21:55:55 +02:00
}
2010-09-27 01:14:42 +02:00
2016-05-20 21:55:55 +02:00
$shell = new $this -> shellClass ( $this );
2013-11-13 20:07:12 +01:00
2016-05-20 21:55:55 +02:00
$shell -> handler_to_use = ucfirst ( $this -> shell ) . 'Handler' ;
2013-11-13 20:07:12 +01:00
2016-05-20 21:55:55 +02:00
if ( ! class_exists ( $shell -> handler_to_use )) {
$this -> stderr ( 'Unknown module ' . $this -> shell );
2019-09-14 21:09:56 +02:00
return 1 ;
2016-05-20 21:55:55 +02:00
}
2013-11-13 20:07:12 +01:00
2016-05-20 21:55:55 +02:00
$task = ucfirst ( $command );
2013-11-13 20:07:12 +01:00
2016-05-20 21:55:55 +02:00
$shell -> new = 0 ;
if ( $task == 'Add' ) {
$shell -> new = 1 ;
}
# TODO: add a way to Cli* to signal if the selected handler is supported (for example, not all *Handler support changing the password)
2013-11-13 20:07:12 +01:00
2016-05-20 21:55:55 +02:00
if ( strtolower ( get_parent_class ( $shell )) == 'shell' ) {
2022-06-28 14:46:11 +02:00
$handler = new $shell -> handler_to_use ();
2016-05-20 21:55:55 +02:00
if ( in_array ( $task , $handler -> taskNames )) {
$this -> shiftArgs ();
$shell -> startup ();
if ( isset ( $this -> args [ 0 ]) && $this -> args [ 0 ] == 'help' ) {
if ( method_exists ( $shell , 'help' )) {
$shell -> help ();
2019-09-14 21:09:56 +02:00
return 1 ;
2016-05-20 21:55:55 +02:00
} else {
$this -> help ();
2019-09-14 21:09:56 +02:00
return 1 ;
2016-05-20 21:55:55 +02:00
}
}
2019-09-14 21:09:56 +02:00
return $shell -> execute ();
2013-11-13 20:07:12 +01:00
}
2016-05-20 21:55:55 +02:00
}
$classMethods = get_class_methods ( $shell );
2013-11-13 20:07:12 +01:00
2016-05-20 21:55:55 +02:00
$privateMethod = $missingCommand = false ;
if (( in_array ( $command , $classMethods ) || in_array ( strtolower ( $command ), $classMethods )) && strpos ( $command , '_' , 0 ) === 0 ) {
$privateMethod = true ;
2010-09-27 01:14:42 +02:00
}
2016-05-20 21:55:55 +02:00
if ( ! in_array ( $command , $classMethods ) && ! in_array ( strtolower ( $command ), $classMethods )) {
$missingCommand = true ;
}
2010-09-27 01:14:42 +02:00
2016-05-20 21:55:55 +02:00
$protectedCommands = array (
2018-03-25 21:34:26 +02:00
'in' , 'out' , 'err' , 'hr' , 'log' ,
2018-03-25 21:23:52 +02:00
'__construct' , 'dispatch' , 'stdout' , 'stderr'
2016-05-20 21:55:55 +02:00
);
2010-09-27 01:14:42 +02:00
2016-05-20 21:55:55 +02:00
if ( in_array ( strtolower ( $command ), $protectedCommands )) {
$missingCommand = true ;
}
2010-09-27 01:14:42 +02:00
2016-05-20 21:55:55 +02:00
if ( $missingCommand && method_exists ( $shell , 'main' )) {
$shell -> startup ();
2019-09-14 21:09:56 +02:00
return $shell -> main ();
2016-05-20 21:55:55 +02:00
} elseif ( ! $privateMethod && method_exists ( $shell , $command )) {
$this -> shiftArgs ();
$shell -> startup ();
2019-09-14 21:09:56 +02:00
return $shell -> { $command }();
2016-05-20 21:55:55 +02:00
} else {
$this -> stderr ( " Unknown { $this -> shellName } command ' $command '. \n For usage, try 'postfixadmin-cli { $this -> shell } help'. \n \n " );
2019-09-14 21:09:56 +02:00
return 1 ;
2010-09-27 01:14:42 +02:00
}
2016-05-20 21:55:55 +02:00
}
/**
* Prompts the user for input , and returns it .
*
* @ param string $prompt Prompt text .
* @ param mixed $options Array or string of options .
* @ param string $default Default input value .
2018-06-18 22:35:20 +02:00
* @ return string Either the default value , or the user - provided input .
2016-05-20 21:55:55 +02:00
*/
2021-04-13 22:19:16 +02:00
public function getInput ( $prompt , $options = null , $default = null )
{
2016-05-20 21:55:55 +02:00
if ( ! is_array ( $options )) {
$print_options = '' ;
} else {
$print_options = '(' . implode ( '/' , $options ) . ')' ;
2010-09-27 01:14:42 +02:00
}
2016-05-20 21:55:55 +02:00
if ( $default == null ) {
$this -> stdout ( $prompt . " $print_options \n " . '> ' , false );
} else {
$this -> stdout ( $prompt . " $print_options \n " . " [ $default ] > " , false );
2010-09-27 01:14:42 +02:00
}
2016-05-20 21:55:55 +02:00
$result = fgets ( $this -> stdin );
2010-09-27 01:14:42 +02:00
2018-01-26 15:45:57 +01:00
if ( $result === false ) {
2016-05-20 21:55:55 +02:00
exit ( 1 );
}
$result = trim ( $result );
2010-09-27 01:14:42 +02:00
2016-05-20 21:55:55 +02:00
if ( $default != null && empty ( $result )) {
return $default ;
}
return $result ;
}
/**
* Outputs to the stdout filehandle .
*
* @ param string $string String to output .
* @ param boolean $newline If true , the outputs gets an added newline .
*/
2021-04-13 22:19:16 +02:00
public function stdout ( $string , $newline = true )
{
2016-05-20 21:55:55 +02:00
if ( $newline ) {
fwrite ( $this -> stdout , $string . " \n " );
} else {
fwrite ( $this -> stdout , $string );
}
}
2010-09-27 01:14:42 +02:00
2016-05-20 21:55:55 +02:00
/**
* Outputs to the stderr filehandle .
*
* @ param string $string Error text to output .
*/
2021-04-13 22:19:16 +02:00
public function stderr ( $string )
{
2016-05-20 21:55:55 +02:00
fwrite ( $this -> stderr , 'Error: ' . $string . " \n " );
}
2010-09-27 01:14:42 +02:00
2016-05-20 21:55:55 +02:00
/**
* Parses command line options
*
* @ param array $params Parameters to parse
*/
2021-04-13 22:19:16 +02:00
public function parseParams ( $params )
{
2016-05-20 21:55:55 +02:00
$count = count ( $params );
for ( $i = 0 ; $i < $count ; $i ++ ) {
2021-01-18 21:46:25 +01:00
if ( $params [ $i ] != '' && $params [ $i ][ 0 ] === '-' && $params [ $i ] != '-1' ) {
2020-05-02 01:26:35 +02:00
$key = substr ( $params [ $i ], 1 );
2024-04-22 22:02:01 +02:00
if ( isset ( $params [ $i + 1 ])) {
2020-05-02 01:26:35 +02:00
# TODO: ideally we should know if a parameter can / must have a value instead of whitelisting known valid values starting with '-' (probably only bool doesn't need a value)
2024-04-22 22:02:01 +02:00
if ( $params [ $i + 1 ][ 0 ] === '-' && $params [ $i + 1 ] != '-1' ) {
2020-05-02 01:26:35 +02:00
$this -> params [ $key ] = true ;
} else {
2024-04-22 22:02:01 +02:00
$this -> params [ $key ] = $params [ $i + 1 ];
2020-05-02 01:26:35 +02:00
$i ++ ;
2016-05-20 21:55:55 +02:00
}
2010-09-27 01:14:42 +02:00
}
2020-05-02 01:26:35 +02:00
} else {
$this -> args [] = $params [ $i ];
}
2010-09-27 01:14:42 +02:00
}
2016-05-20 21:55:55 +02:00
}
/**
* Removes first argument and shifts other arguments up
*
* @ return boolean False if there are no arguments
*/
2021-04-13 22:19:16 +02:00
public function shiftArgs ()
{
2016-05-20 21:55:55 +02:00
if ( empty ( $this -> args )) {
return false ;
2010-09-27 01:14:42 +02:00
}
2016-05-20 21:55:55 +02:00
unset ( $this -> args [ 0 ]);
$this -> args = array_values ( $this -> args );
return true ;
}
/**
* prints help message and exits .
*/
2021-04-13 22:19:16 +02:00
public function help ()
{
2016-05-20 21:55:55 +02:00
$this -> stdout ( " \n Welcome to Postfixadmin-CLI v " . $this -> version );
$this -> stdout ( " --------------------------------------------------------------- " );
$this -> stdout ( " Usage: " );
$this -> stdout ( " postfixadmin-cli <module> <task> [--option value --option2 value] " );
$this -> stdout ( " " );
$this -> stdout ( " Available modules: " );
2018-01-26 15:45:57 +01:00
$modules = explode ( ',' , 'admin,domain,mailbox,alias,aliasdomain,fetchmail' );
2016-05-20 21:55:55 +02:00
foreach ( $modules as $module ) {
$this -> stdout ( " $module " );
}
$this -> stdout ( " " );
$this -> stdout ( " Most modules support the following tasks: " );
$this -> stdout ( " view View an item " );
$this -> stdout ( " add Add an item " );
$this -> stdout ( " update Update an item " );
$this -> stdout ( " delete Delete an item " );
$this -> stdout ( " scheme Print database scheme (useful for developers only) " );
$this -> stdout ( " help Print help output " );
$this -> stdout ( " " );
$this -> stdout ( " " );
$this -> stdout ( " For module-specific help, see: " );
$this -> stdout ( " " );
$this -> stdout ( " postfixadmin-cli <module> help " );
$this -> stdout ( " print a detailed list of available commands " );
$this -> stdout ( " " );
$this -> stdout ( " postfixadmin-cli <module> <task> help " );
$this -> stdout ( " print a list of available options. " );
$this -> stdout ( " " );
exit ();
}
2010-09-27 01:14:42 +02:00
}
2018-01-26 15:45:57 +01:00
define ( " POSTFIXADMIN_CLI " , 1 );
2010-09-27 01:14:42 +02:00
2018-03-25 21:15:45 +02:00
require_once ( dirname ( __FILE__ ) . '/../common.php' );
2010-09-27 01:14:42 +02:00
$dispatcher = new PostfixAdmin ( $argv );
2019-09-14 22:01:09 +02:00
try {
$retval = $dispatcher -> dispatch ();
2019-09-15 12:42:21 +02:00
} catch ( Exception $e ) {
2019-09-14 22:01:09 +02:00
$dispatcher -> stderr ( " Execution Exception: " . $e -> getMessage ());
$retval = 1 ;
}
2019-09-14 21:09:56 +02:00
exit ( $retval );
2013-12-08 20:41:01 +01:00
/* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */