#!/usr/bin/perl -T

=head1 NAME

collect-reminders - collect email reminders to be sent out

=head1 SYNOPSIS

Collect emails reminders set by users for special occasions and move
them to the email-reminder spool directory.

=head1 DESCRIPTION

Email-reminder allows users to define events that they want to be
reminded of by email.

This script is meant to be invoked everyday by a cron job or as the
root user.  It collects the reminder files from each user.

=head1 OPTIONS

=over 6

=item B<--help>

Displays basic usage message.

=item B<--verbose>

Prints out information about what the program is doing, including the
full emails being sent out.

=item B<--version>

Displays the version number.

=back

=head1 FILES

F<~/.email-reminders>, F</etc/email-reminder.conf>

=head1 AUTHOR

Francois Marier <francois@fmarier.org>

=head1 SEE ALSO

email-reminder-editor, send-reminders

=head1 COPYRIGHT

Copyright (C) 2004-2014 by Francois Marier

Email-Reminder is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.

Email-Reminder is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with Email-Reminder; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.

=cut

use strict;
use warnings;

use File::Copy;
use Getopt::Long;
use Pod::Usage;

use EmailReminder::Utils;

# Command-line parameters
my $verbose  = 0;
my $simulate = 0;
my $version  = 0;
my $help  = 0;
GetOptions( "verbose"  => \$verbose,
            "version"  => \$version,
            "help"     => \$help,
    );

sub copy_reminders
{
    my $uid = shift;
    my $homedir = shift;

    my $file = "$homedir/" . $EmailReminder::Utils::USER_CONFIG_FILE;
    if (-e $file) {
        my $destination = $EmailReminder::Utils::SPOOL_DIRECTORY . '/' . $uid;
        print "==> Copying $file to $destination\n" if $verbose;

        # Delete existing file for the user if necessary
        if (-e $destination) {
            if (unlink($destination)) {
                print "A file for uid $uid was already present and has been removed.\n" if $verbose;
            } else {
                die "Could not remove $destination\n";
            }
        }

        # Copy the file to the spool directory
        unless (copy($file, $destination)) {
            die "Could not copy $file\n";
        }

        return 1;
    }
    else {
        print "No reminders in '$homedir'.\n" if $verbose;
    }

    return 0;
}

sub main
{
    my $running_uid = $>;
    if ($running_uid != 0) {
        die "This script must be run as root\n";
    }

    # Iterate through all local users
    while (my (undef, undef, $uid, undef, undef, undef, undef,
               $homedir, $shell, undef) = getpwent) {

        # Untaint uid
        if ($uid =~ /^([0-9]+)$/i) {
            $uid = $1;
        } else {
            die "Error: got a non-numeric uid\n";
        }

        # Try to skip non-human users
        if (($uid < 1000) || ($uid >= 60000) || ($shell eq '/bin/false')) {
            print "Skipped non-human uid $uid\n" if $verbose;
            next;
        }

        # Untaint homedir
        if ($homedir =~ /^([A-Za-z0-9_\-\/.]+)$/) {
            $homedir = $1;
        } else {
            die "Error: home directory for uid $uid contains invalid characters\n";
        }

        copy_reminders($uid, $homedir);
    }
    return 1;
}

if ($help || $version) {
    print "collect-reminders $EmailReminder::Utils::VERSION\n";
    if ($help) {
        print "\n";
        pod2usage(1);
    } else {
        exit(1);
    }
} else {
    main();
}
