Sindbad~EG File Manager

Current Path : /opt/cloudlinux/venv/lib64/python3.11/site-packages/xray/reconfiguration/
Upload File :
Current File : //opt/cloudlinux/venv/lib64/python3.11/site-packages/xray/reconfiguration/xray_ini.py

# -*- coding: utf-8 -*-

# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2021 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT

"""
Shared constants and helpers for xray.ini file management.
"""

import logging
import os
import pwd
import re
from typing import Optional

from xray.internal.utils import cagefsctl_get_prefix

logger = logging.getLogger(__name__)

# directories that don't matter for us
# php is either outdated or just internal
EXCLUDE_DIR_PATHS = (
    'php44', 'php51', 'php52', 'php53',
    'php\\d+-imunify', 'php-internal'
)

# global set of ini locations where php
# usually loads configuration files from
# some of them may be missing, like /opt/plesk
# which only exists on plesk
INI_LOCATIONS = (
    '/opt/alt/php[0-9][0-9]/link/conf',
    '/opt/cpanel/ea-php[0-9][0-9]/root/etc/php.d',
    '/opt/plesk/php/[0-9].[0-9]/etc/php.d',
    '/usr/local/php[0-9][0-9]/lib/php.conf.d',
    '/usr/share/cagefs/.cpanel.multiphp/opt/cpanel/ea-php[0-9][0-9]/root/etc/php.d',
    '/usr/share/cagefs-skeleton/usr/local/php[0-9][0-9]/lib/php.conf.d'
)

# Base user locations for xray.ini files
INI_USER_LOCATIONS = (
    dict(
        path='/var/cagefs/*/*/etc/cl.php.d/alt-php[0-9][0-9]',
        user=lambda path: pwd.getpwnam(path.split('/')[4])
        ),
)

# Per-website locations used when website isolation is enabled
# These directories are created by cagefsctl when enabling website isolation
INI_USER_LOCATIONS_WEBSITE_ISOLATION = (
    dict(
        path='/var/cagefs/*/*/etc/cl.php.d/*/alt-php[0-9][0-9]',
        user=lambda path: pwd.getpwnam(path.split('/')[4])
        ),
)


def is_excluded_path(dir_path: str) -> bool:
    """
    Check if given path is in exclude list.
    """
    for pattern in EXCLUDE_DIR_PATHS:
        if re.search(pattern, dir_path):
            return True
    return False


def get_domain_php_version_from_selector(user: str, website_id: str) -> Optional[str]:
    """
    Get the PHP version configured for a specific domain/website from cl.selector symlinks.

    Reads the 'php' symlink in /var/cagefs/{prefix}/{user}/etc/cl.selector/{website_id}/
    and extracts the alt-phpXX version from the target path.

    :param user: Username
    :param website_id: Website ID hash (e.g., 'd498d1a80d63f8e9')
    :return: PHP version directory name (e.g., 'alt-php80') or None if not found/native
    """
    prefix = cagefsctl_get_prefix(user)
    if prefix is None:
        return None

    selector_path = f'/var/cagefs/{prefix}/{user}/etc/cl.selector/{website_id}/php'

    try:
        if not os.path.islink(selector_path):
            return None

        target = os.readlink(selector_path)
        # Target looks like: /opt/alt/php80/usr/bin/php-cgi
        # Extract phpXX from the path
        match = re.search(r'/opt/alt/php(\d{2})/', target)
        if match:
            return f'alt-php{match.group(1)}'
    except OSError as e:
        logger.debug('Failed to read selector symlink %s: %s', selector_path, e)

    return None

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists