ok
Direktori : /usr/local/lsws/admin/html.6.0.10/classes/ws/ |
Current File : //usr/local/lsws/admin/html.6.0.10/classes/ws/Service.php |
<?php require_once('blowfish.php'); class Service { private $cmd = NULL; public $cmdStatus = NULL; public $act = NULL; public $actId = NULL; public $FNAME = NULL; public $FSTATUS = NULL; public $FPID = NULL; public $serverLog = NULL; public $serverLastModTime = 100; public $listeners = array(); public $adminL = array(); public $vhosts = array(); public $awstats = array(); public $serv = array(); public $license = array(); public $debugOn = NULL; public $messages = array(); public function __construct() { $this->FNAME = '/tmp/lshttpd/.admin'; $this->FSTATUS = '/tmp/lshttpd/.status'; $this->FPID = '/tmp/lshttpd/lshttpd.pid'; } function init() { clearstatcache(); $this->serverLastModTime = filemtime($this->FSTATUS); $this->readStatus(); } function refreshConf($data) { $listeners = $data['listener']; foreach( $listeners as $lname => $addr ) { if ( !isset($this->listeners[$lname]) ) { $this->listeners[$lname] = array(); $this->listeners[$lname]['addr'] = $addr; $this->listeners[$lname]['status'] = 'Error'; } } $vhnames = $data['vhost']; // first char 0|1 (active|inactive), 2nd char A:in conf only, M: in both, S: in status only foreach( $vhnames as $vhname ) { if ( !isset($this->vhosts[$vhname]) ) $this->vhosts[$vhname] = '0A'; else $this->vhosts[$vhname] = substr($this->vhosts[$vhname], 0, 1) . 'M'; } $this->serv['name'] = $data['serv']; if(array_key_exists('awstats',$data)) { $this->awstats = $data['awstats']; } else { $this->awstats = NULL; } $fd = fopen($this->FPID, 'r'); if ( $fd ) { $this->serv['pid'] = trim(fgets($fd)); fclose($fd); } $this->serverLog = $data['servLog']; } public function process($act, $actId) { $this->act = $act; $this->actId = $actId; if ($act == 'RESET_ALL_PHP_PROCESSES') { $this->resetphp(); return true; } if ( $this->isPending() ) { return false; } $this->checkLastMod(); if (( $act == 'upgrade' )|| ( $act == 'switchTo' )|| ( $act == 'validatelicense' )|| ( $act == 'remove' )) { $this->vermgr(); } elseif ( $actId ) { $this->vhostControl(); } elseif ( $act == 'restart' ) { $this->restartServer(); } elseif ( $act == 'toggledbg' ) { $this->cmd = array('toggledbg'); $this->issueCmd(); sleep(2); $this->readStatus(); } return true; } private function resetphp() { $touchfile = $_SERVER['LS_SERVER_ROOT'] . "admin/tmp/.lsphp_restart.txt" ; //fixed location if (touch($touchfile)) { $this->messages[] = ['success', 'Successfully notified LiteSpeed server to restart all detached PHP processes.']; } else { $this->messages[] = ['error', 'Failed to notify LiteSpeed server to restart all detached PHP processes.']; } } function waitForChange() { for( $count = 0; $count < 5; ++$count) { if ( !$this->checkLastMod() ) sleep(1); else return true; } return false; } private function readStatus() { $this->listeners = array(); $this->adminL = array(); $this->vhosts = array(); $this->license = array(); $fd = fopen($this->FSTATUS, 'r'); if ( !$fd ) return false; while ( !feof($fd) ) { $buffer = fgets($fd, 512); if ( strncmp($buffer, 'LISTENER0', 9) == 0 ) { $this->readListener($this->listeners, $buffer, $fd); } elseif ( strncmp($buffer, 'LISTENER1', 9) == 0 ) { $this->readListener($this->adminL, $buffer, $fd); } elseif ( strncmp($buffer, 'VHOST', 5) == 0 ) { $this->readVh($buffer, $fd); } elseif (strncmp($buffer, 'DEBUG_LOG: ', 11) == 0) { if (substr($buffer, 11, 1) === '1') $this->debugOn = true; else $this->debugOn = false; } elseif ( strncmp($buffer, 'LICENSE', 7) == 0 || strncmp($buffer, 'FEATURES', 8) == 0 ) { $this->readLicenseInfo($buffer, $d); } elseif ( strncmp($buffer, 'EOF', 3) == 0 ) break; } fclose($fd); return true; } private function readListener(&$l, $buffer, &$fd) { if ( preg_match( "/\[(.+)\] (.+)$/", $buffer, $matches )) { $lname = $matches[1]; $l[$lname]['addr'] = $matches[2]; $l[$lname]['status'] = 'Running'; $tmp = fgets($fd, 512); while ( strncmp($tmp, 'ENDL' ,4) != 0 ) { if ( strncmp( $tmp, 'LVMAP', 5 ) == 0) { if ( preg_match( "/\[(.+)\] (.+)$/", $tmp, $tm )) { $l[$lname]['map'][$tm[1]][] = $tm[2]; } } $tmp = fgets($fd, 512); } } } private function readVh($buffer, &$fd) { if ( preg_match( "/\[(.+)\] ([01])/", $buffer, $m )) { $vname = $m[1]; if ( $vname != '_AdminVHost' ) $this->vhosts[$m[1]] = $m[2] . 'S'; } } private function readLicenseInfo($buffer, &$fd) { // LICENSE_EXPIRES: 0, UPDATE_EXPIRES: 1597636800, SERIAL: , TYPE: 9:2 if ( preg_match( "/^LICENSE_EXPIRES: (\d+), UPDATE_EXPIRES: (\d+), SERIAL: (.+), TYPE: (.+)$/", $buffer, $m )) { $this->license['expires'] = $m[1]; $this->license['updateExpires'] = $m[2]; $this->license['serial'] = $m[3]; $proc = trim($m[4]); if ($this->license['expires'] == 0) { $this->license['expires_date'] = 'Never'; } else { $this->license['expires_date'] = date('M d, Y', $this->license['expires']); } $this->license['updateExpires_date'] = date('M d, Y', $this->license['updateExpires']); // translate proc to type $this->license['proc'] = $proc; $this->license['type'] = $this->translateLicProc($proc); } else if ( preg_match("/FEATURES: (\d+)$/", $buffer, $m)) { $feature = $m[1]; $this->license['feature'] = $feature; if (($feature & 1) == 0 && $this->license['proc'] == 1) { // no cache, old 1-CPU license $this->license['type'] = '1-CPU License (1-Worker)'; } } } private function translateLicProc($proc) { if (strncmp($proc, '9:', 2) == 0) { return 'Web Host Elite (X-Worker = ' . substr($proc, 2) . ')'; } switch ($proc) { // old type, to be retired case 'V': return 'VPS License (1-Worker with 2GB Memory Limit)'; case 'U': case 'VU': case 'U1': return 'UltraVPS License (1-Worker with 8GB Memory Limit)'; case '8': return '8-CPU License (8-Worker)'; // current ones case 'F': return 'Free Starter (1-Domain & 1-Worker with 2GB Memory Limit)'; case 'S': // SiteOwner return 'Site Owner Plus (5-Domain & 1-Worker)'; case 'SM': // SiteOwner with memeory limit return 'Site Owner (5-Domain 1-Worker with 8GB Memory Limit)'; case 'D': // domain limit return 'Domain Limited (limited-Domain 1-Worker)'; case 'DM': // domain and memory limit return 'Domain Limited (limited-Domain 1-Worker with 8GB Memory Limit)'; case '1M': // 1cpu with memory limit return 'Web Host Lite (1-Worker with 8GB Memory Limit)'; case '1': return 'Web Host Essential (1-Worker)'; case '2': return 'Web Host Professional (2-Worker)'; case '3': return 'Dedicated (3-Worker)'; case '4': return 'Web Host Enterprise (4-Worker)'; case 'X': case '9': // failsafe, should not happen return 'Web Host Elite (X-Worker)'; default : return '1-Worker'; // do not error out to be safe } } function checkLastMod() { clearstatcache(); $mt = filemtime($this->FSTATUS); if ( $this->serverLastModTime != $mt ) { $this->serverLastModTime = $mt; return true; } else { return false; } } function restartServer() { $this->cmd = array('restart'); CLIENT::singleton()->setChanged(false); $this->issueCmd(); } function vermgr() { if ( $this->act == 'switchTo' ) { $this->cmd = array("mgrver:$this->actId"); } elseif ( $this->act == 'remove' ) { $this->cmd = array("mgrver:-d $this->actId"); } elseif ($this->act == 'upgrade') { $product = PRODUCT::GetInstance(); $edition = 'std'; if ($product->edition == 'ENTERPRISE') $edition = 'ent'; $this->cmd = array("{$this->act}:{$this->actId}-$edition"); } elseif ($this->act == 'validatelicense') { $this->cmd = array('ValidateLicense'); } else { unset( $this->cmd ); return; //illegal action } $this->issueCmd(); $this->waitForChange(); $this->readStatus(); } function vhostControl() { $this->cmd = array("$this->act:vhost:$this->actId"); $this->issueCmd(); $this->waitForChange(); $this->readStatus(); } function install( $app ) { $this->cmd = array('install:' . $app); $this->issueCmd(); } public static function getCommandSocket($cmd) { $clientid = CLIENT::singleton()->getIdData(); $uid = PMA_blowfish_decrypt( $clientid['id'], $clientid['sec0']); $password = PMA_blowfish_decrypt( $clientid['pass'], $clientid['sec1']); $outBuf = "auth:" . $uid . ':' . $password . "\n"; $outBuf .= $cmd . "\n" . 'end of actions'; if ( strncmp( $_SERVER['LSWS_ADMIN_SOCK'], 'uds://', 6 ) == 0 ) { $sock = socket_create( AF_UNIX, SOCK_STREAM, 0 ); $chrootOffset = 0; if ( isset( $_SERVER['LS_CHROOT'] ) ) $chrootOffset = strlen( $_SERVER['LS_CHROOT'] ); $addr = substr( $_SERVER["LSWS_ADMIN_SOCK"], 5 + $chrootOffset ); if ( socket_connect( $sock, $addr ) == false ) { error_log( "failed to connect to server addr ($addr)! socket_connect() failed: " . socket_strerror(socket_last_error()) . "\n" ); return false; } } else { $sock = socket_create( AF_INET, SOCK_STREAM, SOL_TCP ); $addr = explode( ":", $_SERVER['LSWS_ADMIN_SOCK'] ); if ( socket_connect( $sock, $addr[0], intval( $addr[1] ) ) == false ) { error_log( 'failed to connect to server (' . $_SERVER['LSWS_ADMIN_SOCK'] . ')! socket_connect() failed: ' . socket_strerror(socket_last_error()) . "\n" ); return false; } } socket_write( $sock, $outBuf ); socket_shutdown( $sock, 1 ); return $sock; } private function issueCmd() { CLIENT::singleton()->reauthenticate(); $commandline = ''; foreach( $this->cmd as $line ) { $commandline .= $line . "\n"; } $sock = Service::getCommandSocket($commandline); if ($sock != FALSE) { $res = socket_recv( $sock, $buffer, 1024, 0 ); socket_close( $sock ); return (( $res > 0 )&&(strncasecmp( $buffer, 'OK', 2 ) == 0 )); } else return FALSE; } public static function retrieveCommandData($cmd) { $sock = Service::getCommandSocket($cmd); $buffer = ''; if ($sock != FALSE) { $read = array($sock); $write = NULL; $except = NULL; $num_changed_sockets = socket_select($read, $write, $except, 3); //wait for max 3 seconds if ($num_changed_sockets === FALSE) { error_log("socket_select failed: " . socket_strerror(socket_last_error())); } else if ($num_changed_sockets > 0) { while (socket_recv($sock, $data, 8192, 0)) { $buffer .= $data; } } socket_close( $sock ); } return $buffer; } function isPending() { if ( file_exists($this->FNAME) ) { $this->cmdStatus = 'IS_PENDING'; return true; } else return false; } function getLogData() { $data = array(); $data['filename'] = $this->getServerLog(); $level = DUtil::getGoodVal(DUtil::grab_input('request','sel_level')); if ( $level == NULL ) $level = 'I'; if (!in_array($level, array('E', 'W', 'N', 'I', 'D'))) { return NULL; } $data['level'] = $level; $fd = fopen($data['filename'], 'r'); if ( !$fd ) return NULL; fseek( $fd, 0, SEEK_END ); $endpos = ftell($fd); fclose($fd); $data['logSize'] = number_format( $endpos/1024, 2); $searchSize = (int) DUtil::getGoodVal(DUtil::grab_input('request','searchSize')); if ( $searchSize <= 0 ) $searchSize = 20; else if ($searchSize > 512) $searchSize = 512; $data['searchSize'] = $searchSize; $searchFrom = (int) DUtil::getGoodVal(DUtil::grab_input('request','searchFrom')); if ( isset($_REQUEST['end']) ) { $searchFrom = $endpos; } else { if ( isset($_REQUEST['prev']) ) $searchFrom -= $searchSize; elseif ( isset($_REQUEST['next']) ) $searchFrom += $searchSize; elseif ( isset($_REQUEST['begin']) ) $searchFrom = 0; if ( $searchFrom < 0 ) $searchFrom = 0; $data['searchFrom'] = $searchFrom; $searchFrom *= 1024; } $searchSize *= 1024; if ( $searchFrom >= $endpos ) { $searchFrom = $endpos - $searchSize; if ( $searchFrom < 0 ) $searchFrom = 0; $data['searchFrom'] = number_format( $searchFrom/1024, 2, '.', ''); } if ( $searchFrom + $searchSize < $endpos ) $endpos = $searchFrom + $searchSize; $data['fromPos'] = $searchFrom; $data['endPos'] = $endpos; return $data; } function showErrLog(&$buf, $len=20480) { $buf = array(); $data = array(); $data['filename'] = $this->getServerLog(); $data['level'] = 'W'; $fd = fopen($data['filename'], 'r'); if ( !$fd ) { $buf[] = 'Failed read server log file from '.$data['filename']; return 0; } fseek( $fd, 0, SEEK_END ); $data['endPos'] = ftell($fd); if ( $data['endPos'] > $len ) $data['fromPos'] = $data['endPos'] - $len; else $data['fromPos'] = 0; fclose($fd); $res = $this->getLog($data); if ( $res[0] == 0 ) return 0; if ( $res[0] > 10 ) { $r = explode("\n", $res[2]); $i = count($r) - 11; for ( $j = 0 ; $j < 10 ; ++$j ) { $buf[] = $r[$i+$j]; } $res[0] = 'last 10'; } else $buf[] = $res[2]; return $res[0]; } function getLog($data) { $newlineTag = '[ERR[WAR[NOT[INF[DEB'; $levels = array( 'E' => 1, 'W' => 2, 'N' => 3, 'I' => 4, 'D' => 5 ); $level = $levels[substr($data['level'], 0, 1)]; $fd = fopen($data['filename'], 'r'); if ( !$fd ) { echo '<tr><td class="message_error" colspan=3>Failed to read server log from file '.$data['filename'].'</td></tr>'; exit; } $endpos = $data['endPos']; fseek( $fd, $data['fromPos'] ); $start = 0; $result = ''; $totalLine = 0; $line = 0; $cutline = 0; $buffer = fgets($fd); while ( !preg_match("/^\d{4}-\d{2}-\d{2} /", $buffer) ) { $buffer = fgets($fd); if ( $buffer === false ) break; $curpos = ftell($fd); if ( $curpos >= $endpos ) break; } do { $buffer = chop($buffer); // check if new line $c28 = substr($buffer, 28 , 3); if ( $c28 && strstr($newlineTag, $c28) ) { // is new line $totalLine ++; if ( $start ) { // finish prior line $result .= '</td></tr>' . "\n"; $start = 0; } $b28 = substr($c28, 0, 1); if ( $levels[$b28] <= $level ) { // start a new line $start = 1; $line ++; $style = 'log_' . $b28; $result .= '<tr><td class="col_time '. $style . '0">'. substr($buffer, 0, 26); $result .= '</td><td class="col_level '. $style . '1">'; $i = strpos($buffer, ']', 27); $result .= ( substr($buffer, 28, $i - 28) ); $result .= '</td><td class="col_mesg '. $style . '2">'; $result .= htmlspecialchars( substr($buffer, $i+2) ); } } elseif ( $start ) { // multi-line output $result .= '<br>'. htmlspecialchars($buffer); } $curpos = ftell($fd); if ( $curpos >= $endpos ) break; } while ( $buffer = fgets($fd) ); fclose($fd); if ( $start ) $result .= '</td></tr>'."\n"; $res = array(); $res[] = $line; $res[] = $totalLine; $res[] = $result; return $res; } function getServerLog() { if ( $this->serverLog == null ) { require_once('ConfigFileEx.php'); $confpath = $_SERVER['LS_SERVER_ROOT'] . "conf/httpd_config.xml" ; //fixed location $logpath = ConfigFileEx::grepTagValue($confpath, 'logging.log.fileName'); $this->serverLog = str_replace('$SERVER_ROOT', $_SERVER['LS_SERVER_ROOT'], $logpath); } return $this->serverLog; } function download($version) { //validate param if (!preg_match("/^\d+\.\d+(\.\d+)?(RC\d+)?$/", $version)) return false; $product = PRODUCT::GetInstance(); // e.g.: 'lsws-4.0.10-ent-i386-linux.tar.gz' $edition = 'std'; if ($product->edition == 'ENTERPRISE') $edition = 'ent'; $platform = $_SERVER['LS_PLATFORM']; if (strpos($platform, 'freebsd') !== FALSE) { $pfrelease = explode('.', php_uname('r')); if ($pfrelease[0] >= 6 ) { $platform .= '6'; } } $main_ver = $version[0] . '.0'; $file = strtolower($product->type) . '-' . $version . '-'. $edition . '-' . $platform . '.tar.gz'; $downloadurl = 'http://download.litespeedtech.com/packages/' . $main_ver . '/' . $file; $savedfile = $_SERVER['LS_SERVER_ROOT'] . 'autoupdate/' . $file; //echo "download url: $downloadurl\n"; $buffer = file_get_contents($downloadurl); if ($buffer == FALSE) return FALSE; $saved = fopen($savedfile, 'wb'); if ($saved == FALSE) return FALSE; $i = fwrite($saved, $buffer); if (!fclose($saved) || $i == FALSE) return FALSE; return TRUE; } function loadParam(&$holder, $line) { $t = preg_split('/[\s,:]/', $line, -1, PREG_SPLIT_NO_EMPTY); $c = count($t)/2; for ( $i = 0 ; $i < $c ; ++$i ) { if(is_array($holder) && array_key_exists($t[2*$i],$holder)) { $holder[$t[2*$i]] += $t[2*$i+1]; } else { $holder[$t[2*$i]] = $t[2*$i+1]; } } } public static function GetLoadAvg() { $load_avg = 'N/A'; $UPTIME = ''; $UPTIME = exec("uptime"); $UPTIME = strtolower( $UPTIME ); $pos = strpos($UPTIME, "load average"); if ( $pos > 0 ) { $pos += 13; if ( $UPTIME[$pos] == 's' ) ++$pos; if ( $UPTIME[$pos] == ':' ) ++$pos; $load_avg = trim(substr($UPTIME, $pos )); } return $load_avg; } }