Accepting request 34936 from Printing
checked in (request 34936) OBS-URL: https://build.opensuse.org/request/show/34936 OBS-URL: https://build.opensuse.org/package/show/Printing/cups?expand=0&rev=185
This commit is contained in:
parent
5ac5efc7dc
commit
e41832c940
499
PrintAnalyzer
Normal file
499
PrintAnalyzer
Normal file
@ -0,0 +1,499 @@
|
||||
#!/usr/bin/perl -w
|
||||
#***************************************************************************
|
||||
# PrintAnalyzer
|
||||
# Generate some stats from cups page_log file
|
||||
# copyright : (C) 1999 - 2002 by Thies Moeller
|
||||
# email : moeller@tu-harburg.de
|
||||
#***************************************************************************
|
||||
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* 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. *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
use strict;
|
||||
use warnings;
|
||||
use POSIX qw(strftime);
|
||||
use Time::Local;
|
||||
|
||||
##############
|
||||
# edit place of your page_log file
|
||||
##############
|
||||
|
||||
my $PAGE_LOG_FILE = "/var/log/cups/page_log";
|
||||
|
||||
##############
|
||||
# edit start and end of normal work time
|
||||
# activity outside this interval will be marked with an "!"
|
||||
# to disable set WorkStart to 0 and WorkEnd to 23
|
||||
##############
|
||||
my $WorkStart = 8;
|
||||
my $WorkEnd = 21;
|
||||
|
||||
|
||||
############################ nothing to modify below this line ##############
|
||||
|
||||
my %userRequests = ();
|
||||
my %userPages = ();
|
||||
my %hourRequests = ();
|
||||
my %dateRequests = ();
|
||||
my %datePages = ();
|
||||
my %pageRequests = ();
|
||||
my %queueRequests = ();
|
||||
my %queuePages = ();
|
||||
my %pageHeu = ();
|
||||
my %copyRequests = ();
|
||||
my %logline = ();
|
||||
my %lastlogline = ();
|
||||
my %billingStats = ();
|
||||
my $totalReq = 0;
|
||||
my $totalPages = 0;
|
||||
|
||||
sub DateCompare
|
||||
{
|
||||
my $date1 = substr($a, 6, 2) * 1024; # Years
|
||||
my $date2 = substr($b, 6, 2) * 1024;
|
||||
|
||||
$date1 += substr($a,3,2) * 64; # Months
|
||||
$date2 += substr($b,3,2) * 64;
|
||||
|
||||
$date1 += substr($a, 0, 2); # Days
|
||||
$date2 += substr($b, 0, 2);
|
||||
return ($date1 <=> $date2);
|
||||
}
|
||||
|
||||
|
||||
sub tzdiff2sec
|
||||
{
|
||||
## this method is copied from LogReport Time.pm
|
||||
## Copyright (C) 2000-2002 Stichting LogReport Foundation LogReport@LogReport.org
|
||||
|
||||
die "tzdiff2sec needs 1 arg\n"
|
||||
unless @_ == 1;
|
||||
|
||||
# e.g. +0100 or -0900 ; +hh:mm, +hhmm, or +hh
|
||||
my ( $sign, $hour, $min ) = $_[0] =~ /^([+-])?(\d\d):?(\d\d)?$/
|
||||
or die "invalid tzdiff format: $_[0]. It must looks like +0100 or -01:00\n";
|
||||
$sign ||= "+";
|
||||
$hour ||= 0;
|
||||
$min ||= 0;
|
||||
my $sec = $hour * 60 * 60 + $min * 60;
|
||||
$sec *= -1 if $sign eq '-';
|
||||
return $sec;
|
||||
}
|
||||
|
||||
sub getMonth
|
||||
{
|
||||
my $AllMonths= 'JanFebMarAprMayJunJulAugSepOctNovDec';
|
||||
my $month = shift(@_);
|
||||
return index($AllMonths, $month)/3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub DateTime2Epoch
|
||||
{
|
||||
my ($day,$month,$year,$hour,$min,$sec,$tz)=
|
||||
unpack'@1 A2 @4 A3 @8 A4 @13 A2 @16 A2 @19 A2 @22 A5', shift();
|
||||
|
||||
my $epoch=timegm $sec ,
|
||||
$min ,
|
||||
$hour,
|
||||
$day,
|
||||
getMonth($month),
|
||||
$year;
|
||||
return $epoch - tzdiff2sec($tz);
|
||||
}
|
||||
|
||||
sub PrintDayLog
|
||||
{
|
||||
my $dateReq;
|
||||
|
||||
############# Output Form ################
|
||||
format DAYLOG_TOP =
|
||||
|
||||
Daily Usage
|
||||
Date %Requests Pages
|
||||
-----------------------------------------
|
||||
.
|
||||
|
||||
format DAYLOG =
|
||||
@<<<<<<<<<<<<< @>>>>>>> @>>>>>>>
|
||||
$dateReq,$dateRequests{$dateReq},$datePages{$dateReq}
|
||||
.
|
||||
############# Output Form ################
|
||||
|
||||
|
||||
$-=0;
|
||||
$~="DAYLOG";
|
||||
$^="DAYLOG_TOP";
|
||||
foreach $dateReq (sort DateCompare keys %dateRequests)
|
||||
{
|
||||
#printf("Monat %d\n",getMonth($dateReq));
|
||||
write;
|
||||
}
|
||||
}
|
||||
|
||||
sub PrintUserLog
|
||||
{
|
||||
my $userReq;
|
||||
my $pageperjob;
|
||||
|
||||
############# Output Form ################
|
||||
format USERLOG_TOP =
|
||||
PrinterAccounting
|
||||
Username Requests Pages Pages/Request
|
||||
--------------------------------------------------------
|
||||
.
|
||||
|
||||
format USERLOG =
|
||||
@<<<<<<<<<<<<<<<<<< @>>>>>>> @>>>>>>> @>>>>>>>>
|
||||
$userReq, $userRequests{$userReq}, $userPages{$userReq}, $pageperjob
|
||||
.
|
||||
############# Output Form ################
|
||||
|
||||
$-=0;
|
||||
$~="USERLOG";
|
||||
$^="USERLOG_TOP";
|
||||
foreach $userReq (sort { $userPages{$b} <=> $userPages{$a}} keys %userRequests)
|
||||
{
|
||||
$pageperjob = sprintf("%5d", POSIX::ceil($userPages{$userReq} / $userRequests{$userReq}));
|
||||
write ;
|
||||
}
|
||||
}
|
||||
|
||||
sub PrintHourLog
|
||||
{
|
||||
my $hourReq;
|
||||
my $outOfWorkingTime;
|
||||
|
||||
############# Output Form ################
|
||||
format HOURLOG_TOP =
|
||||
Hour Usage
|
||||
Hour Requests
|
||||
---------------------
|
||||
.
|
||||
|
||||
format HOURLOG =
|
||||
@<@<<<<< @>>>>>>>
|
||||
$outOfWorkingTime,$hourReq,$hourRequests{$hourReq}
|
||||
.
|
||||
############# Output Form ################
|
||||
|
||||
|
||||
$-=0;
|
||||
$~="HOURLOG";
|
||||
$^="HOURLOG_TOP";
|
||||
|
||||
foreach $hourReq (sort {$a <=> $b} keys %hourRequests)
|
||||
{
|
||||
if($hourReq <$WorkStart || $hourReq > $WorkEnd)
|
||||
{
|
||||
if($hourRequests{$hourReq} == 0)
|
||||
{
|
||||
next;
|
||||
}
|
||||
else
|
||||
{
|
||||
$outOfWorkingTime = "!";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$outOfWorkingTime = " ";
|
||||
}
|
||||
write;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub PrintRequestSize
|
||||
{
|
||||
my $pageReq;
|
||||
my %pageHeu;
|
||||
my $pageHeuK;
|
||||
my $pageperHeu;
|
||||
############# Output Form ################
|
||||
|
||||
format REQUESTLOG_TOP =
|
||||
Heuristic
|
||||
JobSize %Requests
|
||||
---------------------------
|
||||
.
|
||||
|
||||
format REQUESTLOG =
|
||||
@||||||||||| @>>>>>>>>
|
||||
$pageHeuK,$pageperHeu
|
||||
.
|
||||
############# Output Form ################
|
||||
|
||||
# sammeln der Daten
|
||||
foreach $pageReq (sort {$a <=> $b} keys %pageRequests)
|
||||
{
|
||||
if($pageReq >0 && $pageReq <=10)
|
||||
{$pageHeu{"1. 0-10"}+=$pageRequests{$pageReq}};
|
||||
if ($pageReq >10 && $pageReq <=20)
|
||||
{$pageHeu{ "2. 20-30"}+=$pageRequests{$pageReq}};
|
||||
if ($pageReq >20 && $pageReq <=30)
|
||||
{$pageHeu{ "3. 30-40"}+=$pageRequests{$pageReq}};
|
||||
if ($pageReq >40 && $pageReq <=50)
|
||||
{$pageHeu{ "4. 40-50"}+=$pageRequests{$pageReq}};
|
||||
if ($pageReq >50 && $pageReq <=100)
|
||||
{$pageHeu{ "5. 50-100"}+=$pageRequests{$pageReq}};
|
||||
if ($pageReq >100 && $pageReq <=200)
|
||||
{$pageHeu{ "6. 100-200"}+=$pageRequests{$pageReq}};
|
||||
if ($pageReq >200 )
|
||||
{$pageHeu{ "7. 200- "}+=$pageRequests{$pageReq}};
|
||||
}
|
||||
$-=0;
|
||||
$~="REQUESTLOG";
|
||||
$^="REQUESTLOG_TOP";
|
||||
|
||||
foreach $pageHeuK (sort keys %pageHeu)
|
||||
{
|
||||
$pageperHeu = sprintf("%5.2f", 100*$pageHeu{$pageHeuK}/$totalReq);
|
||||
write;
|
||||
}
|
||||
}
|
||||
|
||||
sub PrintCopySize
|
||||
{
|
||||
my $copyReq;
|
||||
my %copyHeu;
|
||||
my $copyHeuK;
|
||||
my $copyperheu;
|
||||
############# Output Form ################
|
||||
format COPY_TOP =
|
||||
Heuristic
|
||||
Copies %Requests
|
||||
---------------------------
|
||||
.
|
||||
format COPYLOG =
|
||||
@||||||||||||| @>>>>>>>>
|
||||
$copyHeuK,$copyperheu
|
||||
.
|
||||
############# Output Form ################
|
||||
|
||||
|
||||
foreach $copyReq (sort {$a <=> $b} keys %copyRequests)
|
||||
{
|
||||
if($copyReq == 1 )
|
||||
{$copyHeu{" 1. single"}+=$copyRequests{$copyReq}};
|
||||
if($copyReq == 2)
|
||||
{$copyHeu{" 2. 2 "}+=$copyRequests{$copyReq}};
|
||||
if($copyReq == 3)
|
||||
{$copyHeu{" 3. 3 "}+=$copyRequests{$copyReq}};
|
||||
if($copyReq == 4)
|
||||
{$copyHeu{" 4. 4 "}+=$copyRequests{$copyReq}};
|
||||
if($copyReq >=5 && $copyReq <=10)
|
||||
{$copyHeu{" 5. 5-10 "}+=$copyRequests{$copyReq}};
|
||||
if ($copyReq >10 && $copyReq <=20)
|
||||
{$copyHeu{ " 6. 20-30 "}+=$copyRequests{$copyReq}};
|
||||
if ($copyReq >20 && $copyReq <=30)
|
||||
{$copyHeu{ " 7. 30-40 "}+=$copyRequests{$copyReq}};
|
||||
if ($copyReq >40 && $copyReq <=50)
|
||||
{$copyHeu{ " 8. 40-50 "}+=$copyRequests{$copyReq}};
|
||||
if ($copyReq >50 && $copyReq <=100)
|
||||
{$copyHeu{ " 9. 50-100 "}+=$copyRequests{$copyReq}};
|
||||
if ($copyReq >100 && $copyReq <=200)
|
||||
{$copyHeu{ "10. 100-200 "}+=$copyRequests{$copyReq}};
|
||||
if ($copyReq >200 )
|
||||
{$copyHeu{ "11. 200- "}+=$copyRequests{$copyReq}};
|
||||
}
|
||||
$-=0;
|
||||
$~="COPYLOG";
|
||||
$^="COPY_TOP";
|
||||
foreach $copyHeuK (sort keys %copyHeu)
|
||||
{
|
||||
$copyperheu = sprintf("%5.2f", 100*$copyHeu{$copyHeuK}/$totalReq);
|
||||
write;
|
||||
}
|
||||
}
|
||||
|
||||
sub PrintQueueLog
|
||||
{
|
||||
my $queueReq;
|
||||
my $reqperqueue;
|
||||
my $pagepermin;
|
||||
my $pageperqueue ;
|
||||
############# Output Form ################
|
||||
format QUEUELOG_TOP =
|
||||
Queue Heuristic
|
||||
Queue %Requests %Pages Pages
|
||||
--------------------------------------------------------------
|
||||
.
|
||||
|
||||
format QUEUELOG =
|
||||
@>>>>>>>>>>>>>>>>>>>>> @>>>>>>> @>>>>>>> @>>>>>>>>
|
||||
$queueReq,$reqperqueue,$pageperqueue,$queuePages{$queueReq}
|
||||
.
|
||||
############# Output Form ################
|
||||
|
||||
|
||||
$-=0;
|
||||
$~="QUEUELOG";
|
||||
$^="QUEUELOG_TOP";
|
||||
foreach $queueReq (sort { $queuePages{$b} <=> $queuePages{$a} } keys %queuePages)
|
||||
{
|
||||
$reqperqueue = sprintf("%5.2f", 100*$queueRequests{$queueReq}/$totalReq);
|
||||
$pageperqueue = sprintf("%5.2f", 100*$queuePages{$queueReq}/$totalPages);
|
||||
write;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub PrintBillingLog
|
||||
{
|
||||
my $billing;
|
||||
my $pageperbilling ;
|
||||
my $billinguser;
|
||||
|
||||
############# Output Form ################
|
||||
format BILLINGLOG_TOP =
|
||||
Billing Heuristic
|
||||
Billing Pages
|
||||
--------------------------------------------------------------
|
||||
.
|
||||
|
||||
format BILLINGLOG =
|
||||
@<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>
|
||||
$billing,$pageperbilling
|
||||
.
|
||||
|
||||
format BILLINGUSERLOG =
|
||||
|- @>>>>>>>>>>>>>>>>>>>>> @>>>>>>>>
|
||||
$billinguser,$pageperbilling
|
||||
.
|
||||
############# Output Form ################
|
||||
|
||||
|
||||
$-=0;
|
||||
$~="BILLINGLOG";
|
||||
$^="BILLINGLOG_TOP";
|
||||
foreach $billing (sort keys %billingStats)
|
||||
{
|
||||
$pageperbilling = $billingStats{$billing}{"total_pages"};
|
||||
$~="BILLINGLOG";
|
||||
write;
|
||||
$~="BILLINGUSERLOG";
|
||||
foreach $billinguser ( sort {$billingStats{$billing}{"user"}{$b} <=> $billingStats{$billing}{"user"}{$a}} keys %{$billingStats{$billing}{"user"}})
|
||||
{
|
||||
$pageperbilling = $billingStats{$billing}{"user"}{$billinguser};
|
||||
write;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub HandleNewJob
|
||||
{
|
||||
my $realpages = $lastlogline{num_pages}*$lastlogline{copies};
|
||||
my $hourstring = POSIX::strftime "%H", localtime($lastlogline{time}) ;
|
||||
my $daystring = POSIX::strftime "%d/%m/%y", localtime($lastlogline{time}) ;
|
||||
|
||||
$userRequests{$lastlogline{user}}++;
|
||||
$userPages{$lastlogline{user}}+=$realpages;
|
||||
$dateRequests{$daystring}++;
|
||||
$datePages{$daystring}+=$realpages;
|
||||
$pageRequests{$realpages}++;
|
||||
$queueRequests{$lastlogline{printer}}++;
|
||||
$queuePages{$lastlogline{printer}}+=$realpages;
|
||||
$hourRequests{$hourstring}++;
|
||||
$copyRequests{$lastlogline{copies}}++;
|
||||
$billingStats{$lastlogline{billing}}{"user"}{$lastlogline{user}} += $realpages;
|
||||
$billingStats{$lastlogline{billing}}{"printer"}{$lastlogline{printer}} += $realpages;
|
||||
$billingStats{$lastlogline{billing}}{"total_pages"} += $realpages;
|
||||
|
||||
$totalReq++;
|
||||
$totalPages+=$realpages;
|
||||
|
||||
}
|
||||
|
||||
sub InitHourHistogram
|
||||
{
|
||||
my $i;
|
||||
for ($i = 0 ; $i <=24 ; $i++)
|
||||
{
|
||||
my $hourstring = sprintf("%02d", $i);
|
||||
$hourRequests{$hourstring}=0;
|
||||
}
|
||||
}
|
||||
|
||||
# main
|
||||
open(PAGELOG,"$PAGE_LOG_FILE") || die "Can't open pagelog file $PAGE_LOG_FILE";
|
||||
|
||||
|
||||
#initialize the hourhistogram
|
||||
InitHourHistogram;
|
||||
|
||||
while(<PAGELOG>)
|
||||
{
|
||||
my $time;
|
||||
my $pagenum;
|
||||
%logline = ();
|
||||
chomp();
|
||||
($logline{printer},
|
||||
$logline{user},
|
||||
$logline{jobid},
|
||||
$time,
|
||||
$pagenum,
|
||||
$logline{copies},
|
||||
$logline{billing}) =
|
||||
($_ =~ /^(.*)\s(.*)\s(\d+)\s(\[.*\])\s(\d+)\s(\d+)\s(.*)$/)
|
||||
or do {
|
||||
print STDERR "Cannot convert $_ \n";
|
||||
next;
|
||||
};
|
||||
# downcase username because of samba
|
||||
$logline{user}=~ tr/A-Z/a-z/;
|
||||
# handle empty user
|
||||
if ($logline{user} eq "") {
|
||||
$logline{user}="TestPages";
|
||||
}
|
||||
# handle empty billing code
|
||||
if ($logline{billing} eq "") {
|
||||
$logline{billing}="-none-";
|
||||
}
|
||||
my $endtime = DateTime2Epoch( $time );
|
||||
|
||||
if ( ! defined $lastlogline{jobid} || $lastlogline{jobid} ne $logline{jobid} )
|
||||
{
|
||||
# new job;
|
||||
$logline{num_pages} = 1;
|
||||
$logline{time} = $endtime;
|
||||
if ( defined $lastlogline{jobid} ) {
|
||||
HandleNewJob;
|
||||
};
|
||||
} else {
|
||||
# same job; update info
|
||||
$logline{num_pages} = $lastlogline{num_pages} + 1;
|
||||
$logline{time} = $lastlogline{time};
|
||||
}
|
||||
%lastlogline= %logline;
|
||||
|
||||
}
|
||||
close(PAGELOG);
|
||||
|
||||
# handle last job
|
||||
if ( defined $lastlogline{jobid} ) {
|
||||
HandleNewJob;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PrintQueueLog;
|
||||
PrintRequestSize;
|
||||
PrintCopySize;
|
||||
PrintBillingLog;
|
||||
PrintUserLog;
|
||||
PrintHourLog;
|
||||
PrintDayLog;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
23
cups-1.1.21-testppd_duplex.patch
Normal file
23
cups-1.1.21-testppd_duplex.patch
Normal file
@ -0,0 +1,23 @@
|
||||
Index: cups-1.3.11/systemv/cupstestppd.c
|
||||
===================================================================
|
||||
--- cups-1.3.11.orig/systemv/cupstestppd.c
|
||||
+++ cups-1.3.11/systemv/cupstestppd.c
|
||||
@@ -931,6 +931,7 @@ main(int argc, /* I - Number of comm
|
||||
if (size->left == 0.0 && size->bottom == 0.0 &&
|
||||
size->right == 0.0 && size->top == 0.0)
|
||||
{
|
||||
+#if 0
|
||||
if (verbose >= 0)
|
||||
{
|
||||
if (!errors && !verbose)
|
||||
@@ -945,6 +946,10 @@ main(int argc, /* I - Number of comm
|
||||
}
|
||||
|
||||
errors ++;
|
||||
+#else
|
||||
+ printf(" WARN Bad %s choice %s!\n",
|
||||
+ option->keyword, choice->choice);
|
||||
+#endif
|
||||
}
|
||||
|
||||
/*
|
99
cups-1.2.0-ppdsdat_generation.patch
Normal file
99
cups-1.2.0-ppdsdat_generation.patch
Normal file
@ -0,0 +1,99 @@
|
||||
Index: cups-1.3.11/scheduler/main.c
|
||||
===================================================================
|
||||
--- cups-1.3.11.orig/scheduler/main.c
|
||||
+++ cups-1.3.11/scheduler/main.c
|
||||
@@ -172,6 +172,7 @@ main(int argc, /* I - Number of comm
|
||||
*/
|
||||
|
||||
fg = 0;
|
||||
+ ppds_generation = 0;
|
||||
|
||||
#ifdef HAVE_LAUNCHD
|
||||
if (getenv("CUPSD_LAUNCHD"))
|
||||
@@ -272,6 +273,10 @@ main(int argc, /* I - Number of comm
|
||||
fg = 1;
|
||||
break;
|
||||
|
||||
+ case 'P' : /* generate ppds only */
|
||||
+ ppds_generation = 1;
|
||||
+ break;
|
||||
+
|
||||
default : /* Unknown option */
|
||||
_cupsLangPrintf(stderr, _("cupsd: Unknown option \"%c\" - "
|
||||
"aborting!\n"), *opt);
|
||||
@@ -340,17 +345,18 @@ main(int argc, /* I - Number of comm
|
||||
perror("cupsd");
|
||||
return (1);
|
||||
}
|
||||
- else if (WIFEXITED(i))
|
||||
+ else if (!ppds_generation && WIFEXITED(i))
|
||||
{
|
||||
fprintf(stderr, "cupsd: Child exited with status %d!\n",
|
||||
WEXITSTATUS(i));
|
||||
return (2);
|
||||
}
|
||||
- else
|
||||
+ else if (!ppds_generation || WTERMSIG(i)!=0)
|
||||
{
|
||||
fprintf(stderr, "cupsd: Child exited on signal %d!\n", WTERMSIG(i));
|
||||
return (3);
|
||||
- }
|
||||
+ } else
|
||||
+ return (0);
|
||||
}
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
@@ -625,6 +631,9 @@ main(int argc, /* I - Number of comm
|
||||
}
|
||||
#endif /* __sgi */
|
||||
|
||||
+ if (ppds_generation > 0)
|
||||
+ return (stop_scheduler);
|
||||
+
|
||||
/*
|
||||
* Initialize authentication certificates...
|
||||
*/
|
||||
@@ -2031,13 +2040,14 @@ static void
|
||||
usage(int status) /* O - Exit status */
|
||||
{
|
||||
_cupsLangPuts(status ? stderr : stdout,
|
||||
- _("Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n"
|
||||
+ _("Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l] [-P]\n"
|
||||
"\n"
|
||||
"-c config-file Load alternate configuration file\n"
|
||||
"-f Run in the foreground\n"
|
||||
"-F Run in the foreground but detach\n"
|
||||
"-h Show this usage message\n"
|
||||
- "-l Run cupsd from launchd(8)\n"));
|
||||
+ "-l Run cupsd from launchd(8)\n"
|
||||
+ "-P Generate ppds.dat and exit\n"));
|
||||
exit(status);
|
||||
}
|
||||
|
||||
Index: cups-1.3.11/scheduler/cupsd.h
|
||||
===================================================================
|
||||
--- cups-1.3.11.orig/scheduler/cupsd.h
|
||||
+++ cups-1.3.11/scheduler/cupsd.h
|
||||
@@ -180,6 +180,8 @@ VAR PSQUpdateQuotaProcPtr PSQUpdateQuota
|
||||
|
||||
|
||||
|
||||
+VAR int ppds_generation;/* Generate ppds.dat and exit() */
|
||||
+
|
||||
|
||||
/*
|
||||
* Prototypes...
|
||||
Index: cups-1.3.11/scheduler/conf.c
|
||||
===================================================================
|
||||
--- cups-1.3.11.orig/scheduler/conf.c
|
||||
+++ cups-1.3.11/scheduler/conf.c
|
||||
@@ -941,6 +941,9 @@ cupsdReadConfiguration(void)
|
||||
return (0);
|
||||
}
|
||||
|
||||
+ if (ppds_generation > 0)
|
||||
+ return(1);
|
||||
+
|
||||
/*
|
||||
* Setup environment variables...
|
||||
*/
|
29
cups-1.2.11-testppd_filename.patch
Normal file
29
cups-1.2.11-testppd_filename.patch
Normal file
@ -0,0 +1,29 @@
|
||||
Index: cups-1.3.11/systemv/cupstestppd.c
|
||||
===================================================================
|
||||
--- cups-1.3.11.orig/systemv/cupstestppd.c
|
||||
+++ cups-1.3.11/systemv/cupstestppd.c
|
||||
@@ -129,6 +129,7 @@ main(int argc, /* I - Number of comm
|
||||
int i, j, k, m, n; /* Looping vars */
|
||||
int len; /* Length of option name */
|
||||
char *opt; /* Option character */
|
||||
+ char *ppdfilename; /* Pointer to actual PPD file */
|
||||
const char *ptr; /* Pointer into string */
|
||||
int files; /* Number of files */
|
||||
int verbose; /* Want verbose output? */
|
||||
@@ -375,6 +376,7 @@ main(int argc, /* I - Number of comm
|
||||
|
||||
errors = 0;
|
||||
ppdversion = 43;
|
||||
+ ppdfilename = argv[i];
|
||||
|
||||
if (verbose > 0)
|
||||
_cupsLangPuts(stdout,
|
||||
@@ -1171,7 +1173,7 @@ main(int argc, /* I - Number of comm
|
||||
|
||||
if (verbose >= 0)
|
||||
{
|
||||
- check_basics(argv[i]);
|
||||
+ check_basics(ppdfilename);
|
||||
|
||||
if (warn & WARN_CONSTRAINTS)
|
||||
errors = check_constraints(ppd, errors, verbose, 1);
|
54
cups-1.2.7-libwrap.patch
Normal file
54
cups-1.2.7-libwrap.patch
Normal file
@ -0,0 +1,54 @@
|
||||
*** cups-1.2.7/scheduler/Makefile.orig Mon Sep 11 20:30:09 2006
|
||||
--- cups-1.2.7/scheduler/Makefile Tue Feb 13 17:56:10 2007
|
||||
*************** TARGETS = \
|
||||
*** 77,82 ****
|
||||
--- 77,83 ----
|
||||
testspeed \
|
||||
testsub
|
||||
|
||||
+ CUPSDLIBS += -lwrap
|
||||
|
||||
#
|
||||
# Make everything...
|
||||
--- cups-1.2.7/scheduler/client.c.orig 2006-11-15 21:28:39.000000000 +0100
|
||||
+++ cups-1.2.7/scheduler/client.c 2007-02-13 19:10:38.000000000 +0100
|
||||
@@ -65,6 +65,11 @@
|
||||
# include <gnutls/x509.h>
|
||||
#endif /* HAVE_GNUTLS */
|
||||
|
||||
+#include <tcpd.h>
|
||||
+#include <syslog.h>
|
||||
+int allow_severity = LOG_INFO;
|
||||
+int deny_severity = LOG_WARNING;
|
||||
+
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
@@ -180,6 +185,27 @@ cupsdAcceptClient(cupsd_listener_t *lis)
|
||||
con->http.hostaddr->ipv4.sin_port = lis->address.ipv4.sin_port;
|
||||
|
||||
/*
|
||||
+ * libwrap/tcp_wrappers:
|
||||
+ * draht@suse.de, Tue Jan 29 2002
|
||||
+ * kssingvo@suse.de, Thu Feb 01 2007
|
||||
+ */
|
||||
+
|
||||
+ if (lis->address.addr.sa_family == AF_INET || lis->address.addr.sa_family == AF_INET6) {
|
||||
+ struct request_info wrap_req;
|
||||
+
|
||||
+ request_init(&wrap_req, RQ_DAEMON, "cupsd" , RQ_FILE, con->http.fd, NULL);
|
||||
+ fromhost(&wrap_req);
|
||||
+ if (!hosts_access(&wrap_req)) { /* we do not accept the connection: */
|
||||
+ cupsdLogMessage(CUPSD_LOG_WARN,
|
||||
+ "tcp_wrappers refused connection from %s, ip=%s. See /etc/hosts.allow and /etc/hosts.deny.",
|
||||
+ eval_client(&wrap_req), eval_hostaddr(wrap_req.client));
|
||||
+ close(con->http.fd);
|
||||
+ free(con);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Check the number of clients on the same address...
|
||||
*/
|
||||
|
27
cups-1.3.11-CVE-2009-2820-regression-fix.patch
Normal file
27
cups-1.3.11-CVE-2009-2820-regression-fix.patch
Normal file
@ -0,0 +1,27 @@
|
||||
--- cgi-bin/admin.c.after-cups-1.3.11-CVE-2009-2820-patch 2009-11-03 12:33:53.000000000 +0100
|
||||
+++ cgi-bin/admin.c 2009-11-03 12:37:37.000000000 +0100
|
||||
@@ -486,6 +486,7 @@ do_am_class(http_t *http, /* I - HTTP c
|
||||
ipp_attribute_t *attr; /* member-uris attribute */
|
||||
char uri[HTTP_MAX_URI]; /* Device or printer URI */
|
||||
const char *name, /* Pointer to class name */
|
||||
+ *op, /* Operation name */
|
||||
*ptr; /* Pointer to CGI variable */
|
||||
const char *title; /* Title of page */
|
||||
static const char * const pattrs[] = /* Requested printer attributes */
|
||||
@@ -497,6 +498,7 @@ do_am_class(http_t *http, /* I - HTTP c
|
||||
|
||||
|
||||
title = cgiText(modify ? _("Modify Class") : _("Add Class"));
|
||||
+ op = cgiGetVariable("OP");
|
||||
name = cgiGetVariable("PRINTER_NAME");
|
||||
|
||||
if (cgiGetVariable("PRINTER_LOCATION") == NULL)
|
||||
@@ -516,6 +518,8 @@ do_am_class(http_t *http, /* I - HTTP c
|
||||
*/
|
||||
|
||||
cgiClearVariables();
|
||||
+ if (op)
|
||||
+ cgiSetVariable("OP", op);
|
||||
if (name)
|
||||
cgiSetVariable("PRINTER_NAME", name);
|
||||
|
424
cups-1.3.11-CVE-2009-2820.patch
Normal file
424
cups-1.3.11-CVE-2009-2820.patch
Normal file
@ -0,0 +1,424 @@
|
||||
diff -upr cups-1.3.11.orig/cgi-bin/admin.c cups-1.3.11/cgi-bin/admin.c
|
||||
--- cups-1.3.11.orig/cgi-bin/admin.c 2009-06-18 23:42:45.000000000 +0200
|
||||
+++ cups-1.3.11/cgi-bin/admin.c 2009-10-21 11:43:02.000000000 +0200
|
||||
@@ -104,6 +104,7 @@ main(int argc, /* I - Number of comm
|
||||
*/
|
||||
|
||||
cgiSetVariable("SECTION", "admin");
|
||||
+ cgiSetVariable("REFRESH_PAGE", "");
|
||||
|
||||
/*
|
||||
* See if we have form data...
|
||||
@@ -134,16 +135,61 @@ main(int argc, /* I - Number of comm
|
||||
|
||||
|
||||
if (getenv("HTTPS"))
|
||||
- snprintf(prefix, sizeof(prefix), "https://%s:%s",
|
||||
- getenv("SERVER_NAME"), getenv("SERVER_PORT"));
|
||||
+ snprintf(prefix, sizeof(prefix), "https://%s:%s",
|
||||
+ getenv("SERVER_NAME"), getenv("SERVER_PORT"));
|
||||
else
|
||||
- snprintf(prefix, sizeof(prefix), "http://%s:%s",
|
||||
- getenv("SERVER_NAME"), getenv("SERVER_PORT"));
|
||||
+ snprintf(prefix, sizeof(prefix), "http://%s:%s",
|
||||
+ getenv("SERVER_NAME"), getenv("SERVER_PORT"));
|
||||
+
|
||||
+ fprintf(stderr, "DEBUG: redirecting with prefix %s!\n", prefix);
|
||||
|
||||
if ((url = cgiGetVariable("URL")) != NULL)
|
||||
- printf("Location: %s%s\n\n", prefix, url);
|
||||
+ {
|
||||
+ char encoded[1024], /* Encoded URL string */
|
||||
+ *ptr; /* Pointer into encoded string */
|
||||
+
|
||||
+
|
||||
+ ptr = encoded;
|
||||
+ if (*url != '/')
|
||||
+ *ptr++ = '/';
|
||||
+
|
||||
+ for (; *url && ptr < (encoded + sizeof(encoded) - 4); url ++)
|
||||
+ {
|
||||
+ if (strchr("%@&+ <>#=", *url) || *url < ' ' || *url & 128)
|
||||
+ {
|
||||
+ /*
|
||||
+ * Percent-encode this character; safe because we have at least 4
|
||||
+ * bytes left in the array...
|
||||
+ */
|
||||
+
|
||||
+ sprintf(ptr, "%%%02X", *url & 255);
|
||||
+ ptr += 3;
|
||||
+ }
|
||||
+ else
|
||||
+ *ptr++ = *url;
|
||||
+ }
|
||||
+
|
||||
+ *ptr = '\0';
|
||||
+
|
||||
+ if (*url)
|
||||
+ {
|
||||
+ /*
|
||||
+ * URL was too long, just redirect to the admin page...
|
||||
+ */
|
||||
+
|
||||
+ printf("Location: %s/admin\n\n", prefix);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /*
|
||||
+ * URL is OK, redirect there...
|
||||
+ */
|
||||
+
|
||||
+ printf("Location: %s%s\n\n", prefix, encoded);
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
- printf("Location: %s/admin\n\n", prefix);
|
||||
+ printf("Location: %s/admin\n\n", prefix);
|
||||
}
|
||||
else if (!strcmp(op, "start-printer"))
|
||||
do_printer_op(http, IPP_RESUME_PRINTER, cgiText(_("Start Printer")));
|
||||
@@ -293,6 +339,31 @@ do_add_rss_subscription(http_t *http) /*
|
||||
* and classes and (re)show the add page...
|
||||
*/
|
||||
|
||||
+ if (cgiGetVariable("EVENT_JOB_CREATED"))
|
||||
+ cgiSetVariable("EVENT_JOB_CREATED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_JOB_COMPLETED"))
|
||||
+ cgiSetVariable("EVENT_JOB_COMPLETED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_JOB_STOPPED"))
|
||||
+ cgiSetVariable("EVENT_JOB_STOPPED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_JOB_CONFIG_CHANGED"))
|
||||
+ cgiSetVariable("EVENT_JOB_CONFIG_CHANGED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_PRINTER_STOPPED"))
|
||||
+ cgiSetVariable("EVENT_PRINTER_STOPPED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_PRINTER_ADDED"))
|
||||
+ cgiSetVariable("EVENT_PRINTER_ADDED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_PRINTER_MODIFIED"))
|
||||
+ cgiSetVariable("EVENT_PRINTER_MODIFIED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_PRINTER_DELETED"))
|
||||
+ cgiSetVariable("EVENT_PRINTER_DELETED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_SERVER_STARTED"))
|
||||
+ cgiSetVariable("EVENT_SERVER_STARTED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_SERVER_STOPPED"))
|
||||
+ cgiSetVariable("EVENT_SERVER_STOPPED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_SERVER_RESTARTED"))
|
||||
+ cgiSetVariable("EVENT_SERVER_RESTARTED", "CHECKED");
|
||||
+ if (cgiGetVariable("EVENT_SERVER_AUDIT"))
|
||||
+ cgiSetVariable("EVENT_SERVER_AUDIT", "CHECKED");
|
||||
+
|
||||
request = ippNewRequest(CUPS_GET_PRINTERS);
|
||||
response = cupsDoRequest(http, request, "/");
|
||||
|
||||
@@ -450,6 +521,10 @@ do_am_class(http_t *http, /* I - HTTP c
|
||||
* Do the request and get back a response...
|
||||
*/
|
||||
|
||||
+ cgiClearVariables();
|
||||
+ if (name)
|
||||
+ cgiSetVariable("PRINTER_NAME", name);
|
||||
+
|
||||
if ((response = cupsDoRequest(http, request, "/")) != NULL)
|
||||
{
|
||||
/*
|
||||
@@ -2336,7 +2411,9 @@ do_menu(http_t *http) /* I - HTTP conn
|
||||
if ((val = cupsGetOption("DefaultAuthType", num_settings,
|
||||
settings)) != NULL && !strcasecmp(val, "Negotiate"))
|
||||
cgiSetVariable("KERBEROS", "CHECKED");
|
||||
+ else
|
||||
#endif /* HAVE_GSSAPI */
|
||||
+ cgiSetVariable("KERBEROS", "");
|
||||
|
||||
cupsFreeOptions(num_settings, settings);
|
||||
|
||||
diff -upr cups-1.3.11.orig/cgi-bin/cgi.h cups-1.3.11/cgi-bin/cgi.h
|
||||
--- cups-1.3.11.orig/cgi-bin/cgi.h 2008-07-12 00:48:49.000000000 +0200
|
||||
+++ cups-1.3.11/cgi-bin/cgi.h 2009-10-21 11:42:42.000000000 +0200
|
||||
@@ -54,6 +54,7 @@ typedef struct cgi_file_s /**** Uploade
|
||||
extern void cgiAbort(const char *title, const char *stylesheet,
|
||||
const char *format, ...);
|
||||
extern int cgiCheckVariables(const char *names);
|
||||
+extern void cgiClearVariables(void);
|
||||
extern void *cgiCompileSearch(const char *query);
|
||||
extern void cgiCopyTemplateFile(FILE *out, const char *tmpl);
|
||||
extern void cgiCopyTemplateLang(const char *tmpl);
|
||||
diff -upr cups-1.3.11.orig/cgi-bin/classes.c cups-1.3.11/cgi-bin/classes.c
|
||||
--- cups-1.3.11.orig/cgi-bin/classes.c 2008-07-12 00:48:49.000000000 +0200
|
||||
+++ cups-1.3.11/cgi-bin/classes.c 2009-10-21 11:43:16.000000000 +0200
|
||||
@@ -69,6 +69,7 @@ main(int argc, /* I - Number of comm
|
||||
*/
|
||||
|
||||
cgiSetVariable("SECTION", "classes");
|
||||
+ cgiSetVariable("REFRESH_PAGE", "");
|
||||
|
||||
/*
|
||||
* See if we are displaying a printer or all classes...
|
||||
diff -upr cups-1.3.11.orig/cgi-bin/help.c cups-1.3.11/cgi-bin/help.c
|
||||
--- cups-1.3.11.orig/cgi-bin/help.c 2008-07-12 00:48:49.000000000 +0200
|
||||
+++ cups-1.3.11/cgi-bin/help.c 2009-10-21 11:43:06.000000000 +0200
|
||||
@@ -63,6 +63,7 @@ main(int argc, /* I - Number of comm
|
||||
*/
|
||||
|
||||
cgiSetVariable("SECTION", "help");
|
||||
+ cgiSetVariable("REFRESH_PAGE", "");
|
||||
|
||||
/*
|
||||
* Load the help index...
|
||||
@@ -102,7 +103,7 @@ main(int argc, /* I - Number of comm
|
||||
*/
|
||||
|
||||
for (i = 0; i < argc; i ++)
|
||||
- fprintf(stderr, "argv[%d]=\"%s\"\n", i, argv[i]);
|
||||
+ fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);
|
||||
|
||||
if ((helpfile = getenv("PATH_INFO")) != NULL)
|
||||
{
|
||||
@@ -179,6 +180,12 @@ main(int argc, /* I - Number of comm
|
||||
topic = cgiGetVariable("TOPIC");
|
||||
si = helpSearchIndex(hi, query, topic, helpfile);
|
||||
|
||||
+ cgiClearVariables();
|
||||
+ if (query)
|
||||
+ cgiSetVariable("QUERY", query);
|
||||
+ if (topic)
|
||||
+ cgiSetVariable("TOPIC", topic);
|
||||
+
|
||||
fprintf(stderr, "DEBUG: query=\"%s\", topic=\"%s\"\n",
|
||||
query ? query : "(null)", topic ? topic : "(null)");
|
||||
|
||||
diff -upr cups-1.3.11.orig/cgi-bin/ipp-var.c cups-1.3.11/cgi-bin/ipp-var.c
|
||||
--- cups-1.3.11.orig/cgi-bin/ipp-var.c 2009-03-05 19:44:14.000000000 +0100
|
||||
+++ cups-1.3.11/cgi-bin/ipp-var.c 2009-10-21 11:42:57.000000000 +0200
|
||||
@@ -1220,7 +1220,9 @@ cgiShowJobs(http_t *http, /* I - Co
|
||||
int ascending, /* Order of jobs (0 = descending) */
|
||||
first, /* First job to show */
|
||||
count; /* Number of jobs */
|
||||
- const char *var; /* Form variable */
|
||||
+ const char *var, /* Form variable */
|
||||
+ *query, /* Query string */
|
||||
+ *section; /* Section in web interface */
|
||||
void *search; /* Search data */
|
||||
char url[1024], /* URL for prev/next/this */
|
||||
*urlptr, /* Position in URL */
|
||||
@@ -1265,10 +1267,13 @@ cgiShowJobs(http_t *http, /* I - Co
|
||||
* Get a list of matching job objects.
|
||||
*/
|
||||
|
||||
- if ((var = cgiGetVariable("QUERY")) != NULL)
|
||||
- search = cgiCompileSearch(var);
|
||||
+ if ((query = cgiGetVariable("QUERY")) != NULL)
|
||||
+ search = cgiCompileSearch(query);
|
||||
else
|
||||
+ {
|
||||
+ query = NULL;
|
||||
search = NULL;
|
||||
+ }
|
||||
|
||||
jobs = cgiGetIPPObjects(response, search);
|
||||
count = cupsArrayCount(jobs);
|
||||
@@ -1293,16 +1298,27 @@ cgiShowJobs(http_t *http, /* I - Co
|
||||
if (first < 0)
|
||||
first = 0;
|
||||
|
||||
- sprintf(url, "%d", count);
|
||||
- cgiSetVariable("TOTAL", url);
|
||||
-
|
||||
if ((var = cgiGetVariable("ORDER")) != NULL)
|
||||
ascending = !strcasecmp(var, "asc");
|
||||
else
|
||||
- {
|
||||
ascending = !which_jobs || !strcasecmp(which_jobs, "not-completed");
|
||||
- cgiSetVariable("ORDER", ascending ? "asc" : "dec");
|
||||
- }
|
||||
+
|
||||
+ section = cgiGetVariable("SECTION");
|
||||
+
|
||||
+ cgiClearVariables();
|
||||
+
|
||||
+ if (query)
|
||||
+ cgiSetVariable("QUERY", query);
|
||||
+
|
||||
+ cgiSetVariable("ORDER", ascending ? "asc" : "dec");
|
||||
+
|
||||
+ cgiSetVariable("SECTION", section);
|
||||
+
|
||||
+ sprintf(url, "%d", count);
|
||||
+ cgiSetVariable("TOTAL", url);
|
||||
+
|
||||
+ if (which_jobs)
|
||||
+ cgiSetVariable("WHICH_JOBS", which_jobs);
|
||||
|
||||
if (ascending)
|
||||
{
|
||||
@@ -1325,11 +1341,10 @@ cgiShowJobs(http_t *http, /* I - Co
|
||||
|
||||
urlend = url + sizeof(url);
|
||||
|
||||
- if ((var = cgiGetVariable("QUERY")) != NULL)
|
||||
+ if (query != NULL)
|
||||
{
|
||||
if (dest)
|
||||
- snprintf(url, sizeof(url), "/%s/%s?QUERY=", cgiGetVariable("SECTION"),
|
||||
- dest);
|
||||
+ snprintf(url, sizeof(url), "/%s/%s?QUERY=", section, dest);
|
||||
else
|
||||
strlcpy(url, "/jobs/?QUERY=", sizeof(url));
|
||||
|
||||
@@ -1344,7 +1359,7 @@ cgiShowJobs(http_t *http, /* I - Co
|
||||
else
|
||||
{
|
||||
if (dest)
|
||||
- snprintf(url, sizeof(url), "/%s/%s?", cgiGetVariable("SECTION"), dest);
|
||||
+ snprintf(url, sizeof(url), "/%s/%s?", section, dest);
|
||||
else
|
||||
strlcpy(url, "/jobs/?", sizeof(url));
|
||||
|
||||
diff -upr cups-1.3.11.orig/cgi-bin/jobs.c cups-1.3.11/cgi-bin/jobs.c
|
||||
--- cups-1.3.11.orig/cgi-bin/jobs.c 2008-07-12 00:48:49.000000000 +0200
|
||||
+++ cups-1.3.11/cgi-bin/jobs.c 2009-10-21 11:43:13.000000000 +0200
|
||||
@@ -57,6 +57,7 @@ main(int argc, /* I - Number of comm
|
||||
*/
|
||||
|
||||
cgiSetVariable("SECTION", "jobs");
|
||||
+ cgiSetVariable("REFRESH_PAGE", "");
|
||||
|
||||
/*
|
||||
* Connect to the HTTP server...
|
||||
diff -upr cups-1.3.11.orig/cgi-bin/printers.c cups-1.3.11/cgi-bin/printers.c
|
||||
--- cups-1.3.11.orig/cgi-bin/printers.c 2008-07-12 00:48:49.000000000 +0200
|
||||
+++ cups-1.3.11/cgi-bin/printers.c 2009-10-21 11:42:30.000000000 +0200
|
||||
@@ -72,6 +72,7 @@ main(int argc, /* I - Number of comm
|
||||
*/
|
||||
|
||||
cgiSetVariable("SECTION", "printers");
|
||||
+ cgiSetVariable("REFRESH_PAGE", "");
|
||||
|
||||
/*
|
||||
* See if we are displaying a printer or all printers...
|
||||
diff -upr cups-1.3.11.orig/cgi-bin/template.c cups-1.3.11/cgi-bin/template.c
|
||||
--- cups-1.3.11.orig/cgi-bin/template.c 2008-07-12 00:48:49.000000000 +0200
|
||||
+++ cups-1.3.11/cgi-bin/template.c 2009-10-21 11:42:50.000000000 +0200
|
||||
@@ -639,6 +639,8 @@ cgi_puts(const char *s, /* I - String
|
||||
fputs(">", out);
|
||||
else if (*s == '\"')
|
||||
fputs(""", out);
|
||||
+ else if (*s == '\'')
|
||||
+ fputs("'", out);
|
||||
else if (*s == '&')
|
||||
fputs("&", out);
|
||||
else
|
||||
@@ -659,7 +661,7 @@ cgi_puturi(const char *s, /* I - String
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
- if (strchr("%&+ <>#=", *s) || *s & 128)
|
||||
+ if (strchr("%@&+ <>#=", *s) || *s < ' ' || *s & 128)
|
||||
fprintf(out, "%%%02X", *s & 255);
|
||||
else
|
||||
putc(*s, out);
|
||||
diff -upr cups-1.3.11.orig/cgi-bin/var.c cups-1.3.11/cgi-bin/var.c
|
||||
--- cups-1.3.11.orig/cgi-bin/var.c 2009-05-08 06:56:54.000000000 +0200
|
||||
+++ cups-1.3.11/cgi-bin/var.c 2009-10-21 11:43:09.000000000 +0200
|
||||
@@ -15,6 +15,7 @@
|
||||
* Contents:
|
||||
*
|
||||
* cgiCheckVariables() - Check for the presence of "required" variables.
|
||||
+ * cgiClearVariables() - Clear all form variables.
|
||||
* cgiGetArray() - Get an element from a form array...
|
||||
* cgiGetFile() - Get the file (if any) that was submitted in the form.
|
||||
* cgiGetSize() - Get the size of a form array value.
|
||||
@@ -135,6 +136,31 @@ cgiCheckVariables(const char *names) /*
|
||||
|
||||
|
||||
/*
|
||||
+ * 'cgiClearVariables()' - Clear all form variables.
|
||||
+ */
|
||||
+
|
||||
+void
|
||||
+cgiClearVariables(void)
|
||||
+{
|
||||
+ int i, j; /* Looping vars */
|
||||
+ _cgi_var_t *v; /* Current variable */
|
||||
+
|
||||
+
|
||||
+ for (v = form_vars, i = form_count; i > 0; v ++, i --)
|
||||
+ {
|
||||
+ _cupsStrFree(v->name);
|
||||
+ for (j = 0; j < v->nvalues; j ++)
|
||||
+ if (v->values[j])
|
||||
+ _cupsStrFree(v->values[j]);
|
||||
+ }
|
||||
+
|
||||
+ form_count = 0;
|
||||
+
|
||||
+ cgi_unlink_file();
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
* 'cgiGetArray()' - Get an element from a form array...
|
||||
*/
|
||||
|
||||
@@ -154,7 +180,7 @@ cgiGetArray(const char *name, /* I - Na
|
||||
if (element < 0 || element >= var->nvalues)
|
||||
return (NULL);
|
||||
|
||||
- return (var->values[element]);
|
||||
+ return (_cupsStrAlloc(var->values[element]));
|
||||
}
|
||||
|
||||
|
||||
@@ -209,7 +235,7 @@ cgiGetVariable(const char *name) /* I -
|
||||
var->values[var->nvalues - 1]);
|
||||
#endif /* DEBUG */
|
||||
|
||||
- return ((var == NULL) ? NULL : var->values[var->nvalues - 1]);
|
||||
+ return ((var == NULL) ? NULL : _cupsStrAlloc(var->values[var->nvalues - 1]));
|
||||
}
|
||||
|
||||
|
||||
@@ -341,9 +367,9 @@ cgiSetArray(const char *name, /* I - Na
|
||||
var->nvalues = element + 1;
|
||||
}
|
||||
else if (var->values[element])
|
||||
- free((char *)var->values[element]);
|
||||
+ _cupsStrFree((char *)var->values[element]);
|
||||
|
||||
- var->values[element] = strdup(value);
|
||||
+ var->values[element] = _cupsStrAlloc(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +414,7 @@ cgiSetSize(const char *name, /* I - Nam
|
||||
{
|
||||
for (i = size; i < var->nvalues; i ++)
|
||||
if (var->values[i])
|
||||
- free((void *)(var->values[i]));
|
||||
+ _cupsStrFree((void *)(var->values[i]));
|
||||
}
|
||||
|
||||
var->nvalues = size;
|
||||
@@ -421,9 +447,9 @@ cgiSetVariable(const char *name, /* I -
|
||||
{
|
||||
for (i = 0; i < var->nvalues; i ++)
|
||||
if (var->values[i])
|
||||
- free((char *)var->values[i]);
|
||||
+ _cupsStrFree((char *)var->values[i]);
|
||||
|
||||
- var->values[0] = strdup(value);
|
||||
+ var->values[0] = _cupsStrAlloc(value);
|
||||
var->nvalues = 1;
|
||||
}
|
||||
}
|
||||
@@ -470,10 +496,10 @@ cgi_add_variable(const char *name, /* I
|
||||
if ((var->values = calloc(element + 1, sizeof(char *))) == NULL)
|
||||
return;
|
||||
|
||||
- var->name = strdup(name);
|
||||
+ var->name = _cupsStrAlloc(name);
|
||||
var->nvalues = element + 1;
|
||||
var->avalues = element + 1;
|
||||
- var->values[element] = strdup(value);
|
||||
+ var->values[element] = _cupsStrAlloc(value);
|
||||
|
||||
form_count ++;
|
||||
}
|
3
cups-1.3.11-source.tar.bz2
Normal file
3
cups-1.3.11-source.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:824b7fe5cefa981f2ce20f356983be182a551f716ccab8f5194fe645b1178303
|
||||
size 3799424
|
26
cups-1.3.3-mime.patch
Normal file
26
cups-1.3.3-mime.patch
Normal file
@ -0,0 +1,26 @@
|
||||
Index: cups-1.3.11/conf/mime.types
|
||||
===================================================================
|
||||
--- cups-1.3.11.orig/conf/mime.types
|
||||
+++ cups-1.3.11/conf/mime.types
|
||||
@@ -75,6 +75,8 @@ application/postscript ai eps ps string
|
||||
contains(0,4096,"LANGUAGE = POSTSCRIPT") \
|
||||
(contains(0,4096,<0a>%!) + \
|
||||
!contains(0,4096,"ENTER LANGUAGE")))
|
||||
+#application/x-dvi dvi string(0,<F702>)
|
||||
+application/netscape-ps ps (string(0,%!) + contains(30,200,"Mozilla"))
|
||||
application/vnd.hp-HPGL hpgl \
|
||||
string(0,<1B>E<1B>%0B) \
|
||||
string(0,<1B>%-1B) string(0,<201B>)\
|
||||
Index: cups-1.3.11/conf/mime.convs.in
|
||||
===================================================================
|
||||
--- cups-1.3.11.orig/conf/mime.convs.in
|
||||
+++ cups-1.3.11/conf/mime.convs.in
|
||||
@@ -40,6 +40,8 @@
|
||||
|
||||
application/pdf application/vnd.cups-postscript 66 pdftops
|
||||
application/postscript application/vnd.cups-postscript 66 pstops
|
||||
+#application/x-dvi application/postscript 50 dvitops
|
||||
+application/netscape-ps application/vnd.cups-postscript 33 ogonki
|
||||
application/vnd.hp-HPGL application/postscript 66 hpgltops
|
||||
application/x-cshell application/postscript 33 texttops
|
||||
application/x-csource application/postscript 33 texttops
|
31
cups-1.3.3-pswrite.patch
Normal file
31
cups-1.3.3-pswrite.patch
Normal file
@ -0,0 +1,31 @@
|
||||
Index: cups-1.3.11/conf/mime.types
|
||||
===================================================================
|
||||
--- cups-1.3.11.orig/conf/mime.types
|
||||
+++ cups-1.3.11/conf/mime.types
|
||||
@@ -76,7 +76,10 @@ application/postscript ai eps ps string
|
||||
(contains(0,4096,<0a>%!) + \
|
||||
!contains(0,4096,"ENTER LANGUAGE")))
|
||||
#application/x-dvi dvi string(0,<F702>)
|
||||
-application/netscape-ps ps (string(0,%!) + contains(30,200,"Mozilla"))
|
||||
+application/mozilla-ps ps (string(0,%!) + \
|
||||
+ contains(30,200,"Creator: Mozilla PostScript"))
|
||||
+application/netscape-ps ps (string(0,%!) + \
|
||||
+ contains(30,200,"Creator: Mozilla (NetScape)"))
|
||||
application/vnd.hp-HPGL hpgl \
|
||||
string(0,<1B>E<1B>%0B) \
|
||||
string(0,<1B>%-1B) string(0,<201B>)\
|
||||
Index: cups-1.3.11/conf/mime.convs.in
|
||||
===================================================================
|
||||
--- cups-1.3.11.orig/conf/mime.convs.in
|
||||
+++ cups-1.3.11/conf/mime.convs.in
|
||||
@@ -41,7 +41,9 @@
|
||||
application/pdf application/vnd.cups-postscript 66 pdftops
|
||||
application/postscript application/vnd.cups-postscript 66 pstops
|
||||
#application/x-dvi application/postscript 50 dvitops
|
||||
-application/netscape-ps application/vnd.cups-postscript 33 ogonki
|
||||
+application/netscape-ps application/postscript 33 ogonki
|
||||
+#application/mozilla-ps application/postscript 33 pswrite
|
||||
+application/mozilla-ps application/vnd.cups-postscript 66 pstops
|
||||
application/vnd.hp-HPGL application/postscript 66 hpgltops
|
||||
application/x-cshell application/postscript 33 texttops
|
||||
application/x-csource application/postscript 33 texttops
|
13
cups-1.3.3-testppd_none.patch
Normal file
13
cups-1.3.3-testppd_none.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- cups-1.3.3/systemv/cupstestppd.c.orig 2007-10-15 18:50:01.000000000 +0200
|
||||
+++ cups-1.3.3/systemv/cupstestppd.c 2007-10-15 18:52:26.000000000 +0200
|
||||
@@ -983,8 +983,8 @@
|
||||
else
|
||||
ydpi = xdpi;
|
||||
|
||||
- if (xdpi <= 0 || xdpi > 99999 || ydpi <= 0 || ydpi > 99999 ||
|
||||
- strcmp(ptr, "dpi"))
|
||||
+ if ((xdpi <= 0 || xdpi > 99999 || ydpi <= 0 || ydpi > 99999 ||
|
||||
+ strcmp(ptr, "dpi")) && (strcmp(ptr, "None")))
|
||||
{
|
||||
if (verbose >= 0)
|
||||
{
|
58
cups-1.3.7-additional_policies.patch
Normal file
58
cups-1.3.7-additional_policies.patch
Normal file
@ -0,0 +1,58 @@
|
||||
--- cups-1.3.7/conf/cupsd.conf.in.orig 2008-07-08 12:11:01.000000000 +0200
|
||||
+++ cups-1.3.7/conf/cupsd.conf.in 2008-07-08 13:11:57.000000000 +0200
|
||||
@@ -78,6 +78,55 @@
|
||||
</Limit>
|
||||
</Policy>
|
||||
|
||||
+DefaultPolicy default
|
||||
+
|
||||
+# easy is a very relaxed policy
|
||||
+<Policy easy>
|
||||
+ # Job-related operations must be done by the owner or an administrator...
|
||||
+ <Limit All>
|
||||
+ Satisfy any
|
||||
+ Order allow,deny
|
||||
+ </Limit>
|
||||
+</Policy>
|
||||
+
|
||||
+# paranoid is a very restricted policy
|
||||
+<Policy paranoid>
|
||||
+ # Job-related operations must be done by the owner
|
||||
+ <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job CUPS-Move-Job>
|
||||
+ Require user @OWNER
|
||||
+ Allow from 127.0.0.0/8
|
||||
+ Order deny,allow
|
||||
+ </Limit>
|
||||
+ # All administration operations require an administrator to authenticate...
|
||||
+ <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>
|
||||
+ AuthType Default
|
||||
+ Require user @SYSTEM
|
||||
+ Allow from 127.0.0.0/8
|
||||
+ Order deny,allow
|
||||
+ </Limit>
|
||||
+
|
||||
+ # All printer operations require a printer operator to authenticate...
|
||||
+ <Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After CUPS-Accept-Jobs CUPS-Reject-Jobs>
|
||||
+ AuthType Default
|
||||
+ Require user @CUPS_DEFAULT_PRINTADMIN_AUTH@
|
||||
+ Allow from 127.0.0.0/8
|
||||
+ Order deny,allow
|
||||
+ </Limit>
|
||||
+
|
||||
+ # Only the owner or an administrator can cancel or authenticate a job...
|
||||
+ <Limit Cancel-Job CUPS-Authenticate-Job>
|
||||
+ Require user @OWNER
|
||||
+ Allow from 127.0.0.0/8
|
||||
+ Order deny,allow
|
||||
+ </Limit>
|
||||
+
|
||||
+ <Limit All>
|
||||
+ Require user @OWNER @CUPS_DEFAULT_PRINTADMIN_AUTH@
|
||||
+ Allow from 127.0.0.0/8
|
||||
+ Order deny,allow
|
||||
+ </Limit>
|
||||
+</Policy>
|
||||
+
|
||||
#
|
||||
# End of "$Id: cupsd.conf.in 7199 2008-01-08 00:16:30Z mike $".
|
||||
#
|
27
cups-1.3.7-keeping_recommended.patch
Normal file
27
cups-1.3.7-keeping_recommended.patch
Normal file
@ -0,0 +1,27 @@
|
||||
--- cups-1.3.7/scheduler/cups-driverd.c.orig 2008-04-01 00:33:33.000000000 +0200
|
||||
+++ cups-1.3.7/scheduler/cups-driverd.c 2008-05-07 12:19:40.000000000 +0200
|
||||
@@ -180,8 +180,6 @@
|
||||
int type) /* I - Driver type */
|
||||
{
|
||||
ppd_info_t *ppd; /* PPD */
|
||||
- char *recommended; /* Foomatic driver string */
|
||||
-
|
||||
|
||||
/*
|
||||
* Add a new PPD file...
|
||||
@@ -238,15 +236,6 @@
|
||||
strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id));
|
||||
|
||||
/*
|
||||
- * Strip confusing (and often wrong) "recommended" suffix added by
|
||||
- * Foomatic drivers...
|
||||
- */
|
||||
-
|
||||
- if ((recommended = strstr(ppd->record.make_and_model,
|
||||
- " (recommended)")) != NULL)
|
||||
- *recommended = '\0';
|
||||
-
|
||||
- /*
|
||||
* Return the new PPD pointer...
|
||||
*/
|
||||
|
11
cups-1.3.7-lppasswd_fixperm.patch
Normal file
11
cups-1.3.7-lppasswd_fixperm.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- cups-1.3.7/scheduler/conf.c.orig 2008-07-01 15:32:53.000000000 +0200
|
||||
+++ cups-1.3.7/scheduler/conf.c 2008-07-01 15:51:22.000000000 +0200
|
||||
@@ -785,7 +785,7 @@
|
||||
Group, 1, 1) < 0 ||
|
||||
cupsdCheckPermissions(StateDir, "certs", RunUser ? 0711 : 0511, User,
|
||||
SystemGroupIDs[0], 1, 1) < 0 ||
|
||||
- cupsdCheckPermissions(ServerRoot, NULL, 0755, RunUser,
|
||||
+ cupsdCheckPermissions(ServerRoot, NULL, 0775, RunUser,
|
||||
Group, 1, 0) < 0 ||
|
||||
cupsdCheckPermissions(ServerRoot, "ppd", 0755, RunUser,
|
||||
Group, 1, 1) < 0 ||
|
38
cups-1.3.9-CVE-2009-3553.patch
Normal file
38
cups-1.3.9-CVE-2009-3553.patch
Normal file
@ -0,0 +1,38 @@
|
||||
--- scheduler/select.c.orig 2008-07-12 00:48:49.000000000 +0200
|
||||
+++ scheduler/select.c 2009-11-12 16:32:50.000000000 +0100
|
||||
@@ -483,7 +483,7 @@ cupsdDoSelect(long timeout) /* I - Time
|
||||
(*(fdptr->read_cb))(fdptr->data);
|
||||
}
|
||||
|
||||
- if (fdptr->write_cb && event->filter == EVFILT_WRITE)
|
||||
+ if (fdptr->use > 1 && fdptr->write_cb && event->filter == EVFILT_WRITE)
|
||||
{
|
||||
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Write on fd %d...",
|
||||
fdptr->fd);
|
||||
@@ -543,7 +543,7 @@ cupsdDoSelect(long timeout) /* I - Time
|
||||
(*(fdptr->read_cb))(fdptr->data);
|
||||
}
|
||||
|
||||
- if (fdptr->write_cb && (event->events & (EPOLLOUT | EPOLLERR | EPOLLHUP)))
|
||||
+ if (fdptr->use > 1 && fdptr->write_cb && (event->events & (EPOLLOUT | EPOLLERR | EPOLLHUP)))
|
||||
{
|
||||
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Write on fd %d...",
|
||||
fdptr->fd);
|
||||
@@ -655,7 +655,7 @@ cupsdDoSelect(long timeout) /* I - Time
|
||||
(*(fdptr->read_cb))(fdptr->data);
|
||||
}
|
||||
|
||||
- if (fdptr->write_cb && (pfd->revents & (POLLOUT | POLLERR | POLLHUP)))
|
||||
+ if (fdptr->use > 1 && fdptr->write_cb && (pfd->revents & (POLLOUT | POLLERR | POLLHUP)))
|
||||
{
|
||||
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Write on fd %d...",
|
||||
fdptr->fd);
|
||||
@@ -725,7 +725,7 @@ cupsdDoSelect(long timeout) /* I - Time
|
||||
(*(fdptr->read_cb))(fdptr->data);
|
||||
}
|
||||
|
||||
- if (fdptr->write_cb && FD_ISSET(fdptr->fd, &cupsd_current_output))
|
||||
+ if (fdptr->use > 1 && fdptr->write_cb && FD_ISSET(fdptr->fd, &cupsd_current_output))
|
||||
{
|
||||
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Write on fd %d...",
|
||||
fdptr->fd);
|
@ -1,9 +1,9 @@
|
||||
--- desktop/cups.desktop.in.orig 2009-10-02 19:15:07.000000000 +0200
|
||||
+++ desktop/cups.desktop.in 2010-01-27 15:14:58.000000000 +0100
|
||||
--- cups-1.3.9/desktop/cups.desktop.orig 2008-09-06 02:30:39.000000000 +0200
|
||||
+++ cups-1.3.9/desktop/cups.desktop 2008-10-13 10:50:03.000000000 +0200
|
||||
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
-Categories=System;Printing;HardwareSettings;X-Red-Hat-Base;
|
||||
-Exec=@CUPS_HTMLVIEW@ http://localhost:631/
|
||||
-Exec=htmlview http://localhost:631/
|
||||
+Categories=System;Printing;HardwareSettings;
|
||||
+Exec=desktop-launch http://localhost:631/
|
||||
Icon=cups
|
||||
|
@ -1,26 +0,0 @@
|
||||
--- conf/cupsd.conf.in.orig 2010-01-27 11:49:09.000000000 +0100
|
||||
+++ conf/cupsd.conf.in 2010-01-27 11:55:34.000000000 +0100
|
||||
@@ -120,3 +120,23 @@ DefaultAuthType Basic
|
||||
#
|
||||
# End of "$Id: cupsd.conf.in 8805 2009-08-31 16:34:06Z mike $".
|
||||
#
|
||||
+
|
||||
+# The policy below is added by openSUSE/Novell during build of our cups package.
|
||||
+# The policy 'allowallforanybody' is totally open and insecure and therefore
|
||||
+# it can only be used within an internal network where only trused users exist
|
||||
+# and where the cupsd is not accessible at all from any external host.
|
||||
+# Have in mind that any user who is allowed to do printer admin tasks
|
||||
+# can change the print queues as he likes (e.g. send copies of confidental
|
||||
+# print jobs from an internal network to any external destination).
|
||||
+# For documentation regarding 'Managing Operation Policies' see
|
||||
+# http://www.cups.org/documentation.php/doc-1.4/policies.html
|
||||
+<Policy allowallforanybody>
|
||||
+ <Limit All>
|
||||
+ Order deny,allow
|
||||
+ Allow from all
|
||||
+ </Limit>
|
||||
+</Policy>
|
||||
+# Explicitely set the CUPS 'default' policy to be used by default:
|
||||
+DefaultPolicy default
|
||||
+# End of additions by openSUSE/Novell.
|
||||
+
|
@ -1,26 +0,0 @@
|
||||
--- scheduler/cups-driverd.cxx.orig 2009-06-09 00:00:14.000000000 +0200
|
||||
+++ scheduler/cups-driverd.cxx 2009-07-01 14:38:44.000000000 +0200
|
||||
@@ -211,7 +211,6 @@ add_ppd(const char *filename, /* I - PP
|
||||
const char *scheme) /* I - PPD scheme */
|
||||
{
|
||||
ppd_info_t *ppd; /* PPD */
|
||||
- char *recommended; /* Foomatic driver string */
|
||||
|
||||
|
||||
/*
|
||||
@@ -250,15 +249,6 @@ add_ppd(const char *filename, /* I - PP
|
||||
strlcpy(ppd->record.scheme, scheme, sizeof(ppd->record.scheme));
|
||||
|
||||
/*
|
||||
- * Strip confusing (and often wrong) "recommended" suffix added by
|
||||
- * Foomatic drivers...
|
||||
- */
|
||||
-
|
||||
- if ((recommended = strstr(ppd->record.make_and_model,
|
||||
- " (recommended)")) != NULL)
|
||||
- *recommended = '\0';
|
||||
-
|
||||
- /*
|
||||
* Add the PPD to the PPD arrays...
|
||||
*/
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:646bc0dbac064d05c0a93735fb556299eda0ae32ce4568506654cb952c719314
|
||||
size 4450466
|
392
cups-1.4svn-pdftops.c
Normal file
392
cups-1.4svn-pdftops.c
Normal file
@ -0,0 +1,392 @@
|
||||
/*
|
||||
* "$Id: pdftops.c 7449 2008-04-14 18:27:53Z mike $"
|
||||
*
|
||||
* PDF to PostScript filter front-end for the Common UNIX Printing
|
||||
* System (CUPS).
|
||||
*
|
||||
* Copyright 2007-2008 by Apple Inc.
|
||||
* Copyright 1997-2006 by Easy Software Products.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Apple Inc. and are protected by Federal copyright
|
||||
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
||||
* which should have been included with this file. If this file is
|
||||
* file is missing or damaged, see the license at "http://www.cups.org/".
|
||||
*
|
||||
* Contents:
|
||||
*
|
||||
* main() - Main entry for filter...
|
||||
* cancel_job() - Flag the job as canceled.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <cups/cups.h>
|
||||
#include <cups/string.h>
|
||||
#include <cups/i18n.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/*
|
||||
* Local functions...
|
||||
*/
|
||||
|
||||
static void cancel_job(int sig);
|
||||
|
||||
|
||||
/*
|
||||
* Local globals...
|
||||
*/
|
||||
|
||||
static int job_canceled = 0;
|
||||
|
||||
|
||||
/*
|
||||
* 'main()' - Main entry for filter...
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line args */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
int fd; /* Copy file descriptor */
|
||||
char *filename, /* PDF file to convert */
|
||||
tempfile[1024]; /* Temporary file */
|
||||
char buffer[8192]; /* Copy buffer */
|
||||
int bytes; /* Bytes copied */
|
||||
int num_options; /* Number of options */
|
||||
cups_option_t *options; /* Options */
|
||||
const char *val; /* Option value */
|
||||
int orientation; /* Output orientation */
|
||||
ppd_file_t *ppd; /* PPD file */
|
||||
ppd_size_t *size; /* Current page size */
|
||||
int pdfpid, /* Process ID for pdftops */
|
||||
pdfwaitpid, /* Process ID from wait() */
|
||||
pdfstatus, /* Status from pdftops */
|
||||
pdfargc; /* Number of args for pdftops */
|
||||
char *pdfargv[100], /* Arguments for pdftops/gs */
|
||||
#ifdef HAVE_PDFTOPS
|
||||
pdfwidth[255], /* Paper width */
|
||||
pdfheight[255]; /* Paper height */
|
||||
#else
|
||||
pdfgeometry[255]; /* Paper width and height */
|
||||
#endif /* HAVE_PDFTOPS */
|
||||
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
|
||||
struct sigaction action; /* Actions for POSIX signals */
|
||||
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
|
||||
|
||||
|
||||
/*
|
||||
* Make sure status messages are not buffered...
|
||||
*/
|
||||
|
||||
setbuf(stderr, NULL);
|
||||
|
||||
/*
|
||||
* Make sure we have the right number of arguments for CUPS!
|
||||
*/
|
||||
|
||||
if (argc < 6 || argc > 7)
|
||||
{
|
||||
_cupsLangPrintf(stderr,
|
||||
_("Usage: %s job user title copies options [filename]\n"),
|
||||
argv[0]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a signal handler to cleanly cancel a job.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
|
||||
sigset(SIGTERM, cancel_job);
|
||||
#elif defined(HAVE_SIGACTION)
|
||||
memset(&action, 0, sizeof(action));
|
||||
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_handler = cancel_job;
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
#else
|
||||
signal(SIGTERM, cancel_job);
|
||||
#endif /* HAVE_SIGSET */
|
||||
|
||||
/*
|
||||
* Copy stdin if needed...
|
||||
*/
|
||||
|
||||
if (argc == 6)
|
||||
{
|
||||
/*
|
||||
* Copy stdin to a temp file...
|
||||
*/
|
||||
|
||||
if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
|
||||
{
|
||||
_cupsLangPrintError(_("ERROR: Unable to copy PDF file"));
|
||||
return (1);
|
||||
}
|
||||
|
||||
fprintf(stderr, "DEBUG: pdftops - copying to temp print file \"%s\"\n",
|
||||
tempfile);
|
||||
|
||||
while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
|
||||
write(fd, buffer, bytes);
|
||||
|
||||
close(fd);
|
||||
|
||||
filename = tempfile;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Use the filename on the command-line...
|
||||
*/
|
||||
|
||||
filename = argv[6];
|
||||
tempfile[0] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the PPD file and mark options...
|
||||
*/
|
||||
|
||||
ppd = ppdOpenFile(getenv("PPD"));
|
||||
num_options = cupsParseOptions(argv[5], 0, &options);
|
||||
|
||||
ppdMarkDefaults(ppd);
|
||||
cupsMarkOptions(ppd, num_options, options);
|
||||
|
||||
/*
|
||||
* Build the command-line for the pdftops or gs filter...
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PDFTOPS
|
||||
pdfargv[0] = (char *)"pdftops";
|
||||
pdfargc = 1;
|
||||
#else
|
||||
pdfargv[0] = (char *)"gs";
|
||||
pdfargv[1] = (char *)"-q";
|
||||
pdfargv[2] = (char *)"-dNOPAUSE";
|
||||
pdfargv[3] = (char *)"-dBATCH";
|
||||
pdfargv[4] = (char *)"-dSAFER";
|
||||
pdfargv[5] = (char *)"-sDEVICE=pswrite";
|
||||
pdfargv[6] = (char *)"-sOUTPUTFILE=%stdout";
|
||||
pdfargc = 7;
|
||||
#endif /* HAVE_PDFTOPS */
|
||||
|
||||
if (ppd)
|
||||
{
|
||||
/*
|
||||
* Set language level and TrueType font handling...
|
||||
*/
|
||||
|
||||
if (ppd->language_level == 1)
|
||||
{
|
||||
#ifdef HAVE_PDFTOPS
|
||||
pdfargv[pdfargc++] = (char *)"-level1";
|
||||
pdfargv[pdfargc++] = (char *)"-noembtt";
|
||||
#else
|
||||
pdfargv[pdfargc++] = (char *)"-dLanguageLevel=1";
|
||||
#endif /* HAVE_PDFTOPS */
|
||||
}
|
||||
else if (ppd->language_level == 2)
|
||||
{
|
||||
#ifdef HAVE_PDFTOPS
|
||||
pdfargv[pdfargc++] = (char *)"-level2";
|
||||
if (!ppd->ttrasterizer)
|
||||
pdfargv[pdfargc++] = (char *)"-noembtt";
|
||||
#else
|
||||
pdfargv[pdfargc++] = (char *)"-dLanguageLevel=2";
|
||||
#endif /* HAVE_PDFTOPS */
|
||||
}
|
||||
else
|
||||
#ifdef HAVE_PDFTOPS
|
||||
pdfargv[pdfargc++] = (char *)"-level3";
|
||||
#else
|
||||
pdfargv[pdfargc++] = (char *)"-dLanguageLevel=3";
|
||||
#endif /* HAVE_PDFTOPS */
|
||||
|
||||
/*
|
||||
* Set output page size...
|
||||
*/
|
||||
|
||||
size = ppdPageSize(ppd, NULL);
|
||||
if (size)
|
||||
{
|
||||
/*
|
||||
* Got the size, now get the orientation...
|
||||
*/
|
||||
|
||||
orientation = 0;
|
||||
|
||||
if ((val = cupsGetOption("landscape", num_options, options)) != NULL)
|
||||
{
|
||||
if (strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 &&
|
||||
strcasecmp(val, "false") != 0)
|
||||
orientation = 1;
|
||||
}
|
||||
else if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL)
|
||||
{
|
||||
/*
|
||||
* Map IPP orientation values to 0 to 3:
|
||||
*
|
||||
* 3 = 0 degrees = 0
|
||||
* 4 = 90 degrees = 1
|
||||
* 5 = -90 degrees = 3
|
||||
* 6 = 180 degrees = 2
|
||||
*/
|
||||
|
||||
orientation = atoi(val) - 3;
|
||||
if (orientation >= 2)
|
||||
orientation ^= 1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PDFTOPS
|
||||
if (orientation & 1)
|
||||
{
|
||||
snprintf(pdfwidth, sizeof(pdfwidth), "%.0f", size->length);
|
||||
snprintf(pdfheight, sizeof(pdfheight), "%.0f", size->width);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(pdfwidth, sizeof(pdfwidth), "%.0f", size->width);
|
||||
snprintf(pdfheight, sizeof(pdfheight), "%.0f", size->length);
|
||||
}
|
||||
|
||||
pdfargv[pdfargc++] = (char *)"-paperw";
|
||||
pdfargv[pdfargc++] = pdfwidth;
|
||||
pdfargv[pdfargc++] = (char *)"-paperh";
|
||||
pdfargv[pdfargc++] = pdfheight;
|
||||
#else
|
||||
if (orientation & 1)
|
||||
snprintf(pdfgeometry, sizeof(pdfgeometry), "-g%.0fx%.0f", size->length,
|
||||
size->width);
|
||||
else
|
||||
snprintf(pdfgeometry, sizeof(pdfgeometry), "-g%.0fx%.0f", size->width,
|
||||
size->length);
|
||||
|
||||
pdfargv[pdfargc++] = pdfgeometry;
|
||||
#endif /* HAVE_PDFTOPS */
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_PDFTOPS
|
||||
if ((val = cupsGetOption("fitplot", num_options, options)) != NULL &&
|
||||
strcasecmp(val, "no") && strcasecmp(val, "off") &&
|
||||
strcasecmp(val, "false"))
|
||||
pdfargv[pdfargc++] = (char *)"-expand";
|
||||
|
||||
pdfargv[pdfargc++] = filename;
|
||||
pdfargv[pdfargc++] = (char *)"-";
|
||||
#else
|
||||
pdfargv[pdfargc++] = (char *)"-c";
|
||||
pdfargv[pdfargc++] = (char *)"save pop";
|
||||
pdfargv[pdfargc++] = (char *)"-f";
|
||||
pdfargv[pdfargc++] = filename;
|
||||
#endif /* HAVE_PDFTOPS */
|
||||
|
||||
pdfargv[pdfargc] = NULL;
|
||||
|
||||
if ((pdfpid = fork()) == 0)
|
||||
{
|
||||
/*
|
||||
* Child comes here...
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PDFTOPS
|
||||
execv(HAVE_PDFTOPS, pdfargv);
|
||||
_cupsLangPrintError(_("ERROR: Unable to execute pdftops program"));
|
||||
#else
|
||||
execv(CUPS_GHOSTSCRIPT, pdfargv);
|
||||
_cupsLangPrintError(_("ERROR: Unable to execute gs program"));
|
||||
#endif /* HAVE_PDFTOPS */
|
||||
|
||||
exit(1);
|
||||
}
|
||||
else if (pdfpid < 0)
|
||||
{
|
||||
/*
|
||||
* Unable to fork!
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PDFTOPS
|
||||
_cupsLangPrintError(_("ERROR: Unable to execute pdftops program"));
|
||||
#else
|
||||
_cupsLangPrintError(_("ERROR: Unable to execute gs program"));
|
||||
#endif /* HAVE_PDFTOPS */
|
||||
|
||||
pdfstatus = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Parent comes here...
|
||||
*/
|
||||
|
||||
while ((pdfwaitpid = wait(&pdfstatus)) < 0 && errno == EINTR)
|
||||
{
|
||||
/*
|
||||
* Wait until we get a valid process ID or the job is canceled...
|
||||
*/
|
||||
|
||||
if (job_canceled)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pdfwaitpid != pdfpid)
|
||||
{
|
||||
kill(pdfpid, SIGTERM);
|
||||
pdfstatus = 1;
|
||||
}
|
||||
else if (pdfstatus)
|
||||
{
|
||||
if (WIFEXITED(pdfstatus))
|
||||
{
|
||||
pdfstatus = WEXITSTATUS(pdfstatus);
|
||||
|
||||
_cupsLangPrintf(stderr,
|
||||
_("ERROR: pdftops filter exited with status %d!\n"),
|
||||
pdfstatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
pdfstatus = WTERMSIG(pdfstatus);
|
||||
|
||||
_cupsLangPrintf(stderr,
|
||||
_("ERROR: pdftops filter crashed on signal %d!\n"),
|
||||
pdfstatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup and exit...
|
||||
*/
|
||||
|
||||
if (tempfile[0])
|
||||
unlink(tempfile);
|
||||
|
||||
return (pdfstatus);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 'cancel_job()' - Flag the job as canceled.
|
||||
*/
|
||||
|
||||
static void
|
||||
cancel_job(int sig) /* I - Signal number (unused) */
|
||||
{
|
||||
(void)sig;
|
||||
|
||||
job_canceled = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: pdftops.c 7449 2008-04-14 18:27:53Z mike $".
|
||||
*/
|
136
cups-pdf.ppd
Normal file
136
cups-pdf.ppd
Normal file
@ -0,0 +1,136 @@
|
||||
*PPD-Adobe: "4.3"
|
||||
*%
|
||||
*% "$Id: pdf.ppd,v 1.2 2003/01/02 15:47:37 gurubert Exp $"
|
||||
*%
|
||||
*% Printer description for a printer that uses the pstopdf filter
|
||||
*%
|
||||
*% This file is based on the laserjet.ppd that comes with CUPS.
|
||||
*%
|
||||
*FormatVersion: "4.3"
|
||||
*FileVersion: "1.1"
|
||||
*LanguageVersion: English
|
||||
*LanguageEncoding: ISOLatin1
|
||||
*PCFileName: "PDF.PPD"
|
||||
*Manufacturer: "SUSE"
|
||||
*Product: "(openSUSE 11.0)"
|
||||
*cupsVersion: 1.1
|
||||
*cupsManualCopies: False
|
||||
*cupsFilter: "application/vnd.cups-postscript 33 pstopdf"
|
||||
*ModelName: "PDF Converter"
|
||||
*ShortNickName: "PDF Converter"
|
||||
*NickName: "PDF Converter CUPS v1.1"
|
||||
*PSVersion: "(3010.000) 550"
|
||||
*LanguageLevel: "3"
|
||||
*ColorDevice: True
|
||||
*DefaultColorSpace: RGB
|
||||
*FileSystem: False
|
||||
*Throughput: "8"
|
||||
*LandscapeOrientation: Plus90
|
||||
*VariablePaperSize: False
|
||||
*TTRasterizer: Type42
|
||||
|
||||
*OpenUI *PageSize/Media Size: PickOne
|
||||
*OrderDependency: 10 AnySetup *PageSize
|
||||
*DefaultPageSize: A4
|
||||
*PageSize Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
|
||||
*PageSize EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
|
||||
*CloseUI: *PageSize
|
||||
|
||||
*OpenUI *PageRegion: PickOne
|
||||
*OrderDependency: 10 AnySetup *PageRegion
|
||||
*DefaultPageRegion: A4
|
||||
*PageRegion Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion Legal/US Legal: "<</PageSize[612 1008]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion Executive/US Executive: "<</PageSize[522 756]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion Tabloid/US Tabloid: "<</PageSize[792 1224]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion A3/A3: "<</PageSize[842 1191]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion A5/A5: "<</PageSize[421 595]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion B5/B5 (JIS): "<</PageSize[516 729]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion EnvISOB5/Envelope B5: "<</PageSize[499 709]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion Env10/Envelope #10: "<</PageSize[297 684]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion EnvC5/Envelope C5: "<</PageSize[459 649]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion EnvDL/Envelope DL: "<</PageSize[312 624]/ImagingBBox null>>setpagedevice"
|
||||
*PageRegion EnvMonarch/Envelope Monarch: "<</PageSize[279 540]/ImagingBBox null>>setpagedevice"
|
||||
*CloseUI: *PageRegion
|
||||
|
||||
*DefaultImageableArea: A4
|
||||
*ImageableArea Letter/US Letter: "18 36 594 756"
|
||||
*ImageableArea Legal/US Legal: "18 36 594 972"
|
||||
*ImageableArea Executive/US Executive: "18 36 504 684"
|
||||
*ImageableArea Tabloid/US Tabloid: "18 36 774 1188"
|
||||
*ImageableArea A3/A3: "18 36 824 1155"
|
||||
*ImageableArea A4/A4: "18 36 577 806"
|
||||
*ImageableArea A5/A5: "18 36 403 559"
|
||||
*ImageableArea B5/JIS B5: "18 36 498 693"
|
||||
*ImageableArea EnvISOB5/B5 (ISO): "18 36 463 673"
|
||||
*ImageableArea Env10/Com-10: "18 36 279 648"
|
||||
*ImageableArea EnvC5/EnvC5: "18 36 441 613"
|
||||
*ImageableArea EnvDL/EnvDL: "18 36 294 588"
|
||||
*ImageableArea EnvMonarch/Envelope Monarch: "18 36 261 504"
|
||||
|
||||
*DefaultPaperDimension: A4
|
||||
*PaperDimension Letter/US Letter: "612 792"
|
||||
*PaperDimension Legal/US Legal: "612 1008"
|
||||
*PaperDimension Executive/US Executive: "522 756"
|
||||
*PaperDimension Tabloid/US Tabloid: "792 1224"
|
||||
*PaperDimension A3/A3: "842 1191"
|
||||
*PaperDimension A4/A4: "595 842"
|
||||
*PaperDimension A5/A5: "421 595"
|
||||
*PaperDimension B5/B5 (JIS): "516 729"
|
||||
*PaperDimension EnvISOB5/Envelope B5: "499 709"
|
||||
*PaperDimension Env10/Envelope #10: "297 684"
|
||||
*PaperDimension EnvC5/Envelope C5: "459 649"
|
||||
*PaperDimension EnvDL/Envelope DL: "312 624"
|
||||
*PaperDimension EnvMonarch/Envelope Monarch: "279 540"
|
||||
|
||||
*DefaultFont: Courier
|
||||
*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM
|
||||
*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM
|
||||
*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM
|
||||
*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM
|
||||
*Font Bookman-Demi: Standard "(001.004S)" Standard ROM
|
||||
*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM
|
||||
*Font Bookman-Light: Standard "(001.004S)" Standard ROM
|
||||
*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM
|
||||
*Font Courier: Standard "(002.004S)" Standard ROM
|
||||
*Font Courier-Bold: Standard "(002.004S)" Standard ROM
|
||||
*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM
|
||||
*Font Courier-Oblique: Standard "(002.004S)" Standard ROM
|
||||
*Font Helvetica: Standard "(001.006S)" Standard ROM
|
||||
*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM
|
||||
*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM
|
||||
*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM
|
||||
*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM
|
||||
*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM
|
||||
*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM
|
||||
*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM
|
||||
*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM
|
||||
*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM
|
||||
*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM
|
||||
*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM
|
||||
*Font Palatino-Bold: Standard "(001.005S)" Standard ROM
|
||||
*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM
|
||||
*Font Palatino-Italic: Standard "(001.005S)" Standard ROM
|
||||
*Font Palatino-Roman: Standard "(001.005S)" Standard ROM
|
||||
*Font Symbol: Special "(001.007S)" Special ROM
|
||||
*Font Times-Bold: Standard "(001.007S)" Standard ROM
|
||||
*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM
|
||||
*Font Times-Italic: Standard "(001.007S)" Standard ROM
|
||||
*Font Times-Roman: Standard "(001.007S)" Standard ROM
|
||||
*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM
|
||||
*Font ZapfDingbats: Special "(001.004S)" Standard ROM
|
||||
*%
|
||||
*% End of "$Id: pdf.ppd,v 1.2 2003/01/02 15:47:37 gurubert Exp $".
|
||||
*%
|
65
cups-pstopdf
Normal file
65
cups-pstopdf
Normal file
@ -0,0 +1,65 @@
|
||||
#!/bin/sh
|
||||
|
||||
# $Id: pstopdf,v 1.2 2003/01/02 15:39:26 gurubert Exp $
|
||||
#
|
||||
# This is a Postscript to PDF filter for CUPS
|
||||
#
|
||||
# (C) 2003 Robert Sander <robert.sander@epigenomics.com>
|
||||
#
|
||||
# Released under GPL
|
||||
#
|
||||
# NO WARRANTY AT ALL
|
||||
#
|
||||
|
||||
echo "INFO: pstopdf argv[$#] = $@" >&2
|
||||
|
||||
if [ $# -lt 5 -o $# -gt 6 ]; then
|
||||
|
||||
echo "ERROR: $0 job-id user title copies options [file]" >&2
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
jobid=$1
|
||||
|
||||
#infile=`mktemp /tmp/$jobid.pstopdf.in.XXXXXX`
|
||||
#if [ $? -ne 0 ]; then
|
||||
# echo "ERROR: Error creating tmpfile $infile" >&2
|
||||
# exit 1
|
||||
#fi
|
||||
#outfile=`mktemp /tmp/$jobid.pstopdf.out.XXXXXX`
|
||||
#if [ $? -ne 0 ]; then
|
||||
# echo "ERROR: Error creating tmpfile $outfile" >&2
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
if [ $# -eq 6 ]; then
|
||||
|
||||
echo "INFO: file is $6" >&2
|
||||
#cp $6 $infile
|
||||
#rm -f $6
|
||||
|
||||
infile="$6"
|
||||
outfile="$infile".pdf
|
||||
|
||||
/usr/bin/ps2pdf "$infile" "$outfile" 2>&1 >> /tmp/pstopdf.log
|
||||
|
||||
else
|
||||
|
||||
outfile=`mktemp /tmp/$jobid.pstopdf.out.XXXXXX`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Error creating tmpfile $outfile" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
/usr/bin/ps2pdf - "$outfile" 2>&1 >> /tmp/pstopdf.log
|
||||
|
||||
fi
|
||||
|
||||
cat $outfile
|
||||
|
||||
# cp "$infile" "$outfile" /tmp/cups/
|
||||
|
||||
rm -f "$outfile"
|
||||
|
||||
exit 0
|
17
cups.SuSEfirewall2
Normal file
17
cups.SuSEfirewall2
Normal file
@ -0,0 +1,17 @@
|
||||
## Name: cups
|
||||
## Description: Firewall Configuration file for printing service CUPS
|
||||
|
||||
# space separated list of allowed TCP ports
|
||||
TCP="ipp"
|
||||
|
||||
# space separated list of allowed UDP ports
|
||||
UDP="ipp"
|
||||
|
||||
# space separated list of allowed RPC services
|
||||
RPC=""
|
||||
|
||||
# space separated list of allowed IP protocols
|
||||
IP=""
|
||||
|
||||
# space separated list of allowed UDP ports for UDP broadcasts
|
||||
BROADCAST="ipp"
|
33
cups.changes
33
cups.changes
@ -1,36 +1,3 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Jan 27 14:43:37 CET 2010 - jsmeix@suse.de
|
||||
|
||||
- CUPS 1.3 -> 1.4 version upgrade and major cleanup:
|
||||
For the CUPS upstream changes see the CHANGES.txt file.
|
||||
Such a major version upgrade is the perfect chance
|
||||
to drop almost all our own patches to enforce a
|
||||
reset to almost 100% compliance with upstream.
|
||||
Here our openSUSE CUPS versions and their number of patches
|
||||
(i.e. the "Patch" entries in the cups.spec files):
|
||||
CUPS version 1.2.12 in openSUSE 10.3: 37
|
||||
CUPS version 1.3.7 in openSUSE 11.0: 29
|
||||
CUPS version 1.3.9 in openSUSE 11.1: 26
|
||||
CUPS version 1.3.11 in openSUSE 11.2: 17
|
||||
Of course this includes patches with backported bug fixes
|
||||
via our maintenance but nevertheless there were really
|
||||
too much openSUSE specific patches.
|
||||
Therefore I would like to provide CUPS 1.4 "as is" to the
|
||||
furthest possible extent (there are still 6 patches left).
|
||||
Then let's see if we get bug reports because of this.
|
||||
I did such a reset to 100% compliance with upstream
|
||||
already in the past for sane-backends and guess what:
|
||||
I got no single bug report at all because of this.
|
||||
I guess what they do at upstream is actually not so bad ;-)
|
||||
- Added the explicite path to '--with-cachedir=/var/cache/cups'
|
||||
in cups.spec to avoid that the fallback value 'yes' results
|
||||
the cache directory '/etc/cups/yes/'.
|
||||
- cups-1.3.11-CVE-2009-2820-regression-fix.patch and
|
||||
cups-1.3.11-CVE-2009-2820.patch have become
|
||||
obsolete because it is fixed in the source.
|
||||
- cups-1.4-full_path_to_configure_with-pdftops.patch has become
|
||||
obsolete because it is fixed in the source.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Dec 15 22:22:18 CET 2009 - jengelh@medozas.de
|
||||
|
||||
|
586
cups.spec
586
cups.spec
@ -1,7 +1,7 @@
|
||||
#
|
||||
# spec file for package cups (Version 1.3.9)
|
||||
# spec file for package cups (Version 1.3.11)
|
||||
#
|
||||
# Copyright (c) 2009 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@ -26,22 +26,12 @@ BuildRequires: fdupes update-desktop-files
|
||||
PreReq: textutils, fileutils, sh-utils, %insserv_prereq,
|
||||
PreReq: %fillup_prereq /usr/sbin/groupadd
|
||||
Url: http://www.cups.org/
|
||||
License: GPL v2 or later
|
||||
License: GPLv2+
|
||||
Group: Hardware/Printing
|
||||
Summary: The Common UNIX Printing System
|
||||
Version: 1.4.2
|
||||
Release: 13
|
||||
# Require the exact matching version-release of the cups-libs sub-package because
|
||||
# non-matching CUPS libraries may let CUPS software crash (e.g. segfault)
|
||||
# because all CUPS software is built from the one same CUPS source tar ball
|
||||
# so that there are CUPS-internal dependencies via CUPS private API calls
|
||||
# (which do not happen for third-party software which uses only the CUPS public API).
|
||||
# The exact matching version-release of the cups-libs sub-package is available
|
||||
# on the same package repository where the cups package is because
|
||||
# all are built simulaneously from the same cups source package
|
||||
# and all required packages are provided on the same repository:
|
||||
Requires: cups-libs = %{version}-%{release}
|
||||
Requires: cups-client = %{version}
|
||||
Version: 1.3.11
|
||||
Release: 7
|
||||
Requires: cups-libs = %{version}, cups-client = %{version}
|
||||
Requires: ghostscript_any, ghostscript-fonts-std, foomatic-filters
|
||||
Requires: util-linux /usr/bin/pdftops
|
||||
%if 0%{?suse_version} >= 1100
|
||||
@ -50,167 +40,240 @@ Requires: pdftools_any
|
||||
Suggests: poppler-tools
|
||||
Conflicts: plp lprold lprng
|
||||
Obsoletes: cups-SUSE-ppds-dat
|
||||
# Source0...Source9 is for sources from upstream:
|
||||
# URL for Source0: http://ftp.easysw.com/pub/cups/1.4.2/cups-1.4.2-source.tar.bz2
|
||||
# MD5 sum for Source0 on http://www.cups.org/software.php is d95e2d588e3d36e563027a963b117b1b
|
||||
# URL for Source0: http://ftp.easysw.com/pub/cups/1.3.11/cups-1.3.11-source.tar.bz2
|
||||
# MD5 sum for Source0 on http://www.cups.org/software.php is 17f3e2bcb3cae3dd9dceb65a2bfd295f
|
||||
Source0: cups-%{version}-source.tar.bz2
|
||||
# Patch0...Patch9 is for patches from upstream:
|
||||
# Source10...Source99 is for sources from Novell/openSUSE which are intended for upstream:
|
||||
# Patch10...Patch99 is for patches from Novell/openSUSE which are intended for upstream:
|
||||
# Patch10 adds 'smb://...' URIs to templates/choose-uri.tmpl:
|
||||
Patch10: cups-1.2rc1-template.patch
|
||||
# Source100...Source999 is for private sources from Novell/openSUSE which are not intended for upstream:
|
||||
Source100: cups-krb5-config
|
||||
Source101: cups.init
|
||||
Source102: postscript.ppd.bz2
|
||||
Source103: cups.sysconfig
|
||||
Source104: cups.xinetd
|
||||
Source105: PSLEVEL1.PPD.bz2
|
||||
Source106: PSLEVEL2.PPD.bz2
|
||||
Source108: cups-client.conf
|
||||
Source109: baselibs.conf
|
||||
# Patch100...Patch999 is for private patches from Novell/openSUSE which are not intended for upstream:
|
||||
# Patch100 adds conf/pam.suse regarding support for PAM for Novell/openSUSE:
|
||||
Patch100: cups-pam.diff
|
||||
# Patch101 adds 'Allow 127.0.0.2' to cupsd.conf
|
||||
# to allow access for the loopback IP address 127.0.0.2
|
||||
# which is set for the hostname by Novell/openSUSE in /etc/hosts
|
||||
Patch101: cups-1.3.6-access_conf.patch
|
||||
# Patch102 changes desktop/cups.desktop according to what Novell/openSUSE needs:
|
||||
Patch102: cups-1.3.9-desktop_file.patch
|
||||
# Patch103 reverts the change which was added by Michael Sweet in Jan 2007
|
||||
# which strips the word "recommended" from NickName in PPDs because
|
||||
# at least yast2-printer in Novell/openSUSE needs it, compare the
|
||||
# 'Why not "recommend" PPDs in the NickName?' and the subsequent
|
||||
# 'RFC: New Driver Rating/Information Attributes' mail thread on cups@easysw.com:
|
||||
Patch103: cups-1.4-do_not_strip_recommended_from_PPDs.patch
|
||||
# Patch104 adds the 'allowallforanybody' policy to cupsd.conf
|
||||
# see https://fate.novell.com/303515
|
||||
Patch104: cups-1.4-additional_policies.patch
|
||||
# Install into this non-root directory (required when norootforbuild is used):
|
||||
Source1: poll_ppd_base.c
|
||||
Source2: lphelp.c
|
||||
Source3: dvitops
|
||||
Source4: pswrite
|
||||
Source5: baselibs.conf
|
||||
Source7: ogonki
|
||||
Source8: cups.init
|
||||
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
|
||||
Source14: cups.xinetd
|
||||
Source15: PSLEVEL1.PPD.bz2
|
||||
Source16: PSLEVEL2.PPD.bz2
|
||||
Source17: cups.SuSEfirewall2
|
||||
Source18: http://download.sourceforge.net/cups-mailto/cups-pdf.ppd
|
||||
Source19: http://download.sourceforge.net/cups-mailto/cups-pstopdf
|
||||
Source20: cups-krb5-config
|
||||
Source21: cups-client.conf
|
||||
Source22: cups-1.4svn-pdftops.c
|
||||
Patch1: cups-1.3.3-mime.patch
|
||||
Patch2: cups-1.2.0-ppdsdat_generation.patch
|
||||
Patch3: cups-1.2rc1-template.patch
|
||||
Patch4: cups-1.2.7-libwrap.patch
|
||||
Patch5: cups-pam.diff
|
||||
Patch6: cups-1.3.6-access_conf.patch
|
||||
# Patch9 cups-1.1.21rc2-preauth_security.patch is finally removed
|
||||
# since CUPS 1.3.10 because it was made for CUPS 1.1 and
|
||||
# it was no longer applied since CUPS 1.2 in Suse Linux 10.3 and
|
||||
# we did not get any user or SLE11 customer request for it.
|
||||
# Patch10 cups-1.1.21rc2-usermode.patch is finally removed
|
||||
# since CUPS 1.3.10 because it was made for CUPS 1.1 and
|
||||
# can no longer apply since CUPS 1.2 in Suse Linux 10.3 because
|
||||
# RunAsUser in cupsd.conf is no longer supported since CUPS 1.2.
|
||||
Patch12: cups-1.3.3-pswrite.patch
|
||||
# Patch13 cups-1.1.21-umlaut_printer.patch is finally removed
|
||||
# since CUPS 1.3.10 because it was made for CUPS 1.1 and
|
||||
# it was no longer applied since CUPS 1.2 in Suse Linux 10.3 and
|
||||
# we did not get any user or SLE11 customer request for it.
|
||||
Patch14: cups-1.1.21-testppd_duplex.patch
|
||||
Patch15: cups-1.2.11-testppd_filename.patch
|
||||
Patch16: cups-1.3.9-desktop_file.patch
|
||||
Patch17: cups-1.3.3-testppd_none.patch
|
||||
# Patch18 cups-1.4svn-pdftops_as_filter.patch is obsolete
|
||||
# since CUPS 1.3.10 because it is fixed in the source.
|
||||
# Patch19 cups-1.4svn-pdftops_dont_fail_on_cancel.patch is obsolete
|
||||
# since CUPS 1.3.10 because it is fixed in the source.
|
||||
Patch20: cups-1.3.7-keeping_recommended.patch
|
||||
Patch21: cups-1.3.7-lppasswd_fixperm.patch
|
||||
Patch22: cups-1.3.7-additional_policies.patch
|
||||
# Patch23 cups-1.3.9-cupstestppd.patch is obsolete
|
||||
# since CUPS 1.3.10 because it is fixed in the source.
|
||||
# Patch24 cups-1.3.9-max_subscription.patch is obsolete
|
||||
# since CUPS 1.3.10 because it is fixed in the source.
|
||||
# Patch25 cups-1.3.9-filter_png_overflow2.patch is obsolete
|
||||
# since CUPS 1.3.10 because it is fixed in the source.
|
||||
# Patch26 cups-1.3.9-hpgltops2.patch is obsolete
|
||||
# since CUPS 1.3.10 because it is fixed in the source.
|
||||
# Patch27 cups-1.3.9-cupsImageReadTiff.patch is obsolete
|
||||
# since CUPS 1.3.10 because it is fixed in the source.
|
||||
# Patch28 cups-1.3.10-fix-DNS-rebinding-protection.patch is obsolete
|
||||
# since CUPS 1.3.11 because it is fixed in the source.
|
||||
# Patch29 full_path_to_configure_with-pdftops.patch adds support
|
||||
# to specify a full path in 'configure --with-pdftops=/usr/bin/pdftops'
|
||||
# to avoid 'BuildRequires: xpdf-tools' which would bloat the build system
|
||||
# but would be only needed to satisfy 'AC_PATH_PROG(CUPS_PDFTOPS, pdftops)'
|
||||
# in cups-pdf.m4 if only 'configure --with-pdftops=pdftops' was possible:
|
||||
Patch29: full_path_to_configure_with-pdftops.patch
|
||||
# Patch30 fixes CUPS Web Interface Cross-Site Scripting (XSS) and CRLF injection in HTTP headers,
|
||||
# (CVE-2009-2820 and Novell/Suse Bugzilla bnc#548317):
|
||||
Patch30: cups-1.3.11-CVE-2009-2820.patch
|
||||
# Patch31 fixes a regression which was introduced by Patch30
|
||||
# now adding a class via web interface fails with 'Unknown operation "{op}"'
|
||||
# (Novell/Suse Bugzilla bnc#548317 starting at comment #24):
|
||||
Patch31: cups-1.3.11-CVE-2009-2820-regression-fix.patch
|
||||
# Patch32 fixes a use-after-free bug in the scheduler which leads to remote denial of service,
|
||||
# (CVE-2009-3553, CUPS STR #3200, and Novell/Suse Bugzilla bnc#554861):
|
||||
Patch32: cups-1.3.9-CVE-2009-3553.patch
|
||||
# Patch100 cups-1.1.23-testpage.patch is finally removed
|
||||
# since CUPS 1.3.10 because it was made for CUPS 1.1 and
|
||||
# it was no longer applied since CUPS 1.2 in Suse Linux 10.3 and
|
||||
# we did not get any user or SLE11 customer request for it.
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
|
||||
|
||||
%description
|
||||
The Common UNIX Printing System provides a portable printing layer for
|
||||
UNIX operating systems like BSD lp or lprng. CUPS provides some
|
||||
UNIX® operating systems like BSD lp or lprng. CUPS provides some
|
||||
additional features.
|
||||
|
||||
http://www.cups.org
|
||||
|
||||
|
||||
|
||||
Authors:
|
||||
--------
|
||||
Easy Software Products <cups@cups.org>
|
||||
|
||||
%define INSTALL install -m755
|
||||
%define INSTALL_SCRIPT install -m755
|
||||
%define INSTALL_DIR install -d -m755
|
||||
%define INSTALL_DATA install -m644
|
||||
%define CPUs %(grep -c ^processor\ /proc/cpuinfo || echo 1)
|
||||
|
||||
%package libs
|
||||
License: GPL v2 or later; LGPL v2.1 or later
|
||||
License: GPLv2+ ; LGPLv2.1+
|
||||
Summary: Libraries for CUPS
|
||||
Group: Hardware/Printing
|
||||
# https://bugzilla.novell.com/show_bug.cgi?id=437293
|
||||
# bug437293
|
||||
%ifarch ppc64
|
||||
Obsoletes: cups-libs-64bit
|
||||
%endif
|
||||
#
|
||||
|
||||
%description libs
|
||||
The Common UNIX Printing System provides a portable printing layer for
|
||||
UNIX operating systems like BSD lp or lprng. CUPS provides some
|
||||
UNIX® operating systems like BSD lp or lprng. CUPS provides some
|
||||
additional features. This package contains libraries needed by CUPS and
|
||||
some other packages.
|
||||
|
||||
|
||||
|
||||
Authors:
|
||||
--------
|
||||
Easy Software Products <cups@cups.org>
|
||||
|
||||
%package client
|
||||
License: GPL v2 or later
|
||||
License: GPLv2+
|
||||
Summary: CUPS Client Programs
|
||||
Group: Hardware/Printing
|
||||
Conflicts: plp lprold lprng
|
||||
# Require the exact matching version-release of the cups-libs sub-package because
|
||||
# non-matching CUPS libraries may let CUPS software crash (e.g. segfault)
|
||||
# because all CUPS software is built from the one same CUPS source tar ball
|
||||
# so that there are CUPS-internal dependencies via CUPS private API calls
|
||||
# (which do not happen for third-party software which uses only the CUPS public API).
|
||||
# The exact matching version-release of the cups-libs sub-package is available
|
||||
# on the same package repository where the cups package is because
|
||||
# all are built simulaneously from the same cups source package
|
||||
# and all required packages are provided on the same repository:
|
||||
Requires: cups-libs = %{version}-%{release}
|
||||
Requires: cups-libs = %{version}
|
||||
|
||||
%description client
|
||||
The Common UNIX Printing System provides a portable printing layer for
|
||||
UNIX operating systems like BSD lp or lprng. CUPS provides some
|
||||
UNIX® operating systems like BSD lp or lprng. CUPS provides some
|
||||
additional features. This package contains all programs needed for
|
||||
running a CUPS client, not a server.
|
||||
|
||||
|
||||
|
||||
Authors:
|
||||
--------
|
||||
Easy Software Products <cups@cups.org>
|
||||
|
||||
%package devel
|
||||
License: GPL v2 or later
|
||||
License: GPLv2+
|
||||
Summary: Development Environment for CUPS
|
||||
Group: Development/Libraries/C and C++
|
||||
# Do not require the exact matching version-release of cups-libs
|
||||
# but only a cups-libs package with matching version because
|
||||
# for building third-party software which uses only the CUPS public API
|
||||
# there are no CUPS-internal dependencies via CUPS private API calls
|
||||
# (the latter would require the exact matching cups-libs version-release):
|
||||
Requires: cups-libs = %{version}
|
||||
Requires: openssl-devel glibc-devel krb5-devel
|
||||
# https://bugzilla.novell.com/show_bug.cgi?id=437293
|
||||
Requires: %{name}-libs = %{version} openssl-devel glibc-devel krb5-devel
|
||||
# bug437293
|
||||
%ifarch ppc64
|
||||
Obsoletes: cups-devel-64bit
|
||||
%endif
|
||||
#
|
||||
|
||||
%description devel
|
||||
The Common UNIX Printing System provides a portable printing layer for
|
||||
UNIX operating systems like BSD lp or lprng. CUPS provides some
|
||||
UNIX® operating systems like BSD lp or lprng. CUPS provides some
|
||||
additional features. This is the development package.
|
||||
|
||||
http://www.cups.org
|
||||
|
||||
%package ddk
|
||||
License: GPL v2 or later
|
||||
Summary: CUPS Driver Development Kit
|
||||
Group: Hardware/Printing
|
||||
Requires: cups = %{version}
|
||||
Requires: cups-devel = %{version}
|
||||
# Since CUPS 1.4 the CUPS Driver Development Kit (DDK) is bundled with CUPS.
|
||||
# For CUPS 1.2.x and 1.3.x, the DDK was separated software
|
||||
# which we provided (up to openSUSE 11.1 / SLE11) in our cupsddk package:
|
||||
Provides: cupsddk = %{version}
|
||||
Obsoletes: cupsddk < %{version}
|
||||
|
||||
%description ddk
|
||||
The CUPS Driver Development Kit (DDK) provides a suite of standard
|
||||
drivers, a PPD file compiler, and other utilities that can be used to
|
||||
develop printer drivers for CUPS and other printing environments. CUPS
|
||||
provides a portable printing layer for UNIX(r)-based operating systems.
|
||||
The CUPS DDK provides the means for mass-producing PPD files and
|
||||
drivers or filters for CUPS-based printer drivers.
|
||||
The Common UNIX Printing System provides a portable printing layer for
|
||||
UNIX operating systems like BSD lp or lprng. CUPS provides some
|
||||
additional features. This is the Driver Development Kit package.
|
||||
|
||||
http://www.cups.org
|
||||
Authors:
|
||||
--------
|
||||
Easy Software Products <cups@cups.org>
|
||||
|
||||
%prep
|
||||
# Be quiet when unpacking:
|
||||
%setup -q -n %{name}-%{version}
|
||||
# Patch0...Patch9 is for patches from upstream:
|
||||
# Patch10...Patch99 is for patches from Novell/openSUSE which are intended for upstream:
|
||||
# Patch10 adds 'smb://...' URIs to templates/choose-uri.tmpl:
|
||||
%patch10 -p1
|
||||
# Patch100...Patch999 is for private patches from Novell/openSUSE which are not intended for upstream:
|
||||
# Patch100 adds conf/pam.suse regarding support for PAM for Novell/openSUSE:
|
||||
%patch100
|
||||
# Patch101 adds 'Allow 127.0.0.2' to cupsd.conf:
|
||||
%patch101 -p1
|
||||
# Patch102 changes desktop/cups.desktop according to what Novell/openSUSE needs:
|
||||
%patch102
|
||||
# Patch103 reverts the change which strips the word "recommended" from NickName in PPDs:
|
||||
%patch103
|
||||
# Patch104 adds the 'allowallforanybody' policy to cupsd.conf:
|
||||
%patch104
|
||||
# Install our special krb5-config (Source100: cups-krb5-config):
|
||||
install -m755 %{SOURCE100} krb5-config
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5
|
||||
%patch6 -p1
|
||||
%patch12 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
# Patch29 full_path_to_configure_with-pdftops.patch adds support
|
||||
# for 'configure --with-pdftops=/usr/bin/pdftops':
|
||||
%patch29
|
||||
# Patch30 fixes CUPS Web Interface Cross-Site Scripting (XSS) and CRLF injection in HTTP headers,
|
||||
# (CVE-2009-2820 and Novell/Suse Bugzilla bnc#548317):
|
||||
%patch30 -p1
|
||||
# Patch31 fixes a regression which was introduced by Patch30
|
||||
# now adding a class via web interface fails with 'Unknown operation "{op}"'
|
||||
# (Novell/Suse Bugzilla bnc#548317 starting at comment #24):
|
||||
%patch31
|
||||
# Patch32 fixes a use-after-free bug in the scheduler which leads to remote denial of service,
|
||||
# (CVE-2009-3553, CUPS STR #3200, and Novell/Suse Bugzilla bnc#554861):
|
||||
%patch32
|
||||
if [ -f /.buildenv ]; then
|
||||
. /.buildenv
|
||||
test -z "$BUILD_DISTRIBUTION_NAME" && BUILD_DISTRIBUTION_NAME="%{?distribution}"
|
||||
fi
|
||||
test -z "$BUILD_DISTRIBUTION_NAME" && BUILD_DISTRIBUTION_NAME="personal build CUPS version"
|
||||
perl -pi -e "s|SUSEVERSION|$BUILD_DISTRIBUTION_NAME|; \
|
||||
s/CUPSVERSION/%{version}/" %{PATCH100}
|
||||
# fix hardcoded $_libdir path to real architecture dependend $_libdir
|
||||
perl -pi -e 's|(CUPS_SERVERBIN=\")\$exec_prefix/lib|$1'%{_libdir}'|' \
|
||||
config-scripts/cups-directories.m4
|
||||
cp -a %{SOURCE9} .
|
||||
cp -a %{SOURCE10} .
|
||||
%{INSTALL_SCRIPT} %{SOURCE20} krb5-config
|
||||
|
||||
%build
|
||||
# To build the /usr/lib/cups/filter/pdftops filter
|
||||
# (via the configure options --enable-pdftops, --with-pdftops=pdftops)
|
||||
# the config-scripts/cups-pdf.m4 tests if there is a pdftops executable in its path
|
||||
# which could be satisfied with 'BuildRequires: xpdf-tools' which would bloat the build system
|
||||
# so that we fake a pdftops executable with the following link:
|
||||
ln -s /bin/true pdftops
|
||||
%{?suse_update_config:%{suse_update_config -f . }}
|
||||
libtoolize --force
|
||||
aclocal
|
||||
autoconf
|
||||
%if %suse_version >= 1010
|
||||
export CXXFLAGS="$CXXFLAGS $RPM_OPT_FLAGS -O2 -fno-strict-aliasing -fstack-protector"
|
||||
export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fstack-protector -DLDAP_DEPRECATED"
|
||||
%else
|
||||
export CXXFLAGS="$CXXFLAGS $RPM_OPT_FLAGS -O2 -fno-strict-aliasing"
|
||||
export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
|
||||
%endif
|
||||
export CXX=g++
|
||||
KRB5CONFIG=${PWD}/krb5-config ./configure \
|
||||
--mandir=%{_mandir} \
|
||||
@ -230,73 +293,98 @@ KRB5CONFIG=${PWD}/krb5-config ./configure \
|
||||
--with-java \
|
||||
--with-php \
|
||||
--with-python \
|
||||
--with-cachedir=/var/cache/cups \
|
||||
--with-python \
|
||||
--with-cachedir \
|
||||
--with-pdftops=/usr/bin/pdftops \
|
||||
--prefix=/
|
||||
make %{?_smp_mflags} CXX=g++
|
||||
# perl -pi -e 's:^(OPTIONS\s+\=):$1 -I/usr/X11R6/include -O2 -fstack-protector -fno-strict-aliasing:' Makedefs
|
||||
# perl -pi -e 's:^(INSTALL_BIN\s+\=.*)-s:$1:' Makedefs
|
||||
# for debugging enable:
|
||||
#perl -pi -e 's:^(OPTIONS\s+\=):$1 -I/usr/X11R6/include -O2 -fno-strict-aliasing -g -DDEBUG:' Makedefs
|
||||
#perl -pi -e 's:^(OPTIM\s+\=):$1 -g -DDEBUG:' Makedefs
|
||||
make %{?jobs:-j%jobs} CXX=g++
|
||||
# Compile additional tools
|
||||
gcc -opoll_ppd_base $CFLAGS -fPIC -fPIE -pie -I. -L./cups %{SOURCE1} -lcups
|
||||
gcc -olphelp $CFLAGS -fPIC -fPIE -pie -I. -L./cups %{SOURCE2} -lcups
|
||||
|
||||
%install
|
||||
make BUILDROOT=$RPM_BUILD_ROOT install
|
||||
install -d -m755 $RPM_BUILD_ROOT/etc/init.d
|
||||
# Source101: cups.init
|
||||
install -m755 %{SOURCE101} $RPM_BUILD_ROOT/etc/init.d/cups
|
||||
install -d -m755 $RPM_BUILD_ROOT/var/adm/fillup-templates
|
||||
# Source103: cups.sysconfig
|
||||
install -m 644 %{SOURCE103} $RPM_BUILD_ROOT/var/adm/fillup-templates/sysconfig.cups
|
||||
make BUILDROOT=$RPM_BUILD_ROOT \
|
||||
install
|
||||
if [ x%{version} = x"1.1.18" ]; then
|
||||
mv $RPM_BUILD_ROOT/usr/sbin/cupstestppd \
|
||||
$RPM_BUILD_ROOT/usr/bin/cupstestppd
|
||||
fi
|
||||
# place CUPS-O-MATIC script in CUPS filter directory
|
||||
%{INSTALL_SCRIPT} %{SOURCE7} $RPM_BUILD_ROOT%{_libdir}/cups/filter
|
||||
%{INSTALL_SCRIPT} %{SOURCE3} $RPM_BUILD_ROOT%{_libdir}/cups/filter
|
||||
%{INSTALL_SCRIPT} %{SOURCE4} $RPM_BUILD_ROOT%{_libdir}/cups/filter
|
||||
# might no longer be needed: ln -s /etc/cups/printcap $RPM_BUILD_ROOT/etc
|
||||
# install the two little tools
|
||||
install -m 755 poll_ppd_base $RPM_BUILD_ROOT/usr/bin/
|
||||
install -m 755 lphelp $RPM_BUILD_ROOT/usr/bin/
|
||||
%{INSTALL_DIR} $RPM_BUILD_ROOT/etc/init.d
|
||||
%{INSTALL_SCRIPT} %{SOURCE8} $RPM_BUILD_ROOT/etc/init.d/cups
|
||||
%{INSTALL_DIR} $RPM_BUILD_ROOT/var/adm/fillup-templates
|
||||
install -m 644 %{SOURCE13} $RPM_BUILD_ROOT/var/adm/fillup-templates/sysconfig.cups
|
||||
perl -pi -e "s:\@LIB\@:%{_libdir}:g" $RPM_BUILD_ROOT/etc/init.d/cups
|
||||
ln -sf ../../etc/init.d/cups $RPM_BUILD_ROOT/usr/sbin/rccups
|
||||
# use Ghostscript fonts instead of CUPS fonts:
|
||||
#
|
||||
rm -r $RPM_BUILD_ROOT/usr/share/cups/fonts
|
||||
#mkdir -p /usr/share/ghostscript/fonts
|
||||
mkdir -p $RPM_BUILD_ROOT/usr/share/ghostscript/fonts
|
||||
ln -sf /usr/share/ghostscript/fonts $RPM_BUILD_ROOT/usr/share/cups/
|
||||
# make directory for ssl files:
|
||||
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/cups/ssl
|
||||
# add old client.conf as reference (Source108: cups-client.conf):
|
||||
install -m644 %{SOURCE108} $RPM_BUILD_ROOT%{_sysconfdir}/cups/client.conf
|
||||
# add old client.conf as reference:
|
||||
%{INSTALL_DATA} %{SOURCE21} $RPM_BUILD_ROOT%{_sysconfdir}/cups/client.conf
|
||||
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d
|
||||
install -m 644 -D packaging/cups-dbus.conf $RPM_BUILD_ROOT%{_sysconfdir}/dbus-1/system.d/cups.conf
|
||||
# Source104: cups.xinetd
|
||||
install -m 644 -D %{SOURCE104} $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d/cups-lpd
|
||||
install -m 644 -D %{SOURCE14} $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d/cups-lpd
|
||||
perl -pi -e "s:\@LIB\@:%{_libdir}:g" $RPM_BUILD_ROOT%{_sysconfdir}/xinetd.d/cups-lpd
|
||||
ln -sf libcupsimage.so.2 $RPM_BUILD_ROOT%{_libdir}/libcupsimage.so
|
||||
ln -sf libcups.so.2 $RPM_BUILD_ROOT%{_libdir}/libcups.so
|
||||
install -d -m755 $RPM_BUILD_ROOT/usr/share/cups/drivers
|
||||
install -d -m755 $RPM_BUILD_ROOT/var/cache/cups
|
||||
install -d -m755 $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name}
|
||||
install -d -m755 $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name}/images
|
||||
ln -sf ../sbin/lpc $RPM_BUILD_ROOT/usr/bin/lpc # bugzilla#16652
|
||||
%{INSTALL_DIR} $RPM_BUILD_ROOT/usr/share/cups/drivers
|
||||
%{INSTALL_DIR} $RPM_BUILD_ROOT/var/cache/cups
|
||||
%{INSTALL_DIR} $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name}
|
||||
%{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
|
||||
# Source102: postscript.ppd.bz2
|
||||
bzip2 -cd < %{SOURCE102} > $RPM_BUILD_ROOT%{_datadir}/cups/model/Postscript.ppd
|
||||
# Source105: PSLEVEL1.PPD.bz2
|
||||
bzip2 -cd < %{SOURCE105} > $RPM_BUILD_ROOT%{_datadir}/cups/model/Postscript-level1.ppd
|
||||
# Source106: PSLEVEL2.PPD.bz2
|
||||
bzip2 -cd < %{SOURCE106} > $RPM_BUILD_ROOT%{_datadir}/cups/model/Postscript-level2.ppd
|
||||
bzip2 -cd < %{SOURCE12} > $RPM_BUILD_ROOT%{_datadir}/cups/model/Postscript.ppd
|
||||
bzip2 -cd < %{SOURCE15} > $RPM_BUILD_ROOT%{_datadir}/cups/model/Postscript-level1.ppd
|
||||
bzip2 -cd < %{SOURCE16} > $RPM_BUILD_ROOT%{_datadir}/cups/model/Postscript-level2.ppd
|
||||
%{INSTALL_DATA} %{SOURCE18} $RPM_BUILD_ROOT%{_datadir}/cups/model/PDF.ppd
|
||||
find %{buildroot}/usr/share/cups/model -name "*.ppd" | while read FILE
|
||||
do # change default paper size from Letter to A4 if possible
|
||||
# https://bugzilla.novell.com/show_bug.cgi?id=suse30662
|
||||
# and delete trailing whitespace:
|
||||
do
|
||||
# change default paper size from letter to A4 if possible (bugzilla#30662)
|
||||
# and delete trailing whitespace
|
||||
perl -pi -e 's:^(\*Default.*)Letter\s*$:$1A4\n:; \
|
||||
s:^(\*ImageableArea A4.*\:\s+)"0 0 595 842":$1"24 48 571 818":; \
|
||||
s:^(\*ImageableArea Letter.*\:\s+)"0 0 612 792":$1"24 48 588 768":; \
|
||||
s:\s\n:\n:' "$FILE"
|
||||
s:\s\n:\n:' \
|
||||
"$FILE"
|
||||
gzip -9 "$FILE"
|
||||
done
|
||||
# add files for menu:
|
||||
rm -f $RPM_BUILD_ROOT/usr/share/applications/cups.desktop
|
||||
# add files for menu
|
||||
rm -f $RPM_BUILD_ROOT//usr/share/applications/cups.desktop
|
||||
%suse_update_desktop_file -i -r %name PrintingUtility 2>/dev/null
|
||||
mkdir $RPM_BUILD_ROOT/usr/share/pixmaps
|
||||
install -m 644 $RPM_BUILD_ROOT/usr/share/icons/hicolor/64x64/apps/cups.png $RPM_BUILD_ROOT/usr/share/pixmaps
|
||||
rm -rf $RPM_BUILD_ROOT/usr/share/icons
|
||||
# remove unpackaged files:
|
||||
# remove unpackaged files
|
||||
rm -rf $RPM_BUILD_ROOT/%{_mandir}/es/cat?
|
||||
rm -rf $RPM_BUILD_ROOT/%{_mandir}/fr/cat?
|
||||
rm -rf $RPM_BUILD_ROOT/%{_mandir}/cat?
|
||||
# remove unknown locale directory:
|
||||
#
|
||||
# SuSEfirewall2:
|
||||
install -d $RPM_BUILD_ROOT/etc/sysconfig/SuSEfirewall2.d/services/
|
||||
install -m 644 %{SOURCE17} $RPM_BUILD_ROOT/etc/sysconfig/SuSEfirewall2.d/services/cups
|
||||
# remove unknown locale directory
|
||||
rm -rf $RPM_BUILD_ROOT/usr/share/locale/no
|
||||
# run fdupes:
|
||||
%fdupes $RPM_BUILD_ROOT
|
||||
|
||||
%clean
|
||||
@ -321,181 +409,93 @@ rm -rf $RPM_BUILD_ROOT/usr/share/locale/no
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%config(noreplace) %attr(640,root,lp) %{_sysconfdir}/cups/cupsd.conf
|
||||
%config(noreplace) %attr(640,root,lp) %{_sysconfdir}/cups/snmp.conf
|
||||
%config(noreplace) %attr(755,lp,lp) %{_sysconfdir}/cups/interfaces
|
||||
%config(noreplace) %{_sysconfdir}/xinetd.d/cups-lpd
|
||||
%config %attr(0755,root,root) %{_sysconfdir}/init.d/cups
|
||||
%config %{_sysconfdir}/pam.d/cups
|
||||
%dir %attr(700,root,lp) %{_sysconfdir}/cups/ssl
|
||||
%dir %attr(755,root,lp) %{_sysconfdir}/cups/ppd
|
||||
%config(noreplace) %attr(640,root,lp) %{_sysconfdir}/cups/cupsd.conf
|
||||
%config(noreplace) %attr(640,root,lp) %{_sysconfdir}/cups/snmp.conf
|
||||
%{_sysconfdir}/cups/cupsd.conf.default
|
||||
%{_sysconfdir}/dbus-1/system.d/cups.conf
|
||||
/var/adm/fillup-templates/sysconfig.cups
|
||||
%config(noreplace) %attr(755,lp,lp) %{_sysconfdir}/cups/interfaces
|
||||
%config(noreplace) %{_sysconfdir}/cups/mime.*
|
||||
%config(noreplace) %{_sysconfdir}/xinetd.d/cups-lpd
|
||||
%{_bindir}/poll_ppd_base
|
||||
%{_bindir}/cupstestppd
|
||||
%{_bindir}/cupstestdsc
|
||||
%dir %{_libdir}/cups
|
||||
%dir %{_libdir}/cups/backend
|
||||
%{_libdir}/cups/backend/http
|
||||
%{_libdir}/cups/backend/ipp
|
||||
%{_libdir}/cups/backend/lpd
|
||||
%{_libdir}/cups/backend/parallel
|
||||
%{_libdir}/cups/backend/scsi
|
||||
%{_libdir}/cups/backend/snmp
|
||||
%{_libdir}/cups/backend/serial
|
||||
%{_libdir}/cups/backend/socket
|
||||
%{_libdir}/cups/backend/usb
|
||||
%{_libdir}/cups/cgi-bin
|
||||
%{_libdir}/cups/daemon
|
||||
%dir %{_libdir}/cups/driver
|
||||
%dir %{_libdir}/cups/filter
|
||||
%{_libdir}/cups/filter/[abd-z]*
|
||||
%dir %{_libdir}/cups/monitor
|
||||
%{_libdir}/cups/monitor/*
|
||||
%dir %{_libdir}/cups/notifier
|
||||
%{_libdir}/cups/notifier/*
|
||||
%{_sbindir}/cupsaddsmb
|
||||
%{_sbindir}/cupsctl
|
||||
%{_sbindir}/cupsd
|
||||
%{_sbindir}/cupsfilter
|
||||
%{_sbindir}/rccups
|
||||
%dir /usr/lib/cups
|
||||
%dir /usr/lib/cups/backend
|
||||
/usr/lib/cups/backend/http
|
||||
/usr/lib/cups/backend/ipp
|
||||
/usr/lib/cups/backend/lpd
|
||||
/usr/lib/cups/backend/parallel
|
||||
/usr/lib/cups/backend/scsi
|
||||
/usr/lib/cups/backend/serial
|
||||
/usr/lib/cups/backend/snmp
|
||||
/usr/lib/cups/backend/socket
|
||||
/usr/lib/cups/backend/usb
|
||||
%dir /usr/lib/cups/cgi-bin
|
||||
/usr/lib/cups/cgi-bin/admin.cgi
|
||||
/usr/lib/cups/cgi-bin/classes.cgi
|
||||
/usr/lib/cups/cgi-bin/help.cgi
|
||||
/usr/lib/cups/cgi-bin/jobs.cgi
|
||||
/usr/lib/cups/cgi-bin/printers.cgi
|
||||
%dir /usr/lib/cups/daemon
|
||||
/usr/lib/cups/daemon/cups-deviced
|
||||
/usr/lib/cups/daemon/cups-driverd
|
||||
/usr/lib/cups/daemon/cups-lpd
|
||||
/usr/lib/cups/daemon/cups-polld
|
||||
%dir /usr/lib/cups/driver
|
||||
%dir /usr/lib/cups/filter
|
||||
/usr/lib/cups/filter/bannertops
|
||||
/usr/lib/cups/filter/commandtoescpx
|
||||
/usr/lib/cups/filter/commandtopclx
|
||||
/usr/lib/cups/filter/commandtops
|
||||
/usr/lib/cups/filter/gziptoany
|
||||
/usr/lib/cups/filter/hpgltops
|
||||
/usr/lib/cups/filter/imagetops
|
||||
/usr/lib/cups/filter/imagetoraster
|
||||
/usr/lib/cups/filter/pdftops
|
||||
/usr/lib/cups/filter/pstops
|
||||
/usr/lib/cups/filter/rastertodymo
|
||||
/usr/lib/cups/filter/rastertoepson
|
||||
/usr/lib/cups/filter/rastertoescpx
|
||||
/usr/lib/cups/filter/rastertohp
|
||||
/usr/lib/cups/filter/rastertolabel
|
||||
/usr/lib/cups/filter/rastertopclx
|
||||
/usr/lib/cups/filter/texttops
|
||||
%dir /usr/lib/cups/monitor
|
||||
/usr/lib/cups/monitor/bcp
|
||||
/usr/lib/cups/monitor/tbcp
|
||||
%dir /usr/lib/cups/notifier
|
||||
/usr/lib/cups/notifier/mailto
|
||||
/usr/lib/cups/notifier/rss
|
||||
%dir %attr(0775,root,ntadmin) %{_datadir}/cups/drivers
|
||||
%{_datadir}/applications/cups.desktop
|
||||
%{_datadir}/pixmaps/cups.png
|
||||
%doc %{_defaultdocdir}/cups
|
||||
%doc %{_mandir}/man1/cupstestppd.1.gz
|
||||
%doc %{_mandir}/man5/classes.conf.5.gz
|
||||
%doc %{_mandir}/man5/client.conf.5.gz
|
||||
%doc %{_mandir}/man5/cups-snmp.conf.5.gz
|
||||
%doc %{_mandir}/man5/cupsd.conf.5.gz
|
||||
%doc %{_mandir}/man5/mailto.conf.5.gz
|
||||
%doc %{_mandir}/man5/mime.convs.5.gz
|
||||
%doc %{_mandir}/man5/mime.types.5.gz
|
||||
%doc %{_mandir}/man5/printers.conf.5.gz
|
||||
%doc %{_mandir}/man5/subscriptions.conf.5.gz
|
||||
%doc %{_mandir}/man7/backend.7.gz
|
||||
%doc %{_mandir}/man7/drv.7.gz
|
||||
%doc %{_mandir}/man7/filter.7.gz
|
||||
%doc %{_mandir}/man7/notifier.7.gz
|
||||
%doc %{_mandir}/man8/cups-deviced.8.gz
|
||||
%doc %{_mandir}/man8/cups-driverd.8.gz
|
||||
%doc %{_mandir}/man8/cups-lpd.8.gz
|
||||
%doc %{_mandir}/man8/cups-polld.8.gz
|
||||
%doc %{_mandir}/man8/cupsaddsmb.8.gz
|
||||
%doc %{_mandir}/man8/cupsctl.8.gz
|
||||
%doc %{_mandir}/man8/cupsd.8.gz
|
||||
%doc %{_mandir}/man8/cupsfilter.8.gz
|
||||
%{_datadir}/cups/
|
||||
%exclude %{_datadir}/cups/ppdc/
|
||||
%{_sbindir}/rc*
|
||||
%dir %attr(0775,root,ntadmin) /usr/share/cups/drivers
|
||||
%dir /usr/share/cups
|
||||
/usr/share/applications/cups.desktop
|
||||
/usr/share/pixmaps/cups.png
|
||||
/usr/share/cups/[bcf-t]*
|
||||
/usr/share/cups/d[ao]*
|
||||
%dir %attr(0775,lp,lp) /var/cache/cups
|
||||
%config %attr(0755,root,root) /etc/init.d/cups
|
||||
%config /etc/pam.d/cups
|
||||
/var/adm/fillup-templates/sysconfig.cups
|
||||
%doc %{_defaultdocdir}/%{name}
|
||||
%doc %{_mandir}/man5/*
|
||||
%doc %{_mandir}/man7/*
|
||||
%doc %{_mandir}/man8/*
|
||||
|
||||
%files client
|
||||
%defattr(-,root,root)
|
||||
%{_bindir}/cancel
|
||||
%{_bindir}/cupstestdsc
|
||||
%{_bindir}/lp
|
||||
%{_bindir}/lpc
|
||||
%{_bindir}/lphelp
|
||||
%{_bindir}/lpoptions
|
||||
%attr(2755,lp,lp) %{_bindir}/lppasswd
|
||||
%{_bindir}/lpq
|
||||
%{_bindir}/lpr
|
||||
%{_bindir}/lprm
|
||||
%{_bindir}/lpstat
|
||||
%{_bindir}/cancel
|
||||
%{_sbindir}/*able
|
||||
%{_sbindir}/accept
|
||||
%{_sbindir}/cupsaccept
|
||||
%{_sbindir}/cupsdisable
|
||||
%{_sbindir}/cupsenable
|
||||
%{_sbindir}/cupsreject
|
||||
%{_sbindir}/lpadmin
|
||||
%{_sbindir}/lpc
|
||||
%{_sbindir}/lpinfo
|
||||
%{_sbindir}/lpmove
|
||||
%{_sbindir}/lp*
|
||||
%{_sbindir}/reject
|
||||
%doc %{_mandir}/man1/cancel.1.gz
|
||||
%doc %{_mandir}/man1/cupstestdsc.1.gz
|
||||
%doc %{_mandir}/man1/lp.1.gz
|
||||
%doc %{_mandir}/man1/lpoptions.1.gz
|
||||
%doc %{_mandir}/man1/lppasswd.1.gz
|
||||
%doc %{_mandir}/man1/lpq.1.gz
|
||||
%doc %{_mandir}/man1/lpr.1.gz
|
||||
%doc %{_mandir}/man1/lprm.1.gz
|
||||
%doc %{_mandir}/man1/lpstat.1.gz
|
||||
%doc %{_mandir}/man8/accept.8.gz
|
||||
%doc %{_mandir}/man8/cupsaccept.8.gz
|
||||
%doc %{_mandir}/man8/cupsdisable.8.gz
|
||||
%doc %{_mandir}/man8/cupsenable.8.gz
|
||||
%doc %{_mandir}/man8/cupsreject.8.gz
|
||||
%doc %{_mandir}/man8/lpadmin.8.gz
|
||||
%doc %{_mandir}/man8/lpc.8.gz
|
||||
%doc %{_mandir}/man8/lpinfo.8.gz
|
||||
%doc %{_mandir}/man8/lpmove.8.gz
|
||||
%doc %{_mandir}/man8/reject.8.gz
|
||||
%doc %{_mandir}/man1/[a-eg-z]*
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root)
|
||||
%{_includedir}/cups/
|
||||
%{_includedir}/cups
|
||||
%{_libdir}/libcups.so
|
||||
%{_libdir}/libcupsimage.so
|
||||
%{_libdir}/libcupscgi.so
|
||||
%{_libdir}/libcupsdriver.so
|
||||
%{_libdir}/libcupsmime.so
|
||||
%{_libdir}/libcupsppdc.so
|
||||
%{_datadir}/cups/ppdc/
|
||||
|
||||
%files ddk
|
||||
%defattr(-,root,root)
|
||||
%{_bindir}/ppdc
|
||||
%{_bindir}/ppdhtml
|
||||
%{_bindir}/ppdi
|
||||
%{_bindir}/ppdmerge
|
||||
%{_bindir}/ppdpo
|
||||
%doc %{_mandir}/man1/ppdc.1.gz
|
||||
%doc %{_mandir}/man1/ppdhtml.1.gz
|
||||
%doc %{_mandir}/man1/ppdi.1.gz
|
||||
%doc %{_mandir}/man1/ppdmerge.1.gz
|
||||
%doc %{_mandir}/man1/ppdpo.1.gz
|
||||
%doc %{_mandir}/man5/ppdcfile.5.gz
|
||||
|
||||
%files libs
|
||||
%defattr(-,root,root)
|
||||
%config(noreplace) %{_sysconfdir}/cups/client.conf
|
||||
%{_bindir}/cups-config
|
||||
# %dir %attr(0775,root,lp) %{_sysconfdir}/cups/
|
||||
%dir %attr(0710,root,lp) %{_var}/spool/cups
|
||||
%dir %attr(1770,root,lp) %{_var}/spool/cups/tmp
|
||||
%dir %attr(0755,lp,lp) %{_var}/log/cups/
|
||||
%dir %attr(0775,lp,lp) %{_var}/cache/cups
|
||||
%{_bindir}/cups-config
|
||||
%config(noreplace) %{_sysconfdir}/cups/client.conf
|
||||
%config(noreplace) /etc/sysconfig/SuSEfirewall2.d/services/cups
|
||||
%{_libdir}/libcups.so.*
|
||||
%{_libdir}/libcupscgi.so.*
|
||||
%{_libdir}/libcupsdriver.so.*
|
||||
%{_libdir}/libcupsimage.so.*
|
||||
%{_libdir}/libcupsmime.so.*
|
||||
%{_libdir}/libcupsppdc.so.*
|
||||
%{_datadir}/locale/*/cups_*
|
||||
%doc %{_mandir}/man1/cups-config.1.gz
|
||||
|
||||
%changelog
|
||||
|
||||
|
41
dvitops
Normal file
41
dvitops
Normal file
@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "$#" -lt "5"; then
|
||||
echo "ERROR: Number of arguments ($#) is wrong" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "$#" -gt "6"; then
|
||||
echo "ERROR: Number of arguments ($#) is wrong" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Log the command line
|
||||
echo dvitops: $@ 1>&2
|
||||
|
||||
# Get the last parameter (which is the filename if present)
|
||||
eval filename="\${$#}"
|
||||
|
||||
if [ -e $filename ]; then
|
||||
FILE_TO_PRINT=$filename;
|
||||
else
|
||||
FILE_TO_PRINT="";
|
||||
fi
|
||||
|
||||
if [ -z $FILE_TO_PRINT ]; then
|
||||
FILE_TO_PRINT=`mktemp -q /tmp/dvitops.XXXXXX`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Can't create temp file, exiting..." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
trap "rm -f $FILE_TO_PRINT" EXIT SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
|
||||
cat >$FILE_TO_PRINT
|
||||
fi
|
||||
|
||||
if [ -z $FILE_TO_PRINT ]; then
|
||||
/usr/bin/dvips -q -f
|
||||
else
|
||||
/usr/bin/dvips -q -f <$FILE_TO_PRINT
|
||||
fi
|
||||
|
||||
|
15
full_path_to_configure_with-pdftops.patch
Normal file
15
full_path_to_configure_with-pdftops.patch
Normal file
@ -0,0 +1,15 @@
|
||||
--- config-scripts/cups-pdf.m4.orig 2009-07-31 14:39:16.000000000 +0200
|
||||
+++ config-scripts/cups-pdf.m4 2009-07-31 15:04:18.000000000 +0200
|
||||
@@ -62,6 +62,12 @@ case "x$with_pdftops" in
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
+
|
||||
+ *) # Use exactly the /path/to/program which is specified
|
||||
+ CUPS_PDFTOPS="$with_pdftops"
|
||||
+ AC_DEFINE(HAVE_PDFTOPS)
|
||||
+ PDFTOPS="pdftops"
|
||||
+ ;;
|
||||
esac
|
||||
|
||||
AC_DEFINE_UNQUOTED(CUPS_PDFTOPS, "$CUPS_PDFTOPS")
|
362
lphelp.c
Normal file
362
lphelp.c
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
*
|
||||
* lphelp
|
||||
* ------
|
||||
#
|
||||
# A simple tool for getting information about an installed printer or a
|
||||
# PPD file. Especially the printer-specific options defined in the PPD
|
||||
# file are listed, so that one can make use of them with the "lp", "lpr",
|
||||
# and "lpoptions" commands. The programm can also be used by installation/
|
||||
# configuration scripts to give a "preview" to a PPD file.
|
||||
#
|
||||
# ONLY WORKS WITH CUPS DAEMON RUNNING!
|
||||
# The CUPS library (libcups.so.*) must be installed!
|
||||
#
|
||||
# Compile with: gcc -olphelp -lcups lphelp.c
|
||||
#
|
||||
* Copyright 2000 by Till Kamppeter
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <cups/cups.h>
|
||||
|
||||
/*
|
||||
* 'main()' - Main entry for test program.
|
||||
*/
|
||||
|
||||
int /* O - Exit status */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
int i, j, k, m; /* Looping vars */
|
||||
const char *filename; /* File to load */
|
||||
FILE *ppdfile;
|
||||
|
||||
// Temporary file name (for reading from stdin)
|
||||
char tmpfile[19] = "/tmp/lphelp.XXXXXX";
|
||||
const int blocksize = 1024;
|
||||
char buffer[blocksize];
|
||||
int bytesread;
|
||||
|
||||
// variables for parsing PPD file for usual options (boolean, enumerated)
|
||||
ppd_file_t *ppd; /* PPD file record */
|
||||
ppd_size_t *size; /* Size record */
|
||||
ppd_group_t *group; /* UI group */
|
||||
ppd_option_t *option; /* Standard UI option */
|
||||
ppd_choice_t *choice; /* Standard UI option choice */
|
||||
static char *uis[] = { "BOOLEAN", "PICKONE", "PICKMANY" };
|
||||
static char *sections[] = { "ANY", "DOCUMENT", "EXIT",
|
||||
"JCL", "PAGE", "PROLOG" };
|
||||
|
||||
// variables for parsing CUPS-O-MATIC info for numerical options (float, int)
|
||||
char line[1024], /* buffer for reading PPD file line by
|
||||
line to search numerical options */
|
||||
item[1024], /* item to be defined (left of "=>") */
|
||||
value[1024], /* value for item (right of "=>") */
|
||||
argname[1024], /* name of the current argument */
|
||||
comment[1024]; /* human-readable argument name */
|
||||
const char *line_contents; /* contents of line */
|
||||
const char *scan; /* pointer scanning the line */
|
||||
char *writepointer;
|
||||
double min, max, defvalue; /* Range of numerical
|
||||
CUPS-O-MATIC option */
|
||||
int opttype; /* 0 = other, 1 = int, 2 = float */
|
||||
int openbrackets; /* How many curled brackets are open? */
|
||||
int inquotes; /* are we in quotes now? */
|
||||
int inargspart; /* are we in the arguments part now? */
|
||||
|
||||
/*
|
||||
* Display PPD files for each file listed on the command-line...
|
||||
*/
|
||||
|
||||
if (argc == 1) {
|
||||
fputs("Usage: lphelp <filename1>.ppd [<filename2>.ppd ...]\n lphelp <printername1> [<printername2> ...]\n lphelp -\n", stderr);
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i ++) {
|
||||
if ((strstr(argv[i], ".ppd")) || (strstr(argv[i], "-")))
|
||||
filename = argv[i];
|
||||
else
|
||||
filename = cupsGetPPD(argv[i]);
|
||||
if (strcmp(filename,"-") == 0) {
|
||||
if ((ppdfile = fdopen(mkstemp(tmpfile), "w")) == NULL) {
|
||||
fprintf(stderr, "Unable to generate temporary file!\n");
|
||||
}
|
||||
while ((bytesread = fread(buffer, 1, blocksize, stdin)) > 0) {
|
||||
fwrite(buffer, 1, bytesread, ppdfile);
|
||||
}
|
||||
fclose(ppdfile);
|
||||
filename = tmpfile;
|
||||
}
|
||||
if ((ppd = ppdOpenFile(filename)) == NULL) {
|
||||
fprintf(stderr, "Unable to open \'%s\' as a PPD file!\n", filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("==============================================================================\n\n");
|
||||
printf("%s\n\n", ppd->modelname);
|
||||
printf("==============================================================================\n\n");
|
||||
printf(" %s printer\n\n", ppd->color_device ? "Colour" : "Black & white");
|
||||
printf(" Printer-specific options\n");
|
||||
printf(" ------------------------\n\n");
|
||||
printf(" Besides the options described in the CUPS software users manual\n");
|
||||
printf(" (http://localhost:631/sum.html) you can use also the following options\n");
|
||||
printf(" when you print on this printer with the \"lp\" or \"lpr\" command (a choice\n");
|
||||
printf(" with the \"default\" mark represents the behaviour of the printer when the\n");
|
||||
printf(" appropriate option is not given on the command line):\n\n");
|
||||
|
||||
for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++) {
|
||||
for (k = 0, option = group->options; k < group->num_options;
|
||||
k ++, option ++) {
|
||||
if (strcmp(option->keyword, "PageRegion") != 0) {
|
||||
if ((strcmp(uis[option->ui],"BOOLEAN") == 0) ||
|
||||
(strcmp(uis[option->ui],"PICKONE") == 0)) {
|
||||
printf(" %s: -o %s=<choice>\n\n",
|
||||
option->text, option->keyword);
|
||||
printf(" <choice> can be one of the following:\n\n");
|
||||
} else {
|
||||
printf(" %s: -o %s=<choice1>,<choice2>,...\n\n",
|
||||
option->text, option->keyword);
|
||||
printf(" <choice1>, <choice2>, and so on can be out of the following:\n\n");
|
||||
}
|
||||
if (strcmp(option->keyword, "PageSize") == 0) {
|
||||
for (m = option->num_choices, choice = option->choices;
|
||||
m > 0;
|
||||
m --, choice ++) {
|
||||
size = ppdPageSize(ppd, choice->choice);
|
||||
|
||||
if (size == NULL)
|
||||
printf(" %s (%s, size unknown", choice->choice, choice->text);
|
||||
else
|
||||
printf(" %s (%s, size: %.2fx%.2fin", choice->choice,
|
||||
choice->text, size->width / 72.0, size->length / 72.0);
|
||||
if (strcmp(option->defchoice, choice->choice) == 0)
|
||||
puts(", default)");
|
||||
else
|
||||
puts(")");
|
||||
}
|
||||
} else {
|
||||
for (m = option->num_choices, choice = option->choices;
|
||||
m > 0;
|
||||
m --, choice ++) {
|
||||
printf(" %s (%s", choice->choice, choice->text);
|
||||
if (strcmp(option->defchoice, choice->choice) == 0)
|
||||
puts(", default)");
|
||||
else
|
||||
puts(")");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
ppdClose(ppd);
|
||||
|
||||
// Search for numerical options of CUPS-O-MATIC
|
||||
if ((ppdfile = fopen(filename,"r")) == NULL) {
|
||||
fprintf(stderr, "Unable to open \'%s\' as a PPD file!\n", filename);
|
||||
continue;
|
||||
}
|
||||
// Reset all variables
|
||||
opttype = 0;
|
||||
min = 0.0; max = 0.0; defvalue = 0.0;
|
||||
openbrackets = 0;
|
||||
inquotes = 0;
|
||||
writepointer = item;
|
||||
inargspart = 0;
|
||||
// Read the PPD file again, line by line.
|
||||
while (fgets(line,sizeof(line),ppdfile)) {
|
||||
// evaluate only lines with CUPS-O-MATIC info
|
||||
if (line_contents = strstr(line,"*% COMDATA #")) {
|
||||
line_contents += 12; // Go to the text after
|
||||
// "*% COMDATA #"
|
||||
for (scan = line_contents;
|
||||
(*scan != '\n') && (*scan != '\0');
|
||||
scan ++) {
|
||||
switch(*scan) {
|
||||
case '[': // open square bracket
|
||||
case '{': // open curled bracket
|
||||
if (!inquotes) {
|
||||
openbrackets ++;
|
||||
// we are on the left hand side now
|
||||
*writepointer = '\0';
|
||||
writepointer = item;
|
||||
// in which type of block are we now?
|
||||
if ((openbrackets == 2) &&
|
||||
(strncasecmp(item,"args",4) == 0)) {
|
||||
// we are entering the arguments section now
|
||||
inargspart = 1;
|
||||
}
|
||||
if ((openbrackets == 3) &&
|
||||
(inargspart == 1)) {
|
||||
// new argument, get its name
|
||||
strcpy(argname,item);
|
||||
}
|
||||
// item already evaluated now
|
||||
item[0] = '\0';
|
||||
} else {*writepointer = *scan; writepointer ++;}
|
||||
break;
|
||||
case ',': // end of logical line
|
||||
case ']': // close square bracket
|
||||
case '}': // close curled bracket
|
||||
if (!inquotes) {
|
||||
// right hand side completed, go to left hand side
|
||||
*writepointer = '\0';
|
||||
writepointer = item;
|
||||
// evaluate logical line
|
||||
if (item[0]) {
|
||||
// Machine-readable argument name
|
||||
if ((openbrackets == 3) &&
|
||||
(inargspart == 1) &&
|
||||
(strcasecmp(item,"name") == 0)) {
|
||||
strcpy(argname,value);
|
||||
}
|
||||
// Human-readable argument name
|
||||
if ((openbrackets == 3) &&
|
||||
(inargspart == 1) &&
|
||||
(strcasecmp(item,"comment") == 0)) {
|
||||
strcpy(comment,value);
|
||||
}
|
||||
// argument type
|
||||
if ((openbrackets == 3) &&
|
||||
(inargspart == 1) &&
|
||||
(strcasecmp(item,"type") == 0)) {
|
||||
if (strcasecmp(value,"int") == 0) opttype = 1;
|
||||
if (strcasecmp(value,"float") == 0) opttype = 2;
|
||||
}
|
||||
// minimum value
|
||||
if ((openbrackets == 3) &&
|
||||
(inargspart == 1) &&
|
||||
(strcasecmp(item,"min") == 0)) {
|
||||
min = atof(value);
|
||||
}
|
||||
// maximum value
|
||||
if ((openbrackets == 3) &&
|
||||
(inargspart == 1) &&
|
||||
(strcasecmp(item,"max") == 0)) {
|
||||
max = atof(value);
|
||||
}
|
||||
// default value
|
||||
if ((openbrackets == 3) &&
|
||||
(inargspart == 1) &&
|
||||
(strcasecmp(item,"default") == 0)) {
|
||||
defvalue = atof(value);
|
||||
}
|
||||
// item already evaluated now
|
||||
item[0] = '\0';
|
||||
}
|
||||
// close bracket
|
||||
if ((*scan == '}') || (*scan == ']')) {
|
||||
// which block did we complete now?
|
||||
if ((openbrackets == 2) &&
|
||||
(inargspart == 1)) {
|
||||
// We are leaving the arguments part now
|
||||
inargspart = 0;
|
||||
}
|
||||
if ((openbrackets == 3) &&
|
||||
(inargspart == 1)) {
|
||||
// The current option is completely parsed
|
||||
// Is the option a valid numerical option?
|
||||
if ((opttype > 0) &&
|
||||
(min != max) &&
|
||||
(argname[0])) {
|
||||
// Correct the default value, if necessary
|
||||
if (min < max) {
|
||||
if (defvalue < min) defvalue = min;
|
||||
if (defvalue > max) defvalue = max;
|
||||
} else {
|
||||
if (defvalue < max) defvalue = max;
|
||||
if (defvalue > min) defvalue = min;
|
||||
}
|
||||
// Show the found argument
|
||||
printf(" %s: -o %s=<value>\n\n",
|
||||
comment, argname);
|
||||
if (opttype == 1) {
|
||||
printf(
|
||||
" <value> must be an integer number in the range %d..%d\n",
|
||||
(int)(min),(int)(max));
|
||||
printf(
|
||||
" The default value is %d\n\n",
|
||||
(int)(defvalue));
|
||||
} else {
|
||||
printf(
|
||||
" <value> must be a decimal number in the range %.2f..%.2f\n",
|
||||
min,max);
|
||||
printf(
|
||||
" The default value is %.2f\n\n",
|
||||
defvalue);
|
||||
}
|
||||
}
|
||||
// reset the values
|
||||
argname[0] = '\0';
|
||||
opttype = 0;
|
||||
min = 0.0; max = 0.0; defvalue = 0.0;
|
||||
}
|
||||
openbrackets --;
|
||||
}
|
||||
} else {*writepointer = *scan; writepointer ++;}
|
||||
break;
|
||||
case '\'': // quote
|
||||
if (!inquotes) { // open quote pair
|
||||
inquotes = 1;
|
||||
} else { // close quote pair
|
||||
inquotes = 0;
|
||||
}
|
||||
break;
|
||||
case '=': // "=>"
|
||||
if ((!inquotes) && (*(scan + 1) == '>')) {
|
||||
scan ++;
|
||||
// left hand side completed, go to right hand side
|
||||
*writepointer = '\0';
|
||||
writepointer = value;
|
||||
} else {*writepointer = *scan; writepointer ++;}
|
||||
break;
|
||||
case ' ': // white space
|
||||
case '\t':
|
||||
if (!inquotes) {
|
||||
// ignore white space outside quotes
|
||||
} else {*writepointer = *scan; writepointer ++;}
|
||||
break;
|
||||
default:
|
||||
// write all other characters
|
||||
*writepointer = *scan; writepointer ++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
inquotes = 0; // quote pairs cannot enclose more
|
||||
// than one line
|
||||
}
|
||||
}
|
||||
fclose(ppdfile);
|
||||
printf("\n\n\n");
|
||||
}
|
||||
|
||||
if (!(strstr(tmpfile, "XXXXXX"))) {
|
||||
unlink(tmpfile);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
50
ogonki
Normal file
50
ogonki
Normal file
@ -0,0 +1,50 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "$#" -lt "5"; then
|
||||
echo "ERROR: Number of arguments ($#) is wrong" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "$#" -gt "6"; then
|
||||
echo "ERROR: Number of arguments ($#) is wrong" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Log the command line
|
||||
echo ogonkify: $@ 1>&2
|
||||
|
||||
# Get the last parameter (which is the filename if present)
|
||||
eval filename="\${$#}"
|
||||
|
||||
case "$CHARSET" in
|
||||
iso-8859-1) CMD="cat " ;;
|
||||
iso-8859-2) CMD="/usr/bin/ogonkify -AT -N " ;;
|
||||
iso-8859-3) CMD="/usr/bin/ogonkify -e L3 -AT -N " ;;
|
||||
iso-8859-4) CMD="/usr/bin/ogonkify -e L4 -AT -N " ;;
|
||||
iso-8859-9) CMD="/usr/bin/ogonkify -e L5 -AT -N " ;;
|
||||
iso-8859-10) CMD="/usr/bin/ogonkify -e L6 -AT -N " ;;
|
||||
iso-8859-15) CMD="/usr/bin/ogonkify -e L9 -AT -N " ;;
|
||||
*) CMD="cat " ;;
|
||||
esac
|
||||
|
||||
if [ -e $filename ]; then
|
||||
FILE_TO_PRINT=$filename;
|
||||
else
|
||||
FILE_TO_PRINT="";
|
||||
fi
|
||||
|
||||
if [ -z $FILE_TO_PRINT ]; then
|
||||
FILE_TO_PRINT=`mktemp -q /tmp/ogonki.XXXXXX`
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Can't create temp file, exiting..." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
trap "rm -f $FILE_TO_PRINT" EXIT SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM
|
||||
cat >$FILE_TO_PRINT
|
||||
fi
|
||||
|
||||
if [ -z $FILE_TO_PRINT ]; then
|
||||
eval $CMD
|
||||
else
|
||||
eval $CMD <$FILE_TO_PRINT
|
||||
fi
|
302
poll_ppd_base.c
Normal file
302
poll_ppd_base.c
Normal file
@ -0,0 +1,302 @@
|
||||
/*
|
||||
*
|
||||
* poll_ppd_base
|
||||
* -------------
|
||||
#
|
||||
# A simple tool for getting a list of all installed PPD files
|
||||
# with printer manufacturer and printer model, polling the database
|
||||
# of the CUPS daemon. This program is mainly intended to be called
|
||||
# from installation/configuration scripts for CUPS.
|
||||
#
|
||||
# ONLY WORKS WITH CUPS DAEMON RUNNING!
|
||||
# The CUPS library (libcups.so.*) must be installed!
|
||||
#
|
||||
# Compile with: gcc -opoll_ppd_base -lcups poll_ppd_base.c
|
||||
#
|
||||
* Copyright 2000 by Till Kamppeter
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <cups/cups.h>
|
||||
#include <cups/ipp.h>
|
||||
#include <cups/language.h>
|
||||
|
||||
// IPP Request routines for getting the printer type, stolen from QTCUPS from
|
||||
// Michael Goffioul (file qtcups/cupshelper.cpp)
|
||||
|
||||
ipp_t* newIppRequest()
|
||||
{
|
||||
ipp_t *request;
|
||||
cups_lang_t *lang;
|
||||
request = ippNew();
|
||||
request->request.op.request_id = 1;
|
||||
lang = cupsLangDefault();
|
||||
ippAddString(request,IPP_TAG_OPERATION,IPP_TAG_CHARSET,"attributes-charset",NULL,cupsLangEncoding(lang));
|
||||
ippAddString(request,IPP_TAG_OPERATION,IPP_TAG_LANGUAGE,"attributes-natural-language",NULL,lang->language);
|
||||
return request;
|
||||
}
|
||||
|
||||
ipp_t* processRequest(ipp_t *req, const char *res)
|
||||
{
|
||||
http_t *HTTP;
|
||||
ipp_t *answer;
|
||||
HTTP = httpConnect(cupsServer(),ippPort());
|
||||
if (!HTTP) {
|
||||
ippDelete(req);
|
||||
return 0;
|
||||
}
|
||||
answer = cupsDoRequest(HTTP,req,res);
|
||||
httpClose(HTTP);
|
||||
if (!answer) return 0;
|
||||
if (answer->state == IPP_ERROR || answer->state == IPP_IDLE) {
|
||||
ippDelete(answer);
|
||||
return 0;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
ipp_t *getPPDList()
|
||||
{
|
||||
ipp_t *request = newIppRequest();
|
||||
char str[1024];
|
||||
const char* server = cupsServer();
|
||||
int port = ippPort();
|
||||
|
||||
request->request.op.operation_id = CUPS_GET_PPDS;
|
||||
if ((!server) || (port < 0)) return NULL;
|
||||
sprintf(str,"ipp://%s:%d/printers/",cupsServer(),ippPort());
|
||||
ippAddString(request,IPP_TAG_OPERATION,IPP_TAG_URI,"printer-uri",NULL,str);
|
||||
//str.sprintf("/printers/%s",name);
|
||||
request = processRequest(request,"/");
|
||||
return request;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main program
|
||||
*/
|
||||
|
||||
int /* O - exit state */
|
||||
main(int argc, /* I - Number of command-line arguments */
|
||||
char *argv[]) /* I - Command-line arguments */
|
||||
{
|
||||
int i,j; /* Looping vars */
|
||||
int makelen = 0; /* Length of current manufacturer name */
|
||||
int makelist = 0; /* List of manufacturers */
|
||||
int makegiven = 0; /* List of models for given manufacturer */
|
||||
int all = 0; /* LIst of all models */
|
||||
char *make; /* Chosen manufacturer */
|
||||
ipp_t *ppdlist; /* List of PPD files resulting from IPP */
|
||||
/* request */
|
||||
ipp_attribute_t *attr, /* Current attribute */
|
||||
*last; /* Last attribute */
|
||||
char *currmake, /* current data red from PPD list */
|
||||
*currmod,
|
||||
*currlang,
|
||||
*currfile,
|
||||
*c;
|
||||
char buffer[80],
|
||||
buffer2[256];
|
||||
int lineprinted = 1; /* Is the current line already printed to
|
||||
stdout */
|
||||
|
||||
// read command line arguments
|
||||
|
||||
for (i = 1; i < argc; i ++)
|
||||
if (argv[i][0] == '-') {
|
||||
switch (argv[i][1]) {
|
||||
case 'm' : /* Manufacturer options */
|
||||
if (argv[i][2] != '\0') {
|
||||
if (strcmp(argv[i],"-ml") == 0) {
|
||||
makelist = 1;
|
||||
} else {
|
||||
make = argv[i] + 2;
|
||||
makegiven = 1;
|
||||
}
|
||||
} else {
|
||||
i ++;
|
||||
if (!(make = argv[i])) return 1;
|
||||
makegiven = 1;
|
||||
}
|
||||
break;
|
||||
case 'a' : /* List all PPD files */
|
||||
all = 1;
|
||||
break;
|
||||
default :
|
||||
fprintf(stderr,"Unknown option \'%c\'!\n", argv[i][1]);
|
||||
fprintf(stderr,"Start program without options for help!\n");
|
||||
return(1);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,"Unknown option \'%s\'!", argv[i]);
|
||||
fprintf(stderr,"Start program without options for help!\n");
|
||||
return(1);
|
||||
}
|
||||
if ((all) || (makegiven)) { // list all PPDs or PPDs of given manufacturer
|
||||
ppdlist = getPPDList();
|
||||
if (!ppdlist) return 1;
|
||||
for (attr = ppdlist->attrs; // go through all entries
|
||||
attr != NULL;
|
||||
attr = attr->next)
|
||||
if (attr->name) {
|
||||
// read data items
|
||||
if (strcmp(attr->name, "ppd-name") == 0) {
|
||||
currfile = attr->values[0].string.text;
|
||||
lineprinted = 0;
|
||||
} else if (strcmp(attr->name, "ppd-make") == 0) {
|
||||
currmake = attr->values[0].string.text;
|
||||
} else if (strcmp(attr->name, "ppd-make-and-model") == 0) {
|
||||
currmod = attr->values[0].string.text;
|
||||
} else if (strcmp(attr->name, "ppd-natural-language") == 0) {
|
||||
currlang = attr->values[0].string.text;
|
||||
}
|
||||
} else { // attr->name = NULL ==> data set completed
|
||||
lineprinted = 1;
|
||||
// Fill empty entries with some default stuff
|
||||
if (!currmod) currmod = "UNKNOWN";
|
||||
if (!currmake) currmake = "UNKNOWN";
|
||||
if (!currlang) currlang = "en";
|
||||
// Remove the manufacturer's name from the model entries
|
||||
makelen = strlen(currmake);
|
||||
if (strcasecmp(currmake,"UNKNOWN") != 0) {
|
||||
if (strncasecmp(currmake,currmod,makelen) == 0) {
|
||||
currmod += makelen;
|
||||
while ((*currmod == ' ') ||
|
||||
(*currmod == '-') ||
|
||||
(*currmod == '\t')) currmod ++;
|
||||
}
|
||||
}
|
||||
// Make the manufacturer's name all-uppercase
|
||||
currmake = strcpy(buffer,currmake);
|
||||
for (i = 0; i < makelen; i ++) buffer[i] = toupper(buffer[i]);
|
||||
// Clean up the driver info
|
||||
currmod = strcpy(buffer2,currmod);
|
||||
if (c = strstr(currmod, "Foomatic + Postscript")) {
|
||||
memmove(c, "PostScript", 10);
|
||||
memmove(c + 10, c + 21, strlen(c) - 20);
|
||||
} else if (c = strstr(currmod, "Foomatic")) {
|
||||
memmove(c + 11, c + 8, strlen(c) - 7);
|
||||
memmove(c, "GhostScript", 11);
|
||||
} else if (c = strstr(currmod, "CUPS+GIMP-print")) {
|
||||
memmove(c + 17, c + 15, strlen(c) - 14);
|
||||
memmove(c, "CUPS + GIMP-Print", 17);
|
||||
} else if (c = strstr(currmod, "Series CUPS")) {
|
||||
memmove(c + 12, c + 11, strlen(c) - 10);
|
||||
memmove(c, "Series, CUPS", 12);
|
||||
} else if (!((strstr(currmod, "PostScript")) ||
|
||||
(strstr(currmod, "Postscript")) ||
|
||||
(strstr(currmod, "POSTSCRIPT")))) {
|
||||
memmove(currmod + strlen(currmod), ", PostScript", 13);
|
||||
}
|
||||
// Put data to stdout when "all" is chosen or when the manufacturer
|
||||
// matches the given one.
|
||||
if ((currfile) && ((all) || !strcasecmp(currmake,make)))
|
||||
printf("%s|%s|%s|%s\n",currfile,currmake,currmod,currlang);
|
||||
}
|
||||
if (!lineprinted) {
|
||||
// Fill empty entries with some default stuff
|
||||
if (!currmod) currmod = "UNKNOWN";
|
||||
if (!currmake) currmake = "UNKNOWN";
|
||||
if (!currlang) currlang = "en";
|
||||
// Remove the manufacturer's name from the model entries
|
||||
makelen = strlen(currmake);
|
||||
if (strcasecmp(currmake,"UNKNOWN") != 0) {
|
||||
if (strncasecmp(currmake,currmod,makelen) == 0) {
|
||||
currmod += makelen;
|
||||
while ((*currmod == ' ') ||
|
||||
(*currmod == '-') ||
|
||||
(*currmod == '\t')) currmod ++;
|
||||
}
|
||||
}
|
||||
// Make the manufacturer's name all-uppercase
|
||||
currmake = strcpy(buffer,currmake);
|
||||
for (i = 0; i < makelen; i ++) buffer[i] = toupper(buffer[i]);
|
||||
// Clean up the driver info
|
||||
currmod = strcpy(buffer2,currmod);
|
||||
if (c = strstr(currmod, "Foomatic + Postscript")) {
|
||||
memmove(c, "PostScript", 10);
|
||||
memmove(c + 10, c + 21, strlen(c) - 20);
|
||||
} else if (c = strstr(currmod, "Foomatic")) {
|
||||
memmove(c + 11, c + 8, strlen(c) - 7);
|
||||
memmove(c, "GhostScript", 11);
|
||||
} else if (c = strstr(currmod, "CUPS+GIMP-print")) {
|
||||
memmove(c + 17, c + 15, strlen(c) - 14);
|
||||
memmove(c, "CUPS + GIMP-Print", 17);
|
||||
} else if (c = strstr(currmod, "Series CUPS")) {
|
||||
memmove(c + 12, c + 11, strlen(c) - 10);
|
||||
memmove(c, "Series, CUPS", 12);
|
||||
} else if (!((strstr(currmod, "PostScript")) ||
|
||||
(strstr(currmod, "Postscript")) ||
|
||||
(strstr(currmod, "POSTSCRIPT")))) {
|
||||
memmove(currmod + strlen(currmod), ", PostScript", 13);
|
||||
}
|
||||
// Put data to stdout when "all" is chosen or when the manufacturer
|
||||
// matches the given one.
|
||||
if ((currfile) && ((all) || !strcasecmp(currmake,make)))
|
||||
printf("%s|%s|%s|%s\n",currfile,currmake,currmod,currlang);
|
||||
}
|
||||
} else if (makelist) { // list all manufacturers
|
||||
ppdlist = getPPDList();
|
||||
if (!ppdlist) return 1;
|
||||
for (attr = ppdlist->attrs, last = NULL; // go through all entries
|
||||
attr != NULL;
|
||||
attr = attr->next)
|
||||
if (attr->name && strcmp(attr->name, "ppd-make") == 0)
|
||||
// only search for manufacturerer entriees
|
||||
if (last == NULL ||
|
||||
strcasecmp(last->values[0].string.text,
|
||||
attr->values[0].string.text) != 0)
|
||||
// Do not take the same manufacturer twice
|
||||
{
|
||||
// Put found manufacturer to stdout
|
||||
printf("%s\n",attr->values[0].string.text);
|
||||
last = attr;
|
||||
}
|
||||
} else { // Help!
|
||||
fprintf(stderr,"Usage:\n");
|
||||
fprintf(stderr,"------\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," poll_ppd_base\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," This help page\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," poll_ppd_base -a\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," List all PPD files\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," poll_ppd_base -ml\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," List of all printer manufacturers supported by the PPD files installed\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," poll_ppd_base -m <manufacturers name>\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," List of all supported printer models of this manufacturer\n");
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr,"ONLY WORKS WITH CUPS DAEMON RUNNING!\n");
|
||||
fprintf(stderr,"\n");
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
12
pswrite
Normal file
12
pswrite
Normal file
@ -0,0 +1,12 @@
|
||||
#! /bin/bash
|
||||
|
||||
# enable "set -x" for debug info in /var/log/cups/error_log
|
||||
#set -x
|
||||
|
||||
# set inputfile to where the input comes from
|
||||
inputfile="-"
|
||||
[ -n "$6" ] && inputfile="$6"
|
||||
|
||||
# output PostScript level 1 (for PostScript level 2 use -dLanguageLevel=2)
|
||||
gs -q -dBATCH -dPARANOIDSAFER -dNOPAUSE -sDEVICE=pswrite -dLanguageLevel=1 -sOutputFile=- $inputfile
|
||||
|
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);
|
||||
}
|
185
setcupsbroadcasting
Normal file
185
setcupsbroadcasting
Normal file
@ -0,0 +1,185 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
#
|
||||
# Script to automatically restrict the printer information broadcasting the
|
||||
# accepting of external broadcasts, and the access to the printers to local
|
||||
# (eth?) networks
|
||||
#
|
||||
|
||||
#
|
||||
# Till Kamppeter (till@mandrakesoft.com)
|
||||
#
|
||||
# Copyright 2000 MandrakeSoft
|
||||
#
|
||||
# This software may be freely redistributed under the terms of the GNU
|
||||
# General Public License.
|
||||
#
|
||||
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
|
||||
# Do not do any changes during the installation
|
||||
|
||||
if ($ENV{'DURING_INSTALL'}) {exit 0};
|
||||
|
||||
# Read CUPS config file
|
||||
|
||||
my $cups_conf = "/etc/cups/cupsd.conf";
|
||||
if (!(-f $cups_conf)) {die "No CUPS configuration file $cups_conf!"};
|
||||
open CONF_CUPS, "$cups_conf" or die "Can't open $cups_conf!";
|
||||
my @cups_conf_content = <CONF_CUPS>;
|
||||
close CONF_CUPS;
|
||||
|
||||
# If it contains at least one "BrowseAddress" line broadcasting is already
|
||||
# configured and we are done, stop silently here.
|
||||
|
||||
grep(/^\s*BrowseAddress[^:]/, @cups_conf_content) and exit 0;
|
||||
|
||||
# Read the output of "ifconfig" to look for local networks
|
||||
|
||||
my $dev_is_localnet = 0;
|
||||
my @local_networks = ();
|
||||
my @local_bcasts = ();
|
||||
my $current_ip = "";
|
||||
my $current_mask = "";
|
||||
my $current_bcast = "";
|
||||
|
||||
if (-x "/sbin/ifconfig") {
|
||||
open IFCONFIG_OUT, "/sbin/ifconfig|" or die "Couldn't run \"ifconfig\"!";
|
||||
while (defined($readline = <IFCONFIG_OUT>)) {
|
||||
# New entry ...
|
||||
if ($readline =~ /^(\S+)\s/) {
|
||||
$dev = $1;
|
||||
# ... for a local network?
|
||||
if ($dev =~ /^eth/) {$dev_is_localnet = 1}
|
||||
else {$dev_is_localnet = 0};
|
||||
# delete previous network data
|
||||
$current_ip = "";
|
||||
$current_mask = "";
|
||||
$current_bcast = "";
|
||||
}
|
||||
# Are we in an entry for a local network?
|
||||
if ($dev_is_localnet == 1) {
|
||||
# Are we in the important line now?
|
||||
if ($readline =~ /\sinet addr:[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\s/) {
|
||||
# Rip out the network addresses
|
||||
if ($readline =~ /\sinet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) {
|
||||
$current_ip = $1;
|
||||
}
|
||||
if ($readline =~ /\sBcast:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) {
|
||||
$current_bcast = $1;
|
||||
}
|
||||
if ($readline =~ /\sMask:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) {
|
||||
$current_mask = $1;
|
||||
}
|
||||
# Is the entry valid?
|
||||
if (($current_ip ne "") and ($current_mask ne "")) {
|
||||
# Is there a broadcast address?
|
||||
if ($current_bcast eq "") {$current_bcast = $current_ip};
|
||||
# Store broadcast address (or current IP if there is none)
|
||||
push @local_bcasts, $current_bcast;
|
||||
# Calculate mask fore access restriction
|
||||
$current_ip =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
|
||||
($i1, $i2, $i3, $i4) = ($1, $2, $3, $4);
|
||||
$current_mask =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
|
||||
($m1, $m2, $m3, $m4) = ($1, $2, $3, $4);
|
||||
$current_net = "";
|
||||
if ($m1 eq "255") {$current_net = "${current_net}${i1}\."};
|
||||
if ($m2 eq "255") {$current_net = "$current_net$i2."};
|
||||
if ($m3 eq "255") {$current_net = "$current_net$i3."};
|
||||
if ($m4 eq "255") {$current_net = "$current_net$i4"}
|
||||
else {$current_net = "$current_net*"};
|
||||
# Store mask
|
||||
push @local_networks, $current_net;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
close(IFCONFIG_OUT);
|
||||
}
|
||||
|
||||
# Remove all valid "BrowseAddress" lines
|
||||
($_ =~ /^\s*BrowseAddress[^:]/ and $_="") foreach @cups_conf_content;
|
||||
|
||||
# Insert the new "BrowseAddress" lines
|
||||
(push @cups_conf_content, "BrowseAddress $_\n") foreach @local_bcasts;
|
||||
|
||||
# Delete all "BrowseOrder", "BrowseAllow" and "BrowseDeny" lines from the file
|
||||
|
||||
($_ =~ /^\s*BrowseOrder/ and $_="") foreach @cups_conf_content;
|
||||
($_ =~ /^\s*BrowseAllow/ and $_="") foreach @cups_conf_content;
|
||||
($_ =~ /^\s*BrowseDeny/ and $_="") foreach @cups_conf_content;
|
||||
|
||||
# Add the new "BrowseOrder" and "BrowseDeny" lines
|
||||
|
||||
push(@cups_conf_content,"BrowseOrder Deny,Allow\n");
|
||||
push(@cups_conf_content,"BrowseDeny All\n");
|
||||
|
||||
# Add a "BrowseAllow" line for every local network
|
||||
|
||||
(push(@cups_conf_content,"BrowseAllow $_\n")) foreach @local_networks;
|
||||
|
||||
# Cut out the root location block
|
||||
#
|
||||
# <Location />
|
||||
# ...
|
||||
# </Location>
|
||||
#
|
||||
# so that it can be treated seperately without affecting the rest of the
|
||||
# file
|
||||
|
||||
if (grep(m!^\s*<Location\s+/\s*>!, @cups_conf_content)) {
|
||||
$root_location_start = -1;
|
||||
$root_location_end = -1;
|
||||
# Go through all the lines, bail out when start and end line found
|
||||
for ($i = 0;
|
||||
($i <= $#cups_conf_content) and ($root_location_end == -1);
|
||||
$i++) {
|
||||
if ($cups_conf_content[$i] =~ m!^\s*<\s*Location\s+/\s*>!) {
|
||||
# Start line of block
|
||||
$root_location_start = $i;
|
||||
} elsif (($cups_conf_content[$i] =~ m!^\s*<\s*/Location\s*>!) and
|
||||
($root_location_start != -1)) {
|
||||
# End line of block
|
||||
$root_location_end = $i;
|
||||
}
|
||||
}
|
||||
# Rip out the block and store it seperately
|
||||
@root_location =
|
||||
splice(@cups_conf_content,$root_location_start,
|
||||
$root_location_end - $root_location_start + 1);
|
||||
} else {
|
||||
# If there is no root location block, create one
|
||||
$root_location_start = $#cups_conf_content + 1;
|
||||
@root_location = ();
|
||||
push @root_location, "<Location />\n";
|
||||
push @root_location, "</Location>\n";
|
||||
}
|
||||
|
||||
# Delete all former "Order", "Allow", and "Deny" lines from the root location
|
||||
# block
|
||||
|
||||
($_ =~ /^\s*Order/ and $_="") foreach @root_location;
|
||||
($_ =~ /^\s*Allow/ and $_="") foreach @root_location;
|
||||
($_ =~ /^\s*Deny/ and $_="") foreach @root_location;
|
||||
|
||||
# Add the new "Order" and "Deny" lines
|
||||
|
||||
splice(@root_location,-1,0,"Order Deny,Allow\n");
|
||||
splice(@root_location,-1,0,"Deny From All\n");
|
||||
splice(@root_location,-1,0,"Allow From 127.0.0.1\n");
|
||||
|
||||
# Add an "Allow" line for every local network
|
||||
|
||||
(splice(@root_location,-1,0,"Allow From $_\n")) foreach @local_networks;
|
||||
|
||||
# Put the changed root location block back into the file
|
||||
|
||||
splice(@cups_conf_content,$root_location_start,0,@root_location);
|
||||
|
||||
# Write back the modified CUPS config file
|
||||
|
||||
open CONF_CUPS, ">$cups_conf" or die "Can't open $cups_conf";
|
||||
print CONF_CUPS @cups_conf_content;
|
||||
close CONF_CUPS;
|
Loading…
x
Reference in New Issue
Block a user