#!/usr/bin/perl -w #********************************************************************** # acslpr - Copyright (C) 2004-2005 - Cameron Morland # This program 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 2, or (at your option) # any later version. # # This program 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. #********************************************************************** # Print files on a remote printer, using ssh. Keep a list of all # files printed using MD5 hashes, so we don't accidentally print the # same file repeatedly. my ($rev) = '$Revision: 1.21 $'; # store the CVS revision that we are $rev =~ s/[^0-9.]*//g; # remove non-numeric component use Getopt::Std; our($options); getopts("bfnvhqu:", \%options); # read commandline switches @files = @ARGV; # remaining arguments are filenames. my ($date) = scalar(localtime); print "ACS printing script version $rev\n"; # find what the username is my ($user); $user = $ENV{USER}; $path = $ENV{HOME}; if ($options{u}) { $user = $options{u}; print "Using '$user' as user.\n"; print "I hope you know what you're doing.\n"; } if (! $user) { # this might never come up. print "I couldn't determine your username. Please add '-u '\n"; print "to the list of options when calling this, and tell the\n"; print "programmer about this problem.\n"; exit(0); } my ($expertmode) = 0; if ($user eq "cjmorlan") { $expertmode = 1; } # the logfile must exist so we can seek it later. my $logfile = "$path/.acslpr-log"; if (! (-e $logfile)) { `touch $logfile`; } if ($options{h}) { print < EOF ; exit(0); } my($printed) = 0; # number of printed files. my ($oldmd5, $oldmd5file, $olddate); foreach $file (@files) { $file =~ s/"/\\"/g; if (-e $file) { # scan the list of previously-printed files for a file with the # same MD5 sum as the file to be printed. my ($md5, $md5file) = split(" ", `md5sum "$file"`); open(LOG, "<$logfile") or die "Can't read $logfile: $!\n"; my $mdfound = 0; while () { ($oldmd5, $oldmd5file, $olddate) = split("\t"); if ($md5 eq $oldmd5) { $mdfound = 1; last; } } close(LOG); if ($mdfound) { # don't print previously-printed files (matching MD5)... if (! $options{f}) { print "*** Skipping file with MD5 sum $md5\n", "*** previously printed ", (scalar localtime($olddate)), ".\n", "*** Use '-f' to print anyway.\n"; next; } else { # ...unless we're told to print MD5 matching files. print "*** Printing file previously printed ", (scalar localtime($olddate)), ".\n"; } } $printed++; # we don't want to run out of quota on /tmp, so use pipes # instead of the filesystem. print "Printing $file: "; if (!$expertmode || $options{b}) { $command = "cat \"$file\" | ssh acs \"lpr\""; } else { $command = "barcodify \"$file\" | ssh acs \"lpr\""; } # record the MD5 sum of the file, even if we don't print it! $newmd5 = `md5sum "$file"`; chomp $newmd5; $newmd5 =~ s| |\t|; open(LOG, ">>$logfile") or die "Can't write $logfile: $!\n"; print LOG "$newmd5\t", time, "\n";; close(LOG); if (! $options{n} ) { print "sent.\n"; `$command`; } else { print "supressed.\n"; } } else { # the file doesn't exist. print "Skipping non-existent $file\n"; } } if (! $options{q}) { if ($printed >= 1) { # give a few seconds for the files to be queued print "Waiting for file(s) to join the queue.\n"; $| = 1; for ($i = 4; $i > 0; $i--) { print "$i\r"; sleep(1); } } # now ssh to acs and list queued jobs. print "print jobs for $user:\n"; $command = "ssh acs \"lpq | grep $user ; pquota | grep ^Semester\""; open(CMD, "$command |") or die "Can't connect: $!\n"; while() { s/^\s*//; # remove leading spaces if (m/^Semester/) { s/\$//g; @x = split; printf("%3.1f%% of quota consumed. %d sheets of paper remain.\n", $x[7] / $x[3] * 100, $x[7] / 0.1); @ctime = localtime(time); $month = $ctime[4]; $day = $ctime[3]; $p = 100 * (($month % 4) * 30 + $day) / (120); printf("%3.1f%% of the term is over.\n", $p); } else { print $_; } } my ($delay) = 72; # hours my ($padding) = 45; print "Jobs printed within the last $delay hours:\n"; # now print our list of jobs of the the last 3 days open(LOG, "<$logfile") or die "Can't read $logfile: $!\n"; while () { ($oldmd5, $oldmd5file, $olddate) = split("\t"); $oldmd5file = substr($oldmd5file, 0, $padding); $oldmd5file = $oldmd5file . (' ' x ($padding - length($oldmd5file))); if ($olddate > time - $delay * 3600) { print $oldmd5file, " printed ", (scalar localtime($olddate)), "\n"; } } close(LOG); }