This commit is contained in:
committed by
Git OBS Bridge
parent
b55a6dc6e3
commit
09d4374e9a
@@ -1,3 +1,8 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Jun 25 10:19:33 CEST 2007 - kssingvo@suse.de
|
||||
|
||||
- added quosnmp script to %doc
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jun 20 18:35:47 CEST 2007 - kssingvo@suse.de
|
||||
|
||||
|
@@ -17,7 +17,7 @@ License: GNU General Public License (GPL), individual distribution permis
|
||||
Group: Hardware/Printing
|
||||
Summary: The Common UNIX Printing System
|
||||
Version: 1.2.11
|
||||
Release: 18
|
||||
Release: 19
|
||||
Requires: cups-libs = %{version}, cups-client = %{version}
|
||||
Requires: ghostscript_any, ghostscript-fonts-std, foomatic-filters
|
||||
Requires: util-linux
|
||||
@@ -30,6 +30,7 @@ Source4: pswrite
|
||||
Source7: ogonki
|
||||
Source8: rccups
|
||||
Source9: http://amaru.ti6.tu-harburg.de/portal/Members/ti6ntm/Projekte/Printanalyzer/PrintAnalyzer
|
||||
Source10: http://homepages.nyu.edu/~ml1100/files/quosnmp
|
||||
Source11: setcupsbroadcasting
|
||||
Source12: postscript.ppd.bz2
|
||||
Source13: cups.sysconfig
|
||||
@@ -155,6 +156,7 @@ perl -pi -e "s|SUSEVERSION|$BUILD_DISTRIBUTION_NAME|; \
|
||||
perl -pi -e 's|(CUPS_SERVERBIN=\")\$exec_prefix/lib|$1'%{_libdir}'|' \
|
||||
config-scripts/cups-directories.m4
|
||||
cp -a %{SOURCE9} .
|
||||
cp -a %{SOURCE10} .
|
||||
|
||||
%build
|
||||
%{?suse_update_config:%{suse_update_config -f . }}
|
||||
@@ -231,6 +233,7 @@ ln -sf ../sbin/lpc $RPM_BUILD_ROOT/usr/bin/lpc # bugzilla#16652
|
||||
%{INSTALL_DIR} $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name}/images
|
||||
install -m 644 -D conf/pam.suse $RPM_BUILD_ROOT/etc/pam.d/cups
|
||||
install -m 755 PrintAnalyzer $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}/
|
||||
install -m 755 quosnmp $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}/
|
||||
for f in CHANGES*.txt CREDITS.txt INSTALL.txt LICENSE.txt README.txt; do
|
||||
install -m 644 "$f" $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}/
|
||||
done
|
||||
@@ -378,6 +381,8 @@ install -m 644 %{SOURCE17} $RPM_BUILD_ROOT/etc/sysconfig/SuSEfirewall2.d/service
|
||||
%{_datadir}/locale/*/cups_*
|
||||
|
||||
%changelog
|
||||
* Mon Jun 25 2007 - kssingvo@suse.de
|
||||
- added quosnmp script to %%doc
|
||||
* Wed Jun 20 2007 - kssingvo@suse.de
|
||||
- removed rccupsrenice: cups-1.2.x does no longer traversing of
|
||||
filesystem during startup. reason no longer present.
|
||||
|
574
quosnmp
Normal file
574
quosnmp
Normal file
@@ -0,0 +1,574 @@
|
||||
#!/usr/bin/perl
|
||||
# quosnmp
|
||||
# Version 1.0.0, Last modified on 2007-06-22
|
||||
# A CUPS backend for SNMP-based print accounting and quota enforcement.
|
||||
#
|
||||
# Released by Marcus Lauer (marcus.lauer at nyu dot edu)
|
||||
#
|
||||
# Copyright (C) 2007 by Marcus Lauer (marcus.lauer at nyu dot edu) except where
|
||||
# previous copyright is in effect.
|
||||
#
|
||||
# Based on accsnmp v1.02.20070124 by jeff hardy (hardyjm at potsdam dot edu)
|
||||
# ############
|
||||
# accsnmp
|
||||
# v1.02.20070124
|
||||
# jeff hardy (hardyjm at potsdam dot edu)
|
||||
# backend wrapper hardware accounting for cups
|
||||
#
|
||||
# ############
|
||||
# Copyright 2007, Jeff Hardy (hardyjm at potsdam dot edu)
|
||||
#
|
||||
# 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 of the License, 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
# USA.
|
||||
#
|
||||
# ###########
|
||||
# example URI - quosnmp://socket://192.168.xxx.xxx
|
||||
#
|
||||
# arguments according to the docs, as C sees them:
|
||||
# 0 1 2 3 4 5 6
|
||||
# lpd jobid username jobtitle copies printoptions file ///or read from STDIN if no filename
|
||||
#
|
||||
# arguments as Perl sees them:
|
||||
# 0 1 2 3 4 5
|
||||
# jobid username jobtitle copies printoptions file ///or read from STDIN if no filename
|
||||
|
||||
|
||||
use strict;
|
||||
use Net::SNMP;
|
||||
|
||||
# --- Modify these settings to suit your needs.
|
||||
my $ENFORCE_QUOTA = 1; # Turn on/off [1/0] print quota enforcement
|
||||
my $SAVE_JOBS = 0; #turn on/off [1/0] saving printjobs
|
||||
my $JOB_BLACKLIST = 0; #turn on/off [1/0] jobs blacklist
|
||||
my @JobBlacklist = (""); # Names of jobs to be blacklisted.
|
||||
|
||||
my $LOGGING = 1; # Turn on/off [1/0] print logging function call
|
||||
my $LOGGING_FILE = "/var/log/cups/acc_page_log"; # File for printer logging
|
||||
my $ERROR_LOGGING = 1; # Turn on/off [1/0] error logging function call
|
||||
my $ERROR_LOGGING_FILE = "/var/log/cups/acc_error_log"; # File for error logging
|
||||
|
||||
my $headerDiscount = 0; # Credit accounts this many pages per print job for mandatory header (or footer) pages
|
||||
|
||||
my $DEBUG = 0; #turn on/off [1/0] debugging function call
|
||||
my $DEBUG_FILE = "/tmp/quosnmp.debug"; #tmp file for debugging
|
||||
|
||||
my $SNMP_COMMUNITY = "public"; #best to use read community obviously
|
||||
|
||||
# --- These settings can be modified, but it is less likely that you will need to do so.
|
||||
my $accDir = "/var/log/cups/accounting"; #directory to keep accounting files
|
||||
my $quoDir = "/var/log/cups/quotas"; #directory to keep quota files
|
||||
my $accPrinterList = "/etc/cups/accounted-printers.txt";#list of special (usually color) printers -- pages printed to these count triple
|
||||
|
||||
my $backendDir = "/usr/lib/cups/backend"; #directory which contains all cups backends
|
||||
|
||||
my $SNMP_TIMEOUT = 15; # SNMP timeout in seconds, 0 to try forever, max 60
|
||||
my $SNMP_RETRIES = 5; # Number of times to retry an SNMP request, max 20
|
||||
my $BACKEND_ATTEMPTS = 10; #backend retry attempts, 0 to try forever
|
||||
my $STALL_TIMEOUT = 600; # Assume printer is stalled after this many seconds, 0 to disable
|
||||
|
||||
# --- You almost certainly do not want to modify these variables.
|
||||
my $PAGECOUNT_OID = "1.3.6.1.2.1.43.10.2.1.4.1.1"; #printer lifetime pagecount
|
||||
my $PRINTERSTATUS_OID = "1.3.6.1.2.1.25.3.5.1.1.1"; #printer status
|
||||
|
||||
|
||||
# --- Only experts should modify the code below this line.
|
||||
|
||||
# This is used by some of the logging features.
|
||||
my @startTime = localtime(time);
|
||||
|
||||
### MAIN
|
||||
{
|
||||
### ARGS CHECK
|
||||
if (!$ARGV[0]){ # Device discovery mode
|
||||
print ("network quosnmp \"Unknown\" \"Accounted Printer (SNMP)\"\n");
|
||||
exit 0;
|
||||
}
|
||||
if (scalar(@ARGV) < 5 || scalar(@ARGV) > 6){ # Error
|
||||
print STDERR ("ERROR: Usage: quosnmp job-id user title copies options [file]\n");
|
||||
exit 1;
|
||||
}
|
||||
# Now that we got this far, let us name the arguments to keep our sanity
|
||||
my ($jobID,$userName,$jobTitle,$copies,$printOptions,$printFile) = @ARGV;
|
||||
|
||||
### ENV CHECK
|
||||
# URI parsing must fit syntax or die
|
||||
# Ex: quosnmp://lpd://192.168.xxx.xxx
|
||||
# Also supported: quosnmp://hp:/net/HP_LaserJet_xxxx_Series?ip=192.168.xxx.xxx
|
||||
$ENV{DEVICE_URI} =~ m#(\S+)://(\S+):/\S+?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\S?# or
|
||||
cleanExit($jobID,$ENV{PRINTER},"ERROR: URI must be in format: quosnmp://<original uri>\n");
|
||||
my $wrapBackend = $1;
|
||||
my $realBackend = $2;
|
||||
my $printerIP = $3;
|
||||
|
||||
### BLACKLIST/QUOTA CHECKS
|
||||
if ( length($userName) < 1 ){ # No username
|
||||
cleanExit($jobID,$ENV{PRINTER},"ERROR: No username for printjob: user must authenticate\n");
|
||||
}
|
||||
|
||||
if ($ENFORCE_QUOTA == 1) {
|
||||
my $printQuota = getPrintQuota($quoDir,$userName);
|
||||
|
||||
if ( $printQuota != -1 ) { # -1 is a special value meaning unlimited printing is allowed.
|
||||
my $userPagesPrinted = getUserTotal("$accDir/$userName");
|
||||
|
||||
# If the user is over quota, or is disallowed to print, or no quota file was found at all, then exit.
|
||||
if ( $userPagesPrinted >= $printQuota || $printQuota == 0 || $printQuota == -2 ) {
|
||||
cleanExit($jobID,$ENV{PRINTER},"ERROR: Account ($userName) is at or over quota ($printQuota pages) and cannot print\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($JOB_BLACKLIST){
|
||||
my $jobStatus = chkJobBlacklist($jobTitle);
|
||||
if ($jobStatus == -1){ # Job is blacklisted
|
||||
cleanExit($jobID,$ENV{PRINTER},"ERROR: Jobname ($jobTitle) is blacklisted from printing\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
### SPOOL JOB TO TEMP FILE
|
||||
my $jid = $jobID;
|
||||
my $uid = $userName;
|
||||
$jid =~ s/\W//g; #sanity check
|
||||
$uid =~ s/\W//g; #sanity check
|
||||
my $tempFile = "$ENV{TMPDIR}/$jid-$uid-cupsjob$$";
|
||||
|
||||
if ($printFile){ # Only spool given print file if we want to save
|
||||
if ($SAVE_JOBS){
|
||||
open (OUT, ">$tempFile") or cleanExit($jid,$ENV{PRINTER},"ERROR: Cannot write $tempFile: $!\n");
|
||||
open (FH, "$printFile") or cleanExit($jid,$ENV{PRINTER},"ERROR: Cannot read $printFile: $!\n");
|
||||
while(<FH>){
|
||||
print OUT "$_";
|
||||
}
|
||||
close FH;
|
||||
close OUT;
|
||||
}
|
||||
}
|
||||
else { # Have to spool to temp if STDIN
|
||||
open (OUT, ">$tempFile") or cleanExit($jid,$ENV{PRINTER},"ERROR: Cannot write $tempFile: $!\n");
|
||||
while(<STDIN>){
|
||||
print OUT "$_";
|
||||
}
|
||||
close OUT;
|
||||
}
|
||||
|
||||
|
||||
### PRINTING
|
||||
# SNMP pagecount: first snmp query
|
||||
my $prePageCount = snmpGet($printerIP,$PAGECOUNT_OID,$jid);
|
||||
|
||||
|
||||
# NOTE: the next several lines are the guts of wrapping a cups backend
|
||||
# 1) Pull the device URI from the environment and fix it by removing the wrapper
|
||||
# 2) Tack this onto the front of the arg array to pass to the real backend
|
||||
# Note: 1 and 2 are required as different backends find the device URI by
|
||||
# different means. LPD gets it from the arg, whereas IPP gets it from env.
|
||||
# 3) If the job arrived via STDIN, tack printFile onto the end of the arg array
|
||||
# This will happen on non-raw queues and needs to be checked, otherwise we
|
||||
# will dos the printer with a "zero byte" error.
|
||||
# 4) Call the real backend with this new argument array
|
||||
|
||||
my $deviceURI = $ENV{DEVICE_URI};
|
||||
$deviceURI =~ s#$wrapBackend://##;
|
||||
$ENV{DEVICE_URI} = $deviceURI;
|
||||
|
||||
if (!($printFile)){
|
||||
$copies = 1;
|
||||
$printFile = $tempFile;
|
||||
}
|
||||
my @argvNew = ($deviceURI,$jobID,$userName,$jobTitle,$copies,$printOptions,$printFile);
|
||||
|
||||
# Loop until $attempts trying the backend
|
||||
my $attempts = $BACKEND_ATTEMPTS;
|
||||
my $exitval = 1;
|
||||
while ($exitval){
|
||||
# Override arg0
|
||||
$exitval = system {"$backendDir/$realBackend"} @argvNew;
|
||||
$exitval >>= 8;
|
||||
if ($attempts > 0){
|
||||
$attempts--;
|
||||
if ($attempts == 0){
|
||||
unlink $tempFile;
|
||||
cleanExit($jid,$ENV{PRINTER},"ERROR: Backend failed!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Now the real backend is processing the job, and we loop to keep an eye
|
||||
# on the printer status until it is done.
|
||||
sleep 1;
|
||||
my $waitCount = 0;
|
||||
my $somethingPrinted = 0;
|
||||
$SIG{ALRM} = sub { cleanExit($jid,$ENV{PRINTER},"ERROR: Printer is stalled!\n") };
|
||||
while (1){
|
||||
alarm ($STALL_TIMEOUT);
|
||||
|
||||
# 3 is idle, 4 is printing, 5 is warmup, 1 is other
|
||||
my $prStatus = snmpGet($printerIP,$PRINTERSTATUS_OID,$jid);
|
||||
if ($prStatus == 4){
|
||||
print STDERR "INFO: Printer status: printing\n";
|
||||
$somethingPrinted = 1;
|
||||
}
|
||||
elsif (($prStatus != 4) && ($somethingPrinted)){
|
||||
$waitCount += 1;
|
||||
# Wait until status is idle for several counts
|
||||
if ($waitCount == 3){
|
||||
print STDERR "INFO: Job printed successfully\n";
|
||||
last;
|
||||
}
|
||||
}
|
||||
else{
|
||||
print STDERR "INFO: Printer status: other\n";
|
||||
}
|
||||
sleep 2;
|
||||
}
|
||||
|
||||
# SNMP pagecount: last snmp query
|
||||
my $postPageCount = snmpGet($printerIP,$PAGECOUNT_OID,$jid);
|
||||
|
||||
|
||||
### ACCOUNTING
|
||||
# Delta of our pagecounts
|
||||
my $totalPages = $postPageCount - $prePageCount;
|
||||
# Give a discount for header pages
|
||||
if ($headerDiscount > 0){
|
||||
$totalPages = $totalPages - $headerDiscount;
|
||||
if ($totalPages < 1){
|
||||
$totalPages = 0;
|
||||
}
|
||||
}
|
||||
# If no error from real backend (non-zero is error)...
|
||||
if (!$exitval){
|
||||
accounting($userName,$totalPages);
|
||||
}
|
||||
|
||||
|
||||
### CLEANUP/EXIT
|
||||
# If requested, write out a system log.
|
||||
if ( $LOGGING ) {
|
||||
open (LOG_FH, ">>$LOGGING_FILE") or $LOGGING = 0;
|
||||
flock LOG_FH, 2;
|
||||
seek LOG_FH, 0 , 2;
|
||||
printf LOG_FH "%04d-%02d-%02d\t%02d:%02d:%02d\t",$startTime[5]+1900,$startTime[4]+1,$startTime[3],$startTime[2],$startTime[1],$startTime[0];
|
||||
print LOG_FH "$printerIP\t$jobID\t$userName\t$jobTitle\t$copies\t$prePageCount\t$postPageCount\t$exitval\t$totalPages\t$headerDiscount\n";
|
||||
flock LOG_FH, 8;
|
||||
close (LOG_FH);
|
||||
}
|
||||
if ($DEBUG == 1){
|
||||
#print STDERR ("ERROR: $postPageCount minus $prePageCount equals $totalPages\n");
|
||||
debug($DEBUG_FILE);
|
||||
}
|
||||
if (!$SAVE_JOBS){
|
||||
unlink $tempFile;
|
||||
}
|
||||
exit $exitval;
|
||||
}
|
||||
|
||||
|
||||
sub cleanExit{
|
||||
# Args: jobid, queuename, error message to print
|
||||
# Returns: nothing, deletes job and re-enables queue
|
||||
my $jobid = shift;
|
||||
my $queue = shift;
|
||||
my $errorMsg = shift;
|
||||
|
||||
if ( length($errorMsg) > 0 ) {
|
||||
print STDERR $errorMsg;
|
||||
|
||||
if ( $ERROR_LOGGING == 1 ) {
|
||||
my @errorTime = localtime(time);
|
||||
|
||||
open (ERR_LOG_FH, ">>$ERROR_LOGGING_FILE") or $ERROR_LOGGING = 0;
|
||||
flock ERR_LOG_FH, 2;
|
||||
seek ERR_LOG_FH, 0 , 2;
|
||||
printf LOG_FH "%04d-%02d-%02d\t%02d:%02d:%02d\t",$errorTime[5]+1900,$errorTime[4]+1,$errorTime[3],$errorTime[2],$errorTime[1],$errorTime[0];
|
||||
print ERR_LOG_FH "$jobid\t$queue\t$errorMsg\n";
|
||||
flock ERR_LOG_FH, 8;
|
||||
close (ERR_LOG_FH);
|
||||
}
|
||||
}
|
||||
sleep 1;
|
||||
system("/usr/bin/lprm","$jobid");
|
||||
sleep 1;
|
||||
system("/usr/sbin/cupsenable","$queue");
|
||||
sleep 1;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
|
||||
sub snmpGet{
|
||||
# Args: ip, oid, jid
|
||||
# Returns: value of SNMP query. JobID needed only for exiting script cleanly if this fails.
|
||||
my $ip = shift;
|
||||
my $oid = shift;
|
||||
my $jid = shift;
|
||||
|
||||
# Creating the session should always succeed
|
||||
my ($session, $error) = Net::SNMP->session(
|
||||
-hostname => $ip,
|
||||
-version => 'snmpv1', #or 'snmpv2c' or 'snmpv3' as required
|
||||
-community => $SNMP_COMMUNITY,
|
||||
-timeout => $SNMP_TIMEOUT, #default, max: 60
|
||||
-retries => $SNMP_RETRIES #default, max: 20
|
||||
);
|
||||
# Paranoid check
|
||||
if (!defined($session)) {
|
||||
cleanExit($jid,$ENV{PRINTER},"ERROR: SNMP session creation error: $error\n");
|
||||
}
|
||||
|
||||
# The get request will loop until the alarm is tripped
|
||||
my $result;
|
||||
my $err;
|
||||
|
||||
eval{
|
||||
while(!defined($result)){
|
||||
$result = $session->get_request(
|
||||
-varbindlist => [$oid]
|
||||
);
|
||||
$err = $session->error;
|
||||
}
|
||||
alarm (0); # cancel the alarm
|
||||
};
|
||||
if ($@ =~ /SNMP ERROR/){
|
||||
cleanExit($jid,$ENV{PRINTER},"ERROR: SNMP Error: $err\n");
|
||||
}
|
||||
# Paranoid check. This is spurious because the eval loop won't let this happen.
|
||||
if (!defined($result)) {
|
||||
my $err = $session->error;
|
||||
$session->close;
|
||||
cleanExit($jid,$ENV{PRINTER},"ERROR: SNMP Error: $err\n");
|
||||
}
|
||||
|
||||
my $return = $result->{$oid};
|
||||
$session->close;
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
sub chkJobBlacklist{
|
||||
# Args: jobname
|
||||
# Returns: -1/bad | 1/good
|
||||
# This is not terribly safe, but can be terribly handy
|
||||
my $jobName = shift;
|
||||
|
||||
foreach my $blackJob (@JobBlacklist) {
|
||||
if ($blackJob =~ $jobName) { return -1; }
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub accounting{
|
||||
# Args: user, totalpages, printername
|
||||
# Returns: nothing, logs to page_log and writes to user file in accounting directory
|
||||
my $user = shift;
|
||||
my $newPages = shift; #what was printed this time
|
||||
|
||||
if ($user eq ""){
|
||||
$user = "NO_USER";
|
||||
}
|
||||
my $accFile = "$accDir/$user";
|
||||
|
||||
# If color printer from our printer accounting list, multiply pagecount by three
|
||||
#
|
||||
# Example accPrinterList:
|
||||
# Every queuename ends with colon, color queues add =COLOR=
|
||||
#
|
||||
# SAT104CL:=COLOR=
|
||||
# SAT325:
|
||||
# SIS217:
|
||||
#
|
||||
if (chkPrinterColor($ENV{PRINTER},$accPrinterList)){
|
||||
$newPages = $newPages*3;
|
||||
}
|
||||
|
||||
# Send nonstandard message to page_log (real wrapped backend will also send standard message)
|
||||
print STDERR ("PAGE: $user $newPages\n");
|
||||
|
||||
# And now handle their historical total
|
||||
# If accFile exists: get previous count, get total, write new count
|
||||
if (-e $accFile){
|
||||
my $histPages = getUserTotal($accFile);
|
||||
my $totPages = $newPages + $histPages;
|
||||
setUserTotal($accFile,$totPages);
|
||||
}
|
||||
# Else accFile does not exist: write out new accFile
|
||||
else{
|
||||
setUserTotal($accFile,$newPages);
|
||||
# Modify read permissions so accounting is secure
|
||||
chmod (0640,"$accFile");
|
||||
system ("chown","lp","$accFile");
|
||||
system ("chgrp",$user,"$accFile"); # Note: this doesn't work unless CUPS runs this backend as root!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub getUserTotal{
|
||||
# Args: accounting file
|
||||
# Returns: user's historical pagecount
|
||||
my $accFile = shift;
|
||||
my $histPages;
|
||||
open (FH, "$accFile") or warn "ERROR: Cannot read $accFile: $!\n";
|
||||
while(<FH>){
|
||||
$histPages = $histPages+$_; #extra safety in case of badly formatted file
|
||||
}
|
||||
close (FH);
|
||||
return $histPages;
|
||||
}
|
||||
|
||||
|
||||
sub setUserTotal{
|
||||
# Args: accounting file
|
||||
# Returns: nothing, writes to user's pagecount file
|
||||
my $accFile = shift;
|
||||
my $totPages = shift;
|
||||
open (OUT, ">$accFile") or warn "ERROR: Cannot write $accFile: $!\n";
|
||||
flock OUT, 2;
|
||||
print (OUT "$totPages\n");
|
||||
flock OUT, 8;
|
||||
close (OUT);
|
||||
}
|
||||
|
||||
|
||||
sub chkPrinterColor{
|
||||
# Args: printer, printerlistfile
|
||||
# Returns: 1/color printer | 0/not color printer
|
||||
my $printer = shift;
|
||||
my $accPrinterList = shift;
|
||||
open (FH, "$accPrinterList") or warn "Cannot read $accPrinterList: $!\n";
|
||||
while (<FH>){
|
||||
if (m/^$printer:=COLOR=/i){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
close FH;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
sub debug{
|
||||
# Args: debugging file
|
||||
# Returns: nothing, just write out some debug info
|
||||
my $debugFile = shift;
|
||||
my $date=`/bin/date +%T%t%D`;
|
||||
|
||||
open (OUT, ">>$debugFile");
|
||||
flock OUT, 2;
|
||||
seek OUT, 0, 2;
|
||||
print (OUT "\n=======================\n");
|
||||
|
||||
# print time
|
||||
print (OUT "\n$date\n");
|
||||
|
||||
# print args
|
||||
print (OUT "\narguments passed to backend:\n");
|
||||
my $i=0;
|
||||
foreach (@ARGV){
|
||||
print (OUT "$i:$_\t");
|
||||
$i++;
|
||||
}
|
||||
print (OUT "\n");
|
||||
|
||||
# print env
|
||||
print (OUT "\nenvironment variables:\n");
|
||||
for(keys(%ENV)) {
|
||||
print (OUT "$_ = $ENV{$_}\t");
|
||||
}
|
||||
print (OUT "\n");
|
||||
|
||||
print (OUT "\n=======================\n");
|
||||
flock OUT, 8;
|
||||
close (OUT);
|
||||
}
|
||||
|
||||
|
||||
sub getPrintQuota {
|
||||
# Args: accounting filedir, username
|
||||
# Returns: user's print quota
|
||||
#
|
||||
# * The user quota _always_ has first priority
|
||||
# * The group which gives the highest quota has second priority, e.g. will be used if
|
||||
# no user quota is found.
|
||||
# * The default quota _always_ has the lowest priority. It will only be used if no
|
||||
# other quota is found.
|
||||
#
|
||||
# Possible return values:
|
||||
# -2 No quota files found, printing not allowed.
|
||||
# -1 Unlimited printing allowed (no quota).
|
||||
# 0 Printing explictly not allowed.
|
||||
# n>0 Quota is n pages.
|
||||
|
||||
my $quotadir = shift;
|
||||
my $user = shift;
|
||||
my $acctQuota = -2; # A "no quota file found" error condition is the default.
|
||||
|
||||
# First, look for a per-user quota. This quota has top priority.
|
||||
my $quotaFile = ($quotadir,"/",$user,"_user_quota");
|
||||
if ( -e $quotaFile ) {
|
||||
$acctQuota = read_quota_file($quotaFile);
|
||||
}
|
||||
|
||||
# If there is no user quota, look for a per-group quota for each group the user is in.
|
||||
# The first one found is used. Otherwise, the default quota is still used.
|
||||
if ( ! -e $quotaFile ) {
|
||||
my ($name,$passwd,$gid,$members) = getgrent();
|
||||
|
||||
while ( length($name)>0 ) {
|
||||
# This next line will allow me to use a simple pattern match.
|
||||
my $testmembers = " " . $members . " ";
|
||||
|
||||
if ( $testmembers =~ /\s$user\s/ ) {
|
||||
my $testquotafile = $quotadir . "/" . $name . "_group_quota";
|
||||
my $testquota = read_quota_file($testquotafile);
|
||||
|
||||
if ( $testquota == -1 ) {
|
||||
$acctQuota = $testquota;
|
||||
last;
|
||||
} elsif ( $testquota > $acctQuota ) {
|
||||
$acctQuota = $testquota;
|
||||
}
|
||||
}
|
||||
|
||||
($name,$passwd,$gid,$members) = getgrent();
|
||||
}
|
||||
|
||||
# If no group quota was found either, use the default quota.
|
||||
if ( length($name) == 0 ) {
|
||||
$quotaFile = "$quotadir/print_quota";
|
||||
$acctQuota = read_quota_file($quotaFile);
|
||||
}
|
||||
}
|
||||
|
||||
return $acctQuota;
|
||||
}
|
||||
|
||||
|
||||
sub read_quota_file {
|
||||
# Arguments: file to read
|
||||
# Returns: user's current quota
|
||||
my $quotafile = shift;
|
||||
my $quota = -2; # An error condition is the default
|
||||
|
||||
open (FH, "$quotafile") or return ($quota);
|
||||
while(<FH>) {
|
||||
$quota = $_;
|
||||
}
|
||||
close (FH);
|
||||
|
||||
chomp($quota); # When editing files by hand, many people toss a newline in there.
|
||||
|
||||
return ($quota);
|
||||
}
|
Reference in New Issue
Block a user