Sindbad~EG File Manager
# -*- 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