✘✘ GRAYBYTE WORDPRESS FILE MANAGER ✘✘

​🇳​​🇦​​🇲​​🇪♯➤ server.blackpussy.asia ​🇻​♯➤ 5.14.0-611.20.1.el9_7.x86_64 #1 SMP 🇾​♯➤ 2026

𝗛𝗢𝗠𝗘 𝗜𝗗 ♯➤ 163.245.207.76 ♯➤ 𝗔𝗗𝗠𝗜𝗡 𝗜𝗗 216.73.216.243
𝗢𝗣𝗧𝗜𝗢𝗡𝗦 ♯ CRL ♯➤ 𝗢𝗞 ┃ WGT ♯➤ 𝗢𝗞 ┃ SDO ♯➤ 𝗢𝗞 ┃ PKEX ♯➤ 𝗢𝗙𝗙
𝗗𝗘𝗔𝗖𝗧𝗜𝗩𝗔𝗧𝗘𝗗 ♯➤ mail,mb_send_mail
𝗖𝗨𝗥𝗥𝗘𝗡𝗧 𝗙𝗜𝗟𝗘 : /usr/local/cpanel/scripts//migrate_ccs_to_cpdavd
#!/usr/local/cpanel/3rdparty/bin/perl
#                                      Copyright 2025 WebPros International, LLC
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited.

package MigrScr;

# Conversion script from CCS data to CPDAVD

use strict;
no strict 'refs';    # XXX WHY
use warnings;
use DBD::Pg;
use Digest::MD5;
use MIME::Base64;

use Data::Dumper;

use Cpanel::JSON                 ();
use Cpanel::AcctUtils::Lookup    ();
use Cpanel::PwCache              ();
use Cpanel::SafeDir::MK          ();
use Cpanel::DAV::CaldavCarddav   ();
use Cpanel::FileUtils::TouchFile ();
use Cpanel::DAV::Defaults        ();
use Cpanel::DAV::Calendars       ();
use Cpanel::DAV::Tasks           ();
use Cpanel::DAV::AddressBooks    ();

use parent 'Cpanel::HelpfulScript';

sub _OPTIONS {
    return qw(
      help
      overwrite
      dryrun
      verbosity=s
      user=s
    );
}

if ( $> != 0 ) {
    die "This script must be run by the root user\n";
}

#################################################################################################################################
# Set defaults
#################################################################################################################################

my $overwrite_existing = 0;
my $verbosity          = 1;
my $dryrun             = 0;
my $singleuser;

# ++'d every time there is a logmsg with -1 prio
my $errcnt = 0;

# Save any user that has run into an error while writing ( likely an account being over quota ) and will help cut down on futile attempts
my %user_has_write_errors;

exit __PACKAGE__->new(@ARGV)->run() if !caller();

sub run {    ## no critic(Subroutines::ProhibitExcessComplexity)
    my ($self) = @_;
    #################################################################################################################################
    # Get arguments to override the defaults
    #################################################################################################################################

    if ( $self->getopt('overwrite') ) {
        logmsg( 1, "Overwriting existing entry files" );
        $overwrite_existing = 1;
    }
    if ( $self->getopt('dryrun') ) {
        logmsg( 1, "Dry run, no changes will be made anywhere" );
        $dryrun = 1;
    }
    if ( defined( $verbosity = $self->getopt('verbosity') ) ) {
        logmsg( 1, "Setting verbosity to $verbosity" );
    }
    if ( defined( $singleuser = $self->getopt('user') ) ) {
        logmsg( 1, "Only processing the single account: $singleuser" );
    }

    # Map data to a local system and mail user by UIDs
    if ( !-f '/var/cpanel/ccs/ccs-persistance.json' ) {
        logmsg( -1, "This server does not appear to have the file /var/cpanel/ccs/ccs-persistance.json , which is critical for converting from CCS to native CPDAVD." );
        return 1;
    }

    logmsg( 1, "Starting migration from CCS to native CPDAVD" );

    my $pers_data_hr           = Cpanel::JSON::SafeLoadFile('/var/cpanel/ccs/ccs-persistance.json');
    my %pers_data_keyed_on_uid = reverse %{ $pers_data_hr->{'users'} };

    # print "\npers_data_hr:\n" . Dumper( $pers_data_hr );
    # print "\npers_data_keyed_on_uid:\n" . Dumper( \%pers_data_keyed_on_uid );

    #################################################################################################################################
    # Create a hash that contains all the important known information about the accounts, keyed on CCS UID
    #################################################################################################################################

    # This hash is our main mapping for account (email or system), the system user that owns the account, and the home directory for the system user.
    # These are used quite often so it makes sense to build this once.
    my %user_lookup;

    # Now we have all users known to CCS, both their CCS-UID and the associated user, either a system account or an email address
    foreach my $uid ( keys %pers_data_keyed_on_uid ) {
        my $sysuser = eval { Cpanel::AcctUtils::Lookup::get_system_user( $pers_data_keyed_on_uid{$uid} ) };

        #     next if( $singleuser && $singleuser ne $sysuser );
        if ($@) {

            # Not fatal, but we should warn about it
            logmsg( 1, "Could not determine sysuser for $pers_data_keyed_on_uid{$uid}, skipping old user" );
        }
        else {
            logmsg( 4, "$uid is  $pers_data_keyed_on_uid{$uid}  on the system account: $sysuser" );
            $user_lookup{$uid}{'acct'}       = $pers_data_keyed_on_uid{$uid};
            $user_lookup{$uid}{'sysuser'}    = $sysuser;
            $user_lookup{$uid}{'syshomedir'} = Cpanel::PwCache::gethomedir($sysuser);

            # Ensure each user has a calendar and addressbook, metadata included
            logmsg( 4, "Ensuring $pers_data_keyed_on_uid{$uid} has default calendar, task list, and address book configured" );
            eval { Cpanel::DAV::Defaults::create_calendar( $pers_data_keyed_on_uid{$uid} ); };
            eval { Cpanel::DAV::Defaults::create_task( $pers_data_keyed_on_uid{$uid} ); };
            eval { Cpanel::DAV::Defaults::create_addressbook( $pers_data_keyed_on_uid{$uid} ); };
        }
    }

    #################################################################################################################################
    #################################################################################################################################
    #
    # This section handles writing out the CCS UID->user %user_lookup mapping per system user, for "translation" by clients already
    # configured for CCS
    #
    #################################################################################################################################
    #################################################################################################################################

    # Get an array of UIDs, sorted by the system user from the %user_lookup hash. We do this for the sake of efficiency to avoid
    # a lot of extra file IO
    my @sorted_uids = sort { $user_lookup{$a}{'sysuser'} cmp $user_lookup{$b}{'sysuser'} } keys %user_lookup;

    my $last_sysuser;
    my $last_uid;
    my %data;
    logmsg( 4, "Going through sorted list of UIDs to write out the user mapping" );
    foreach my $uid (@sorted_uids) {
        logmsg( 4, "Processing UID $uid" );
        if ( !$last_sysuser ) {
            $last_sysuser = $user_lookup{$uid}{'sysuser'};
            $last_uid     = $uid;
            $data{$uid}   = $user_lookup{$uid}{'acct'};
        }
        if ( $last_sysuser eq $user_lookup{$uid}{'sysuser'} ) {
            $data{$uid} = $user_lookup{$uid}{'acct'};
        }
        else {
            # We have moved on to a new user, so load the data for the user we were just working with, merge it with the new data, then
            # write out the UID map, then start processing this new user
            my $full_dir_path = $user_lookup{$last_uid}{'syshomedir'} . '/.caldav/';
            my $file          = '.user_id_table';
            my $map_hr        = load_uid_mapping( $full_dir_path . $file );
            my $total_hr      = { %{$map_hr}, %data };
            my $map_str;
            foreach my $k ( keys %{$total_hr} ) {
                $map_str .= "$k $total_hr->{$k}\n";
            }

            # Ensure 0600 perms when creating this file so we don't leak email addresses
            # This will be something like /home/user/.caldav/.user_id_table
            write_data_to_file( 1, $user_lookup{$last_uid}{'acct'}, $user_lookup{$last_uid}{'sysuser'}, $full_dir_path, $file, $map_str );

            # Reset %data et al for new user
            $last_sysuser = $user_lookup{$uid}{'sysuser'};
            $last_uid     = $uid;
            %data         = ();
            $data{$uid}   = $user_lookup{$uid}{'acct'};
        }
    }

    #################################################################################################################################
    # Connect to CCS pgsql database
    #################################################################################################################################

    our $ccs_pg_socket_dir = '/opt/cpanel-ccs/data/Data/Database/psqlsocks';

    my $dbh = DBI->connect( "dbi:Pg:dbname=caldav;host=$ccs_pg_socket_dir", 'caldav', undef, { 'RaiseError' => 1 } );
    if ( !$dbh ) {

        # This is a non-starter
        my $errstr = "Couldn't connect to Postgres" . ( $DBI::errstr ? ': ' . $DBI::errstr : '' );
        logmsg( 2, $errstr );
        die $errstr;
    }

    #################################################################################################################################
    #################################################################################################################################
    #
    # This section handles dumping the delegation information from CCS to the native delegation system
    #
    #################################################################################################################################
    #################################################################################################################################

    my $query_delegation_string = 'SELECT delegator, delegate, read_write FROM delegates';
    my $del_ary_ref             = $dbh->selectall_arrayref($query_delegation_string);

    foreach my $entry ( @{$del_ary_ref} ) {

        # $delegator and $delegate are UIDs from CCS. $readwrite is 1 for write access, 0 for read (and delegation by it's mere existence)
        my ( $delegator, $delegate, $readwrite ) = @{$entry};
        logmsg( 2, "Found delegation record from $delegator to $delegate , rw = $readwrite" );
        if ( exists( $user_lookup{$delegator} ) ) {
            if ( exists( $user_lookup{$delegate} ) ) {

                # We have matched both owner and delegatee to local accounts
                my $sysuser_delegator = $user_lookup{$delegator}{'sysuser'};
                my $sysuser_delegate  = $user_lookup{$delegate}{'sysuser'};

                if ( defined $singleuser && ( $sysuser_delegator ne $singleuser && $sysuser_delegate ne $singleuser ) ) {
                    logmsg( 3, "Skipping delegation record as it does not involve the account: $singleuser" );
                    next;
                }

                my %collection_data;
                $collection_data{'acct_homedir'} = $user_lookup{$delegator}{'syshomedir'};
                $collection_data{'sys_user'}     = $user_lookup{$delegator}{'sysuser'};
                $collection_data{'root'}         = $user_lookup{$delegator}{'syshomedir'} . '/.caldav/' . $user_lookup{$delegator}{'acct'};
                my $collection_obj = Cpanel::DAV::CaldavCarddav->new(%collection_data);

                # Ensure the directory exists before trying to use it, as the user.
                if ( ( $singleuser && $user_lookup{$delegator}{'sysuser'} ne $singleuser ) && ( !-d $user_lookup{$delegator}{'syshomedir'} . '/.caldav/' ) ) {
                    my $privs_obj = _drop_privs_if_needed($sysuser_delegator);
                    logmsg( 3, "Creating dav directory for $sysuser_delegator $user_lookup{$delegator}{'syshomedir'}/.caldav/" );
                    Cpanel::SafeDir::MK::safemkdir( $user_lookup{$delegator}{'syshomedir'} . '/.caldav/' ) if $dryrun != 1;
                }

                # Get a hash ref of the sharing config for the user
                my $sharing_hr = $collection_obj->load_sharing();

                # Make the changes to the hash ref
                # Using "calendar" until we can figure out how to get the UID for the default calendar at this stage
                my $section_to_update = $user_lookup{$delegator}{'acct'} . ' calendar';    # the space here is the break between two parts of the section header, don't remove it
                my $new_perms         = 'r';
                if ( $readwrite == 1 ) {
                    $new_perms = 'r,w';
                }
                $sharing_hr->{ $user_lookup{$delegator}{'acct'} }{'calendar'}{ $user_lookup{$delegate}{'acct'} } = $new_perms;

                # Save the hashref that includes our changes
                if ( $dryrun != 1 ) {
                    my $privs_obj = _drop_privs_if_needed( $user_lookup{$delegator}{'sysuser'} );
                    $collection_obj->save_sharing($sharing_hr);
                }
            }
            else {
                logmsg( 3, "Could not find an existing user that matches delegate UID $delegate" );
            }
        }
        else {
            logmsg( 3, "Could not find an existing user that matches delegator UID $delegator" );
        }
    }

    #################################################################################################################################
    #################################################################################################################################
    #
    # This section handles migrating the caldav/carddav data to the correct places on the filesystem
    #
    #################################################################################################################################
    #################################################################################################################################

    # Since CCS only supported 1 calendar and 1 addressbook, we can migrate those events to a default calendar and addressbook for cpdavd
    # ideally we keep the UID mappings the same ? Another option could be to create the dir by UID and symlink default_* to the UID dir.

    # Run query/queries needed to get all the info needed for dumping the data

    # Process addressbook data
    my $query_addressbook_object_string = 'SELECT resource_name,vcard_text,vcard_uid,owner_uid FROM addressbook_object INNER JOIN addressbook_home ON addressbook_home.resource_id = addressbook_object.addressbook_home_resource_id';
    my $card_ar                         = $dbh->selectall_arrayref($query_addressbook_object_string);

    foreach my $entry ( @{$card_ar} ) {
        my ( $file, $data, $uid, $owneruid ) = @{$entry};
        $data =~ s/\015\012|[\015\012]/\n/g;
        my $found_user = 0;
        if ( exists $user_lookup{$owneruid}{'acct'} ) {
            $found_user = 1;
            my $user          = $user_lookup{$owneruid}{'acct'};
            my $sysuser       = $user_lookup{$owneruid}{'sysuser'};
            my $user_homedir  = $user_lookup{$owneruid}{'syshomedir'};
            my $full_dir_path = $user_homedir . '/.caldav/' . $user . '/addressbook/';
            logmsg( 4, "Calling function to save addressbook entry for $user to ${full_dir_path}${file}" );

            # HBHB TODO - note that the $file might not always be .vcf, some are .vcard , so we need to decide whether to change the file extension
            # on all files here, or handle non-.vcf file extensions elsewhere.
            write_data_to_file( $found_user, $user, $sysuser, $full_dir_path, $file, $data );

        }
        else {
            if ($singleuser) {
                logmsg( 3, "Not saving homeless entry due to use of --user=$singleuser" );
                next;
            }
            logmsg( 3, "Could not determine owner ($owneruid) of addressbook entry: $file" );

            # Save to catch-all
            write_data_to_file( $found_user, 'root', 'root', undef, $file, $data );
        }

    }

    # Generate a map of the collection properties so we can retain the displayname, calendar-color and calendar-order for the .metadata

    my %resource_property_map;
    my $query_tasks_object_string = "SELECT resource_id,value FROM resource_property;";
    my $resprops_ar               = $dbh->selectall_arrayref($query_tasks_object_string);
    foreach my $entry ( @{$resprops_ar} ) {
        my ( $resource_id, $value ) = @{$entry};
        if ( $value =~ m/\<calendar-order\ .+\>(\d+)\<\/calendar-order\>/ ) {
            $resource_property_map{$resource_id}{'calendar-order'} = $1;
        }
        elsif ( $value =~ m/\<calendar-color\ .+\>(.+)\<\/calendar-color\>/ ) {
            $resource_property_map{$resource_id}{'calendar-color'} = $1;
        }
        elsif ( $value =~ m/\<calendar-description\ .+\>(.+)\<\/calendar-description\>/ ) {
            $resource_property_map{$resource_id}{'calendar-description'} = $1;
        }
        elsif ( $value =~ m/\<displayname\ .+\>(.+)\<\/displayname\>/ ) {
            $resource_property_map{$resource_id}{'displayname'} = $1;
        }
    }

    # Process calendar data
    # We are mapping this with the following understanding:
    # calendar_bind.calendar_resource_id = calendar_object.calendar_resource_id
    # calendar_bind.calendar_home_resource_id = calendar_home.resource_id
    # calendar_home.resource_id -> calendar_home.owner_uid
    # The LEFT JOIN to get the attachment_id is so we don't skip records without the match
    # We aggregate the various attachment data as json, as this allows us to process each event as a single row from the query

    my $query_calendar_object_string = 'SELECT
                                        calendar_home.owner_uid,
                                        icalendar_text,
                                        icalendar_type,
                                        organizer,
                                        calendar_resource_name,
                                        resource_name,
                                        calendar_bind.calendar_resource_id,
                                        calendar_bind.calendar_resource_name,
                                        json_agg(attachment_calendar_object.attachment_id) AS attachment_ids,
                                        json_agg(attachment_calendar_object.managed_id) AS managed_ids,
                                        json_agg(attachment.path) AS attachment_paths,
                                        json_agg(attachment.content_type) AS content_types
                                    FROM calendar_home
                                    INNER JOIN calendar_bind
                                        ON calendar_home.resource_id = calendar_bind.calendar_home_resource_id
                                    INNER JOIN calendar_object
                                        ON calendar_object.calendar_resource_id = calendar_bind.calendar_resource_id
                                    LEFT JOIN attachment_calendar_object
                                        ON calendar_object.resource_id = attachment_calendar_object.calendar_object_resource_id
                                    LEFT JOIN attachment
                                        ON attachment_calendar_object.attachment_id = attachment.attachment_id
                                    GROUP BY
                                        calendar_home.owner_uid,
                                        icalendar_text,
                                        icalendar_type,
                                        organizer,
                                        calendar_resource_name,
                                        resource_name,
                                        calendar_bind.calendar_resource_id,
                                        calendar_bind.calendar_resource_name;
                                    ';
    my $cal_ar = $dbh->selectall_arrayref($query_calendar_object_string);

    foreach my $entry ( @{$cal_ar} ) {

        my ( $owner_uid, $data, $type, $organizer, $cal_type, $file, $collection_id, $collection_internal_name, $attachment_ids_json, $managed_ids_json, $attachment_filenames_json, $attachment_mimetypes_json ) = @{$entry};

        # Assign a catch-all for unknown / unhandled event types
        # Note that using a name like "default_calendar" rather than the UID it has been using breaks the link with existing caldav configurations, so we should
        # probably find the actual UID of the collection and mark it as default, then handle the default_calendar/default_addressbook path in cpdavd instead, or
        # just name set the displayname of the UID dir to default in the metadata.
        my $collection_type = '';
        my $entry_type_dir  = '.unknown';
        if ( $type eq 'VEVENT' ) {
            $entry_type_dir  = 'calendar';
            $collection_type = 'calendar';
        }
        elsif ( $type eq 'VTODO' ) {
            $entry_type_dir  = 'tasks';
            $collection_type = 'tasks';
        }
        elsif ( $type eq 'VCARD' ) {    # we shouldn't ever see this, but it's a field in the db, sooo
            $entry_type_dir  = 'addressbook';
            $collection_type = 'addressbook';
            logmsg( 2, "Found a VCARD entry while looking for calendar data? File($file) data($data)" );
        }
        my $protected = 0;

        if ( length($collection_id) && $collection_id =~ m/^\d+$/ && length($collection_internal_name) ) {

            # if the internal name for a calendar is "calendar", we keep that as the default for the new "calendar", otherwise we append the collection_id to keep collections unique
            if ( length($collection_internal_name) and $collection_internal_name ne $entry_type_dir ) {
                $entry_type_dir .= '-' . $collection_internal_name;
            }
            else {
                $protected = 1;
            }
        }

        $data =~ s/\015\012|[\015\012]/\n/g;
        my $found_user = 0;
        my $user       = '-';
        my $sysuser    = '-';
        my $full_dir_path;

        if ( exists( $user_lookup{$owner_uid}{'acct'} ) ) {
            $found_user = 1;
            $user       = $user_lookup{$owner_uid}{'acct'};
            $sysuser    = $user_lookup{$owner_uid}{'sysuser'};

            # Set the directory to write the file to the correct place in the user's homedir
            my $user_homedir = $user_lookup{$owner_uid}{'syshomedir'};
            $full_dir_path = $user_homedir . '/.caldav/' . $user . '/' . $entry_type_dir . '/';
            logmsg( 3, "Owner for this record is $user" );
        }
        else {
            logmsg( 3, "Falling back to parsing event data to find owner" );
            my @data_lines = split( /\n/, $data );
            foreach my $line (@data_lines) {
                chomp($line);
                if ( $line =~ m/^X\-CALENDARSERVER\-PERUSER\-UID\:(.+)/ ) {
                    my $data_uid = $1;
                    chomp($data_uid);
                    if ( exists( $user_lookup{$data_uid}{'acct'} ) ) {
                        $found_user = 1;
                        $user       = $user_lookup{$data_uid}{'acct'};
                        $sysuser    = $user_lookup{$data_uid}{'sysuser'};

                        # Set the directory to write the file to the correct place in the user's homedir
                        my $user_homedir = $user_lookup{$data_uid}{'syshomedir'};
                        $full_dir_path = $user_homedir . '/.caldav/' . $user . '/' . $entry_type_dir . '/';

                        logmsg( 3, "Owner for this record is $user" );
                        last;
                    }
                    else {
                        logmsg( 3, "Could not determine owner from /var/cpanel/ccs/ccs-persistance.json by X-CALENDARSERVER-PERUSER-UID ($data_uid) in entry data." );
                    }
                    last;
                }
            }
        }

        if ( !$user_has_write_errors{$sysuser} ) {

            # Create the collection if not already there, only needed for accounts we can map
            if ( length($full_dir_path) && !-d $full_dir_path ) {

                # The only real problem with a failure in these evals is the collection doesn't get metadata written, but the data should still be written to the directory
                if ( length($user) and $user ne '-' ) {
                    local $@;

                    # Set defaults for things that might not have a value in the db to be defined already but needed for each collection type during creation,
                    # then attempt to create the collection

                    if ( $collection_type eq 'calendar' ) {
                        $resource_property_map{$collection_id}{'displayname'}    //= 'Calendar (migrated)';
                        $resource_property_map{$collection_id}{'calendar-color'} //= Cpanel::DAV::Defaults::CPANEL_ORANGE;    # '#ff6c2c';
                        logmsg( 2, "Creating calendar $resource_property_map{$collection_id}{'displayname'} for $user" );
                        eval { my @ret = Cpanel::DAV::Calendars::create_calendar( $user, $entry_type_dir, $resource_property_map{$collection_id}{'displayname'}, $resource_property_map{$collection_id}{'calendar-color'}, $protected ); };
                        if ($@) { logmsg( -1, $@ ); }
                    }
                    elsif ( $collection_type eq 'tasks' ) {
                        $resource_property_map{$collection_id}{'displayname'}    //= 'Task List (migrated)';
                        $resource_property_map{$collection_id}{'calendar-color'} //= Cpanel::DAV::Defaults::CPANEL_ORANGE;    # '#ff6c2c';
                        logmsg( 2, "Creating tasks $resource_property_map{$collection_id}{'displayname'} for $user" );
                        eval { Cpanel::DAV::Tasks::create_task( $user, $entry_type_dir, $resource_property_map{$collection_id}{'displayname'}, $resource_property_map{$collection_id}{'calendar-color'}, $protected ); };
                        if ($@) { logmsg( -1, $@ ); }
                    }
                    elsif ( $collection_type eq 'addressbook' ) {
                        $resource_property_map{$collection_id}{'displayname'}          //= 'Addressbook (migrated)';
                        $resource_property_map{$collection_id}{'calendar-description'} //= 'Addressbook';
                        logmsg( 2, "Creating addressbook $resource_property_map{$collection_id}{'displayname'} for $user" );
                        eval { Cpanel::DAV::AddressBooks::create_addressbook( $user, $entry_type_dir, $resource_property_map{$collection_id}{'displayname'}, $resource_property_map{$collection_id}{'calendar-description'}, $protected ); };
                        if ($@) { logmsg( -1, $@ ); }
                    }
                }
            }

            # Write the event data out to its new file
            write_data_to_file( $found_user, $user, $sysuser, $full_dir_path, $file, $data );

            # If we have attachment data, process it so it stays linked with the event
            if ( $attachment_ids_json ne '[null]' ) {
                if ( !defined $full_dir_path ) {
                    logmsg( 3, "No full_dir_path found, saving to /var/cpanel/saved_dav/" );
                    $full_dir_path = '/var/cpanel/saved_dav/';
                    $sysuser       = 'root';
                }
                logmsg( 9, "Calling migrate_attachment with ( $user, $sysuser, $full_dir_path, $file, $managed_ids_json, $attachment_ids_json, $attachment_filenames_json, $attachment_mimetypes_json )\n" );
                migrate_attachment( $user, $sysuser, $full_dir_path, $file, $managed_ids_json, $attachment_ids_json, $attachment_filenames_json, $attachment_mimetypes_json );
            }
        }
    }

    #################################################################################################################################
    #################################################################################################################################
    #
    # End of processing. From here we just let anyone watching know that it's done.
    #
    #################################################################################################################################
    #################################################################################################################################

    logmsg( 1, "Migration from CCS to native CPDAVD complete" );
    Cpanel::FileUtils::TouchFile::touchfile('/var/cpanel/migrate_ccs_to_cpdavd.done');
    if ($errcnt) {
        my $errors_string = $errcnt > 1 ? 'errors' : 'error';
        logmsg( 1, "The migration detected $errcnt $errors_string while processing. Run this script with a higher verbosity (--verbosity=9) to see more details." );
        if ( scalar( keys %user_has_write_errors ) ) {
            logmsg( 1, "The following users had errors during write operations. Please ensure users are not over quota and the disk is not full :" );
            foreach my $user ( keys %user_has_write_errors ) {
                logmsg( 1, " - $user had write errors : " );
                foreach my $error ( @{ $user_has_write_errors{$user}{'errors'} } ) {
                    logmsg( 1, "   - $error" );
                }
            }
        }
    }

    return 0;
}

#################################################################################################################################
#################################################################################################################################

# TODO - maybe send managed_id and attachment_id to write_data_to_file, or just build this out a little more with all the same data and priv dropping ?
sub migrate_attachment {    ##no critic(Subroutines::ProhibitExcessComplexity Subroutines::ProhibitManyArgs)
    my ( $user, $sysuser, $full_dir_path, $file, $managed_ids_json, $attachment_ids_json, $attachment_filenames_json, $attachment_mimetypes_json ) = @_;

    my $managed_ids_ar          = Cpanel::JSON::Load($managed_ids_json);
    my $attachment_ids_ar       = Cpanel::JSON::Load($attachment_ids_json);
    my $attachment_filenames_ar = Cpanel::JSON::Load($attachment_filenames_json);
    my $attachment_mimetypes_ar = Cpanel::JSON::Load($attachment_mimetypes_json);

    my $path = $full_dir_path . $file;
    my @cleaned_ics;

    # Read in the existing file, strip ICS of previous ATTACH lines since they won't make sense with new backend
    if ( open( my $dav_fh, '<', $path ) ) {
        my @dav_lines = (<$dav_fh>);
        close($dav_fh);

        # Remove existing attach line(s), if present
        my $inside_attach = 0;
        foreach my $line (@dav_lines) {
            chomp $line;
            logmsg( 9, "[ Inside ATTACH: $inside_attach ] LINE($line)" );
            if ( $line =~ m/^\s+/ ) {
                logmsg( 9, " - started with space" );
                if ( $inside_attach == 1 ) {
                    logmsg( 9, " - line started with space and we are inside the ATTACH block, dropping it" );

                    # skip
                }
                else {
                    # This is not part of the folded ATTACH line we want to remove
                    logmsg( 9, " - line started with space, but keeping since it is not inside the ATTACH block" );
                    push( @cleaned_ics, $line . "\n" );
                }
            }
            elsif ( $line =~ m/^ATTACH\;/ ) {
                logmsg( 9, " - found start of the ATTACH line" );
                $inside_attach = 1;
            }
            else {
                logmsg( 9, " - line is not the ATTACH line or a starting space line after it, keeping it" );
                $inside_attach = 0;
                push( @cleaned_ics, $line . "\n" );
            }
        }
    }
    else {
        logmsg( -1, "migrate_attachment: can not read from $path : $!" );
    }

    # At this point, we have the ATTACH-less version of the .ics file in memory in @cleaned_ics
    # Now we walk through each attachment, copy the old attachments to their new home, and once it's all done, add our new
    # ATTACH lines to @cleaned_ics and overwrite the original .ics
    my @final_attach_lines;

    my $cnt = @{$managed_ids_ar};
    for ( my $i = 0; $i < $cnt; $i++ ) {
        my $managed_id          = @{$managed_ids_ar}[$i];
        my $attachment_id       = @{$attachment_ids_ar}[$i];
        my $attachment_filename = @{$attachment_filenames_ar}[$i];
        my $attachment_mimetype = @{$attachment_mimetypes_ar}[$i];

        my $hexed_atid          = Digest::MD5::md5_hex($attachment_id);
        my $first_sub_dir       = substr( $hexed_atid, 0, 2 );
        my $second_sub_dir      = substr( $hexed_atid, 2, 2 );
        my $old_attachment_path = '/opt/cpanel-ccs/data/Data/Attachments/' . $first_sub_dir . '/' . $second_sub_dir . '/' . $hexed_atid;
        my $base64filename      = MIME::Base64::encode_base64( $attachment_filename, '' );
        logmsg( 9, "migrate_attachment: original attachment path is $old_attachment_path" );

        # Make sure we can find the source at the expected location, if so, copy it to the new home
        if ( -f $old_attachment_path ) {
            my $attachment_destination_path = $full_dir_path . $file . '-attachment-' . $managed_id . '-' . $base64filename;
            logmsg( 2, "migrate_attachment: Migrating attachment from $old_attachment_path to normal path for event $attachment_destination_path" );
            if ( $dryrun == 1 ) {
                logmsg( 2, "migrate_attachment: dryrun in effect, not copying attachment file" );
            }
            else {
                if ( -d $full_dir_path ) {
                    if ( open( my $old_attachment_fh, '<', $old_attachment_path ) ) {
                        my $old_attachment_size = ( stat($old_attachment_path) )[7];

                        # Now that we have opened the old attachment to read from as root, drop to the user to do all the file writing
                        my $privs_obj = _drop_privs_if_needed($sysuser);

                        if ( -e $attachment_destination_path && $overwrite_existing != 1 ) {
                            logmsg( 2, "migrate_attachment: Not overwriting attachment file $attachment_destination_path since it already exists. Call with --overwrite if needed" );
                            next;
                        }

                        # Quota handling is not as reliable/up-to-date as we want for this, so rather than relying on a perfectly working quota
                        # system, instead we just try to catch errors during writing and move along to the next attachment which might be smaller.
                        my $error_writing_attachment = 0;
                        if ( open( my $new_attachment_fh, '>', $attachment_destination_path ) ) {
                            while (<$old_attachment_fh>) {
                                last if $error_writing_attachment;    # if we get an error, stop trying to write
                                local $! = undef;
                                print $new_attachment_fh $_;
                                if ($!) {
                                    $error_writing_attachment = 1;
                                    push( @{ $user_has_write_errors{$sysuser}{'errors'} }, $! );
                                    logmsg( -1, "migrate_attachment: Got error while writing data to new attachment file: $!" );
                                    logmsg( -1, " - the original path is $old_attachment_path and should moved to $attachment_destination_path" );
                                }
                            }
                            close($new_attachment_fh);
                        }
                        else {
                            $error_writing_attachment = 1;
                            logmsg( -1, "migrate_attachment: Could not open new attachment for writing: $!" );
                        }
                        close($old_attachment_fh);

                        if ( $error_writing_attachment == 1 ) {
                            logmsg( -1, "migrate_attachment: Skipping attachment migration due to fatal errors, this will result in the attachment being removed from the related event." );
                            return;
                        }

                        if ( !length($user) || $user eq '-' ) {
                            logmsg( -1, "migrate_attachment: No user associated with this attachment, skipping URL fix." );
                            return;
                        }

                        my $new_attachment_size = ( stat($attachment_destination_path) )[7];
                        logmsg( 4, "migrate_attachment: Original attachment size = $old_attachment_size , new attachment size = $new_attachment_size" );
                        if ( $old_attachment_size == $new_attachment_size ) {

                            # Normally we build this based on the request, but we don't have that here, so we use the email domain instead. Attachments are only for calendar events for the default/single CCS calendar.
                            my ( $luser, $domain ) = split( /\@/, $user );
                            my $url = 'https://' . $domain . ':2080/principals/' . $user . '/calendar/' . $file . '-attachment-' . $managed_id . '-' . $base64filename;
                            logmsg( 9, "migrate_attachment: URL($url)" );
                            my $attach_line = "ATTACH;FILENAME=$attachment_filename;FMTTYPE=$attachment_mimetype;SIZE=$new_attachment_size;MANAGED-ID=$managed_id:$url";

                            # Ensure we fold the attach line before 75 bytes
                            my $chunks_ar = Cpanel::DAV::CaldavCarddav::fold_string( $attach_line, 74 );
                            $attach_line = join( "\n", @{$chunks_ar} ) . "\n";
                            logmsg( 9, "migrate_attachment: ATTACH line after folding:\n$attach_line" );
                            push( @final_attach_lines, $attach_line );

                        }
                        else {
                            logmsg( -1, "migrate_attachment: Original attachment size not the same as the new attachment size, assuming quota or disk issue and skipping." );
                            return;
                        }
                    }
                    else {
                        logmsg( -1, "migrate_attachment: Could not open $old_attachment_path for reading" );
                        return;
                    }

                }
                else {
                    logmsg( -1, "migrate_attachment: No directory found at $full_dir_path, skipping attachment migration $old_attachment_path" );
                }
            }
        }
        else {
            logmsg( -1, "migrate_attachment: Could not find attachment at expected path, $old_attachment_path : $!" );
        }

        logmsg( 9, "#############################################################\n" . Dumper( \@cleaned_ics, \@final_attach_lines ) );

        logmsg( 2, "migrate_attachment: Attachment migrated." );
    }

    # Modify the cleaned ICS data and insert the new attach line(s)
    my $index = 0;

    if ( @cleaned_ics == 0 ) {
        logmsg( -1, "migrate_attachment: ics data is empty, likely due to the account being over quota." );
        return;
    }
    if ( !grep m/^BEGIN\:(VEVENT|VCARD)/, @cleaned_ics ) {
        logmsg( -1, "migrate_attachment: could not find the start of the VEVENT in the ics file, assuming corrupted data (@cleaned_ics)" );
        return;
    }
    $index++ until $cleaned_ics[$index] =~ m/^BEGIN\:(VEVENT|VCARD)/;
    if (@final_attach_lines) {
        logmsg( 4, "migrate_attachment: splicing in attach lines at $index (@final_attach_lines)" );
        splice( @cleaned_ics, $index + 1, 0, @final_attach_lines );
    }

    if ( $dryrun == 1 ) {
        logmsg( 2, "migrate_attachment: dryrun in effect, not writing out modified event file" );
    }
    else {
        # Write it back out
        my $privs_obj = _drop_privs_if_needed($sysuser);
        if ( open( my $dav_out_fh, '>:encoding(utf8)', $path ) ) {
            foreach my $line (@cleaned_ics) {
                local $! = undef;
                print $dav_out_fh $line;
                if ($!) {
                    push( @{ $user_has_write_errors{$sysuser}{'errors'} }, $! );
                    logmsg( -1, "migrate_attachment: Could not write cleaned ics to $path : $!" );
                }
            }
            close($dav_out_fh);
            logmsg( 3, "migrate_attachment: wrote modified file to $path" );
        }
        else {
            logmsg( -1, "migrate_attachment: could not open $path for writing : $!" );
        }
    }
    logmsg( 3, "migrate_attachment: Event file updated with new ATTACH lines." );

    return;
}

# This handles writing calendar and addressbook data to the correct location, or to a catch-all location
sub write_data_to_file {    ## no critic qw(Subroutines::ProhibitManyArgs)
    my ( $found_user, $user, $sysuser, $full_dir_path, $file, $data ) = @_;
    if ( defined $user_has_write_errors{$sysuser} ) {
        logmsg( 5, "Skipping write attempt for $sysuser to $file due to previous write errors" );
        return;
    }

    my $privs_obj;    # Be sure to keep this in scope as long as privs need to be dropped

    if ( $found_user == 1 ) {

        # Now we need to get the user information
        logmsg( 3, "Considering writing to file $file for $user ($sysuser)" );

        if ( defined $singleuser && ( $singleuser ne $user && $singleuser ne $sysuser ) ) {
            logmsg( 3, "Skipping $sysuser due to --user=$singleuser argument" );
            return;
        }

        # Drop privs to user, make needed directories and write files securely
        $privs_obj = _drop_privs_if_needed($sysuser);

    }
    else {
        # If we get here, it means we found an entry but can not match it to a currently existing user.
        # This is more than likely abandoned data from terminated users, but we want to save it just in case the UIDs got unsynced.
        # We save the data in a catch-all location for manual recovery later, so it can simply be copied into the correct place.
        # We do not drop privs here, using a static full_dir_path where we can safely save homeless entries and only root can read it.
        # There is a technical possibility for the UIDs to conflict, but so improbable it is not a concern.
        if ($singleuser) {
            logmsg( 3, "Skipping saving of homeless entry due to --user=$singleuser argument" );
            return;
        }

        $full_dir_path = '/var/cpanel/saved_dav/';
        logmsg( 1, "Entry can not be mapped to existing user, saving to ${full_dir_path}${file}" );
    }

    # Ensure the directory exists for the files to be written to
    if ( !-d $full_dir_path ) {
        logmsg( 3, "Need to make directory $full_dir_path" );
        if ( $dryrun != 1 ) {
            Cpanel::SafeDir::MK::safemkdir($full_dir_path);
        }
        else {
            logmsg( 3, "Dry run in effect, normally would be creating the directory $full_dir_path" );
        }
    }

    # Write the content to the file, given correct conditions are met
    my $full_path = $full_dir_path . $file;
    if ( -f $full_path && $overwrite_existing != 1 ) {
        logmsg( 3, "The path $full_path already exists. To overwrite, call this script with the --overwrite argument" );
        return;
    }
    if ( $dryrun != 1 ) {
        my $orig_umask = umask(0077);
        if ( open( my $fh, '>:encoding(utf8)', $full_path ) ) {
            logmsg( 2, "Writing entry data to $full_path" );
            local $! = undef;
            print $fh $data;
            if ($!) {
                push( @{ $user_has_write_errors{$sysuser}{'errors'} }, $! );
                logmsg( -1, "Error writing data to $full_path : $!" );
            }
            close($fh);
        }
        else {
            logmsg( -1, "Could not open $full_path for writing: $!" );

            # Consider dumping it elsewhere ?
        }
        umask($orig_umask);
    }
    else {
        logmsg( 2, "Dry run in effect, normally would be writing entry data to $full_path" );
    }
    return;
}

#################################################################################################################################
# Misc functions
#################################################################################################################################

# Log output based on verbosity setting and importance of message. Big Errors should always be -1 and are reported to STDERR explicitly
sub logmsg {
    my ( $verb, $msg ) = @_;
    my $xinfo = '[' . $$ . '] [' . scalar( localtime( time() ) ) . '] ';

    # If requested to be totally silent with --verbosity=0 , respect it as much as possible.
    return if ( defined($verbosity) && $verbosity == 0 );

    # Print regular messages to STDOUT, error message ( $verb = -1 ) to STDERR and append "ERROR: " to it to make it clear that this
    # the message is more than just informational or a warning
    my $extra = '';
    my $fh    = *STDOUT;
    if ( $verb < 0 ) {
        $errcnt++;
        $extra = 'ERROR: ';
        $fh    = *STDERR;
    }
    if ( $extra || ( defined($verbosity) && $verb <= $verbosity ) ) {    # Always report Big Errors
        print $fh "${xinfo}${extra}${msg}\n";
    }
    return;
}

# Logger from Cpanel::DAV::CaldavCarddav to handle direct 1:1 copies of the functions we use from there
sub dbg {
    my ( $pkg, $file, $line, $sub, $hasargs ) = caller();
    my @args = @_;

    if ( $verbosity >= 4 ) {
        $file =~ s/^\/usr\/local\/cpanel\///;

        print '[' . $$ . '] [' . scalar( localtime( time() ) ) . "] [$file : $line ]: ";
        foreach my $what (@args) {
            my $ref = ref $what;
            my $nl  = '\n';
            if ( $ref eq 'HASH' ) {
                print "(ref=$ref)\n" . Dumper($what);
            }
            else {
                print Dumper($what);
            }
        }
    }
    return;
}

# Loads the UID > username mapping into a hash ref. We use this data for translating CCS style URL requests to the native format.
sub load_uid_mapping {
    my ($path) = @_;
    logmsg( 5, "Loading UID mapping from $path" );
    my %map;
    if ( open( my $fh, '<', $path ) ) {
        while (<$fh>) {
            my ( $uid, $user ) = split( /\s+/, $_ );
            $map{$uid} = $user;
        }
    }
    else {
        logmsg( 5, "Could not load UID mapping from $path: $!" );
    }
    return \%map;
}

# Same function as used in a few other scripts to drop privs if requested user is not root
sub _drop_privs_if_needed {
    my ($user) = @_;
    if ( $> == 0 && $user ne 'root' ) {
        require Cpanel::AccessIds::ReducedPrivileges;
        return Cpanel::AccessIds::ReducedPrivileges->new($user);
    }
    return;
}

__END__

=head1 NAME

scripts/migrate_ccs_to_cpdavd

=head1 SYNOPSIS

Usage:

    /usr/local/cpanel/scripts/migrate_ccs_to_cpdavd <options>

Examples:

    /usr/local/cpanel/scripts/migrate_ccs_to_cpdavd --verbosity=0 --overwrite
    /usr/local/cpanel/scripts/migrate_ccs_to_cpdavd --verbosity=6 --overwrite --user=hibdraco
    /usr/local/cpanel/scripts/migrate_ccs_to_cpdavd --verbosity=3 --dryrun

This script migrates user data from the Calendaring and Contacts plugin to native CPDAVD caldav/carddav.
This requires the CCS Postgres database server to be running.

Available Options:

    --help: You are here.
    --verbosity=#: The default is --verbosity=1 . The higher the number, the more debugging output you get.
    --overwrite: Overwrite any existing files. The default is to not overwrite events.
    --dryrun: Do a dry run of the script. This will not write any changes to the filesystem.
    --user=$user: Only process migration for a single account. If this is a system user account, it will process all of the email accounts under it.
      If the user is an email address, it will only process events for that single user.
      Note that this option prevents saving homeless entries, UID mapping for other users, etc and should only be used for debugging or recovery.

=cut

Current_dir [ 𝗡𝗢𝗧 𝗪𝗥𝗜𝗧𝗘𝗔𝗕𝗟𝗘 ] Document_root [ 𝗪𝗥𝗜𝗧𝗘𝗔𝗕𝗟𝗘 ]

Current_dir [ 𝗡𝗢𝗧 𝗪𝗥𝗜𝗧𝗘𝗔𝗕𝗟𝗘 ] Document_root [ 𝗪𝗥𝗜𝗧𝗘𝗔𝗕𝗟𝗘 ]


[ Back ]
𝗡𝗔𝗠𝗘
𝗦𝗜𝗭𝗘
𝗟𝗔𝗦𝗧 𝗧𝗢𝗨𝗖𝗛
𝗨𝗦𝗘𝗥
𝗦𝗧𝗔𝗧𝗨𝗦
𝗙𝗨𝗡𝗖𝗧𝗜𝗢𝗡𝗦
..
--
12 Sep 2026 4.57 AM
root / wheel
0711
cpan_sandbox
--
16 Jan 2026 9.28 PM
root / root
0755
php_sandbox
--
16 Jan 2026 9.28 PM
root / root
0755
MirrorSearch_pingtest
2.38 KB
9 Feb 2022 6.45 PM
root / root
0755
activesync-invite-reply
1.693 KB
9 Feb 2022 6.45 PM
root / root
0755
add_dns
2.361 KB
9 Feb 2022 6.45 PM
root / root
0755
adddns
2.361 KB
9 Feb 2022 6.45 PM
root / root
0755
addpop
6.082 KB
9 Feb 2022 6.45 PM
root / root
0755
addsystemuser
3.267 KB
9 Feb 2022 6.45 PM
root / root
0755
adduser
0.09 KB
11 Feb 2015 5.35 PM
root / root
0755
agent360.sh
16.029 KB
13 Apr 2026 8.58 PM
root / root
0700
apachelimits
4.307 KB
9 Feb 2022 6.45 PM
root / root
0755
archive_sync_zones
3.049 KB
11 Feb 2025 5.08 AM
root / root
0755
auto-adjust-mysql-limits
1.811 KB
9 Feb 2022 6.45 PM
root / root
0755
autorepair
1.244 KB
9 Feb 2022 6.45 PM
root / root
0755
backup_jobs_helper
10.878 KB
14 Jul 2026 1.33 PM
root / root
0755
backups_clean_metadata_for_missing_backups
1.574 KB
9 Feb 2022 6.45 PM
root / root
0755
backups_create_metadata
15.748 KB
9 Feb 2022 6.45 PM
root / root
0755
backups_list_user_files
4.562 KB
9 Feb 2022 6.45 PM
root / root
0755
balance_linked_node_quotas
2.581 KB
9 Feb 2022 6.45 PM
root / root
0755
biglogcheck
1.688 KB
9 Feb 2022 6.45 PM
root / root
0755
build_bandwidthdb_root_cache_in_background
1.524 KB
9 Feb 2022 6.45 PM
root / root
0755
build_cpnat
3.412 KB
9 Feb 2022 6.45 PM
root / root
0755
build_mail_sni
3.873 KB
28 Jul 2022 12.22 AM
root / root
0755
build_maxemails_config
1.142 KB
9 Feb 2022 6.45 PM
root / root
0755
builddovecotconf
9.638 KB
16 Jan 2026 9.26 PM
root / root
0755
buildeximconf
6.999 KB
11 Feb 2025 5.08 AM
root / root
0755
buildhttpdconf
2.602 KB
9 Feb 2022 6.45 PM
root / root
0755
buildpureftproot
0.526 KB
9 Feb 2022 6.45 PM
root / root
0755
call_pkgacct
2.252 KB
14 Jul 2026 1.33 PM
root / root
0755
ccs-check
4.913 KB
9 Feb 2022 6.45 PM
root / root
0755
check_cpanel_pkgs
10.602 KB
7 Aug 2026 4.57 AM
root / root
0755
check_domain_tls_service_domains.pl
6.681 KB
9 Feb 2022 6.45 PM
root / root
0755
check_immutable_files
5.489 KB
9 Feb 2022 6.45 PM
root / root
0755
check_mail_spamassassin_compiledregexps_body_0
0.183 KB
13 Apr 2016 6.55 PM
root / root
0755
check_maxmem_against_domains_count
3.566 KB
9 Feb 2022 6.45 PM
root / root
0755
check_mount_procfs
2.023 KB
9 Feb 2022 6.45 PM
root / root
0755
check_mysql
5.563 KB
11 Feb 2025 5.08 AM
root / root
0755
check_plugin_pkgs
2.453 KB
11 Feb 2025 5.08 AM
root / root
0755
check_security_advice_changes
8.278 KB
11 Feb 2025 5.08 AM
root / root
0755
check_unmonitored_enabled_services
4.557 KB
28 Jul 2022 12.22 AM
root / root
0755
check_unreliable_resolvers
3.586 KB
9 Feb 2022 6.45 PM
root / root
0755
check_users_my_cnf
6.046 KB
9 Feb 2022 6.45 PM
root / root
0755
check_valid_server_hostname
7.656 KB
28 Jul 2022 12.22 AM
root / root
0755
checkalldomainsmxs
2.404 KB
9 Feb 2022 6.45 PM
root / root
0755
checkbashshell
1.177 KB
9 Feb 2022 6.45 PM
root / root
0755
checkccompiler
1.224 KB
9 Feb 2022 6.45 PM
root / root
0755
checkexim.pl
3.098 KB
9 Feb 2022 6.45 PM
root / root
0755
checklink
1.292 KB
9 Feb 2022 6.45 PM
root / root
0755
checkusers
0.836 KB
9 Feb 2022 6.45 PM
root / root
0755
chkpaths
0.138 KB
11 Feb 2015 5.35 PM
root / root
0755
chpass
0.406 KB
9 Feb 2022 6.45 PM
root / root
0755
ckillall
1.112 KB
9 Feb 2022 6.45 PM
root / root
0755
clean_dead_mailman_locks
2.091 KB
9 Feb 2022 6.45 PM
root / root
0755
clean_up_temp_wheel_users
2.439 KB
9 Feb 2022 6.45 PM
root / root
0755
clean_user_php_sessions
4.761 KB
28 Jul 2022 12.22 AM
root / root
0755
cleandns
13.114 KB
11 Feb 2025 5.08 AM
root / root
0755
cleandns8
0.407 KB
9 Feb 2022 6.45 PM
root / root
0755
cleanmsglog
0.718 KB
11 Feb 2015 5.35 PM
root / root
0755
cleanphpsessions
0.91 KB
9 Feb 2022 6.45 PM
root / root
0755
cleanphpsessions.php
0.643 KB
31 Aug 2022 5.28 PM
root / root
0644
cleanquotas
1.612 KB
9 Feb 2022 6.45 PM
root / root
0755
cleansessions
5.891 KB
11 Feb 2025 5.08 AM
root / root
0755
cleanupinterchange
2.643 KB
9 Feb 2022 6.45 PM
root / root
0755
cleanupmysqlprivs
0.755 KB
25 Feb 2025 4.12 PM
root / root
0755
clear_orphaned_virtfs_mounts
3.56 KB
9 Feb 2022 6.45 PM
root / root
0755
comet_license_registration_sync
1.671 KB
14 Jul 2026 1.33 PM
root / root
0755
comet_protected_item_maintenance
20.782 KB
14 Jul 2026 1.33 PM
root / root
0755
comparecdb
1.524 KB
9 Feb 2022 6.45 PM
root / root
0755
compilers
2.863 KB
9 Feb 2022 6.45 PM
root / root
0755
compilerscheck
0.976 KB
9 Feb 2022 6.45 PM
root / root
0755
configure_firewall_for_cpanel
0.508 KB
9 Feb 2022 6.45 PM
root / root
0755
configure_rh_firewall_for_cpanel
0.508 KB
9 Feb 2022 6.45 PM
root / root
0755
configure_rh_ipv6_firewall_for_cpanel
0.508 KB
9 Feb 2022 6.45 PM
root / root
0755
convert2dovecot
0.666 KB
9 Feb 2022 6.45 PM
root / root
0755
convert_accesshash_to_token
4.073 KB
9 Feb 2022 6.45 PM
root / root
0755
convert_and_migrate_from_legacy_backup
1.97 KB
9 Feb 2022 6.45 PM
root / root
0755
convert_maildir_to_mdbox
1.663 KB
9 Feb 2022 6.45 PM
root / root
0755
convert_mdbox_to_maildir
1.658 KB
9 Feb 2022 6.45 PM
root / root
0755
convert_roundcube_mysql2sqlite
26.121 KB
7 Mar 2025 3.31 PM
root / root
0755
convert_to_dovecot_delivery
4.334 KB
9 Feb 2022 6.45 PM
root / root
0755
convert_whmxfer_to_sqlite
1.464 KB
9 Feb 2022 6.45 PM
root / root
0755
copy_user_mail_as_root
1.251 KB
9 Feb 2022 6.45 PM
root / root
0755
copy_user_mail_as_user
1.343 KB
9 Feb 2022 6.45 PM
root / root
0755
cpan_config
2.803 KB
9 Feb 2022 6.45 PM
root / root
0755
cpanel_initial_install
67.952 KB
11 Jun 2026 4.57 AM
root / root
0755
cpanelsync
28.312 KB
9 Feb 2022 6.45 PM
root / root
0755
cpanelsync_postprocessor
1.618 KB
9 Feb 2022 6.45 PM
root / root
0755
cpanpingtest
0.942 KB
9 Feb 2022 6.45 PM
root / root
0755
cpbackup
44.786 KB
11 Feb 2025 5.08 AM
root / root
0755
cpbackup_transport_file
5.646 KB
28 Jul 2022 12.22 AM
root / root
0755
cpdig
2.814 KB
11 Jun 2026 4.58 AM
root / root
0755
cpfetch
1.229 KB
9 Feb 2022 6.45 PM
root / root
0755
cphulkdblacklist
0.423 KB
9 Feb 2022 6.45 PM
root / root
0755
cphulkdwhitelist
1.305 KB
9 Feb 2022 6.45 PM
root / root
0755
cpservice
2.865 KB
9 Feb 2022 6.45 PM
root / root
0755
cpuser_port_authority
19.292 KB
9 Feb 2022 6.45 PM
root / root
0755
cpuser_service_manager
10.853 KB
28 Jul 2022 12.22 AM
root / root
0755
create_default_featurelist
11.624 KB
10 Sep 2026 4.31 PM
root / root
0700
createacct
30.35 MB
11 Sep 2026 4.57 AM
root / root
0700
custom_backup_destination.pl.sample
5.061 KB
28 Jul 2022 12.22 AM
root / root
0755
custom_backup_destination.pl.skeleton
2.838 KB
9 Feb 2022 6.45 PM
root / root
0755
dcpumon-wrapper
0.83 KB
9 Feb 2022 6.45 PM
root / root
0755
delpop
6.201 KB
9 Feb 2022 6.45 PM
root / root
0755
detect_env_capabilities
0.496 KB
9 Feb 2022 6.45 PM
root / root
0755
disable_prelink
2.774 KB
9 Feb 2022 6.45 PM
root / root
0755
disablefileprotect
2.188 KB
11 Feb 2025 5.08 AM
root / root
0755
distro_changed_hook
1.157 KB
9 Feb 2022 6.45 PM
root / root
0755
dnscluster
4.439 KB
9 Feb 2022 6.45 PM
root / root
0755
dnsqueuecron
1.285 KB
9 Feb 2022 6.45 PM
root / root
0755
dnssec-cluster-keys
3.75 KB
9 Feb 2022 6.45 PM
root / root
0755
dovecot_maintenance
7.658 KB
11 Feb 2025 5.08 AM
root / root
0755
dovecot_set_defaults.pl
0.961 KB
9 Feb 2022 6.45 PM
root / root
0755
dumpcdb
0.846 KB
9 Feb 2022 6.45 PM
root / root
0755
dumpinodes
0.671 KB
9 Feb 2022 6.45 PM
root / root
0755
dumpquotas
0.602 KB
9 Feb 2022 6.45 PM
root / root
0755
dumpstor
0.892 KB
9 Feb 2022 6.45 PM
root / root
0755
ea4_fresh_install
2.636 KB
9 Feb 2022 6.45 PM
root / root
0755
edit_cpanelsync_exclude_list
2.579 KB
9 Feb 2022 6.45 PM
root / root
0755
editquota
3.43 KB
11 Feb 2025 5.08 AM
root / root
0755
email_archive_maintenance
6.152 KB
9 Feb 2022 6.45 PM
root / root
0755
email_hold_maintenance
1.46 KB
9 Feb 2022 6.45 PM
root / root
0755
enable_spf_dkim_globally
8.827 KB
9 Feb 2022 6.45 PM
root / root
0755
enablefileprotect
2.099 KB
9 Feb 2022 6.45 PM
root / root
0755
ensure_autoenabled_features
3.15 MB
18 Aug 2026 4.57 AM
root / root
0700
ensure_conf_dir_crt_key
4.824 KB
9 Feb 2022 6.45 PM
root / root
0755
ensure_cpuser_file_ip
2.549 KB
9 Feb 2022 6.45 PM
root / root
0755
ensure_crontab_permissions
1.075 KB
9 Feb 2022 6.45 PM
root / root
0755
ensure_dovecot_memory_limits_meet_minimum
3.133 KB
9 Feb 2022 6.45 PM
root / root
0755
ensure_hostname_resolves
2.512 KB
1 Apr 2025 10.57 PM
root / root
0755
ensure_includes
0.587 KB
9 Feb 2022 6.45 PM
root / root
0755
ensure_vhost_includes
13.526 KB
9 Feb 2022 6.45 PM
root / root
0755
exim_tidydb
2.965 KB
9 Feb 2022 6.45 PM
root / root
0755
eximconfgen
1.318 KB
9 Feb 2022 6.45 PM
root / root
0755
eximstats_spam_check
0.847 KB
9 Feb 2022 6.45 PM
root / root
0755
expunge_expired_certificates_from_sslstorage
3.563 KB
9 Feb 2022 6.45 PM
root / root
0755
expunge_expired_pkgacct_sessions
0.832 KB
9 Feb 2022 6.45 PM
root / root
0755
expunge_expired_transfer_sessions
1.063 KB
9 Feb 2022 6.45 PM
root / root
0755
fastmail
5.157 KB
9 Feb 2022 6.45 PM
root / root
0755
featuremod
1.924 KB
9 Feb 2022 6.45 PM
root / root
0755
fetchfile
0.412 KB
9 Feb 2022 6.45 PM
root / root
0755
find_and_fix_rpm_issues
6.989 KB
11 Feb 2025 5.08 AM
root / root
0755
find_outdated_services
6.47 KB
11 Jun 2026 4.58 AM
root / root
0755
find_pids_with_inotify_watch_on_path
3.657 KB
9 Feb 2022 6.45 PM
root / root
0755
fix-cpanel-perl
28.43 KB
18 Aug 2026 4.57 AM
root / root
0755
fix-listen-on-localhost
3.941 KB
2 Jun 2026 4.57 AM
root / root
0755
fix-web-vhost-configuration
6.148 KB
9 Feb 2022 6.45 PM
root / root
0755
fix_dns_zone_ttls
1.337 KB
9 Feb 2022 6.45 PM
root / root
0755
fix_innodb_tables
4.052 KB
9 Feb 2022 6.45 PM
root / root
0755
fix_reseller_acls
10.701 KB
16 Jun 2025 1.21 PM
root / root
0755
fixetchosts
4.32 KB
9 Feb 2022 6.45 PM
root / root
0755
fixheaders
0.559 KB
9 Feb 2022 6.45 PM
root / root
0755
fixmailinglistperms
0.984 KB
9 Feb 2022 6.45 PM
root / root
0755
fixmailman
2.094 KB
9 Feb 2022 6.45 PM
root / root
0755
fixnamedviews
1.218 KB
9 Feb 2022 6.45 PM
root / root
0755
fixndc
0.403 KB
9 Feb 2022 6.45 PM
root / root
0755
fixquotas
18.393 KB
11 Feb 2025 5.08 AM
root / root
0755
fixrelayd
1.742 KB
9 Feb 2022 6.45 PM
root / root
0755
fixrndc
16.387 KB
11 Feb 2025 5.08 AM
root / root
0755
fixtar
0.491 KB
9 Feb 2022 6.45 PM
root / root
0755
fixtlsversions
4.703 KB
9 Feb 2022 6.45 PM
root / root
0755
fixvaliases
1.999 KB
9 Feb 2022 6.45 PM
root / root
0755
fixwebalizer
0.943 KB
9 Feb 2022 6.45 PM
root / root
0755
forcelocaldomain
0.874 KB
9 Feb 2022 6.45 PM
root / root
0755
ftpfetch
2.198 KB
6 Dec 2019 5.06 PM
root / root
0755
ftpquotacheck
8.312 KB
9 Feb 2022 6.45 PM
root / root
0755
ftpsfetch
2.359 KB
6 Dec 2019 5.06 PM
root / root
0755
ftpupdate
0.255 KB
10 Jan 2020 7.19 PM
root / root
0755
gather_update_log_stats
4.252 KB
27 Jul 2026 9.43 PM
root / root
0700
gather_update_logs_setupcrontab
5.451 KB
27 Jul 2026 9.43 PM
root / root
0700
gemwrapper
1.741 KB
9 Feb 2022 6.45 PM
root / root
0755
gencrt
6.26 KB
9 Feb 2022 6.45 PM
root / root
0755
generate_account_suspension_include
5.703 KB
9 Feb 2022 6.45 PM
root / root
0755
generate_google_drive_credentials
1.108 KB
9 Feb 2022 6.45 PM
root / root
0755
generate_google_drive_oauth_uri
0.961 KB
9 Feb 2022 6.45 PM
root / root
0755
generate_maildirsize
14.559 KB
2 Jul 2026 4.57 AM
root / root
0755
gensysinfo
1.157 KB
9 Feb 2022 6.45 PM
root / root
0755
get_locale_from_legacy_name_info
1.993 KB
9 Feb 2022 6.45 PM
root / root
0755
getremotecpmove
22.543 KB
1 Sep 2026 4.57 AM
root / root
0755
grpck
1.189 KB
9 Feb 2022 6.45 PM
root / root
0755
hackcheck
3.02 KB
9 Feb 2022 6.45 PM
root / root
0755
hook
1.452 KB
9 Feb 2022 6.45 PM
root / root
0755
httpspamdetect
2.823 KB
11 Jun 2026 4.58 AM
root / root
0755
hulk-unban-ip
4.08 MB
18 Aug 2026 4.57 AM
root / root
0700
import_exim_data
8.392 KB
28 Jul 2022 12.22 AM
root / root
0755
increase_filesystem_limits
0.87 KB
9 Feb 2022 6.45 PM
root / root
0755
initacls
4.987 KB
9 Feb 2022 6.45 PM
root / root
0755
initfpsuexec
0.434 KB
9 Feb 2022 6.45 PM
root / root
0755
initialize_360monitoring
2.758 KB
25 Jun 2026 1.40 PM
root / root
0700
initquotas
19.347 KB
26 Feb 2026 4.57 AM
root / root
0755
initsuexec
4.026 KB
9 Feb 2022 6.45 PM
root / root
0755
install_cpanel_analytics
1.927 KB
2 Dec 2022 4.41 PM
root / root
0755
install_dovecot_fts
1.567 KB
9 Feb 2022 6.45 PM
root / root
0755
install_plugin
2.802 KB
28 Jul 2022 12.22 AM
root / root
0755
install_tuxcare_els_php
1.845 KB
10 Dec 2025 4.21 PM
root / root
0755
installpkg
0.562 KB
9 Feb 2022 6.45 PM
root / root
0755
installpostgres
6.558 KB
12 Sep 2025 1.13 PM
root / root
0755
installsqlite3
1.822 KB
9 Feb 2022 6.45 PM
root / root
0755
ipcheck
3.926 KB
9 Feb 2022 6.45 PM
root / root
0755
ipusage
7.445 KB
9 Feb 2022 6.45 PM
root / root
0755
is_update_available
3.265 KB
20 May 2026 4.57 AM
root / root
0755
isdedicatedip
0.588 KB
9 Feb 2022 6.45 PM
root / root
0755
jetbackup-check
3.688 KB
9 Feb 2022 6.45 PM
root / root
0755
killdns
0.412 KB
9 Feb 2022 6.45 PM
root / root
0755
killdns-dnsadmin
1.152 KB
9 Feb 2022 6.45 PM
root / root
0755
killmysqluserprivs
0.423 KB
9 Feb 2022 6.45 PM
root / root
0755
killmysqlwildcard
1.152 KB
9 Feb 2022 6.45 PM
root / root
0755
killpvhost
0.833 KB
9 Feb 2022 6.45 PM
root / root
0755
killspamkeys
0.915 KB
9 Feb 2022 6.45 PM
root / root
0755
link_3rdparty_binaries
1.241 KB
11 Mar 2022 3.43 PM
root / root
0755
linksubemailtomainacct
3.172 KB
9 Feb 2022 6.45 PM
root / root
0755
listcheck
0.525 KB
9 Feb 2022 6.45 PM
root / root
0755
listsubdomains
1.049 KB
9 Feb 2022 6.45 PM
root / root
0755
litespeed-check
3.859 KB
9 Feb 2022 6.45 PM
root / root
0755
locale_export
5.206 KB
11 Feb 2025 5.08 AM
root / root
0755
locale_import
4.69 KB
29 Jul 2026 4.50 PM
root / root
0755
locale_info
3.99 KB
9 Feb 2022 6.45 PM
root / root
0755
log_retention
21.282 KB
26 Feb 2026 4.57 AM
root / root
0755
logo.dat
0.2 KB
11 Feb 2015 5.35 PM
root / root
0644
magicloader
1.938 KB
9 Feb 2022 6.45 PM
root / root
0755
maildir_converter
6.076 KB
9 Feb 2022 6.45 PM
root / root
0755
mailperm
16.526 KB
11 Feb 2025 5.08 AM
root / root
0755
mailscannerupdate
2.42 KB
9 Feb 2022 6.45 PM
root / root
0755
mainipcheck
9.996 KB
9 Feb 2022 6.45 PM
root / root
0755
maintenance
52.192 KB
7 Aug 2026 4.57 AM
root / root
0755
make_config
0.397 KB
11 Feb 2015 5.35 PM
root / root
0644
make_hostname_unowned
1.161 KB
9 Feb 2022 6.45 PM
root / root
0755
manage_extra_marketing
12.762 KB
10 Sep 2026 4.31 PM
root / root
0700
manage_greylisting
16.327 KB
11 Jun 2026 4.57 AM
root / root
0755
manage_mysql_profiles
16.335 KB
11 Feb 2025 5.08 AM
root / root
0755
mass_change_php_setting
10.648 KB
11 Jun 2026 4.58 AM
root / root
0755
migrate_ccs_to_cpdavd
47.057 KB
11 Feb 2025 5.08 AM
root / root
0755
migrate_local_ini_to_php_ini
7.409 KB
9 Feb 2022 6.45 PM
root / root
0755
migrate_whmtheme_file_to_userdata
2.954 KB
9 Feb 2022 6.45 PM
root / root
0755
mkwwwacctconf
2.329 KB
31 Aug 2022 5.28 PM
root / root
0755
modify_accounts
4.071 KB
11 Feb 2025 5.08 AM
root / root
0755
modify_featurelist
16.164 KB
10 Sep 2026 4.31 PM
root / root
0700
modify_packages
3.639 KB
11 Feb 2025 5.08 AM
root / root
0755
modsec_vendor
15.633 KB
9 Feb 2022 6.45 PM
root / root
0755
mysqlconnectioncheck
6.716 KB
11 Feb 2025 5.08 AM
root / root
0755
mysqlpasswd
4.136 KB
11 Feb 2025 5.08 AM
root / root
0755
named.ca
1.565 KB
11 Feb 2015 5.35 PM
root / root
0644
named.rfc1912.zones
0.756 KB
22 Sep 2017 4.06 PM
root / root
0644
notify_expiring_certificates
9.367 KB
11 Mar 2022 3.43 PM
root / root
0755
notify_expiring_certificates_on_linked_nodes
1.329 KB
28 Jul 2022 12.22 AM
root / root
0755
oopscheck
1.115 KB
9 Feb 2022 6.45 PM
root / root
0755
optimize_eximstats
3.882 KB
9 Feb 2022 6.45 PM
root / root
0755
panel_ini
4.111 KB
2 Jun 2026 4.57 AM
root / root
0755
patch_mail_spamassassin_compiledregexps_body_0
2.395 KB
9 Feb 2022 6.45 PM
root / root
0755
patchfdsetsize
2.719 KB
9 Feb 2022 6.45 PM
root / root
0755
pedquota
2.256 KB
9 Feb 2022 6.45 PM
root / root
0755
perform_sqlite_auto_rebuild_db_maintenance
1.983 KB
11 Feb 2025 5.08 AM
root / root
0755
perlinstaller
0.516 KB
9 Feb 2022 6.45 PM
root / root
0755
perlmods
1.176 KB
9 Feb 2022 6.45 PM
root / root
0755
php_fpm_config
9.734 KB
9 Feb 2022 6.45 PM
root / root
0755
phpini_tidy
0.671 KB
9 Feb 2022 6.45 PM
root / root
0755
pkgacct
89.907 KB
11 Jun 2026 4.58 AM
root / root
0755
post_snapshot
2.094 KB
11 Feb 2025 5.08 AM
root / root
0755
post_sync_cleanup
5.833 KB
11 Jun 2026 4.58 AM
root / root
0755
primary_virtual_host_migration
2.443 KB
9 Feb 2022 6.45 PM
root / root
0755
process_cpmove
4.315 KB
14 Jul 2026 1.33 PM
root / root
0755
process_pending_cpanel_php_pear_registration
2.728 KB
16 Jun 2025 1.21 PM
root / root
0755
proxydomains
9.592 KB
12 Sep 2025 1.13 PM
root / root
0755
ptycheck
0.707 KB
9 Feb 2022 6.45 PM
root / root
0755
purge_modsec_log
1.526 KB
9 Feb 2022 6.45 PM
root / root
0755
purge_old_config_caches
2.075 KB
9 Feb 2022 6.45 PM
root / root
0755
pwck
0.691 KB
9 Feb 2022 6.45 PM
root / root
0755
quickdnslookup
1.132 KB
9 Feb 2022 6.45 PM
root / root
0755
quickwhoisips
2.293 KB
28 Jul 2022 12.22 AM
root / root
0755
quota_auto_fix
1.406 KB
9 Feb 2022 6.45 PM
root / root
0755
quotacheck
22.363 KB
28 Jul 2022 12.22 AM
root / root
0755
rawchpass
0.449 KB
9 Feb 2022 6.45 PM
root / root
0755
rdate
4.798 KB
28 Jul 2022 12.22 AM
root / root
0755
realadduser
5.608 KB
9 Feb 2022 6.45 PM
root / root
0755
realchpass
3.258 KB
9 Feb 2022 6.45 PM
root / root
0755
realperlinstaller
5.669 KB
9 Feb 2022 6.45 PM
root / root
0755
realrawchpass
0.415 KB
9 Feb 2022 6.45 PM
root / root
0755
rebuild_bandwidthdb_root_cache
1.452 KB
9 Feb 2022 6.45 PM
root / root
0755
rebuild_dbmap
5.798 KB
9 Feb 2022 6.45 PM
root / root
0755
rebuild_provider_openid_connect_links_db
1.015 KB
9 Feb 2022 6.45 PM
root / root
0755
rebuild_whm_chrome
2.224 KB
9 Feb 2022 6.45 PM
root / root
0755
rebuilddnsconfig
25.498 KB
7 Mar 2025 3.31 PM
root / root
0755
rebuildhttpdconf
2.602 KB
9 Feb 2022 6.45 PM
root / root
0755
rebuildinstalledssldb
2.849 KB
9 Feb 2022 6.45 PM
root / root
0755
rebuildippool
0.497 KB
9 Feb 2022 6.45 PM
root / root
0755
rebuilduserssldb
0.926 KB
9 Feb 2022 6.45 PM
root / root
0755
refresh-dkim-validity-cache
5.967 KB
9 Feb 2022 6.45 PM
root / root
0755
regenerate_tokens
2.176 KB
20 Apr 2022 7.26 PM
root / root
0755
remote_log_transfer
11.597 KB
31 Aug 2022 5.28 PM
root / root
0755
remove_dovecot_index_files
5.887 KB
9 Feb 2022 6.45 PM
root / root
0755
removeacct
28.2 MB
11 Sep 2026 4.57 AM
root / root
0700
rescan_user_dovecot_fts
2.977 KB
9 Feb 2022 6.45 PM
root / root
0755
reset_mail_quotas_to_sane_values
6.818 KB
9 Feb 2022 6.45 PM
root / root
0755
resetmailmanurls
2.028 KB
9 Feb 2022 6.45 PM
root / root
0755
resetquotas
4.612 KB
11 Feb 2025 5.08 AM
root / root
0755
restartsrv
3.189 KB
11 Feb 2025 5.08 AM
root / root
0755
restartsrv_apache
0.412 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_apache_php_fpm
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_base
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_bind
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_chkservd
0.417 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_clamd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_cpanel_php_fpm
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_cpanellogd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_cpdavd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_cpgreylistd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_cphulkd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_cpipv6
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_cpsrvd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_crond
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_dnsadmin
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_dovecot
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_exim
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_eximstats
0.492 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_ftpd
0.416 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_ftpserver
0.89 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_httpd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_imap
0.427 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_inetd
2.466 KB
20 Apr 2022 7.26 PM
root / root
0755
restartsrv_ipaliases
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_lmtp
0.427 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_mailman
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_mysql
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_named
0.565 KB
11 Feb 2025 5.08 AM
root / root
0755
restartsrv_nscd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_p0f
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_pdns
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_pop3
0.427 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_postgres
0.417 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_postgresql
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_powerdns
0.432 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_proftpd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_pureftpd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_queueprocd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_rsyslog
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_rsyslogd
0.427 KB
9 Feb 2022 6.45 PM
root / root
0755
restartsrv_spamd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_sshd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_syslogd
2.4 KB
11 Mar 2022 3.43 PM
root / root
0755
restartsrv_tailwatchd
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_unknown
10.78 MB
11 Sep 2026 4.57 AM
root / root
0755
restartsrv_xinetd
0.412 KB
9 Feb 2022 6.45 PM
root / root
0755
restorecpuserfromcache
1.961 KB
9 Feb 2022 6.45 PM
root / root
0755
restorepkg
48.7 MB
11 Sep 2026 4.57 AM
root / root
0700
rfc1912_zones.tar
10 KB
11 Feb 2015 5.35 PM
root / root
0644
rpmup
5.069 KB
11 Feb 2025 5.08 AM
root / root
0755
rsync-user-homedir.pl
5.765 KB
9 Feb 2022 6.45 PM
root / root
0755
run_if_exists
0.5 KB
9 Feb 2022 6.45 PM
root / root
0755
run_plugin_lifecycle
3.965 KB
10 Sep 2026 4.31 PM
root / root
0700
runstatsonce
0.43 KB
9 Feb 2022 6.45 PM
root / root
0755
runweblogs
1.021 KB
9 Feb 2022 6.45 PM
root / root
0755
sa-update_wrapper
3.338 KB
9 Feb 2022 6.45 PM
root / root
0755
safetybits.pl
0.824 KB
9 Feb 2022 6.45 PM
root / root
0755
secureit
4.721 KB
9 Feb 2022 6.45 PM
root / root
0755
securemysql
4.396 KB
11 Feb 2025 5.08 AM
root / root
0755
securerailsapps
3.575 KB
9 Feb 2022 6.45 PM
root / root
0755
securetmp
16.76 KB
16 Jun 2025 1.21 PM
root / root
0755
sendicq
0.463 KB
9 Feb 2022 6.45 PM
root / root
0755
servicedomains
9.592 KB
12 Sep 2025 1.13 PM
root / root
0755
set_mailman_archive_perms
1.754 KB
9 Feb 2022 6.45 PM
root / root
0755
setpostgresconfig
6.036 KB
9 Feb 2022 6.45 PM
root / root
0755
setup_greylist_db
16.327 KB
11 Jun 2026 4.57 AM
root / root
0755
setup_modsec_db
1.304 KB
9 Feb 2022 6.45 PM
root / root
0755
setup_systemd_timer_for_plugins
3.921 KB
10 Sep 2026 4.31 PM
root / root
0700
setupftpserver
10.475 KB
9 Feb 2022 6.45 PM
root / root
0755
setupmailserver
9.393 KB
7 Mar 2025 3.31 PM
root / root
0755
setupnameserver
12.596 KB
12 Sep 2025 1.13 PM
root / root
0755
show_php_settings
3.674 KB
11 Jun 2026 4.58 AM
root / root
0755
shrink_modsec_ip_database
12.974 KB
9 Feb 2022 6.45 PM
root / root
0755
simpleps
3.051 KB
9 Feb 2022 6.45 PM
root / root
0755
slurp_exim_mainlog
5.775 KB
9 Feb 2022 6.45 PM
root / root
0755
smartcheck
15.128 KB
16 Jun 2025 1.21 PM
root / root
0755
smtpmailgidonly
8.147 KB
8 Jul 2026 8.50 PM
root / root
0755
snapshot_prep
5.876 KB
11 Feb 2025 5.08 AM
root / root
0755
spamassassin_dbm_cleaner
5.853 KB
28 Jul 2022 12.22 AM
root / root
0755
spamassassindisable
3.74 KB
10 Jun 2022 3.47 PM
root / root
0755
spamboxdisable
2.27 KB
10 Jun 2022 3.47 PM
root / root
0755
sshcontrol
14.377 KB
9 Feb 2022 6.45 PM
root / root
0755
ssl_crt_status
3.836 KB
9 Feb 2022 6.45 PM
root / root
0755
suspendacct
18.082 KB
12 Sep 2025 1.13 PM
root / root
0755
suspendmysqlusers
4.775 KB
11 Feb 2025 5.08 AM
root / root
0755
swapip
3.822 KB
9 Feb 2022 6.45 PM
root / root
0755
sync-mysql-users-from-grants
1.196 KB
9 Feb 2022 6.45 PM
root / root
0755
sync_child_accounts
1.771 KB
9 Feb 2022 6.45 PM
root / root
0755
sync_contact_emails_to_cpanel_users_files
1.136 KB
10 Jun 2022 3.47 PM
root / root
0755
synctransfers
1.925 KB
9 Feb 2022 6.45 PM
root / root
0755
syslog_check
1.358 KB
9 Feb 2022 6.45 PM
root / root
0755
sysup
0.63 KB
9 Feb 2022 6.45 PM
root / root
0755
test_sa_compiled
1.067 KB
9 Feb 2022 6.45 PM
root / root
0755
transfer_account_as_user
2.342 KB
9 Feb 2022 6.45 PM
root / root
0755
transfer_accounts_as_root
4.756 KB
9 Feb 2022 6.45 PM
root / root
0755
transfer_in_progress
3.082 KB
9 Feb 2022 6.45 PM
root / root
0755
transfer_in_progress.pod
0.305 KB
17 Nov 2016 1.07 AM
root / root
0644
transfermysqlusers
10.1 MB
11 Sep 2026 4.57 AM
root / root
0700
try-later
7.949 KB
9 Feb 2022 6.45 PM
root / root
0755
unblockip
0.651 KB
9 Feb 2022 6.45 PM
root / root
0755
uninstall_cpanel_analytics
1.201 KB
9 Feb 2022 6.45 PM
root / root
0755
uninstall_dovecot_fts
0.549 KB
9 Feb 2022 6.45 PM
root / root
0755
uninstall_plugin
2.839 KB
28 Jul 2022 12.22 AM
root / root
0755
unlink_service_account
2.619 KB
9 Feb 2022 6.45 PM
root / root
0755
unpkgacct
4.603 KB
9 Feb 2022 6.45 PM
root / root
0755
unslavenamedconf
0.843 KB
9 Feb 2022 6.45 PM
root / root
0755
unsuspendacct
18.455 KB
11 Sep 2026 4.57 AM
root / root
0755
unsuspendmysqlusers
7.096 KB
11 Feb 2025 5.08 AM
root / root
0755
upcp
43.006 KB
25 Aug 2026 4.57 AM
root / root
0755
upcp-running
2.703 KB
9 Feb 2022 6.45 PM
root / root
0755
upcp.static
955.33 KB
11 Sep 2026 4.57 AM
root / root
0755
update-packages
5.069 KB
11 Feb 2025 5.08 AM
root / root
0755
update_apachectl
0.469 KB
9 Feb 2022 6.45 PM
root / root
0755
update_db_cache
0.42 KB
9 Feb 2022 6.45 PM
root / root
0755
update_dkim_keys
1.45 KB
9 Feb 2022 6.45 PM
root / root
0755
update_exim_rejects
1.213 KB
9 Feb 2022 6.45 PM
root / root
0755
update_existing_mail_quotas_for_account
4.776 KB
9 Feb 2022 6.45 PM
root / root
0755
update_feature_flags
0.935 KB
11 Feb 2025 5.08 AM
root / root
0755
update_freebusy_data
5.25 KB
1 Apr 2025 10.57 PM
root / root
0755
update_known_proxy_ips
0.979 KB
9 Feb 2022 6.45 PM
root / root
0755
update_local_rpm_versions
4.56 KB
2 Dec 2022 4.41 PM
root / root
0755
update_mailman_cache
8.345 KB
9 Feb 2022 6.45 PM
root / root
0755
update_mysql_systemd_config
1.068 KB
7 Mar 2025 3.31 PM
root / root
0755
update_neighbor_netblocks
0.476 KB
9 Feb 2022 6.45 PM
root / root
0755
update_sa_config
2.145 KB
9 Feb 2022 6.45 PM
root / root
0755
update_spamassassin_config
10.73 KB
2 Dec 2022 4.41 PM
root / root
0755
update_users_jail
0.675 KB
9 Feb 2022 6.45 PM
root / root
0755
update_users_vhosts
0.782 KB
9 Feb 2022 6.45 PM
root / root
0755
updatedomainips
0.591 KB
9 Feb 2022 6.45 PM
root / root
0755
updatenameserverips
1.656 KB
9 Feb 2022 6.45 PM
root / root
0755
updatenow
5.178 KB
28 Jul 2022 12.22 AM
root / root
0755
updatenow.static
2.02 MB
11 Sep 2026 4.57 AM
root / root
0755
updatenow.static-cpanelsync
2.03 MB
12 Sep 2026 4.57 AM
root / root
0700
updatesigningkey
1.949 KB
9 Feb 2022 6.45 PM
root / root
0755
updatessldomains
1.813 KB
9 Feb 2022 6.45 PM
root / root
0755
updatesupportauthorizations
2.492 KB
9 Feb 2022 6.45 PM
root / root
0755
updateuserdatacache
2.47 KB
9 Feb 2022 6.45 PM
root / root
0755
updateuserdomains
0.756 KB
9 Feb 2022 6.45 PM
root / root
0755
upgrade_bandwidth_dbs
2.219 KB
9 Feb 2022 6.45 PM
root / root
0755
upgrade_subaccount_databases
2.731 KB
9 Feb 2022 6.45 PM
root / root
0755
userdata_wildcard_cleanup
5.739 KB
9 Feb 2022 6.45 PM
root / root
0755
userdirctl
5.014 KB
9 Feb 2022 6.45 PM
root / root
0755
validate_sshkey_passphrase
1.215 KB
9 Feb 2022 6.45 PM
root / root
0755
verify_api_spec_files
0.739 KB
9 Feb 2022 6.45 PM
root / root
0755
verify_pidfile
1.961 KB
9 Feb 2022 6.45 PM
root / root
0755
verify_vhost_includes
7.341 KB
28 Jul 2022 12.22 AM
root / root
0755
vps_optimizer
7.819 KB
9 Feb 2022 6.45 PM
root / root
0755
vzzo-fixer
0.708 KB
9 Feb 2022 6.45 PM
root / root
0755
whmlogin
2.334 KB
9 Feb 2022 6.45 PM
root / root
0755
whoowns
1.128 KB
13 Sep 2016 4.25 PM
root / root
0755
wwwacct
30.35 MB
11 Sep 2026 4.57 AM
root / root
0700
wwwacct2
0.086 KB
11 Feb 2015 5.35 PM
root / root
0755
xfer_rcube_schema_migrate.pl
2.402 KB
9 Feb 2022 6.45 PM
root / root
0755
xfer_rcube_uid_resolver.pl
1.803 KB
9 Feb 2022 6.45 PM
root / root
0755
xferpoint
3.126 KB
9 Feb 2022 6.45 PM
root / root
0755
xfertool
16.234 KB
11 Feb 2025 5.08 AM
root / root
0755
zoneexists
0.781 KB
9 Feb 2022 6.45 PM
root / root
0755

✘✘ GRAYBYTE WORDPRESS FILE MANAGER @ 2026 CONTACT ME ✘✘
Static GIF Static GIF