HEX
Server: Apache/2.4.65 (Unix) OpenSSL/1.1.1k
System: Linux vps109042.inmotionhosting.com 4.18.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64
User: cisa (1010)
PHP: 8.2.30
Disabled: NONE
Upload Files
File: //opt/cwprads/__pycache__/sparta.cpython-313.pyc
�

���i0f����SrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKrSSK
r
SSKrSSKrSSKrSSKrSSKrSSKJr SSKJr SSKJr SSKJr SSKJrJrJr SSKJ r! SS	KJ"r" SSK#r#SSK$r$SS
K%J&r& SSK'J(r( \"SS
9r)\RTRW5r,Sr-\R\"S5r/"SS\R`5r1GSGSjr2"SS5r3"SS5r4"SS5r5\"SS55r6Sr7Sr8Sr9Sr:S r;S!r<S"r=S#r>S$r?S%r@S&rAS'rBGSHS(jrCS)rDS*rES+rF1S,krGS-rHS.rIGSIS/jrJS0rKS1rLS2rMS3rNS4rOS5rPS6rQS7rRS8rSS9rTS:rUS;rVS<rWS=rXS>rYS?rZS@r[GSJSAjr\SBr]SCr^GSJSDjr_SEr`SFraSGrbSHrcSIrdGSKSJjreSKrfSLrgSMrhSNriSOrjSPrkSQrlSRrmSSrnSTroSUrpSVrqSWrrSXrsSYrtSZruS[rvS\rwS]rxGSLS^jryS_rzS`r{Sar|Sbr}GSMScjr~SdrSer�Sfr�Sgr�Shr�Sir�Sjr�Skr�Slr�Smr�GSNSnjr�Sor�Spr�Sqr�Srr�Ssr�Str�Sur�Svr�Swr�Sxr�Syr�Szr�S{r�S|r�S}r�S~r�\GR4"S\GR65r�\GR4"S�5r�\GR4"S�5r�\GR4"S�5r�S�\�S\�4S�jr�S\�4S�jr�S�\�S\�4S�jr�S�\�SS4S�jr�S�\�S�\�S\\�4S�jr�S\\�4S�jr�S\\�4S�jr�S\\�4S�jr�S\\�4S�jr�S�\�S\\�4S�jr�S�r�S�r�S�r�S�r�S�r�S�r�S�r�S�r�S�r�S�r�S�r�S�\�S\�4S�jr�S�\�4S�jr�S�r�S�r�S�r�S�r�S�\�S\�4S�jr�GSOS�\�S�\�S\GR~4S�jjr�S\\�4S�jr�S�\�S�\\�4S�jr�S�\�S\\�4S�jr�S�\�S\�4S�jr�S�\\�S\�4S�jr�S�\�S�\�S\\�4S�jr�S�\�S�\�S�\�S�\\�4S�jr�S�\�S\\�4S�jr�S�\�S�\�S�\�S\�4S�jr�S�\�SS4S�jr�S�\�S�\�S\�4S�jr�S�r�S�r�S�r�GSPS�jr�S�r�S�r�S�r�S�r�S�r�S�r�S�r�\GR4"S�\GR65r�S�r�S�r�S�r�S�r�S�r�S�\�S\�4S�jr�S�\�4S�jr�S�r�S�r�S�\�S�\�S�\�4S�jr�S�\�S�\�S�\�4S�jr�S�\�S�\�S�\�4S�jr�S�\�S�\�S�\�S�\�S�\�4
S�jr�S�\�4S�jr�S�r�S�r�S�r�S�r�S�r�S�r�GSQS�jr�S�r�S�r�S�r�S�r�S�r�S�r�S�r�S�r�S�r�S�\�4S�jr�S�\�S�\�S�\�4S�jr�S�\�S�\�4S�jr�S�r�S�r�S�r�S�r�S�r�S�S�/S�//GSQGS/GS/GS/GS/GS.GS//GSQGS/GS	/GS
/GS/GS/GS
./GSQGSGS/GSGS/GS/GS/GS/GS/GS/GS.GS/GS/GS/GS.GS/GSGS/GS /GS!/GS"/GS#GS$/GS%/GS&GS'/GS(GS)/GS*/GS+.
GS,/GS-/GS./GS//GS0.GS1.r�GS2GrGSIGS3jGrGSRGS4jGrGS5GrGS6GrGS7GrGS8GrGSIGS9jGrGS:GrGS;Gr	GS<Gr
GS=GrGS>GrGS?Gr
GS@GrGSAGrGSBGrGSCGrGSDGrGSEGrG\GSF:Xa	G\"5 gg(Su�
SPARTA: System Performance Audit & Reporting Tool for Analysts
A command-line auditor that produces a full Markdown report of system health, resources, services, and a site’s context within the server.
Built by Dakota P.
�N)�Counter)�ThreadPoolExecutor)�	dataclass)�Path)�List�Optional�Set)�error)�request)�whmapi1)�color�)�max_workersz/var/log/SPARTA.log�SPARTAc�(^�\rSrSrU4SjrSrU=r$)�NewlineStreamHandler�0c�>�URRS5 URR5 [TU]U5 g![a Nf=f�N�
)�stream�write�flush�	Exception�super�emit)�self�record�	__class__s  ��/opt/cwprads/sparta.pyr�NewlineStreamHandler.emit2sL���	��K�K���d�#��K�K����	���V����	��	�s�5A�
A�A�)�__name__�
__module__�__qualname__�__firstlineno__r�__static_attributes__�
__classcell__)rs@r rr0s
�����r�returnc��[[SSS9 [R"[S5 SSS5 [R[R5 [R(ag[R"[5nUR[R5 UR[R"S55 [5nUR[R5 UR[R"S55 [R!U5 [R!U5 g!,(df   GN=f![an[S[SU35UeSnAff=f)N�a�utf-8��encodingz#[FATAL] Failed to prepare log file �: z'%(asctime)s [%(levelname)s] %(message)sz%(levelname)s: %(message)s)�open�LOG_FILE�os�utimer�
SystemExit�logger�setLevel�logging�DEBUG�handlers�FileHandler�setFormatter�	Formatterr�WARNING�
addHandler)�exc�file_handler�console_handlers   r �
setup_loggingrC;s���
�(�C�'�
2��H�H�X�t�$�3��O�O�G�M�M�"�
�����&�&�x�0�L����'�-�-�(�������C�D��+�,�O����W�_�_�-�� � ����6�7�����l�#�
���o�&�33�
2�����1�(��2�c�U�C�
��	���s3�E�E�E�
E�E�E�
E<�!E7�7E<c�T�\rSrSrSrSSSSS.SjrS	\S
\4SjrSr	SSjr
SrSrg
)�ProgressBar�[u�
Simple TTY-friendly progress bar with ANSI coloring.

Renders like:
  Building: <section> 73%
  |██████████████████████████████░░░░░░░░░░░░|
  Checking bounces/defers
�2z	Progress:�Complete�)�width�prefix�suffix�decimalsc��[S[U55Ul[U5Ul[	U5Ul[	U5Ul[U5UlSUl[RR5Ul[R"S5UlSUlSUlSUlSUlSUlg)NrIr�\x1b\[[0-9;]*mz��)�max�int�totalrJ�strrKrLrM�	iteration�sys�stdout�isatty�_is_tty�re�compile�_ansi_re�_color_bold�_color_blue�_color_reset�
_bar_width�_lines_drawn)rrTrJrKrLrMs      r �__init__�ProgressBar.__init__es�����C��J�'��
���Z��
��&�k����&�k����H�
��
�����z�z�(�(�*����
�
�#4�5��
�$���%���%��������r)�valuer*c�L�[URRSU55$)N�)�lenr]�sub)rres  r �_visible_len�ProgressBar._visible_lens���4�=�=�$�$�R��/�0�0r)c
���UR(dURUlgURbg[R"5R
nSSURS3nURSURUSUR3nURU5n[S[UR[SU5U-
55Ulg![a SnN�f=f)	N�P�d�.�f� �%�
�)rZrJra�shutil�get_terminal_size�columnsrrMrKr^r`rjrR�min)r�	term_cols�sample_percent�
sample_out�reserveds     r �_ensure_bar_width�ProgressBar._ensure_bar_width�s����|�|�"�j�j�D�O���?�?�&��	��0�0�2�:�:�I� ��$�-�-���1�2���{�{�m�1���� �� 0��$�2C�2C�1D�
F�	��$�$�Z�0�����D�J�J��B�	� 2�X� =�>�
�����	��I�	�s�C�C!� C!Nc���Uc)[URURS-5UlOy[U[5(a2[URURU(aSOS-5UlO1[U5n[
S[URU55UlUR(aUR5 URnOURnSUR[UR5--nUSURS3n[X0R-UR-5nSU-SX6-
--nUR(aIURSUR US	UR"3nUR$S
US
UR"3n	OURSUS	3nS
US
3n	UR&=(d Sn
UR(d�[(R*R-US-5 [(R*R-U	S-5 [(R*R-U
S-5 [(R*R/5 gUR0(a�[(R*R-S
UR0S35 [3UR05H"n[(R*R-S5 M$ [(R*R-S
UR0S35 [(R*R-US-5 [(R*R-U	S-5 [(R*R-U
S-5 [(R*R/5 SUlg![[4a, [URURS-5UlGN-f=f![4a� [(R*R-US-5 [(R*R-U	S-5 [(R*R-U
S-5 [(R*R/5 gf=f)NrIrrnrorpu█u░rqrr�|rgrz[�Fz
�)rxrTrV�
isinstance�boolrSrR�	TypeError�
ValueErrorrZr}rarJ�floatrMrKr^r`r_rLrWrXrrrb�ranger)rre�
numeric_value�	bar_width�
percent_value�percent_str�
filled_length�progress_bar�line1�line2�line3�_s            r �update�ProgressBar.update�sU���=� ����T�^�^�a�-?�@�D�N�	
E��e�T�*�*�%(��
�
�D�N�N�5�a�a�$H�&�D�N�%(��J�M�%(��C��
�
�M�,J�%K�D�N��<�<��"�"�$����I��
�
�I��t�~�~��d�j�j�0A�A�B�
�&�q�����q�&8�9���I���6�$�*�*�D�E�
��}�,�u�	�8Q�/R�R���<�<��{�{�m�1�T�%5�%5�$6�{�m�1�T�EV�EV�DW�X�E��'�'�(��,��q��9J�9J�8K�L�E��{�{�m�1�[�M��3�E���~�Q�'�E����!�r���|�|��J�J���U�T�\�*��J�J���U�T�\�*��J�J���U�T�\�*��J�J�����	�� � ��
�
� � �5��):�):�(;�1�!=�>��t�0�0�1�A��J�J�$�$�[�1�2��
�
� � �5��):�):�(;�1�!=�>��J�J���U�T�\�*��J�J���U�T�\�*��J�J���U�T�\�*��J�J���� !�D���Y�z�*�
E�!$�T�Z�Z����!�1C�!D���
E��Z�	��J�J���U�T�\�*��J�J���U�T�\�*��J�J���U�T�\�*��J�J����	�s,�AN�50N�&D1O�8O�O�BQ(�'Q(c���UR(a>[RRS5 [RR	5 gURUR5 gr)rZrWrXrrr�rT�rs r �finish�ProgressBar.finish�s;���<�<��J�J���T�"��J�J�����K�K��
�
�#r))
r]rar_r^r`rZrbrMrVrKrLrTrJ�N)
r#r$r%r&�__doc__rcrUrSrjr}r�r�r'r"r)r rErE[s=��������41�#�1�#�1�
�.>�@$r)rEc�F�\rSrSrSrSS\S\S\4SjjrSS\4Sjjr	S	r
g
)�SectionProgress��z�
Maps one section to 100 virtual ticks on the main ProgressBar.
Call tick('label') at each sub-step to advance smoothly and show status.
�section_position�steps�section_namec��UupVXlX@lX`l[S[	U55UlSUl[S[	U55S-
S-UlSUR
-UlURS-Ul	SUl
g)NrIrrnrs)�progressr��_sections_totalrRrSr��i�base�delta�max_pos�_mini_width)rr�r�r�r��
section_index�sections_totals       r rc�SectionProgress.__init__�sz��)9�%�
� �
�(��-����C��J�'��
������C�
�.�/�!�3�s�:��	��4�:�:�%��
��y�y�3������r)�labelc�j�[URURS-5UlUR(dg[	UR
[SURUR-5-5n[	URUR-UR-5nSU-SURU-
--nSUR3URl	U=(d SnUSU3R5URlURRU5 g![a N(f=f)NrIrnu■u□z
Building: rgrq)rxr�r�r�rSr�r�r�r�rK�striprLrr�)rr��pos�filled�subbar�suffix_labels      r �tick�SectionProgress.tick�s����T�Z�Z����!��,����}�}���$�)�)�c�#�t�v�v��
�
�':�;�;�<���T�%�%����.����;�<�����%�4�+;�+;�f�+D�"E�E��	�%/��0A�0A�/B�#C�D�M�M� � �;�B�L�&2�^�1�V�H�#=�#C�#C�#E�D�M�M� �	
�
�
���S�!���	��	�s�<A
D%�%
D2�1D2)	r�r�r�r�r�r�r�r�r�N)rg)r#r$r%r&r��tuplerSrUrcr�r'r"r)r r�r��s@����� ���	�
��$"�#�"�"r)r�c� �\rSrSrSrS\S\S\4SjrS\S\4SjrS\S\4SjrS	\S\4S
jr	S\S\4Sjr
S\S\4S
jrS\S\4SjrS\S\4Sjr
S5S\4SjjrSrS5S\4SjjrS\S\4SjrSrSrSrS\\S\S\S\4SjrS	\S\4SjrS\4SjrS\S\4SjrS \S\4S!jrS"\S\4S#jrS \S\4S$jrS\4S%jrS&\S\4S'jr S&\S\4S(jr!S\4S)jr"S&\SS*4S+jr#S6S,jr$S-\S\4S.jr%S/r&S0r'S\S\4S1jr(S2r)S3r*S4r+g*)7�SpartaReportic�<�SURS5-/UlSUlSUlSUlSUlSUlSUlSUl/Ul	SUl
SUlSUlSUl
/UlSUlSUlSUlSUlSUlSUlSUlSUl/UlSUlSUl/UlSUlSUlSUlSUlSUl/Ul /Ul!SUl"SUl#SUl$/Ul%SUl&SUl'SUl(SUl)SUl*SUl+SUl,SUl-SUl.SUl/SUl0SUl1SUl2SUl3SUl4SUl5SUl6SUl7SUl8SUl9SUl:SUl;SUl<SUl=SUl>SUl?SUl@SUlASUlBSUlCSUlDSUlESUlFSUlGSUlHSUlISUlJSUlKSUlLSUlMSUlNSUlOSUlPSUlQ/UlRSUlSSUlTSUlUSUlVSUlWSUlXSUlYSUlZSUl[SUl\/Ul]SUl^SUl_SUl`SUlaSUlb0Ulc/UldSUleSUlfSUlgSUlhSUliSUljSUlkSUllSUlmSUlnSUlog)Nz


z"# System Performance Audit Report:)p�format_heading�sectionsr�r�r�r��	server_id�server_type�
panel_type�domains�managed_domain�
os_version�main_ip�mail_ip�all_ips�managed_domain_ip�
logical_cores�mem_total_gb�mem_avail_gb�mem_alloc_gb�mem_swap_gb�mem_buffers_gb�deadweight_future�_async_tasks�domain_count�domain_owner�	user_list�
user_count�domain_registrar�
is_registered�domain_reg_expiry�domain_reg_status�whois_nameservers�dig_nameservers�domain_resolves�port_80_service�
vhost_path�	web_stack�docroot�cms_type�http_status�has_gzip�
has_cache_hit�has_cloudflare�cdn_provider�cdn_cache_status�
cdn_cache_hit�has_ultrastack�system_php_version�php_version�php_handler�has_php_fpm�php_fpm_max_requests�php_fpm_max_children�php_fpm_max_idle_timeout�total_fpm_pools�total_max_children�max_fpm_children�dbms_version�mysqltuner_opt_in�mysqltuner_install�key_buffer_size�innodb_buffer_pool_size�max_connections�current_connections�largest_databases�query_cache_type�query_cache_size�tmp_table_size�max_heap_table_size�table_open_cache�table_definition_cache�innodb_log_file_size�join_buffer_size�sort_buffer_size�max_allowed_packet�slow_query_log�slow_query_log_file�long_query_time�performance_schema�local_email�mail_ptr�email_accounts�email_user_count�email_disk_usage�spam_protection�total_email_disk_usage�highest_disk_mail_accounts�highest_disk_email_account�highest_usage_email_folder�email_bounce_stats�
has_monarx�has_imunify�firewall_stack�has_ssl�
ssl_issuer�ssl_expires�ssl_trusted�ssl_self_signed�installed_services�failed_services�
apache_mpm�apache_maxworkers�apache_maxconnections�apache_serverlimit�apache_threadsperchild�apache_startservers�apache_minsparethreads�apache_maxsparethreads�apache_minspareservers�apache_maxspareservers�apache_mpm_conf_pathr�s r rc�SpartaReport.__init__s����t�*�*�+O�P�P�$
��
���
�!���"��� ���������������"���������������!%���!��� ��� ��� �������	
��"&������ ��� ��������� $���!���!%���!%����	
��
�	
�� $���#����	
����������
������
�!���"��� ��� $���!����	
��#'������������$(��!�$(��!�(,��%�#���"&��� $��� ����	
��#'���#���'+��$�#���#'�� ��	
��!%��� $���"���#'�� � $���&*��#�$(��!� $��� $���"&���"����	
� � $���"&��������
��	
��!%��� $���#����	
�#�+/��'�*.��'��	
�'�
�	
�������� ���������������#���"$���!������!%���%)��"�"&���&*��#�#'�� �&*��#�&*��#�&*��#�&*��#��	
�!r)�style�textr*c��UcSO
[U5n[(dU$US:XaSUS3$[[US5nUcU$U"U5$)Nrg�
progress_bluerPrQ)rU�
USE_COLORS�getattrr
)rr&r're�
style_funcs     r �apply_color�SpartaReport.apply_color�sV���l���D�	���z��L��O�#��e�W�G�,�,��U�E�4�0�
����L��%� � r)c�J�URSU5nURSU5$)Nr)�bold�r-)rr'�coloreds   r r��SpartaReport.format_heading�s'���"�"�?�D�9�������0�0r)c�&�URSU5$)Nr)r1�rr's  r �format_subheading�SpartaReport.format_subheading�s�������6�6r)r�c���[U5RS5S3nUcSO
[U5nU(dSnURSU5nURSU5nURSU5nUSU3$)N�:rg�Unknown�whiter0rq�rU�rstripr-)rr�re�
label_text�	raw_value�
value_colored�
label_bold�
label_coloreds        r �format_label_value�SpartaReport.format_label_value�s|���E�
�)�)�#�.�/�q�1�
��-�B�S��Z�	��!�I��(�(��)�<�
��%�%�f�j�9�
��(�(��*�=�
����-��1�1r)�
block_textc�8�URS[U55$)Nr;�r-rU�rrEs  r �format_block�SpartaReport.format_block�s�������Z��9�9r)c�8�URS[U55$)N�dimrGrHs  r �format_block_dim�SpartaReport.format_block_dim�s������s�:��7�7r)c�8�URS[U55$)N�amberrGr5s  r �format_amber�SpartaReport.format_amber�s�������T��3�3r)c�8�URS[U55$)N�redrGr5s  r �format_error�SpartaReport.format_error�s������s�4�y�1�1r)c���[U5RS5S3nURSU5nURSU5nUcSO
[U5nU(dSnURX75nUSU3$�Nr9r0r;rgr:rqr<�	rr�re�value_styler>rArB�
value_textr@s	         r �mem_format_label_value�#SpartaReport.mem_format_label_value�sz���E�
�)�)�#�.�/�q�1�
��%�%�f�j�9�
��(�(��*�=�
� �=�R�c�%�j�
��"�J��(�(��A�
����-��1�1r)c�^�U4SjnSU4SjjnU"U5nU"U(aSRU5OS5nU"U5n	UcSO[U5R5n
U
(dSn
U
R5R5S:XaSOS	nU"X�S
9nU"S5SUS
U"S5SUS
U"S5SU	S
U"S5SU3$)Nc�>�[U5RS5S3nTRSTRSU55$�Nr9r;r0r<)r��label_cleanrs  �r r>�3SpartaReport.reg_format_summary.<locals>.label_text�sD��� ��Z�.�.�s�3�4�A�6�K��#�#���)�)�&�+�>��
r)c�t>�UcSO
[U5nUR5(dSnTRX5$�Nrgr:)rUr�r-)rer&�rawrs   �r r[�3SpartaReport.reg_format_summary.<locals>.value_text�s3����
�"�3�u�:�C��9�9�;�;����#�#�E�/�/r)�, �Nonergr:�active�greenrT)r&�	Registrarrqr�Nameservers�
Expiration�Status�r;)�joinrUr��lower)
r�	registrar�nameservers�expiry�statusr>r[�registrar_value�nameservers_value�expiry_value�
status_raw�status_style�status_values
`            r �reg_format_summary�SpartaReport.reg_format_summary�s����	�	0�%�Y�/��&�&1�D�I�I�k�"�v�
��"�&�)��!�>�R�s�6�{�/@�/@�/B�
��"�J�"�'�'�)�/�/�1�X�=�G�5�	�"�*�A���+�&�'�q��(9���-�(�)��+<�*=�R��,�'�(��,��r��(�#�$�A�l�^�
5�	
r)c��[U5RS5S3nURSU5nURSU5nUcSO
[U5nUR5(dSnURX75nUSU3$rX)rUr=r-r�rYs	         r �dns_format_label_value�#SpartaReport.dns_format_label_values����E�
�)�)�#�.�/�q�1�
��%�%�f�j�9�
��(�(��*�=�
� �=�R�c�%�j�
����!�!�"�J��(�(��A�
����-��1�1r)�
dmarc_summaryc��U=(d SR5R5nU(dgURS5(agURS5(dURS5(dSU;agg)	NrgrTzpresent (policy missingrP�missing�nonezdeliverability issuesr;)r�rq�
startswith)rr��summarys   r �dns_dmarc_style�SpartaReport.dns_dmarc_stylesk�� �&�B�-�-�/�5�5�7�������7�8�8��
���y�)�)��!�!�&�)�)�'�7�2��r)c��[[U5R55nSUs=::aS::ag SUs=::aS::ag gg![a gf=f)Nr;��i+rji�iWrT)rSrUr�r)rr{�
status_ints   r �site_stats_http_status_style�)SpartaReport.site_stats_http_status_style sb��	��S��.�4�4�6�7�J��*�#��#��$��*�#��#��$����	��	�s�"A�
A�Ac�>�[U5nUcgUS:agUS:agg)Nr;g�?rjg@rPrT)�_site_stats_parse_seconds)r�ttfb_value_text�ttfb_secondss   r �site_stats_ttfb_style�"SpartaReport.site_stats_ttfb_style,s.��0��A������#����#���r)c�*^�SU4Sjjn[TSS5=(d URSS5nURSS5n[[TSS55n[[TSS55nU"SUTRU5S	9U"S
URSS55U"SUTR	U5S	9U"S
URSS55U"SURSS55U"SURSS55U"SURSS55U"SU(aSOSU(aSOSS	9U"SU(aSOSU(aSOSS	9/	nU(dSRU5$STR
S5/n	U	RU5 SRX�-5$)Nc��>�[U5RS5S3nTRSU5nTRSU5nUcSO
[U5nU(dSnTRX&5nUSU3$rXr<)	r�rerZr>rArBr[r@rs	        �r �label_value�;SpartaReport.site_stats_render_summary.<locals>.label_value7s{�����J�-�-�c�2�3�1�5�J��)�)�&�*�=�J� �,�,�W�j�A�M�$�}��#�e�*�J��&�
� �,�,�[�E�M�#�_�A�m�_�5�5r)r��HTTP Response Code�N/AzTime to First Byter�Fr��rZzTLS Handshake Timez
TLS HandshakezTime to First Byte (TTFB)zTotal Load Timez
Total TimezRedirects Followedz
Download SizezDownload SpeedzGZIP Compression�Enabled�DisabledrjrTz	Cache HIT�Yes�Norrgz### Redirects Foundro)r+�getr�r�r�rpr6�extend)
r�parsed_metrics�redirect_entriesr��http_status_value�	ttfb_textr�r��lines�redirect_sections
`         r �site_stats_render_summary�&SpartaReport.site_stats_render_summary6s����	6�$��-��
�=�
�
�
� 4�e�
<�	�#�&�&�';�U�C�	����j�%�8�9���W�T�?�E�B�C�
�
�$�!� �=�=�%��
�
�$�n�&8�&8��%�&P�
�
�+�� �6�6�y�A�
�

�!�>�#5�#5�l�E�#J�
�
�$��"�"�#7��?�
�
���!3�!3�O�U�!K�
�
� �.�"4�"4�5E�u�"M�
�
�"�%�	�:�(0�W�e�
�

��&��D�(5�W�5�
�E'
��R ��9�9�U�#�#��� 6� 6�7L� M�N����� 0�1��y�y��1�2�2r)�
directives�effective_values�active_pathc	���[SU5SS9nSU=(d S3/nUH8nURURU5SURUS535 M: SR	U5$)Nc3�8# �UHn[U5v� M g7fr�)rh��.0�	directives  r �	<genexpr>�5SpartaReport.phpini_render_summary.<locals>.<genexpr>|s���@�Z�	�S��^�^�Z���r)�defaultzAuthoritative INI File: r��  r)rR�append�ljustr�rp)rr�r�r�rJr�r�s       r �phpini_render_summary�"SpartaReport.phpini_render_summaryysy���@�Z�@�!�L��+�K�,@�5�+A�B�C��#�I��L�L��?�?�5�)�*�"�-=�-A�-A�)�U�-S�,T�U�
�$��y�y���r)c��[U5RS5S3nURSU5nURSU5$�Nr9r0r;r<)rr�r>rAs    r �mail_format_label_only�#SpartaReport.mail_format_label_only�sC���E�
�)�)�#�.�/�q�1�
��%�%�f�j�9�
������4�4r)c���[U5nSnSnUS:�a6U[U5S-
:a$US-nUS-
nUS:�aU[U5S-
:aM$USSX43$![[4a gf=f)	Nr:)�B�KB�MB�GB�TBr�rI��@�.2frq)r�r�r�rh)r�	num_bytesre�units�
unit_indexs     r �mail_format_bytes�SpartaReport.mail_format_bytes�s���	��)�$�E�.���
��t�m�
�c�%�j�1�n� =��V�O�E��!�O�J��t�m�
�c�%�j�1�n� =����A�e�/�0�1�1���:�&�	��	�s�A�A*�)A*�bounce_statsc��Sn/n[U=(d 0R5USS9H?upEURUSURSS5SURSS5S	35 MA S
R	U5$)Nc�h�US=(d 0nURSS5URSS5-$)NrI�bouncedr�deferred)r�)�item�countss  r �sort_key�:SpartaReport.email_bounce_format_summary.<locals>.sort_key�s0���!�W�]��F��:�:�i��+�f�j�j��Q�.G�G�Gr)T��key�reverser0r�rz
 bounced, r�z	 deferredr)�sorted�itemsr�r�rp)rr�r�r��
email_addressr�s      r �email_bounce_format_summary�(SpartaReport.email_bounce_format_summary�s���	H���%+�
�
�R�&�&�(�h��&
�!�M�
�L�L� �/��F�J�J�y�!�$<�#=�Z��
�
�S]�_`�Ha�Gb�bk�l�
�&
��y�y���r)r>c	�X�URSURS[U555$)Nr;r0rG�rr>s  r �	ssh_label�SpartaReport.ssh_label�s+������T�%�%�f�c�*�o�>�
�	
r)�analysisc	���SRUS5nUSnURS5SURSU53URS5SURUS(aS	OSU53URS
5SURUS(aSOS	US(aSOS
53/nUS(dSupVOUS(aSupVOSupVURURS5SURXe535 USbUSS:�aSOSnURURS5SURXqS535 URURS5SURSUS535 US(aSOSnUS(aS	OSn	URURS5SURX�535 SRU5$) Nrg�ports�	root_modezPort(s) in use:rqrjzRoot Access:�root_allowedrTzPublic keys:�public_key_enabledr�r��passwords_effective)r�rj�passwords_require_key)zKey required with password�yellow)r�rTzPassword login:�	tries_int�r�zAuthentication Try Limit:�max_auth_trieszSession Limit:�max_sessions�empty_passwords_allowedr�r�zEmpty Passwords Allowed:r)rpr�r-r�)
rr��	ports_strr�r��password_value�password_color�tries_color�empty_pw_value�empty_pw_colors
          r �ssh_render_summary�SpartaReport.ssh_render_summary�sB���I�I�h�w�/�0�	��[�)�	��~�~�/�0�1��4�3C�3C�G�Y�3W�2X�Y��~�~�n�-�.�a��0@�0@�(�Sa�Jb��ho�qz�0{�/|�}��~�~�n�-�.�a��0@�0@�H�Ui�Lj��pu�EM�Nb�Ec�xA�is�1t�0u�
v�
���-�.�-@�*�N�N�
�-�
.�.�*�N�N�
.>�*�N�
����~�~�/�0�1��4�3C�3C�N�3c�2d�e�	
���%�1�h�{�6K�a�6O�
��	�
	����~�~�9�:�;�1�T�=M�=M�k�dt�[u�=v�<w�x�	
�	����~�~�.�/�0��$�2B�2B�7�H�Uc�Ld�2e�1f�g�	
�#+�+D�"E��4���7�8�E�g�	�	����~�~�8�9�:�!�D�<L�<L�^�<l�;m�n�	
��y�y���r)c�L�URSURSUS355$�Nr;r0r9r1r�s  r �	ssl_label�SpartaReport.ssl_label�s.������T�%�%�f���A�.>�?�
�	
r)c�x�URSURSS55nURSS5nUSU3$)Nr;r0zstatus:rT�disabledrqr1)r�status_labelr{s   r �ssl_disabled_status_line�%SpartaReport.ssl_disabled_status_line�sI���'�'��T�%�%�f�i�8�
���'�'��z�:����q���/�/r)�self_signedc��USLaURSS5$USLa+U(aURSS5$URSS5$URSS5$)	NTrj�enabledFr�z enabled (self-signed, untrusted)zenabled (untrusted)zenabled (unverified)r1)r�trust_staters   r �ssl_status_text�SpartaReport.ssl_status_text�sk���$���#�#�G�Y�7�7��%����'�'��@����#�#�H�.C�D�D�����*@�A�Ar)c��U(aURSS5$U(aURSU5$URSS5$)Nr��self signedrj�unknownr1)rr�
issuer_orgs   r �ssl_issuer_text�SpartaReport.ssl_issuer_text�sA����#�#�H�m�<�<���#�#�G�Z�8�8�����)�4�4r)c���Uup#nU(aUcURSS5$USU3nUS::aURSU5$US::aURSU5$URSU5$)Nr�ru · days left: �rT�rjr1)r�expiration_info�expires_display�days_remaining�_expires_iso�expires_texts      r �ssl_expires_text�SpartaReport.ssl_expires_text�s���8G�5����N�$>��#�#�H�i�8�8�)�*�/�.�9I�J���Q���#�#�E�<�8�8��R���#�#�H�l�;�;������6�6r)Nc��Sn[U[[45(a[U5S:�aUSnXlU(aSOUSLaSOSUlX0lXPlg)Nr�rTF)r�r��listrhrrrr)rrrr	r�expires_isos      r �ssl_update_report_fields�%SpartaReport.ssl_update_report_fieldss\��������
�6�6��O�$��)�)�!�,�K�&���D�{�d�/B�e��	
��%��&�r)c��[U[5(aU(dg1SknU(aURS5 U(aURS5 SSSSSS	.n/nUR5H�upx[U[5(aU(dM#/n	UR5Hlup�U=(d 0n[	URS
S55nX�;aM2URUS5n
UR
X�5nU	RSU
S
U35 Mn U	(dM�URURSU355 URU	5 URS5 M� U(dgSRU5R5S-$)NzNone detected
>ri�failed�
activating�inactive�inactive (disabled)rjrTrPrL)rirrrr�stater�- r0�### rgr)r��dict�addr�rUr�r-r�r6r�rpr=)rr�include_inactive�include_disabled�include_states�state_styler��
category_name�services�category_lines�
friendly_name�datar r&�
state_texts               r �format_installed_services�&SpartaReport.format_installed_servicesse���,�d�3�3�;M�$�;������z�*�����4�5���!��#*�
����'9�'?�'?�'A�#�M��h��-�-�X���N�'/�~�~�'7�#�
��z�r���D�H�H�W�i�8�9���.��#����u�5��!�-�-�e�;�
��%�%��=�/��J�<�&H�I�(8��~����T�3�3�d�=�/�4J�K�L����^�,����R� �'(B�*�$��y�y���&�&�(�4�/�/r)�cleaned_historyc��/nURS5 U=(d 0R5H@up4URSUSUSS35 USHnURSU35 M MB SRU5$)	Nz@Historical service failures seen in the journal (last 24 hours):r!� (�countz	 events):r�z    r)r�r�rp)rr1�output_linesr,r-�entrys      r �!svc_format_service_failure_output�.SpartaReport.svc_format_service_failure_outputIs��������N�	
�%4�$9�r�#@�#@�#B��M����"�]�O�2�d�7�m�_�I� N�O��g����#�#�d�5�'�N�3�'�$C��y�y��&�&r)c���[RSU5 U"5$![aAnSUS[U53n[R	U5 URU5sSnA$SnAff=f)NzRunning section: %sz[Error] Failed to get r0)r6�debugrrUr
rU)r�description�func�er
s     r �run_section�SpartaReport.run_sectionUs`�����*�K�8�	,��6�M���	,�,�[�M��C��F�8�D�E��L�L����$�$�U�+�+��	,�s��
A*�6A%�A*�%A*c�>�URRXU45 gr�)r�r�)r�marker�future�	render_fns    r �add_async_insertion� SpartaReport.add_async_insertion^s����� � �&�)�!<�=r)c��URH1up#nUR5nU"U5nUR
X'S5nM3 U$![a6n[R	SU5 SU3nURU5nSnAN[SnAff=f)NzAsync task failed for marker %r�+[Error] Failed to gather deadweight usage: rI)r��resultrr6�	exceptionrU�replace)rr'rA�fut�render�bodyr=�replacements        r �_apply_async_insertions�$SpartaReport._apply_async_insertionsbs���#'�#4�#4��F��
/��z�z�|��
!��,�K��<�<��Q�7�D�$5����
�
/�� � �!B�F�K�D�Q�C�H���(�(��.���
/�s�A�
B�,A?�?Bc�l�[RS5 URRSUS35 g)NzAdding new section to report.r)r6r:r�r�)r�contents  r �add_section�SpartaReport.add_sectionos*�����4�5��
�
���r�'��"�-�.r)c��[RS5 SRUR5nUR	U5nU$)NzStarting report generationr)r6r:rpr�rOr5s  r �generate_report�SpartaReport.generate_reportss6�����1�2��y�y����'���+�+�D�1���r))or�r�rr#r!rr"r rr$rrrr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrr	rrrr�r�r�rrr�rr�r
rrr�r�r�rr�r�r�r�rr�rr�rr�r�r�rr�r�r�r�r�r�r�r�r�r�r�r�rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrr�r
rrrrr�r�r�r�rr�r�r�r�r�r�r�ro)TT),r#r$r%r&rcrUr-r�r6rCrIrMrQrUr\r|rr�r�r�r�rr#r�r�r�r�r�r�r�r�r�rr
rrr/r7r>rDrOrSrVr'r"r)r r�r�s��T
�n!��!�C�!�C�!�1�3�1�3�1�7�c�7�c�7�2��2�s�2�:�s�:�s�:�8�3�8�3�8�4��4��4�2��2��2�
2�3�
2�!
�F
2�3�
2��S��S��$
��A3�F	 ��s�)�	 �7;�	 �JM�	 �	�	 �5�C�5�C�5�
2�c�2� �� �� �
�C�
�C�
�
- �4�- �C�- �^
�C�
�C�
�
0�#�0�B��B��B�5�4�5��5�7�3�7�'�(,�'�	
�'�(��	10�f	'��	'�#�	'�,�>��C��C��/�r)r�c�4�\rSrSr%\\S'\\S'\\S'Srg)�SiteStatsArtifactsiz�temp_directory�header_dump_path�trace_output_pathr"N)r#r$r%r&rU�__annotations__r'r"r)r rYrYzs�������r)rYc	�0�[R"SS9nURSSSS9 SSS	S
SSS
SS.nUR5HQup#URSU3SUS9 SU3/nUS:XaUR	S5 UR"USU3SSUS3S.6 MS U$)Nz>SPARTA: System Performance Audit & Reporting Tool for Analysts)r;z--full�
store_truez+Audit the full server environment (default))�action�helpzAudit only system informationz,Audit only site and domain based informationz)Audit only web server traffic informationz&Audit only PHP and handler informationzAudit only database informationzAudit only mail informationzAudit only security informationz Audit only services and versions)�system�site�traffic�php�db�mail�securityr*z--z--no-rgz
--no-email�no_z	Omit the z section from the report)�destr`ra)�argparse�ArgumentParser�add_argumentr�r�)�parser�section_help�section_key�	help_text�
omit_flagss     r �build_arg_parserrs�s���
�
$�
$�T��F������
:���2�>�>�7�/�-�5�6�	�L�#/�"4�"4�"6��������
����	�	
��k�]�+�,�
��&� ����l�+����
��{�m�$���[�M�)A�B�		
�#7�$�Mr)c�,�[U=(d S5R5n[R"SU5nU(a'UR	S5UR	S5pCUU3$[R
"SSU5n[
U5S:�aUSS$U$)Nrgz
^(\d+)\.(\d+)rIrz\D)rUr�r[�match�grouprirh)�version_string�cleanedru�major�minor�numeric_onlys      r �_cwp_php_short_verr|�s����.�&�B�'�-�-�/�G��H�H�%�w�/�E���{�{�1�~�u�{�{�1�~�u����� � ��6�6�%��W�-�L�"�<�0�A�5�<����G�<�Gr)c��^�/SQnSSSSSSS.n[R"S/SSS9R5R5n[RS	U5 S
U;a�UR
S
SS9S
n[RSU5 UH�n[R"XT5nU(dM"URS5n[R"SSU5nXplURUS5Ul
[RSUR5 [RSUR5  g [RS5 O[RSU5 Sn
[!U
5R5R5m[#U4SjU55(aw[R"SST5nTUlURUS5Ul
[RSUR5 [RSUR5 g[R%S5 M�![a n	[RSU	5 Sn	A	N�Sn	A	ff=f)N)z^(dedi\d+)$z
^(ded\d+)$z	^(cc\d+)$z^(elite\d+)$z^(advanced\d+)$z
^(vps\d+)$�	Dedicated�VPS)�dedi�ded�cc�elite�advanced�vps�hostnameTr��r'�timeoutzDetected hostname: %sz.inmotionhosting.comrI)�maxsplitrzExtracted base hostname: %sz\d+rgr:zAuto-detected server ID: %szDeduced server type: %sz6Hostname detected but did not match known ID patterns.z9Hostname %s is not in standard format for auto-detection.zHostname detection failed: %sz�Hostname is not typical. Enter the server ID below.
Accepted formats: dedi###, ded###, cc###, elite###, advanced###, and vps###:
>>> c3�R># �UHn[R"UT5v� M g7fr�)r[ru)r��pattern�
id_entereds  �r r�� get_server_id.<locals>.<genexpr>�s����E�H��r�x�x���,�,�H�s�$'zReceived server ID: %szFInvalid format entered. Double-check the server's ID before entering.
)�
subprocess�check_outputr�rqr6r:�splitr[�searchrvrir�r�r��infor�input�any�warning)�report�patterns�typesr��	shortnamer�rur��	parsed_idr@�promptr�s           @r �
get_server_idr��s����H�������

�E� ;��#�#�Z�L�t�Q�G�
�U�W�
�U�W�	�
	���,�h�7�!�X�-� ���'=���J�1�M�I��L�L�6�	�B�#���	�	�'�5���5� %���A��I� "���v�r�9� =�I�'0�$�).���9�i�)H�F�&��K�K� =�v�?O�?O�P��L�L�!:�F�<N�<N�O��$�
�L�L�H�
�
�L�L�K��
�	]����6�]�(�(�*�0�0�2�
��E�H�E�E�E����v�r�:�6�I�)�F��!&���9�i�!@�F���K�K�0�&�2B�2B�C��L�L�2�F�4F�4F�G�����U�	
����;����4�c�:�:��;�s+�BH5�,BH5�4H5�H5�5
I�?I�Ic�0�[RSUR5 SnSnSnSS/n[RRU5(aUSUlO�[RRU5(aUSUlOc[RRUS5(a2[RRUS5(aUS	UlO
US
Ul[RSUR5 UR$)Nz.Determining panel type for given server ID: %s)�cPanel�Control Web Panel�UltraStack ONE�	Baremetalz/usr/local/cpanel/cpsrvdz/usr/local/cwpsrvz
/etc/ansible/z/home/wordpress/rrIrr�zDetected panel type: %s)r6r:r�r3�path�existsr�)r�r��cp_path�cwp_path�ultra_pathss     r �get_panel_typer�s���
�L�L�8�&�:J�:J��
K�E�(�G�"�H�"�$6�7�K�	�w�w�~�~�g���!�!�H���	������	!�	!�!�!�H���	������A��	'�	'�B�G�G�N�N�;�q�>�,J�,J�!�!�H���!�!�H���
�L�L�*�F�,=�,=�>����r)c
��[RSUR5 URS:XaV[S5nUSSVs/sHo"SPM	 snUl[RS[UR55 GO�URS:Xa�S	n[
S
5nUR5nURU5 UR5nUVs/sHowSPM	 snUl[RS[UR55 SSS5 SSS5 GO@URS:XGa[
5nUR5nURS
5 UR5nUH�n	U	Sn
U	SnURSU
SUS35 UR5nU(aIUSn
[R"SSU
RS55nURRU5 M�M� SSS5 SSS5 [RS[UR55 O,URS:Xa[R#S5 /UlUR(a[+UR[,5(d+[R/S5 [&R("S5 [UR5Ul[RSUR5 gs snfs snf!,(df   GN�=f!,(df   N�=f![ a$n[RSU
UU5 SnAGM�SnAff=f!,(df   GNa=f!,(df   GNk=f![ a: [R%SUR5 [&R("S5 GN[f=f)Nz(Gathering domain list for panel type: %sr��get_domain_infor-r��domainz Retrieved %d domains from cPanelr�z�
            SELECT domain FROM user
            UNION
            SELECT domain from domains
            UNION
            SELECT CONCAT(subdomain, '.', domain) AS domain from subdomains;
            �root_cwpzRetrieved %d domains from CWPr�z�
                        SELECT table_schema, table_name
                        FROM information_schema.tables
                        WHERE table_name LIKE '%\_options';
                        �table_schema�
table_namez[
                                SELECT option_value
                                FROM `z`.`za`
                                WHERE option_name = 'siteurl';
                                �option_valuez
^https?://rg�/z&Failed to parse siteurl from %s.%s: %sz(Retrieved %d domains from UltraStack ONEr�z.Baremetal domain detection is not implemented.z*Fatal error while gathering domains for %srIz*[Fatal] No domains found. Aborting script.zDomains gathered: %s)r6r:r�rr�rh�get_mysql_connection�cursor�execute�fetchallr��fetchoner[rir�r�rr�rIrW�exitr�r�criticalr�)r�r-�d�query�connr��results�row�options_tablesr6rf�tablerH�raw_urlr��inner_es                r �get_domainsr�s��
�L�L�;�V�=N�=N�O�E�����(��,�-�D�37��<�	�3J�K�3J�a��k�3J�K�F�N��L�L�2�C����4G�
��
�
�"5�
5��E�&�j�1�T��[�[�]�f��N�N�5�)�$�o�o�/�G�?F�%G�w��(�m�w�%G�F�N��K�K�7��V�^�^�9L��	#�2�1��
�
�"2�
2�%�'�4��[�[�]�f��N�N�$��
&,�_�_�%6�N�!/��"�>�2�� %�l� 3���"�N�N�0'�')�d�#�e�W�5!�,$�%�
&,�_�_�%6�F�%�*0��*@��)+���$1�2�w�}�}�S�7I�*"��!'��� 5� 5�f� =� &�"0�#�(�>
�L�L�:�C����<O�
��
�
�+�
-��N�N�K�L��F�N��>�>��F�N�N�D�!A�!A����D�E�������f�n�n�-�F��
�L�L�'����8��SL��"&H�#�]��2�1��D )��"�L�L� H� "� %� '�	�����/#�]��(�'��N�����8�&�:K�:K�	
�	�����	�s��%N�L�1N�N�%L�6&L
�L�*1L
�L�#N�-N�M3�1M!�A6L0�M!�M3�1N�,N�N�L
�
L	�L�
L-�)N�-N�0
M	�:M	�M!�M	�M!�!
M0	�+M3�3
N�=N�AO	�O	c�t^
^�[R"S5m
SmU
U4Sjn[USS5(d+[R	S5 [
R"S5 URVs1sHo"R5iM nn[USS5nU(aGT"U5nU"U5(aXS;aXT:waXPl	UR$[RSU5 [S	5nT"U5nU"U5(d[RSU5 M:XS;aXPl	UR$SU3nURS5(aUS
SOSnXs;aUOU(aX�;aUOSn	[RSUU	=(d S5 M�s snf![a [RS
5 gf=f)Nzo^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])$c��U=(d SR5R5RS5nURS5(dURS5(aUR	SS5SnUR	SS5SnURS	5R
S
5nU$![a U$f=f)Nrgro�http://�https://�://rIr�r�idna�ascii)r�rqr=r�r��encode�decoder)�domain_texts r �normalize_domain�,get_managed_domain.<locals>.normalize_domainps���"�(�b�/�/�1�7�7�9�@�@��E���!�!�)�,�,��0F�0F��1
�1
�&�+�+�E�1�5�a�8�K�!�'�'��Q�/��2��	�%�,�,�V�4�;�;�G�D�K�����	����	�s� B0�0
B>�=B>c�D>�[TRT"U555$r�)r�ru)r��
domain_regr�s ��r �is_valid_domain�+get_managed_domain.<locals>.is_valid_domain}s����J�$�$�%5�k�%B�C�D�Dr)r�z<Unable to find domains on this server. Report this as a bug.rIr�zIPre-set managed_domain '%s' not found in server domains; prompting again.z7Managed domain for this report (e.g. example.com):
>>> z/No input available to determine managed domain.z]Invalid domain format entered: %s. Examples: example.com, example.co.uk, subdomain.example.mx�www.�z3Domain '%s' not found in server inventory. Hint: %sr�)r[r\r+r6r�rWr�r�rqr�r�r��EOFErrorr
r�)r�r�r��
domains_lower�current�domre�variant_www�variant_apex�hintr�r�s          @@r �get_managed_domainr�js�������	9��J�
�E��6�9�d�+�+����J�	
�	�����(.���7��1�W�W�Y��M�7��f�.��5�G���w�'���3���C�$8��~�(+�%��(�(�(����W��	
�
�	��J��C��s�#���s�#�#��N�N�o��
�
���$'�!��(�(�(��S�E�l��"%�.�.��"8�"8�s�1�2�w�d���+�
� �L�$A���
	
�	���A���N�F�	
�E��8��(�	��L�L�J�K��	�s�.F�&F�F7�6F7c�R�SnSnSn[RRU5(a�[R	S5 [USS9nUR
5nSSS5 [SW55nURSS	5R5RS
5Ul
UR$[RRU5(aL[R	S5 [USS9nUR5R5Ul
SSS5 O�[RRU5(aL[R	S5 [USS9nUR5R5Ul
SSS5 O[RS
5 SUl
UR$!,(df   GNi=f!,(df   N,=f!,(df   N==f![a* [RS5 SUl
UR$f=f)Nz/etc/os-releasez/etc/centos-releasez/etc/redhat-releasez%Detected OS info from /etc/os-releaser-r.c3�r# �UH-nSU;dMUR5RSS5v� M/ g7f)�=rIN�r�r��r��lines  r r��!get_os_version.<locals>.<genexpr>�s2����7<�t��t��*��
�
��"�"�3��*�*�u���
7�'7�PRETTY_NAMErg�"z)Detected OS info from /etc/centos-releasez)Detected OS info from /etc/redhat-releasez6No known OS release file found. Defaulting to unknown.zUnknown Operating Systemz+Failed to retrieve operating system version)r3r�r�r6r:r1�	readlinesr#r�r�r��readr�rrI)r��
newer_file�
older_file�sym_older_filerpr��os_infos       r �get_os_versionr��s���"�J�&�J�*�N�7�
�7�7�>�>�*�%�%��L�L�@�A��j�7�3�q����
��4���7<���G����M�2�.�4�4�6�<�<�S�A�
��.����'�W�W�^�^�J�
'�
'��L�L�D�E��j�7�3�q�$%�F�F�H�N�N�$4��!�4�3��W�W�^�^�N�
+�
+��L�L�D�E��n�w�7�1�$%�F�F�H�N�N�$4��!�8�7�
�N�N�H�
�!;�F��
����94�3��4�3��
8�7���7����F�G�6�������7�sc�AG2�F>�AG2�6AG2�9$G�AG2�)$G!�
%G2�>
G
�G2�
G�G2�!
G/�+G2�2&H&�%H&c��[R"5n[RSU5 U$![a [RS5 gf=f)NzKernel version detected: %sz!Failed to retrieve kernel versionz$[Error] Failed to get kernel version)�platform�releaser6r:rrI)�kernel_versions r �
get_kernelr��sK��6�!�)�)�+�����2�N�C�����6����<�=�5�6���,/�A�Ac���Sn[RRU5(ax[USS9n[	UR5R
5S5nSSS5 [WS-5n[US-S-5n[US-S-5nUSUS	US
3$[US35e!,(df   NW=f![a�n[RSU5 [R"S
S/SS9R5n[RSU5 UsSnA$![a.n[R!SUU5 SUSU3sSnAsSnA$SnAff=fSnAff=f)Nz/proc/uptimer-r.r�Qi�<z days, z hours, z minutesz
 not foundz Primary uptime method failed: %s�uptime�-pT�r'z.Uptime retrieved from fallback 'uptime -p': %sz3Both uptime methods failed: primary=%s, fallback=%sz#[Error] Failed to retrieve uptime: z | Fallback error: )r3r�r�r1r��readliner�rS�FileNotFoundErrorrr6r�r�r�r�r:rI)	�uptime_filerp�uptime_seconds�days�hours�minutesr=�output�sub_errs	         r �
get_uptimer�sa�� �K�Y�
�7�7�>�>�+�&�&��k�G�4��!&�q�z�z�|�'9�'9�';�A�'>�!?��5��~�)�4�5�D���9�5�$�>�?�E��>�D�0�R�7�8�G��V�7�5�'��'��(�C�C��;�-�z� :�;�;�5�4���Y����9�1�=�	Y��,�,��4� �t���e�g�
�
�L�L�@�&�
��M���	Y����E���
�
9���;N�w�i�X�X�X��
	Y��Y�sk�.B?�+B.�AB?� B?�.
B<�8B?�?
E"�	E� <D"�E"�"
E�,E�
E�E�E"�E�E�E"c��[SSSS9nUR5R5nSSS5 [SW5S5n[	SU55Ul[
5n[
5nSnUH�nURS5(a/[URS	S
5S
R55nMHURS5(dM`[URS	S
5S
R55nUcM�URXh45 URU5 M� Sn	[USS
5=(d S
R5R5n
U
S:Xa�SnSn[R R#U5(aX[USSS9nUR5R5R5=(d S
/Sn
SSS5 W
S:XaSOSn	Oa[R R#U5(a;[USSS9nUR5R5S:XaSOSn	SSS5 OSn	[$R'SU	5 UR+SU5/nU
S:Xa�UR-UR+SUR
55 UR-UR+S[/U555 UR-UR+S[/U555 O~U
S:XaxUR-UR+SUR
55 U	S:wa!UR-UR+SU	55 U	S:Xa UR-UR1S 55 S!R3U5S!-$!,(df   GNg=f![a SnGM8f=f![a GMJf=f!,(df   GN�=f!,(df   GN�=f![a [$R)S5 Sn	GN�f=f![a) [$R5S"5 UR7S#5s$f=f)$Nz
/proc/cpuinfor-rJ�r/�errorsc3�# �UH@nURS5(dMURSS5SR5v� MB g7f)z
model namer9rIN)r�r�r�r�s  r r�� get_cpu_stats.<locals>.<genexpr>sA���
�)�D��?�?�<�0�.��
�
�3��"�1�%�+�+�-�-�)�s
�A
�*A
r:c3�T# �UHoRS5(dMSv� M  g7f)�	processorrIN�r�r�s  r r�r s���#
�'�$�?�?�;�+G�A�A�-�s�(�	(zphysical idr9rIzcore idr�rgr�z/sys/fs/cgroup/cpu.maxz#/sys/fs/cgroup/cpu/cpu.cfs_quota_usrrRr�r�z-1�Not detectedzVPS burstable: %sz4Failed to read cgroup quota for burstable detection.z	CPU Model�	dedicatedzLogical Cores (Threads)zPhysical CoreszCPU SocketszVisible Logical Cores (vCPUs)z
VPS Burstablez`NOTE: This is a legacy VPS plan. Logical core count may not reflect guaranteed CPU availability.rzFailed to retrieve CPU statsz$[Error] Failed to retrieve CPU stats)r1r��
splitlines�next�sumr��setr�rSr�r�rr$r+rqr3r�r�r6r�r�rCr�rhrMrprIrU)r��file_handle�
cpuinfo_lines�	cpu_model�physical_cpu_ids�physical_core_pairs�current_physical_idr��core_id�	burstabler��cgroup_v2_cpu_max�cgroup_v1_quota�first_tokenr�s               r �
get_cpu_statsrs��oK�
��g�i�
�
�'�,�,�.�9�9�;�M�
�
�
�)�
�

�

�	� #�#
�'�#
� 
����5��!�e��"��!�D����}�-�-�/�*-�d�j�j��a�.@��.C�.I�.I�.K�*L�'�����+�+��!�$�*�*�S�!�"4�Q�"7�"=�"=�"?�@�G�'�2�'�+�+�-@�,J�K�$�(�(�)<�=�"� �	��v�}�b�9�?�R�F�F�H�N�N�P���%��
&�$<�!�"G���7�7�>�>�"3�4�4��)�G�I��$�'�,�,�.�4�4�6�<�<�>�F�2�$��'���*5��)=��4�I��W�W�^�^�O�4�4��'�'�)��$� +�/�/�1�7�7�9�T�A�"�!%�"���!/�I����/��;��*�*�;�	�B�C���+�%��L�L��)�)�-�v�/C�/C��
�

�L�L��)�)�$�c�*=�&>��
�

�L�L��)�)�-��=M�9N�O�
��E�
!��L�L��)�)�3�V�5I�5I��
�
�I�%�����-�-�o�y�I���E�!�����+�+�z����y�y���$�&�&�U
�
��4!�/�*.�'�/��
!����� �������
&����J��&�	�	
&��R�K����7�8��"�"�#I�J�J�K�s��P�N�A#P�,N�<P�,N2�P�A!P�*3O(�:O�AO(�'O�!O(�!D*P�
N�P�N/�*P�.N/�/P�2
O�<P�O�P�
O�O(�
O%� O(�(!P
�	P�P
�
P�0Q�Qc��^�U4SjnU4Sjn[SSSS9nUR5R5R5SSupEnSSS5 U"5nU"S
5TRSW35TRSW35TRS
W35/nU=(d SR5R5S:XaTRSU5n	OTRU5n	U"S5U	/n
SRU5R5S-SRU
5R5-S-$!,(df   N�=f![a [
R
S5 S	=n=pVGNf=f)Nc�>�[R"S5(d[RS5 gSn[R
R
U5(a+[S[R"U555(d[RS5 g[R"/SQS	S
9nSnUR5SSH]nUR5n[U5S
:aM$[US5nTR (dMFUTR :�dMXUS-
nM_ US:�a[R#SU5 US3$g![a M�f=f![$a [R'S5 gf=f)N�sarz$'sar' not found for historical load.z[Notice] 'sar' not installed�/var/log/sac3�B# �UHoRS5v� M g7f��saNr	)r��names  r r��Hget_load_stats.<locals>.get_historical_high_load_text.<locals>.<genexpr>�s���M�:L�$����-�-�:L���zsysstat logging not enabled.z%[Notice] sysstat logging not enabled.)r�-q�-s�00:00:00Tr�rr�r��rIz%d high-load events foundz? instance(s) of 1-minute load exceeding logical CPU core count.z2No high load events recorded in the past 24 hours.z.Failed to gather historical load data from sarz.[Error] Unable to gather historical load data.)ru�whichr6r�r3r��isdirr��listdirr�r�rr�rhr�r�r�r�rrI)�sa_dirr��high_load_event_countr��parts�one_min_loadr�s      �r �get_historical_high_load_text�5get_load_stats.<locals>.get_historical_high_load_text�sW���(	D��<�<��&�&����E�F�5�"�F����
�
�f�%�%��M�"�*�*�V�:L�M�M�M����=�>�>��,�,�/�d��F�%&�!��)�)�+�A�B�/���
�
����u�:��>���#(��q��?�L��(�(�(�$��(<�(<�<�)�Q�.�)�0�%�q�(����7�9N�O�/�0�0o�p�p�G��"������	D����M�N�C�	D�sN�0E�A&E�AE�,E
�:E�
E�)E�

E�E�E�E�E=�<E=c�>�[U5RS5S3nTRSU5nTRSU5$r�r<�r�r>rAr�s   �r �_format_label_only�*get_load_stats.<locals>._format_label_only��D����E�
�)�)�#�.�/�q�1�
��'�'��
�;�
��!�!�'�:�6�6r)z
/proc/loadavgr-rJrr�z;Failed to retrieve runtime load averages from /proc/loadavgr�zRuntime Load Averagesz1 min: z5 min: z15 min: rgz2no high load events recorded in the past 24 hours.rjz24hr High Load Eventsr�

)r1r�r�r�rr6rIrMrqr-rpr=)r�r1r5r�	one_value�
five_value�
fifteen_value�historical_text�
runtime_lines�historical_rendered�high_load_liness`          r �get_load_statsr@�s����)D�V7�
7�
��g�i�
�
�� � �"�(�(�*�0�0�2�2�A�6�
1�I�=�
�4�5�O�	�2�3����'�)�� 5�6����'�*�� 6�7����(�=�/� :�;�	�M�	��2��e�g�e�e�g�M�N�%�0�0��/�J��$�5�5�o�F��	�2�3���O�	
�	�	�-� �'�'�)�
�	�
�)�)�O�
$�
+�
+�
-�	.��	��C
�
���7����I�	
�27�6�	�6�J��	7�s.�E
�3D<�
E
�<
E
�E
�
E
�
$E5�4E5c�R^�Sn[USSS9n[SU55mSSS5 U4Sjn[U"S5S-S	5Ul[U"S
5S-S	5Ul[URUR-
S	5Ul[U"S5S-S	5Ul[SU"S
5U"S5U"S5-U"S5-
-5n[US-S	5Ul[URS-S	5n[RSURURUR
URUR5 U$!,(df   GN3=f![a; [RS5 SUlSUlSUlSUlSUlgf=f)N�
/proc/meminfor-rJrc3�r# �UH-nSU;dMUR5RSS5v� M/ g7f�r9rINr�r�s  r r��,_mem_parse_meminfo_values.<locals>.<genexpr>�s6����'�D��$�;�+��
�
��"�"�3��*�*�'�r�c�x>�[TRUS5R5R5S5$)N�0 kBr)rSr�r�r�)�key_name�meminfos �r �kb�%_mem_parse_meminfo_values.<locals>.kb�s0����w�{�{�8�V�4�:�:�<�B�B�D�Q�G�H�Hr)�MemTotal�r�MemAvailable�	SwapTotalr�Buffers�Cached�SReclaimable�Shmemg�������?z`Memory totals: %s GB total, %s GB available, %s GB allocated, %s GB buff/cache, %s GB swap limitzFailed to parse /proc/meminfog�������?)
r1r#�roundr�r�r�r�rRr�r6r�rrI)r��meminfo_filerrJ�buffcache_kb�unsafe_available_gbrIs      @r �_mem_parse_meminfo_valuesrX�s����"�L�-�
��7�9�
�
���'���G�
�	I�$�B�z�N�W�$<�a�@���#�B�~�$6��$@�!�D���#����&�"5�"5�5�q�
���#�2�k�?�W�#<�a�@����
��y�M�R��\�B�~�,>�>��G��L�M�
��!&�l�W�&<�a� @���#�F�$7�$7�$�$>��B�����n�����������!�!����
	
�#�"�G
�
��J�����8�9���������� !��������s)�E!�E�D+E!�
E�E!�!AF&�%F&c��/n[US5nURS[R5 UR	5nSnUS:�a�[U5U:a�[
X%5nXW-nURU5 URU5U-nURS5nUSn[USS5H%n	[U5U:�a OURU	5 M' US:�a[U5U:aM�U(a [U5U:aURU5 SSS5 [U5V
s/sHo�RSS5PM sn
$!,(df   N9=fs sn
f![a [RSU5 /s$f=f)	N�rbrr)�
rIr-�ignorezFailed to tail log file: %s)r1�seekr3�SEEK_END�tellrhrxr�r��reversedr�r�rr6rI)r��	max_lines�
block_sizer�r�position�buffer�	read_sizer/�raw_liner�s           r �_mem_tail_linesrgsZ���E��
�$��
�����Q����,�"�'�'�)�H��F��Q�,�3�u�:�	�#9��
�5�	��%��� � ��*�$�)�)�)�4�v�=�����U�+���q��� (��q�r�� 3�H��5�z�Y�.���L�L��*�!4��Q�,�3�u�:�	�#9��#�e�*�y�0����V�$�)�,<D�E�?�K�?�4���G�X�.�?�K�K�-�
��,L�������6��=��	��s;�E �CE
�0'E
�E �,E�E �

E�E � "F�Fc���Sn/n[R"S5H�n[RRU5(dM)[	USS9HunUR5nSU;aSU;aM!US-
n[R"SU[R5nU(dMUURURS55 Mw M� X4$![a [RS	5 X4$f=f)
Nrz/var/log/messages*�P�)razkilled process�oomrIzkilled process \d+ \(([^)]+)\)z2Failed to check /var/log/messages* for OOM history)�globr3r��isfilergrqr[r��
IGNORECASEr�rvrr6rI)�	oom_count�killed_processesr�r��
lower_linerus      r �_mem_collect_oom_historyrq/s����I���O��I�I�2�3�D��7�7�>�>�$�'�'��'���>��!�Z�Z�\�
�$�J�6��Z�/���Q��	��	�	�5�t�R�]�]����5�$�+�+�E�K�K��N�;�?�	4�,�&�&���O����M�N��&�&�O�s�BC�$(C�C3�2C3c	��[R"S5(dgSn[RR	U5(a+[S[R"U555(dg[R"/SQSS9nUR5nSn/n[U5HsupgSUR5;dMUR5R5nURS5URS	5URS
5S.nX6S-Sn O U(dgSn	UH�nUR5n
[U
5[UR!55::aM;[#[%X�S5[%X�S	5-[%X�S
5-S
-S5nX�:dM�U	S-
n	M� [(R+SU	5 U	$![&a M�f=f![,a [(R/S5 gf=f)Nrrrc3�B# �UHoRS5v� M g7fr!r	)r��filenames  r r��1_mem_collect_low_memory_events.<locals>.<genexpr>Ts���M�:L�h�#�#�D�)�)�:L�r%)r�-rr'r(Tr��	kbmemfree�	kbbuffers�kbcached)rwrxryrIrMrz(Low memory availability events (24h): %dz2Failed to analyze historical memory usage with sar)rur*r3r�r+r�r,r�r�r�	enumeraterqr��indexrhrR�valuesrTrSr�r6r�rrI)rWr-r��	sar_lines�header_indexes�
data_lines�
line_indexr��header�low_memory_event_countr/�avail_gbs            r �_mem_collect_low_memory_eventsr�Ms����<�<�����
�F�
���
�
�f����M�"�*�*�V�:L�M�M�M��2��(�(�+�$�
���%�%�'�	����
� )�)� 4��J��d�j�j�l�*�����+�+�-��!'���k�!:�!'���k�!:� &���Z� 8�"��
'�A�~�'7�8�
��!5���!"���D��J�J�L�E��5�z�S��!6�!6�!8�9�9��
� ��E��"=�>�?��e�;�$?�@�A�B��e�:�$>�?�@�A�������-�&�!�+�&�%�(	���6�8N�	
�&�%���
��
�������M�N���sJ�0A
G�A#G�%?G�%?G�$G�+ G�
G�G�G�G�G?�>G?c
���[U5n[5up#[U5n[U5S:waSOSn[U5S:XaSOSnURSURS35URSURS35URSURS35URS	URS35URS
URS35SURSUUS
9URSUUS
9/nU(axSR[[U555nURSS5n	UR!URSU	55 UR!URSU55 O UR!URSSSS
95 SRU5R#5S-$![a SnGN�f=f![a SnGN�f=f)NrrTr;rj�Total� GB�	Available�	AllocatedzBuffered/Cachez
Swap Limitrgz%Total Historical Out-of-Memory Eventsr�z$Low Memory Events (24hr, <5% Memory)rgr0z'Recent Process Kills Due to OOM Events:z&Recent Process Kills Due to OOM Eventsrhr)rXrqr�rSrrCr�r�r�r�r�r\rpr�rr-r�r=)
r�rWrnror��oom_value_style�low_mem_value_styler��
unique_killedrAs
          r �get_memory_statsr��s��3�F�;��":�"<��I�;�<O�P��"�#&�y�>�Q�#6�%�G��&��1�2�a�7�G�U�	�	�!�!�'�f�.A�.A�-B�#�+F�G��!�!�+�&�2E�2E�1F�c�/J�K��!�!�+�&�2E�2E�1F�c�/J�K��!�!���!6�!6� 7�s�;�	
�	�!�!�,�6�3E�3E�2F�c�0J�K�
��%�%�3��'�	&�	
�
	�%�%�2�"�+�	&�	
�
�E�*��	�	�&��-=�)>�"?�@�
��'�'��=�
�
�	���V�'�'���<�=�
���V�'�'��}�=�>�
����)�)�8��#�
*�
�	
��9�9�U��"�"�$�t�+�+��_�"�!��"���&�%��&�s"�G�G�G�G�G(�'G(>�aufs�nsfs�proc�ramfs�sysfs�tmpfs�autofs�cgroup�mqueue�pstore�virtfs�debugfs�fusectl�overlay�tracefs�configfs�devtmpfs�squashfs�	hugetlbfs�	selinuxfs�
rpc_pipefs�binfmt_misc)�/proc�/sys�/dev�/runz/var/lib/dockerz/var/lib/containersz/snapc�T�[[U5S-S5$![a gf=f)N�@r�)rTrSr)�bytes_values r �_disk_to_gbr��s0����S��%��1�1�5�5������s��
'�'c�L�[R"US[RUS9$![Ra0n[RSSR
U5U5 SnAgSnAf[a0n[RSSR
U5U5 SnAgSnAff=f)NT�r'�stderrr�zCommand failed: %s -> %srqrgzException running: %s -> %s)r�r��STDOUT�CalledProcessErrorr6r:rpr)�commandr�r@s   r �	_disk_runr��s�����&�&����$�$��	
�	
���(�(�����/����'�1B�C�H��������2�C�H�H�W�4E�s�K����s �$'�B#�&A&�&
B#�3&B�B#c��0nU=(d SR5SSH3nUR5n[U5S:�dM$USXSUS4'M5 U$![a [RS5 U$f=f)NrgrIr
r���zFailed parsing df -PT output)rr�rhrr6rI)�
df_types_text�fs_type_mapr�r/s    r �
_disk_fstypesr�s����K�9�"�(�b�4�4�6�q�r�:�D��J�J�L�E��5�z�Q��5:�1�X��1�X�u�R�y�1�2�;�����9����7�8���9�s�<A�A�A<�;A<c�j^�U=(d SR5U;ag[U4SjU55$)NrgTc3�F># �UHnTRU5v� M g7fr�r	)r�rK�
mountpoints  �r r��_disk_skip.<locals>.<genexpr>s#�����4J�&�
���f�%�%�4J�s�!�rqr�)r��fstype�
exclude_types�exclude_mount_prefixess`   r �
_disk_skipr�s5�����"�����.����4J���r)c���SSSS.n/nU=(d SR5SSH�nUR5n[U5S:aM$USnUSn	URX�4S5=(d Sn
[	X�X#5(aM]US==[US5-
ss'US	==[US
5-
ss'US==[US5-
ss'UR
UU
U	[US5[US
5[US5US
S.5 M� [U5S:H=(a USRS5S:HnU(aUSSO&US(a[US	US-S-S5S3OSnUS(a[USS-S
5OSUS	(a[US	S-S
5OSUS(a[USS-S
5OSUUUS.$![a [RS5 N�f=f)Nr)rT�used�availrgrIr�r)�?rTr�rr�r�r�)�fs�type�mnt�size_gb�used_gbr��pctzFailed parsing df size outputr�r�r�rnrr�0%r�r�)�total_gbr�r��pct_used�single_root�	per_mount)rr�rhr�r�rSr�r�rr6rIrT)
�
df_sizes_textr�r�r��totalsr��	line_textrw�
filesystemr�r�r�r�s
             r �_disk_mountsr�s���!�a�
0�F��I�:�'�-�2�9�9�;�A�B�?�I��o�o�'�G��7�|�a��� ���J� ���J� �_�_�j�%=�r�B�I�c�F���M�����7�O�s�7�1�:��.�O��6�N�c�'�!�*�o�-�N��7�O�s�7�1�:��.�O����$�"�%�*�7�1�:�6�*�7�1�:�6� +�G�A�J� 7�"�1�:��

�%@�@�i�.�A�%�H�)�A�,�*:�*:�5�*A�S�*H�K��	�!��U���g���f�V�n�v�g��6�#�=�q�A�B�!�D��

�6<�G�_�E�&��/�W�-�q�1�#�5;�6�N�E�&��.�G�,�a�0��6<�G�_�E�&��/�W�-�q�1�#��"��
�
���:����8�9�:�s�DG�G3�2G3c���SnSnU=(d SR5SSH{nUR5n[U5S:aM$USnUSn	USn
USnURX�4S5n[	X�X#5(aM^U[U	5-
nU[U
5-
nM} U(a[XT-S-S5S	3OS
n
XEU
S.$![a M�f=f![a [RS5 NTf=f)NrrgrIr�rr�zFailed parsing inode usagernrrr�)rTr�r�)rr�rhr�r�rSr�rr6rIrT)�df_inodes_textr�r�r��inode_total�
inode_usedr�r/r��itotal�iusedr�r��	inode_pcts              r �_disk_inodesr�Vs!���K��J�7�#�)�r�5�5�7���;�D��J�J�L�E��5�z�A�~���q��J��1�X�F��!�H�E��r��J� �_�_�j�%=�r�B�F���M����
��s�6�{�*���c�%�j�(�
�%<�4��*�*�c�1�1�5�
6�a�8�
��
!�Y�G�G���
��
���7����5�6�7�s6�A:C�C�C�
C�
C�C�C�C6�5C6c
�0�//S.nSn/SQ/SQSS/4H&n[USS9nUR5(dM$Un O U(a�UR5H�n[R"S	U5VVs0sHupVXVRS
5_M nnnURS5S;dMTUS
R
SURSS5SURSS5SURSS5SURS5S:XaSOURS5S:XaSOS35 M� [RRS5(am[SSS9nUR5R5n	SSS5 W	(a4S U	;a.US R
S!5 US R
S"U	-S#-5 [R "S%5(a][/S&QS'S9n
U
R5(a<US R
S(5 US R
S"U
R5-S#-5 U$s snnf![a [RS5 GN3f=f!,(df   N�=f![a [RS$5 N�f=f))N��devices�raidrg)�lsblk�-P�-oz+NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT,MODEL,ROTA)r�r�r�z$NAME,TYPE,SIZE,MOUNTPOINT,MODEL,ROTAr�r���r�z(\w+)=(".*?"|\S+)r��TYPE)�diskr��mpathr�z- /dev/�NAMEr�z  (�MODEL�-z	)  Size: �SIZEz	  Media: �ROTA�0�SSD�1�HDDzFailed parsing lsblk outputz/proc/mdstatr-r.r�z**/proc/mdstat:**�```
�
```zFailed reading /proc/mdstat�mdadm)r�z--detail�--scanr)z**mdadm --detail --scan:**)r�r�rr[�findallr�r�rr6rIr3r�r�r1r�rur*)rH�	lsblk_rawr��output_textr��k�vr�r�mdstat_text�
mdadm_scans           r �
_disk_dedir�}st���R�
(�F��I�L�E�	�$����
 ���3�������#�I����
	<�&�1�1�3�	�!#�
�
�+?�� K�� K����w�w�s�|�O� K����7�7�6�?�&?�?��9�%�,�,�!�#�'�'�&�#�"6�!7�s�3�7�7�7�C�;P�:Q�R!�!$�����!5� 6�7"�,/�G�G�F�O�s�,B�5�RU�RY�RY�Z`�Ra�eh�Rh��nq�!t�v��
4�
�w�w�~�~�n�%�%�	<��n�w�7�;�)�.�.�0�6�6�8��8��v��4��v��%�%�&9�:��v��%�%�g��&;�g�&E�F��|�|�G����>��J�
�������6�N�!�!�">�?��6�N�!�!�'�J�,<�,<�,>�">��"H�I��M��;���	<����:�;�	<��
8�7��
�	<����:�;�	<�sV�-H<�2H6�H<�)BH<�
I3�I"�9AI3�6H<�<I�I�"
I0�,I3�3J�Jc�2^�[RS5 S;U4Sjjn[[SS/55n[	[/SQ5U[
[5n[/SQ5=(d
 [SS/5n[UU[
[5n//S	.n[TS
S5=(d SR5S:Xa
[5n[URS
5=(d S5n[URS5=(d S5nU(aX�-OSn	U(aU	S::aSOSn
U"SUS
S35U"SUSSUSS35U"SUSS3U
S9U"SUSSUSSUS S35S/nUS!(a�US"(d�URS#5 URS$RS%S&S'S(S)S*55 [!US!S+S,9HFnURS-RUS.SS/US0SS1US2S3USS3USS3US 55 MH URS45 URS5 [TS
S5=(d SR5S:XaoURS55 UR#US6=(d S7/5 US8(a6URS5 URS95 UR#US85 S:R%U5R'5S:-$![a SnGNf=f![a SnGN	f=f)<Nz2Gathering disk usage, mounts, and RAID/LVM detailsr;c��>�[U5RS5S3nTRSU5nTRSU5nUcSO
[U5nU(dSnTRX&5nUSU3$rXr<)	r�rerZr>rArBr[r@r�s	        �r � _format_label_value_custom_color�7get_disk_info.<locals>._format_label_value_custom_color�s{����E�
�)�)�#�.�/�q�1�
��'�'��
�;�
��*�*�7�J�?�
� �=�R�c�%�j�
��"�J��*�*�;�C�
����-��1�1r)�dfz-PT)rz-B1z,--output=source,size,used,avail,pcent,target)r�-iz#--output=source,itotal,iused,targetrr�r�rgrr�r�r�g�������?rTzTotal Capacityr��Usedr�z GB (r��)r�r��Inodesr�z used / rTz total (r�r�r�z#### Mounted Filesystemsz(```
{:<32} {:<8} {:>8} {:>8} {:>8} {:>6}�Mount�Type�SizeGB�UsedGB�AvailGBzUse%c��US$)Nr�r")�xs r �<lambda>�get_disk_info.<locals>.<lambda>�s��!�E�(r)�r�z${:<32} {:<8} {:>8} {:>8} {:>8} {:>6}r�� r�r�r�r�z```z#### Physical Storage Devicesr�z,- [Info] Could not enumerate physical disks.r�z#### RAID Statusrro)r6r�r�r�r��DISK_EXCLUDE_TYPES�DISK_EXCLUDE_MOUNT_PREFIXESr�r+rqr�r�r�rr��formatr�r�rpr=)
r�rr��	disk_data�
inode_text�
inode_data�dedicated_detailsr�r��	avail_pct�avail_styler��mount_entrys
`            r �
get_disk_infor�sd���
�K�K�D�E�2� �	�4��-� 8�9�K���I�	
�	��#�
�I��;��!�	�D�$�<�	 ������#�	�J�%'��3����
�r�*�0�b�7�7�9�[�H�&�L�������z�2�9�c�:�������z�2�9�c�:��*2��$�s�I�#�	�T�(9�%�w�K�	)���:�!6� 7�s�;�	
�	)��y��+�,�E�)�J�2G�1H��J�	
�	)��I�j�1�2�#�6�K�	
�	)���&�!�"�(�:�g�+>�*?�x�
�SX�HY�GZ�Z[�\�	
�	�
�E�"���i�
�&>�
���/�0�
���7�>�>����8�Y��
�	
�
"��k�"�(:�
�K�
�L�L�6�=�=���&�s��+���'���+�"�9�-�c�2�"�9�-�c�2�"�:�.�s�3���&�
�	
�
�	���U��
���R����
�r�*�0�b�7�7�9�[�H�
���4�5�
����i�(�
@�>�?�	
��V�$��L�L����L�L�+�,��L�L�*�6�2�3��9�9�U��"�"�$�t�+�+��}������
�����s$�#K3�)#L�3L�L�L�Lc��UR(aURR5S:wa[RS5 g[R
"S5(d[R
S5 g[RS5 [R"SS/S	S
9nUR5Vs/sH<nUR5RS5(dM)UR5SPM> nnU(d[R
S
5 g/nUH�n[RSU5 [R"SSU/S	[RS9n[R"SU[R 5nU(d&[R"SU[R 5nU(aUR#S5R%5OSR'5nUR)SUSU35 [R+SUU5 M� [RS5 SR5U5$s snf![R,aAn	[R
SXYR.5 UR)SUS35 Sn	A	GMwSn	A	f[0a0 [R3SU5 UR)SUS35 GM�f=f![0a$n	[R3S5 SU	3sSn	A	$Sn	A	ff=f) Nrz7Skipping SMART check: server is not a Dedicated server.z<SMART health checks are only available on Dedicated servers.�smartctlzsmartctl not found on system.zX[Notice] smartctl not installed. Run `yum install smartmontools` to enable SMART checks.z>Scanning for SMART-compatible devices using `smartctl --scan`.r�Tr�z/dev/rz%No SMART-compatible devices detected.z/[Warning] No SMART-compatible devices detected.z$Checking SMART status for device: %s�-H�r'r�z<SMART overall-health self-assessment test result:\s*([A-Z]+)zSMART Health Status:\s*([A-Z]+)rI�UNKNOWNr!r0z-SMART check for device %s returned status: %szsmartctl failed for %s: rc=%dz: [Error reading SMART data]z%Unexpected error reading SMART for %sz&Completed SMART check for all devices.rzFailed to retrieve SMART stats.z([Error] Failed to retrieve SMART stats: )r�rqr6r�rur*r�r�r�rr�r�r�r�r[r��Irv�upper�
capitalizer�r:r��
returncoderrIrp)
r��scan_outputr�r�r��devicer��mrur=s
          r �get_smart_statsr*s�������!3�!3�!9�!9�!;�{�!J����M�N�M��<�<�
�#�#����6�7�i�;>����L�	
�!�-�-�z�8�.D�4�P��$�.�.�0�
�0���z�z�|�&�&�w�/�
�D�J�J�L��O�0�	�
���N�N�B�C�D����F�#
J����B�F�K�#�0�0���v�.��%�,�,����I�I�S���D�D���
��	�	�:�F�B�D�D��A�12�!�'�'�!�*�*�*�,�y�L�L�N������F�8�2�f�X�6�7����C����+�L	���<�=��y�y��!�!��e
��L�0�0�
J����3�V�\�\������F�8�+G�H�I�I���
J�� � �;�V������F�8�+G�H�I�I�	
J���>����:�;�9�!��=�=��>�ss�8>K�6(H>�"H>�9K�K� C4I�)K�>K�K�5J�K�8K�K�K�K�
L�K<�6L�<Lc�f�/SQn[R"U[R[RSSS9nUR=(d SR5nU(dg/nUH<nUR
SS5upVS	U;aM UR[U5U45 M> U(dg
URSSS9 USS
nSnSn	UHup�U	SU"U
5SSUS3-
n	M U	S-
n	U	$![a M�f=f![a$n[RS5 SU3sSnA$SnAff=f)N)�findr��-pathr��-pruner�r-r�r.r�r-r�r.r�r-r�r.r�r-z/var/spool/postfixr.r��-typerpz-sizez+500M�-printfz%s	%p
TF)r�rXr'�checkrg�0No files larger than 500MB found on the system.
�	rIr�z!No significant disk usage found.
c��US$�Nrr")�ts r r� get_deadweight.<locals>.<lambda>�s��1�Q�4r)r��c���/SQnSn[U5nUS:�a6U[U5S-
:a$US-nUS-
nUS:�aU[U5S-
:aM$XS;a	USX3$USX3$)	N)r��K�M�G�T�Prr�rIr�)r�r:r;�.0fr�)r�rh)�nr�r�s   r �humanize� get_deadweight.<locals>.humanize�s���2�E��A��a��A��t�)��C��J��N� 2��V����Q����t�)��C��J��N� 2�
�8��.��S�'�%�(��$�
��#�w�u�x�j�)�
r)r�r!z>7r�rz"Failed to gather deadweight usage.rG)
r��run�DEVNULL�PIPErXrr�r�rSr�sortr6rI)�find_cmdrHr��entriesr��size_strr��toprAr��sizer=s            r �get_deadweightrL]sK��QA�
��>�����%�%��?�?���
�����$�"�0�0�2���F����D�
�!%���D�!�!4����t�#������H�
�t�4�5���7�������6��c�r�l��	����J�D���H�T�N�2�.�b���b�9�9�G���7������5�
��
��8�A����=�>�<�Q�C�@�@��A�sZ�A"D�%D�-C1�D�	C1�%D�1?D�1
C?�;D�>C?�?D�
D0�D+�%D0�+D0c�"^^^
^�SmSm
U
4SjmU4SjnU4SjnUU4Sjn/SQnSnU"UU5upgU"U5up�n
[RS	U5 [RS
U5 [RSU	5 SS
TRSU5TRSU5TRSU	5/nU(dU
(a�URS
U"S5S/5 U(a@UR	S
5 UR	U"S55 URSU55 U
(a@UR	S
5 UR	U"S55 URSU
55 SRU5R
5S-$)Nc���U=(d SR5Vs/sHBnUR5(dMURS5(aM2UR5PMD sn$s snf)Nrg�#)rr�r�)r'r�s  r �filter_cron_lines�$get_crons.<locals>.filter_cron_lines�sX�����/�/�1�
�1���z�z�|�
�$(�O�O�C�$8�
�D�J�J�L�1�
�	
��
s�A(�A(�A(c�`^�U=(d SR5m[U4SjU55$)Nrgc3�,># �UH	oT;v� M g7fr�r")r��keyword�lowereds  �r r��=get_crons.<locals>.contains_backup_keyword.<locals>.<genexpr>�s����>�X�'�g�%�X���r�)r'�keywordsrUs  @r �contains_backup_keyword�*get_crons.<locals>.contains_backup_keyword�s&����:�2�$�$�&���>�X�>�>�>r)c�R>�UVs/sHnT"X!5(dMUPM sn$s snfr�r")rHrXr6rYs   �r �collect_backup_matches�)get_crons.<locals>.collect_backup_matches�s2���!�
� ��&�u�7�
� �
�	
��
s�$�$c�>�[U5RS5S3nTRSU5nTRSU5$r�r<r4s   �r �
label_only�get_crons.<locals>.label_only�r7r)c�l>�Sn/n[RRS5(a�[SSSS9nUVs/sHBnUR	5(dMURS5(aM2UR	5PMD nnSSS5 U[
W5-
nT"Xa5nURU5 U(a[RS[
U55 UH�n[RRU5(dM)[R"U5V	s/sHn	U	RS5(aMU	PM n
n	U[
U
5-
nT"X�5nURU5 U(dM�[RS	[
U5U5 M� X#4$s snf!,(df   GN!=fs sn	f)
Nrz/etc/crontabr-rJrrOz/Found %d backup-related entries in /etc/crontabroz*Found %d backup-related cron entries in %s)r3r�r�r1r�r�rhr�r6r�r+r,)�cron_directoriesrX�system_count�system_backup_entries�crontab_filer��
crontab_lines�backup_entries�cron_directoryr6�directory_entriesr\s           �r �&collect_system_cron_counts_and_backups�9get_crons.<locals>.collect_system_cron_counts_and_backups�s������ "��
�7�7�>�>�.�)�)�������!-�!� ,���z�z�|�!�,0�O�O�C�,@�!�D�J�J�L� ,��!��
�C�
�.�.�L�3�M�L�N�!�(�(��8�����E���'��
/�N��7�7�=�=��0�0�� �Z�Z��7�!�7�E��'�'��,��7�
�!�

�C� 1�2�2�L�3�4E�P�N�!�(�(��8��~����@���'�"��/�(�2�2��G!����,!s4�F�F�F�/F�F�F1�;F1�F�
F.c	�N>�SnSn/nT
"[R"SS/S[RS95n[U5nT	"X@5nUR	U5 U(a[
R
S[U55 [R"5H�nURnUS;d URS	:dURS
;aM7T
"[R"SSSU/S[RS95nU(dMoU[U5-
nT	"X�5nUR	U5 U(dM�[
R
S[U5U5 M� XU4$![Ra [
RS5 GNf=f![Ra GMf=f)
Nr�crontab�-lTr!z6Found %d backup-related cron entries in root's crontabz$Root does not have a crontab defined)�nobody�mysql��)�
/sbin/nologin�/usr/sbin/nologin�
/bin/falsez-uz/Found %d backup-related entries in %s's crontab)r�r�rDrhr�r6r�r�r:�pwd�getpwall�pw_name�pw_uid�pw_shell)rX�
root_countr��user_backup_entries�
root_linesrg�
user_entry�username�
user_linesr\rPs         ��r �$collect_user_cron_counts_and_backups�7get_crons.<locals>.collect_user_cron_counts_and_backups�s�����
��
� ��	A�*��'�'���%�D��9K�9K���J�
�Z��J�3�J�I�N��&�&�~�6�����L���'���,�,�.�J�!�)�)�H��/�/��$�$�t�+��&�&�G�H��	
�.��+�+�"�D�$��9�!�)�1�1���
����#�j�/�)�J�3�J�I�N��&�&�~�6��~����E���'���9)�D�':�:�:��K�,�,�	A��L�L�?�@�	A��*�0�0�
��
�s$�A6E�.F�)F�F�F$�#F$)z/etc/cron.dz/etc/cron.dailyz/etc/cron.hourlyz/etc/cron.monthlyz/etc/cron.weekly)�backupzSystem cron job count: %dzRoot cron job count: %dzUser cron job count: %dzPScheduled tasks configured on the server, either system-managed or user-defined.rgz4System Cron Job Count (/etc/crontab and /etc/cron.*)z+Root Cron Job Count (`crontab -l` for root)z,User Cron Job Count (`crontab -l -u <user>`)zBackup-Related Cron JobszzPossibly related to system or user backups. Timing affects system load, therefore backups should run during nightly hours.z8Found in system-level crontab or /etc/cron.* directoriesc3�,# �UH
nSU3v� M g7f�r!Nr"�r�r6s  r r��get_crons.<locals>.<genexpr>g	s���N�3M�%�2�e�W��3M���z(Found in crontab entries (root or users)c3�,# �UH
nSU3v� M g7fr�r"r�s  r r�r�l	s���L�3K�%�2�e�W��3K�r�r)r6r:rCr�r�rpr=)r�r_rjr��system_cron_directories�backup_keywords�system_cron_job_count�system_backup_cron_entries�root_cron_job_count�user_cron_job_count�user_backup_cron_entriesr�r\rYrPs`           @@@r �	get_cronsr��s����
�?�
�7�
+3�Z8;�t��"�O�	/�#��	
�6��	-�_�=�G��.F��L�L�,�.C�D�
�L�L�*�,?�@�
�L�L�*�,?�@�	[�
��!�!�B�!�	
�	�!�!�9�;N�	
�	�!�!�:�<O�	
�

�E�"�%=�
�����5�6�M�
�	
�&��L�L����L�L��N��
�

�L�L�N�3M�N�N�#��L�L����L�L��$N�O�P��L�L�L�3K�L�L��9�9�U��"�"�$�t�+�+r)c!�^�[RS5 [TR=(a& [	TR5R5S:H5nS[
U5-n[TRTRTR4UTR5nU4SjnU4Sjn0nURS5 [T5US'URS5 [5US	'URS
5 [5US'URS5 [!T5US
'URS5 [#T5US'URS5 [%T5US'URS5 ['T5US'SnU(aHURS5 [)T5US'TR+S5STR-US5S3n[/TSS5c[0R3[45TlSnURS5 [=T5US'TR?S5STRAS US5STRASUS	5STRAS!US5STR-US
5STR+S"5STR-US5STR+S#5STR-US5STR+S$5STR-US5SUTR+S%5SUSTR+S&5STR-US53n	TR6bTRCUTR6US'9 U	$TRCU[0R3[S(5US'9 U	$![8a  [R;S5 STlGN�f=f![8a+ [R;S)5 S*n
TREU
5s$f=f)+NzBuilding 'System' sectionrr�c�D>�TRTRU55$r�)rMrU)rMr�s �r �render_deadweight_error�5system_build_section.<locals>.render_deadweight_error�	s����&�&�v�':�':�4�'@�A�Ar)c�>�UcSO
[U5nUR5nUS:XaTRSS5$TRU5$)Nrgz/No files larger than 500MB found on the system.rjr2)rUr�r-rM)rMr'�strippedr�s   �r �render_deadweight�/system_build_section.<locals>.render_deadweight�	sR����\�r�s�4�y���:�:�<���H�H��%�%��L��
��&�&�t�,�,r)z
OS versionr��Kernelr��Uptime�uptime_valuez	CPU stats�cpu_summaryz
Load averages�load_summaryzMemory stats�memory_summaryzDisk storage�disk_summaryrgzSMART health�
smart_summaryz### SMART Statusrr8r��*Failed to queue deadweight background scanz<!--DEADWEIGHT_SLOT-->�Crons�cron_summaryz## System SummaryzOperating Systemz
Server Uptimez### Load Averagesz
### Memoryz### Disk Usagez### Large Files (>500MB)z
### Cron Jobs)rArBrCz.[Error] Deadweight scan could not be started.
z Failed to build 'System' sectionz�[Error] Failed to build system section. Please do a manual review for OS version, Kernel version, uptime, CPU, Load, Memory, Disk, Deadweight files, SMART stats, and cron jobs. Please report this bug.)#r6r:r�r�rUrqrSr�r�r�r�r�r�r�r�rrr@r�rr*r6rMr+�EXECUTOR�submitrLr�rrIr�r�rCrDrU)r��is_dedicatedr��section_progressr�r��	summaries�smart_block�deadweight_marker�section_text�
error_texts`          r �system_build_sectionr�q	s9���
�L�L�,�-�����M�s�6�#5�#5�6�<�<�>�+�M��L�
��L�!�!�E�&����	�	�	�v�4�4�5�
����	��B�	-�X/��	����l�+�"0��"8�	�,�����h�'�&0�l�	�"�#����h�'�$.�L�	�.�!����k�*�#0��#8�	�-� ����o�.�$2�6�$:�	�.�!����n�-�&6�v�&>�	�"�#����n�-�$1�&�$9�	�.�!�����!�!�.�1�)8��)@�I�o�&��+�+�,>�?�@���*�*�9�_�+E�F�G�t�M�
�
�6�.��5�=�
0�+3�?�?�>�+J��(�
5�����g�&�$-�f�$5�	�.�!��$�$�%8�9�:�"��(�(�);�Y�|�=T�U�V�VX��(�(��9�=M�3N�O�P�PR��(�(��)�N�:S�T�U�UW��&�&�y��'?�@�A���'�'�(;�<�=�R��&�&�y��'@�A�B�"��'�'��5�6�b��&�&�y�1A�'B�C�D�B��'�'�(8�9�:�"��&�&�y��'@�A�B�"��m��'�'�(B�C�D�B� �!���'�'��8�9���&�&�y��'@�A�B�
D�	�&�#�#�/��&�&�(��/�/�+�
'�
���
�&�&�(�����J��2�
'�
����W�
0�� � �!M�N�+/��(�
0��Z�/����;�<�
5�	�
�"�"�:�.�.�/�s>�,D8O�%N�E'O�+*O�&O�<O�?O�O�2O8�7O8c���SnSnSnSnSnSn[USS5=(d SR5n[US	S5=(d SR5n/n	S
n
SnUS:Xa/U"U5nU(d[RSU5 U"5up�OvUS
;aQU"5n	[	U	5n
U"U5nU(a[RSUU5 O6[R
SU5 OUS:XaSnSn
S/n	OUS:XaU"5up�SnU"USU5 U"USU	5 U"USU
5 [USU
5$![a.nS[U5S3n
[RS5 SnAN^SnAff=f)Nc�j�[XU5 g![a [RSU5 gf=f)NzFailed to set %s)�setattrrr6rI)�obj�	attr_nameres   r �safe_setattr�$get_user_stats.<locals>.safe_setattr�	s1��	<��C�E�*���	<����/��;�	<�s�� 2�2c���Sn[SSU05nURS05=(d 0RS05=(d 0nURS5=(d SnU(a[RSUU5 U(aU$[R"SU/S	[RS
S9R5nUR5=(d S/SnU(a[RS
UU5 U$![a [RSU5 N�f=f![a [RS5 U$[a [RSU5 U$f=f)N�domainuserdatar�r-�userdata�userz1cPanel domain owner for %s via domainuserdata: %szBWHM API call 'domainuserdata' failed while looking up owner for %s�whoownsTr)r�rz*cPanel domain owner for %s via whoowns: %sz"whoowns binary not found on systemz7'whoowns' fallback failed while looking up owner for %s)
rr�r6r�rrIr�r�rDr�r�r�r:)�domain_name�
owner_name�responser��whoowns_outputs     r �cpanel_domain_owner�+get_user_stats.<locals>.cpanel_domain_owner�	sj���
�	��/�(�K�1H�I�H� ���V�R�0�6�B�;�;��B����
�"���f�-�5��J�����G�������	�'�4�4��K�(��!�)�)��	�
�e�g�
�)�.�.�0�:�T�F�A�>�J�����@�������?�	����T��
�	��.!�	?��L�L�=�>���
�	����I��
�
��
	�s+�A:C:�A0D �: D�D� E%�E%�$E%c��Sn/n[S5nURS05=(d 0RSS5n[RSU5 [S5nURS05=(d 0RS	/5=(d /nUVs/sH+oURS
5(dMURS
5PM- nn[RS[U55 X4$![a-nS[U53n[R
S5 SnAN�SnAff=fs snf![a [R
S5 X4$f=f)
Nr�get_current_users_countr-�userszTotal cPanel users: %s�[Error] Unexpected exception: z%WHM API call to get user count failed�	listaccts�acctr�z$Collected cPanel user list: %d usersz4WHM API call to get full user list failed for cPanel)rr�r6r�rrUrIrh)�users_count�
users_listr�r@�account_listr�s      r �cpanel_users�$get_user_stats.<locals>.cpanel_users!
sG�����
�	F��8�9�H�#�<�<���3�9�r�>�>�w��J�K��K�K�0�+�>�
	��{�+�H�$�L�L���4�:��?�?������
�.:��-9�T�X�X�f�=M� ����� �\�
��
�K�K�>��J��P��&�&��%�	F�:�3�s�8�*�E�K����D�E�E��	F�����	����F�
��&�&�	�sC�AC,�AD+�D&�3D&�!D+�,
D#�6#D�D#�&D+�+E�Ec��[R"S/SS[RS9nUR5R	5nUSSVs/sH,o"R5(dMUR5SPM. sn$s snf![au [R"/SQSS[RS9nUR	5Vs/sH)o"R5(dMUR5PM+ Os snfsns$f=f)Nz/scripts/list_usersTrs�r'r�r�rr)r,z$/usr/local/cwpsrv/var/services/usersz	-maxdepthr�r/�lr0z%f
)r�r�rDr�rr�r)r�r�r�s   r �
cwp_user_list�%get_user_stats.<locals>.cwp_user_list=
s���	��,�,�&�'���!�)�)�	�F��L�L�N�-�-�/�E�05�a�b�	�J�	��Z�Z�\�O�D�J�J�L��O�	�J�J��J���	��,�,�	���!�)�)��F� *0�):�):�)<��)<��
�
����
�
��)<���
�!	�s=�AB�
B�)B�B�B�AD�C<�'C<�;	D�Dc�D�[R"SU/SS[RS9R5nU=(d S$![a [
R
SU5 Of=fSn[S5nUR5nURX 45 UR5nU(dSSS5 SSS5 g[[UR555sSSS5 sSSS5 $!,(df   O=fSSS5 g!,(df   g=f)Nr�Tr)r�z2'whoowns' failed for %s, falling back to SQL queryah
        SELECT owner FROM (
            SELECT username AS owner, domain FROM user
            UNION ALL
            SELECT user AS owner, domain FROM domains
            UNION ALL
            SELECT user AS owner, CONCAT(subdomain, '.', domain) AS domain FROM subdomains
            ) AS all_owners
            WHERE domain = %s
            LIMIT 1;
        r�)r�r�rDr�rr6r�r�r�r�r�r
�iterr|)r�r�r�r�r�rHs      r �cwp_domain_owner�(get_user_stats.<locals>.cwp_domain_owner[
s���	�#�0�0��K�(���!�)�)�	�
�e�g�
��%��%���	��N�N�D��
�	��
��"�*�
-������&����u�n�5����*����	�.�
-��D�����1�2���.�
-�����.�
-�
-�sA�?A� A%�$A%�5D�+C6�1D�!C6�#	D�6
D	�D�
Dc�$�Sn[SSS9nUHVnUR5RS5(dM)UR5n[	U5S:�a[US5n O SSS5 1S	kn[R"5Vs/sH3nURU:�dMURU;dM'URPM5 nn[	U5U4$!,(df   Nr=f![a [RS5 N�f=fs snf)
Nrqz/etc/login.defsr-r.�UID_MINrrIz,Failed to parse UID_MIN from /etc/login.defs>rtrrrs)r1r�r�r�rhrSrr6r�rurvrxryrw)�minimum_uid�login_defs_filer�r/�invalid_shellsr6�login_userss       r �baremetal_users�'get_user_stats.<locals>.baremetal_users}
s�����		K��'�'�:�o�+�D��z�z�|�.�.�y�9�9� $�
�
����u�:��?�*-�e�A�h�-�K��,�;�N������
�'���|�|�{�*�
����n�4�
�E�M�M�'�	�
��;���,�,�#;�:���	K��N�N�I�J�	K��
sE�
C(�(C�1C�+C(�D
�&D
�8D
�
C%�!C(�%C(�(D
�	D
r�rgr�rr�zTUnable to determine cPanel domain owner for %s; report.domain_owner will remain None>�CWPr�z)Domain owner for %s via CWP detection: %sz.No domain owner found for %s via CWP detectionr�rzFailed to get CWP user datar��	wordpressrIr�r�r�r�)
r+r�r6r
rhr�r�rrUrI)
r�r�r�r�r�r�r�r�r�r�r�r�r@s
             r �get_user_statsr��	s���<�.�`'�8�< 3�D-�,�&�,��3�9�r�@�@�B�J��f�&6��;�A�r�H�H�J�N��I��J��L��X��*�>�:����L�L�f��
�!-���
�I�	�3�	3�	<�%��I��Y��J�+�N�;�L�����?�"� �����D�"��
�'�	'�"���
� �M�	�	�{�	"� /� 1��
�������6����i�0����z�2��6�<��4�4��#�	<�9�#�c�(��2�F�J����:�;�;��	<�s�8D7�D7�7
E/�$E*�*E/c���U=(d SR5nURSS5SRSS5Sn[R"SU5(aUR	SS5nU$)	Nrgr=rIrrqz^\d{4}\.\d{2}\.\d{2}$ror�)r�r�r[rurJ)�date_strres  r �_reg_normalize_dater��
sb��
�^��"�"�$�E��K�K��Q���"�(�(��a�0��3�E�	�x�x�(�%�0�0��
�
�c�3�'���Lr)c#�|# �[5nU=(d /HnX!;dM
URU5 Uv� M! g7fr�)rr$)�sequence�seenr�s   r �_reg_unique_orderedr��
s2����5�D���B������H�H�T�N��J��s�<�<c�|�Sn[R"5nUR5(aU$U"5HSnU(aH[U5R	5(a(URUS9 [RSU5  U$MSMU U$![a!n[RSX#5 SnAMSnAff=f)Nc3�~# �[RRS5nU(aUv� SnUHnUv� M	 g7f�N�
SSL_CERT_FILE)z /etc/pki/tls/certs/ca-bundle.crtz1/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pemz/etc/ssl/certs/ca-bundle.crt�r3�environr�)�
env_cafile�
candidates�ca_paths   r �candidate_ca_files�2_reg_build_ssl_context.<locals>.candidate_ca_files�
s8����Z�Z�^�^�O�4�
����
�
�
"�G��M�"���;=��cafilez(Loaded CA bundle for RDAP TLS verify: %sz(Failed loading CA bundle %s for RDAP: %s)	�ssl�create_default_context�get_ca_certsr�is_file�load_verify_locationsr6r:r)r��contextr�r@s    r �_reg_build_ssl_contextr��
s�����(�(�*�G��������%�'��
	��4��=�0�0�2�2��-�-�W�-�=����>�����N�3�w�(��N���	��L�L�:�G�
�
��	�s�A
B�
B;�B6�6B;c�p�[U=(d /5Vs/sHoR5PM sn$s snfr�)r�r%)�status_list�ss  r �_reg_normalize_statusesr��
s*��$7��8I�r�$J�K�$J�q�L�L�N�$J�K�K��Ks�3c���U=(d /Vs1sH3o(dMU=(d SRS5R5iM5 nn[U[RS9$s snf)Nrgror)r=rqr�rU)�ns_list�nsrxs   r �_reg_normalize_nameserversr�
sP��9@��B��N��"�2�-���b� � ��%�+�+�-��G�N��'�s�y�y�)�)��Os
�
A"�,A"c�V�SU;a#URSS5SR5$g)NrorI)r�rq)r�s r �_reg_extract_tldrs+��
�f�}��|�|�C��#�A�&�,�,�.�.�r)c��[R"USS0S9n[5n[R"X!US9nURS:wa:[
R"XRSUR3URS5e[R"UR5RSSS	95sSSS5 $!,(df   g=f)
N�Acceptzapplication/json)�headers)r�r�r�zHTTP r-rJ�r)r�Requestr��urlopenru�urlerror�	HTTPErrorr�json�loadsr�r�)�urlr��req�ssl_context�resps     r �_reg_fetch_jsonrs���
�/�/�#��2D�'E�
F�C�(�*�K�	����{�	C�t��;�;�#���$�$��[�[�E�$�+�+��"7����t��
��z�z�$�)�)�+�,�,�W�Y�,�G�H�
D�	C�	C�s�A<B=�=
Cc�^�SU3/n[U5mT(dU$SnSn[R"U5nU(aP[R"5UR-
S:a*[USSS9n[R"U5nSSS5 U(d6[SSS	9n[US
SS9n[R"X55 SSS5 [U[5(aURS5OSn[U[5(a�UH�n[U[5(a[U5S:aM)US
USp�[!U4SjU=(d /55(dMWU	=(d /H<n
U
=(d SR#S5n
U
(dM&UR%U
SU35 M> M� ['5n/nUH,n
X�;dM
UR)U
5 UR%U
5 M. U$!,(df   GNq=f![a SnGN�f=f!,(df   GNY=f![a GNif=f![a SnGN|f=f)Nzhttps://rdap.org/domain/z/tmp/iana_rdap_dns.jsonr��rr-r.z#https://data.iana.org/rdap/dns.jsonrsr��wr*rrrIc3�x># �UH/nTR5[U5R5:Hv� M1 g7fr�)rqrU)r�r6�tlds  �r r��&_reg_rdap_endpoints.<locals>.<genexpr>9s&����K�z��s�y�y�{�c�!�f�l�l�n�4�z�s�7:rgr�z/domain/)rr3�stat�time�st_mtimer1r
�loadrr�dumpr�r#r�rrhr�r=r�rr$)r�r��
cache_path�	iana_data�
cache_stat�handler*�service�tlds�basesr�r��dedupedrrs              @r �_reg_rdap_endpointsr's���,�V�H�5�6�J�
�6�
"�C����*�J��I���W�W�Z�(�
��4�9�9�;��)<�)<�<��E��j�#��8�F� �I�I�f�-�	�9�
�
	�'�5�r��I�
��*�c�G�<���I�I�i�0�=�&0�	�4�%@�%@�	�
�
�j�!�d�
��(�D�!�!��G��g�t�,�,��G��q�0@��!�!�*�g�a�j�%��K�t�z�r�z�K�K�K��������
��*�*�3�/���4��%�%���h�v�h�&?�@�$�
 ��5�D��G����?��H�H�S�M��N�N�3����N�O9�8�����	���=�<���
��
���	��I�	�s~�AH�/G0�H�
H8�!H'�,H�H'�0
G?�:H�?H�H�H�
H$�H'�$H'�'
H5�1H8�4H5�5H8�8I�Ic�(�SnSn[URS/5=(d /5n/nURS/5=(d /H�nURS5=(d /n[SU55(dM6URS/5n[U[5(as[	U5S:�adUSH[n[U[5(dM[	U5S:�dM+US	S
:XdM6[US5R
5=(d Sn O U(dM� O URS/5=(d /HCn	U	RS
S5=(d SR5S:XdM2U	RS5n O URS/5=(d /H;n
URU
RS5=(d U
RS55 M= U=(d SU(a[U5OS[U5[U5SS.$)Nru�entities�rolesc3�X# �UH o=(d SR5S:Hv� M" g7f)rgrrN�rq)r��roles  r r��"_reg_parse_rdap.<locals>.<genexpr>Qs ���I�5�4�J�B�%�%�'�;�6�5�s�(*�
vcardArrayrrIr�r�fnr��events�eventActionrg�
expiration�	eventDaters�ldhName�unicodeNameT)rrrt�statusesrs�
has_object)rr�r�r�rhrUr�rqr�r�r�r)�	rdap_datarr�
expiry_rawr7rs�entityr*�vcard_arrayr6�event�ns_objs           r �_reg_parse_rdapr?Is����I��J��I�M�M�(�B�/�5�2�6�H��K��-�-�
�B�/�5�2�5���
�
�7�#�)�r���I�5�I�I�I���j�j��r�2���k�4�(�(�S��-=��-B�$�Q����u�d�+�+��E�
�a���a��D�(� #�E�!�H�
� 3� 3� 5� =��I��(��9��!6�$���x��,�2��2���I�I�m�R�(�.�B�5�5�7�<�G����;�/�J��3�
�-�-�
�r�2�8�b�8�����6�:�:�i�0�M�F�J�J�}�4M�N�9��&�$�5?�%�j�1�T�+�H�5�1�+�>���r)c	���[R"U[R[RSUSS9nURUR=(d SUR
=(d S4$)NTF�rXr�r'r�r1rg)r�rCrEr&rXr�)�command_args�timeout_secondsr�s   r �_reg_run_cmdrDrsO���>�>��������
���
�D��?�?�T�[�[�.�B�$�+�+�2C��D�Dr)c�T�[U5nU(aU(dg[USSU/SS9up4nUS:wdU(dg[R"SU[R[R
-5nU(aUR
S5R5$S$![a gf=f)N�-hzwhois.iana.orgrs�rCrz^\s*whois:\s*(\S+)\s*$rI)	rrDr[r�r#r;rvr�r)r��
whois_pathrr&rX�_stderrrus       r �_reg_whois_referral_serverrJ~s���
�6�
"�C��j��	�&2�
��/��5�r�'
�#�
�G���?�&���	�	�3�V�R�T�T�B�D�D�[�I��).�u�{�{�1�~�#�#�%�8�D�8������s�B�AB�B�
B'�&B'c�t�[R"S[R5n[R"S[R5n[R"S[R5n[R"S[R5n[R"S[R5nSnSn/n[5n	Sn
U=(d SR	5GH�nU=(d SR5nU(dM&U(dBUR
U5n
U
(a*U
RS5R5=(d SnMoU(dBUR
U5n
U
(a*U
RS5R5=(d SnM�UR
U5n
U
(aNU	RU
RS	5R5RS
5R55 GMUR
U5n
U
(a1URU
RS5R55 GMgU
(aGMqUR
U5n
U
(dGM�Sn
GM� U=(d SU(a[U5OS[U5[U	[RS9U
S
.$)Nz?^\s*(Registrar|Sponsoring Registrar|Registrar Name)\s*:\s*(.+)$z�^\s*(Registry Expiry Date|Registrar Registration Expiration Date|Expiry Date|Expiration Time|paid-till|Expiration Date)\s*:\s*(.+)$z(^\s*Name Server\s*:\s*([A-Za-z0-9\.\-]+)zC^\s*(Domain Status|Status)\s*:\s*([^\s].*?)(?:\s+https?://\S+)?\s*$z^\s*Domain Name\s*:\s*(.+)$FrgrrIroTr)rrrtr7rs�saw_domain_name)r[r\r#rrr�rurvr$r=rqr�r�r�r�rU)�
whois_text�registrar_re�	expiry_re�
ns_line_re�	status_re�domain_name_rerrr:r�rsrLrfr�rus              r �_reg_parse_whoisrS�s���:�:�J�B�D�D��L��
�
�	O�
����I����G����N�J��
�
�N�
����I��Z�Z� >����E�N��I��J��K��%�K��O��%�2�1�1�3����B�%�%�'����� �&�&�t�,�E��!�K�K��N�0�0�2�:�d�	����O�O�D�)�E��"�[�[��^�1�1�3�;�t�
��� � ��&����O�O�E�K�K��N�0�0�2�9�9�#�>�D�D�F�G������%������u�{�{�1�~�3�3�5�6����"�(�(��.�E��u�"&��=4�B�&�$�5?�%�j�1�T�+�K�8��k�s�y�y�9�*��r)c�d^�U=(d SR5mSn[U4SjU55$)Nrg)zno match forz	not foundzstatus: availablezstatus: freez
no data foundzno entries foundzquery_status: 220z!domain you requested is not knownz(this domain name has not been registeredzobject does not existzno such domainc3�,># �UH	oT;v� M g7fr�r")r��sig�lows  �r r��'_reg_whois_not_found.<locals>.<genexpr>�s����-�W�c�c�z�W�rWr�)rM�signalsrWs  @r �_reg_whois_not_foundrZ�s0������
"�
"�
$�C��G��-�W�-�-�-r)c�J�SUlSUlSUl/UlSUlgr�)r�r�r�r�r�)r�s r �_reg_reset_fieldsr\�s*��"�F��#�F��#�F��!�F���F�r)c�H�[USS5=(d SR5R5n[U5 U(aSU;a[RS5 g[
U5GHn[RSU5 [USS9n[U5nUSUlUSUl
US
(aSRUS
5OSUlUSUl[#US5Ul[R'SUR=(d S5 [R'SUR=(d S5 [R'SUR=(d S5 [R'SUR (aSRUR 5OS5 UR)URUR URUR5s $ [R'S5 [*R,"S5nU(d[R/S5 SUlg[1X5nSnU(aUSXq/OSXa/4H�n	U	(dM[RSSRU	55 [3U	SS9up�nU=(d SR5n
U
(aU
S :Xd[5U
5S!:�aU
n O0U(a%[RS"U
U=(d SSS#5 M�M� U(dSUlg&[;U5(a)[R'S'U5 [U5 S(Ulg)UR5nS*U;dS+U;dS,U;a[R/S-5 SUlg.[=U5nUSUlUSUl
US
(aSRUS
5OSUlUSUl[?[#UR5[#UR5[#UR 5[#UR5[#URAS/S(55/5(d[R'S0U5 S(Ulg)S1Ul[R'S2UR=(d S5 [R'S3UR=(d S5 [R'S4UR=(d S5 [R'S5UR (aSRUR 5OS5 UR)URUR URUR5$![a"n[RS	X$5 SnAGM-SnAff=f![a [RS
5  GM�f=f![6R8a [R/S$5 GM�[a"n[R/S%U5 SnAGM�SnAff=f)6Nr�rgrozBget_registration_info called without a valid report.managed_domainz"[Error] Managed domain is not set.zRDAP lookup: %srtr�zRDAP candidate failed: %s -> %sz(RDAP parse error; falling back to WHOIS.rrrtr7rgrsr8z[RDAP] Registrar: %sr:z[RDAP] Expiration: %sz[RDAP] Status: %sz[RDAP] Nameservers: %srhzAttempting WHOIS fallback.�whoisz9whois binary not found in PATH; cannot do WHOIS fallback.zY[Notice] Unable to determine domain registration: RDAP failed and WHOIS is not installed.rFzWHOIS command: %srq�#rGrrGz'WHOIS attempt returncode %s. stderr: %sr�z,WHOIS attempt timed out; trying next option.z-WHOIS attempt failed: %s; trying next option.z+[Error] WHOIS failed or returned no output.z%WHOIS indicates %s is not registered.Fz"[Notice] Domain is not registered.zlimit exceededzquota exceededzplease try again laterz'WHOIS rate limit or throttle indicated.z3[Error] WHOIS rate limit exceeded. Try again later.rLzPWHOIS parsing produced no registration signals for %s; treating as unregistered.Tz[WHOIS] Registrar: %sz[WHOIS] Expiration: %sz[WHOIS] Status: %sz[WHOIS] Nameservers: %s)!r+r�rqr\r6r
r'r:rrr?rIr�r�rpr�r�r�r�r�r|rur*r�rJrDrhr��TimeoutExpiredrZrSr�r�)r�r�rr-r@�fieldsrH�referral_server�whois_outputrBr&rXr�r��whois_lowers               r �get_registration_infore�sL���f�.��3�9�r�
@�
@�
B�
H�
H�
J�F��f���S��&����P�	
�4�"�6�*��	��L�L�*�C�0�"�3��3�D�
	�$�T�*�F�
#)��"5���#)�(�#3�� �-3�J�-?�D�I�I�f�Z�(�)�T�	� �$*�-�#8�� �#�F�<�$8�9������"�F�$;�$;�$H�y�	
�	���#�V�%=�%=�%J��	
�	���'��)A�)A�)N�Y�O����$��+�+��	�	�&�2�2�3��	
��(�(��#�#��$�$��$�$��$�$�	
�	
�M+�Z�K�K�,�-����g�&�J�����G�	
� $���j�0��D�O��L�
����7��	��
����	Q��L�L�,�c�h�h�|�.D�E�)5��b�*�&�J���l��)�)�+�F��:��?�c�&�k�B�.>�%�������=���\�r�4�C�(���-�B�#���<��L�)�)����;�V�D��&�!�$���3��$�$�&�K��K�'��{�*�#�{�2����@�A�#���D�
�l�
+�F�$�[�1�F��%�h�/�F��)/�
�);��	�	�&��$�%���� &�m�4�F�����(�(�)���)�)�*���)�)�*���)�)�*�����-�u�5�6�	
���	���^��	
� %���3��F��
�K�K�'��)@�)@�)M�I�N�
�K�K�(�&�*B�*B�*O�i�P�
�K�K�$�f�&>�&>�&K�)�L�
�K�K�!��'�'�
�I�I�f�.�.�/����$�$����� � �� � �� � �	���a�	��L�L�:�C�E���	���	����G�H��	��V�(�(�	K��N�N�I�J�J��	Q��N�N�J�C�P�P��	Q�sO�1 U2�V!�*A)W	�*W	�2
V�<V�V�!W�W�	)X!�6	X!�?X�X!c���S/nU(aURS5 XAU/-
n[R"USUS9R5$![a!n[
R
SXU5 SnAgSnAff=f)N�dig�+shortTr�zdig failed for %s %s: %srg)r�r�r�r�rr6r:)r#�rrtype�shortrC�argsr@s      r �_dns_run_digrl�sp���7�D�����H���T�N��D���&�&��t�_�
�
�%�'�	�������/��s�C����s�#A�
A2�A-�-A2c��[USSS9nUR5Vs/sH#n[R"SU5(dM!UPM% sn$s snf)Nr,T�rjz^\d{1,3}(\.\d{1,3}){3}$)rlrr[ru)r#r��ips   r �_dns_a_recordsrp�sO���t�S��5�K��(�(�*��*�B�
�8�8�.��3�	�*����s� A�Ac��[USSS9n/nUR5H^nUR5nURS5(aUR	S5(aUSSnU(dMMURU5 M` U$)N�txtTrnr�rIr�)rlrr�r��endswithr�)r#r��txt_entriesr�r�s     r �_dns_txt_recordsru�s{���t�U�$�7�K��K� �+�+�-�	��?�?�$�����s�#�#��(9�(9�#�(>�(>���"�~�H��8����x�(�.��r)c��/n[USSS9nU=(d SR5HenSU;aM[R"SUR	55n[US5nUSR
S	5nURXV45 Mg U(d�[USS
S9nUR5Hln[R"SU5nU(dM#UR[URS55URS
5R
S	545 Mn URSS9 U$![a GMf=f)N�mxFrnrgz	MX	�\s+���r�roTz^\s*(\d+)\s+(\S+)\.?$rIrc��US$r5r"�r�s r r�!_dns_mx_records.<locals>.<lambda>�s��T�!�Wr)r)rlrr[r�r�rSr=r�rrurvrF)	r��
mx_records�mx_full_outputr�r/�priority�target�mx_short_outputrus	         r �_dns_mx_recordsr��s#���J�!�+�t�5�A�N�$�*��6�6�8�	��9�$���������!2�3��	��5��9�~�H��2�Y�%�%�c�*�F����x�0�1�9��&�{�D��E��(�3�3�5�I��H�H�5�y�A�E��u��!�!�����Q��(�%�+�+�a�.�*?�*?��*D�E��6��O�O�,�O�-�����	��	�s�4D4�4
E�Ec�:�[S[U55S5$)Nc3�r# �UH-nUR5RS5(dM)Uv� M/ g7f)zv=spf1N�rqr��r�r6s  r r��"_dns_spf_record.<locals>.<genexpr>�s-���	
�2���w�w�y�#�#�H�-�
�A�2���(7�	7)r
ru)r�s r �_dns_spf_recordr��s&���	
�%�k�2�	
�
	
�
�r)c�0�[U5nU(dgUS4$)N��/Missing, which can cause deliverability issues.rTr;)r�)r��
spf_records  r �_dns_spf_displayr��s�� ��-�J��G��w��r)c��[S[SU355S5nU(dg[R"SU[RS9nU(dgURS5R
5R5nUS:Xag	U$)
Nc3�r# �UH-nUR5RS5(dM)Uv� M/ g7f)zv=dmarc1Nr�r�s  r r��,_dns_dmarc_policy_summary.<locals>.<genexpr>�s-���	
�>���w�w�y�#�#�J�/�
�A�>�r�z_dmarc.r�z(?:^|;)\s*p\s*=\s*([^;\s]+)��flagsz'Present (policy missing or unparseable)rIr�z,None, which can cause deliverability issues.)r
rur[r�r#rvr�rq)r��	dmarc_raw�policy_match�policy_values    r �_dns_dmarc_policy_summaryr��s����	
�%���}�&=�>�	
�
	
�
�I��@��9�9�&�	�����L��8��%�%�a�(�.�.�0�6�6�8�L��v��=��r)c�@�[U5nURU5nX#4$r�)r�r�)r�r�r�r&s    r �_dns_dmarc_displayr��s%��-�k�:�M��"�"�=�1�E���r)c��SH.nUSU3n[U5n[SU55(dM. g [S[U555(agg)N)r��	selector1�	selector2�googlerg�dkimz._domainkey.c3�x# �UH0nSU;=(d SU;=(d SUR5;v� M2 g7f)zp=zk=r�Nr,r�s  r r��#_dns_dkim_exists.<locals>.<genexpr>
s7���
� ���Q�Y�?�D�A�I�?�6�Q�W�W�Y�+>�?� �s�8:Tc3�H# �UHnSUR5;v� M g7f)r�Nr,r�s  r r�r�

s���
F�(E�1�6�Q�W�W�Y��(E�s� "F)rur�)r��selector�fqdn�txt_recordss    r �_dns_dkim_existsr��sh������<��}�5��&�t�,���
� �
�
�
��� �
F�(8��(E�
F�F�F��r)c�*�[U5nU(agg)N)�Detectedrjr�)r�)r��dkim_existss  r �_dns_dkim_displayr�
s��"�;�/�K��"�Cr)c��[USS5nU(d[U5nU(aU(aX2;aSUlgSUlgU(aU(dSUlgU(dSUlgSUlg	![a [R	S5 Nqf=f![a [R	S
5 SUlgf=f)N�mail_IPz>get_mail_ip() failed while trying to determine mail routing IPT�LocalF�Externalz5Unknown (MX resolves but outbound mail IP is unknown)zNo MX records foundr:z8Failed while determining local_email from MX and mail IPz.Unknown (error while determining mail routing))r+�get_mail_iprr6rIr)r�r}�mx_top_target_ar�s    r �_dns_mail_routing_statusr�
s��� @��&�)�T�2���
�%�f�-���w��)�%)��"��!&�F����7�!%�F��J��!%�F��(�!�����+�
�� � �T��
��,�@����F�	
�"���?�@�sJ�B�A2�B�B�B�B�*B�2B�B�B�B�&C�?Cc��[R"SS[USS5=(d SR5[RS9RSS5SR5R
S5R5nU(dg	[US
SS9R5Vs/sH+nUR5(dMUR
S5PM- nn[U5n[U5Ul[U5nU(a[USS5O/n[XU5n[S
U3SSS9nU(a"UR5SR
S5OSn	U	(d[S
U35O/n
[U5up�[!X5up�[#U5unnUR%SU(aSR'U5OS5UR%SU(aSR'U5OS5UR%SU(a-SR'UVVs/sHunnSUSU3PM snn5OS5UR%SU(aSR'U5OS5UR%SU5UR%SU	=(d S5/nU	(d9UR)UR%SU
(aSR'U
5OS55 UR)UR%SUUS95 UR)UR%SU
US95 UR)UR%SUUS95 SR'U5$s snfs snnf)N�
^\s*https?://rgr�r�r�rIrroz[Error] managed_domain is emptyrTrnr��cname�NSrgz
None found�A�MXz
Priority: z	 Target: zHighest Priority MX TargetzMail Routing (Based on DNS)z	WWW CNAMEzWWW A�SPFr�zDMARC Policy�DKIMr)r[rir+r�r#r�r=rqrlrrpr�r�r�r�r�r�r�rrpr�)r��apex_domainr��
ns_records�	a_recordsr}r��mail_routing_status�www_cname_output�	www_cname�
www_a_records�spf_display�	spf_style�
dmarc_display�dmarc_style�dkim_display�
dkim_style�prio�tgtr�s                    r �get_dns_infor�>
sJ��
�����
�V�-�r�
2�
8�b�?�?�A��$�$�		
�
��s�A��q�
	�
���	����	�����0�!��d�$�?�J�J�L��L�D��:�:�<�	����C��L����{�+�I�!�)�_�F�� ��-�J�:D�n�Z��]�1�%5�6�"�O�2��O���$�d�;�-�$8�'��N���	�#�#�%�a�(�/�/��4�
��5>���k�]�+�,�2��.�k�:��K�!3�K�!H��M�0��=��L�*�	�%�%��:�$�)�)�J�'�<�	
�	�%�%������9�%��	
�	�%�%���
�	�	�*4��)3�I�D�#�%�T�F�)�C�5�9�)3���"�	
�	�%�%�(�*9�D�I�I�o�&�|�	
�	�%�%�)�+>�	
�	�%�%�k�9�3L��M�7
�E�<�
����)�)��,9��	�	�-�(�|�
�	
�
�L�L��%�%���!�	&�	
��
�L�L��%�%���#�	&�	
��
�L�L��%�%���"�	&�	
���9�9�U����w��Ps�)L?�L?�Mc�^^�SmU4SjnU4SjnU4SjnSnU4SjnU"5nU"5nU"[TSS55nU"U5n	UTlUTlU	Tl[TSS5=(d S	n
U"S
5SU=(d S3U"S
5S[	U53U"SU
35SU	=(d S3/nSRU5$)Nc�L�[R"USS[RS9$)NTr)r��r�r�rD)rBs r �run_command� get_ip_info.<locals>.run_command�
s$���&�&��t�Q�z�7I�7I�
�	
r)c	�~>�TRSTRS[U5RS5S355$r�)r-rUr=)r>r�s �r �
bold_label�get_ip_info.<locals>.bold_label�
s@����!�!�����v�#�j�/�*@�*@��*E�)F�a�'H�I�
�	
r)c��>�T"/SQ5n[R"SU5nU(aURS5$S$![a n[RSU5 SnAgSnAff=f)N)ro�router�z1.1.1.1z\bsrc\s+(\d+\.\d+\.\d+\.\d+)rIrgzmain ip detection failed: %s)r[r�rvrr6r:)r�ru�errr�s   �r �get_main_ip� get_ip_info.<locals>.get_main_ip�
s[���	� �!B�C�F��I�I�=�v�F�E�%*�5�;�;�q�>�2��2���	��L�L�7��=���	�s�8>�>�
A(�A#�#A(c�>�[5nT"/SQ5nUR5H]nUR5n[R"SU5nU(dM3URS5nUS:wdMLUR
U5 M_ Sn[XS9$![a n[RSU5 SnAN1SnAff=f)N)ro�-4�addrz!inet\s+(\d+\.\d+\.\d+\.\d+)/\d+\srIz	127.0.0.1zall ipv4 detection failed: %sc�f�[SURS555$![a gf=f)Nc3�8# �UHn[U5v� M g7fr�)rS�r��parts  r r��Iget_ip_info.<locals>.get_all_ipv4.<locals>.ip_sort_key.<locals>.<genexpr>�
s���F�3E�4�S��Y�Y�3E�r�ro)��r�r�r�)r�r�r)�ip_texts r �ip_sort_key�6get_ip_info.<locals>.get_all_ipv4.<locals>.ip_sort_key�
s3��
,��F�7�=�=��3E�F�F�F���
,�+�
,�s� #�
0�0r)rrr�r[rurvr$rr6r:r�)�ipv4_addressesr�r�ru�
ip_addressr�r�r�s       �r �get_all_ipv4�!get_ip_info.<locals>.get_all_ipv4�
s�������
	?� �!5�6�F��)�)�+���z�z�|�����!E�t�L���5�!&���Q��J�!�[�0�&�*�*�:�6�
,�	,��n�6�6���	?��L�L�8�#�>�>��	?�s$�A	B�B�3B�
B>�B9�9B>c��U=(d SR5n[R"SSU[RS9n[R"SSU5nUR	SS5SRS5R
5nU$)	Nrgr�r�z^.*@r�rIrro)r�r[rir#r�r=rq)�
raw_domain�domain_values  r r��%get_ip_info.<locals>.normalize_domain�
sq��"�(�b�/�/�1���v�v�.��L����M���v�v�g�r�<�8��#�)�)�#�q�1�!�4�;�;�C�@�F�F�H���r)c��>�U(aSU;agT"SSSU/5nUR5H3nUR5n[R"SU5(dM1Us $ [
R"U5up4nUH#n[R"SU5(dM!Us $ g![a NPf=f![a n[RSX5 SnAgSnAff=f)Nrorgrgrhr�z^\d+\.\d+\.\d+\.\d+$z&dns resolve fallback failed for %s: %s)	rr�r[rur�socket�gethostbyname_exr6r:)	r�r�r��	_hostname�_aliases�	addressesr�r�r�s	        �r �resolve_domain_ipv4�(get_ip_info.<locals>.resolve_domain_ipv4�
s�����c��4��	� �%��3��!D�E�F��)�)�+���z�z�|���8�8�3�T�:�:��K�,�
	�-3�-D�-D��.�*�I��(�
��8�8�3�Z�@�@�%�%�(����	��	���	��L�L�8�+�
�
���		�sB�A	B(�B(�"B(�%8B8�!B8�%B8�(
B5�4B5�8
C"�C�C"r�rgzmanaged domainzServer Host IP:rqr:z
IPs on ServerzIP Assigned to rhr)r+r�r�r�rhrp)
r�r�r�r�r�r�r�r��normalized_domainr��managed_domain_display�
summary_linesr�s
`           @r �get_ip_infor��
s����
�

��7�,��0�m�G��n�G�(���9I�2�)N�O��+�,=�>���F�N��F�N�0�F��	��(�"�-�A�1A��
�'�(�
)��7�+?�i�*@�A��o�&�
'�q��W���7���(>�'?�@�A�
B�!�DU�D_�Y_�C`�a��M��9�9�]�#�#r)c�.�[RSUR5 [S5Ul[RSUR5 UR(d$[R
S5 /UlSUlgURR5nSU;Ga�URRS5 [U5nU(Gai[U5=(d SR5n[RSU=(d S	5 S
U;dSU;a�URRS5 [RS5 [U5n[U5=(d SR5nS
U;a2URRS5 SURS3UlGO[R
SU=(d S	5 O�S
U;a1URRS5 SURS3UlO�[R
SU=(d S	5 [U5UlO�[RS5 [U5UlOrS
U;a1URRS5 SURS3UlO;URRU5 [R
SUR5 [RSUR5 [RSUR5 g)a

Determine the front-end service on :80 and the upstream chain.
Sets:
  - report.web_stack (list)
  - report.vhost_path (path to the *Apache* vhost when Apache is the terminal backend;
                       for standalone NGINX, we set it to the NGINX vhost path.)
z8Determining the server's web stack and vhost path for %srmzService on port 80: %szNo service found on port 80.N�nginxrgz Backend service behind NGINX: %sr"z
cache-main�varnishzKVarnish detected behind NGINX. Checking for backend port in Varnish config.�httpd�apachez /usr/local/apache/conf.d/vhosts/�.confz(Unknown final backend behind Varnish: %sz Unknown backend behind NGINX: %szNGINX is standalone.z Unrecognized port 80 service: %szWeb stack detected: %szVhost path resolved: %s)r6r�r��get_service_on_portr�r:r�r�r�rqr��get_nginx_proxy_pass�get_varnish_backend_port�get_nginx_vhost_path)r��svc�
proxy_port�backend�varnish_port�
final_backends      r �
get_web_stackr
s���K�K�B�����
1��4�F��
�L�L�)�6�+A�+A�B��!�!����5�6���� ����
�
 �
 �
&�
&�
(�C��#�~�������(�)�&�1�
��*�:�6�<�"�C�C�E�G��L�L�2�G�4H�y�
��w�&�)�w�*>�� � �'�'�	�2����a�� 8��?��'��5�;���%�'���m�+��$�$�+�+�H�5�*J�6�K`�K`�Ja�af�(g�F�%��N�N�B�%�2���
�G�#�� � �'�'��1�&F�v�G\�G\�F]�]b�$c��!����6��8L�9��%9��$@��!��K�K�.�/� 4�V� <�F��	�C��������)�.�v�/D�/D�.E�U�K�	��
	������$����.��0F�0F�	
��K�K�(�&�*:�*:�;�
�K�K�)�6�+<�+<�=r)c��[SSU05nURS05RS05=(d 0nURS5=(d SR5$![a [RSU5 gf=f)Nr�r�r-r��documentrootrgz$WHM API domainuserdata failed for %s)rr�r�rr6rI)r��api_responser�s   r �_cpanel_try_api_docrootr	^s}����/�(�F�1C�D���#�#�F�B�/�3�3�J��C�I�r�����^�,�2��9�9�;�;�������?��H���s�A A#�# B�Bc�<�SUSU3nX"S-US-4nUH�n[RRU5(dM)[USSS9nUR	S5(a[
R"U5nO[R"U5nSSS5 [W[5(a5URS5=(d S	R5nU(aUs $M�M� g	!,(df   N]=f![a [RS
U5 GMf=f)N�/var/cpanel/userdata/r�z.yamlz.jsonrr-r.rrgz'Failed reading cPanel userdata file: %s)r3r�r�r1rsr
r�yaml�	safe_loadr�r#r�r�rr6rI)�ownerr��	base_path�candidate_paths�candidate_path�
userdata_filer��
docroot_values        r �_cpanel_try_userdata_docrootrhs��'��w�a��x�8�I� �g�"5�y�7�7J�K�O�)���w�w�~�~�n�-�-��	��n�c�G�<�
�!�*�*�7�3�3�#�y�y��7�H�#�~�~�m�<�H�	=��(�D�)�)�!)���n�!=�!C�� J� J� L�
� �(�(�!�*�*�(�=�<���	����9�>�
�
�	�s+�C6�
AC%�A
C6�%
C3	�/C6�6 D�Dc��[S5oR5nURSXU45 UR5nU(a(UR	S5=(d SR5OSsSSS5 sSSS5 $!,(df   O=fSSS5 g!,(df   g=f![a [RSU5 gf=f)Nr�a�
                SELECT username, CONCAT('/home/', username, '/public_html') AS docroot
                FROM user WHERE domain = %s
                UNION
                SELECT user AS username, path AS docroot FROM domains WHERE domain = %s
                UNION
                SELECT user AS username, CONCAT('/home/', user, '/public_html/', subdomain) AS docroot
                FROM subdomains WHERE CONCAT(subdomain, '.', domain) = %s
                LIMIT 1;
                r�rgz3Failed querying CWP root_cwp for docroot guess (%s))	r�r�r�r�r�r�rr6rI)r�r�r�r�s    r �_cwp_guess_docroot_from_dbr�s����
!�*�
-��{�{�}���N�N�	���(�
��/�/�#�C�9<�C�G�G�I�&�,�"�3�3�5�"�8E�}�
-�
-�}�}��
-�
-�
-�� �����A�6�	
��	�sL�B0�B�AB�2	B�;	B0�
B	�B�B0�
B-�)B0�-B0�0 C�Cc��U(a$[RRU5(dg[USSSS9nUR	5nSSS5 [
R"SW5nU(aURS5R5$S$!,(df   NM=f![a [RSU5 gf=f)	Nrgrr-rJrz DocumentRoot\s+("?)(\/[^\s"]+)\1rz0Failed parsing Apache vhost for DocumentRoot: %s)r3r�r�r1r�r[r�rvr�rr6rI)r��
vhost_file�
vhost_contentrus    r �_cwp_try_apache_vhost_docrootr�s����R�W�W�^�^�J�7�7���
���g�i�
�
�&�O�O�-�M�
�
�	�	�=�}�M��).�u�{�{�1�~�#�#�%�6�B�6�

�
�������>�
�	
��	�s/�B#�B�AB#�B#�
B �B#�# C�Cc��[RSURUR5 [	USS5=(d SR5nUS:XGak[	USS5=(d SR5n[	USS5=(d SR5nU(d2SUl[RUR5 UR$U(d2SUl[RUR5 UR$[U5nU(a2X@l[RS	UR5 UR$[X25nU(a2XPl[RS
UR5 UR$SUl[RSX#5 UR$US
:XGag[[	USS5=(d S5n[	USS5=(d /nSU;a�[	USS5(a�[UR5nU=(d U=(d SUlU(a,[RSUR5 UR$[RSUR5 UR$SU;aTSU;aN[U5=(d U=(d SUl[RSUR5 UR$U=(d SUl[RSU5 UR$US:Xa3SUl[RSUR5 UR$SUl[RSUR5 UR$![a4 U=(d SUl[R!S5 URs$f=f) Nz*Starting docroot resolution for %s on [%s]r�rgr�r�r�z'[Error] No managed_domain set on reportzF[Error] Unable to resolve cPanel domain owner. Docroot lookup skipped.zcPanel docroot from WHM API: %sz%cPanel docroot from userdata file: %sz8[Error] No userdata file found or 'documentroot' missingz.cPanel docroot not found for %s under owner %sr�r�r�r�z)[Error] Apache vhost missing DocumentRootzApache DocumentRoot: %sz9Apache DocumentRoot not found. Using fallback docroot: %sr�z)[Error] Could not determine NGINX docrootzNginx-only docroot: %sz/[Error] Unsupported or missing service in stackz$Could not resolve docroot. Stack: %sz:[Error] Unexpected exception during CWP docroot resolutionz!Failed to resolve docroot for CWPr�z/home/wordpress/doc_rootz!UltraStack ONE: docroot set to %sz[Error] Unsupported panel typezUnsupported panel type: %s)r6r�r�r�r+r�r�r
r	rr�rrr��get_nginx_docrootrrI)	r�r�r�r�api_docroot�
fs_docroot�guessed_docrootr��apache_docroots	         r �get_docrootr!�s5��
�K�K�4���������&�,��3�9�r�@�@�B�J��X���&�"2�B�7�=�2�D�D�F������4�:��A�A�C���F�F�N��L�L����(��>�>�!��e�F�N��L�L����(��>�>�!�-�f�5���(�N��K�K�9�6�>�>�J��>�>�!�1�%�@�
��'�N��K�K�?����P��>�>�!�
G�	��	���<�f�	
��~�~���(�(�4��F�,�b�1�7�R�
���F�K��6�<�"�	�)	"��9�$����t�)L�)L�!>��%�%�"��#�C�&�C�B���
"��K�K� 9�6�>�>�J��~�~�%�	�N�N�S������~�~�%��)�#��	�(A�%�f�-�C�&�C�B���
���4�f�n�n�E��~�~�%� �E�D�
�N�
�N�N�A�9�M��>�>�!��%�%�3������7����H��~�~��5�F�N�
�N�N�/��1B�1B�C��>�>����	"��P�O�
�N�
���@�A��>�>�!�
	"�s&�?A8N�8+N�$AN�>1N�;O�Oc�<^^^^	�[RSUR5 URmT(a$[R
R
T5(dSUlUR$S<U4SjjmS=U4Sjjm	T	"S5nSmU(ac[R"U5RS05=(d 0nSRUR55S-U-R5mS	U4S
j4SU4Sj4S
U4Sj4SU4Sj4SU4Sj4SU4Sj4SU4Sj4SU4Sj4SU4Sj4SU4Sj4SU4Sj4SU4S j4S!U4S"j4S#UU4S$j4S%UU4S&j4S'U4S(j4S)U4S*j4S+U4S,j4S-U4S.j4S/UU	4S0j4S1U4S2j4S3U4S4j4S5U4S6j4S7U4S8j4S9UU	4S:j4/nUHupEU"5(dMX@lUs $ SUlg![a UR5mN�f=f![a [RS;5 SUlgf=f)>NzDetecting CMS for: %sr:c�>�[RRTU5nUS:Xa[RRU5$US:Xa[RR	U5$[RRU5$)Nrpr�)r3r�rprlr+r�)�rel_path�moder��
document_roots   �r r��get_cms.<locals>.existss^����w�w�|�|�M�8�4���3�;��7�7�>�>�$�'�'��3�;��7�7�=�=��&�&��w�w�~�~�d�#�#r)c�">�[RRTU5n[RRU5(a'[	USSSS9nURU5sSSS5 $g!,(df   g=f![a gf=f�Nrr-r\rrg)r3r�rprlr1r�r)r$�	max_bytesr��fhr&s    �r �	read_file�get_cms.<locals>.read_file%s����	��7�7�<�<�
�x�8�D��w�w�~�~�d�#�#��$��g�h�G�2��7�7�9�-�H�G�$�
�	H�G����	��	�s0�AB�A0�$	B�0
A>�:B�>B�
B�
Bz
composer.jsonrg�requirerqzWordPress (WooCommerce)c�v>�T"SS5=(a) T"SS5=(a T"SS5=(a	 T"SS5$)N�
wp-config.phprp�
wp-contentr��wp-includeszwp-content/plugins/woocommercer"�r�s�r r�get_cms.<locals>.<lambda>=sA���F�?�C�0�>��|�S�)�>��}�c�*�>��7��=�>r)�	WordPressc�V>�T"SS5=(a T"SS5=(a	 T"SS5$)Nr0rpr1r�r2r"r3s�r rr4Ds/���F�?�C�0�+��|�S�)�+��}�c�*�+r)�Joomlac�V>�T"SS5=(a T"SS5=(a	 T"SS5$)Nzconfiguration.phprp�
administratorr��
componentsr"r3s�r rr4Js0���F�.��4�*����,�*��|�S�)�*r)�Drupalc�6>�T"SS5=(a	 T"SS5$)N�corer��sitesr"r3s�r rr4Ns���6�&�#�.�G�6�'�3�3G�Gr)�Magentoc�6>�T"SS5=(a	 T"SS5$)Nzapp/etc/env.phprpzbin/magentor"r3s�r rr4Qs!���F�,�c�2�+��}�c�*�+r)�
PrestaShopc�6>�T"SS5=(a	 T"SS5$)Nzconfig/settings.inc.phprp�classesr�r"r3s�r rr4Vs!���F�4�c�:�'��y�#�&�'r)�OpenCartc�V>�T"SS5=(a T"SS5=(a	 T"SS5$)N�catalogr��adminrbr"r3s�r rr4[s/���F�9�c�*�&��w��$�&��x��%�&r)�	MediaWikic�6>�T"SS5=(a	 T"SS5$)NzLocalSettings.phprp�includesr�r"r3s�r rr4as!���F�.��4�(��z�3�'�(r)�Moodlec�6>�T"SS5=(a	 T"SS5$)Nzversion.phprpzlib/moodlelib.phpr"r3s�r rr4fs!���F�=�#�.�1��*�C�0�1r)�TYPO3c�6>�T"SS5=(a	 T"SS5$)N�typo3r�z typo3conf/LocalConfiguration.phprpr"r3s�r rr4ks#���F�7�C�(�@��9�3�?�@r)zConcrete CMSc�6>�T"SS5=(a	 T"SS5$)N�concreter��applicationr"r3s�r rr4ps���F�:�s�+�J��}�c�0J�Jr)�MODXc�V>�T"SS5=(a T"SS5=(a	 T"SS5$)Nr=r��manager�
connectorsr"r3s�r rr4ts/���F�6�3�'�*��y�#�&�*��|�S�)�*r)�
OctoberCMSc�6>�T"SS5=(a	 T"SS5$)Nzmodules/systemr�zconfig/cms.phprpr"r3s�r rr4zs"���F�+�S�1�.��'��-�.r)z	Craft CMSc�.>�T"SS5=(d ST;$)N�craftr�zcraftcms/cmsr"��
composer_blobr�s��r rr4s���F�7�C�(�K�N�m�,K�Kr)�SilverStripec�N>�ST;=(d T"SS5=(d	 T"SS5$)Nzsilverstripe/frameworkzapp/_configr�zmysite/_configr"r[s��r rr4�s/���,�
�=�-��m�S�)�-��&��,�-r)�ExpressionEnginec�>�T"SS5$)Nz	system/eer�r"r3s�r rr4�s���V�K��%=r)�phpBBc�6>�T"SS5=(a	 T"SS5$)Nz
config.phprpzstyles/prosilverr�r"r3s�r rr4�s!���F�<��-�0��)�3�/�0r)�XenForoc�6>�T"SS5=(a	 T"SS5$)Nzsrc/XFr��
internal_datar"r3s�r rr4�s���F�8�S�)�J�f�_�c�.J�Jr)�MyBBc�6>�T"SS5=(a	 T"SS5$)Nzinc/config.phprpzinc/settings.phpr"r3s�r rr4�s"���F�+�S�1�0��)�3�/�0r)�Gravc�v>�T"SS5=(a) T"SS5=(a ST"S5R5;$)Nrbr�zuser/config�gravzsystem/defines.phpr,�r�r,s��r rr4�s?���F�8�S�)�B��}�c�*�B��)�$8�9�?�?�A�A�Br)�DokuWikic�6>�T"SS5=(a	 T"SS5$)Nzdoku.phprpzconf/dokuwiki.phpr"r3s�r rr4�s!���F�:�s�+�1��*�C�0�1r)�Kirbyc�6>�T"SS5=(a	 T"SS5$)N�kirbyr�zsite/configr"r3s�r rr4�s���&��#�.�M�6�-��3M�Mr)�Shopwarec�>�ST;$)N�shopwarer"�r\s�r rr4�s
���Z�=�8r)�Syliusc�>�ST;$)N�syliusr"rts�r rr4�s
���8�}�4r)�Ghostc�V>�T"SS5=(a ST"S5R5;$)NrRr��ghostzpackage.jsonr,rks��r rr4�s,���F�9�c�*�=��9�^�4�:�:�<�<�=r)zUnhandled CMS detection error�r�)i@
)r6r�r�r�r3r�r+r�r
rr�rp�keysrqrrI)
r��composer_raw�required�rules�cms_namer1r\r&r�r,s
      @@@@r �get_cmsr�s����
�K�K�'��)>�)>�?��N�N�M�����
�
�m� <� <�#�������$���_�-�L��M��	1��z�z�,�/�3�3�I�r�B�H�b�H��������)�C�/�,�>��e�g�
�
&�
>�	
�
�
+�	
�
�
*�	
�
�G�H��
+�	
�
�
'�	
�
�
&�	
�
�
(�	
�
�
1�	
�
�
@�	
�
�J�	
�

�
*�	
�
�
.�	
�
�K�	
�

�
-�	
�
�=�>��
0�	
�
�J�	
�

�
0�	
�
�
B�	
�
�
1�	
�

�M�N�	�8�9�	�4�5��
=�	
�Uo
�E�b�$�O�H��w�w�"*���� %�
$�����w�	1�(�.�.�0�M�	1��z�����8�9�#�����s1�A"G�)G2�>	G2�	G2�G/�.G/�2&H�Hc���[U[RRUS5[RRUS5S9n[R"UR
SS9 U$)Nzcurl_headers.txtzcurl_trace.txt)rZr[r\T��exist_ok)rYr3r�rp�makedirsrZ)rZ�	artifactss  r �_site_stats_prepare_tempr��sQ��"�%������n�6H�I��'�'�,�,�~�7G�H��I�
�K�K�	�(�(�4�8��r)c��g)Na.
--- Performance Metrics ---
URL: %{url_effective}
HTTP Response Code: %{http_code}
Redirects Followed: %{num_redirects}
TLS Handshake: %{time_appconnect}s
Time to First Byte: %{time_starttransfer}s
Total Time: %{time_total}s
Download Size: %{size_download} bytes
Download Speed: %{speed_download} B/s
r"r"r)r �_site_stats_curl_format_stringr��s��	2�
r)c�4�SSSSSSSSS	S
[5SUSU/$)
N�curlr'r�z	/dev/null�-A�IMHr zAccept-Encoding: gzip�-Lz-wz
--dump-header�-v)r�)rr[s  r �_site_stats_build_curl_commandr��s<�������
�����&�(������r)c��Ucg[U[5(aU$[U[5(aURSSS9$[U[[
45(aSR
SU55$[U5$)Nrgr-rJrrc3�8# �UHn[U5v� M g7fr�)�_site_stats_coerce_text�r�r�s  r r��*_site_stats_coerce_text.<locals>.<genexpr>�s���I�5�4�0��6�6�5�r�)r�rU�bytesr�rr�rp�res r r�r��sl���}���%�������%�����|�|�G�I�|�6�6��%�$���'�'��y�y�I�5�I�I�I��u�:�r)c���[U5n[USSSS9nURU=(d S5 SSS5 g!,(df   g=f![a [RSUSS9 g	f=f)
Nrr-rJrrgTzFailed to write %s��exc_infoF)r�r1rrr6r:)r�rR�content_textrs    r �_site_stats_write_text_filer��sn���.�w�7��
�$��g�i�
@�K����l�0�b�1�A��A�
@��������)�4�$��?���s+�A�=�A�
A�A�A�A0�/A0c���[R"U[R[RSSSUSS9$![Ra�n[	[USS5=(d [USS5=(d S5n[
X%5 [RS	[US
S5U5 U(aIUR5n[RSS
R[U5S:�aUSSOU55 S[US
S5S3sSnA$SnAf[a [RS5 g[a n[RSU5 SnAgSnAff=f)NTr-rJF)rXr�r'r/rr�r1r�r�rgzcurl timed out after %ss for %sr�rzcurl stderr tail (timeout):
%sr�(����z[Error] curl timed out after r�z1curl executable not found when attempting to run.z"[Error] curl executable not found.z%Unexpected exception running curl: %sz[Error] Failed to execute curl.)r�rCrEr`r�r+r�r6r
rr:rprhr�rIr)�curl_commandrr\rC�
timeout_error�stderr_text�stderr_linesr@s        r �_site_stats_run_curlr��sG��+1��~�~���?�?��?�?����#��	
�		
���$�$�_�-��M�8�T�2�
��}�h��5�
��
��	$�$5�C����-��M�9�i�8��	
��&�1�1�3�L��L�L�1��	�	��<�(�2�-�!���&�%��
�/�w�}�i�QZ�/[�.\�\]�^�^���4����L�M�3��1����@�#�F�0��1�s.�69�E �
CD�
E �"E �7	E �E�E c���0nU=(d SR5H?nSU;aMURSS5up4UR5XR5'MA U$)Nrgr0rI)rr�r�)�stdout_textr�r�r�res     r �_site_stats_parse_metricsr�.sX���N��"��.�.�0���t����Z�Z��a�(�
��&+�k�k�m��y�y�{�#�	1�
�r)c	��/nSnSnU=(d SR5H�nURS5(a,UR5n[U5S:�aUSUSp#MCMEURS5(dM]URS	S5SR	5nURUS
USUS35 M� U$)
Nz???zHTTP/1.1rgz< HTTPr�rIrz< Location:r0rqr3r)rr�r�rhr�r�)r�r��	http_code�
http_protocolr�r/�locations       r �_site_stats_parse_redirectsr�8s������I��M��"��.�.�0���?�?�8�$�$��J�J�L�E��5�z�Q��+0��8�U�1�X�y��
�_�_�]�
+�
+��z�z�$��*�1�-�3�3�5�H��#�#�y�k��8�*�B�}�o�Q�$O�P�1��r)c��0nSn[USSSS9nUHYnUR5RS5(a	US-
n/X'US:�dM8XRUR	55 M[ SSS5 URU/5$!,(df   N =f![
a [RS	5 /s$f=f)
Nr�rr-rJr�http/rIrz7Failed to read/parse dumped headers for final response.)	r1rqr�r�r�rr6r�r�)r[�headers_by_request�header_index�header_filer�s     r �#_site_stats_final_headers_from_dumpr�Is������L��
��c�G�I�
�
�#���:�:�<�*�*�7�3�3� �A�%�L�79�&�4��1�$�&�4�;�;�D�J�J�L�I�$�
��!�!�,��3�3�
�
�������E�	
��	�	�s4�B�7B�
%B�2B�
B�B�B�!C�Cc�&�[SU55$)Nc3�Z# �UH!nSU=(d SR5;v� M# g7f)zcontent-encoding: gziprgNr,)r�r�s  r r��'_site_stats_has_gzip.<locals>.<genexpr>as)����#�F�	!�V�\�r�$8�$8�$:�:�#���)+r{)�
final_headerss r �_site_stats_has_gzipr�`s����#���r)c��UH@nU=(d SR5nSU;aM$SU;aM,SU;dSU;dSU;dM@ g g)	Nrg�cache�miss�hitzhit fromz	cache hitTFr,)r�r��header_lowers   r �_site_stats_has_cache_hitr�gsT������"�+�+�-���,�&���\�!���\�!��\�)��l�*�� �r)c���UHInU(a>[RRU5(a[R"U5 MGMIMK g![a [
R
SU5 Mqf=f)NzFailed to remove %s�r3r�r��removerr6r�)�pathsr�s  r �_site_stats_cleanupr�wsX����	8�������t�,�,��	�	�$��-�t����	8��N�N�0�$�7�	8�s�AA� A5�4A5c��Ucg[U5R5nURS5(aUSSn[U5$![a gf=f)Nr�r�)rUr�rsr�r)r[�raw_texts  r r�r��sZ������:��$�$�&�H��������C�R�=����X��������s�
A�
A�Ac�4�[RSUR5 [R"S5nU(d[RS5 g[
5n[USS5=(d Sn[X2R5n[RSU5 [RS	S
RU55 [RSURUR5 [XCURSS
9n[!U["5(a#[%URUR/5 U$Un['URUR(=(d S5 UR*S:wa�[RSUR*U5 UR(=(d SR-5SSn[RSSRU55 [%URUR/5 SSRU5-$[/UR05nUR3S5Ul[7UR(5n	[9UR5n
[;U
5Ul[?U
5Ul [RSUR45 [RSUR<5 [RSUR@5 URCX�5n[%URUR/5 U$![a [RS5 gf=f![aEn[RS5 [%URUR/5 SU3sSnA$SnAff=f)Nz(Gathering site performance stats for: %sr�z8curl binary not found in PATH. Cannot gather site stats.z&[Error] curl not found on this system.z7[Error] Failed to create temp directory for site stats.r�rgzUsing curl at: %szcurl command: %srqz&Dump headers -> %s ; verbose/err -> %sr8rGrz*curl exited with non-zero status %s for %sr�zcurl stderr tail:
%srzBUnable to retrieve performance metrics at this time due to error:
r�zHTTP Response Code: %szGZIP Compression: %szCache Hit Detected: %sz*Failed to parse curl output for site statsz$[Error] Failed to parse site stats: )"r6r�r�rur*r
r�rrIr+r�r[r:rpr\r�r�rUr�r�r�r&rr�rXr�r�r�r�r�r�r�r�r�)
r��	curl_pathr�rr��process_or_error�process�stderr_tailr�r�r�r��parse_errors
             r �get_site_statsr��s��
�K�K�2�F�4I�4I�����V�$�I�����O�P�7�I�,�.�	��&�*�B�
/�
5�2�C�1��
'�
'��L��L�L�$�i�0�
�L�L�#�S�X�X�l�%;�<�
�L�L�0��"�"��#�#��,��9�6�6�����"�C�(�(��
�
'�
'��)D�)D�E�	
� ���G���#�#�W�^�^�%9�r�����Q�����8�����	
�
�~�~�+��7�7�9�#�$�?�����,�d�i�i��.D�E��
�
'�
'��)D�)D�E�	
�
R��i�i��$�
%�	
�
D�2�7�>�>�B��+�/�/�0D�E���6�w�~�~�F��;��&�&�
�
�/�}�=���8��G������,�f�.@�.@�A����*�F�O�O�<����,�f�.B�.B�C��6�6��
��	�
�
'�
'��)D�)D�E�	
����O�I����E�	
�I�	I��R�D����E�F��
�
'�
'��)D�)D�E�	
�6�k�]�C�C��D�s1�
L#�DM�#M�M�
N�:N�N�Nc�
�[RS5 [URURUR
4SUR5n0nURS5 [U5Ul	URS5 [U5US'URS5 [U5US'[US[5(a?USR5RS5(aUR!S	US5US'URS
5 [#U5US'URS5 [+U5 URS5 [-U5 URS5 [/U5UlURS5 [3USS5(d#UR!S	UR4S35US'O[7U5US'SR?/URAS5PSPURCSUR45PSPURCS[3USS55PSPURCS URD5PSPURCS![3US"S#55PSPURCS$URF5PSPURCS%URH(aS&R?URH5OS'5PSPURCS([3US)S#55PSPURCS*[3US+S5=(d S,5PS-PURKS.5PSPURMUROSS55PS-PURKS/5PSPURMUROSS55PS-PURKS05PSPURMUROSS55PS-PURKS15PSPURQUROSS55P5$![$a5 [R'S5 UR!S	S
5US'SUlGNf=f![8R:a9 [R=SUR45 UR!S	S5US'GN�[$a. [R'S5 UR!S	S5US'GN�f=f![$a, [R'S25 S3nUR!S	U5s$f=f)4Nz$Building 'Account & Website' sectionr�zGathering user informationzFinding server IP information�
ip_summaryzChecking domain registration�registration_summaryz[Notice]rTzBuilding DNS summary�dns_summaryzDNS summary build failedz3[Error] Failed to retrieve DNS information via dig.F�Detecting web stackzFinding document rootz
Detecting CMSz&Collecting site performance statisticsr�zg does not resolve to any IP address on the internet.
Unable to determine website performance statistics�site_stats_summaryz Site stats curl timed out for %sz�[Warning] curl timed out while collecting site performance stats.
The server may be under heavy load or not responding quickly.
Skipping detailed performance metrics for this run.zSite stats collection failedzh[Error] Failed to collect site performance statistics.
Please review curl or site availability manually.rgz'## Account, Website, and Domain SummaryrzManaged Domainz
Account Ownerr��PanelzUser Accounts on Serverr�r:zDomains on ServerzWeb Server Stackrgr
z
Document Rootr�zCMS Detectedr�rhr8z### Site Performance Stats:z### Domain Registration:z### DNS:z### IP Address Info:z+Failed to build 'Account & Website' sectionz�[Error] Failed to build account section. Please do a manual review for account, DNS, IP, and site stats. Please report this bug.))r6r:r�r�r�r�r�r�r�r�r�rer�rU�lstripr�r-r�rrIr�rr!r�r�r+r�r�r�r`r
rpr�rCr�r�r�r6rIr�rM)r�r��section_outputsr�s    r �account_build_sectionr��s��
�L�L�7�8�&����	�	�	�v�4�4�5�	����	��^5������:�;�*�6�2������=�>�(3�F�(;���%����<�=�2G��2O��.�/���2�3�S�
�
��4�5�<�<�>�I�I��
�
�7=�6H�6H���'=�>�7�O�2�3�	���4�5�	+�-9�&�-A�O�M�*�	���3�4��f�����5�6��F�����o�.�!�&�/������F�G��v�0�%�8�8�4:�4F�4F���(�(�)�*E�E�5�O�0�1�
�8F�v�8N�� 4�5�(
P�
P�v�$�$�%N�O�P�
P�PR�
P��(�(�)9�6�;P�;P�Q�R�
P�RT�
P��(�(��'�&�.�Z^�:_�`�a�
P�ac�
P��(�(��&�2C�2C�D�E�
P�FH�
P��(�(�)B�G�F�T`�bk�Dl�m�n�	
P�oq�	
P�
�(�(�)<�f�>Q�>Q�R�S�
P�
TV�
P��(�(�);�]c�]m�]m�d�i�i��HX�HX�>Y�tB�D�E�

P�EG�

P��(�(��'�&�)�U^�:_�`�a�
P�bd�
P��(�(�����UY�9Z�9d�^d�e�f�
P�gk�
P��'�'�(E�F�G�
P�HJ�
P��"�"�?�#6�#6�7K�R�#P�Q�R�
P�SW�
P��'�'�(B�C�D�
P�EG�
P��"�"�?�#6�#6�7M�r�#R�S�T�
P�UY�
P��'�'�
�3�4�
P�57�
P��"�"�?�#6�#6�}�b�#I�J�K�
P�LP�
P��'�'�(>�?�@�
P�AC�
P� �&�&��':�':�<��'L�M�N�!
P�	
��[�	+����7�8�-3�-?�-?��E�.�O�M�*�&+�F�"�
	+��6�,�,�	
����6��8M�8M��9?�8J�8J��J�9�� 4�5��
�� � �!?�@�8>�8J�8J��H�9�� 4�5�
��8�5����F�G�
H�	��!�!�%��4�4�
5�sj�C	S�O?�'BS�Q�H)S�?;P>�:S�=P>�>S�A	S�
S�
3S�S�S�S�3S=�<S=c
�t�SS/SS/SS/SS/SS/SS//nUGH�nUSn[RRU5(aQ[RRU5(a*[R"U[R
5(dM}O[R"U5cM�[R"U[R[RS	S
SS9nUR=(d UR =(d SR#5nU(dGM
[$R&"SU[$R(5nU(d[RSU5 GMSUR+S5nSU3Ul[R/SUR,U5 UR,s $ [R1S5 SUlUR,$![Ra [RS
U5 GM�[a"n[RSX55 SnAGMSnAff=f)N�	apachectlr�z/usr/local/apache/bin/apachectlr�z/usr/local/apache/bin/httpd�
apache2ctl�apache2rTr)FrAz%Apache version probe timed out for %sz&Apache version probe failed for %s: %srgzApache/?(\d+\.\d+(?:\.\d+)?)z0No Apache version string found in output from %srIzApache z%Detected Apache version '%s' using %sz?Apache version could not be determined from available binaries.�#Unable to detect, do this manually.)r3r��isabsrl�access�X_OKrur*r�rCrEr`r6r:rrXr�r�r[r�rmrv�apache_versionr�r�)	r��apache_commandsr��binary_namerHr@�command_output�
version_matchrws	         r �get_apache_versionr�Us���	�d��	*�D�1�	�$��	&��-�	�t��	�D��
�O�#���a�j��
�7�7�=�=��%�%������{�+�+��	�	�+�r�w�w�0O�0O��1P��|�|�K�(�0��	��^�^��!���!������
�F�"!�-�-�>�6�=�=�>�B�E�E�G�����	�	�+���M�M�
�
�
��L�L�B�K�
�
�&�,�,�Q�/��")�.�)9� :������3��!�!��	
�
�$�$�$�i#�l�N�N�I��B�F��� � � ��K�(�(�	��L�L�@�+�N���	��L�L�8�+�
�
��		�s�/5G�*H7�	H7�H2�2H7c�n�[R"US[RUS9$![a gf=f)NTr�rg)r�r�rDr)rBr�s  r �_apache_run_commandr��s@����&�&����%�%��	
�	
������s�$'�
4�4c��UHWn[RRU5(dM)[USSSS9nUR	5nSSS5 X lWs $ g!,(df   N=f![a Mzf=fr))r3r�rlr1r�r$r)r�rr�config_file�config_texts     r �_apache_read_first_existingr��s|��)��
�7�7�>�>�.�)�)�
��"�C�'�(�� �"-�"2�"2�"4�K��/=�+�"�"�*������
��
�s(�A0�A�
A0�
A-	�)A0�0
A>�=A>c���[R"S[R"U5S3U=(d S5nU(dg[UR	S55$![
a gf=f)Nz	(?mi)^\s*z\s+(\d+)rgrI)r[r��escaperSrvr)�directive_name�source_text�directive_matchs   r �_apache_extract_intr��sc���i�i��R�Y�Y�~�.�/�x�8���r��O�����?�(�(��+�,�,������s�A�
A)�(A)c���U=(d SR5HPn[R"SUR55nU(dM1UR	S5R5s $ g)Nrgz^mpm_(\w+)_module\brI)rr[rur�rvrq)�modules_output�output_line�module_matchs   r �_apache_detect_mpm_from_modulesr��sX��&�,�"�8�8�:���x�x� 6��8I�8I�8K�L���<��%�%�a�(�.�.�0�0�;�r)c��SH?n[R"SUS3U=(d S[R5(dM=Us $ g)N)r=�worker�preforkzLoadModule\s+mpm_�_modulerg)r[r�r#)r��
candidate_mpms  r �_apache_detect_mpm_from_configr��sC��7�
�
�9�9� ���w�7��9J��B�D�D�
�
�!� �	8�
r)c���U(aU(dg[R"S[R"U5S3U[R[R-5nU(aURS5$S$)Nrgz<IfModule\s+mpm_z_module>(.*?)</IfModule>rI)r[r�r�r#�Srv)r��mpm_name�block_matchs   r �_apache_extract_mpm_blockr�s[���h���)�)��B�I�I�h�/�0�0H�I��
���r�t�t���K�
$/�;���Q��6�B�6r)c�\^�U4Sjn[TS/5=(d /n[U[5(aU/n[TSS5=(d SR5n[	SU55=(d US;nU(d[
R
S5 g[TS	S5=(d SR5R5n[S
S/5=(d
 [SS/5n[U5Tl
US
:XaSO	US;aSOSn[TU5nU(a!TR(d[U5Tl
[UTR5=(d Un	[SU	5TlTRc[SU	5Tl[SU	5TlTR c[SU	5Tl[SU	5Tl[SU	5Tl[SU	5Tl[SU	5Tl[SU	5Tl[SU	5Tl[SU	5TlU"STR(aTRR15OS5U"STR5U"STR 5/n
TR"b"U
R3U"STR"55 TR$b"U
R3U"STR$55 TR&b"U
R3U"STR&55 TR(b"U
R3U"STR(55 TR*b"U
R3U"STR*55 TR,b"U
R3U"STR,55 TR.b"U
R3U"STR.55 [TSS5(a"U
R3U"S TR455 [
R
S!5 S"R7U
5$)#Nc��>�[U5RS5S3nTRSU5nTRSU5nUcSO
[U5nU(dSnTRSU5nUSU3$rXr<�r�rer>rArBr[r@r�s       �r �_format_label_value_bold_label�7get_apache_conf.<locals>._format_label_value_bold_label��}����E�
�)�)�#�.�/�q�1�
��'�'��
�;�
��*�*�7�J�?�
� �=�R�c�%�j�
��"�J��*�*�7�J�?�
����-��1�1r)r�r�rgc3�N^# �UHm[U4SjS55v� M g7f)c3�Z># �UH o[T5R5;v� M" g7fr��rUrq�r��termr�s  �r r��,get_apache_conf.<locals>.<genexpr>.<genexpr>��!����F�2E�$�C��I�O�O�%�%�2E���(+�r�r�Nr{r�s @r r��"get_apache_conf.<locals>.<genexpr>��'������D�	�F�2E�F�F�F����"%rzApache not in web stackz!Apache not detected in web stack.r�r�z-Mr��cpanel)�'/etc/apache2/conf.modules.d/00-mpm.conf�/etc/apache2/conf/httpd.confz&/etc/apache2/conf/extra/httpd-mpm.conf��cwp�control web panel)z+/usr/local/apache/conf/extra/httpd-mpm.confz!/usr/local/apache/conf/httpd.conf)z%/etc/httpd/conf.modules.d/00-mpm.confz/etc/httpd/conf/httpd.confrr�MaxRequestWorkers�
MaxClients�MaxConnectionsPerChild�MaxRequestsPerChild�ServerLimit�ThreadsPerChild�StartServers�MinSpareThreads�MaxSpareThreads�MinSpareServers�MaxSpareServersz
Apache MPMr:r$z
Config SourcezApache config summary builtr)r+r�rUrqr�r6r�r�r�r�rr�r�rr�rrrrrr r!r"r#r%r�r$rp)r�rr�r��
has_apacher��apache_modules_output�config_pathsr�r�r�s`          r �get_apache_confr'�s6���	2����R�0�6�B�I��)�S�!�!��K�	��v�'8�"�=�C��J�J�L�O������0�
�/�	/��
����-�.�2��&�,��3�9�r�@�@�B�H�H�J�J�/�	�d���.�	�g�t�_�	-��8�8M�N�F����!�	
��9�9�	
�
��,.�f�l�C�K��6�,�,�:�;�G���	"�+�v�/@�/@�A�P�[�� 3��[� �F�����'�#6��+�$
�� �$7� �+�$�F� ��#�#�+�':�!�;�(
��$�!4�M�;� O�F��$7��;�%�F�!�"5���"�F��%8��;�%�F�!�%8��;�%�F�!�%8��;�%�F�!�%8��;�%�F�!�
	'��.4�.?�.?�F���(�(�*�Y�	
�	'���!9�!9�	
�	'�$�f�&B�&B�	
��M�� � �,����*��v�8�8�
�	
�
�$�$�0����*�!�6�#@�#@�
�	
�
�!�!�-����*��� :� :�
�	
�
�$�$�0����*�!�6�#@�#@�
�	
�
�$�$�0����*�!�6�#@�#@�
�	
�
�$�$�0����*�!�6�#@�#@�
�	
�
�$�$�0����*�!�6�#@�#@�
�	
��v�-�t�4�4����*���!<�!<�
�	
��K�K�-�.��9�9�]�#�#r)c	��[USS5nU(d[S5nXlU(aS[U5R	5;a[
R
S5 SUlg[R"S5nU(d]SHWn[RRU5(dM)[R"U[R5(dMUUn O U(d[
RS5 SUlg[ R""US	/[ R$[ R$S
SSS
9nSR+SUR,UR.455R15n[
R3SU=(d S5 [4R6"SU=(d S5nU(d[
RS5 SUlgUR9S5nX�l[
R
SU5 SU3$![&a(n[
R)SX%5 SUlSnAgSnAff=f)Nr�rmr�z<NGINX is not serving on port 80; skipping version detection.z3Not detected (NGINX is not serving HTTP on port 80))z/usr/sbin/nginxz/usr/local/sbin/nginxz/usr/bin/nginxz3NGINX binary not found in PATH or common locations.zBUnable to detect NGINX version (binary not found, check manually).r�Tr)FrAzFailed to execute %s -v: %szAUnable to detect NGINX version (nginx -v failed, check manually).rc3�6# �UHo(dMUv� M g7fr�r"r�s  r r��$get_nginx_version.<locals>.<genexpr>�s����=�����=�s�
�	zRaw NGINX version output: %sz<empty>znginx[^0-9]*([\d.]+\d)rgz*Could not parse NGINX version from output.zDUnable to detect NGINX version (unparseable output, check manually).rIzDetected NGINX version: %szNGINX )r+r�r�rUrqr6r��
nginx_versionrur*r3r�rlr�r�r�r�rCrErrIrprXr�r�r:r[r�rv)	r�r��nginx_binary�	candidate�	completedr@�
raw_outputr�rws	         r �get_nginx_versionr0�s����f�&7��>�O��-�b�1��!0���g�S��-A�-G�-G�-I�I����J�	
� $���D��<�<��(�L��
�I�
�w�w�~�~�i�(�(�R�Y�Y�y�"�'�'�-J�-J�(���
�����L�M�#���P�	
�
��N�N�
�4� ��?�?��?�?����

�	�����#�*�*�I�,<�,<�=����e�g���L�L�/��1H�y�I��I�I�7��9I�r�J�M�����C�D�#���U�"�(�(��+�N�)��
�K�K�,�n�=�
�N�#�$�$��+�
����6��J�#���O�	
��
�s�7H�
I�H<�<Ic	�P�[USS5=(d SR5R5nURSS5n[USS5=(d SR5nUS:XGa[USS5=(d SR5nU(a/SUS	US
3n[R
R
U5(aU$Sn/SQnUH�n[R
RU5(dM)[[R"[R
RUS
555Hn	U"X�5(dMU	s s $ M� [R"SUS
35n
U
(aU
S$SU=(d SS	US
3$US:XaSUS
3$US:XaSUS
3$g)Nr�rgror�r�r�r�z/etc/nginx/vhosts/�__r�c
��[USS9nUH�nSU;aM[R"SSURSS55R	S5nUR5Vs/sHoUR
5PM nnUH5nXQ:Xd$USU3:XdURS	U35(dM,  SSS5 g
 M� SSS5 gs snf!,(df   g=f![a [RSU5 gf=f)
Nr-r.�server_namerxrqrg� ;
r�roTzError scanning NGINX vhost %sF)r1r[rirJr�r�rqrsrr6rI)r�r�rpr�rxr6�tokenss       r �match_domain�*get_nginx_vhost_path.<locals>.match_domain�s���
H��$��1�Q� !��(��4�$�"$�&�&�"�C����m�R�)H�#��%��-� �6=�]�]�_�!E�_��'�'�)�_��!E�!'�A� !��#$�$�v�h��#7�#$�:�:��&��l�#;�#;�'+�2�1�"(�!"�2�"��"F�2�1�"���
H�� � �!@�$�G��
H�sS�
C�AC�#C�<,C�,C�.C�7C�=C�C�
C�C�C� C?�>C?�z/etc/nginx/vhostsz/etc/nginx/conf.d/vhostsz/etc/nginx/conf.d�*.confz/etc/nginx/vhosts/*__rr"r�z/etc/nginx/conf.d/vhosts/r�z/etc/nginx/conf.d/)r+r�rqrJr3r�rlr+r�rkrp)r�r��domain_underscored�panelr�pr7�search_dirsr�r��fallbacks           r r�r��s����f�.��3�9�r�
@�
@�
B�
H�
H�
J�F�����S�1��
�V�\�2�
.�
4�"�;�;�=�E��������4�:��A�A�C���$�U�G�2�.@�-A��G�A��w�w�~�~�a� � ���	�*
���A��7�7�=�=��#�#���t�y�y������a��)B�C�D����-�-��K�E���9�9�4�5G�4H��N�O����A�;��!��!3�)� 4�B�7I�6J�%�P�	
�
�#�#�*�6�(�%�8�8�� � �#�F�8�5�1�1�r)c�^
�Sm
SnSnSnSnU
4Sjn[USS5=(d SR5R5nSnU"U5HQn[US	S
9n	U	R	5n
SSS5 U"W
5HnU"X�5(dMX�4n O U(dMQ O U(dgUSUl[RS
US5 U"US5nU(dgU"X5$!,(df   N�=f![
a [RSU5 M�f=f![
a# [RSUR5 gf=f)Nc��S/nUR[[R"S555 [R"S[R
"U5S3[R5n[R"S[R5nUH�n[RRU5(dM)[USS9nUR5nSSS5 URW5nU(dMgURS5nURU5n	U	(dM�U	RS5R5n
U
R!S	5(a g[R"S
U
5nU(aURS5s $M� g!,(df   N�=f!["a [$R'SUU5 GM5f=f)Nz/etc/nginx/conf.d/upstream.confz/etc/nginx/conf.d/*.confzupstream\s+z\s*\{(.*?)\}z^\s*server\s+([^;#]+);r-r.rIzunix:z:(\d+)$zError reading upstream %s in %s)r�r�rkr[r\r�r�r;r3r�rlr1r�r�rvr�r�rr6rI)�
upstream_name�search_paths�upstream_block_re�	server_re�config_pathr+r'r��
block_body�server_matchr��
port_matchs            r �resolve_upstream_port�3get_nginx_proxy_pass.<locals>.resolve_upstream_portsv��9�:�����F�4�9�9�-G�#H�I�J��J�J��2�9�9�]�3�4�N�C�R�T�T�
���J�J�8�"�$�$�?�	�'�K��7�7�>�>�+�.�.��
��+��8�B��7�7�9�D�9�/�6�6�t�<��"��(�.�.�q�1�
�(�/�/�
�;��#��%�+�+�A�.�4�4�6���$�$�W�-�-���Y�Y�z�6�:�
��%�+�+�A�.�.��#(�2�+9�8���
�� � �5�!����
�s<�
F&�
F� F&�=)F&�(5F&�.F&�
F#	�F&�&!G�Gc	�V�UR5nUH�nSU;aM[R"SSURSS55R	S5nUR5H=nUR5nXR:Xd$USU3:XdUR
SU35(dM<  g M� g	)
Nr4rxrqrgr5r�roTF)rqr[rirJr�r�rs)�block_linesr�rUrerx�tokens      r �
block_matches�+get_nginx_proxy_pass.<locals>.block_matches,s����#�#�%���C��C�'���f�f�V�S�#�+�+�m�R�*H�I�O�O���G�!��������
���$��$�w�i� 0�0��~�~��'��m�4�4��)�
�r)c	3�(# �[5n[U5nU(a9[RR	U5(aURU5 Uv� /SQnUH�n[RR
U5(dM)[[R"[RRUS555HEnXQ;dM
[RR	U5(dM0URU5 Uv� MG M� g7f)Nr9r:)
rr�r3r�rlr$r+r�rkrp)r�r��initial�dirs�	directoryr=s      r �iter_vhosts�)get_nginx_proxy_pass.<locals>.iter_vhosts>s�����u��&�v�.���r�w�w�~�~�g�.�.��H�H�W���M�
���I��7�7�=�=��+�+���D�I�I�b�g�g�l�l�9�h�&G�H�I���=�R�W�W�^�^�A�%6�%6��H�H�Q�K��G�J��s�CD�"D�4Dc��/n/nSnSnUH�nUR5nU(d@URS5(a*SnU/nURS5URS5-
nMZU(dMcURU5 X5RS5URS5-
-
nUS::dM�URU5 Sn/nM� U$)NrF�serverT�{�})r�r�r4r�)r��blocks�cur�depth�	in_serverrer�s       r �extract_server_blocks�3get_nginx_proxy_pass.<locals>.extract_server_blocksSs����������	��C��y�y�{�H���!4�!4�X�!>�!>� �	��e���	�	�#�����3��7����y��
�
�3�����3��#�)�)�C�.�8�8���A�:��M�M�#�&� %�I��C���
r)c�n�SnSn/nUH�nUR5nU(dF[R"SU5(a*SnU/nURS5URS5-
nM`U(dMiUR	U5 X$RS5URS5-
-
nUS::dM� U$ U$)NFrzlocation\s+/\s*\{?TrYrZ)r�r[rur4r�)rM�in_locr]�	collectedrer�s      r �extract_location_block�4get_nginx_proxy_pass.<locals>.extract_location_blockjs��������	��C��y�y�{�H��b�h�h�'<�h�G�G��� �E�	��	�	�#�����3��7����v�� � ��%����3��#�)�)�C�.�8�8���A�:������r)c�>�UH�nUR5nSU;aM[R"SU5nU(aURS5s $[R"SU5=(d [R"SU5nU(dM�URS5n[	USS5=(d SR5nSU;a
T"U5s $ g g)	N�
proxy_passz(proxy_pass\s+https?://[^\s:;]+:(\d+)\s*;rIz+proxy_pass\s+https?://([A-Za-z0-9_.-]+)\s*;z)proxy_pass\s+http://([A-Za-z0-9_.-]+)\s*;r�rg�
ultrastack)r�r[r�rvr+rq)	r��location_linesrer��literal�upstreamrBr<rJs	        �r �parse_proxy_pass�.get_nginx_proxy_pass.<locals>.parse_proxy_pass~s����!�C��y�y�{�H��8�+���i�i�;�X��G���}�}�Q�'�'��y�y�>�������<�h��
�
�x� (���q� 1�
� ���r�:�@�b�G�G�I���5�(�0��?�?��+"�,r)r�rgr-r.zCannot read vhost %srIzNGINX vhost match found in %srzNGINX parsing error for %s)r+r�rqr1r�rr6rI�nginx_matched_vhostr:r�)r�rOrUr_rdrlr��matched_info�	conf_pathr+r��blockr�rJs             @r r�r�sP���"�H�$�*�.�(�2�f�.��3�9�r�
@�
@�
B�
H�
H�
J�F�!���$�V�,�I�
��)�g�6�"��L�L�N�E�7�/�u�5�� ��/�/�$)�#5�L��6�
�|��-� ��%1�!�_��"����4�l�1�o�F�)�,�q�/�:������1�1�17�6���
�� � �!7��C��
��0�����5�v�7L�7L�M���sr�

D'�
D�"C/�3D�;D'�D'�%D'�15D'�'D'�/
C=	�9D�<D'�=D� D$� D'�#D$�$D'�'*E�Ec���[U5n[RRU5(dg[	USS9nUR5nSSS5 [
USS5n[R"S[R"U5S[R"U5S3W5(dg[R"SU[R5nU(a][R"S	URS
55nU(a0URS5R5Ul
UR$[R"S	U5nU(aPURS5R5Ul
[RSX@R5 UR$g!,(df   GNb=f![ a# [R#S
UR$5 gf=f)Nr-r.r�rgz\bserver_name\b[^\n;]*\b(z|www\.z)\bz&location\s+/\s*\{([^{}]|\{[^{}]*\})*\}zroot\s+([^\s;]+);rrIzFound NGINX docroot for %s: %sz$Failed to parse NGINX docroot for %s)r�r3r�rlr1r�r+r[r�r�r�rvr�r�r6r�rrIr�)r�r�rprRr��	loc_blockr)s       r rr�sx����'�D�
�7�7�>�>�$����
�
�$��
)�Q��f�f�h�G�*��f�.��3���y�y�(����3��(8��r�y�y��~�>N�c�R��
�
���I�I�5�w����
�	���	�	�.�	����0B�C�A��!"�����!1�!1�!3����~�~�%��I�I�*�G�4����W�W�Q�Z�-�-�/�F�N��K�K�8�#�~�~�N��>�>�!�
��=*�
)��2�
����2�F�4I�4I�	
��
�s7�
F:�F(�
A F:�.B	F:�8A-F:�(
F7�2F:�:*G'�&G'c��SURS3n[RRU5(d[RSU5 g[
USS9nUR5nSSS5 [R"SW5nU(a)URS5n[RSXQ5 U$[RS	U5 g!,(df   Nl=f![a# [RS
UR5 gf=f)Nz/etc/varnish/conf.d/vhosts/r�zVarnish vhost not found: %sr-r.z\.port\s*=\s*"(\d+)"rIz#Found Varnish backend port %s in %sz*No backend port found in Varnish vhost: %sz$Failed to parse Varnish vhost for %s)r�r3r�rlr6r�r1r�r[r�rvr:rrI)r�r�rprRru�ports      r r�r��s���
(��)>�)>�(?�u�E�D�
�7�7�>�>�$������4�d�;���
�$��
)�Q��f�f�h�G�*��	�	�1�7�;����;�;�q�>�D��L�L�>��K��K����C�T�J��*�
)�������2�F�4I�4I�	
��	�s1�
C�C�(AC�7C�
C�C�*D�Dc�B�[USS5=(d SnUR5R5nU(d([R	S5 SUlUR
$SU;a([R	S5 SUlUR
$SU;dUS	:Xa([R	S
5 SUlUR
$SU;GaSn[R"S5(aF[R"/S
Q[R[RSSS9nURS:HnO�[R"S5(a_[R"/SQ[R[RSSS9nUR=(d SR5nSU;nO[R	S5 X0lUR
$[R	SU5 SUlUR
$![a [RS5 N\f=f)z�
- panel_type contains "Ultrastack ONE"  -> True
- panel_type is Control Web Panel (CWP) -> False (not installable)
- panel_type is cPanel                  -> True if imh-ultrastack-ded is installed
- anything else                         -> False
r�rgzIPanel type unknown while checking for UltraStack; assuming not installed.F�ultrastack onezCPanel type indicates UltraStack ONE, marking UltraStack as present.Trrz?Panel type is Control Web Panel; UltraStack is not installable.r�rpm)rxr&�imh-ultrastack-ded)rXr�r'r1r�
dpkg-query)rzz-Wz-f=${Status}ryzinstall ok installedz=No known package manager found while checking for UltraStack.z?Failed to detect UltraStack package via system package manager.zCUnrecognized panel_type '%s'; assuming UltraStack is not installed.)r+r�rqr6r�r�rur*r�rCrDr&rErXrrI)r��panel_type_raw�panel_type_norm�has_ultrastack_pkgr�r�s      r �check_for_ultrastackr~�s����V�\�2�6�<�"�N�$�*�*�,�2�2�4�O�����W�	
�!&����$�$�$��?�*����Q�	
�!%����$�$�$��o�-��E�1I����M�	
�!&����$�$�$��?�"�"��	��|�|�E�"�"�!�~�~�7�%�-�-�%�-�-�����&*�_�_��%9�"����l�+�+�!�~�~�N�%�?�?�%�-�-������+�+�+��2�2�4��%;�v�%E�"����S��!3���$�$�$�
�K�K�M���"�F��� � � ���	����Q�
�	�s �A G<�1A9G<�+G<�<H�Hc�&^^
^^�Sm
[5[5[5S.m[RR5R	S5mSU
UU4SjjnU4SjnU"5n[TSS5=(d /n[TSS5=(d SR
5nS	RS
U55nSU;=(d SU;=(d US
;nSU;=(d US:HnU(a"URS5(aU"USS5 U(aWURS5(aA[RRUS5(aU"USSURS5S9 TS(dgU4Sjn	U	"S5U	"S5-$)N)N�bot�crawl�crawler�spider�slurp�bingpreview�bingbot�	googlebotzgoogle-inspectiontool�googleother�duckduckbot�	yandexbot�yandeximages�baiduspider�sogou�	seznambot�
semrushbot�mj12bot�ahrefs�	ahrefsbot�applebot�	amazonbot�petalbot�	bytedance�	tiktokbot�	claudebot�opensiteexplorer�blexbot�uptimerobot�pingdom�site24x7�netcraft�dotbot�linkchecker�integritybot�facebookexternalhit�facebot�
twitterbot�
discordbot�linkedinbot�slackbot�whatsapp�telegrambot�	redditbot�ia_archiverzarchive.org_bot�waybackzpython-requests�aiohttpr��wgetzlibwww-perlzgo-http-client�okhttp�gptbotzchatgpt-user�chatgpt�bardzgoogle-extendedzanthropic-aiz	cohere-ai�
perplexitybot�perplexityai�openaiz
openai-sharedzmeta-externalagent�facebookbot�miuibot�zoominfo�majestic�
majestic12�monitis�newrelicpinger�datadog�cloudflarehealthcheckszcloudflare-verifiedbot�
cloudflarebot�
statuscake)rur��botsz	%d/%b/%Y:c�v>�U(a$[RRU5(dg[USSSS9n[	USS9H�upVU(aXS:�a O�T(aTU;aM"U(aX&;aM0[
R"SU5nU(a2URS5nT
SX4==S-
ss'T
S	U==S-
ss'UR5n	THn
X�;dM
T
S
X4==S-
ss'M M� SSS5 g!,(df   g=f![a [RSU5 gf=f)N�rtr-rJrrI��startz"\s+([0-9]{3})\s+rur�r�zFailed processing %s log)r3r�r�r1rzr[r�rvrqrr6r:)r��source_name�
domain_filterrar"�line_numberr��status_match�status_coderp�bot_name�	bot_names�date_patternr s           ���r �process_log_file�'get_web_stats.<locals>.process_log_file�s����2�7�7�>�>�$�/�/��	B��d�D�7�9�E��)2�6��)C�%�K� �[�%<��#��D�(@� �$��)B� �#%�9�9�-A�4�#H�L�#�&2�&8�&8��&;���h���(B�C�q�H�C��h���4��9�4�!%����J�$-��#�1�!�&�M�;�*A�B�a�G�B�%.�!*D�F�E�E��(�	B��L�L�3�[�A�	B�s5�D�B#D�"D�;D�
D�D�D� D8�7D8c�n>�[T	SS5=(d SR5n[T	SS5=(d SR5nSnSnSnUS:XaU(aSUS3nUnGOJUS:XadU(aXSUS	3nSU3n[RR	U5(aUnO&[RR	U5(aUnS
nUnO�US:XaeU(aYSUS
3nSUS
3n[RR	U5(aUnO&[RR	U5(aUnS
nUnOu[RR	S5(aSnO&[RR	S5(aSn[RR	S
5(aS
nUnUUUS.$)Nr�rgr�r�z/usr/local/apache/domlogs/z.logr�z/usr/local/apache/logs/domlogs/z-ssl_logz/var/log/nginx/access.logr�z/var/log/httpd/ssl-z-access.logz/var/log/httpd/z/var/log/httpd/access_logz/var/log/apache2/access.log)�
apache_log�	nginx_log�nginx_domain_filter)r+r�r3r�r�)
r�r��apache_log_path�nginx_log_pathr��primary�alt�ssl_log�non_ssl_logr�s
         �r �resolve_log_plan�'get_web_stats.<locals>.resolve_log_plan�s�����f�l�B�7�=�2�D�D�F�
�!�&�*:�B�?�E�2�L�L�N������"���,�,��0��0@��E� �"1���
�8�
#��5�n�5E�X�N��8��7G�H���7�7�>�>�'�*�*�&-�O��W�W�^�^�C�(�(�&)�O�8�N�"0��
�+�
+��/��/?�{�K�� /��/?�{�K���7�7�>�>�'�*�*�&-�O��W�W�^�^�K�0�0�&1�O�8�N�"0���w�w�~�~�9�:�:�"=������� =�>�>�"?���w�w�~�~�9�:�:�!<��&4�#�*�'�#6�
�	
r)r�r�rgrqc3�T# �UHn[U5R5v� M  g7fr�r	r�s  r r�� get_web_stats.<locals>.<genexpr>�s���B�	��#�d�)�/�/�+�+�	�s�&(r�r�rr�r�r�r�)r�r�z2No recent access log entries detected for today.

c	�$>�T
SRUS5nU(dg/nURSUR5S35 [T
SR	5VVs1sHup4X0:XdMUiM snn[
S9nUH'nURSUS	-S
ST
SX4SS
35 M) URSSS
SUSS35 URS5 T
SR	5Vs/sHofSU:XdM
UPM nnU(d"URS5 SR
U5$[USS9H)up�URSU	S	-SST
SX	4SS
35 M+ URS5 SR
U5$s snnfs snf)Nr�rrgr"z" Access Log Summary
Status Codes:
rurr�r9z<6rq�7drzTotal:r8zBot Activity by User-Agent:
r�z  (none)


c��US$�NrIr"r{s r r�>get_web_stats.<locals>.render_source_summary.<locals>.<lambda>5s��T�!�Wr)z<22)r�r�r$r�r|rSrp)r�rTr��src�code�codesr��bot_keysr�r�r s          �r �render_source_summary�,get_web_stats.<locals>.render_source_summarys�����h��#�#�K��3������
����;�$�$�&�'�'K�L�	
��$)��?�#7�#7�#9�
�#9�K�S��%��#9�
�
�

���D��L�L��T�C�Z��O�1�U�8�_�k�5H�%I�"�$M�R�P�
��
	���r�(�2��a��b�z��6�7�
���4�5�!��=�-�-�/�
�/�C�q�6�[�3H�C�/�	�
���L�L�)�*��7�7�5�>�!�!�(�0D�E�K�A��L�L��X��^�C�(��%��-��8O�*P�QS�)T�TV�W�
�F�
	���V���w�w�u�~���9
��
s�F
�.F
�,F
�<F
)Ni��)r�dt�datetime�now�strftimer+rqrpr�r3r�r�)
r�r�r��log_planr�r��
stack_textr$�	has_nginxr�r�r�r s
`         @@@r �
get_web_statsr�Gs}���O�I�d�)��)��	�
�E��;�;�?�?�$�-�-�k�:�L�:@�B�B�<5
�n �!�H����T�2�8�b�I��v�'8�"�=�C��J�J�L�O����B�	�B�B�J�	�J��	2��j� �	2��1�1��
�:�%�C��G�)C�I��h�l�l�<�0�0���,�/��:�	��L�L��%�%��G�G�N�N�8�K�0�1�1���[�!��"�,�,�'<�=�	
���?�E�'�R!��*�-B�7�-K�K�Kr)c��^^�S[4U4SjjmS+UU4SjjnS[S[4SjnS[4Sjn[TS	S
5=(d S
R5nU(dg[R"S5(dg
SUS3SUS3SU3SU3/nSnS
nS
nS
n	UHIn
U"U
5nUnUR
=(d S
nUR=(d S
n	U"U5nU(a OMK U(dgURS:wa@U(d9U	=(d S
R5SSnU(aSSRU5-$S$U=(d U=(d S
R5n
SU
;=(d SU
;=(d SU
;=(d SU
;nSU
;=(d SU
;=(d SU
;n[U5Tl
U(aSO
U(aSOSTlSTlSTlU=(d S
R5H�nUR5nUR#S5(a8UR%SS 5S R5R'5Tl ORUR#S5(dMyUR%SS 5S R5R'5Tl O TR(dS!U
;aS"TlSTlO%TR(aS#TR;TlTR=(d S$nTR=(d S$nTR (aS%OTR S&LaS'OS$nU"S(U5SU"S)U5SU"S*U5S3$![a GM�f=f),Nr'c�N>�UHnTRX 5nX0:wdMUs $ U$r�r1)r'�stylesr&r2r�s    �r �_apply_first_style�)get_cdn_stats.<locals>._apply_first_styleAs.����E��(�(��5�G�������r)c�N>�[U5RS5S3nT
RSU5nT
RSU5nUcSO[U5R5nU(dSnUR	5U:HnU(a
T	"US5nOT
RSU5nUSU3$)	Nr9r0r;rg�
None detected)rPr�rjrq)rUr=r-r�rq)r�re�
none_tokenr>rArBr?�is_noner@r�r�s         ��r r�5get_cdn_stats.<locals>._format_label_value_bold_labelHs�����E�
�)�)�#�.�/�q�1�
��'�'��
�;�
��*�*�7�J�?�
��-�B�S��Z�-=�-=�-?�	��'�I��/�/�#�z�1���.�y�:M�N�M�"�.�.�w�	�B�M����-��1�1r)�raw_header_textr*c�|�/n/nU=(d SR5H�nU=(d SRS5nUR5RS5(aU/nMFU(dMOUR	5(d
U(aUn/nMqURU5 M� U(aUnSR
U5$)Nrg�
r�r)rr=rqr�r�r�rp)r��
current_block�final_blockrfr�s     r �_extract_final_header_block�2get_cdn_stats.<locals>._extract_final_header_block[s����
���(�.�B�:�:�<�H��N��*�*�4�0�D��z�z�|�&�&�w�/�/�!%��
�� ���:�:�<�<� �"/�K� "�
��� � ��&�!=�$�'�K��y�y��%�%r)rc	��SSSSSSSSU/	n[R"U[R[RS	S
SS9$)
Nr��-sSz-Ir�z
--max-time�15r�z Mozilla/5.0 (compatible; SPARTA)TrtFrA)r�rCrE)r�cmds  r �
_curl_head�!get_cdn_stats.<locals>._curl_headvsQ���������.��

���~�~���?�?��?�?����

�	
r)r�rgz[Error] No managed_domain setr�z[Error] curl not foundr�z/robots.txtr�z[Error] CDN check failedri��zCDN check failed:
rzserver: cloudflarezcf-ray:zcf-cache-status:z
cf-mitigated:zserver: bunnycdnzx-bunnycdn-request-id:z
cdn-cache:�
Cloudflare�BunnyCDNr9rIzcf-mitigated: challenge�	CHALLENGE�HITr��HitFzNot hit�ProviderzCache Statusz	Cache Hit)z
none detected)rUr+r�rur*rXr�rr&rrprqr�r�r�r�r�r�r�r$)r�rrrr��urls_to_try�	last_proc�final_headers_block�raw_headersr�rr�r��
headers_lower�
is_cloudflare�is_bunnyr�rp�provider_str�
status_str�hit_strr�s`                    @r �
get_cdn_statsr@s�������"1�2�2�&&�S�&�S�&�6
��
�*�f�.��3�9�r�
@�
@�
B�F��.��<�<����'��6�(�+�&�
�&���%�
�6�(��
�&���	�K��I����K��K���	��c�?�D��I��+�+�+��K��+�+�+��K�"=�k�"J��"��#���)����q� �)<�"�(�b�4�4�6�s�t�<���
"�D�I�I�k�$:�:�	
�,�	
�)�=�K�=�2�D�D�F�M�	�
�-�	,��
�%�	,���.�	,��m�+�	�	�m�+�	)�#�}�4�	)��=�(�
�!��/�F��%��(�J����#�F���F��$�*��6�6�8���Z�Z�\�
�� � �!3�4�4�� � ��a�(��+�1�1�3�9�9�;�
�#�
�� � ��.�.�� � ��a�(��+�1�1�3�9�9�;�
�#�
�9�
�#�#�%��6�"-���#���	�	 �	 �$��(?�(?�?����&�&�9�/�L��(�(�;�O�J����	�!�/�/�5�8�i�o��*�*�l�C�
D�B�)�.�*�E�
F�b�)�+�w�?�
@��	D���G�	��	�s�!AM(�(
M7�6M7c���Sn[US/5=(d /n[U[5(aU/n[SU55nU(d[RS5 SnU$[USS5=(d SR
5R5nSnUS:XaSnO�US	;aS
nO�US;aY[RRS5(aSnOcS
H+n[RRU5(dM)Un O4 O1SH+n[RRU5(dM)Un O U(a$[RRU5(d[RSU5 SnU$Sn/n[R"U5H�n	U	R5(dMU	RR5n
U
RS5(dSU
;dSU
;aMXU	R!5R"nUR'X�R45 M� U(dSU3nU$UR-SSS9 USSn
U
VV
s/sHup�SU"U5SU
3PM nnn
X�lXPlSUS3S R3U5-nU$![$a GM
f=f![(a'n[R+SU5 SU3nUsSnA$SnAff=fs sn
nf)!Nrgr�c3�N^# �UHm[U4SjS55v� M g7f)c3�Z># �UH o[T5R5;v� M" g7fr�r	r
s  �r r��0get_largest_traffic.<locals>.<genexpr>.<genexpr>�r
rrNr{r�s @r r��&get_largest_traffic.<locals>.<genexpr>�rrz Apache not detected in web stackz@Apache not detected in web stack. Skipping traffic log analysis.r�r�/usr/local/apache/logs/domlogsr�/usr/local/apache/domlogs)rwrh�/var/log/httpd)rr)rrr z,Domlog directory not found for panel_type=%sz"Apache domlog directory not found.c�t�/SQn[U5nUHnUS:dX1S:Xa	USU3s $US-nM! US3$)N)r�r:r;r<r=r�r�r?r�r�)r�)�
size_bytesr�rK�units    r �format_size�(get_largest_traffic.<locals>.format_size(sT��)���Z� ���D��d�{�d�B�i�/��s��D�6�*�*��F�N�D����Q��r)�.gzr�r
zFailed scanning domlogs in %sz([Error] Failed scanning Apache domlogs: z"No usable Apache domlogs found in c��US$r5r"r{s r r�%get_largest_traffic.<locals>.<lambda>Gs��$�q�'r)Tr�rsr!rqz%Top Apache traffic logs (by size) in z:
r)r+r�rUr�r6r�r�rqr3r�r+r��scandirr�r#rsr�st_size�OSErrorr�rrIrF�largest_traffic_results�largest_traffic_log_dirrp)r��result_messager�r$r��log_dirr-r$rHr6r#r"r@�top_entriesr�s               r �get_largest_trafficr1�s����N����R�0�6�B�I��)�S�!�!��K�	������J�����6�7�N�	����&�,��3�9�r�@�@�B�H�H�J�J��G��X��2��	�3�	3�-��	�7�	7�
�7�7�=�=�)�*�*�&�G��	��7�7�=�=��+�+�'�G��
�
�I�
�w�w�}�}�Y�'�'�#���
��"�'�'�-�-��0�0����:�J�	
�>���� ��G���Z�Z��(�E��=�=�?�?���:�:�#�#�%�D��}�}�U�#�#�w�$��'�T�/��
�"�Z�Z�\�1�1�
�
�N�N�J�
�
�3�4�)� �=�g�Y�G�����L�L�)�4�L�8��#�2�,�K�!,�
� +��J�
�[��
$�%�Q�t�f�-� +�
�
�
&1�"�%,�"�0��y��<�t�y�y��?O�O�����5�
��
�������8�'�B�C�C�5�I�������
sI�A.J+�3J�
 J+�K�
J(�#J+�'J(�(J+�+
K�5K�K�Kc�^�U4Sjn[RS5 [TRTRTR
4STR5n0nURS5 [TS/5(d;/(d4[TSS5(d"[RS5 [T5 URS
5 [RS5 [T5US'[RS
5 URS5 [RS5 [TS/5=(d /n[U[5(aU/n[TSS5=(d SR5n[!SU55=(d US;n[!SU55=(d US:HnU(a[#T5OSTlU(a['T5OSTlSUS'TR$(dTR((a�/nTR$(a"UR+U"STR$55 TR((a"UR+U"STR(55 TR-S5S3SR/U5-S-US'URS5 [RS5 [1T5US'[RS5 URS5 [RS5 [3T5Tl[RS5 URS 5 [TS!S5c[7T5 [TS#S5c[9T5 [TS#S5S%La�[R;S&[TS'S5[TS!S5[TS#S55 [TS#S5S(LaTR<S)3OTR<S*3S-[TS!S5S(LaS+O[TS!S5S%LaS,OS--S.-US/'O8[RS05 [?T5US/'[RS15 URS25 [RS35 [AT5US4'[RS55 [TS6S(5(aS7OS8n	TRCS95S:TR-S;5S<TREURGSS55SURGSS5U"S=U	5S:TR-S>5SURGSS5S:TR-S?5SURGS/S5S:TR-S@5STREURGS4S553$![a [RS	5 GNf=f![a [RS"5 GN�f=f![a [RS$5 GN�f=f![a+ [RSA5 SBn
TRIU
5s$f=f)CNc��>�[U5RS5S3nTRSU5nTRSU5nUcSO
[U5nU(dSnTRSU5nUSU3$rXr<rs       �r r�=traffic_build_section.<locals>._format_label_value_bold_labelYrr)zBuilding 'Traffic' sectionr�r�r�r�rgz/traffic: web_stack empty, calling get_web_stackz3get_web_stack failed while building Traffic sectionzAggregating status codesz$traffic: about to call get_web_stats�web_stats_summaryztraffic: finished get_web_statszDetecting web server versionsz*traffic: determining Apache/NGINX versionsc3�N^# �UHm[U4SjS55v� M g7f)c3�Z># �UH o[T5R5;v� M" g7fr�r	r
s  �r r��2traffic_build_section.<locals>.<genexpr>.<genexpr>�s!����J�6I�d��D�	���)�)�6I�rrNr{r�s @r r��(traffic_build_section.<locals>.<genexpr>�s'����
�)��
�J�6I�J�J�J�)�rrc3�Z# �UH!nS[U5R5;v� M# g7f)r�Nr	r�s  r r�r9�s"���K�9J���3�t�9�?�?�,�,�9J�r�r��web_version_block�Apache�NGINXz### Web Server Versionsrz)Collecting Apache configuration variablesz&traffic: about to call get_apache_conf�apache_conf_summaryz!traffic: finished get_apache_confzChecking for UltraStackz+traffic: about to call check_for_ultrastackz&traffic: finished check_for_ultrastackzDetecting CDN/proxyr�z'traffic: get_registration_info() failedr�ztraffic: get_dns_info() failedTzJSkipping CDN/proxy detection for %s (is_registered=%r, domain_resolves=%r)r�Fz does not resolve to an IP.z" DNS resolution status is unknown.zADomain registration check indicates the domain is not registered.z=Domain registration check indicates the domain is registered.z&Domain registration status is unknown.z
CDN/proxy detection skipped.�cdn_status_summaryz$traffic: about to call get_cdn_statsztraffic: finished get_cdn_statszFinding highest traffic logsz*traffic: about to call get_largest_traffic�largest_traffic_summaryz%traffic: finished get_largest_traffic�has_ultrastack_flagr�r�z## Traffic & Web Server Summaryr8z1### Web Server Status Codes and Bot Traffic Statsz4
Based on 100,000 most-recent lines in access log.

zHas UltraStackz$### Apache Web Server Configuration:z### CDN/Proxy Detectionz### Highest Traffic Apache Logsz!Failed to build 'Traffic' sectionz�[Error] Failed to build traffic section. Please perform a manual review of web server status codes, traffic legitimacy, Apache configuration, CDN/proxy configuration, and Apache traffic logs. Please report this as a bug.)%r6r:r�r�r�r�r�r�r+rrrIr�r�rUrqr�r��apache_version_strr0�nginx_version_strr�r6rpr'r~rArer�r�r�rr1r�rMr�rU)r�rr�r��current_web_stackr�r$r��
version_lines�ultrastack_valuer�s`          r �traffic_build_sectionrGXs7���	2��L�L�-�.�&����	�	�	�v�4�4�5�	����	��W/������3�4����R�0�0�B��F�-�r�2�2�b�
����N�O��f�%�	���8�9����;�<�/<�V�/D��+�,����6�7����=�>����A�B�#�F�K��<�B����'��-�-�!2� 3��"�6�+<�b�A�G�R�N�N�P���
�)�
�
�4�� 3�
3�	�
�K�9J�K�K�
*��'�)�	�+5��v�&�$�	�!�*3��f�%��	� �02��+�,��$�$��(@�(@��M��(�(��$�$�2� �&�";�";���
�'�'��$�$�2���!9�!9����+�+�,E�F�G�r�J��)�)�M�*�+���
�/�0�	���I�J����=�>�1@��1H��-�.����8�9����7�8����B�C�%9�&�%A��"����=�>����3�4��6�?�D�1�9�
L�%�f�-��6�,�d�3�;�
C��V�$��6�,�d�3�4�?��K�K�\��� 0�"�5�����6��� 1�4�8�	
��v�'8�$�?�5�H��,�,�-�-H�I�"�1�1�2�2T�U����v���=��F�X�#�6�?�D�A�T�I�X�E��3�3�
�0�1�&
�L�L�?�@�4A�&�4I�O�0�1��L�L�:�;����<�=����A�B�5H��5P��1�2����<�=��V�%:�E�B�B�E��	�
�$�$�%F�G�H���'�'�([�\�]�^D��&�&��':�':�;N�PR�'S�T�U�UW��"�"�#6��;�<�-�.>�@P�Q�R�RV��'�'�(N�O�P�PR��"�"�#8�"�=�>�d��'�'�(A�B�C�2��"�"�#7��<�=�T��'�'�(I�J�K�2��&�&��':�':�;T�VX�'Y�Z�[�
]�
	
��o�
�� � �I��
��N�
L�� � �!J�K�
L���
C�� � �!A�B�
C��r�/����<�=�
S�	�
�"�"�:�.�.�/�s��?X� V�6JX�V?�X�.W%�9HX�V<�8X�;V<�<X�?W"�X�!W"�"X�%X�X�X�X�2Y�?Yz-reached\s+max_children\s+setting|max_childrenz1\[(\d{2}-[A-Za-z]{3}-\d{4})\s+\d{2}:\d{2}:\d{2}\]z+\[(\d{4}-\d{2}-\d{2})\s+\d{2}:\d{2}:\d{2}\]z*^(\d{4}-\d{2}-\d{2})\s+\d{2}:\d{2}:\d{2}\b�two_digit_versionc�n�[U5n[R"SU5(a
USSUS3$U$)Nz\d{2}rrorI)rUr[�	fullmatch)rHs r �_php_short_to_semverrKsD���-�.��	�|�|�H�/�0�0�#�A�&�'�q�):�1�)=�(>�?�?��r)c� �SHwn[R"U5(dM [R"USS/SS[RS9R5n[R"SU5(aUs $My g![a M�f=f)	N�rez/usr/bin/phpz/usr/local/bin/phprvzecho PHP_VERSION;Tr�r��^\d+\.\d+\.\d+�	[Unknown])	rur*r�r�r�r�r[rur)�php_binary_path�system_version_outputs  r �_php_try_cli_versionrRs���H���|�|�O�,�,��
	�$.�$;�$;� �$�(;�<���!�(�(�	%�
�e�g�
"��x�x�)�+@�A�A�,�,�B�I����	��	�s�AA?�?
B
�B
�
probe_pathc���[USSS9nURS5 SSS5 g!,(df   g=f![a n[R	SX5 SnAgSnAff=f)Nrr-r.z<?php echo PHP_VERSION; ?>Tz$Failed writing PHP probe file %s: %sF)r1rrr6rI)rSrr@s   r �_php_write_probe_filerU0s_���
�*�c�G�
4�����:�;�5��5�
4��������2�J�	
���	�s)�9�(�9�
6�9�9�
A#�A�A#�path_to_removec���U(a<[RRU5(a[R"U5 ggg![a n[
R
SX5 SnAgSnAff=f)Nz&Failed to remove temporary file %s: %sr�)rVr@s  r �_php_remove_filerX<sU��
��b�g�g�n�n�^�<�<��I�I�n�%�=�>���
����4�n�	
�	
��
�s�AA�
A0�A+�+A0r�r&c�v�U(a+U(a$[RRU5(dgS[R"5S3n[RR	X5n[U5(dgSSSSSSS	US
3SUSU3/	SSSSSSS
SU3SU3/	SSSSSSSS	US3SUSU3/
/nUHan[R"US[RS9R5n[R"SU5(aUs [U5 $Mc [U5 g![Ra1n[RSSR	U5U5 SnAM�SnAf[ a1n[RSSR	U5U5 SnAM�SnAff=f![U5 f=f)N�.spar_phpdetect_�.phpr�r�rz-m�4z--failz	--resolvez
:80:127.0.0.1r�r�r zHost: zhttp://127.0.0.1/z-kz:443:127.0.0.1r�Tr!rNzHTTP probe failed: %s -> %srqzHTTP probe exception: %s -> %s)r3r�r+�getpidrprUr�r�r�r�r[rurXr�r6r:r)	r�r&�
temp_filename�
temp_filepath�http_probe_commands�
probe_command�probe_output�cper@s	         r �_php_cwp_http_proberdFs���
���w�w�}�}�]�+�+��&�r�y�y�{�m�4�8�M��G�G�L�L��>�M� ��/�/��:(��������!�"�-�0��.�)��=�/�:�

����������(�)�#�M�?�3�

���������!�"�.�1��>�*�!�M�?�;�
�/#
��J1�M�
�)�6�6�!��%�,�,� ��%�'�	�
�8�8�-�|�<�<�'�'�	��'�=�1�(	��'����0�0�
����1�3�8�8�M�3J�C�����
����4��H�H�]�+�����
��	��'�sO�>>F+�=AD*�F+�F+�*F(�>&E*�$F+�*
F(�7&F#�F+�#F(�(F+�+
F8c�6�[US/5=(d /nSU;dSU;ag[USS5=(d [U5nU(a$[RR	U5(dg[USSSS	9nUR
5nSSS5 [R"S
W[R5nU(dg[URS55$!,(df   NV=f![a n[RSU5 SnAgSnAff=f)
Nr�r�r�r�rgrr-r\rzRfastcgi_pass\s+unix:/opt/(?:alt/)?php-fpm(\d{2})/usr/var/sockets/[^\s;]+\.sock\s*;rIz.Failed parsing NGINX vhost for PHP version: %s)r+r�r3r�rlr1r�r[r�r#rKrvrr6rI�r�r�r�r�
vhost_textr�r@s       r �_php_cwp_nginx_vhost_proberh�s������R�0�6�B�I��i��8�y�#8�����r�2��6J��7�J��R�W�W�^�^�J�7�7���
���g�h�
�
�$�)�)�+�J�
��	�	�a���D�D�
�
�
��#�M�$7�$7��$:�;�;�
�
�������I�3�O����s6�0C.�<C�
5C.�C.�
C+�'C.�.
D�8D�Dc�&�[US/5=(d /nSU;ag[USS5=(d SnU(a$[RRU5(dg[	USSSS9nUR5nSSS5 [R"S	W[R5=(d� [R"S
U[R5=(dS [R"SU[R5=(d& [R"SU[R5nU(dg[URS
55$!,(df   N�=f![a n[RSU5 SnAgSnAff=f)Nr�r�r�rgrr-r\rzbSetHandler\s+"?proxy:unix:/opt/alt/php-fpm(\d{2})/usr/var/sockets/[^"|]+\.sock\|fcgi://localhost"?z1/opt/alt/php-fpm(\d{2})/usr/var/sockets/\S+\.sockz#/opt/alt/php(\d{2})/usr/bin/php-cgizapplication/x-httpd-php(\d{2})rIz/Failed parsing Apache vhost for PHP version: %s)r+r3r�rlr1r�r[r�r#rKrvrr6rIrfs       r �_php_cwp_apache_vhost_proberj�sB�����R�0�6�B�I��y� �����r�2�8�b�J��R�W�W�^�^�J�7�7���
���g�h�
�
�$�)�)�+�J�
�
�I�I�u�����
�

N�
�y�y�D������

N��y�y�6�
�B�D�D��

N��y�y�:�J����M�	� ��#�M�$7�$7��$:�;�;�/
�
��0�����J�C�P����s7�!E&�-E�>B<E&�;E&�
E#�E&�&
F�0F�Fc�0�[USS5=(d SnU(dg[[R"SUS355nU(dg[5n[USS5=(d [	U5nUU(aURSS5OS/nUH�nU(a$[RRU5(dM0[USSS	S
9nUR5nSSS5 [R"SW[R5H#n	URU	RS55 M% M� Sn
U(aBUH<n[R""S
U5n	U	(dM#U	RS5U;dM:Un
 O U
(dUSn
[R""S
U
5nU(dg[%URS55$!,(df   N�=f![ a N�f=f![ a n
[&R)SU
5 Sn
A
gSn
A
ff=f)Nr�rg�*/opt/alt/php-fpm*/usr/etc/php-fpm.d/users/r�r�z	.ssl.confrr-r\rz:/opt/(?:alt/)?php-fpm(\d{2})/usr/var/sockets/[^\s;]+\.sockrIz/opt/alt/php-fpm(\d{2})/rz)Error scanning CWP PHP-FPM pool files: %s)r+r�rkrr�rJr3r�rlr1r�r[�finditerr#r$rvrr�rKr6rI)r�r��pool_file_candidates�socket_versions�nginx_vhost_pathr�	path_itemrrgru�chosenr�pool_version_matchr@s              r �_php_cwp_pool_probert�s����6�>�2�6�<�"�L���6�%��I�I�<�\�N�%�P�
� 
��
$��$'�E��	�&���b� � .�%�f�-�
�!�(�%�,�,�W�k�B���O�-�	� ������y�(A�(A����s�W�X�� �!,�!1�!1�!3�J�� �[�[�Q���D�D��E�
$�'�'����A��7��-� ���"6���	�	�"=�~�N���5�U�[�[��^��>�+�F��	#7�
�)�!�,�F��Y�Y�'B�F�K��!��#�$6�$<�$<�Q�$?�@�@�5����	��	��"�����D�c�J����sm�*G+�
G+�A:G�G
�!AG�:*G+�(G+�?0G+�0G+�

G	�G�
G(�%G+�'G(�(G+�+
H�5H�Hc��[USS5=(d Sn[USS5=(d SnU(aU(dgSUSUS3n[RRU5(dg[	USSS	S
9n[
R"U5nSSS5 WRS5nU(dg[[U55$!,(df   N;=f![a n[RSX75 SnAgSnAff=f)
Nr�rgr��/home/�/.conf/webservers/r�rr-r\rzphp-fpm_verzFailed reading CWP JSON %s: %s)
r+r3r�rlr1r
rr�rKrUrr6rI)r�r�r��
cwp_json_pathr�cwp_json�json_version_valuer@s        r �_php_cwp_json_prober{s����6�>�2�6�<�"�L��V�%5�r�:�@�b�N��~�����0��0@��F���7�7�>�>�-�(�(���
��3���
�
��y�y��-�H�
�&�\�\�-�8��!��#�C�(:�$;�<�<�
�
�������9�=�N����s6�+C�7C� C�/C�
C�
C�
C>�C9�9C>�docroot_pathc��U(a$[RRU5(dgS[R"5S3n[RR	X5n[U5(dgSH�n[R"U5(dM [R"USU/SS[RS9R5n[R"SU5(aUs [U5 $M� [U5 g![Ra!n[ R#S	X55 SnAM�SnAf[$a!n[ R#S
X65 SnAM�SnAff=f![U5 f=f)NrZr[rMz-fTr�r�rNz
%s failed: %sz%s exception: %s)r3r�r+r]rprUrur*r�r�r�r�r[rurXr�r6r:r)r|r^r_rP�
cli_output�cli_cpe�
cli_exceptions       r �_php_cli_docroot_prober�0s3���r�w�w�}�}�\�:�:��&�r�y�y�{�m�4�8�M��G�G�L�L��=�M� ��/�/��(�L�O��<�<��0�0��
Q�'�4�4�$�d�M�:���%�,�,�	�
�%�'���8�8�-�z�:�:�%�%�	��'�;� M�"	��'����0�0�
H����_�o�G�G���
Q����/��P�P��
Q��	��'�sO�7"E,�AD�-E,�;E,�E)�D;�5E,�;
E)�E$�E,�$E)�)E,�,
E9c��[RSUR5 [5Ul[RSUR5 UR
S:XGaq[
USS5=(d SR5n[
USS5=(d Sn[X5nU(a(X0l	[RSU5 UR$[U5nU(a(X0l	[RSU5 UR$[U5nU(a(X0l	[RS	U5 UR$[U5nU(a(X0l	[RS
U5 UR$[U5nU(a(X0l	[RSU5 UR$[RS5 [
USS5=(d SnU(a$[R R#U5(dS
n[R%U5 XPl	U$['U5nU(a^X0l	URS:Xa&X0l[RSUR5 [RSU5 UR$SUl	[R)UR5 UR$)NzDetecting PHP version for: %szSystem PHP Version (CLI): %sr�r�rgr�z&Detected PHP version %s via HTTP probez-Detected PHP %s from NGINX vhost fastcgi_passz!Detected PHP %s from Apache vhostz"Detected PHP %s from CWP pool filez(Detected PHP %s from CWP JSON (advisory)z+CWP detection fell through; using CLI probez8[Error] Docroot is invalid or not set. Do this manually.rOz%Detected PHP version %s via CLI probez0[Error] CLI detection failed, try manual method.)r6r�r�rRr�r�r+r�rdr�rhrjrtr{r:r3r�r+r
r�r�)r�r�r&�detectedr|�
error_messages      r �get_php_versionr�Ps8��
�K�K�/��1F�1F�G� 4� 6�F��
�K�K�.��0I�0I�J�
���/�/�!�&�*:�B�?�E�2�L�L�N����	�2�6�<�"�
�&�~�E���!)���K�K�@�(�K��%�%�%�-�f�5���!)���K�K�?��
��%�%�%�.�v�6���!)���K�K�;�X�F��%�%�%�&�v�.���!)���K�K�<�h�G��%�%�%�&�v�.���!)���K�K�B�H�M��%�%�%����B�C��6�9�b�1�7�R�L��r�w�w�}�}�\�:�:�F�	�	���]�#�*����%�l�3�H��%���$�$��3�(0�%��K�K�.��0I�0I�
�	���;�X�F��!�!�!�K�F��
�N�N�6�%�%�&����r)c��[RSUR5 URS:XGaSURSURS3n[
RRU5(a0SUlSUl	[RSU5 UR$S	Ul	[RS
5 UR(d2SUl[RUR5 UR$SUR;a/SUlSUl	[RS
5 UR$SUR;Ga�UR(a.[
RRUR5(d9SUlS	Ul	[RUR5 UR$[URSSSS9nUR5nSSS5 SW;dSU;a/SUlS	Ul	[RS5 UR$SU;a5SU;a/SUlS	Ul	[RS5 UR$SU;a5SU;a/SUlS	Ul	[RS5 UR$SUlS	Ul	[RUR5 UR$S!UR$=(d S"R'5S#3UlS	Ul	[RUR5 UR$URS%:XGa�[R)S&5 UR*(d/S'UlSUl	[RS(5 UR$S)URS*URS+3n[
RRU5(a0SUl	SUl[RS,U5 UR$S	Ul	[RS-5 [,R."S.UR*5nU(a&S/UR1S05UR1S153nO/S2UlSUl	[RS35 UR$[R)S4U5 [2R4"/S5QS[2R6S6S79n[8R:"U5nUR=S805R=S9/5n	U	Hn
U
R=S:5U:XdMU
R=S;5nU(aMX�lUR'5S:HUl	[RS<UUR5 URs $ O S=U3UlSUl	[RUR5 UR$URS@:Xa/SUlSUl	[RSA5 UR$URSB:Xa/SCUlSUl	[RSD5 UR$[C[EUSES5[F5(aKURR'5S:Xa-UR(d[RSF5 SUl	SGUl[RSHUR5 UR$!,(df   GN=f![ a< S UlS	Ul	[R#UR5 URs$f=f![ a< S$UlS	Ul	[R#UR5 URs$f=f![2R>a< S>UlSUl	[R#UR5 URs$[8R@a< S?UlSUl	[R#UR5 URs$f=f)INzDetecting PHP handler for: %sr�rvrwr��php-fpmTz+Detected PHP-FPM in use via config file: %sFzMPHP-FPM config not found. Checking active web service to determine handler...z[Error] Web stack not detectedr�zBNGINX configuration on CWP. Only php-fpm can be used in this case.r�z#[Error] Apache vhost file not foundrr-rJrzmod_suphp.c�suPHP_UserGroup�suPHPz)Detected suPHP handler from Apache vhost.�
SetHandlerzapplication/x-httpd-php�dsoz'Detected DSO handler from Apache vhost.�
AddHandler�cgiz'Detected CGI handler from Apache vhost.z-[Unknown] Handler not matched in Apache vhostz#[Error] Failed to read Apache vhostz[Unknown] Web service 'rgz
' not handledz*[Error] Exception during handler detectionr�z(Retrieving PHP handler for cPanel systemzFPHP version not set before handler detection, find this info manually.z\PHP version not set before handler detection, unable to continue with PHP Handler detection.rr��
.php-fpm.yamlz1Detected PHP-FPM in use based on existence of: %szPHP-FPM not detected.z(\d+)\.(\d+)�ea-phprIrzMInvalid PHP version format detected. You must find this information manually.z$Invalid PHP version format detected.z,Converted PHP version string to EA format %s)r�php_get_handlersz
--output=jsonrr�r-�version_handlers�version�current_handlerzDetected PHP handler for %s: %sz+[Error] Handler not found for PHP version: z.[Error] Failed to run whmapi1 php_get_handlersz0[Error] Failed to parse JSON output from whmapi1r�z0Detected PHP handler for UltraStack ONE: php-fpmr�rOz8Panel type is Baremetal - PHP handler detection skipped.r�zMHandler is php-fpm but has_php_fpm=False; correcting boolean for consistency.zUnknown PHP HandlerzUnhandled panel type: %s)$r6r�r�r�r�r3r�rlr�r�r�r
r�r�r1r�rrIr�rqr:r�r[rurvr�r�r�r
rr�r��JSONDecodeErrorr�r+rU)r�rFrr�fpm_config_pathr��
ea_version�
whmapi_output�whmapi_datar��
handler_entryr�s            r �get_php_handlerr��sU��
�K�K�/��1F�1F�G�
���/�/��v�2�2�3�3E�f�F[�F[�E\�\a�b��
�7�7�>�>�+�&�&�!*�F��!%�F���K�K�=�{�
��%�%�%�"������[�	
�Q	&��#�#�%E��"����V�/�/�0��)�)�)��&�*�*�*�%.��"�%)��"����X���)�)�)��6�+�+�+��(�(�������%�%�1�1�*O�F�&�).�F�&��N�N�6�#5�#5�6�!�-�-�-�/.���)�)��!(�(�	�
$�(2���(9�
�
�&��6�,�
�=�-4��*�-2��*����$O�P�%�1�1�1�%�
�5�5��F�-2��*�-2��*����$M�N�%�1�1�1�%�
�5�5��F�-2��*�-2��*����$M�N�%�1�1�1�H��&�*/�F�&��N�N�6�#5�#5�6�!�-�-�-�$;�F�<R�<R�<X�VX�;_�;_�;a�:b�bo�!p�F��!&�F���N�N�6�-�-�.��%�%�%����H�$����?�@��!�!�!i�F��!%�F���L�L�n�
��%�%�%�L	&� 5�f�6I�6I�5J�!�F�La�La�Kb�bo�p�O��w�w�~�~�o�.�.�%)��"�%.��"����G�#���)�)�)�!&�F���K�K�/�0��H�H�_�f�6H�6H�I�M���]�0�0��3�4�]�5H�5H��5K�4L�M��&u��"�%)��"����C�D��)�)�)��L�L�>�
�
�'�3�3�@��!�(�(��	�M��*�*�]�3�K�*���v�r�:�>�>�"�B� ��"2�
� �$�$�Y�/�:�=�&3�&7�&7�8I�&J�O�&�-<�*�+�1�1�3�y�@��*����=�&�"�.�.��
 &�1�1�1��"2�">�j�\�J�
��"&�F���N�N�6�-�-�.��%�%�%�"���,�,�&���!������F�G��!�!�!�
���K�'�(���!������F�	
��!�!�!�	�7�6�=�$�7��=�=����$�$�&�)�3��"�"����[�	
�"���.�F��
�L�L�+�V�->�->�?�����]���T!�.�)N�F�&�).�F�&��$�$�V�%7�%7�8�!�-�-�-�	.���	&�!M�F��!&�F�����V�/�/�0��%�%�%�		&��`�,�,�	&�@�
��"&�F�����V�/�/�0��%�%�%��#�#�	&�B�
��"&�F�����V�/�/�0��%�%�%�
	&�s��A]!�>]!�B]!�\�"\�3A\�6:\�1:\�,8\�%A]!�*A0^*�B^*�4B
^*�A$^*�*?^*�
\�\�A]�]!�]�]!�!A^'�&^'�*A
a�9Aa�ac�:�U(a$[RRU5(d0$[USSSS9n[R
"U5=(d 0sSSS5 $!,(df   g=f![a [RSU5 0s$f=f)Nrr-r\rzFailed reading YAML: %s)	r3r�rlr1rr
rr6rI)�path_to_yamlrs  r �_phpfpm_read_yamlr�ps|��	��2�7�7�>�>�,�#?�#?��I�
��#���
�
��>�>�+�.�4�"�
�
�
�������2�L�A��	��s3�,A5�A5�A$�	A5�$
A2�.A5�2A5�5"B�Bc��U(a$[RRU5(dg[USSSS9nUR	5sSSS5 $!,(df   g=f![
a [RSU5 gf=f)Nrgrr-r\rzFailed reading file: %s)r3r�rlr1r�rr6rI)�path_to_filers  r �_phpfpm_read_textr�}ss��	��2�7�7�>�>�,�#?�#?��
��#���
�
��#�#�%�
�
�
�������2�L�A���s3�+A%�A%�A�
	A%�
A"�A%�"A%�% B�Bc�t�UH2n[U[5(dMX ;dM!URU5s $ gr�)r�r#r�)�mappingr|rHs   r �_phpfpm_get_anyr��s2�����g�t�$�$��)<��;�;�x�(�(��r)c��[R"X=(d S5nU(a[URS55$S$![a gf=f)NrgrI)r[r�rSrvr)r��
text_valuerus   r �_phpfpm_extract_intr��sF����	�	�'�#3��4��&+�s�5�;�;�q�>�"�5��5������s�?A�A�
A�Ac��SnSn[USS5(a[USS5(d[RS5 SUU4$[[US55nSUSURS3n[U5nU(d[RSU5 S	U3UU4$[
S
U5Ul[
SU5Ul[
SU5Ul	S
URSURSUR3n[US/5=(d /nU(d[RS5 XaU4$SnSn	UH^n
SU
S3n[R"U5H;n[U5n
U
(dM[
S
U
5nUcM(U[U5-
nU	S-
n	M= M` U	S:�aUnU	n[RSU	U5 O[RS5 XaU4$)Nr�r�zGPHP version or domain owner not set - cannot locate CWP PHP-FPM config.z+PHP version or domain's user owner not set.z/opt/alt/php-fpmz/usr/etc/php-fpm.d/users/r�z.CWP PHP-FPM config not found or unreadable: %s�!PHP-FPM config file not found at �pm\.max_children\s*=\s*(\d+)�pm\.max_requests\s*=\s*(\d+)�$pm\.process_idle_timeout\s*=\s*(\d+)�Max Children: �
Max Requests: �
Process Idle Timeout: r�zCCWP user_list is empty on report; PHP-FPM totals may be incomplete.rrlrIz6CWP PHP-FPM totals: pools=%d, total pm.max_children=%dz5No CWP PHP-FPM pools detected while computing totals.)r+r6r
r|r�r�r�r�r�r�r�rkrSr�)r�r�r��	short_verrprRr�r��total_children�
pool_countr~r��	pool_path�	pool_text�max_children_values               r �_phpfpm_cwp_effectiver��s(�����O��6�=�$�/�/�w����8�8�	���U�	
�
:���
�	
�#�7�6�=�#A�B�I�"�9�+�-F�v�GZ�GZ�F[�[`�a�I��	�*�G�����<�i�	
�0�	�{�;���
�	
�#6�'��#�F��#6�'��#�F��':�/��'�F�#�
��4�4�5�6��4�4�5�6!�!'�!@�!@� A�	C�����R�0�6�B�I�����Q�	
��O�;�;��N��J���>�x�j��N�����7�+�I�)�)�4�I���!4�/��"��"�)���c�"4�5�5�N��!�O�J�,���A�~�+��$�����D���	
�	���N�O���7�7r)c�Z^^^�SUUU4SjjnU"SS5nU"SS5nU"SS5nXEU4$)	Nc�v>�U(dU4OX4n[T/UQ76nUc[T/UQ76nUc[T/UQ76nU$r�)r�)�key_underscore�
key_dottedr|re�domain_mapping�global_yaml�	pool_yamls    ���r r?�(_phpfpm_cpanel_resolve.<locals>.fallback�sY������ �-�	
�
 ��6��6���=�#�I�5��5�E��=�#�K�7�$�7�E��r)�pm_max_childrenzpm.max_children�pm_max_requestszpm.max_requests�pm_process_idle_timeoutzpm.process_idle_timeoutr�r")r�r�r�r?�mc_val�mr_val�it_vals```    r �_phpfpm_cpanel_resolver��sD������'�):�
;�F�
�'�):�
;�F�
�/�1J�
K�F��6�!�!r)c��[USS5n[USS5nU(aU(dS[USS5[USS54$SUSUS3Ul[UR5Ul[S	5Ul[S
5UlUR(d_UR(dNUR
(d=[RS5 SUR3[USS5[USS54$[UR=(d 0URUR
5uUl	Ul
UlS
UlS
Ul
[R"S5H�n[U5Ul[UR=(d 0URUR
5uUl nUR cM_U=R[#UR 5-
slU=RS-
sl
M� URS
:�aNURUlURUl[R+SURUR5 O[R-S5 SURSURSUR3nXPR&UR(4$![$a GMcf=f)Nr�r�zDDomain owner or domain not set; cannot locate cPanel PHP-FPM config.r�r�rr�r�z2/var/cpanel/ApachePHPFPM/system_pool_defaults.yamlz$/var/cpanel/ApachePHPFPM/system.yamlzANo PHP-FPM YAML sources found (domain, pool defaults, or system).r�rz%/var/cpanel/userdata/*/*.php-fpm.yamlrIz9cPanel PHP-FPM totals: pools=%d, total pm.max_children=%dz8No cPanel PHP-FPM pools detected while computing totals.r�r�r�)r+�phpfpm_domain_yaml_pathr��phpfpm_domain_yaml�phpfpm_pool_defaults_yaml�phpfpm_globals_yamlr6r
r�r�r�r��phpfpm_total_children_sum�phpfpm_pool_countrk�phpfpm_pool_domain_yaml�phpfpm_pool_max_childrenrSrr�r�r�r�)r�r�r�r�r�r�s      r �_phpfpm_cpanel_effectiver��s����6�>�4�8�L��V�%5�t�<�N��~�R��F�0�$�7��F�-�t�4�
�	
� ��~�Q�~�.>�m�L��"�!2��&�&�!�F��(9�<�(�F�$�"3�.�"�F��

�%�%��0�0��*�*����O�	
�0��0N�0N�/O�P��F�0�$�7��F�-�t�4�
�	
�	��!�!�'�R��(�(��"�"�	�	��#��#��'�()�F�$� �F���Y�Y�F�G�	�):�9�)E��&�0F��*�*�0�b��,�,��&�&�1
�-��'��A�
�*�*�2��	��,�,���/�/�1�
�,�
�$�$��)�$�H�"���!�#�$*�$D�$D��!�!'�!9�!9������G��$�$��,�,�	
�	���F�	
�
��4�4�5�6��4�4�5�6!�!'�!@�!@� A�	C���-�-�v�/E�/E�E�E��-�	��	�s�=J<�<
K�
Kc��SnSnSURS3n[U5nU(d[RSU5 SU3UU4$[	SU5Ul[	SU5Ul[	SU5UlSUR
S	URS
UR3nUR
b[UR
5nSnXQU4$)Nz/etc/php-fpm.d/r�z'UltraStack PHP-FPM config not found: %sz)[Error] PHP-FPM config file not found at r�r�r�r�r�r�rI)	r�r�r6r
r�r�r�r�rS)r�r�r�rprRr�s      r �_phpfpm_ultrastack_effectiver�Ys�����O�!�&�"7�"7�!8��>�I��	�*�G�����>�	�J�7�	�{�C���
�	
�#6�'��#�F��#6�'��#�F��':�/��'�F�#�
��4�4�5�6��4�4�5�6!�!'�!@�!@� A�	C���"�"�.� ��!<�!<�=������7�7r)c�2�[RSURUR5 [	[USS5[5(aLURR5S:Xa.[USS5(d[RS5 SUl
[USS5(d[RS5 g	SnSn[US
S5=(d SnUS:Xa[U5upAnOdUS
:Xa[U5upAnOOUS:Xa[U5upAnO:US:Xa[RS5 SnO[RSU5 SU3nUbXlUbX lU$![a$n[R!S5 SU3nSnAN=SnAff=f)Nz.Gathering PHP-FPM configuration for %s on [%s]r�r�r�FzKphp-fpm handler detected but has_php_fpm is False/None; correcting to True.Tz@PHP-FPM is not in use for this site - skipping config retrieval.z/[Notice] PHP-FPM not detected for this account.r�rgr�r�r�r�zBPanel type is Baremetal - PHP-FPM configuration detection skipped.z<[Notice] Baremetal PHP-FPM config detection not implemented.zUnknown panel type: %sz [Error] Unsupported panel type: z)Failed to retrieve PHP-FPM configuration.z3[Error] Exception while retrieving PHP-FPM config: )r6r�r�r�r�r+rUr�rqr�r�r�r�r�r
rrIr�r�)r�r�r�r�r�r@s      r �get_php_fpm_configr�~s���
�K�K�8��������	�7�6�=�$�7��=�=����$�$�&�)�3���
�u�5�5����Y�	
�"����6�=�%�0�0����N�	
�A����O�N��V�\�2�6�<�"�
��,�,�%�f�-�
9�G���8�
#�(��0�
9�G���+�
+�,�V�4�
9�G���;�
&��N�N�T�
�O�
�
�L�L�1�:�>�8���E�G��%�$6�!��"�!0���N���N����D�E�G��u�M���N�s0�*E(�0E(�E(�E(�8E(�(
F�2F�F�log_linec��[[[4H7nURU=(d S5nU(dM&UR	S5s $ g)NrgrIzunknown-date)�_PHPFPM_TIMESTAMP_BRACKETED�_PHPFPM_TIMESTAMP_ISO_BRACKETED�_PHPFPM_TIMESTAMP_ISOr�rv)r�r��	match_objs   r �"_phpfpm_extract_date_from_log_liner��sD��#�'����
�N�N�8�>�r�2�	��9��?�?�1�%�%��r)rwc�`�U=(d SR5nU(dgURS5(aU$[R"SU5nU(a%SUR	S5UR	S53$[R"SU5nU(aSUR	S53$g)Nrgr�z
(\d)\.(\d)rIrz	^(\d{2})$)r�r�r[rurv)rw�match_mm�match_dds   r �#_phpfpm_cpanel_package_from_versionr��s���$�*��1�1�3�N���� � ��*�*����x�x�
�~�6�H������q�)�*�8�>�>�!�+<�*=�>�>��x�x��n�5�H������q�)�*�+�+�r)c
��[U=(d /VVs1sHan[R"U5HCn[RR	U5(dM)URS5(aMAUiME Mc snn5$s snnf)Nr&)r�rkr3r�rlrs)�
glob_patternsr�r�s   r �_phpfpm_list_log_filesr��sr���*�/�R�/�	
�/���	�	�'�*���w�w�~�~�d�#�
�-1�M�M�%�,@�
�*�
�/�	
����	
s�AB
�B
�2
B
c��SnU=(d /H�n[RSU5 [USSSS9nUH|n[R	U5(dMU(aUR	U5(dUR	U5(dMU[U5nUR
US5S-X8'US-
nM~ SSS5 M� U$!,(df   M�=f![a [RSU5 M�f=f)	NrzScanning file: %srr-r\rrIzFailed reading %s)	r6r�r1�_PHPFPM_MAX_CHILDREN_REGEXr�r�r�rrI)	�log_file_paths�
pool_regex�domain_regex�date_to_hit_count�total_event_count�
log_file_pathrr�r�s	         r �_phpfpm_scan_error_logsr��s����'�-�2�-�
�	A��K�K�+�]�;���s�W�X���'�D�5�<�<�T�B�B� �$��):�):�4�)@�)@�U�'�.�.�t�4�4� �A�$�G�H�)�-�-�h��:�Q�>�&�/�&��*�%�(���.�.��)���"�	A����0�-�@�	A�s/�"C�BC�7C�
C	�C�C� C;�:C;c	���[USS5(dg[USS5=(d SR5nU(dg[USS5=(d SR5n[USS5=(d Sn[USS5=(d SR5nURS	S
5nXESU34Vs1sHnU(dMUiM nnU(aO[R"SS
R[
[RU55-[R5OSn[R"[R"U5[R5n	0n
/nUS:Xa~[U5Ul
UR(d[RS5 SUS	3$SURS3SURS3/n[RSURU5 O\US:XaSS/n[RSU5 O;US:XaSS/n[RSU5 O/SQn[RSU5 [U5Ul[RS[!UR5U5 UR(dSUS	3$[#URUU	U
5Ul[RS UUR$5 UR$S!:XaS"US#3$['U
R)5S$S%9UlS&S'UR$3S(/nUR-S)UR*55 S*RU5$s snf![.a [R1S+5 g,f=f)-Nr�Fr�rgz[Error] managed_domain not set.r�r�r�ror��www_z\[pool\s+(?:%s)\]r�r�zLPHP version not available; cannot resolve cPanel PHP-FPM log path precisely.z No PHP-FPM error logs found for z/opt/cpanel/z#/root/usr/var/log/php-fpm/error.logz$/root/usr/var/log/php-fpm/error.log*z+PHP-FPM error log patterns (cPanel, %s): %sr��)/opt/alt/php-fpm*/usr/var/log/php-fpm.log�*/opt/alt/php-fpm*/usr/var/log/php-fpm.log*z2PHP-FPM error log patterns (Control Web Panel): %sr��/var/log/php-fpm/error.log�/var/log/php-fpm/error.log*z/PHP-FPM error log patterns (UltraStack ONE): %s)z6/opt/cpanel/ea-php*/root/usr/var/log/php-fpm/error.logz7/opt/cpanel/ea-php*/root/usr/var/log/php-fpm/error.log*r�r�r�r�z)PHP-FPM error log patterns (fallback): %sz,Scanning %d PHP-FPM error log file(s) for %sz/Total PHP-FPM pm.max_children events for %s: %drz#No PHP-FPM Max Children events for z in current or rotated logs.c��US*US4$)NrIrr")�kvs r r�$get_php_fpm_errors.<locals>.<lambda>vs���1��v�r�!�u�or)r�### PHP-FPM Max Children EventszTotal hits: zBy date:c3�6# �UHupSUSU3v� M g7f)r!r0Nr")r��date_string�count_values   r r��%get_php_fpm_errors.<locals>.<genexpr>~s'���
�,L�(����
�R��}�-�,L�s�rz+Unhandled exception in get_php_fpm_errors()zJUnable to evaluate PHP-FPM errors from error logs; please review manually.)r+r�rJr[r\rp�mapr�r#r��phpfpm_package_stemr6r�r�r��phpfpm_error_log_filesrhr�� phpfpm_total_max_children_eventsr�r��phpfpm_sorted_date_countsr�rrI)
r�r�r�r<r�underscoredr-�pool_candidatesr�r�r��log_patternsr5s
             r �get_php_fpm_errorsr	s��@\��v�}�e�4�4��!�&�*:�B�?�E�2�L�L�N���4��v�}�b�9�?�R�F�F�H�����b�1�7�R������4�:��A�A�C��$�,�,�S�#�6��$�D��
�2F�G�
�G�	��
�G�	�
��
�J�J�$��(�(�3�r�y�y�/�:�;�<����
��	��z�z�"�)�)�N�";�R�T�T�B�������H��)L��*�F�&��-�-����b��:�.�9I��K�K��v�9�9�:�:]�^��v�9�9�:�:^�_��L�
�K�K�=��*�*��
��)�
)�;�<��L�
�K�K�D��
�
�&�
&�,�-��L�
�K�K�A�<�
�
�L�
�K�K�;�\�
�)?�|�(L��%����:���-�-�.��	
��,�,�5�n�5E�Q�G�G�2I��)�)����	3
��/�	���=���3�3�	
��2�2�a�7�8��8H�Hd�e�e�+1��#�#�%�+E�,
��(�

.��6�B�B�C�D��
��
	���
�,2�,L�,L�
�	
��y�y��&�&��_
��b�\����F�G�[�\�sK�M�+M�A9M�:M�	M�CM�(C.M�AM�+A"M�M�M5�4M5c�t�[RS5 Sn[USS5(a[UR5S-nUcXSn[USS9n[
SU55nSSS5 WRSS	5R5S
n[U5S-nUS-n/SQn/nS
SSSSSRU5/n	[R"U	S[RSS9n
U
R5H4nUR5(dMUR[U55 M6 U(a[)U5[+U5-S-nOSnUS
:�a[Xl-5UlOSUlUR,b[/UR,5OSn
SUSS3SUSS3SUSS3SU
3/nSRU5$!,(df   GNa=f![R ["[R$4a [R'S5 N�f=f![0a [R3S 5 g!f=f)"Nz9Estimating safe PHP-FPM pm.max_children from memory usager�r�rBr-r.c3�r# �UH-nSU;dMUR5RSS5v� M/ g7frDr�r�s  r r��"get_php_fpm_max.<locals>.<genexpr>�s6���� ,���d�{�/�D�J�J�L�&�&�s�A�.�.� ,�r�rLrGrg333333�?)r�z	php-fpm80z	php-fpm81z	php-fpm82z	php-fpm83z	php-fpm84�psz--no-headersr��rssz-C�,Tr)r�zPps command failed or no PHP-FPM processes found while estimating pm.max_childrenr�r�zTotal RAM: r�� MBz!Budget for PHP-FPM (60 percent): z Average PHP-FPM process memory: z0Recommended pm.max_children (single busy site): rz(Failed to calculate PHP-FPM max childrenz8[Error] Exception while estimating safe pm.max_children.)r6r�r+r�r�r1r#r�r�rSrpr�r�r��isdigitr�r�r�r`r:rrhr�rUrrI)r��total_memory_mb�meminfo_pathrUrI�mem_total_kb_str�sixty_percent_memory_mb�php_fpm_process_names�
rss_kb_values�
ps_command�	ps_outputre�avg_process_memory_mb�recommended_strr�s               r �get_php_fpm_maxr	�si��
�K�K�K�L�XJ����6�>�4�0�0�#�F�$7�$7�8�6�A�O��"�*�L��l�W�5���� ,����6� '�{�{�:�v�>�D�D�F�q�I��!�"2�3�f�<�O�"1�D�"8��!
���
�������H�H�*�+�

�
�	�"�/�/���!�(�(��	�I�#���*���=�=�?�?�!�(�(��U��4�+���M�"�S��%7�7�&�@�
"�%(�!� �1�$�&)�'�?�'�F�#�'+�F�#��&�&�2�
��'�'�(��	��/�#�.�c�2�/�0G��/L�C�P�.�/D�S�.I��M�>��>O�P�	
�
��y�y��'�'�Y6�5��R
�)�)���%�%�
�	�

�L�L�-�
�	��L�J����C�D�I�J�sV�;H�F?�%AH�AG�G�.BH�?
G�	H�>H�H�H�H�H7�6H7�command_namec�2�[R"U5SL$r�)rur*)r	s r �_phpini_command_existsr	�s���<�<��%�T�1�1r)�command_textr�c	�4�[R"USSSUSS9$)NTF)�shellr'�capture_outputr�r1)r�rC)r	r�s  r �_phpini_run_shellr	�s'���>�>���
����
�r)c���[USS5nU(aU$[SSS9RR5nU=(d S$![a [
R
SSS9 gf=f)N�	server_ipzGip route get 1.1.1.1 | awk -F'src ' 'NR==1{split($2,a," ");print a[1]}'r�r�z)get_php_ini(): failed to detect server IPTr�)r+r	rXr�rr6r:)r��server_ip_valuer�s   r �_phpini_detect_server_ipr	�sn���f�k�4�8�O�����'�W��
��&����	��"�d�"�������@�4��P���s�,A�A&�%A&�tsv_contentr�c��00p2U=(d SR5H6nSU;aMURSS5upVUS;aXcU'M+XQ;dM2XbU'M8 X#4$)Nrgr3rI)�php_ini_loaded_file�user_ini.filename�sapi)rr�)r 	r�r��metar�r�res       r �_phpini_parse_tsvr&	sg����d�!�'�R�3�3�5�	��y� ���_�_�T�1�-�
���F�F���I�
�
�$)�S�!�6��!�!r)�	start_dirc� �[RRU5n[RRUS5n[RR	U5(aU$[RRU5nX1:XagUnMo)Nz	.user.ini)r3r��abspathrprl�dirname)r'	�current_dirr�
parent_dirs    r �_phpini_nearest_user_inir-	si���'�'�/�/�)�,�K�
������k�;�?��
�7�7�>�>�.�)�)�!�!��W�W�_�_�[�1�
��$�� ��r)�
htaccess_pathc�D�[RRU5(dg[USSSS9nUH)n[R
"SU5(dM! SSS5 g SSS5 g!,(df   g=f![a [RSUSS	9 gf=f)
NFrr-r\rz^\s*php_(?:value|flag)\s+\S+Tz-get_php_ini(): failed reading .htaccess at %sr�)	r3r�rlr1r[r�rr6r:)r.	�
htaccess_filer�s   r � _phpini_htaccess_sets_php_valuesr1	 s���
�7�7�>�>�-�(�(��
�
��3���
�
�*�	��9�9�<�i�H�H��
�
�+�
��
�
���
�
����;���	�	
�
�

�s@�A=� A,�A,�A=�!A,�#A=�,
A:�6A=�:A=�=B�Bc�f�SRSU55n[R"SUS35$)Nrgc3�.# �UHnSUS3v� M
 g7f)r�Nr"r�s  r r��+_phpini_build_probe_body.<locals>.<genexpr>4s���F�:�i�1�Y�K�q�)�:�s�a�        <?php
        @header('Content-Type: text/plain');
        function norm($k, $v) {
            if ($v === false || $v === '') return 'Off';
            $lv = strtolower(trim((string)$v));
            if ($lv === '1' || $lv === 'on' || $lv === 'true' || $lv === 'yes') return 'On';
            if ($lv === '0' || $lv === 'off' || $lv === 'false' || $lv === 'no') return 'Off';
            return (string)$v;
        }
        $keys = array(a�);
        foreach ($keys as $k) {
            $raw = ini_get($k);
            echo $k, "\t", norm($k, $raw), "\n";
        }
        echo "php_ini_loaded_file\t", (function_exists('php_ini_loaded_file') ? (php_ini_loaded_file() ?: "N/A") : "N/A"), "\n";
        echo "user_ini.filename\t", (ini_get('user_ini.filename') !== false && ini_get('user_ini.filename') !== '' ? ini_get('user_ini.filename') : "N/A"), "\n";
        echo "sapi\t", PHP_SAPI, "\n";
        )rp�textwrap�dedent)r��keys_phps  r �_phpini_build_probe_bodyr8	3s=���y�y�F�:�F�F�H��?�?�
 � �j�!	��
�
r)�
probe_bodyc���[USSS9nURU5 SSS5 [R"US5 g!,(df   N&=f![an[U5sSnA$SnAff=f)Nrr-r.i�)r1rr3�chmodrrU)rSr9	�
probe_filer@s    r �_phpini_write_prober=	Js\���
�*�c�G�
4�
����Z�(�5�
����U�#��5�
4�����3�x����s1�A�?�A�
A
�	A�
A/�
A*�$A/�*A/r��
probe_name�
user_agentr	c���SnSnU(a[S5(dXE4$SGHnSnU(aSUSUSUSU3nSUS	US
USUSUS
US
US3n[USS9n	U	R=(d Sn
SU
;a%U
RSS5up�UR	5nOU
nUR	5(a4Un[
R
SUR5U=(d S5  XE4$[
R
SUR5UU	RU	R=(d SSS5 GM XE4$![a( [
R
SUR5SS9 GMIf=f)Nrgr�)�https�httpz
--resolve z:443:z --resolve z:80:zcurl -fsS -A "z1" -H "Accept: text/plain,*/*;q=0.1" -H "Referer: r�zA/" -w "\n__CODE__=%{http_code}" --connect-timeout 3 --max-time 6 z "r�r�r�r�z

__CODE__=rIzget_php_ini(): HTTP %s code=%sr�z9get_php_ini(): HTTP %s failed (code=%s, rc=%s, stderr=%r)r�z"get_php_ini(): HTTP %s probe threwTr�)r	r	rX�rsplitr�r6r:r$r&r�r)
r�r>	r?	r	�runtime_rawr��scheme�resolve_flagr	�curl_resultr�rM�	code_lines
             r �_phpini_fetch_over_httprI	Ts����K��I��/��7�7��%�%�#��*	��L��!+�F�8�5���;�v�h�VZ�[d�Ze�f��!���- � &�x�s�6�(�3T�T`�Sa�b��8�3�v�h�a�
�|�1�	6�
�,�L�!�D�K�%�,�,�2��K���+�"-�"4�"4�]�A�"F���%�O�O�-�	�"���z�z�|�|�"�����4��L�L�N��&���
� �!�!�
�L�L�K�������&�&��#�#�)�r�4�C�0�
�?$�Z�!�!���	��L�L�4������
�
�	�s�CD9�*AD9�9-E+�*E+c��[USS5nU(aU$[R"SU5nU(aURS5OSn/nU[R"S5-
nU[R"S5-
nU(aU[R"SUS35-
nU[R"S5-
nU[R"S	5-
nU(aUS
$S$)N�
fpm_socketz^/home/([^/]+)/rIz3/opt/cpanel/ea-php*/root/usr/var/run/php-fpm/*.sockz//opt/cpanel/ea-php*/root/var/run/php-fpm/*.sockz"/opt/alt/php-fpm*/usr/var/sockets/z.sockz/run/php-fpm/*.sockz/var/run/php-fpm/*.sockr)r+r[rurvrk)r�r|�fpm_socket_path�
docroot_match�	user_name�socket_candidatess      r �_phpini_guess_fpm_socketrP	�s����f�l�D�9�O�����H�H�/��>�M�*7�
�#�#�A�&�T�I�������=��������9������T�Y�Y�0���5�A�
�	
������#8�9�9������#<�=�=��#4��Q��>�$�>r)rL	c	���U(a[S5(dg[RR5nUR	SUSU-S.5 [
R"SSSU/SSS	US
S9nUR=(d SnSU;aURSS
5S
nOSU;aURSS
5S
nUR5$![a [RSSS9 gf=f)Nzcgi-fcgirg�GETr�)�REQUEST_METHOD�SCRIPT_FILENAME�SCRIPT_NAMEz-bindz-connectTr�F)r'r	r��envr1z

rIr8z"get_php_ini(): FastCGI probe threwr�)
r	r3r��copyr�r�rCrXr�r�rr6r:)rSr>	rL	rV	�fcgi_resultrMs      r �_phpini_fetch_over_fcgirY	�s����"8��"D�"D����j�j�o�o����
�
�"'�#-�"�Z�/�
�	
�!�n�n�
��*�o�>������

���!�!�'�R������:�:�j�!�,�Q�/�D�
�t�^��:�:�f�a�(��+�D��z�z�|��������9�D��I���s�B.C	�	C*�)C*c��[R"U5 [RSU5 g![a [RSUSS9 gf=f)Nz$get_php_ini(): removed probe file %sz-get_php_ini(): failed to remove probe file %sTr�)r3r�r6r:r)rSs r �_phpini_cleanup_prober[	�sK��
�
�	�	�*�����;�Z�H���
����;���	�	
�
�r�r%	c�l�URS5=(d SR5R5nURSS5nURS5S;nU(a[U5OSn[R
R
US5nUS:Xa[U5(aU$U$U=(d U$)	Nr$	rgr"	r�r#	)Nrgr�r�z	.htaccess�apache2handler)r�r�rqr-	r3r�rpr1	)r|r%	r$	�
master_ini�user_ini_enabled�
user_ini_pathr.	s       r �_phpini_determine_active_pathra	�s����H�H�V��"��)�)�+�1�1�3�D����/��7�J��x�x� 3�4�=���3C� ��.����G�G�L�L��{�;�M����0�
�>�>�
�	
��	
��&�J�&r)c	��[USS5nU(a$[RRU5(d[RSU5 g[USS5=(d
 [USS5n[R
SUU5 /SQnS[R"5S	3n[RRX5n[U[U55nU(a[RS
5 SU3$[R
SU5 S
nSn[UU[USS5[U55upxU(d|[X5n	U	(aU[R
SU	5 [XTU	5nU(a[R
S5 O+[R
S5 O[R
S5 [!U5 U(d[R#SUU5 g[%Xs5up�[R'S[)U
5UR+SS5UR+SS55 [-X5n[R
SUR+S5=(d S
R/5R15=(d SU=(d S5 [R
S5 UR3X:U5$![!U5 f=f)Nr�z(get_php_ini(): invalid report.docroot=%rz-[Error] get_php_ini(): invalid report.docrootr�r�z,get_php_ini(): start (docroot=%s, domain=%s))	�memory_limit�
post_max_size�upload_max_filesize�max_execution_time�max_input_time�max_input_vars�display_errorszzlib.output_compression�allow_url_fopen�spar_iniget_r[z!get_php_ini(): cannot write probez+[Error] get_php_ini(): cannot write probe: z"get_php_ini(): wrote probe file %srg�http_user_agentzoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36z/get_php_ini(): trying FastCGI probe (socket=%s)z&get_php_ini(): FastCGI probe succeededz"get_php_ini(): FastCGI probe emptyz+get_php_ini(): skipping FastCGI (no socket)z3get_php_ini(): probe failed. http_code=%s domain=%sz0[Error] Unable to fetch effective php.ini valuesz9get_php_ini(): got %d directives (sapi=%s, master_ini=%s)r$	r�r"	z!get_php_ini(): SAPI=%s; active=%srzget_php_ini(): summary built)r+r3r�r+r6r
r:r]rpr=	r8	rIrI	r	rP	rY	r[	r�r&	r�rhr�ra	r�rqr�)
r�r|r�r�r>	rS�write_errorrD	r�rL	r�r%	r�s
             r �get_php_inirn	�sk���6�9�d�3�L��r�w�w�}�}�\�:�:����?��N�>��&�"2�D�9��W���$�>�K��L�L�6����
�J� ��	�	��}�D�1�J������l�7�J�%��,�Z�8��K�����<�=�<�[�M�J�J�
�L�L�5�z�B��K��I�*�!8�����!�1�
�
%�V�,�"
����6�v�L�O�����E�#��6��O�����L�L�!I�J��L�L�!E�F����J�K��j�)�����A���	
�
B�.�{�G���
�K�K�C�������������&��.�	�0��C�K�
�L�L�+�
�(�(�6�
�
 �b�	'�	'�	)�	/�	/�	1�	>�Y���u���L�L�/�0��'�'��k����9	�j�)�s
�B'K�
Kc�
^^^^�[RS5 [TRTRTR
4[
TSS5(aSOSTR5nS[S[4U4SjjmS	[S[4U4S
jjmS?S[S	[S[4UUU4S
jjjmS?S[S	[S[4U4Sjjjn[
TSS5(a.[RR[
TS55(d\[RS5 [
TSS5S:Xa[
TSS5(d[T5 [!T5 [#T5 UR%S5 ['T5TlUR%S5 [+T5TlUR%S5 [/T5TlSS0n[
TSS5(Ga0UR%S5 [3T5TlUR%S5 [7T5TlSR;S [
TS!S5bS"[
TS!S53OS[
TS#S5bS$[
TS#S53OS[
TS%S5bS&[
TS%S53OS455R=5Tl[AT5=(d STl!TRB=(d SRE5RGS'5(a?SR;TRBRI5S(S5RE5Tl!S)TRKS*5-S-U"[
TS+S5SS,9-S)-TRKS-5-S-U"[
TS.S5SS,9-[
TS/S5(a*S)TRKS05-S-U"[
TS/S5S1S,9-OS-[
TS2S5(a*S)TRKS'5-S-U"[
TS2S5S1S,9-OS-US'SR;TRMS35TROS4[
TS5[
TS6S7555TROS8[
TS6S755TROS9[
TS:S755STRKS;5U"[
TS<S5SS,9/5US-$![a [RS5 GN�f=f![a [RS5 GN�f=f![a [RS5 GN�f=f![a) [RS=5 TRQS>5s$f=f)@NzBuilding 'PHP' sectionr�Fr)r�r>r*c�>�[U5RS5S3nTRSTRSU55$r`r<)r>r�r�s  �r r5�-php_build_section.<locals>._format_label_onlycs?����z�?�)�)�#�.�/�q�1���!�!�'�6�+=�+=�f�e�+L�M�Mr)rZc�X>�UcSO
[U5nU(dSnTRX5$rd)rUr-)rerZr[r�s   �r �
_format_value�(php_build_section.<locals>._format_valuegs+��� �=�R�c�%�j�
��"�J��!�!�+�:�:r)r;r�c	�>�Ucg[U5RS5nUR5(dU$[R"SU5nU(aURS5OSnU[
U5SnSU;aQURSS5upgUR5(a(T"U5nT"UR5U5n	UUSU	3$[R"SU5n
U
(a`T
RST
RS	U
RS555nT"U
RS
5R5U5n	UUSU	3$T
RX5$)Nrgrz^(\s*(?:[-*]\s+)?)rIr9rqz^(\S+)\s{2,}(.+)$r;r0rr�)	rUr=r�r[rurvrhr�r-)r�rZ�original�prefix_matchrK�	remainder�left�rightrBr@�spaced_matchr5rs	r�s           ���r �_format_kv_line�*php_build_section.<locals>._format_kv_linemsK�������y�>�(�(��.���~�~����O��x�x� 5�x�@��*6��#�#�A�&�B���S��[�]�+�	��)��#�/�/�#�q�1�K�D��{�{�}�}� 2�4� 8�
� -�e�k�k�m�[� I�
� ��-���-��A�A��x�x� 4�i�@���"�.�.���+�+�F�L�4F�4F�q�4I�J��M�*��"�"�1�%�+�+�-�{��M��X�m�_�B�}�o�>�>��!�!�+�8�8r)rEc�z>^�UcSO
[U5nSRUU4SjUR555$)Nrgrc3�2># �UHnT"UTS9v� M g7f)r�Nr")r�r�r|	rZs  ��r r��>php_build_section.<locals>._format_kv_block.<locals>.<genexpr>�s����
�)��
�D�k�:�)�s�)rUrpr)rErZr'r|	s ` �r �_format_kv_block�+php_build_section.<locals>._format_kv_block�s8����'�r�S��_���y�y�
����)�
�
�	
r)r�zCphp_build_section: docroot not set or invalid, attempting discoveryr�rgr�r�zGphp_build_section: failed to gather user stats before docroot detectionz<php_build_section: get_web_stack() failed during PHP sectionz:php_build_section: get_docroot() failed during PHP sectionzDetecting PHP versionzDetecting PHP handlerz!Fetching effective php.ini values�
php_fpm_blockzFetching PHP-FPM configzEstimating safe pm.max_childrenrc3�8# �UHnU(dMUv� M g7fr�r"r�s  r r��$php_build_section.<locals>.<genexpr>�s"���;��D�$�'���s��	r�zTotal PHP-FPM pools on server: r�zTotal Max Children: r�zTotal system users: r�rIr8z### PHP-FPM Configuration�php_fpm_configr�z"### PHP-FPM Estimated Max Children�php_fpm_max_summary�php_fpm_server_summary_textz### PHP-FPM Server-wide SummaryrL�php_fpm_errorsz## PHP SummaryzSystem PHP Versionr��site_php_versionr:zSite PHP VersionzPHP Handlerr�z### PHP INI Values�php_ini_summaryzFailed to build PHP sectionz�[Error] Failed to build PHP section. Please review PHP version, handler, PHP-FPM configuration, and php.ini values manually. Please report this as a bug.ro))r6r:r�r�r�r�r+r�rUr3r�r+r�r�rrIrr!r�r�r�	r�r�rn	r�	r�r�	r	r�	rpr�r�	r	r�	r�r�rr6r�rCrU)r�r�r�	r�r|	r5rs	s`   @@@r �php_build_sectionr�	Ys����
�L�L�)�*�&����	�	�	�v�4�4�5�
�V�]�E�
2�
2������	��N�s�N�s�N�;�#�;�#�;�9�3�9�S�9�s�9�9�>
�S�
�s�
��
�
�^
��v�y�$�/�/�r�w�w�}�}��F�I�&�8
�8
�
�K�K�U�
�
���L�"����&-�f�n�b�&I�&I�"�6�*�

��f�%�

��F�#�	���5�6�"1�&�"9������5�6�,�V�4������A�B�!,�V�!4���*�B�/���6�=�%�0�0��!�!�";�<�$6�v�$>�F�!��!�!�"C�D�)8��)@�F�&�15���;�
#�6�+<�d�C�O�:�'�&�J[�]a�:b�9c�d��#�6�+?��F�#�$�/�w�v�?S�UY�/Z�.[�\� �#�6�<��>�J�/�w�v�|�T�/R�.S�T���;�2�*�e�g�+
�.�.%7�v�$>�$D�"�F�!��&�&�,�"������=�>�?�)-�	�	��)�)�4�4�6�q�r�:�)��&�(��%�
��*�*�+F�G�H���#��F�$4�b�9�w����
��*�*�+O�P�Q���#��F�$9�2�>� '���.�v�'D�b�I�I���.�.�9����	�
'���(E�r�J�$)����1�F�v�'7��<�<���.�.�9����	�
'���(8�"�=�5����I%�
�O�,�T
�I�I��)�)�*:�;��-�-�,��"�0�#�F�,>�	�J����-�-�*���(:�I�F���-�-�%���
�y�A����,�,�-A�B�$���(9�2�>�$+��)�
�6�o�.�7
/�	
��]�
�� � �]��
���
�� � �R��
���
�� � �P��
��B�
����6�7��"�"�
_�
�	
�
�st�	AT)�.R7�S�T�%MT)�7S�T)�S�T)�T�<T)�?T�T)�T&�"T)�%T&�&T)�)0U�Uc� �SnSSjnSnU"SS5nU(ajU"U"US/55nU(a=UupgUSU3Ul[RSUUR5 UR$[RS	U5 U"S
S5nU(ajU"U"US/55nU(a=UupgUSU3Ul[RSUUR5 UR$[RS	U5 U"S
S5n	U	(ajU"U"U	S/55nU(a=UupgUSU3Ul[RSU	UR5 UR$[RS	U	5 [R	S5 g)Nc��UH:n[R"U5nU(dM"[RSX5 Us $ g)NzFound database binary: %s (%s))rur*r6r:)�candidate_binariesr��binary_paths   r �find_first_binary�+get_dbms_version.<locals>.find_first_binary6s=��-�K� �,�,�{�3�K��{����4�k��#�"�
.�r)c	�j�[RSSRU55 [R"U[R
[R
SUSS9nUR=(d UR=(d SR5n[RSUR[U55 U$![Ra( [RSSRU55 g[a0n[RS	SRU5U5 SnAgSnAff=f)
NzRunning command: %srqTFrArgzCommand exit=%s, bytes=%szCommand timed out: %szCommand failed: %s (%s))r6r:rpr�rCrErXr�r�r&rhr`r�rrI)r�r�rHr�r@s     r �execute_command�)get_dbms_version.<locals>.execute_command@s���	��L�L�.�����0A�B��^�^��!���!������
�F�%�m�m�B�v�}�}�B��I�I�K�N��L�L�+��!�!��N�#�
�
"�!���(�(�	��N�N�2�C�H�H�W�4E�F���	����6�����8I�3�O���	�s�B;B>�>9D2�9	D2�&D-�-D2c�F�U(dg[R"SU[R5(aSOSn[R"SU5nU(d[R	S5 gURS5nSR
URS5SS5nX4$)	N�mariadb�MariaDB�MySQLz(\d+\.\d+\.\d+|\d+\.\d+)z"No version string found in output.rIror)r[r�r#r6r:rvrpr�)r��dbms_familyr�rw�major_minor_versions     r �extract_version_info�.get_dbms_version.<locals>.extract_version_infoYs������y�y��^�R�T�T�:�:�
��	�
�	�	�"=�~�N�
���L�L�=�>��&�,�,�Q�/��!�h�h�~�';�';�C�'@��!�'D�E���/�/r)�mariadbd�mysqldz	--versionrqz)Detected DBMS from server binary '%s': %sz%No parsable version from '%s' output.r�	rpz)Detected DBMS from client binary '%s': %sz
mariadb-admin�
mysqladminr�z&Detected DBMS from admin tool '%s': %sz0Database server version could not be determined.r�)r�)r�r6r�r:r�)
r�r�	r�	r�	�
server_binary�version_infor�	r��
client_binary�admin_binarys
          r �get_dbms_versionr�	5s�����20� &�j�(�;�M��+��]�K�8�9�
���#/� �K�%0�M��7�)�"<�F���K�K�;���#�#�
�
�&�&�&����<�m�L�%�i��9�M��+��]�K�8�9�
���#/� �K�%0�M��7�)�"<�F���K�K�;���#�#�
�
�&�&�&����<�m�L�$�_�l�C�L��+��\�9�5�6�
���#/� �K�%0�M��7�)�"<�F���K�K�8���#�#�
�
�&�&�&����<�l�K�
�N�N�E�F�0r)c��[RSU5 [R"SU[RR
S9$)Nz$Attempting database connection to %sz
/root/.my.cnf)�read_default_file�database�cursorclass)r6r��pymysql�connect�cursors�
DictCursor)r�	s r r�r��s5��
�K�K�6��A��?�?�)���O�O�.�.��r)c�$�[5SLnU(aSnOSn[U5R5R5nSS1nU(aSUlX4;UlgX4;aSUlSUlgSUlSUlg![a SnNMf=f)	a.
Determine whether MySQLTuner should be installed and/or run.
Behavior:
    - If mysqltuner is installed: prompt to run it.
    - If mysqltuner is not installed: prompt to install and run it.
Stores the result in:
    report.mysqltuner_opt_in   (True/False)
    report.mysqltuner_install  (True/False)
Nz(MySQLTuner is installed. Run it? [y/N]: z8MySQLTuner is not installed. Install and run it? [y/N]: rg�y�yesFT)�find_mysqltuner_pathr�r�rqr�r�r�)r��	installedr��choice�
yes_valuess     r �get_mysqltuner_opt_inr�	�s���%�&�d�2�I��;��K����v��$�$�&�,�,�.���u��J��$)��!�#)�#7�� ��
��$(��!�#'�� �$)��!�#(�� �������s�'B�B�Bc��[R"S5nU(aU$SHWn[RR	U5(dM)[R
"U[R5(dMUUs $ g)N�
mysqltuner)z/usr/local/bin/mysqltunerz/usr/bin/mysqltunerz/usr/local/sbin/mysqltunerz/usr/sbin/mysqltuner)rur*r3r�r�r�r�)�
tuner_pathrs  r r�	r�	�s`�����l�+�J�������7�7�>�>�.�)�)�b�i�i��B�G�G�/
�/
�"�!��r)c�^
�[R"S5m
[R"S5nU=(d SR5n/nSnU[U5:a�X$nT
R	SU5nURU5(a�US-n/nU[U5:aTT
R	SX'5n	URU	5(aO)UR
X'5 US-
nU[U5:aMT[U
4SjU55n
U
(a"UR
U5 URU5 UnM�UR
U5 US-
nU[U5:aM�/nSnUHZnT
R	SU5R5S:Xa US-
nUS::aUR
U5 MEMGSnUR
U5 M\ SRU5R5$)NrOz^-{4,}\s*.+?\s*-{4,}\s*$rgrrIc3�d># �UH%nTRSU5R5v� M' g7f)rgN)rir�)r��b�ansi_res  �r r��3_mysqltuner_strip_empty_sections.<locals>.<genexpr>�s(����H�%�Q�g�k�k�"�a�0�6�6�8�8�%�s�-0r)r[r\rrhrirur�r�r�r�rp)r'�	header_rer��keptr{r��plain�
next_indexrq�
next_plain�has_contentrx�	blank_runr�	s             @r � _mysqltuner_strip_empty_sectionsr�	�s�����j�j�*�+�G��
�
�6�7�I�
�Z�R�#�#�%�E�
�D�
�E�
�#�e�*�
��|�����B��%���?�?�5�!�!����J��E��s�5�z�)�$�[�[��U�->�?�
��?�?�:�.�.�����U�.�/��a��
��s�5�z�)��H�%�H�H�K�����D�!����E�"��E�����D��
��
��/�#�e�*�
�2�G��I����;�;�r�4� �&�&�(�B�.���N�I��A�~����t�$���I��N�N�4� ���9�9�W��#�#�%�%r)c�^�[USS5n[USS5nU(dU(dg[5nSnU(dP[RR	U5(a,[R
"U[R5(aUnU(GaXU(GdP[R"S5=(d3 [R"S5=(d [R"S5mU4S	jnU"5(dg
Sn[R"SS
USU/SSSS9nURS:waIUR=(d SUR=(d S-nUR5nU(aSU3$S$[R"SSU/SSSS9n	U	RS:waIU	R=(d SU	R=(d S-nUR5nU(aSU3$S$UnU(d
[5nU(dP[RR	U5(a,[R
"U[R5(aUnU(dgU(dSUS3$[ R#S5 [%S['[)[+[USS5=(d S5S-555n[%S['[)[+[US S5=(d S5S-555n[R"US![-U5S"[-U5S#S$S%/SSS&SS'9n
U
R=(d SU
R=(d S-nU
RS:waS(U
RS&U3n[/U5$![an
SU
3sSn
A
$Sn
A
ff=f![a SnN�f=f![a SnN�f=f))Nr�Fr�z'MySQLTuner was skipped at user request.z /usr/local/bin/sparta-mysqltuner�apt-get�dnf�yumc��>�[R"S5(agT(dg[RR	T5S:XaM[[RSS9n[R"SS/SSUSS9 [R"/S	QSSUSS9 O[R"TS
SS/SSSS9 [[R"S55$![a [RS
5 N@f=f)Nr�TFr�	�noninteractive)�DEBIAN_FRONTENDr�)r'r	rV	r1)r�	�install�-yr�r�	r�	�r'r	r1z'Failed while attempting to install curl)
rur*r3r��basenamer#r�r�rCrr6rIr�)�apt_env�pkg_manager_paths �r �install_curl_if_missing�0get_mysql_tuner.<locals>.install_curl_if_missing%s�����|�|�F�#�#��#��
L��7�7�#�#�$4�5��B�"�2�:�:�?O�P�G��N�N�"�H�-�!�'+�#�#���N�N�<�!�'+�#�#���N�N�)�9�d�F�C�!�'+�#�	�����V�,�-�-���
L�� � �!J�K�
L�s�A/C�C�C4�3C4zEcurl not found and could not be installed; cannot install mysqltuner.zLhttps://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.plr�z-fsSLr�Tr�	rrgz2Failed to download mysqltuner script from GitHub.
z1Failed to download mysqltuner script from GitHub.r;	�755z#Failed to chmod mysqltuner to 755.
z"Failed to chmod mysqltuner to 755.z&Error during mysqltuner installation: z"MySQLTuner could not be installed.zMySQLTuner is installed at z, but user chose not to run it.zRunning mysqltunerr�r�r�z
--forcememz--forceswapz--nogoodz--noinfoz--colorr)r'r	r�r1zMySQLTuner exited with rc=)r+r�	r3r�rlr�r�rur*r�rCr&rXr�r�rr6r�rRrSrTr�rUr�	)r��install_requested�
run_requestedr�	�sparta_tuner_pathr�	rrG	�combined�chmod_resultr@�mem_mb�swap_mb�
run_result�combined_outputr�	s               @r �get_mysql_tunerr�	
s������(<�e�D���F�$7��?�M��]�8�%�'�J�:����G�G�N�N�,�-�-��I�I�'����1�1�&�
����L�L��#�
#��|�|�E�"�
#��|�|�E�"�	�"	.�H'�(�(�Z�(	B�`�C�$�.�.���#�t�->�?��#��	�K��%�%��*�'�.�.�4�"��&�&�,�"���$�>�>�+�� �J�(��T��M��&�>�>��%�!2�3��#��	�L��&�&�!�+�(�/�/�5�2� �'�'�-�2���$�>�>�+�� �;�8�*�E��>��+�J�
�)�+�
���G�G�N�N�,�-�-��I�I�'����1�1�&�
��3��,�Z�L�8W�X�X�
�K�K�$�%���
�s�5��w�v�~�q�A�F�Q�G�$�N�O�P�
����
�s�5��w�v�}�a�@�E�A�F��M�N�O�
���������K����L����		
������J�""�(�(�.�B�:�3D�3D�3J��K�O�����!�6�z�7L�7L�6M�R�P_�O`�a��+�O�<�<��m�	B�;�C�5�A�A��	B��.�����������s\�A4N�7N�9A0N�*N�,N�>N$�>N6�
N!�N�N!�N!�$N3�2N3�6O�Oc�R�/Ul[RRS5(d[RSS5 g/Ul[R"S5nUGHSnURSS9(dMURRS5(dURS;a"[RSUR5 Ml[RS	UR5 S
Ul[R"URSS9H_up4nUHSnU=R[RR[RRX655-
slMU Ma URR#UR[%URS
-S545 GMV SSS5 URR'SSS9 URSSUlUR(dgSRSUR55$![ a8 [RS[RRX655 GMJf=f!,(df   N�=f![(a [R+S5 /Ulgf=f)Nz/var/lib/mysqlz"MySQL data directory not found: %sz[data dir missing]F��follow_symlinksro>rWrp�information_schemar�#innodb_tempz-Skipping system/hidden database directory: %sz Measuring database directory: %sr)�followlinkszUnreadable file skipped: %srMrc��US$r�r"r{s r r�'get_largest_databases.<locals>.<lambda>�s��t�A�wr)Tr�rsz[none detected]rc3�8# �UHupSUSUS3v� M g7f)r�r3z MB)Nr")r��
database_name�size_mbs   r r��(get_largest_databases.<locals>.<genexpr>�s)���
�*B�&�
����r�'��$�/�*B�r�z%Failed while scanning database sizes.z[error])r�r3r�r+r6r��database_sizes_mbr)�is_dirr#r�r:�database_total_bytes�walk�getsizerpr+r�rTrFrrI)r�rir6�	root_pathr��
file_names�	file_names       r �get_largest_databasesr�	�s1��!�F��
�7�7�=�=�)�*�*����;�=M�N�#�;�#%�� �
�Z�Z�(�
)�->�*���|�|�E�|�:���:�:�(�(��-�-����@�2��L�L�G��
�
������?����L�./��+�02����J�J�E�1�,�I�*�&0�	��"�7�7�2�7�7�?�?� "�����Y� B�<��7�&0�1��(�(�/�/��
�
��f�9�9�[�I�1�M���E+�*�T	� � �%�%�*>��%�M�#)�#;�#;�C�R�#@�� ��'�'�$��y�y�
�*0�*B�*B�
�
�	
��' '��"�L�L� =� "�����Y� B�����;*�
)��j�����@�A�#%�� ���sX�I=�!CI,�"AH'�1AI,�<AI=�!I=�'=I)�$I,�(I)�)I,�,
I:�6I=�=&J&�%J&c
���SnSnSn[5nU UR	5nURS5 UR
5=(d /nUGH�nURS5=(d SR5n	URS	5n
U	S
:XaU"U
5Ul	MRU	S:XaU"U
5Ul
MgU	S:XaU"U
S5UlM}U	S
:XaX�lM�U	S:XaU"U
5Ul
M�U	S:XaU"U
5UlM�U	S:XaU"U
5UlM�U	S:XaU"U
S5UlM�U	S:XaU"U
S5UlM�U	S:XaU"U
5UlGMU	S:XaU"U
5UlGM"U	S:XaU"U
5UlGM8U	S:XaU"U
5UlGMNU	S:Xa	X�lGM]U	S:Xa	X�lGMlU	S:Xa	X�lGM{U	S:XdGM�X�lGM� URS5 UR55nU(aU"URS	5S5UlSSS5 SSS5 SR9/SPU"[;US
S55PS PU"[;USS55PS!P[;USS5=(d S"PS#P[;US$S5=(d S"PS%P[;US
S5=(d S"PS&PU"[;USS55PS'PU"[;USS55PS(PU"[;USS55PS)P[;USS5=(d S"PS*P[;USS5=(d S"PS+PU"[;USS55PS,PU"[;USS55PS-PU"[;USS55PS.PU"[;USS55PS/P[;USS5=(d S"PS0P[;USS5=(d S"PS1P[;USS5=(d S"PS2P[;USS5=(d S"PS3P5nU$![a n[RSU5 SnAgSnAff=f!,(df   GN=f!,(df   GN
=f![a n[RSU5 SnAgSnAff=f)4Nc��U(dg[U5R5R5nUR5(a[	U5$SnURS5(aSnUSSnO;URS5(aSnUSSnOURS5(aSnUSSnUR5(a[	U5U-$S$)	NrIr:r�r�r;rMr<r�)rUr�r$r	rSrs)rer'�
multipliers   r �
parse_size�#get_dbms_config.<locals>.parse_size�s������5�z���!�'�'�)���<�<�>�>��t�9���
��=�=�����J����9�D�
�]�]�3�
�
�$�J����9�D�
�]�]�3�
�
�+�J����9�D�)-�����s�4�y�:�%�A�T�Ar)c�>�U(a[US-S-S5S3$S$)Nr�rr	r�)rTr�s r �to_mb�get_dbms_config.<locals>.to_mb s'��8=�%����t�+�Q�/�0��4�H�5�Hr)c�r�[U5$![[4a [R	SX5 gf=f)NzUnable to parse %s value: %s)rSr�r�r6r�)rer�s  r �safe_int�!get_dbms_config.<locals>.safe_int
 s7��	��u�:����:�&�	��N�N�9�5�H��	�s�

�&6�6zDatabase connection failed: %sz.[Error] Unable to connect to MySQL or MariaDB.a~
                    SHOW GLOBAL VARIABLES
                    WHERE Variable_name IN (
                        'key_buffer_size',
                        'innodb_buffer_pool_size',
                        'max_connections',
                        'query_cache_type',
                        'query_cache_size',
                        'tmp_table_size',
                        'max_heap_table_size',
                        'table_open_cache',
                        'table_definition_cache',
                        'innodb_log_file_size',
                        'join_buffer_size',
                        'sort_buffer_size',
                        'max_allowed_packet',
                        'slow_query_log',
                        'slow_query_log_file',
                        'long_query_time',
                        'performance_schema'
                    );
                �
Variable_namerg�Valuer�r�r�r�r�r�r�r�r�r�r�r�rrrrrz,SHOW GLOBAL STATUS LIKE 'Threads_connected';�Threads_connectedz%Failed to retrieve DBMS variables: %sz*[Error] Failed to retrieve DBMS variables.zMax Key Buffer Size: z
Max InnoDB Buffer Pool Size: z
Max Connections: r�z
Current Connection Threads: r�z#

Query Cache:
  query_cache_type: z
  query_cache_size: z&

Temporary Tables:
  tmp_table_size: z
  max_heap_table_size: z#

Table Cache:
  table_open_cache: z
  table_definition_cache: z&

InnoDB Log:
  innodb_log_file_size: z

Buffers:
  join_buffer_size: z
  sort_buffer_size: z 

Limits:
  max_allowed_packet: z$

Slow Query Log:
  slow_query_log: z
  slow_query_log_file: z
  long_query_time: z)

Instrumentation:
  performance_schema: r)r�rr6r
r�r�r�r�rqr�r�r�r�r�r�r�r�r�r�r�r�rrrrrr�r�rpr+)r�r�	r�	r�	�
connectionr@r��rowsr��variablerer�s            r �get_dbms_configr
�s���B�*I��@�)�+�
�
a<�
��"�"�$����� ��,���(�.�B���C� #���� 8� >�B�E�E�G�H��G�G�G�,�E��#4�4�1;�E�1B��.�!�%>�>�9C�E�9J��6�!�%6�6�19�!�#4�2��.�"�%7�7�27�/�!�%7�7�2<�U�2C��/�!�%5�5�0:�5�0A��-�!�%:�:�5?��5F��2�!�%7�7�2:�!�#5�3��/�"�%=�=�8@�!�#;�9��5�"�%;�;�6@��6G��3�!�%7�7�2<�U�2C��/�!�%7�7�2<�U�2C��/�!�%9�9�4>�u�4E��1�!�%5�5�05�-�!�%:�:�5:�2�!�%6�6�16�.�!�%9�9�49�1�w �z���M�N��o�o�'���19�����(�*=�2�F�.�s%��F	Z�	Z�
�	Z��g�f�6G��&N� O�P�	Z�Q(�	Z�(-�g�f�>W�Y]�.^�(_�'`�	Z�a�	Z�#�F�,=�t�D�M��N�	Z�O'�	Z�(/�v�7L�d�'S�'\�W\�&]�	Z�^�	Z�
 '�v�/A�4�H�Q�E�R�	Z�
S�	Z� %�W�V�5G��%N�O�P�
	Z�Q�
	Z�#�7�6�3C�T�#J�K�L�	Z�M"�	Z�#(���8M�t�(T�"U�!V�	Z�W�	Z� '�v�/A�4�H�Q�E�R�	Z�S%�	Z�&-�V�5M�t�%T�%]�X]�$^�	Z�_#�	Z�$)���9O�QU�)V�#W�"X�	Z�Y�	Z�  %�W�V�5G��%N�O�P�!	Z� Q�!	Z�" %�W�V�5G��%N�O�P�#	Z�"Q!�#	Z�&"'�w�v�7K�T�'R�!S� T�'	Z�&U�'	Z�*%�V�-=�t�D�M��N�+	Z�*O"�+	Z�,#*�&�2G��"N�"W�RW�!X�-	Z�,Y�-	Z�.&�f�.?��F�O�%�P�/	Z�.Q!�/	Z�2")��1E�t�!L�!U�PU� V�3	Z�2WY�3	Z��:�N��I�@����5�s�;�?��@��%�$���Z��|�<����<�c�B�;��<�sj�
O6�Q�P5�F,P#�AP#�*P5�2Q�6
P �P�P �#
P2	�-P5�5
Q�?Q�Q�
Q1�Q,�,Q1c�:�[RS5 Sn[URURUR
4UUR5nURS5 [U5nURS5 [U5nURS5 [U5nURS5 [U5nSUS3nSUS3nSUS3n	URS	5S
URSU5SURS
5SURU5SURS5SURU5SURS5S
URU	53$![ a+ [R#S5 Sn
UR%U
5s$f=f)NzBuilding 'Database' sectionr�zDetecting DBMS versionzCollecting DBMS configurationzRunning MySQLTunerzFinding largest DBsr�r�z## Database SummaryrzDBMS Versionr8z### DBMS Configuration:z### MySQLTuner:z### Top 10 Largest Databases:z)Failed to build 'Database Tuning' sectionz�[Error] Failed to build database section. Manually check for the DBMS version, install MySQL Tuner and run it for results, find the database name and the size of the database, and check to see if it can be optimized. Please report this as a bug.)r6r:r�r�r�r�r�r�r�	r
r�	r�	r�rCr6rMrrIrU)r�r�r�r��dbms_config_summary�mysqltuner_output�largest_db_summary�
dbms_block�tuner_block�
largest_blockr�s           r �database_build_sectionr
� s���
�L�L�.�/�
�E�&����	�	�	�v�4�4�5�
����	��#/����6�7�'��/�����=�>�-�f�5�����2�3�+�F�3�����3�4�2�6�:���0�1��7�
��/�0��6��� 2�3�5�9�
��$�$�%:�;�<�B��(�(���F�G�t��'�'�(A�B�C�4��&�&�z�2�3�4��'�'�(9�:�;�4��&�&�{�3�4�D��'�'�(G�H�I���&�&�}�5�6�
8�		
���/����D�E�
e�	�
�"�"�:�.�.�/�s�DE%�%2F�Fz[\w\.\+\-]+@[\w\.\-]+c���[RRU5(d[R	S5 U$[USSSS9nUR
5nSSS5 Sn0nWHknSU;aMURSS5up�UR5R5nU	R5n	U(aU	(dM]US	:XaU	nMgX�U'Mm X;aXan
[RS
X5 U
$U(a[R	SU5 U$[R	S5 U$!,(df   N�=f![a [RSU5 Us$f=f)
Nz5cPanel mailips file not present; using main server IPrr-r\rz*Failed reading %s; falling back to main IPr9rI�*z(Found domain-specific SMTP IP for %s: %sz%Using wildcard SMTP IP for cPanel: %szDmailips file had no matching or wildcard entry; using main server IP)
r3r�rlr6r:r1r�rrIr�r�rqr�)�mailips_path�
target_domain�fallback_ip�mailips_file�
mailips_lines�wildcard_ip�
domain_ip_mapr��entry_domain�entry_ip�	chosen_ips           r �_mail_ip_from_cpanel_mailipsr
� sY��
�7�7�>�>�,�'�'����L�M���	�
��#���
�
�(�2�2�4�M�
��K��M����d�?��!%���C��!3���#�)�)�+�1�1�3���>�>�#���8���3��"�K��&.�l�#���%�!�0�	����6�
�	
�������<�k�J���
�L�L�N����U
�
�������8�,�	
���	�s/�D?�	D.�D?�.
D<�8D?�<D?�?"E$�#E$c�^^
�[RRU5(d[R	S5 U$[USSSS9nUR
5nSSS5 SnSm
U
U4S	jn/nWHbnU"U5(a8U(aU"U5OSn	U	(a[RS
TU	5 U	s $U/nMHU(dMQURU5 Md U(aU"U5OSn	U	(a[RS
TU	5 U	$[RS5 U$!,(df   N�=f![a [RSU5 Us$f=f)Nz,Postfix master.cf not present; using main IPrr-r\rz)Failed reading %s; using main IP fallbackc��[U5=(a. URS5(+=(a SU;=(a SU;$)N)rqr3�unixr�)r�r�)r�s r �is_service_header�6_mail_ip_from_cwp_master_cf.<locals>.is_service_header!s@����O�
#��)�)�+�6�6�
#��9�$�
#��	�!�		
r)c���SnSnUHgnSU;a%URSS5SR5nM.SU;dM6URSS5SR5R5nMi X4$)Nzsmtp_bind_address=rIzsmtp_helo_name=)r�r�rq)rM�block_helo_domain�
block_bind_ip�
block_lines    r �extract_block_settings�;_mail_ip_from_cwp_master_cf.<locals>.extract_block_settings!s��� ���
�%�J�#�z�1� *� 0� 0�1E�q� I��!��%�'��� �J�.��$�$�%6��:�1�=�C�C�E�K�K�M�"��&�!�/�/r)c�8>�T"U5upU(aUT:XaU$gr�r")rMr"
r#
r%
r
s   ��r �block_matches_domain�9_mail_ip_from_cwp_master_cf.<locals>.block_matches_domain,!s%���+A�+�+N�(���.�-�?� � �r)z.Found CWP Postfix smtp_bind_address for %s: %szENo per-domain smtp_bind_address found in CWP master.cf; using main IP)r3r�rlr6r:r1r�rrIr�r�)�master_cf_pathr
r
�master_cf_file�master_cf_linesr
r(
�current_block_linesr��
matched_ipr%
s `        @r �_mail_ip_from_cwp_master_cfr/
!sb���
�7�7�>�>�.�)�)����C�D���	�
��C�'�(�
�
�,�6�6�8�O�
�
�0�$������T�"�"�'�%�%8�9��
�
����D�!���
"�!�#'�&������&�&�t�,�% �,�	�0�1�
��
����<���	
�
��
�K�K�O����_
�
�������7��	
���	�s/�D4�D#�D4�#
D1�-D4�1D4�4"E�Ec���[USS5(d[RS5 g[USS5=(d SR5n[USS5=(d SR5R	5nUR
nUS:Xa[
SX#5nX@lU$US:Xa[S	X#5nX@lU$X0lU$![a  [RS
5 X0lUs$f=f)Nr�z8main_ip is missing on report; defaulting mail IP to Noner�rgr�r�z/etc/mailipsr��/etc/postfix/master.cfz<Unhandled error determining mail IP; falling back to main IP)r+r6r�r�rqr�r
r�r/
rrI)r�r�r
r
r�s     r r�r�Z!s����6�9�d�+�+����F�	
���&�,��3�9�r�@�@�B�J�	��)�2�	.�	4�"�;�;�=�C�C�E���.�.�K����!�2��
��G�%�N��N��,�,�1�(�-��G�%�N��N�$����������J�	
�%�����s�C�&C�C�'C2�1C2c��[USS5SLa[RS5 g[USS5nU(d[RS5 g[R
"SSSU/S	S
S9nSnUR
5H-nUR5nU(dMURS5n O U(d[RS
U5 gX0l	U$![a n[RSX5 SnAgSnAff=f)NrFzClocal_email is False; skipping PTR lookup for external mail routingr�z7mail_ip is not set on report; cannot perform PTR lookuprgrhz-xTr)r�rozNo PTR record found for %szPTR lookup failed for %s: %s)r+r6r:r�r�r�rr�r=rr)r�r�r��	ptr_valuer�r=s      r �get_ptrr4
�!s����v�}�d�+�u�4����Q�	
���f�i��.�G�����E�	
����(�(�
�H�d�G�,�4��
���	��%�%�'�D��:�:�<�D������C�(�I��(���L�L�5�w�?��#����������3�W�@����s�A:C�
C�
C?�C:�:C?c���[USS5=(d SR5n[USS5=(d SR5R5nU(d/UlgUS:Xa/UlSUlgUS:Xa[
R
S5 /UlgUS:XaQ[US	S5=(d SR5nU(d[
RS
5 /UlgSUSU3nO*US
:XaSU3nO[
RSU5 /Ulg[RRU5(d%[
R
SX$5 /UlSUlg/n[R"U5nUHUnURSS9(dMURnURS5(aM=USU3n	URU	5 MW SSS5 UR!5 XPl[#U5Ul[
R
SURUU5 UR$!,(df   Nb=f![$a [
R'S5 /Ulgf=f)Nr�rgr�r�rr�z=Baremetal detected; email account enumeration not implementedr�r�z7domain_owner is not set; cannot derive cPanel mail pathrv�/mail/r��/var/vmail/z8Unknown panel_type '%s'; cannot enumerate email accountsz#Mail directory not found for %s: %sFr�	ro�@z*Found %s email accounts for %s on panel %sz"Failed to enumerate email accounts)r+r�rqrrr6r�r�r3r�r+r)r�	r#r�r�rFrhrrI)
r�r�r�rrrrHr6�mailbox_userr�s
          r �get_email_accountsr:
�!sJ���&�,��3�9�r�@�@�B�J��f�.��3�9�r�
@�
@�
B�
H�
H�
J�F�� "����C��)�)�$&�F�!�&'�F�#����$��K�K�O�
�%'�F�!����!��V�^�R�8�>�B�E�E�G�E�����M��)+��%�� ���v�f�X�6�I�
�.�
.�%�f�X�.�I�
�N�N�J��
�%'�F�!���w�w�}�}�Y�'�'��K�K�5�v�
�%'�F�!�&'�F�#����
�Z�Z�	�
"�g� ���|�|�E�|�:��$�z�z���*�*�3�/�/��#/�.��&�� :�
��%�%�m�4�!�#�	���� .��"%�n�"5������8��#�#���		
��&�&�&�'#�
"��*�����=�>� "�����sL�'I
�<"I
�A
I
�-2I
� AI
�)I
�AH9�AI
�9
I�I
�
&I3�2I3�directory_pathc	��Sn[R"U5HOup#nUHCnU[RR[RR	X%55-
nME MQ U$![
a MZf=fr5)r3r�	r�r�	rpr�)r;
�total_bytes�rootr��filesr�	s      r �_mail_dir_size_bytesr@
�!sm���K��'�'�.�1�����I�
��r�w�w���r�w�w�|�|�D�/L�M�M���2����%�
��
�s�?A.�.
A<�;A<rc��0nU=(d /H�n[U5RSS5S=(d SR5nU(dMA[RRX5n[RR
U5(d[RSU5 M�[U5U[U5'M� U$)Nr8
rIrrgz!Mailbox directory missing for: %s)
rUr�r�r3r�rpr+r6r:r@
)rr��usager�r~�mailbox_paths      r �_mail_collect_usage_maprD
"s����E�%�+��+�
��
�&�,�,�S�!�4�Q�7�=�2�D�D�F�����w�w�|�|�I�8���w�w�}�}�\�*�*��L�L�<�m�L��$8��$F��c�-� �!�,��Lr)c���[USS5=(d SR5nUS;ag[USS5=(d SR5R5nU(d[R	S5 gUS:XaI[USS5=(d SR5nU(d[R	S5 gS	US
U3$US:XaSU3$[RS
U5 g)Nr�rg�r�r�r�z0managed_domain not set; skipping mail disk usager�r�z9Domain owner not set; skipping mail disk usage for cPanelrvr6
r�r7
z+Unknown panel type '%s' for mail disk usage)r+r�rqr6r:r�)r�r��domain_lowerrs    r �_mail_get_mail_base_pathrH
"s����&�,��3�9�r�@�@�B�J��4�4���F�$4�b�9�?�R�F�F�H�N�N�P�L�����G�H���X������4�:��A�A�C����L�L�K�
����w�f�\�N�3�3��(�(��\�N�+�+�
�N�N�@�*�M�r)c
��^�STl[TSS5nU(d[RS5 g[	T5nU(dg[X!5nU(dg[
UR5SSS9SSn[UR55nUSSn[RRX&RS	S
5S5nSVs0sHon[RR[RRXx55(dMFU[[RRXx55_Mq n	nUTlUTlUTlU	TlTR)STR+U55S
TR-S5/n
U
R/U4SjU55 U	(a`U
R1S
5 U
R1TR-S5SUS35 U
R/U4SjU	R555 SRU
5TlTR$s snf![2a [R5S5 gf=f)N�No disk usage data collected.rz/No email accounts detected; skipping disk usagec��US$r�r"r{s r r�&get_email_disk_usage.<locals>.<lambda><"s���Q�r)Tr�r�rr8
rI)r\�new�tmp�sent�archive�drafts�trashzTotal email disk usagergz Top email accounts by disk usagec3�V># �UHupSUSTRU53v� M  g7f�r�r0N�r�)r�r��usage_bytesr�s   �r r��'get_email_disk_usage.<locals>.<genexpr>a"s4����
�.7�*�
����r�&�":�":�;�"G�!H�I�.7���&)z Folder usage for highest accountr3z):c3�V># �UHupSUSTRU53v� M  g7frT
rU
)r��folder_name�folder_bytesr�s   �r r�rW
k"s4�����1I�-�K��[�M��F�$<�$<�\�$J�#K�L�1I�rX
rz#Failed calculating email disk usage)�email_disk_summaryr+r6r�rH
rD
r�r�rr|r3r�rpr�r+r@
rrr
rrCr�r�r�r�rrI)r�rr�	usage_map�	top_three�total_usage�
highest_email�highest_mailbox_pathrZ
�folder_breakdownr�s`          r �get_email_disk_usagerc
*"sI��� ?�F���V�%5�t�<�N�����E�F��C�,�V�4�	���+�I�F�	�����O�O��#7��
�
�1��	��)�*�*�,�-��!�!��Q��
�!�w�w�|�|��*�*�3��2�1�5� 
�� �	
� ���w�w�}�}�R�W�W�\�\�*>�L�M�
�K�-������1�?��
� �		�
� )4��%�,5��)�,9��)�,<��)�
�%�%�(�&�*B�*B�;�*O�
�
��)�)�*L�M�
��	���
�.7�
�	
�
��L�L����L�L��0�0�1S�T�U�UW�Xe�Wf�fh�i�
�
�L�L��1A�1G�1G�1I��
�
%)�I�I�e�$4��!��(�(�(��Y
��\�����>�?���s8�H>�H>�A4H>�AH9�-H9�C4H>�9H>�>I �I �mta_type�current_yearc
�`�U=(d SR5nUS:Xa;[U5S:ag[RR	USSUS3S5$[U5S:ag[RR	USUSSUSSUS3S	5$![
a gf=f)
Nrg�eximrrrqrIz%Y-%m-%d %H:%M:%Sr�z%Y %b %d %H:%M:%S)r�rhr�r��strptimer)r�rd
re
r/s    r �_email_bounce_parse_timestampri
x"s������R�&�&�(���v���5�z�A�~���;�;�'�'���8�*�A�e�A�h�Z�(�*=��
��u�:��>���{�{�#�#��n�A�e�A�h�Z�q��q��
�!�E�!�H�:�>��
�	
������s"�.B �*B �B �,3B � 
B-�,B-rpc��US:Xa4SU=(d S;nSU=(d S;=(d SU=(d S;nX44$SU=(d S;nSU=(d S;nX44$)Nrg
z ** rgz temporarily deferredz max defers and failureszstatus=bouncedzstatus=deferredr")r�rprd
�	is_bounce�is_defers     r �_email_bounce_detect_statusrm
�"sq���6���x�~�2�.�	�*���"�
�>�
'�J�,<�"�
=�	��"�"� �Z�%5�2�6�I� �Z�%5�2�6�H���r)c���US:Xa�U=(d SRS5nUS:XaU=(d SRS5nUS:waoUS-nU[U5:a
XS:XaUS-
nURS	U5nUS:XaURS
U5nUS:waXUOXSR5nSU;aU$[R	U=(d S5nU(aURS5$S$)
N�postfixrgz to=<r�z to=r��<rI�>rqr8
r)r,rhr��_EMAIL_BOUNCE_ADDR_REGEXr�rv)r�rprd
�to_index�start_index�	end_indexr-r�s        r �_email_bounce_extract_addressrv
�"s����9���$�"�*�*�7�3���r�>�"�(�b�.�.�v�6�H��r�>�"�Q�,�K��S��]�*�x�/D��/K��q� �� �
�
�c�;�7�I��B��$�M�M�#�{�;�	���?��Y�/��l�+��e�g�	
�
�i�� � �(�/�/���B�?�I�!*�9�?�?�1��4��4r)�log_pathr�c�V�[USSSS9nUH�nURS5n[XqU5nU(aX�:aM.UR5n	[	XyU5up�U
(d	U(dM\[XyU5nU(dMqUR5nUR
SU-5(dM�X�;aSSS.X\'U
(aX\S	==S
-
ss'U(dM�X\S==S
-
ss'M� SSS5 g!,(df   g=f![a [RSU5 gf=f)
Nrr-r\rrr8
r�r�r�r�rIr�z!Failed while reading mail log: %s)
r1r=ri
rqrm
rv
rsrr6rI)
rw
rd
r��cutoff_timere
r��log_filer��log_timerprk
rl
r�s
             r �_email_bounce_scan_log_filer}
�"s$��#H�
�(�C�'�(�
C�x�$��#�?�?�4�0��8����� �8�#9��%�^�^�-�
�&A��(�'�#�	�"�X�� =��(�!�
�%�� -� 3� 3� 5�
�$�-�-�c�N�.B�C�C�� �4�>?�Q�2O�L�/�� �/�	�:�a�?�:��8� �/�
�;�q�@�;�?%�D�
C�
C��B�H����<�h�G�H�s5�D�CC4�C4�+D�4
D�>D�D� D(�'D(c���U=(d 0R5VVs0sH7upURSS5(dURSS5(dM5X_M9 snn$s snnf)Nr�rr�)r�r�)r��addressr�s   r �_email_bounce_filter_statsr�
�"s[��!-� 2��9�9�;��;�O�G��:�:�i��#�#�v�z�z�*�a�'@�	���;����s�4A�Ac	���[USS5=(d SR5n[USS5=(d SR5R5nSUlU(d[RS5 gUS:XaSnSnOS	nS
n[RRU5(d[RSU5 g[RR5nU[R"SS
9-
n0n[US/5=(d /H"nSSS.U[U5R5'M$ [UUUUUR US9 [#U5=(d SUlUR$(dSUl[RSU5 gUR'UR$5Ul[R)S[+UR$5U5 UR$$)Nr�rgr��"No bounce or defer data collected.z3managed_domain is not set; cannot analyze mail logsr�z/var/log/exim_mainlogrg
z/var/log/maillogro
zMail log not found at %srI)r�rrry
)rw
rd
r�rz
re
r�z:No bounce/defer stats found for domain %s in last 24 hoursz?Collected bounce/defer stats for %d email accounts on domain %s)r+r�rq�email_bounce_summaryr6r�r3r�rlr�r�r�r��	timedeltarUr}
�yearr�
rr�r:rh)	r�r�r�rw
rd
�current_timerz
r�r�s	         r �get_email_bounce_statsr�
�"s����&�,��3�9�r�@�@�B�J�	��)�2�	.�	4�"�;�;�=�C�C�E��#G�F������L�M���X��*����%����
�7�7�>�>�(�#�#����.��9���;�;�?�?�$�L�����1�!5�5�K��L� ��)9�2�>�D�"�D�
�?@�a�3P��S��'�-�-�/�0�E� ���%��!�&�&�!�
�!;�<� H� P�D�F���$�$�&J��#����H��	
��"(�"D�"D��!�!�#�F���L�L�I��F�%�%�&���
�$�$�$r)c�f�[USS5=(d SR5n[USS5=(d SR5nSUlUS:Xa�U(d/[R	S5 SUlSUlUR
$SUS	3n[RRU5(aS
UlSUlUR
$SUlSUlUR
$US:Xa�S
n[RRU5(d/[R	S5 SUlSUlUR
$[USSSS9nUR5R5nSSS5 SW;aSUlSUlUR
$SU;aS
UlSUlUR
$SUlSUlUR
$US;aSUlSUlUR
$[R	SU5 SUlSUlUR
$!,(df   N�=f![a2 [RS5 SUlSUlUR
s$f=f![a2 [RS5 SUlSUlUR
s$f=f)Nr�rgr��No spam protection detected.r�z/domain_owner missing for SpamAssassin detectionrhrvz/.spamassassinenable�SpamAssassinzDetected SpamAssassinr�r1
z:Postfix master.cf not found; cannot detect spam protectionrr-r\rzcontent_filter=smtp-amavis�AmavisdzDetected Amavisd�spamassassinz?Failed to parse Postfix master.cf for spam protection detectionrF
z+Unknown panel type '%s', defaulting to Nonez'Error determining spam protection setup)r+r��spam_protection_summaryr6r�r
r3r�rlr1r�rqrrI)r�r�r��sa_flag_path�	master_cfrprRs       r �get_spam_protectionr�
'#s����&�,��3�9�r�@�@�B�J��F�N�B�7�=�2�D�D�F�L�%C�F�"�L&���!�����E��*0��&�1O��.��-�-�-�#�L�>�1E�F�L��w�w�~�~�l�+�+�)7��&�1H��.��-�-�-�%+�F�"�-K�F�*��)�)�)��,�,�0�I��7�7�>�>�)�,�,����P��*0��&�1O��.��-�-�-�
.���s�W�X����f�f�h�n�n�.�G��
0�7�:�-6�F�*�5G�F�2�!�1�1�1�!�W�,�-;�F�*�5L�F�2�!�1�1�1�)/��&�1O��.��-�-�-��8�8�%+�F�"�-K�F�*��)�)�)����9�:�	
�"(���)G��&��%�%�%�K���&�
.�� � �U��*0��&�1O��.��-�-�-�

.��(�&����B�C�!'���)G��&��%�%�%�	&�st�;I4�
AI4�I4�+AI4�H5�H$�2'H5�H5�:H5�I4�4/I4�$
H2�.H5�59I1�.I4�0I1�1I4�49J0�/J0c��[RS5 [USS5nUc|[U5=(d SR	5nSU;a?[UR5=(a URR	5U;UlOSUlURn[URURUR4USLaSOSUR5nUSLaDURS	5 URS
5SUR!URS35S
3$URS5 [#U5 [USS5=(d SnURS5 [%U5=(d SnURS5 ['U5 [USS5nURS5 [)U5 URS5 [+U5 [USS5=(d Sn[-U5R/5R	5S:XaUR1SS5nOUR3U5nURS5 [5U5 [USS5=(d Sn[USS5=(d SR/5R	5S;aUR1SU5nOUR1S U5nURS
5SUR7S!U5SUR7S"U5SUR7S#Ub[-U5OS5S$UR9S%5S[US&S5=(d S'S$UR9S(5SUS$UR9S)5SU3$![a SUlGNf=f![a) [R;S*5 UR=S+5s$f=f),NzBuilding 'Email' sectionrrgrwTFrIr�zExternal email configuredz## Email Summaryrz( does not utilize this server for email.zZ
MX records route mail delivery to an external provider, so local mail checks are skipped.zDetermining outbound mail IPr�r:z
PTR lookupzNo PTR foundzCounting accountsrzMeasuring disk usagezChecking bounces/defersr�
r�
z"no bounce or defer data collected.rjzDetecting spam protectionr�
r�
r
)rgr�rTzOutbound Mail IPzReverse DNS (PTR)zNumber of Email Accountsr8z%### Highest Email Account Disk Usage:r\
rJ
z#### Bounce Back and Deferral Count:z### Spam Protection:zFailed to build 'Email' sectionz�[Error] Failed to build email section. Check email accounts, disk usage, bounces and defers, and spam protection manually. Please report this as a bug.)r6r:r+r�rqr�r�rrr�r�r�r�r�r�r�rQr�r4
r:
rc
r�
rUr�r-rMr�
rCr6rIrU)	r��local_email_flag�	dns_lowerr�r��ptr_display�email_account_count�bounces_summary�spam_summarys	         r �mail_build_sectionr�
{#s���
�L�L�+�,��v�}�d�;����		&�%�f�-�3��:�:�<�I��y� �%)�&�*?�*?�%@�&��)�)�/�/�1�Y�>��"�&*��"�"�-�-��&����	�	�	�v�4�4�5��%�'��Q����	��G
��u�$��!�!�"=�>��(�(�);�<�=�R��&�&�&�*?�*?�)@�@h�'i�j�k�ll�l�
�	���<�=��F���&�)�T�2�?�i�����l�+��f�o�7������1�2��6�"�%�f�.@�$�G�����4�5��V�$����7�8��v�&��F�2�D�9�
4�3�	�

�� �&�&�(�.�.�0�3�
4�%�0�0��=��O�%�5�5�o�F�O����9�:��F�#��F�5�t�<�
.�-�	�

�F�-�t�4�:��
�%�'�%�%�'��.�"�-�-�g�|�D�L�!�-�-�e�\�B�L��$�$�%7�8�9���(�(�);�W�E�F�b��(�(�)<�k�J�K�2��(�(�)C�bu�cB�c�J]�F^�HQ�S�T�TX��'�'�(O�P�Q�QS��v�3�T�:�]�>]�^�^b��'�'�(M�N�O�r���t��'�'�(>�?�@���n�	
�	
��A�	&�!%�F��	&��Z�
����:�;��"�"�
+�
�	
�
�s2�A&N�N�"AN�+IN�N�N�0O
�O
c�.�[R"/SQSS9nURS:XaSUl[RS5 gSUl[RS5 g![a'nSUl[RSU5 SnAgSnAff=f)	N)�	systemctl�	is-active�--quietzmonarx-agent.serviceF�r1rTz Monarx agent service is running.z$Monarx agent service is NOT running.z(Failed to check Monarx agent service: %s)r�rCr&rr6r�rr
)r�rHr=s   r �
get_monarxr�
�#s���
D����I��
������!� $�F���K�K�:�;� %�F���K�K�>�?���D�!������?��C�C��D�s�AA#�A#�#
B�-B�Bc�J�/SQnSnUH\n[R"SSSU/SS9nURS:Xa[R	SU5 S	nMF[RS
U5 M^ X lg![a'nSUl[RSU5 SnAgSnAff=f)N)zimunify360-webshield.servicezimunify360-pam.servicez!imunify-auditd-log-reader.serviceFr�
r�
r�
r�
rzImunify service %s is running.Tz"Imunify service %s is not running.z'Failed to check Imunify360 services: %s)	r�rCr&r6r�r:rrr
)r�r*�any_runningr#rHr=s      r �get_imunifyr�
�#s���C�
�����G��^�^��k�9�g�>�e��F�� � �A�%����<�g�F�"�����A�7�K� �)����C�"������>��B�B��C�s�A.A1�1
B"�;B�B"c	�X^�S[S[4SjmS/S/S/S/S/S	S
//SQS/S
.n/nUR5H2up4[U4SjU55(dM!UR	U5 M4 X l[RSU(aSRU55 U$S5 U$)zo
- Controllers: csf, apf, ufw, firewalld
- Backends:    nftables, iptables
- Related:     imunify360, fail2ban
�	unit_namer*c��[R"SSSU/SS9RS:H$![a [RSUSS	9 gf=f)
Nr�
r�
r�
Fr�
rz"systemctl check failed for unit %sTr�)r�rCr&rr6r:)r�
s r �systemd_is_active�'get_firewall.<locals>.systemd_is_active$sd��	���� �+�y�)�D����*��	�
���	��L�L�4�i�$�
�
��		�s�%(�A
�	A
�csf�apf�ufw�	firewalld�nftables�iptables�	ip6tables)zimunify360-webshieldzimunify360-pamzimunify-auditd-log-reader�
imunify360z
imunify-agent�imunify360-agent�fail2ban)r�
r�
r�
r�
r�
r�
r�
r�
c3�4># �UH
nT"U5v� M g7fr�r")r��ur�
s  �r r��get_firewall.<locals>.<genexpr>4$s����3�U�� ��#�#�U�s�z+Security layers detected (systemd only): %srgr�)	rUr�r�r�r�rr6r�rp)r��layer_unitsr��layerr�r�
s     @r �get_firewallr�

$s����
�S�
�T�
� �w��w��w�!�]��L���-�
� �L��K�$�H�#�)�)�+����3�U�3�3�3��O�O�E�"�,�%��
�K�K�5�'��	�	�(����O�.4���Or)c��[U[5(aU(aUSOSnU=(d SR5R5nUS;agUS;agU$)Nr�rg)r�	�truer��onT)�no�falser��offF)r�rr�rq)rer��string_values   r �_ssh_parse_boolr�
?$sT���%����"��b�	����K�R�&�&�(�.�.�0�L��1�1���2�2���Nr)c���[R"S5=(d Sn[R"US/S[RSS9n1Skn0nU=(d SR5H�nUR
5(aS	U;aM URSS
5upVUR
5R5nUR
5nXR;a#URU/5RU5 M�XcU'M� U$)N�sshdz/usr/sbin/sshdz-TTrsr�>ru�	denyusers�
allowusers�
denygroups�allowgroups�
listenaddress�authenticationmethodsrgrqrI)rur*r�r�r�rr�r�rq�
setdefaultr�)�	sshd_pathr��
multi_keys�configr�r�res       r �_ssh_get_effective_configr�
J$s������V�$�8�(8�I�
�
$�
$�	�D��
�� � ��	�F��J��F���2�)�)�+���z�z�|�|�s�$����Z�Z��a�(�
���i�i�k���!�����
�������c�2�&�-�-�e�4��3�K�,��Mr)c	�>�URS5n[U[5(aSRU5O
U=(d SnUR	5(d/$UR5Vs/sH$n[
SURS555PM& sn$s snf)Nr�
rqrgc3�n# �UH+oR5(dMUR5v� M- g7fr�)r�r�s  r r��0_ssh_auth_method_alternatives.<locals>.<genexpr>u$s ���D�^�T�z�z�|�L�D�J�J�L�L�^�s�5�5r	)r�r�rrpr�r�r)r�
�
auth_value�auth_stringr�s    r �_ssh_auth_method_alternativesr�
k$s������3�4�J��j�$�'�'�	�������B��
������	��$�$�&��&�C�	�D�S�Y�Y�s�^�D�D�&����s�,+Bc�t�U(dgUH*nSU;=(d [SU55nU(dM* g g)NT�passwordc3�B# �UHoRS5v� M g7f�zkeyboard-interactiveNr	�r��methods  r r��9_ssh_passwords_allowed_by_auth_methods.<locals>.<genexpr>~$� ���8
�DO�&���4�5�5�K�r%Fr{)�alternatives�alternative�has_passwords   r �&_ssh_passwords_allowed_by_auth_methodsr�
z$sD����#��!�[�0�
�C�8
�DO�8
�5
���<��$�r)c��U(dgSnSnUH6nSU;=(d [SU55nU(dM*SnSU;dM4SnM8 U=(a U$)NFTr�
c3�B# �UHoRS5v� M g7fr�
r	r�
s  r r��-_ssh_passwords_require_key.<locals>.<genexpr>�$r�
r%�	publickeyr{)r�
�saw_password�requires_key_everywherer�
r�
s     r �_ssh_passwords_require_keyr�
�$sh�����L�"��#��!�[�0�
�C�8
�DO�8
�5
���<��L��+�-�*/�'�$��3�3�3r)c��URS5=(d SR5nSSSSSS.nURXR55nX3S:g4$)N�permitrootlogin�prohibit-passwordr�r�zKey-onlyzKey-only (forced commands))r�
r�	zwithout-passwordr�
zforced-commands-only)r�rqr%)r�
�prl_raw�prl_mapr�s    r �_ssh_root_access_moder�
�$s]���z�z�+�,�C�0C�J�J�L�G���&�'� <��G����G�%7�%7�%9�:�I��J�.�/�/r)c�Z�[URS5S5n[URS5=(d URS5S5n[URS5S5nU=(a Un[U5n[U5n[	U5nU=(d U=(a UnX�4$)N�passwordauthenticationT�kbdinteractiveauthentication�challengeresponseauthenticationF�usepam)r�
r�r�
r�
r�
)	r�
�password_auth_enabled�keyboard_interactive_enabled�use_pam�password_via_keyboardr�
�passwords_allowed_by_amr�r�s	         r �_ssh_password_login_stater�
�$s���+��
�
�+�,�d���$3��
�
�1�2�	9��:�:�7�8�
�$� �
�f�j�j��2�D�9�G�8�D�W��0��8�L�D����7�|�D���6�!6�"�
!���5�5r)c���[URS5=(d S5n[URS5=(d S5n[U5nXU4$![a SnNf=f)N�maxauthtries�6�maxsessions�10)rUr�rSr)r�
r�r�r�s    r �_ssh_limitsr�
�$sd������N�3�:�s�;�N��v�z�z�-�0�8�D�9�L����'�	��l�2�2�����	��s�A�A&�%A&c�T�URS5=(d S/n[U[5(aU/O
[U5n[	U5up4[URS5S5n[
U5upg[U5up�n
[URS5S5nUUUUUUUU	U
US.
$)Nru�22�pubkeyauthenticationT�permitemptypasswordsF)
r�r�r�r�r�r�r�r�r�r�)r�r�rUrr�
r�
r�
r�
)r�
�ports_valuer�r�r�r�r�r�r�r�r�r�s            r �_ssh_analyze_configr�$s����*�*�V�$�.���K�'��S�9�9�[�M�t�K�?P�E�3�F�;��I�(��
�
�)�*�D���2K��2�.��/:�&�.A�+�N�|�-��
�
�)�*�E���
��$�0�2�!6�(��$�#:��r)c�*�[5n[U5nUR
U5$![a) [RS5 UR	S5s$f=f![a) [RS5 UR	S5s$f=f)Nz1Failed to read effective SSH config via `sshd -T`z*Unable to read effective SSH configurationz Failed to summarize SSH settingsz Unable to summarize SSH settings)r�
rr6rIrUrr�)r��effective_configr�s   r �get_ssh_settingsr�$s���G�	�8�:��'�'7�8���(�(��2�2���	����C�
��&�&�<��
�		���G����;�<��"�"�#E�F�F�G�s,�
)�A�0A�A�A�A�0B�Bc��[R"SSU=(d SR5[RS9R	S5SR5nUnSnURS5(aJUR
S5nUS	:wa2US
UnXS
-SnURS5(a[US
S5nOROQSU;aKURS5S
:Xa6URSS
5upgUR5(a
Un[U5nURS5RS
5nX�4$![a SnN2f=f![a UnX�4$f=f)Nr�rgr�r�ri��[�]r�rIr9r�r�)r[rir�r#r�r�r,rSr�r4rC	r	r�r�r)	r�rx�hostru�bracket_endrx	�	host_part�	port_part�	host_idnas	         r �_ssl_parse_host_portr
�$s[��
�����f�l��%9�%9�%;�2�4�4�H�	��s��A�	�	�����D��D����#����l�l�3�'���"���1�[�)�D��a�� 1�2�I��#�#�C�(�(���y���}�-�D���'�>�g�m�m�C�0�A�5�#*�>�>�#�q�#9� �I�� � �"�"� ���9�~����K�K��'�.�.�w�7�	��?���"���D������	��?���s$�1D6� E�6E�E�E�Erru�verifyc
�P^�S[S[4SjnSmS[RSS4U4SjjnU(aO[R"5nSUl[RUlUR5(dU"U5 O@[R"[R5nSUl[RUlU"U5(aSOUn[R"X4S	S
9nURXvS9nUR5n	U	(aU	sSSS5 sSSS5 $URSS9n
U
(d0sSSS5 sSSS5 $[R"U
5n[ R"R%S
S5n[ R&"USS9 [ R(R+USUSUS35n
[-U
SSS9nUR/U5 SSS5 [R0R3U
5nU=(d 0sSSS5 sSSS5 $!,(df   NK=f![4a6n[6R9SUUU5 0sSnAsSSS5 sSSS5 $SnAff=f!,(df   O=fSSS5 g!,(df   g=f)N�	host_textr*c�R�[R"U5 g![a gf=f)NTF)�	ipaddressr�r�)rs r �
is_ip_address�&_ssl_fetch_cert.<locals>.is_ip_address%s*��	�� � ��+����	��	�s��
&�&c3�~# �[RRS5nU(aUv� SnUHnUv� M	 g7fr�r�)r�r�r�s   r r��+_ssl_fetch_cert.<locals>.candidate_ca_files$%s8����Z�Z�^�^�O�4�
����
�
�
�D��J��r�r�c�>�T"5HRnU(aG[U5R5(a'URUS9 [R	SU5  gMRMT g![
a!n[R	SX5 SnAM}SnAff=f)Nr�z#Loaded CA bundle for TLS verify: %szFailed loading CA bundle %s: %s)rr�r�r6r:r)r�r�r@r�s   �r �load_system_cas�(_ssl_fetch_cert.<locals>.load_system_cas1%s{���(�*�F�
M��d�6�l�2�2�4�4��1�1��1�@��L�L�!F��O��5�6�+���
M����>��L�L��
M�s�A
A � 
B�*B�BTFr�r�)�server_hostname)�binary_form�SPARTA_TMP_DIRz/root/SPARTA_tmpr��sparta_peer_cert_r�z.pemrr-r.z'Failed decoding peer cert for %s:%s: %s)rUr�r��
SSLContextr��check_hostname�
CERT_REQUIRED�verify_moder��PROTOCOL_TLS_CLIENT�	CERT_NONEr��create_connection�wrap_socket�getpeercert�DER_cert_to_PEM_certr3r�r�r�r�rpr1r�_ssl�_test_decode_certrr6r:)rrurrrr�r�sock�
secure_socket�	cert_dict�cert_der�pem_text�temp_dir�	temp_pathr"�decodedr@r�s                 @r �_ssl_fetch_certr2%sO���������M����M�D�M���,�,�.��!%���!�/�/����#�#�%�%��G�$���.�.��!8�!8�9��!&���!�m�m���+�I�6�6�d�I�O�	�	!�	!�9�"3�Q�	?�4�
�
 �
 ��!�
�
�%�1�1�3�I�� �
�
�
@�	?�%�0�0�T�0�B�H���
�
�
@�	?�
��3�3�H�=���:�:�>�>�*:�<N�O�����H�t�4��G�G�L�L�� 1�)��A�d�V�4�H��	��)�S�7�;�v��L�L��*�<��(�(�4�4�Y�?���}�"�$�-
�
�
@�	?�&<�;��
�
����=����	��	�=
�
�
@�	?��0
��/
�
��
�
@�	?�	?�s�-J�=I<�	J�)I<�	J�A=H9�H(�#1H9�	J�(
H6�2H9�9
I9�I4�I9�I<�!	J�4I9�9I<�<
J
	�J�
J%c���[XSS9SS4$![Ra�n[USS5=(d S[USS5=(d S[	U5=(d S/nSSRU5R
5;n[RS	XU5 [XSS9SU4sSnA$SnAf[a.n[RS	XU5 [XSS9SS4sSnA$SnAff=f)
NT)rF�verify_messagerg�reasonrrqz!Verified TLS failed for %s:%s: %s)
r2r��SSLCertVerificationErrorr+rUrprqr6r:r)rrur@�
message_parts�is_self_signed_hints     r �_ssl_get_peer_certr9k%s���K��y�t�<�d�E�I�I���'�'�
��C�)�2�.�4�"��C��2�&�,�"���H�N��
�
�
,�s�x�x�
�/F�/L�/L�/N�N�����8�)�3�O��I�E�:���
�	
��
�K����8�)�3�O��y�u�=�t�U�J�J��K�s-��C(�BB-�'C(�-
C(�:#C#�C(�#C(c��URS5=(d /nUH1nUH(up4U=(d SR5S;dM$Us s $ M3 UH1nUH(up4U=(d SR5S;dM$Us s $ M3 g)N�issuerrg)�organizationname�o)�
commonname�cn)r�rq)�	cert_data�issuer_list�rdnr�res     r �_ssl_get_issuer_orgrC�%s~���-�-��)�/�R�K����J�C��	�r� � �"�&?�?��������J�C��	�r� � �"�&:�:�����r)c��URS5=(d /nURS5=(d /n[U=(a
 U=(a X:H5$![a n[R	SU5 SnAgSnAff=f)Nr;�subjectzBFailed to compare subject and issuer for self-signed detection: %sF)r�r�rr6r:)r@rA�subject_listr@s    r �_ssl_is_self_signedrG�%ss���-�-��)�/�R�K��=�=��+�1�r�L�	���H�L�H�[�-H�
�	
�������P��	
����s�A�
A?�A:�:A?c� �URS5nU(dgURSS5n[RR	US5R[R
RS9n[RR[R
R5n[X4-
RS5nURS5UUR54$![a n[RS	U5 SnAgSnAff=f)
N�notAfter)NNNz GMTz UTCz%b %d %H:%M:%S %Y UTC)�tzinforz%Y-%m-%d %H:%M:%S UTCzFailed to parse expiration: %s)r�rJr�r�rh
�timezone�utcr�rRr�r��	isoformatrr6r:)r@�raw_expiresr�
expiration_dtr�rr@s       r �_ssl_parse_expirationrP�%s����-�-�
�+�K��� �"�*�*�6�6�:�����,�,��1�
�
�'������'�
)�	��k�k�o�o�b�k�k�o�o�.���m�1�7�7��;���"�"�#:�;���#�#�%�
�	
��
� ����5�s�;��� �s�CC#�#
D
�-D�D
c�l�[USS5=(d SR5nU(dSUlURS5$[	U5up#[X#5upEnSUl[U=(d [U55n[U5n	[U5n
URXXX�5 UR!S5SUR#XX53UR!S	5SUR%X�53UR!S
5SUR'U
53/nSR)U5$![a@n[RSUUU5 SUlSUl	UR5sSnA$SnAff=f![a0 [R+S5 SUlURS
5s$f=f)Nr�rgzstatus: no domain providedz/TLS handshake failed (unverified) for %s:%s: %sFTrurqr;�expiresrz Failed to summarize SSL settingsz Unable to summarize SSL settings)r+r�rrUr
r9rr6r
rr�r�rGrCrPrr�rr
rrprI)r�r�rrur@r�self_signed_hint�unverified_excrr	rr�s            r �get_sslrU�%s���,G��&�"2�B�7�=�2�D�D�F���!�F�N��&�&�'C�D�D�.�v�6��	�
	5�7I��8�4�I�$4�����+�M�/B�9�/M�N��(��3�
�/�	�:���'�'��j�	
�
����)�*�!�F�,B�,B�;�,\�+]�^�����)�*�!�F�,B�,B�;�,[�+\�]����	�*�+�1�V�-D�-D�_�-U�,V�W�
��
�y�y�����5�		5��L�L�A����	
�#�F�N�!&�F���2�2�4�4��		5��8�G����;�<�����"�"�#E�F�F�G�sI�AE9�
E9�D,�!C
E9�,
E6�65E1�+E6�,E9�1E6�6E9�97F3�2F3c��^�[RS5 Sn[TRTRTR
4UTR5nSU4SjjnU4SjnURS5 [T5 URS5 [T5 URS5 [T5 URS5 [T5nURS	5 [T5nU"S
[[TSS555nU"S
[[TSS555nU"[TSS5=(d /5n	TRS5STR!S5SUSUSU	STR!S5STR#U5STR!S5STR#U53$![$a+ [R'S5 Sn
TR)U
5s$f=f)NzBuilding 'Security' sectionr)c�>�TRSTRSUS355nU(aTRSU5OTRSU5nUSU3$)Nr;r0r9rjrTrqr1)r>r��
detected_text�missing_textr�rer�s      �r �_colored_status_line�4security_build_section.<locals>._colored_status_line�%sm����"�"��V�'�'��:�,�a�0@�A�
��
�
���w�
�6��#�#�E�<�8�	�
���%��!�!r)c��>�TRSTRSS55nU(a&USTRSSRU553$USTRSS53$)	Nr;r0z	Firewall:rqrjrgrTzNo firewall detected)r-rp)�firewall_itemsr�r�s  �r �_colored_firewall_line�6security_build_section.<locals>._colored_firewall_line�%sr����"�"��V�'�'���<�
����W�A�f�0�0��$�)�)�N�:S�T�U�V�V����&�,�,�U�4J�K�L�M�Mr)zChecking Monarx agentzChecking Imunify agentzDetecting firewall stackzReading SSH configzSummarizing SSL�MonarxrF�Imunifyrrz## Security Summaryr8z### Anti-Malwarerz### SSHz### SSLz+Failed to build 'Security Insights' sectionz�[Error] Failed to build security section. Check for Monarx, Imunify, Firewall, SSH, and SSL settings manually. Please report this as a bug.)r�zNot Detected)r6r:r�r�r�r�r�r�r�
r�
r�
rrUr�r+r�r6rMrrIrU)r�r�r�rZr^�ssh_settings_summary�ssl_summary�monarx_line�imunify_line�
firewall_liner�s`          r �security_build_sectionrg�%s���
�L�L�.�/�
�E�&����	�	�	�v�4�4�5�
����	��!�#�	"� N�,/����5�6��6�����6�7��F�����8�9��V�����2�3�/��7�����/�0��f�o��*��d�7�6�<��?�@�
��,��t�G�F�M�5�A�B�
��/��F�,�d�3�9�r�
�
�
�$�$�%:�;�<�D��'�'�(:�;�<�B��m�2��n�B��o�T��'�'�	�2�3�2��&�&�';�<�=�T��'�'�	�2�3�2��&�&�{�3�4�
6�
	
���/����F�G�
F�	��"�"�:�.�.�
/�s�"EF:�:2G/�.G/r�r�r�)�lshttpd�	litespeed�lsws�haproxyr��hitch�nghttpx)r<r=�	LiteSpeed�HAProxy�Varnish�Hitchrm�tomcat)�node�nodejs�pm2�gunicorn�supervisord�monit�docker�podman)�Tomcat�NodeJS�Gunicorn�Supervisord�Monit�Docker�Podman)rpr�	r�	�
postgresqlzpostgresql-�mongod�mongodb�
opensearch�
elasticsearch�redis�	memcached�rabbitmq)zMySQL / MariaDB�
PostgreSQL�MongoDB�
OpenSearch�
Elasticsearch�Redis�	Memcached�RabbitMQ�named�pdnsz
pdns-recursor)zBIND (named)zPowerDNS AuthoritativezPowerDNS Recursorr�
r�
�lfdr�
r�
r�
�clamdz
clamav-daemon�	freshclamr�
r�
�	imunifyavzimunify-antivirus�auditd)
�Fail2Ban�CSFr�
r�
r�
z
ClamAV DaemonzClamAV Freshclam�
Imunify360�	ImunifyAVr��
node_exporter�
prometheus�grafana�netdata)z
Node Exporter�
Prometheus�Grafana�Netdata)zWeb ServerszApplication RuntimeszDatabases and SearchzMail and DNSzSecurity and Firewall�
Monitoringc�(�[R"SS/SS9nUR5H@nSUS3U;dM[R"SU5nU(dM/URS5s $ g![a [RS	U5 gf=f)
N�ssz-ltnpTr�r9rqzusers:\(\("([^"]+)",pid=(\d+),rIz Failed to get service on port %s)	r�r�rr[r�rvrr6rI)rur�r�rus    r r�r�l&s���C��(�(�$���t�D���%�%�'�D��4�&��{�d�"��	�	�"C�T�J���5� �;�;�q�>�)�(����C����;�T�B��C�s"�2A.�A.�A.�+A.�. B�Bc��[5n[R"/SQSUS9nUR5HKnUR	5nU(dMUSRS5(dM7UR
US5 MM [R"/SQSUS9nUR5HKnUR	5nU(dMUSRS5(dM7UR
US5 MM U$![a [RSSS9 N�f=f![a [RS	SS9 U$f=f)
N)r�
zlist-unit-files�--type=service�--no-legend�
--no-pagerTr�r�.servicez systemctl list-unit-files failedr�)r�
z
list-unitsr�z--allr�r�zsystemctl list-units failed)
rr�r�rr�rsr$rr6r:)rCr��unit_files_textr�r/�list_units_texts      r �_systemd_list_service_unitsr�}&s6���E�E�H�$�1�1�
��#�

��)�3�3�5�I��O�O�%�E��u��q��*�*�:�6�6��	�	�%��(�#�6�C�$�1�1�
��#�
��)�3�3�5�I��O�O�%�E��u��q��*�*�:�6�6��	�	�%��(�#�6��L��/�H����7�$��G�H��(�C����2�T��B��L�C�s=�AC=�C=�+C=�AD!�D!�#D!�=D�D�!E�Ec��[R"SSUSS/SU[RS9n0nUR	5H?nSU;aMURSS	5upVUR
5X5R
5'MA URS
S5nURSS5nURS
S5n	US:Xag1Skn
US:XagUS:XagUS:XagUS;aX�;aggU=(d S$![a gf=f)Nr�
�showz.--property=LoadState,ActiveState,UnitFileStater�Tr�rr�rI�	LoadStaterg�ActiveState�
UnitFileStatez	not-found�
not-installed>�bad�masked�static�invalidr��indirect�	generated�	transientrirr)�deactivatingrrr)r�r�rDrrr�r�r�)r�
rC�show_output�
key_valuesr�r�re�
load_state�active_state�unit_file_state�
disabled_likes           r �_systemd_state_forr��&s#��� �-�-����@��
��#��%�%�
���J� �+�+�-�	��i����_�_�S�!�,�
��"'�+�+�-�
�9�9�;��	.�����R�0�J��>�>�-��4�L� �n�n�_�b�9�O��[� ��	�M��x����x����|�#���3�3��+�(���$�9�$��M����s�*C/�/
C<�;C<c�z�[5nUH�nURS5(aX0;aURU5 M1URSS5n[R
"SUS35nUH,nURU5(dMURU5 M. M� [U5$![a M�f=f)Nr�r
z.*�^�$)	rrsr$rJr[r\rrur�)�	all_unitsr��
matched_unitsr��	sanitized�
regex_patternr�
s       r �_systemd_find_units_by_patternsr��&s����E�M������J�'�'�G�,@����g�&���O�O�C��.�	�	��J�J�!�I�;�a�'8�9�M�#�I��"�"�9�-�-��!�!�)�,�#���-� � ���	��	�s�B,�,
B:�9B:c�T�/nUHnUR[U5U45 M! U$r�)r�r�)�units_to_prober7r�
s   r �_systemd_probe_unitsr��&s-���H�#�	����+�I�6�	�B�C�$��Or)c��[n[SS9n0nUR5GHupE[R	SU5 0nUR5H�upx[X(5n	[
U	=(d U5n
[SU
55(aSnO�[SU
55(aSnOj[SU
55(aS	nOP[S
U
55(aSnO6[SU
55(aS
nO[SU
55(aSnOSnUU	=(d US.Xg'M� XcU'GM X0lUR$)NrsrGzChecking category: %sc3�0# �UHoSS:Hv� M g7f)rriNr"�r�rus  r r��)get_installed_services.<locals>.<genexpr>'s���@�x�V�!�9��(�x���ric3�0# �UHoSS:Hv� M g7f)rrNr"r�s  r r�r�
's���B��v�A�Y�(�*��r�rc3�0# �UHoSS:Hv� M g7f)rrNr"r�s  r r�r�'s���F�X�6�A�Y�,�.�X�r�rc3�0# �UHoSS:Hv� M g7f)rrNr"r�s  r r�r�'s���D�8��A�Y�*�,�8�r�rc3�0# �UHoSS:Hv� M g7f)rrNr"r�s  r r�r�'s���O�h�F�A�Y�"7�7�h�r�rc3�0# �UHoSS:Hv� M g7f)rr�Nr"r�s  r r�r�'s���I��f�A�Y�/�1��r�r�r)r r�)	�SERVICE_CATEGORIESr�r�r6r:r�r�r�r)r��
categoriesr�r��categoryr*�category_resultsr,r�r�r7r s            r �get_installed_servicesr��&s-��#�J�+�B�?�I��G�(�.�.�0������,�h�7���'/�~�~�'7�#�M�;�I�P�M�+�M�,E�X�F�H��@�x�@�@�@� ���B��B�B�B� ���F�X�F�F�F�$���D�8�D�D�D�"���O�h�O�O�O�-���I��I�I�I�'��!���&�2�(�/��+�'(8�0-���91�<!(���$�$�$r)c���0n[R"/SQSS[RS9n/nUR5HJnUR	5nU(dMUSnURS5(dM9UR
U5 ML 0n[R5HEnUR5H.up�URU	[55RU
5 M0 MG UR5H}up�/nUHBnURS5(aUSSOUnU
Hn
X�;dM
UR
U5  M@ MD U(dMXSR[[U555X'M U(aUO/UlU(dgS
RSUR555$![a"n[ R#S	U5 0nSnANeSnAff=f)N�r�
z--failedr�r�Tr)r�rr�i����rgz#Failed to query failed services: %src3�8# �UHupSUSUS3v� M g7f)r!r3rNr")r��friendlyr�s   r r��$get_service_stats.<locals>.<genexpr>U's(����:�O�H�
�X�J�b���q�!�:�r�)r�r�rDrr�rsr�r�r|r�r�
rr�rpr�rr6r:r)r��failed_services_map�systemctl_output�failed_service_unitsr�rwr�
�friendly_to_patternsr*r,r�r��base_unit_namer�r@s               r �get_service_statsr�"'s�����*!�%�2�2�B����%�%�	
�� "��$�/�/�1�D��j�j�l�G��w�#�A�J�	��%�%�j�1�1�(�/�/�	�:�2� "��*�1�1�3�H�+3�>�>�+;�'�
�$�/�/�
�s�u�E�L�L���,<�4�(<�'A�'A�'C�#�M��M�1�	�!�)�)�*�5�5��c�r�N�"��
 (�G��0�%�,�,�Y�7�� (�
2��}�59�Y�Y��3�}�-�.�6�#�2�(D�*5H�0�R�F�����9�9��2�8�8�:������!����:�C�@� ���!�s1�AF9�F9�6B5F9�/F9�)F9�9
G%�G � G%c�L�[R"USU[RS9$)NTr�r�)rBrCs  r �
_svc_run_textr�['s'���"�"��
���!�!�	�r)c��[/SQSS9nUR5HmnUR5nU(aURS5(aM2URS5(dMJUR	SS5SR5s $ [RRS5(ag	g
![
a N2f=f)N)zsystemd-analyzez
cat-configzsystemd/journald.confr�rG)rO�;zStorage=r�rIz/var/log/journalzpersistent (inferred)zvolatile (inferred))	r�rr�r�r�rr3r�r+)�
journald_confr�r�s   r �_svc_get_journald_storage_moder�d's���
�%�F��
�
�"�,�,�.�D��z�z�|�H��x�2�2�:�>�>���"�"�:�.�.��~�~�c�1�-�a�0�6�6�8�8�/�
�w�w�}�}�'�(�(�&� ���
��
�s�A"B5�($B5�
B5�5
C�Cc���[USS/SS9R5nUR5Vs/sHo"R5(dMUPM nn[U5$s snf![a gf=f)Nz--list-bootsr�r�rGr)r�r�rrhr)�journalctl_path�
boots_textr��bootss    r �_svc_get_boot_countr�x'sp���"�
�n�l�;�Q�
�
�%�'�	�#-�"7�"7�"9�J�"9�$�Z�Z�\��"9��J��5�z���K������s(�-A#�A�A�A#�A#�#
A0�/A0c���[/SQSS9nUR5H<nUR5nU(dMUSRS5(dM7USs $ g![a gf=f)Nr�r)rGrr�)r�rr�rsr)�
failed_outputr�rws   r �_svc_get_any_failed_unit_namer��'sv��

�%�B��
�
�"�,�,�.�D��j�j�l�G��w�7�1�:�.�.�z�:�:��q�z�!�/����
���
�s"�4A�A�A�A�
A,�+A,c��U(dg[SSUSS/SS9nUR5nSU;=(d S	U;$![a gf=f)
NFr�
rurnr�r�rGzjournal has been rotatedzlog output is incomplete)r�rqr)r�
�status_text�lower_statuss   r �%_svc_unit_status_has_rotation_warningr��'sf����
�#�
�(�I�t�\�B��
��#�(�(�*��*�l�:�
�&�,�6�	
������s�/:�
A�Ac�L^�ST;aST;agSn[U4SjU55$)Nzsystemd[zsystemd:F)zfailed to startzmain process exitedzentered failed statezfailed with resultz"start request repeated too quicklyzservice hold-off time overzunit entered failed statezstart operation timed outc3�,># �UH	oT;v� M g7fr�r")r�rArps  �r r��/_svc_is_systemd_failure_line.<locals>.<genexpr>�'s����B�/���#�/�rWr{)rp�failure_markerss` r �_svc_is_systemd_failure_liner��'s/�����#�
�*�(D��	�O��B�/�B�B�Br)c���U=(d SR5R5nSU;aSnOSn/nU=(d SR5R5nURS5(aURS5 [	U5nUbUS::aURS5 U(aURS	5 U(aUS
SR
U5S3$U$![
a SnN`f=f)
Nrgzno journal entries returnedz2No journal entries returned for the last 24 hours.z:No historical service failures found in the last 24 hours.�volatilezjournald storage is volatilerIzlimited boot historyzjournal rotation detectedz (Note: rgr)r�rqr�r�rSrrp)	�journald_storage�boots_available�rotation_warning�reason_line�reason_lowerr��notes�storage_text�	boots_ints	         r �_svc_build_no_history_messager	�'s��� �%�2�,�,�.�4�4�6�L�$��4�C��K���E�$�*��1�1�3�9�9�;�L����z�*�*�
���3�4����(�	����a��
���+�,��
���0�1����x��	�	�%� 0�1��3�3��K�����	��s�C!�!C0�/C0c
��[USSSSSSS/SS	9$![a n[RS
U5 SnAgSnAff=f)Nz--sincez24 hours agor�z0..4z-n�800r��rGzjournalctl query failed: %srg)r�rr6r:)r�r@s  r �_svc_try_journal_queryr
�'sZ������������	
��
�	
�������2�C�8����s��
>�9�>c���0n[R5HEnUR5H.up#URU[	55RU5 M0 MG U$r�)r�r|r�r�
rr�)�friendly_patternsr*r,r�s    r �_svc_collect_friendly_patternsr�'sT����&�-�-�/��'/�~�~�'7�#�M��(�(����>�E�E�h�O�(8�0��r)c��^
�[5nUR5VVVs0sH%up#X#Vs/sHoDR5PM sn_M' nnnnUVs0sH	nUS/S._M nnU=(d SR5H�nUR5m
[	T
5(dM%UR5Hgup#[U
4SjU55(dM!XbnUS==S-
ss'[
US5S:a"USRUR55  M� M� UR5VV	s0sHup)U	SS:�dMX)_M sn	n$s snfs snnnfs snfs sn	nf)	Nr)r4r�rgc3�,># �UH	oT;v� M g7fr�r")r�r�rps  �r r��._svc_parse_service_failures.<locals>.<genexpr>(s����A��W�j�(��rWr4rIr�r�)	rr�rqrr�r�rhr�r�)�	logs_textrr,r�r��patterns_lower�service_historyr��bucketr-rps          @r �_svc_parse_service_failuresr�'sm���6�8��(9�'>�'>�'@��'@�#�M�	�x�@�x�G�
�
��x�@�@�'@���/��.�M�	��R�0�0�.���
��b�,�,�.���Z�Z�\�
�+�J�7�7��'5�';�';�'=�#�M��A��A�A�A�(�7���w��1�$���v�g��'�!�+��7�O�*�*�4�:�:�<�8��
(>�/�$3�#8�#8�#:��#:��M���=�1��	�
��#:����-A����
��$s(�E�E�E�E�6E$�	E$�Ec���[R"S5nU(d	0Ulg[5n[	U5n[[
55n[U5nU(d0Ul[UUUS5$[U5nX`lU(d[UUUS5$URU5$![a'n[RSU5 0UlSnAgSnAff=f)N�
journalctlz<Historical failure check unavailable (journalctl not found).z*no journal entries returned for that queryz#no systemd failure patterns matchedz1Failed to collect historical service failures: %s)rur*�service_failure_historyr�r�r�r�r
r	rr7rr6r:)r�r�rrrrr1r@s        r �get_service_failure_historyr(s���(� �,�,�|�4���-/�F�*�N�
�:�;��-�o�>��@�)�+�
��+�?�;�	��-/�F�*�0� �� �<�	�
�6�i�@��)8�&��0� �� �5�	�
��7�7��H�H�������H�#�N�)+��&����s)�%B.�AB.�7%B.�B.�.
C�8C�Cc
��[RS5 Sn[URURUR
4UUR5nURS5 [U5nURU5nURS5 [U5nU(dSnUS:waSOSnURXe5nURS5 [U5nU(dSnURS	5 URS
5SUSURS
5SUSURS5SURU5S3$![ a+ [R#S5 Sn	UR%U	5s$f=f)NzBuilding 'Services' sectionr�zEnumerating installed servicesz Checking current failed servicesr�rTrLz$Checking historical service failureszFinalizing services sectionz## Software Services Summaryz�
Below is a categorized summary of key services detected on the system and their current status.
If a service is missing from the list, it means it was not detected on the server.

rz-Current Failed Services (systemctl --failed):r8z*Historical Service Failures (recent logs):z/Failed to build 'Services and Versions' sectionz�[Error] Failed to build services section. Manually check for installed services and whether they are active, failed, or enabled but not running. Please report this as a bug.)r6r:r�r�r�r�r�r�r�r/r�r-rr�r6rMrrIrU)
r�r�r�r�installed_summary_text�current_failed_summary�current_failed_style�current_failed_block�history_summaryr�s
          r �services_build_sectionr#<(s���
�L�L�.�/�
�E�&����	�	�	�v�4�4�5�
����	��*/����>�?�3�F�;��!'�!A�!A��"
��	���@�A�!2�6�!:��%�%4�"�,��>�E�E�	� &�1�1� � 
��	���D�E�5�f�=���-�O����;�<��$�$�%C�D�E�Fe�&�&�b��'�'�(W�X�Y�Y[�#�$�D��'�'�(T�U�V�VX��&�&��7�8��
<�		
���/����J�K�
l�	��"�"�:�.�.�
/�s�C2E�2E9�8E9c�^^�SnSnSmU4SjnSnSnS[S[4S	jmS
[S[4U4Sjjn[5 [RS5 [	5R5nU"5nU"Xg5up�n
[R
S
USRU	55 [5n[U5 [U5 U"X�5 SU	;a[U5 SU	;a[RS5 U"X�5 U"X�5 UR5nU"U5n
[RR!US-5 [RR!SU
S35 [RR#5 [$R'SS9 [RS5 g![(a [R+S5 gf=f)Nc
��SS[4SS[4SS[4SS[4S	S
[4SS[
4S
S[4SS[44$)NrbzSystem SectionrczAccount and Website SectionrdzTraffic SectionrezPHP SectionrfzDatabase SectionrgzMail SectionrhzSecurity Sectionr*zSoftware Services Section)r�r�rGr�	r
r�
rgr#r"r)r �collect_section_specs�#main.<locals>.collect_section_specsv(sj��
�'�)=�>�
�2�4I�J�
�)�+@�A�
�M�#4�5�
�%�'=�>�
�^�%7�8�
�+�-C�D�
�4�6L�M�	
�		
r)c��^
�UVs/sHo"SPM	 nnUVs1sHn[XS5(dMUiM nnUVs1sHn[USU3S5(dMUiM nnUR=(d U(+nU(a[U5OUnUVs/sHnXH;dM
XF;dMUPM snm
[U
4SjU55n	UT
U	4$s snfs snfs snfs snf)NrFric3�<># �UHoST;dM
Uv� M g7f)rNr")r��spec�chosen_keyss  �r r��8main.<locals>.resolve_chosen_sections.<locals>.<genexpr>�(s���� 
�*�T�1�g��.D�D�D�]�s��	)r+�fullrr�)�parsed_args�
section_specsr*�section_keysr��include_keys�exclude_keys�
run_full_mode�	base_keys�chosen_sectionsr+s          @r �resolve_chosen_sections�%main.<locals>.resolve_chosen_sections�(s���,9�:�M�D�Q��M��:�'�
�'�C�7�;�U�+K�C�<�	�
�
$�
�#���{�c�#��K��7�
�#�	�
�$�(�(�<��,<�
�)6�C��%�L�	�$�
�#����
�$'�$;�
�#�
��
 � 
�*� 
�
���k�?�:�:��);��
��
��
s,�C
�C�C�C�C�	C�#C�*Cc�2^�Sn[U4SjU55$)N)rcrdrergrhc3�,># �UH	oT;v� M g7fr�r")r�rpr+s  �r r��5main.<locals>.needs_domain_context.<locals>.<genexpr>�(s����
�:M�;�;�&�:M�rWr{)r+�domain_context_keyss` r �needs_domain_context�"main.<locals>.needs_domain_context�(s#���L���
�:M�
�
�	
r)c�>^�T"T5(dg[U5 [U5 [U4SjS55nU(a4[USS5=(d SR	5(d[U5 [U4SjS55nU(a6[USS5=(d SR	5(d[
U5 ggg)Nc3�,># �UH	oT;v� M g7fr�r"�r�r�r+s  �r r��7main.<locals>.prepare_domain_context.<locals>.<genexpr>�(s����!
�*E�3�;��*E�rW)rergrhr�rgc3�,># �UH	oT;v� M g7fr�r"r@s  �r r�rA�(s����
�*I�3�;��*I�rW)rgrdrhr�)r�r�r�r+r�r�r�)r�r+�needs_user_context�needs_ip_contextr<s `  �r �prepare_domain_context�$main.<locals>.prepare_domain_context�(s����#�K�0�0���F���6�"� �!
�*E�!
�
��
��V�^�T�:�@�b�G�G�I�I��6�"��
�*I�
�
��
��V�Y��5�;��B�B�D�D����E�
r)c���SU;d[USS5bg[R[5Ul[
R
S5 g![a [
RS5 SUlgf=f)Nrbr�z#[deadweight] background scan queuedr�)	r+r�r�rLr�r6r�rrI)r�r+s  r �queue_deadweight_scan_if_needed�-main.<locals>.queue_deadweight_scan_if_needed�(sf���K�'��v�2�D�9�E��	,�'/���~�'F�F�$��K�K�=�>���	,����I�J�'+�F�$�	,�s�3A�&A4�3A4c��^�[U5Tl[TRS-SSSS9Tl[	USS9H[unup4nUTlUTl[RSU5 TRUS	3U4U4S
jj5nTRU5 M] TRR5 g![[4a!n[RSU5 SnAM�SnAff=f)Nrnz	Building:rgr)rKrLrMrIr�zBuilding section: %s�_build_sectionc�>�U"T5$r�r")�section_funcr�s �r r�,main.<locals>.run_sections.<locals>.<lambda>�(s
���l�6�6Jr)z1Fatal error occurred in SPARTA main execution: %s)rhr�rEr�rzr�r�r6r�r>rS�RuntimeErrorr+rIr�)r�r5r{rp�
section_labelrMrRr�s`       r �run_sections�main.<locals>.run_sections�(s���� #�O� 4���%��!�!�C�'����	
���BK��1�B
�=�E�=�K��$)�F� �"/�F���K�K�.�
�>�	
� �,�,�"�m�>�2�(4�J����"�"�7�+�B
�$	����� ��!�'�*�
�� � �G�����
�s�(-B4�4C%�C � C%r'r*c�b�U(dg[R"S5nURSU5$)Nrgz\x1B\[[0-?]*[ -/]*[@-~])r[r\ri)r'�ansi_escapes  r �
strip_ansi�main.<locals>.strip_ansi�(s(�����j�j�!;�<�����r�4�(�(r)�report_textc�l>�[RR5RS5nSUS3nUS-nT"U5n[R
"SSS9 [
USS	S
9nURUR5S-5 SSS5 [R"X25 U$!,(df   N&=f)Nz%Y_%m_%d_%H%M%Sz/root/server_audit_report.z.mdz.tmpz/rootTr�rr-r.r)
r�r�r�r�r3r�r1rr=rJ)rW�	timestamp�report_pathr0�	file_textr"rUs      �r �write_report_to_file�"main.<locals>.write_report_to_file�(s�����K�K�O�O�%�.�.�/@�A�	�2�9�+�S�A���&�(�	��{�+�	�
���G�d�+�
�)�S�7�
3�v��L�L��)�)�+�d�2�3�4�	�
�
�9�*���	4�
3�s�"#B%�%
B3z === SPARTA Execution Started ===zRun mode: full=%s sections=%sr	rfrbz�Servers with larger than normal disk usage may delay report generation. Please be patient.Use --no-system to skip disk-space usage checks.rz
Report saved to: F)�waitz)=== SPARTA Report Generation Complete ===z.Fatal error occurred in SPARTA main execution.)rUrCr6r�rs�
parse_argsr:rpr�r�r�r�	r�rVrWrXrrr��shutdownrrI)r&r6rErHrQr\rkr/r3r+r5r�rW�report_file_pathr<rUs              @@r �mainrbu(s����

�;�.
� �2,�!�:)��)��)��#��#���O�
�K�K�2�3���(�(�*�D�)�+�M�2I��3�/�M���L�L�'������8M�� K�����f���v���v�3��;��!�&�)��{�"��N�N�C�
�
	(��<��V�-��,�,�.��/��<���
�
����t�+�,��
�
���.�/?�.@��C�D��
�
�������u��%����?�@���K����I�J�K�s�-DF5�5G�G�__main__)r*N)rii )rs)�)Tr))z/root/SPARTA_tmp/)r8)r))r�r�)F)r�(r�rkr�r�rkrr
r8r3r�rur[rur�r�r�rWr5	r�collectionsr�concurrent.futuresr�dataclassesr�pathlibr�typingrrr	�urllibr
rrr�	r�cpapisr�radsr
r�rXrYr*r2�	getLoggerr6�
StreamHandlerrrCrEr�r�rYrsr|r�r�r�r�r�r�rrr@rXrgrqr�r�rrr�r�r�r�r�r�r�rr*rLr�r�r�r�r�r�r�rrrr'r?rDrJrSrZr\rerlrprur�r�r�r�r�r�r�r�r�r�rr	rrrr!r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rr'r0r�r�rr�r~r�rr1rGr\r#r�r�r�r�rUrKrRr�rUrXrdrhrjrtr{r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r	r	r	rS�CompletedProcessr	r	r&	r-	r1	r8	r=	rI	rP	rY	r[	r#ra	rn	r�	r�	r�r�	r�	r�	r�	r�	r
r
rr
r
r/
r�r4
r:
r@
rD
rH
rc
ri
rm
rv
r}
r�
r�
r�
r�
r�
r�
r�
r�
r�
r�
r�
r�
r�
r�
r�
rrr
r2r9rCrGrPrUrgr�r�r�r�r�r�r�r�r�r�r�r�r�r�r	r
rrrr#rbr#r"r)r �<module>rps�	���������	��
�	�
�
�
��
����1�!��&�&�$�������!�,��
�Z�Z�
�
�
 �
�!��	�	�	�8�	$���7�0�0��'�@C$�C$�L)"�)"�Zi	�i	�X�����(�V	H�D
�N�.O9�dQ
�j$�N6�Y�@pK�fX�v/�d�>'�<=�@6,�r��0���
� 	��?�D$H�N.�be,�PD>�NRA�j|,�~u/�rZ5�z���DL�*�
�I�3�l&�R	E��";�|.�$ �c�L��	��8���0 ��.D�!@�Hl�^]$�@N>�b��6�2�&c�Lb�J���(	��;=�.1�b��"4�.�
� 8�	�ZD�zh5�XD!�N	��
���7�e$�P=%�@<�~s�l$�N�4F!�RvL�rp�fb�Jl/�` �Z�Z�4��D�D���!�j�j�8���#%�*�*�2�#���
�
�1���
�C��C���c��$	�c�	�d�	�
�S�
�T�
�K��K�(+�K�
�c�]�K�\�(�3�-��:$�8�C�=�$�N;�8�C�=�;�|�8�C�=��4����#���@B�JX�v
�
���O8�d"�(WF�t"8�J<�~	��	��	����$��>A\�H[J�|2��2��2�
'(�
��
� #�
�� � �
����
��
"�3�
"�D��I�
"�	!��	!���
�	!��C��D��&
��c��
�s�
�.�C��S��X�c�]��6"��6"� �6"�.1�6"�>F�s�m�6"�r?�3�?�8�C�=�?�2���!$��7:����D	
�c�	
�d�	
�'��'�4�'�C�'�4h�VX
�xe1�P�")�J�&,&�^\=�~B�Jf�R./�d�:�:�&>����E��0�fU�p$�N#�LK�\�����
�s�
� �4K�\��� ��03��,
�#�
�3�
�#�
�5��5�"�5�.1�5�4,H��,H��,H��	,H��
,H��,H�^�T��8%�vQ&�ha
�JD�"C�22�j��B�	�
4� 
0�6�03��@G�( �� �FL�s�L�#�L�t�L�^K�#�K�S�K�*
�� �,-G�`O/�j�I�&���5��;��;����;���*�+��L�%�����*��*��:�#�]�3��i�(�#�n�)�*���!�]��L�	�!�	�#)�(�-�.�� �L��u�~�!�]��L��L�!�?�3�(�M�#�%7�8�!�#6�7��*��*�*�#�n��;��;�	�]4��n�")�X4%�n!�(�$%�N6�r�!�(��
� C�"�B�(��@)�X5/�rmK�`�z���F�r)