JFIF$        dd7 

Viewing File: /usr/local/cpanel/scripts/check_immutable_files

#!/usr/local/cpanel/3rdparty/bin/perl

# cpanel - scripts/check_immutable_files           Copyright 2022 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

#
# This is the authorative code used to sync /usr/local/cpanel
# Accept no imitators.
#

use strict;
use warnings;

use Cpanel::Usage           ();
use Cpanel::SafeRun::Errors ();

my $frequency = 10;
my $force     = 0;
my $is_help   = 0;

Cpanel::Usage::wrap_options(
    \@ARGV,
    \&usage,
    {
        'frequency' => \$frequency,
        'force'     => \$force,
        'help'      => \$is_help,
    }
);

my $immutable_file_list = '/var/cpanel/immutable_files';
check_last_usage($immutable_file_list);    # Will exit if not necessary to proceed.

# Instead of just testing the exit code returned the script find-immutable-files
# execution, checking for a "{number} immutable files have been found" output line
# coming back from the script allows us to differentiate two distinct cases of
# non-zero exit code, namely: 1) The script ran and actual immutable files were
# found; 2) the script could not run at all for some reason. At some point we might
# decide that the second of those two is not a reason to hold up execution of the
# update script that calls this script.

my $script = '/usr/local/cpanel/bin/find-immutable-files';
my $n_found;

( my $myname = $0 ) =~ s{.*/}{};
my $consequences = "Script '$myname' will terminate now with non-zero exit code.";

die("\"$script\" is not executable. $consequences") if ( !-x $script );

my $output = Cpanel::SafeRun::Errors::saferunallerrors( 'nice', '-n', '20', $script, $frequency );
die("Unable to run script \"$script\". $consequences") if ( !defined $output );

if ( $output !~ /\b0 immutable files have been found\b/ ) {
    my $foundmatch = qr/\bfound\s+the\s+following\s+files\s+marked\s+as\s+immutable\s+/;

    $output =~ /$foundmatch/
      or die "Script $script could not be run or returned incomplete information. $consequences\n";

    if (
        $output =~ m{
                            ${foundmatch}in\s+the\s+[^\n]*location:\s*\n\n
                            (
                                (
                                    [^\n]+\n
                                )+
                            )
                            \n
                         }xms
    ) {
        $n_found = $1 =~ y/\n//;
    }

    defined $n_found
      or die "Script $script returned incomplete information. $consequences\n";

    die "$n_found immutable files were found on the system. $consequences\n";
}

print "OK: No immutable files were found on the system.\n";
exit 0;

sub check_last_usage {
    my $immutable_file_list = shift or die;

    return if ($force);                        # --force passed on command line.
    return if ( !-e $immutable_file_list );    # Check has never run.
    return if ( -s $immutable_file_list );     # Re-run if files were found on last run.

    # Run if the previous check was less than $frequency days ago
    my $immutable_last_run_days = -M $immutable_file_list;
    return if ( $immutable_last_run_days > $frequency );

    my $interval = round($immutable_last_run_days);
    if ( $interval >= round($frequency) ) {

        # message to user should not say "was last run approx. 10 days ago which is less than 10 days"
        $interval = round( $frequency - 1 );
    }

    if ( $interval <= 0 ) {

        # message to user should not say "was last run approx. 0 days ago"
        $interval = 'less than one day ago';
    }
    elsif ( $interval == 1 ) {
        $interval = 'approximately one day ago';
    }
    else {
        $interval = "approximately $interval days ago";
    }

    print "Not testing for immutable files, because the test was last run $interval (less than $frequency days)\n";
    exit 0;
}

sub round {

    # We could use Math::Round::round(), but tests show that loading that module
    # would consume some 900K memory. Hence the following homegrown solution instead.
    my $num = shift;
    return int( .5 + $num );
}

sub usage {
    print qq{Usage: $0 [options]};
    print qq{

    Options:
      --frequency=N     Do not perform check if we have already done so in past N days; default = 10
      --force           Force a check for immutable files, regardless of how recently it was last done
      --help            Brief help message

};
}

__END__

=head1 NAME

check_immutable_files - checks for immutable files in /usr/local/cpanel, if this has not already been done recently

=head1 USAGE

    # Normally called by maintenance with no flags.
    # file being used to log all other update-related proceses.
    /scripts/check_immutable_files

=head1 DESCRIPTION

When used standalone, you should probably use --verbose, otherwise
it won't appear to do anything.

Will not do anything if it has been invoked in the past 10 days (or
whatever number of days are indicated with the --frequency option),
unless called with --force. --frequency=0 is functionally
equivalent to --force, unless you do something unusual like
changing file mod times into the future.

If the check is run, the exit status will indicate whether immutable
files were found.

    --frequency=N   Do not perform check if we have already done so in past N days; default = 10.

    --force         Force a check for immutable files, regardless of how recently it was last done.

    --help          Print a brief help message
Back to Directory  nL+D550H?Mx ,D"v]qv;6*Zqn)ZP0!1 A "#a$2Qr D8 a Ri[f\mIykIw0cuFcRı?lO7к_f˓[C$殷WF<_W ԣsKcëIzyQy/_LKℂ;C",pFA:/]=H  ~,ls/9ć:[=/#f;)x{ٛEQ )~ =𘙲r*2~ a _V=' kumFD}KYYC)({ *g&f`툪ry`=^cJ.I](*`wq1dđ#̩͑0;H]u搂@:~וKL Nsh}OIR*8:2 !lDJVo(3=M(zȰ+i*NAr6KnSl)!JJӁ* %݉?|D}d5:eP0R;{$X'xF@.ÊB {,WJuQɲRI;9QE琯62fT.DUJ;*cP A\ILNj!J۱+O\͔]ޒS߼Jȧc%ANolՎprULZԛerE2=XDXgVQeӓk yP7U*omQIs,K`)6\G3t?pgjrmۛجwluGtfh9uyP0D;Uڽ"OXlif$)&|ML0Zrm1[HXPlPR0'G=i2N+0e2]]9VTPO׮7h(F*癈'=QVZDF,d߬~TX G[`le69CR(!S2!P <0x<!1AQ "Raq02Br#SCTb ?Ζ"]mH5WR7k.ۛ!}Q~+yԏz|@T20S~Kek *zFf^2X*(@8r?CIuI|֓>^ExLgNUY+{.RѪ τV׸YTD I62'8Y27'\TP.6d&˦@Vqi|8-OΕ]ʔ U=TL8=;6c| !qfF3aů&~$l}'NWUs$Uk^SV:U# 6w++s&r+nڐ{@29 gL u"TÙM=6(^"7r}=6YݾlCuhquympǦ GjhsǜNlɻ}o7#S6aw4!OSrD57%|?x>L |/nD6?/8w#[)L7+6〼T ATg!%5MmZ/c-{1_Je"|^$'O&ޱմTrb$w)R$& N1EtdU3Uȉ1pM"N*(DNyd96.(jQ)X 5cQɎMyW?Q*!R>6=7)Xj5`J]e8%t!+'!1Q5 !1 AQaqё#2"0BRb?Gt^## .llQT $v,,m㵜5ubV =sY+@d{N! dnO<.-B;_wJt6;QJd.Qc%p{ 1,sNDdFHI0ГoXшe黅XۢF:)[FGXƹ/w_cMeD,ʡcc.WDtA$j@:) -# u c1<@ۗ9F)KJ-hpP]_x[qBlbpʖw q"LFGdƶ*s+ډ_Zc"?%t[IP 6J]#=ɺVvvCGsGh1 >)6|ey?Lӣm,4GWUi`]uJVoVDG< SB6ϏQ@ TiUlyOU0kfV~~}SZ@*WUUi##; s/[=!7}"WN]'(L! ~y5g9T̅JkbM' +s:S +B)v@Mj e Cf jE 0Y\QnzG1д~Wo{T9?`Rmyhsy3!HAD]mc1~2LSu7xT;j$`}4->L#vzŏILS ֭T{rjGKC;bpU=-`BsK.SFw4Mq]ZdHS0)tLg