1
0
forked from pool/cups-backends
OBS User unknown 2007-01-15 23:08:17 +00:00 committed by Git OBS Bridge
commit cc93d2f219
12 changed files with 1115 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.osc

156
README-beh.html Normal file
View File

@ -0,0 +1,156 @@
<html><head>
<meta name="description" content="&lt;!-- content: undefined tag: description --&gt;"><title>beh - The Backend Error Handler</title></head><body bgcolor="#ffffff">
<table border="0" cellpadding="6" cellspacing="0" width="100%">
<tbody><tr>
<td bgcolor="#ffffff" width="100%"> <!-- top bar -->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody><tr>
<td><font size="+3">
<a href="http://www.linuxprinting.org/beh.html">beh</a> -
The Backend Error Handler</font></td>
<!-- could put other stuff here flush right in with title -->
</tr>
</tbody></table>
</td>
</tr>
<tr>
<td height="100%" valign="top" width="100%"> <!-- contents -->
<!-- header/announcementy things go here -->
Very annoying with CUPS is that when an error on the communication
between the CUPS backend and the printer occurs, CUPS disables the
print queue and to be able to continue printing an administrator (root
access required) has to re-enable the queue. It is not enough to
simply fix the printer's communication problem (like turning it on,
fixing the network connection, ...).<p>
This is especially a very bad design for desktop/home users. They
often only turn on their printers when they really want to print (to
save energy). Then it happens easily that they send a job and forget
to turn on the printer. CUPS disables the queue and the annoying
re-enabling procedure has to be done. And many users even do not know
about the problem. So the printer does not print and the queue gets
nuked and re-created. Or the people cry on the help forums or at the
installation support of their distributions.</p><p>
This problem can be easily worked around by installing <tt><a href="http://www.linuxprinting.org/download.cgi?filename=beh&amp;show=0">beh</a></tt>, the
<b>B</b>ackend <b>E</b>rror <b>H</b>andler. This script makes the
handling of such backend errors configurable, so that the problem can
easily be worked around. The new possibilities are:</p><p>
</p><ul>
<li> Let queues simply not being disabled. Simple approach, but job gets
lost.
</li><li> Repeat a given number of times.
</li><li> Repeat infinitely often, until the job gets finally through. This
is the standard of LPRng, and it eliminates loss of the job.
</li><li> The interval between two attempts to run the backend can also be
configured.
</li><li> Configuration is done independently for each print queue. So local
printers and network printers can be treated differently.
</li></ul><p>
Simply <a href="http://www.linuxprinting.org/download.cgi?filename=beh&amp;show=0">download</a> the
script, copy it into the CUPS backend directory (normally
<tt>/usr/lib/cups/backend/</tt>), and make it executable with
"<tt>chmod 755 beh</tt>. Then restart CUPS that it registers the new
backend, usually with "<tt>killall -HUP cupsd</tt>" or
"/etc/init.d/cups restart". If you did all correctly, there must be a
line containing "<tt>beh</tt>" in the output of "<tt>lpinfo
-v</tt>".</p><p>
<tt>beh</tt> is a wrapper which is called by CUPS in place of the usual backend, which is called by <tt>beh</tt> now. This way <tt>beh</tt>
can, depending on its configuration, repeat the call of the backend or
simply hide the error status of the backend from being seen by the CUPS
daemon.</p><p>
To make a print queue usinf <tt>beh</tt>, get root and call a command as follows:</p><p>
<tt>lpadmin -p &lt;queue name&gt; -E -v beh:/&lt;dd&gt;/&lt;att&gt;/&lt;delay&gt;/&lt;originaluri&gt;</tt></p><p>
with</p><p>
</p><dl>
<dt><tt>&lt;queue name&gt;</tt>:
</dt><dd>The name of your print queue<p>
</p></dd><dt><tt>&lt;dd&gt;</tt>:
</dt><dd>Don't Disable, if "<tt>1</tt>", <tt>beh</tt> always exits with
zero status, so the queue gets never disabled when the original
backend exits with an error. "<tt>0</tt>" carries the error
status of the last call of the backend (after
<tt>&lt;att&gt;</tt> retries) on to CUPS, so the queue usually
gets disabled.<p>
</p></dd><dt><tt>&lt;att&gt;</tt>:
</dt><dd>Attempts, number of attempts to recall the backend in case of
an error. "<tt>0</tt>" means infinite retries. In this case
<tt>&lt;dd&gt;</tt> gets meaningless.<p>
</p></dd><dt><tt>&lt;delay&gt;</tt>:
</dt><dd>Delay between two attempts to call the beckend, to be given in
seconds and as an integer number. Meaningless if
<tt>&lt;att&gt;</tt> is one.<p>
</p></dd><dt><tt>&lt;originaluri&gt;</tt>:
</dt><dd>The original URI, which your queue had before (use "<tt>lpstat
-v</tt>" to get your queue's URI shown).<p>
</p></dd></dl><p>
All parameters, especially, <tt>&lt;dd&gt;</tt>,
<tt>&lt;att&gt;</tt>, and <tt>&lt;delay&gt;</tt> have always to be
specified, even if one of them is meaningless due to the setting of
the others.</p><p>
<tt>beh</tt> works with every backend except the <tt>hp</tt> backend
from <a href="http://hpinkjet.sf.net/">HPLIP</a>. If <tt>beh</tt> is
used with the <tt>hp</tt> backend, the HP Toolbox will not find the
printers any more.</p><p>
Example URIs:</p><p>
</p><dl>
<dt><tt>beh:/1/3/5/socket://printer:9100</tt>
</dt><dd>On the network printer with host name "<tt>printer</tt>" it is
tried to access 3 times with 5 second delays between the
attempts. If the job still fails, the queue is not disabled
(and the job discarded).<p>
</p></dd><dt><tt>beh:/0/10/60/socket://printer:9100</tt>
</dt><dd>Retry 10 times in one minute intervals, disable the queue when
still not succeeding.<p>
</p></dd><dt><tt>beh:/1/0/60/usb://Brother/HL-5040%20series</tt>
</dt><dd>On a Brother HL-5040 on the USB try infinitely often until the
printer comes back, in intervals of one minute. This way the
job does not get lost when the printer is turned off and one
can intendedly delay printing by simply switching off the
printer. The ideal configuration for desktop printers and/or
home users.<p>
</p></dd></dl><p>
Report bugs in <tt><a href="http://www.linuxprinting.org/forums.cgi?group=linuxprinting.foomatic.devel">linuxprinting.foomatic.devel</a></tt>.
</p></td>
</tr>
</tbody></table>
</body></html>

203
beh Normal file
View File

@ -0,0 +1,203 @@
#!/usr/bin/perl
# The above Perl path may vary on your system; fix it!!! -*- perl -*-
# beh - Backend Error Handler
# A wrapper for CUPS backends to make error handling configurable
# Usually, if a CUPS backend exits with an error status other than zero
# (for example if a printer is not turned on or not reachable on the
# network), CUPS disables the print queue and one can only print again
# if a system administrator re-enables the queue manually. Even restarting
# CUPS (or rebooting) does not re-enable disabled queues.
#
# For system administrators this can get annoying, for newbie users
# who are not aware of this problem it looks like that CUPS is severely
# broken. They remove and re-install print queues, getting on the nerves
# of distro install support, people, or even switch back to a proprietary
# operating system.
#
# This script makes the handling of such backend errors configurable, so
# that the problem can easily be worked around. The new possibilities are:
#
# - Let queues simply not being disabled. Simple approach, but job gets
# lost.
#
# - Repeat a given number of times.
#
# - Repeat infinitely often, until the job gets finally through. This
# is the standard of LPRng, and it eliminates loss of the job.
#
# - The interval between two attemts to run the backend can also be
# configured.
#
# - Configuration is done independently for each print queue. So local
# printers and network printers can be treated differently.
# Save this file in your CUPS backend directory, usually
# /usr/lib/cups/backend/ or /usr/local/lib/cups/backend/
#
# Mark this filter world-readable and world-executable. Restart CUPS to
# make the new backend known to the spooler.
#
# See http://www.linuxprinting.org/cups-doc.html and the additional
# instructions below.
# beh - Backend Error Handler
#
# Copyright 2005 Till Kamppeter <till.kamppeter@gmx.net>
#
# 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.
# Usage:
#
# cp beh /usr/lib/cups/backend/
# chmod 755 /usr/lib/cups/backend/beh
# killall -HUP cupsd (or "/etc/init.d/cups restart")
# lpadmin -p <queue name> -E -v beh:/<dd>/<att>/<delay>/<originaluri>
#
# with
# <queue name>: The name of your print queue
# <dd>: Don't Disable, if "1", beh always exits with zero
# status, so the queue gets never disabled when the
# original backend exits with an error. "0" carries
# the error status of the last call of the backend
# (after <att> retries) on to CUPS, so the queue
# usually gets disabled.
# <att>: Attempts, number of attempts to recall the backend
# in case of an error. "0" means infinite retries. In
# this case <dd> gets meaningless.
# <delay>: Delay between two attempts to call the beckend, to
# be given in seconds and as an integer number.
# Meaningless if <att> is one.
# <originaluri>: The original URI, which your queue had before.
#
# All parameters, especially, <dd>, <att>, and <delay> have always to
# be specified, even if one of them is meaningless due to the setting of
# the others.
#
# beh works with every backend except the "hp" backend of HPLIP.
#
# Example URIs:
#
# beh:/1/3/5/socket://printer:9100
#
# On the network printer with host name "printer" it is tried to access
# 3 times with 5 second delays between the attempts. If the job still
# fails, the queue is not disabled (and the job discarded).
#
# beh:/0/10/60/socket://printer:9100
#
# Retry 10 times in one minute intervals, disable the queue when still
# not succeeding.
#
# beh:/1/0/60/usb://Brother/HL-5040%20series
#
# On a Brother HL-5040 on the USB try infinitely often until the printer
# comes back, in intervals of one minute. This way the job does not get
# lost when the printer is turned off and one can intendedly delay
# printing by simply switching off the printer. The ideal configuration
# for desktop printers and/or home users.
# Acknowledgement
#
# Thanks to Jeff Hardy (hardyjm at potsdam dot edu) for writing the
# "accsnmp" wrapper backend (http://fritz.potsdam.edu/projects/cupsapps/).
# This backend showed me the trick how to write a universal wrapper
# backend in a scripting language.
use strict;
$0 =~ m!^(.*)/([^/]+)\s*$!;
my $progname = ($2 || $0);
my $progpath = ($1 || "/usr/lib/cups/backend");
if (!$ARGV[0]){
print "network $progname \"Unknown\" \"Backend Error Handler\"\n";
exit 0;
}
if (scalar(@ARGV) < 5 || scalar(@ARGV) > 6){
print STDERR "ERROR: Usage: $progname job-id user title copies options [file]\n";
exit 1;
}
my ($jobID, $userName, $jobTitle, $copies, $printOptions, $printFile) =
@ARGV;
my $tempFile;
if (!$printFile) {
my $jid = $jobID;
my $uid = $userName;
$jid =~ s/\W//g; #sanity check
$uid =~ s/\W//g; #sanity check
$tempFile = "$ENV{TMPDIR}/$jid-$uid-cupsjob$$";
open (OUT, ">$tempFile") or die "ERROR: Cannot write $tempFile: $!\n";
while(<STDIN>){
print OUT "$_";
}
close OUT;
$printFile = $tempFile;
# Backends should only produce multiple copies if a file name is
# supplied (see CUPS Software Programmers Manual)
$copies = 1;
}
my $uri = $ENV{DEVICE_URI};
$uri =~ m!^$progname:/(\d+)/(\d+)/(\d+)/(\S+)$! or
die "URI must be \"beh:/<dd>/<att>/<delay>/<original uri>\"!\n";
my $dontdisable = $1;
my $attempts = $2;
my $delay = $3;
$uri = $4;
$uri =~ m!^([^:\s]+):!;
my $backend = $1;
$ENV{DEVICE_URI} = $uri;
# Control by "lpr" command line options, commented out for security
# reasons (user could intendedly make queues being disabled)
#$printOptions =~ m/\bBackendErrorDisableQueue=(\S*)\b/ &&
# ($dontdisable = ($1 =~ /no/i ? 1 : 0));
#$printOptions =~ m/\bBackendErrorRetries=(\S*)\b/ && ($attempts = $1);
#$printOptions =~ m/\bBackendErrorRetryDelay=(\S*)\b/ && ($delay = $1);
#$printOptions =~ m/\bBackendErrorRetryForever=(\S*)\b/ &&
# ($delay = ($1 =~ /yes/i ? 0 : $delay));
my $exitvalue;
while($exitvalue = (($uri !~ m!^file:(.*)$!) && ($uri !~ m!^(/.*)$!) ?
system {"$progpath/$backend"}
($uri, $jobID, $userName, $jobTitle, $copies,
$printOptions, $printFile) :
system ("cat $printFile > $1")) >> 8) {
if ($attempts > 0) {
$attempts --;
last if $attempts == 0;
}
sleep $delay if $delay > 0;
}
unlink $tempFile if $tempFile;
$exitvalue = 0 if $dontdisable;
exit $exitvalue;

33
cups-backends.changes Normal file
View File

@ -0,0 +1,33 @@
-------------------------------------------------------------------
Wed Mar 22 19:20:19 CET 2006 - lmuelle@suse.de
- Update beh backend to the current version.
- Add beh documentation derivated from http://www.linuxprinting.org/beh.html.
- Move ncp backend to the ncpfs package.
-------------------------------------------------------------------
Wed Jan 25 21:35:17 CET 2006 - mls@suse.de
- converted neededforbuild to BuildRequires
-------------------------------------------------------------------
Thu Jan 12 15:54:28 CET 2006 - kssingvo@suse.de
- added backend error handler (beh) (bugzilla#132002)
-------------------------------------------------------------------
Tue Oct 4 10:23:29 CEST 2005 - jsrain@suse.cz
- fixed the error handling in the pipe backend (#93480)
-------------------------------------------------------------------
Mon Sep 19 23:12:59 CEST 2005 - lmuelle@suse.de
- Don't redirect stdout to stderr in the pipe backend.
- Install the right files, [#117887].
-------------------------------------------------------------------
Tue Jul 26 12:47:55 CEST 2005 - kssingvo@suse.de
- initial version

83
cups-backends.spec Normal file
View File

@ -0,0 +1,83 @@
#
# spec file for package cups-backends (Version 1.0)
#
# Copyright (c) 2006 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
# package are under the same license as the package itself.
#
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
# norootforbuild
Name: cups-backends
BuildRequires: cups-devel hal-devel
Summary: Various Free Backends for the cups Package
License: GPL
Group: Hardware/Printing
Version: 1.0
Release: 11
Source0: http://www.srz.de/Members/bla/cups/backend/hpnpf/hpnpf.tgz
Source1: http://www.srz.de/Members/bla/cups/backend/hpnpf/hpnpf.txt
Source2: cups-pipe.pl
Source4: hal.c
Source5: http://www.linuxprinting.org/download/printing/beh
Source6: README-beh.html
Patch0: hpnpf.patch
Requires: cups-libs, dbus-1, hal
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%description
This package contains free additional backends for CUPS.
Authors:
--------
Jiri Srain <jsrain@suse.cz>
Jeffrey Stedfast <fejj@novell.com>
%prep
%setup -c -T
mkdir hpnpf
cd hpnpf
tar xzvvf %{SOURCE0}
cd ..
cp -a %{SOURCE4} .
cp -a %{SOURCE5} beh
cp -a %{SOURCE6} .
%build
gcc $RPM_OPT_FLAGS -fPIC -fPIE -pie -DDBUS_API_SUBJECT_TO_CHANGE \
-I%{_includedir}/dbus-1.0/ -I%{_libdir}/dbus-1.0/include/ \
-ldbus-1 -lhal hal.c -o hal
%install
mkdir -p $RPM_BUILD_ROOT/%{_libdir}/cups/backend
install -m 755 -D ${RPM_SOURCE_DIR}/cups-pipe.pl $RPM_BUILD_ROOT%{_libdir}/cups/backend/pipe
install -m 755 -D hal $RPM_BUILD_ROOT%{_libdir}/cups/backend/hal
install -m 755 -D beh $RPM_BUILD_ROOT%{_libdir}/cups/backend/beh
%files
%defattr(-, root,root)
%dir %{_libdir}/cups
%dir %{_libdir}/cups/backend
%{_libdir}/cups/backend/*
%doc README-beh.html
%changelog -n cups-backends
* Wed Mar 22 2006 - lmuelle@suse.de
- Update beh backend to the current version.
- Add beh documentation derivated from http://www.linuxprinting.org/beh.html.
- Move ncp backend to the ncpfs package.
* Wed Jan 25 2006 - mls@suse.de
- converted neededforbuild to BuildRequires
* Thu Jan 12 2006 - kssingvo@suse.de
- added backend error handler (beh) (bugzilla#132002)
* Tue Oct 04 2005 - jsrain@suse.cz
- fixed the error handling in the pipe backend (#93480)
* Mon Sep 19 2005 - lmuelle@suse.de
- Don't redirect stdout to stderr in the pipe backend.
- Install the right files, [#117887].
* Tue Jul 26 2005 - kssingvo@suse.de
- initial version

68
cups-pipe.pl Normal file
View File

@ -0,0 +1,68 @@
#!/usr/bin/perl -w
#
# CUPS backend for printing to any program via pipe
#
# Copyright (c) 2003 SuSE Linux AG, Nuernberg, Germany.
#
# Author: Jiri Srain <jsrain@suse.cz>, 2003
#
$scheme = "pipe";
if (@ARGV == 0)
{
print "file $scheme \"Unknown\" \"Printing to any command via pipe\"\n";
exit 0;
}
# in case of wrong number of arguments: print usage hint
if (@ARGV != 5 && @ARGV != 6)
{
print STDERR "
Usage: pipe job-id user title copies options [file]
example for device-URI: 'pipe:/path/to/targetcommand'
Install a printqueue with 'lpadmin -p <pipe-printer-name>
-v pipe:/</path/to/targetcommand> -E
";
exit 1;
}
if (defined ($ARGV[5]))
{
$file = $ARGV[5];
}
else
{
$file = "-";
}
# get file to which the job is "printed" from device URI, so
# so that you can use this backend multiple times, for various
# "pipe" printers...
$uri = $ENV{"DEVICE_URI"};
$arg = $uri;
$arg =~ s/$scheme:(.*)/$1/;
$cmdln = "/bin/cat $file | $arg";
if ($> == 0)
{
$cmdln = "su -c \"$cmdln \" lp";
}
my $exit = system ($cmdln);
if ($exit != 0)
{
print STDERR "ERROR: Error occurred while executing $cmdln";
}
exit $exit >> 8;

358
hal.c Normal file
View File

@ -0,0 +1,358 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Authors: Jeffrey Stedfast <fejj@novell.com>
* Authors: Klaus Singvogel <kssingvo@suse.de>
*
* Copyright 2005 Novell, Inc. (www.novell.com)
*
* 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 Street #330, Boston, MA 02111-1307, USA.
*
*/
#include <cups/cups.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <dbus/dbus.h>
#include <hal/libhal.h>
static LibHalContext *
get_hal_ctx (void)
{
DBusConnection *connection;
LibHalContext *hal_ctx;
DBusError error;
if (!(hal_ctx = libhal_ctx_new ())) {
fprintf (stderr, "ERROR: Unable to create HAL context\n");
return NULL;
}
dbus_error_init (&error);
if (!(connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error))) {
fprintf (stderr, "ERROR: Unable to connect to DBUS: %s\n", error.message);
libhal_ctx_free (hal_ctx);
dbus_error_free (&error);
return NULL;
}
libhal_ctx_set_dbus_connection (hal_ctx, connection);
if (!libhal_ctx_init (hal_ctx, &error)) {
fprintf (stderr, "ERROR: Unable to init HAL context: %s\n", error.message);
libhal_ctx_free (hal_ctx);
dbus_error_free (&error);
return NULL;
}
return hal_ctx;
}
/*
* 'list_devices()' - List all HAL printer devices.
*/
static void
list_devices (void)
{
LibHalContext *hal_ctx;
char **printers;
int i, n;
if (!(hal_ctx = get_hal_ctx ()))
return;
printers = libhal_find_device_by_capability (hal_ctx, "printer", &n, NULL);
if (n == 0)
printf("direct hal \"Unknown\" \"Hal printing backend\"\n");
for (i = 0; i < n; i++) {
char *vendor, *product, *description;
char make_model[1024];
/* We only want printers that have device nodes */
if (!libhal_device_property_exists (hal_ctx, printers[i], "printer.device", NULL))
continue;
vendor = libhal_device_get_property_string (hal_ctx, printers[i], "printer.vendor", NULL);
product = libhal_device_get_property_string (hal_ctx, printers[i], "printer.product", NULL);
description = libhal_device_get_property_string (hal_ctx, printers[i], "printer.description", NULL);
/* Try our hardest to get a good name */
if (product != NULL) {
if (vendor != NULL) {
snprintf (make_model, sizeof (make_model), "%s %s", vendor, product);
} else {
strncpy (make_model, product, sizeof (make_model) - 1);
make_model[sizeof (make_model) - 1] = '\0';
}
} else if (description != NULL) {
strncpy (make_model, description, sizeof (make_model) - 1);
make_model[sizeof (make_model) - 1] = '\0';
} else if (vendor != NULL) {
snprintf (make_model, sizeof (make_model), "%s printer", vendor);
} else {
strcpy (make_model, "Unknown");
}
printf ("direct hal://%s \"%s\" \"%s\"\n", printers[i], make_model,
description != NULL ? description : make_model);
libhal_free_string (vendor);
libhal_free_string (product);
libhal_free_string (description);
}
libhal_ctx_shutdown (hal_ctx, NULL);
libhal_ctx_free (hal_ctx);
}
/*
* 'get_device_file()' - Get a device file from a HAL device UDI
*/
static char *
get_device_file (const char *uri)
{
LibHalContext *hal_ctx;
const char *udi;
char *device;
if (strncmp (uri, "hal://", 6) != 0)
return NULL;
if (!(hal_ctx = get_hal_ctx ()))
return NULL;
udi = uri + 6;
device = libhal_device_get_property_string (hal_ctx, udi, "printer.device", NULL);
libhal_ctx_shutdown (hal_ctx, NULL);
libhal_ctx_free (hal_ctx);
return device;
}
/*
* 'main()' - Send a file to the specified HAL printer device.
*
* Usage:
*
* printer-uri job-id user title copies options [file]
*/
int
main (int argc, char *argv[])
{
int fp; /* Print file */
int copies; /* Number of copies to print */
char *device; /* Device file to open */
int fd; /* Device file descriptor */
ssize_t nwritten; /* Number of bytes written */
size_t nbytes; /* Number of bytes read */
size_t tbytes; /* Total number of bytes written */
char buffer[8192]; /* Output buffer */
char *bufptr; /* Pointer into buffer */
struct termios opts; /* Parallel port options */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action; /* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
#if defined(__linux) && defined(LP_POUTPA)
unsigned char status; /* Port status (off-line, out-of-paper, etc.) */
#endif /* __linux */
/*
* Make sure status messages are not buffered...
*/
setbuf (stderr, NULL);
/*
* Ignore SIGPIPE signals...
*/
#ifdef HAVE_SIGSET
sigset (SIGPIPE, SIG_IGN);
#elif defined(HAVE_SIGACTION)
memset (&action, 0, sizeof (action));
action.sa_handler = SIG_IGN;
sigaction (SIGPIPE, &action, NULL);
#else
signal (SIGPIPE, SIG_IGN);
#endif /* HAVE_SIGSET */
/*
* Check command-line...
*/
if (argc == 1) {
list_devices ();
return 0;
} else if (argc < 6 || argc > 7) {
fputs ("Usage: URI job-id user title copies options [file]\n", stderr);
return 1;
}
/*
* If we have 7 arguments, print the file named on the command-line.
* Otherwise, send stdin instead...
*/
if (argc == 6) {
fp = 0;
copies = 1;
} else {
if ((fp = open (argv[6], O_RDONLY)) == -1) {
perror ("ERROR: unable to open print file");
return 1;
}
copies = atoi (argv[4]);
}
if (!(device = get_device_file (argv[0]))) {
fprintf (stderr, "ERROR: Unable to open HAL device \"%s\"\n", argv[0]);
return 1;
}
do {
if ((fd = open (device, O_RDWR | O_EXCL)) == -1) {
if (errno == EBUSY) {
fputs ("INFO: Device busy; will retry in 30 seconds...\n", stderr);
sleep (30);
} else if (errno == ENXIO || errno == EIO || errno == ENOENT) {
fputs ("INFO: Printer not connected; will retry in 30 seconds...\n", stderr);
sleep (30);
} else {
fprintf (stderr, "ERROR: Unable to open device \"%s\": %s\n",
argv[0], strerror (errno));
return 1;
}
}
} while (fd == -1);
libhal_free_string (device);
/*
* Set any options provided...
*/
tcgetattr (fd, &opts);
opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */
/**** No options supported yet ****/
tcsetattr (fd, TCSANOW, &opts);
/*
* Now that we are "connected" to the port, ignore SIGTERM so that we
* can finish out any page data the driver sends (e.g. to eject the
* current page... Only ignore SIGTERM if we are printing data from
* stdin (otherwise you can't cancel raw jobs...)
*/
if (argc < 7) {
#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
sigset (SIGTERM, SIG_IGN);
#elif defined(HAVE_SIGACTION)
memset (&action, 0, sizeof (action));
sigemptyset (&action.sa_mask);
action.sa_handler = SIG_IGN;
sigaction (SIGTERM, &action, NULL);
#else
signal (SIGTERM, SIG_IGN);
#endif /* HAVE_SIGSET */
}
#if defined(__linux) && defined(LP_POUTPA)
if (ioctl (fd, LPGETSTATUS, &status) == 0) {
fprintf (stderr, "DEBUG: LPGETSTATUS returned a port status of %02X...\n", status);
if (!(status & LP_POUTPA))
fputs ("WARNING: Media tray empty!\n", stderr);
else if (!(status & LP_PERRORP))
fputs ("WARNING: Printer fault!\n", stderr);
else if (!(status & LP_PSELECD))
fputs ("WARNING: Printer off-line.\n", stderr);
}
#endif /* __linux && LP_POUTPA */
/*
* Finally, send the print file...
*/
while (copies > 0) {
copies--;
if (fp != 0) {
fputs ("PAGE: 1 1\n", stderr);
lseek (fp, 0, SEEK_SET);
}
tbytes = 0;
while ((nbytes = read (fp, buffer, sizeof (buffer))) > 0) {
/*
* Write the print data to the printer...
*/
tbytes += nbytes;
bufptr = buffer;
while (nbytes > 0) {
if ((nwritten = write (fd, bufptr, nbytes)) == -1)
if (errno == ENOTTY)
nwritten = write (fd, bufptr, nbytes);
if (nwritten == -1) {
perror ("ERROR: Unable to send print file to printer");
break;
}
nbytes -= nwritten;
bufptr += nwritten;
}
if (nwritten == -1)
break;
if (argc > 6)
fprintf (stderr, "INFO: Sending print file, %lu bytes...\n", (unsigned long) tbytes);
}
}
/*
* Close the socket connection and input file and return...
*/
close (fd);
if (fp != 0)
close (fp);
fputs ("INFO: Ready to print.\n", stderr);
return 0;
}

95
hpnpf.patch Normal file
View File

@ -0,0 +1,95 @@
--- hpnpf/fifo.c.orig 2000-07-18 05:40:24.000000000 +0200
+++ hpnpf/fifo.c 2005-07-26 12:15:35.000000000 +0200
@@ -29,6 +29,7 @@
#endif
#include <stdio.h>
+#include <string.h>
#include "fifo.h"
extern char leftstr[]; /* hpnpf: prepend or leftover string */
--- hpnpf/hpnptyd.c.orig 1992-02-14 23:05:57.000000000 +0100
+++ hpnpf/hpnptyd.c 2005-07-26 12:17:53.000000000 +0200
@@ -81,8 +81,12 @@
/*
* Declare external variables.
*/
+#ifndef errno
extern int errno; /* system error number */
+#endif
+#ifndef LINUX
extern char *sys_errlist[]; /* array of system error messages */
+#endif
extern char *optarg; /* pointer to option argument */
extern int optind; /* index of current option */
extern int opterr; /* flag to enable error logging by getopt() */
--- hpnpf/linux_std.mak.orig 2004-02-14 21:46:29.000000000 +0100
+++ hpnpf/linux_std.mak 2005-07-26 12:15:09.000000000 +0200
@@ -1,8 +1,10 @@
-CC=cc -DSVR4 -DLINUX -DSTDARG -lnsl
+CC=cc -DSVR4 -DLINUX -DSTDARG
+LIBS=-lnsl
+
all: hpnpf hpnptyd
hpnptyd: fifo.h hpnptyd.o network.o fifo.o log.o
- cc -o hpnptyd hpnptyd.o network.o fifo.o log.o
+ ${CC} -o hpnptyd hpnptyd.o network.o fifo.o log.o ${LIBS}
hpnpf: fifo.h hpnpf.o network.o fifo.o log.o status.o
${CC} -o hpnpf hpnpf.o network.o fifo.o log.o status.o
--- hpnpf/log.c.orig 2004-02-14 21:44:10.000000000 +0100
+++ hpnpf/log.c 2005-07-26 12:16:23.000000000 +0200
@@ -27,6 +27,8 @@
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
#ifdef STDARG
#include <stdarg.h>
#else
--- hpnpf/network.c.orig 2000-07-24 00:38:34.000000000 +0200
+++ hpnpf/network.c 2005-07-26 12:12:55.000000000 +0200
@@ -28,6 +28,9 @@
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
+#ifdef LINUX
+#include <stdlib.h>
+#endif
/* adapt to UNIX System 5.4 1995-01-29/Bl */
#ifdef SVR4
--- hpnpf/hpnptyd.c.orig 2005-07-26 12:18:48.000000000 +0200
+++ hpnpf/hpnptyd.c 2005-07-26 12:20:39.000000000 +0200
@@ -41,6 +41,7 @@
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
+#include <stdlib.h>
#if defined(BSD)
#include <sys/file.h>
#include <sys/ioctl.h>
--- hpnpf/linux_std.mak.orig 2005-07-26 12:18:48.000000000 +0200
+++ hpnpf/linux_std.mak 2005-07-26 12:23:22.000000000 +0200
@@ -1,7 +1,8 @@
CC=cc -DSVR4 -DLINUX -DSTDARG
LIBS=-lnsl
-all: hpnpf hpnptyd
+all: hpnpf
+# doesn't link: hpnptyd
hpnptyd: fifo.h hpnptyd.o network.o fifo.o log.o
${CC} -o hpnptyd hpnptyd.o network.o fifo.o log.o ${LIBS}
--- hpnpf/network.c.orig 2005-07-26 12:23:54.000000000 +0200
+++ hpnpf/network.c 2005-07-26 12:27:47.000000000 +0200
@@ -28,6 +28,7 @@
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
+#include <string.h>
#ifdef LINUX
#include <stdlib.h>
#endif

3
hpnpf.tgz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7f1f135034f6be05ebb7066d8bed3630b895746f368206f3970d6bbe981b9d24
size 27507

92
hpnpf.txt Normal file
View File

@ -0,0 +1,92 @@
hpnpf A replacement backend for the CUPS socket backend
=========================================================
DESCRIPTION
This backend is based on HP's hpnpf utility (the sources of which have been freely
availabel until 1992) and has been extended to safely report the backchannel messages
from a JetDierect driven HP printer and - for PostScript printers only - to use
the TBCP (Tagged Binary Communications Protocol) as defined by Adobe.
The program can be run either as a CUPS backend or as a standalone utility, depending
on the name it is called by:
- if the name it is called with contains one of the strings '://' or 'backend/hpnpf'
(the latter for use with the CUPS backend test utility), it runs as a CUPS
backend, following the CUPS backend calling and input/output conventions.
- otherwise, it runs as a standalone utility and accepts additional switches.
INSTALLATION
Unzip and untar the file hpnpf.tgz into a suitable directory.
Within that directory, on SYSV UNIXes, run "make hpnpf", on Linux systems,
run "make -f linux.mak hpnpf". (Don't try to make hpnptyd, this won't succeed.)
On systems which do not/no longer support the good old varargs stuff but
require the use of the new stdarg approach for variable argument lists,
use
make -f linux_std.mak
or
make -f sysv_std.mak
for SYSV systems.
For CUPS use, copy the compiled binary hpnpf to the CUPS backend directory,
usually /usr/lib/cups/backend.
For standalone use, copy the binary to e.g. /usr/local/bin.
CUPS USAGE
When configuring a CUPS printer for using this backend, the URI syntyx is much the same
as for the standard socket backend:
hpnpf://printername:port
where port usually is 9100.
To enable TBCP, append the string "/TBCP" to the URI, as:
hpnpf://printername:port/TBCP
The backend writes information to a printer specific log file,
/var/log/cups/status_log.printername
For each job printed, an identification line like
INFO: [Mon Sep 11 11:08:08 2000] HPDIACOS.0001.SRZ0.11486.PS (1999)
containing the current date, the job ID (much like the standard backend) and the job number.
An info message like
INFO: Printing: HPDIACOS.0001.SRZ0.11486.PS
is written to stderr and thus captured by cupsd and available as status message.
Any PostScript error messages are logged like:
INFO: %%[ Error: rangecheck; OffendingCommand: getinterval ]%%
These errors are passed as info messages to cupsd as:
INFO: HPDIACOS.0001.SRZ0.11486.PS | %%[ Error: rangecheck; OffendingCommand: getinterval ]%%
and thus available as the printer's status message.
If no error occurred, a completion message is passed to cupsd like:
INFO: Printed: HPDIACOS.0001.SRZ0.11486.PS
For debugging, you may append "-D" to the device-URI. In this case, any PJL commands and replies
are logged to the printer specific status log file as specified above, and
debugging messages from hpnpf are written to /var/log/cups/printername.log.
STANDALONE USAGE
Called without any parameters the following usage message is printed to stderr:
usage: hpnpf -x periph [-c port] [-nNPrRSTvwW] [-p port] [-s statusfile] [-l logfile] file ...
-n (PLC only) map LF->CRLF, FF->CRFF
-N map LF->CRLF physically
-P (PostScript only) print banner page
-r run in relay mode
-R do no retries if connection fails
-S delete all CRs
-T (PostScript only) use TBCP (Tagged Binary Communcations Protocol)
-v verbose mode
-w wait for the job to be completed
-W as -w, additionally display all PJL commands and replies
-c port control port number (for relay mode only)
-x periph name or IP addr of printer
-p port port number to connect with
-s statusfile file to which status messages are written; default: stdout
-l logfile file to which logging messages are written (- : stderr)
file ... files to be printed; read from stdin if no files are given
The -w switch enables the logging of the PostScript messages, the -W switch additionally
logs the PJL commands and replies, -T enables the TBCP protocol. All other switches have the
same meaning as of the original hpnpf (but haven't been fully tested with this version).

0
ready Normal file
View File