#!/usr/bin/env perl # Simplified BSD License (FreeBSD License) # # Copyright (c) 2026, Daily Data Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # setCleanupScripts # Utility script to selectively copy cleanup scripts into the sneakernet cleanupScripts # directory based on the current month. Each script in the configuration is associated # with one or more months (1-12). The script determines the current month and copies # matching scripts from the source directory to the destination directory for sneakernet # to encrypt, transfer, and execute on the target machine. # # Usage: setCleanupScripts [--verbose|-v] [--help|-h] [--version|-V] # # Author: R. W. Rodolico # Created: January 2026 # # Revision History (oldest to newest): # v1.0.0 (2026-01-18) - Initial release with verbose flag support # # For detailed changelog, see setCleanupScripts.md use strict; use warnings; use Getopt::Long qw(GetOptions); Getopt::Long::Configure("bundling"); use FindBin; use lib "$FindBin::Bin/.."; use ZFS_Utils qw(loadConfig makeConfig); our $VERSION = '1.0.0'; # Parse command-line options my $verbose = 0; my $help = 0; my $version = 0; GetOptions( 'verbose|v' => \$verbose, 'help|h' => \$help, 'version|V' => \$version, ) or do { print "Invalid options\n"; exit 2; }; if ($help) { print "Usage: $FindBin::Script [--verbose] [--help] [--version]\n"; print " --verbose, -v Display informational messages\n"; print " --help, -h Display this help message\n"; print " --version, -V Display version number\n"; exit 0; } elsif ($version) { print "$FindBin::Script v$VERSION\n"; exit 0; } # Script configuration my $scriptFullPath = "$FindBin::Bin/setCleanupScripts"; my $config_file = "$scriptFullPath.yaml"; # Load configuration from YAML file my $config = loadConfig($config_file); # If config file doesn't exist (loadConfig returns undef), create it from datastructure unless (defined $config && keys %$config) { print "Configuration file not found, creating from defaults\n"; # Load default configuration structure from external file my $defaultConfig = do "$scriptFullPath.datastructure"; die "Error loading datastructure file: $@" if $@; die "Error reading datastructure file: $!" unless defined $defaultConfig; die "datastructure file did not return a hash reference" unless ref($defaultConfig) eq 'HASH'; # Create YAML config file from default structure makeConfig($config_file, $defaultConfig); # Try loading again after creation $config = loadConfig($config_file); unless (defined $config && keys %$config) { die "ERROR: Failed to create or load configuration file\n"; } die "Default configuration file created, please edit $config_file as needed and re-run the script\n"; } # Validate configuration structure die "ERROR: Invalid configuration - missing 'scripts' key\n" unless exists $config->{scripts}; die "ERROR: Invalid configuration - 'scripts' must be a hash reference\n" unless ref($config->{scripts}) eq 'HASH'; my $source_path = $config->{sourcePath} || '.'; my $dest_path = $config->{destinationPath} || '.'; my %scripts = %{$config->{scripts}}; # Get current month (1-12) my $current_month = (localtime)[4] + 1; print "Current month: $current_month\n" if $verbose; print "Source path: $source_path\n" if $verbose; print "Destination path: $dest_path\n" if $verbose; print "Scripts to copy:\n" if $verbose; # Check each script and copy if current month matches foreach my $script (keys %scripts) { my @months = @{$scripts{$script}}; if (grep { $_ == $current_month } @months) { my $source_file = "$source_path/$script"; my $dest_file = "$dest_path/$script"; print " - $script\n" if $verbose; # Check if source file exists if (-f $source_file) { # Copy the file system("cp", $source_file, $dest_file); if ($? == 0) { print " Copied: $source_file -> $dest_file\n" if $verbose; } else { warn " ERROR: Failed to copy $source_file\n"; } } else { warn " WARNING: Source file not found: $source_file\n"; } } }