HEX
Server: LiteSpeed
System: Linux ws4.angoweb.net 5.14.0-611.13.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 11 04:57:59 EST 2025 x86_64
User: tswangoe (2287)
PHP: 8.1.33
Disabled: show_source, system, shell_exec, passthru, exec, phpinfo, popen, proc_open
Upload Files
File: //opt/alt/python37/lib/python3.7/site-packages/clquota/__pycache__/__init__.cpython-37.pyc
B

�%Ud��@s�ddlmZddlmZddlmZddlZddlZddlZddlZddlm	Z	ddl
ZddlZddl
Z
ddlmZmZmZmZmZddlmZddlmZdd	lmZmZdd
lmZmZmZmZddl m!Z!ddl"m#Z#dd
l$m%Z%m&Z&m'Z'ddl(m)Z)ddl*Z*ddl+Z+e+j,�-�Z.dZ/Gdd�de0�Z1Gdd�de0�Z2Gdd�de0�Z3Gdd�de0�Z4Gdd�de	�Z5Gdd�de0�Z6Gdd�de0�Z7Gdd�de7�Z8d d!�Z9d"d#�Z:e;d$�d%d&�Z<Gd'd(�d(e=�Z>dS))�)�print_function)�division)�absolute_importN)�FormattedException)�S_IRUSR�S_IWUSR�S_IRGRP�S_IROTH�ST_DEV)�map)�	iteritems)�CPAPIExternalProgramFailed�
EncodingError)�run_command�ExternalProgramFailed�write_file_lines�get_file_lines)�ClPwd)�defaultdict)�
list_users�admin_packages�resellers_packages)�check_quota_enabled�defaultc@seZdZdd�ZdS)�NoSuchPackageExceptioncCst�|d|f�dS)NzNo such package (%s))�	Exception�__init__)�self�package�r�A/opt/alt/python37/lib/python3.7/site-packages/clquota/__init__.pyr)szNoSuchPackageException.__init__N)�__name__�
__module__�__qualname__rrrrr r(src@seZdZdd�ZdS)�NoSuchUserExceptioncCst�|d|f�dS)NzNo such user (%s))rr)r�userrrr r.szNoSuchUserException.__init__N)r!r"r#rrrrr r$-sr$c@seZdZdd�ZdS)�InsufficientPrivilegesExceptioncCst�|d�dS)NzInsufficient privileges)rr)rrrr r3sz(InsufficientPrivilegesException.__init__N)r!r"r#rrrrr r&2sr&c@seZdZdd�ZdS)�IncorrectLimitFormatExceptioncCst�|d|f�dS)NzIncorrect limit format (%s))rr)r�limitrrr r8sz&IncorrectLimitFormatException.__init__N)r!r"r#rrrrr r'7sr'cs(eZdZdZejd��fdd�Z�ZS)�MalformedConfigExceptionz\
    Raised when config files is malformed and
    cl-quota is not able to work with it
    )�errorcs$tt|��dtt|�d�d��dS)Nz�cl-quota can't work because for malformed config. Please, contact CloudLinux support if you need help with resolving this issue. Details: %(error_message)s)�
error_message)�message�context)�superr)r�dict�str)rr*)�	__class__rr rAs
z!MalformedConfigException.__init__)r!r"r#�__doc__�ConfigParser�ParsingErrorr�
__classcell__rr)r1r r)<sr)c@seZdZdd�ZdS)�GeneralExceptioncCst�||�dS)N)rr)rr,rrr rOszGeneralException.__init__N)r!r"r#rrrrr r6Nsr6cseZdZ�fdd�Z�ZS)�QuotaDisabledExceptioncstt|��d�dS)Nz&Quota disabled for all users on server)r.r7r)r)r1rr rTszQuotaDisabledException.__init__)r!r"r#rr5rr)r1r r7Ssr7c@seZdZdZddd�ZdS)�UserQuotaDisabledExceptionz?
    Raised when quota is disabled for one particular user
    NcCsDd}|r|d|7}|r$|d|7}|r4|d|7}t�||�dS)NzQuota disabledz for user id %sz (home directory %s)z; %s)rr)r�uid�homedirr,Zall_msgrrr r\sz#UserQuotaDisabledException.__init__)NNN)r!r"r#r2rrrrr r8Xsr8cCsD|ddkr|d7}d}|dkr$dSx|D]}|�|�r*dSq*WdS)zd
    >>> _is_sys_path('/home/username')
    False
    >>> _is_sys_path('/var/davecot')
    True
    ����/)	z/root/z/usr/z/var/z/sbin/z/dev/z/bin/z/srv/z/sys/z	/etc/ntp/TN)�
startswith)�pathZ	sys_path_�path_rrr �_is_sys_pathgs

r@cs$t�}|����fdd��D�}|S)z)
    Return no system users uid list
    cs$g|]}t�|j�s�|j�qSr)r@�pw_dir�pw_uid)�.0Zusr)�pw_dictrr �
<listcomp>sz#_get_users_list.<locals>.<listcomp>)r�
get_user_dict)Zcl_pwdZ	users_uidr)rDr �_get_users_listxsrG)�returncCstjtjddd�}|S)zJ
    Check `cl_quota_inodes_inheritance` parameter in the config file
    Zcl_quota_inodes_inheritanceF)�default_val)�cldetectlib�get_boolean_param�CL_CONFIG_FILE)�resrrr �is_quota_inheritance_enabled�srNc@sFeZdZdZdZdZdZdZdZdZ	dZ
ed	Zd
Zdd�Z
ed
d��Zdd�Zdd�Zdd�Zdd�Zdd�Zd�dd�Zdd�Zd�dd�Zd�d d!�Zd�d"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Z ed2d3��Z!d�d4d5�Z"d�d6d7�Z#d�d8d9�Z$d�d:d;�Z%d�d<d=�Z&d�d>d?�Z'd�d@dA�Z(d�dBdC�Z)d�dDdE�Z*d�dFdG�Z+dHdI�Z,dJdK�Z-dLdM�Z.d�dNdO�Z/dPdQ�Z0d�dRdS�Z1dTdU�Z2dVdW�Z3dXdY�Z4dZd[�Z5d\d]�Z6d^d_�Z7d`da�Z8dbdc�Z9ddde�Z:dfdg�Z;dhdi�Z<djdk�Z=dldm�Z>dndo�Z?dpdq�Z@drds�ZAdtdu�ZBedvdw��ZCdxdy�ZDdzd{�ZEd|d}�ZFd~d�ZGd�d�d��ZHd�d��ZIdS)��QuotaWrapperz4
    Base quota class for inode quotas handling
    z/proc/mountsz/usr/sbin/setquotaz/usr/sbin/repquotaz%/usr/bin/getcontrolpaneluserspackagesz/etc/container/cl-quotas.datz/etc/container/cl-quotas.cacheNz.lockFcCs�|�tj�|�tj�|�tj�t�|_d|_i|_i|_	i|_
i|_i|_i|_
|��|_ddddddg|_t��|_|��|_|�|j�|_d|_d|_dS)N�
bytes_used�
bytes_soft�
bytes_hardZinodes_used�inodes_soft�inodes_hard)�_assert_file_existsrO�PROC_MOUNTS�REPQUOTA�SETQUOTA�list�_quota_enabled_list�_panel_present�_grace�_quota�
_device_quota�_package_to_uids_map�_uid_to_packages_map�_uid_to_homedir_map�_get_saved_data_handler�_dh�_fields�os�geteuid�_euid�_load_quota_devices�_devices�_get_mountpoint_device_map�_mountpoint_device_mapped�_device_user_map�_all_package_list)rrrr r�s$


zQuotaWrapper.__init__cCstj�|�std|f��dS)z>
        Checks if command is present and exits if no
        zNo such command (%s)N)rer>�exists�RuntimeError)r>rrr rU�sz QuotaWrapper._assert_file_existscCs|S)Nr)rrrr �	__enter__�szQuotaWrapper.__enter__cCs|j��dS)N)�LOCK_FD�close)r�type�value�	tracebackrrr �__exit__�szQuotaWrapper.__exit__cCs|�|�|��S)z9
        Returns user limits converted to tuples
        )�_convert_data_to_tuples�_get_current_quotas)rr9rrr �get_user_limits�szQuotaWrapper.get_user_limitscCs|�|���S)z=
        Returns all user limits converted to tuples
        )rwrx)rrrr �get_all_users_limits�sz!QuotaWrapper.get_all_users_limitscCs|�|j|d��S)z�
        :param packname: Package name for get limits. If None, returns all packages,
                          else - only supplied package
        Returns package limits converted to tuples (called only from main)
        )�packname)rw�_get_package_quotas)rrrrr �get_package_limits�szQuotaWrapper.get_package_limitscCs|�|j|dd��S)zY
        Returns all packages limits converted to tuples (called only from main)
        T)r{�all_packages)rwr|)rrrrr �get_all_packages_limits�sz$QuotaWrapper.get_all_packages_limitscCs"|dkrdS|dkrdS|�|�S)z�
        Preprocessed passed limit: 'default' --> '0', 'unlimited' --> -1, else calls _check_limit
        :param limit:
        :return:
        r�0)�	unlimitedz-1z-1)�_check_limit)rr(rrr �_preprocess_limit�s
zQuotaWrapper._preprocess_limitcCs�i}i}|j�d�r�t|j�d��dkr�|��}xf|j�d�D]V}|r^||kr^|j�d|�q>|j�d|��d�}t|�dkr�q>|d|df||<q>W|r�|�	�|�
�x0|j��D]"}||kr�||||<q�d||<q�W|S)z�
        Retrive all available packages with their limits
        :param clean_dead_packages: if True - remove all nonexistent packages from cl-quotas.dat
        :return: Dictionary: { 'package_name': (soft_limit, hard_limit) }
        �packagesr�:��)r�r�)
rc�has_section�len�items�_get_all_package_list�options�
remove_option�get�split�_write_data�_get_package_to_users_mapr_�keys)rZclean_dead_packages�package_limits_dictZdb_packages�list_of_packagesr�package_limitsrrr �_get_all_packages_with_limits�s( z*QuotaWrapper._get_all_packages_with_limitsTcCs0|s|dks|dkrdS|��|}|}	|�|�}|�|	�}|dk�r`|dkrRd}|dkr^d}|j�d�r�|j�dd�r�|j�dd��d�}
|p�|
d}|p�|
d}n|p�d}|p�d}|j||d�|�r|d	kr�d}n|dkr�|}|	d	kr�d}n|dkr�|}|jd||d
�|�	�}
xD|
D]<}|
|\}}|dk�s@|dk�r|j
||||||d��qWdS|�r||j|||d
�\}}nd\}}||}}|dk�s�|dk�r�d}|dk�s�|dk�r�d}|�|�}||}|d
|k�s�|d|k�s�|�r�|�
|�d}|tk�rl|j�d��rN|j�d|��rN|j�d|��d�}
|
d}|
d}nd}d}|�p^|}|�ph|}n|}|}tjd||d|d|||�|�|��g}t|�|�r�|dk�r�d}n|dk�r�|}|dk�r�d}n|dk�r�|}|�|||�|dk�r
|dk�s|dk�r,|dk�r,|�|||�dS)z=
        Sets limits for users
        :return: None
        Nr�z-1�usersr�rr�)�soft�hard)z-1r�)r9r�r�)�
only_store)r�r�rTrSz-urQrR)r�z-1)�_check_adminr�rcr��
has_optionr�r��_apply_to_all_if_not_set�_save_user_limitsr��set_package_limit�_combine_user_limitsrx�_get_uid_to_packages_map�DEFAULT_PACKAGErOrX�_get_home_device�_fetch_homedirr)rr9r�r��save�syncZ
force_saver�Zsoft_argZhard_arg�limitsZ
cache_softZ
cache_hardr�r�p_soft�p_hardZuser_combine_softZuser_combine_hard�	user_soft�	user_hard�saved_quotas�cachedZuser_package�
soft_limit�
hard_limit�cmdrrr �set_user_limits�





"






(zQuotaWrapper.set_user_limitc
Cs�t�}|tkrdS|s*|dks&|dkr*dS|��|�|�}|�|�}g}|r`|�|||�\}}|r�||jdd�kr�||��kr�|�|||�dSy|�|�Wntk
r�|r�dSYnX|�	�}	|�
�}
�x�|	��D�]�}�xB|�|�D�]2}||	|k�rq�|�t
|��d}
t�rdt��rdt��}|�|
�}||k�rd|�|d�}||d}||d}|j|||d�}|�s|q�|dk�r�d	}n|d�p�d	}|dk�r�d	}n|d
�p�d	}yR|�|
|d|
|df||f��s|�d||
|d|
|d
||f�Wq�tk
�r Yq�Xq�Wt|�dk�r6q�d�|�d}|�rv||jk�r`d|j|<|j|||j|<ntjd|g}t||d�g}q�W|�r�|�|||�dS)z?
        Sets limits for package
        :rtype : None
        NT)r~rrSrT)r9r�r�z-1r�r�z%s %s %s %s %srQrR�
�z-bu)�std_in)rr�r�r��!_get_saved_package_limits_if_noner|r��_save_package_limitsr�_get_device_user_maprxr��	get_names�int�IS_DArN�clcontrollib�DirectAdminZ_get_user_package�_combine_package_limits�limits_are_equal�append�KeyErrorr��joinr^rOrXr)rrr�r�r�r�r��clpwdr��device_user_mapr��devicer9�_user�panelZ
_real_packageZ_real_quotas�datar�r�r�rrr r�{s�








zQuotaWrapper.set_package_limitc		Cs|��|�d�}x0|��D]$}||\}}|j|||ddd�qWi|_|j�d�r�x�|j�d�D]t}yL|�|�|j�	d|��
d�}t|�dkr�wd|\}}|j|||ddd�Wqdt
k
r�|j�d|�YqdXqdW|��x0|j��D]"}tjd|g}t||j|d�q�Wd	S)
zN
        Read limits from file and applies them to packages and users
        TF)r�r�r�r�z-bu)r�N)r�r�r�r�r]rcr�r�r�r�r�r�r�r$r�r�r^rOrXr)	rr�rr�r�r9r�r�r�rrr �synchronize�s*

zQuotaWrapper.synchronizec	s�|��g}|���xBtt����td�D]*�|��gtt��fdd�|j���q*W|�	d�|�
tj�}t
j|t
jd�}|�|�|�tj�|��dS)zF
        Caches the limits to non-privileged user to see them
        )�keycs��|S)Nr)�x)�current_quotas�krr �<lambda>��z.QuotaWrapper.save_user_cache.<locals>.<lambda>T)�quotingN)r�rx�sortedrYr�r�r�rrd�_get_global_lock�_prepare_writerrO�	CACHEFILE�csv�writer�
QUOTE_MINIMAL�	writerows�_end_writer�
_release_lock)r�
cache_content�file_handler�csv_outr)r�r�r �save_user_cache�s*

zQuotaWrapper.save_user_cachecCs&|jdkr dtddg���k|_|jS)z6
        Return True if control panel present
        N�Unknownz/usr/bin/cldetectz--detect-cp-nameonly)r[r�rstrip)rrrr �_check_present_panel�s
z!QuotaWrapper._check_present_panelcCs|jdkrt��dS)z2
        Raise exception if no admin user
        rN)rgr&)rrrr r�s
zQuotaWrapper._check_adminc
Csp|�d�tjddd�}t|_zBy|�tj�Wn,tjk
r\}zt|��Wdd}~XYnXWd|�	�X|S)z:
        Gets ConfigParser handler for future use
        TNF)�
interpolation�strict)
r�r3r0�optionxform�readrO�DATAFILEr4r)r�)r�dh�errr rb
s

z$QuotaWrapper._get_saved_data_handlerc	Cs�|jdk	r|jSi}g}xF|��D]:}y|�|�|�|��|f�Wq"tk
rZw"Yq"Xq"Wx:|D]2}|d|kr�g||d<||d�|d�qfW||_|jS)zF
        Returns dictionary mapping devices to lists of users
        Nrr�)rl�_get_list_of_uidsr�r�r�r�)rZdevices_mapZdevice_user_pairsr9�pairrrr r�s

z!QuotaWrapper._get_device_user_mapcCs>|dks|dkr|St�d�}|�|�}|s4t|��|�d�S)Nz-1z(\d+)r�)�re�compile�searchr'�group)rr(Z
limit_patternZ
pattern_matchrrr r�0s

zQuotaWrapper._check_limitcCs||krdSdS)z�
        Compare tuples
        :param limits1: tuple
        :param limits2: tuple
        :return: True of tuple 1 equal to tuple 2
        TFr)Zlimits1Zlimits2rrr r�9szQuotaWrapper.limits_are_equalc
Cs�g}|��}|��}x�|��D]�}tjd|g}x�|��D]�}|||ks8t|�|�krXq8|j|||d�}	|	snq8|�	||d||df|	�s8|�
d|||d||d|	dp�d	|	d
p�d	f�q8Wt|�dkr�qd�|�d}t
||d�g}qWd
S)zr
        Applies limits to all users if no other (user or package) ones has
        not been set for them
        z-bu)r9r�r�rSrTz%s %s %s %s %srQrRrr�r�r�)r�N)r�rxr�rOrXr�r�r��_combine_default_limitsr�r�r�r�r)
rr�r�r�r�r�r�r�r9r�rrr r�Es. 


z%QuotaWrapper._apply_to_all_if_not_setcCsx|j|||d�\}}d\}}x&|�|�D]}|j|||d�\}}q(W|jd||d�\}	}
|	dkrdd}	|
dkrpd}
|	|
fS)zc
        Determines user limits taking into account
        saved package and default ones
        )r9r�r�)NN)rr�r�r�N)�_get_saved_user_limits_if_noner��*_get_saved_package_limits_if_none_or_unlim�'_get_saved_user_limits_if_none_or_unlim)rr9r�r�Zu_softZu_hardr�r�rZd_softZd_hardrrr r�csz!QuotaWrapper._combine_user_limitscCsD|j|d�\}}|r|rdS|dkr(|}|dkr4|}|jd||d�S)zc
        Determines package limits taking into account
        saved user and default ones
        )r9rNr�)r9r�r�)r�r�)rr9r�r��t_soft�t_hardrrr r�usz$QuotaWrapper._combine_package_limitscCsH|j|d�\}}|dk	r|}|dk	r(|}|dkr4d}|dkr@d}||fS)z�
        Determines default limits taking into account saved user and package ones
        :param soft: soft limit from uid=0
        :param hard: hard limit from uid=0
        )r9Nz-1r�)r�)rr9r�r�r�r�rrr r��sz$QuotaWrapper._combine_default_limitsc	Cs~yD|j�d|��d�\}}|dkr.|dkr.|}|dkrB|dkrB|}Wntjtjfk
r`YnX|�|�}|�|�}||fS)z?
        Retrives saved user limits if none has passed
        r�r�Nr�)rcr�r�r3�NoSectionError�
NoOptionErrorr�)rr9r�r�r�r�rrr r��s

z+QuotaWrapper._get_saved_user_limits_if_nonec	Cs�yl|j�d|��d�\}}|dkr&d}|dkr2d}|dksB|dkrN|dkrN|}|dks^|dkrj|dkrj|}Wntjtjfk
r�YnX|�|�}|�|�}||fS)zN
        Applies saved user limits if none or unlimit has been passed
        r�r�z-1r�N)rcr�r�r3r�r�r�)rr9r�r�r�r�rrr r��s

z4QuotaWrapper._get_saved_user_limits_if_none_or_unlimc	Cs�|tkrjyD|j�d|��d�\}}|dkr6|dkr6|}|dkrJ|dkrJ|}Wntjtjfk
rhYnX|�|�}|�|�}||fS)zA
        Applies saved package limits if none has passed
        r�r�Nr�)r�rcr�r�r3r�r�r�)rrr�r��	pack_soft�	pack_hardrrr r��s

z.QuotaWrapper._get_saved_package_limits_if_nonec	Cs�|tkrzyT|j�d|��d�\}}|dks2|dkr>|dkr>|}|dksN|dkrZ|dkrZ|}Wntjtjfk
rxYnX|�|�}|�|�}||fS)zQ
        Applies saved package limits if none or unlimit has been passed
        r�r�Nr�)r�rcr�r�r3r�r�r�)rrr�r�r�r�rrr r��s

z7QuotaWrapper._get_saved_package_limits_if_none_or_unlimcCsb|jdkr|��S|js"|��|_|r\y||j|iStk
rZ|�|�t|��YnX|jS)z�
        Retrieves current quotas.
        If euid == 0, use data from repquota utility, else from /etc/container/cl-quotas.cache file
        r)rg�_load_user_cacher]�_load_current_quotasr��_check_if_quota_enabledr$)rr9rrr rx�s


z QuotaWrapper._get_current_quotasc	
Csi}|r|��}n|��}x�|D]�}dg}yx|dkrN|j�dd��d�\}}n|j�d|��d�\}}|�|�}|�|�}|dkr�d}|dkr�d}|�||g�Wn*tjtj	fk
r�|�ddg�YnX|�
|�||��q W|�ry|||iStk
�rt
|��YnX|S)aa
        Prepares package limits data for outputting
        (call only from get_package_limits/get_all_packages_limits - main)
        :param packname: Package name for get limits. If present, function returns
                            limits only for this package, else - all packages
        :param all_packages: If False reads only used and admin's packages, True - all packages
                                (including reseller packages without users)
        :return Dictionary of package limits:
            {package_name: {'inodes_used': 'xxx', 'inodes_soft': 'yyy', 'inodes_hard': 'zzz'}
        �-rr�r�r�r�z-1)r��_get_list_of_packagesrcr�r�r��extendr3r�r��update�	_populater�r)	rr{r~�qr�r�valuesr�r�rrr r|�s4



z QuotaWrapper._get_package_quotasc	s,|ttt�fdd�t|jdd�����iS)Ncs|d�|dfS)Nr�rr)r�)r�rr r� r�z(QuotaWrapper._populate.<locals>.<lambda>�)r/rYr�	enumeraterd)r�itemr�r)r�r r�szQuotaWrapper._populatecCst|�����S)N)rYr�r�)rrrr r�"sz"QuotaWrapper._get_list_of_packagescCst|�����S)N)rYr�r�)rrrr r�%szQuotaWrapper._get_list_of_uidscCsB|js|��|_|r<y
|j|Stk
r:t|��YnX|jS)N)r_�_load_package_uids_datar�r)rrrrr r�(s

z&QuotaWrapper._get_package_to_users_mapcCsF||jkrdS|�|�}t|d�}|r6t|||d��n|j�|�dS)N)r>)r9r:r,)rZr�rr8r�)rr9Zhome_dirZquota_disabled_messagerrr r�2s


z$QuotaWrapper._check_if_quota_enabledcCsB|js|��|_|r<y
|j|Stk
r:t|��YnX|jS)N)r`rr_r�r$)rr9rrr r�<s

z%QuotaWrapper._get_uid_to_packages_mapc	
Csy
t�}Wn8tttfk
rB}ztdt|���Wdd}~XYnXtt�}tt�|_xBt	|�D]6\}}t|�}|d}||�
|�|j|�
|�q`Wytdd�}Wn6ttfk
r�}ztdt|���Wdd}~XYnXx|D]}||kr�q�g||<q�Wt|k�rg|t<|S)z�
        Retrieve package-uids map from cpapi. Only for custom panels. See LU-610 for details
        :return: Dictionary with data. Example:
            {'default': ['1038', '1043', '1046'], 'res1_pack1': ['1044'], 'pack1': ['1042']}
        z%s. Can not get usersNrT)�	raise_excz%s. Can not get admin packages)
r�OSErrorr
rrr0rrYr`rr�rr�)	rZusers_packagesr�Zpackages_usersr9Zuid_dataZs_uidrZ
admin_pkgsrrr �_get_packages_uids_from_cpapiFs,
"
"

z*QuotaWrapper._get_packages_uids_from_cpapicCsRi}|jdkr|S|��sJtttt���|t<tdd�|tD��|_|S|�	�S)z�
        Gets map of packages and users
        :rtype dict
        :return Dictionary with data. Example:
            {'default': ['1038', '1043', '1046'], 'res1_pack1': ['1044'], 'pack1': ['1042']}
        rcss|]}|tfVqdS)N)r�)rC�irrr �	<genexpr>ysz7QuotaWrapper._load_package_uids_data.<locals>.<genexpr>)
rgr�rYrr0rGr�r/r`r)rr�rrr rks
z$QuotaWrapper._load_package_uids_datac
Cs|jr|jSy.g|_tdd�}x|D]}|j�|�q$WWn6ttfk
rp}ztdt|���Wdd}~XYnXy:tdd�}x*|��D]}x|D]}|j�|�q�Wq�WWn6ttfk
r�}ztdt|���Wdd}~XYnXt	|jkr�|j�t	�|jS)zm
        Retrives all (root and resellers) panel package list
        :return: List of package names
        T)rz%s. Can not get admin packagesNz!%s. Can not get reseller packages)
rmrr�rr
rr0rrr�)rZlist_admin_packagesrr�Zdict_resellers_packages�
packages_listrrr r�~s&

"

"
z"QuotaWrapper._get_all_package_listc	s\xV���D]J�y.tt��fdd�|jdd���}|��<Wq
tk
rRw
Yq
Xq
W�S)zI
        Convert dict to tuples for passing to printing routines
        cs|��|fS)Nr)r�)r�r�rr r��r�z6QuotaWrapper._convert_data_to_tuples.<locals>.<lambda>rN)r��tuplerrdr�)rr��entryr)r�r�r rw�sz$QuotaWrapper._convert_data_to_tuplescsti}d}�j}tjdg}t|�}t�dtj�}�x0|��D�]"}|�d��r|sRq:|�	�}t
|�dkrp��|�}|ddd�}	|	dkr�q:yZ||kr���|�}||kr��
��|	�|�r�ttt�fd	d
�t|dd�����||	<Wntttfk
�rw:YnXq:|�d��r*||�d
�d���}q:d|kr:|�|�}
|
r:�j�tttdd
�|
����q:W|�����|S)zZ
        Gets current quota settings from repqouta utility for further processing
        Nz-unaz2(block|inode)\sgrace\stime:?\s(\d[\w:]+)(?:;|$|\s)�#�rr�r�cs�j|d|dfS)Nrr�)rd)r�)rrr r��r�z3QuotaWrapper._load_current_quotas.<locals>.<lambda>r�z***z/devZgracecSs|d��|dfS)Nrr�)�lower)r�rrr r��r�)rirOrWrr�r��
IGNORECASE�
splitlinesr=r�r��#_remove_redundant_fields_from_input�_find_unknown_device�_is_home_devicer�r/rYrrr��
IndexErrorr$�find�strip�findallr\r��_add_default)rrr��devicesr�r�Zgrace_regex_pattern�line�partsr9�foundr)rr r��s>


.

"z!QuotaWrapper._load_current_quotascs:|dd�}t�d��|��fdd�|dd�D��|S)Nr�z^\d+$csg|]}��|�r|�qSr)r�)rC�field)�is_digit_patternrr rE�szDQuotaWrapper._remove_redundant_fields_from_input.<locals>.<listcomp>)r�r�r�)rrZstripped_partsr)r r r�s

z0QuotaWrapper._remove_redundant_fields_from_inputcCsXt|j�dkr,|j�tdd�t��D���y
|j|Stk
rRt|��YnXdS)Nrcss|]}t|j�|jfVqdS)N)r0rBrA)rCr
rrr r
�sz.QuotaWrapper._fetch_homedir.<locals>.<genexpr>)r�rar�r/�pwd�getpwallr�r$)rr9rrr r��s
zQuotaWrapper._fetch_homedirc	Cs�i}ttj�}t�d�}x�|D]�}|�d�r.q|�|�}|d}d|di}xP|D]H}|�d�sj|�d�r~|�d�d|d	<qR|�d
�rR|�d�d|d<qRW||kr�||�|�q|g||<qW|��t	|�dkr�t
��|S)aj
        Gets mounted filesystems list and picks ones with quota on

        Example of returned data structure:
            {'/dev/mapper/VolGroup-lv_root': [
                {'mountpoint': '/', 'quota_file': 'quota.user', 'quota_type': 'vfsv0'},
                {'mountpoint': '/var', 'quota_file': 'quota.user', 'quota_type': 'vfsv0'}
                ],
            '/dev/mapper/VolGroup-lv_root2': [
                {'mountpoint': '/', 'quota_file': 'quota.user', 'quota_type': 'vfsv0'},
                {'mountpoint': '/var', 'quota_file': 'quota.user', 'quota_type': 'vfsv0'}
            ]
            }
        z |,zrootfs /r�
mountpointr�z	usrquota=zusruota=�=Z
quota_filezjqfmt=Z
quota_type)�openrOrVr�r�r=r�r�rrr�r7)	rrZproc_mounts_streamZ
split_pattr�line_splitedr��mountpoint_dataZline_splited_elementrrr rh�s*






z QuotaWrapper._load_quota_devicescs�i}zVy$���ttj�}tj|dd�}Wn,ttfk
rVt�j	�t
��jd�iSXWd��
�Xt�j	�}xN|D]F��d|krv|��dt
tt��fdd�tt�j�����i�PqvW|s�t�j	�t
��jd�iS|S)zJ
        For non-privileged user we outputting data from the file
        �,)�	delimiterr�Nrcs�j|�|dfS)Nr�)rd)r�)�rowrrr r�sz/QuotaWrapper._load_user_cache.<locals>.<lambda>)r�r%rOr�r��readerr�IOErrorr0rgr/�fromkeysrdr�r�rYr�ranger�)rr�foZcvs_inr9r)r*rr r�s$



zQuotaWrapper._load_user_cachecCsXdd�}g}x8t|�D],\}}x"|D]}|d}|�||f�q$WqW|j|dd�|S)z�
        return list tuple ('mountpoin tpath', 'device') reverse sorted by deep mountpoint path
        [('/mountpoint_path/path', '/device'), ('/mountpoint_path', '/device')]
        cSs$|ddkrd}n|d�d�}|S)Nrr<)�count)Zdevice_mountpointZ	deep_pathrrr �sort_by_deep_path$szBQuotaWrapper._get_mountpoint_device_map.<locals>.sort_by_deep_pathr#T)r��reverse)rr��sort)rrr1Zmountpoint_device_mapr�Zmountpoint_data_listr'Zmountpoint_pathrrr rjs
z'QuotaWrapper._get_mountpoint_device_mapcCsBdd�}|tj�|��}x$|jD]\}}|�||��r |Sq WdS)z3
        Returns device user homedir is on
        cSs|r|ddkr|d7}|S)Nr;r<r)r>rrr �
_add_slash6sz1QuotaWrapper._get_home_device.<locals>._add_slashN)rer>�dirnamerkr=)r�homer4r5Zmounpoint_pathr�rrr r�2s
zQuotaWrapper._get_home_devicecCs|�|�|kS)z;
        Checks if a device is user homedir device
        )r�)rr6r�rrr r?szQuotaWrapper._is_home_devicecCs~ydt�|�t}t�|�t�|�f}x<|j��D].}t�|�t}|t�|�t�|�fkr0|Sq0WWntk
rx|SXdS)N)re�statr
�major�minorrir�r)rr��devZdev_to_findZcurrent_devicerrr rEsz!QuotaWrapper._find_unknown_devicec	s�ddddg�yB|j�dd��d�\}}|dkr2d}|dkr>d}��||g�Wn*tjtjfk
rx��ddg�YnXdttt	�fdd�t
|j����iS)zw
        Insert 'default' quota.
        Calls only from _load_current_quotas, after parsing repquota's output
        r�r�r�r�z-1cs|d�|dfS)Nr�rr)r�)rrr r�`r�z+QuotaWrapper._add_default.<locals>.<lambda>)rcr�r�r�r3r�r�r/rYrrrd)rr�r�r)rr rPszQuotaWrapper._add_defaultcCs�|dkrd}|dkrd}|�|||�\}}|dks:|dkrf|dksV|dkrf|j�d�rf|j�d|�n0|j�d�s~|j�d�|j�d|d||f�|��dS)z#
        Saves user limits
        Nr�r�z%s:%s)r�rcr�r��add_section�setr�)rr9r�r�rrr r�bszQuotaWrapper._save_user_limitscCs�|dkrd}|dkrd}|�|||�\}}|dks:|dkrf|dksV|dkrf|j�d�rf|j�d|�n0|j�d�s~|j�d�|j�d|d||f�|��|�|�dS)z&
        Saves package limits
        Nr�r�z%s:%s)r�rcr�r�r;r<r��_copy_package_limits_to_cpanel)rrr�r�rrr r�ts z!QuotaWrapper._save_package_limitscCst��sdSd|��}t|�}t|�dkr.dS|�|�\}}|dkrP|dkrPdS|j|dd�|}x$|��D]\}}|dkrld||<qlW|�|�dd	�|�d
d	�f|d|d
f�r�dSx6dD].}	dt	|	�d
t	||	�d}
|�
|
�q�Wt||d�dS)zV
        Copy package quota limits from cl-quotas.dat to cpanel packages data
        Nz/var/cpanel/packages/rT)r~r�z-1rSr�rT)rSrT�lve_r$r��w)rJ�	is_cpanelrr��_parse_cpanel_package_datar|r�r�r�r0r�r)rr�package_path�cpanel_package_lines�old_cpanel_dataZmodified_cpanel_linesZquotas_datar�rtZ
limit_typeZlimit_stringrrr r=�s*

 z+QuotaWrapper._copy_package_limits_to_cpanelcCs�|dd�}i}xx|D]p}|�d�rp|���d�}|d�dd���}|ddkr^|d||<|dkrp|�|�|�d	�rd
|krdSqW||fS)z�
        Process cpanel_package_lines - get values of all old lve_ limits
        and remove lines with limits that would be changed
        Nr>r$rr�r��DEFAULT)rSrTZ_PACKAGE_EXTENSIONS�lve)NN)r=rr��replace�remove)rCZcpanel_package_lines_modifiedrDr�
line_partsZ
limit_namerrr rA�s


z'QuotaWrapper._parse_cpanel_package_datacCsx|dkr<|dkr<y|j�||�Wqltjk
r8YqlXn0|j�|�sT|j�|�|j�||d||f�|��dS)z&
        Saves data to a file
        r�z%s:%sN)rcr�r3r�r�r;r<r�)rr�r�rZ	item_typerrr �
_save_data�szQuotaWrapper._save_datac	Csptj�|�}y(tjd|d�\}}t�|d�}||_|Sttfk
rjtj�	|�r^t�
|�td��YnXdS)zH
        Open temporary file for writing and return file object
        Zlvetmp_)�prefix�dirr?zCould not save dataN)rer>r5�tempfile�mkstemp�fdopen�_tmpr,rrn�unlinkr6)r�filepathr>�fd�	temp_pathr�rrr r��s
zQuotaWrapper._prepare_writercCsHy.ttBtBtB}t�|j|�t�||�Wntk
rBYnXdS)z0
        Routines after writing to file
        N)	rrrr	re�renamerP�chmodr)rr>�maskrrr r��szQuotaWrapper._end_writercCs:|�d�|�tj�}|j�|�|�tj�|��dS)z7
        Actual place of saving data to a file
        TN)r�r�rOr�rc�writer�r�)rr�rrr r��s

zQuotaWrapper._write_datac	Cs�|r
dt_tjdkr~yttjd�t_Wn ttfk
rFtd��YnXyt�	tj�
�tj�Wntk
r|td��YnXdS)NT�rz Can't open lock file for readingzCan't get lock)rO�
LOCK_WRITErqr%�	LOCK_FILEr,rr6�fcntl�flock�fileno�LOCK_EX)rrXrrr r��s
zQuotaWrapper._get_global_lockcCs$tjs tjdk	r tj��dt_dS)N)rOrZrqrr)rrrr r��s
zQuotaWrapper._release_lock)N)F)NNTTFF)NNTTF)NN)NN)NN)NN)NN)NN)NN)NN)N)NF)N)N)F)Jr!r"r#r2rVrXrWZGETPACKSr�r�rqr[rZr�staticmethodrUrprvryrzr}rr�r�r�r�r�r�r�r�rbr�r�r�r�r�r�r�r�r�r�r�rxr|r�r�r�r�r�r�rrr�rwr�rr�rhr�rjr�rrrr�r�r=rArJr�r�r�r�r�rrrr rO�s�

"
r
S	









-




%
$'


rO)?�
__future__rrrrer�r!r��clcommonr�configparserr3rMr\r7rrrr	r
�builtinsr�future.utilsr�clcommon.cpapi.cpapiexceptionsr
r�clcommon.utilsrrrr�clcommon.clpwdr�collectionsr�clcommon.cpapirrrZclcommon.clquotarrJr��detect�is_dar�r�rrr$r&r'r)r6r7r8r@rG�boolrN�objectrOrrrr �<module>	sF