该系统为使用PHP开发的基于web的Subversion(SVN)服务器端管理工具。支持功能:SVN仓库管理、SVN用户管理、SVN分组管理、目录授权、目录浏览、Hooks管理、在线dump备份、在线备份恢复、SVN用户禁用、服务器状态管理、日志管理、消息通知、更新检测...
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

180 lines
4.7 KiB

<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
define('BASE_PATH', __DIR__);
require_once BASE_PATH . '/../config/config.php';
class Daemon
{
private $pidfile;
private $state;
private $cmdlist = array(
"start",
"stop",
"console"
);
function __construct()
{
$this->pidfile = dirname(__FILE__) . '/svnadmind.pid';
}
private function init_daemon()
{
$pid = pcntl_fork();
if ($pid < 0) {
exit("pcntl_fork 错误");
} elseif ($pid > 0) {
exit();
}
$sid = posix_setsid();
if (!$sid) {
exit("posix_setsid 错误");
}
$pid = pcntl_fork();
if ($pid < 0) {
exit("pcntl_fork 错误");
} elseif ($pid > 0) {
exit();
}
chdir("/");
umask(0);
if (defined('STDIN')) {
fclose(STDIN);
}
if (defined('STDOUT')) {
fclose(STDOUT);
}
if (defined('STDERR')) {
fclose(STDERR);
}
file_put_contents($this->pidfile, getmypid());
return getmypid();
}
private function init_socket()
{
//创建套接字
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create 错误");
//绑定地址和端口
socket_bind($socket, IPC_ADDRESS, IPC_PORT) or die("socket_bind 错误");
//设置可重复使用端口号
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
//监听 设置并发队列的最大长度
socket_listen($socket, SOCKET_LISTEN_BACKLOG);
while (true) {
//非阻塞式回收僵尸进程
pcntl_wait($status, WNOHANG);
$clien = socket_accept($socket) or die("socket_accept 错误");
//非阻塞式回收僵尸进程
pcntl_wait($status, WNOHANG);
$pid = pcntl_fork();
if ($pid == -1) {
die('pcntl_fork 错误');
} else if ($pid == 0) {
$this->handle_request($clien);
} else {
}
}
}
private function handle_request($clien)
{
//接收客户端发送的数据
$data = socket_read($clien, SOCKET_READ_LENGTH);
//console
$this->state == "console" ? print_r("\n---------接收内容---------\n" . $data . "\n") : "";
if (trim($data) != "") {
//执行
$result = shell_exec($data);
} else {
//探测程序会发送空信息
$result = "";
}
//console
$this->state == "console" ? print_r("\n---------执行结果---------\n" . $result . "\n") : "";
//处理没有返回内容的情况 否则 socket_write 遇到空内容会报错
$result = $result == "" ? ISNULL : $result;
//将结果返回给客户端
socket_write($clien, $result, strlen($result)) or die("socket_write 错误");
//关闭会话
socket_close($clien);
//退出进程
exit();
}
private function start_daemon()
{
if (file_exists($this->pidfile)) {
$pid = file_get_contents($this->pidfile);
$result = trim(shell_exec("ps -ax | awk '{ print $1 }' | grep -e \"^$pid$\""));
if (strstr($result, $pid)) {
echo "进程正在运行中 无需启动\n";
exit();
}
}
return $this->init_daemon();
}
private function start()
{
clearstatcache(true, DB_FILE);
if (!file_exists(DB_FILE)) {
echo "数据库文件不存在 请复制数据库文件到指定目录\n";
return;
}
$this->start_daemon();
$this->init_socket();
}
private function stop()
{
if (file_exists($this->pidfile)) {
$pid = file_get_contents($this->pidfile);
posix_kill($pid, 9);
unlink($this->pidfile);
}
}
public function run($argv)
{
if (isset($argv[1])) {
$this->state = $argv[1];
if (!in_array($this->state, $this->cmdlist)) {
echo "用法: php svnadmind.php [start] [stop] [console]\n";
exit();
}
if ($this->state == 'start') {
$this->start();
} else if ($this->state == 'stop') {
$this->stop();
} else if ($this->state == 'console') {
$this->init_socket();
}
} else {
echo "用法: php svnadmind.php [start] [stop] [console]\n";
}
}
}
$deamon = new Daemon();
$deamon->run($argv);