#!/usr/bin/perl -w # $Id: votify,v 1.5 2005/05/16 04:03:46 agriffis Exp $ # # Copyright 2005-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # # votify: generate, verify and submit voting ballots for trustee elections # BEGIN { my $dirname; if(-f '/etc/elections/Votify.pm') { $dirname = '/etc/elections'; } else { use Cwd qw(abs_path); use File::Basename qw(dirname); $dirname = dirname(abs_path(__FILE__)); } push @INC, $dirname; } use POSIX; use Getopt::Long; use List::Util; use Votify 'user'; use strict; ###################################################################### # Global vars ###################################################################### (my $zero = $0) =~ s,.*/,,; (my $version = $Votify::version) =~ s/.*?(\d.*\d).*/$zero version $1\n/; my (%opt); # Collect the open elections my (%open_elections, $usage_elections); %open_elections = Votify::get_open_elections_hash(); if (scalar keys %open_elections) { $usage_elections = join("\n ", keys %open_elections); } else { $usage_elections = "(no elections currently open)"; } my $usage = < where is one of: --new Generate a new ~/.ballot- for editing --verify Verify content of ~/.ballot- --submit Submit ~/.ballot- to be counted --help Show this help message --version Show version information and is one of the elections currently in-progress. The following elections are currently open: $usage_elections Instructions: (1) Create a new ballot with the --new command. This generates a file in your home directory called ~/.ballot-. The file contains a shuffled listing of the candidates. Note that the permissions on the file are set so that only you have read+write permissions. \$ $zero --new (2) Edit ~/.ballot- and rearrange the candidates linewise in order of preference. Candidates you consider equal can be listed on the same line. Any candidates you omit are implied on the last line. For example, if tom, jerry, sam, linford and karin are running, you could put: karin linford jerry In this case, you prefer karin over everybody else. You prefer linford and jerry over tom and sam. The file format is case-insensitive, ignores empty lines and comments that start with the hash '#' symbol. (3) Verify your choices. The $zero program will explain in English if it appears that you've made any errors in your ballot. \$ $zero --verify (4) Submit your ballot. This renames your ballot to ~/.ballot--submitted so that it will be tallied when the votes are collected. \$ $zero --submit EOT ###################################################################### # Main ###################################################################### package main; # Make sure umask is secure before we do anything umask 077; # Parse the options on the cmdline. Put the short versions first in # each optionstring so that the hash keys are created using the short # versions. For example, use 'q|qar', not 'qar|q'. my ($result) = GetOptions( \%opt, 'new', # generate new ~/.ballot- 'verify', # verify content of ~/.ballot- 'submit', # rename ~/.ballot to ~/.ballot--submitted 'help', # help message 'version', # version information ); if ($opt{'help'} or not %opt) { print STDERR $usage; exit 0 } if ($opt{'version'}) { print STDERR $version; exit 0 } die "$zero: only one command allowed; use --help for help\n" if 1 < keys %opt; die "$zero: election required; use --help for help\n" unless @ARGV == 1; my ($election) = $ARGV[0]; $election =~ s/^\.ballot-//g; # bug 326751 my ($b) = Ballot->new($election); # Check if the election is open. This should really happen in an # Election class in Votify.pm eventually my ($starttime, $stoptime); $starttime = $open_elections{$election}{'starttime'}; $stoptime = $open_elections{$election}{'stoptime'}; if ($starttime && $starttime > time) { print "\n", "*" x 75, "\n"; print "WARNING: Specified election doesn't start until ", scalar(localtime $starttime), "\n"; print "*" x 75, "\n"; } if ($stoptime && $stoptime < time) { print "\n", "*" x 75, "\n"; print "WARNING: Specified election ended at ", scalar(localtime $stoptime), "\n"; print "*" x 75, "\n"; } if ($opt{'new'}) { # Make sure the user is eligible open(F, '<', $open_elections{$election}{'votersfile'}) or die "Failed to open voters file"; my (@voters) = ; chomp(@voters); close(F); unless (grep { $_ eq getpwuid($>) } @voters) { print STDERR <populate(); $b->write(); # Let the user know what we did print <{filename} Please edit this file with your preferred editor. Additional instructions can be read at the top of the ballot. EOF exit 0; } if ($opt{'verify'} or $opt{'submit'}) { $b->read(); $b->verify(); if ($opt{'verify'}) { print <{'filename'}.'-submitted'; die("File already exists, please remove $s") if -e $s; rename($b->{'default_filename'}, $s) or die("Couldn't rename $b->{default_filename}"); print <