diff options
author | Didier Raboud <odyx@debian.org> | 2012-10-25 21:07:57 +0200 |
---|---|---|
committer | Didier Raboud <odyx@debian.org> | 2012-10-25 21:07:57 +0200 |
commit | 81ab83f382660bc7980ae954725c4ebf28764b03 (patch) | |
tree | 523268f698a63a8fd44f3491d94d140266b2403b /backend | |
parent | a75966e33dbc3e3e096338fd332f515cb313b58a (diff) | |
download | cups-81ab83f382660bc7980ae954725c4ebf28764b03.tar.gz |
Imported Upstream version 1.6.0upstream/1.6.0
Diffstat (limited to 'backend')
-rw-r--r-- | backend/Dependencies | 177 | ||||
-rw-r--r-- | backend/Makefile | 72 | ||||
-rw-r--r-- | backend/backend-private.h | 20 | ||||
-rw-r--r-- | backend/dnssd.c | 782 | ||||
-rw-r--r-- | backend/ipp.c | 128 | ||||
-rw-r--r-- | backend/lpd.c | 36 | ||||
-rw-r--r-- | backend/network.c | 38 | ||||
-rw-r--r-- | backend/parallel.c | 676 | ||||
-rw-r--r-- | backend/runloop.c | 20 | ||||
-rw-r--r-- | backend/serial.c | 1327 | ||||
-rw-r--r-- | backend/snmp-supplies.c | 103 | ||||
-rw-r--r-- | backend/snmp.c | 6 | ||||
-rw-r--r-- | backend/socket.c | 10 | ||||
-rw-r--r-- | backend/testbackend.c | 53 | ||||
-rw-r--r-- | backend/usb-darwin.c | 16 | ||||
-rw-r--r-- | backend/usb-libusb.c | 8 | ||||
-rw-r--r-- | backend/usb-unix.c | 18 | ||||
-rw-r--r-- | backend/usb.c | 4 |
18 files changed, 988 insertions, 2506 deletions
diff --git a/backend/Dependencies b/backend/Dependencies index afc21fa9..eeb231a2 100644 --- a/backend/Dependencies +++ b/backend/Dependencies @@ -1,107 +1,70 @@ -# DO NOT DELETE THIS LINE -- make depend depends on it. - -ipp.o: backend-private.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h -ipp.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -ipp.o: ../cups/language.h ../cups/string-private.h ../config.h -ipp.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h -ipp.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h -ipp.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h -ipp.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h -ipp.o: ../cups/transcode.h ../cups/thread-private.h ../cups/snmp-private.h -ipp.o: ../cups/backend.h ../cups/sidechannel.h ../cups/array-private.h -ipp.o: ../cups/array.h -lpd.o: ../cups/http-private.h ../config.h ../cups/http.h -lpd.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h -lpd.o: backend-private.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h -lpd.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -lpd.o: ../cups/language.h ../cups/string-private.h ../cups/debug-private.h -lpd.o: ../cups/versioning.h ../cups/ppd-private.h ../cups/ppd.h -lpd.o: ../cups/cups.h ../cups/pwg-private.h ../cups/http-private.h -lpd.o: ../cups/language-private.h ../cups/transcode.h -lpd.o: ../cups/thread-private.h ../cups/snmp-private.h ../cups/backend.h -lpd.o: ../cups/sidechannel.h -dnssd.o: backend-private.h ../cups/cups-private.h ../cups/cups.h -dnssd.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -dnssd.o: ../cups/array.h ../cups/language.h ../cups/string-private.h -dnssd.o: ../config.h ../cups/debug-private.h ../cups/versioning.h -dnssd.o: ../cups/ppd-private.h ../cups/ppd.h ../cups/cups.h -dnssd.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h -dnssd.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h -dnssd.o: ../cups/language-private.h ../cups/transcode.h -dnssd.o: ../cups/thread-private.h ../cups/snmp-private.h ../cups/backend.h -dnssd.o: ../cups/sidechannel.h ../cups/array.h -parallel.o: backend-private.h ../cups/cups-private.h ../cups/cups.h -parallel.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -parallel.o: ../cups/array.h ../cups/language.h ../cups/string-private.h -parallel.o: ../config.h ../cups/debug-private.h ../cups/versioning.h -parallel.o: ../cups/ppd-private.h ../cups/ppd.h ../cups/cups.h -parallel.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h -parallel.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h -parallel.o: ../cups/language-private.h ../cups/transcode.h -parallel.o: ../cups/thread-private.h ../cups/snmp-private.h ../cups/backend.h -parallel.o: ../cups/sidechannel.h -serial.o: backend-private.h ../cups/cups-private.h ../cups/cups.h -serial.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -serial.o: ../cups/array.h ../cups/language.h ../cups/string-private.h -serial.o: ../config.h ../cups/debug-private.h ../cups/versioning.h -serial.o: ../cups/ppd-private.h ../cups/ppd.h ../cups/cups.h -serial.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h -serial.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h -serial.o: ../cups/language-private.h ../cups/transcode.h -serial.o: ../cups/thread-private.h ../cups/snmp-private.h ../cups/backend.h -serial.o: ../cups/sidechannel.h -snmp.o: backend-private.h ../cups/cups-private.h ../cups/cups.h -snmp.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -snmp.o: ../cups/array.h ../cups/language.h ../cups/string-private.h -snmp.o: ../config.h ../cups/debug-private.h ../cups/versioning.h -snmp.o: ../cups/ppd-private.h ../cups/ppd.h ../cups/cups.h -snmp.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h -snmp.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h -snmp.o: ../cups/language-private.h ../cups/transcode.h -snmp.o: ../cups/thread-private.h ../cups/snmp-private.h ../cups/backend.h -snmp.o: ../cups/sidechannel.h ../cups/array.h ../cups/file.h -snmp.o: ../cups/http-private.h -socket.o: ../cups/http-private.h ../config.h ../cups/http.h -socket.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h -socket.o: backend-private.h ../cups/cups-private.h ../cups/cups.h -socket.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h -socket.o: ../cups/array.h ../cups/language.h ../cups/string-private.h -socket.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h -socket.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h -socket.o: ../cups/http-private.h ../cups/language-private.h -socket.o: ../cups/transcode.h ../cups/thread-private.h ../cups/snmp-private.h -socket.o: ../cups/backend.h ../cups/sidechannel.h -test1284.o: ../cups/string-private.h ../config.h ieee1284.c backend-private.h -test1284.o: ../cups/cups-private.h ../cups/cups.h ../cups/file.h -test1284.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -test1284.o: ../cups/language.h ../cups/string-private.h -test1284.o: ../cups/debug-private.h ../cups/versioning.h -test1284.o: ../cups/ppd-private.h ../cups/ppd.h ../cups/cups.h -test1284.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h -test1284.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h -test1284.o: ../cups/language-private.h ../cups/transcode.h -test1284.o: ../cups/thread-private.h ../cups/snmp-private.h ../cups/backend.h -test1284.o: ../cups/sidechannel.h -testbackend.o: ../cups/string-private.h ../config.h ../cups/cups.h -testbackend.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h -testbackend.o: ../cups/http.h ../cups/array.h ../cups/language.h -testbackend.o: ../cups/sidechannel.h -testsupplies.o: backend-private.h ../cups/cups-private.h ../cups/cups.h -testsupplies.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h -testsupplies.o: ../cups/http.h ../cups/array.h ../cups/language.h -testsupplies.o: ../cups/string-private.h ../config.h ../cups/debug-private.h -testsupplies.o: ../cups/versioning.h ../cups/ppd-private.h ../cups/ppd.h -testsupplies.o: ../cups/cups.h ../cups/pwg-private.h ../cups/http-private.h -testsupplies.o: ../cups/http.h ../cups/md5-private.h ../cups/ipp-private.h -testsupplies.o: ../cups/ipp.h ../cups/language-private.h ../cups/transcode.h -testsupplies.o: ../cups/thread-private.h ../cups/snmp-private.h -testsupplies.o: ../cups/backend.h ../cups/sidechannel.h -usb.o: backend-private.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h -usb.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h -usb.o: ../cups/language.h ../cups/string-private.h ../config.h -usb.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h -usb.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h -usb.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h -usb.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h -usb.o: ../cups/transcode.h ../cups/thread-private.h ../cups/snmp-private.h -usb.o: ../cups/backend.h ../cups/sidechannel.h +ipp.o: ipp.c backend-private.h ../cups/cups-private.h \ + ../cups/string-private.h ../config.h ../cups/debug-private.h \ + ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \ + ../cups/http.h ../cups/array.h ../cups/http-private.h \ + ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \ + ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \ + ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \ + ../cups/snmp-private.h ../cups/backend.h ../cups/sidechannel.h \ + ../cups/array-private.h +lpd.o: lpd.c ../cups/http-private.h ../config.h ../cups/http.h \ + ../cups/versioning.h ../cups/array.h ../cups/md5-private.h \ + ../cups/ipp-private.h ../cups/ipp.h backend-private.h \ + ../cups/cups-private.h ../cups/string-private.h \ + ../cups/debug-private.h ../cups/language-private.h ../cups/transcode.h \ + ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \ + ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \ + ../cups/snmp-private.h ../cups/backend.h ../cups/sidechannel.h +dnssd.o: dnssd.c backend-private.h ../cups/cups-private.h \ + ../cups/string-private.h ../config.h ../cups/debug-private.h \ + ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \ + ../cups/http.h ../cups/array.h ../cups/http-private.h \ + ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \ + ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \ + ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \ + ../cups/snmp-private.h ../cups/backend.h ../cups/sidechannel.h +snmp.o: snmp.c backend-private.h ../cups/cups-private.h \ + ../cups/string-private.h ../config.h ../cups/debug-private.h \ + ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \ + ../cups/http.h ../cups/array.h ../cups/http-private.h \ + ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \ + ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \ + ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \ + ../cups/snmp-private.h ../cups/backend.h ../cups/sidechannel.h +socket.o: socket.c ../cups/http-private.h ../config.h ../cups/http.h \ + ../cups/versioning.h ../cups/array.h ../cups/md5-private.h \ + ../cups/ipp-private.h ../cups/ipp.h backend-private.h \ + ../cups/cups-private.h ../cups/string-private.h \ + ../cups/debug-private.h ../cups/language-private.h ../cups/transcode.h \ + ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \ + ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \ + ../cups/snmp-private.h ../cups/backend.h ../cups/sidechannel.h +test1284.o: test1284.c ../cups/string-private.h ../config.h ieee1284.c \ + backend-private.h ../cups/cups-private.h ../cups/debug-private.h \ + ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \ + ../cups/http.h ../cups/array.h ../cups/http-private.h \ + ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \ + ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \ + ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \ + ../cups/snmp-private.h ../cups/backend.h ../cups/sidechannel.h +testbackend.o: testbackend.c ../cups/string-private.h ../config.h \ + ../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \ + ../cups/http.h ../cups/array.h ../cups/language.h \ + ../cups/sidechannel.h +testsupplies.o: testsupplies.c backend-private.h ../cups/cups-private.h \ + ../cups/string-private.h ../config.h ../cups/debug-private.h \ + ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \ + ../cups/http.h ../cups/array.h ../cups/http-private.h \ + ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \ + ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \ + ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \ + ../cups/snmp-private.h ../cups/backend.h ../cups/sidechannel.h +usb.o: usb.c backend-private.h ../cups/cups-private.h \ + ../cups/string-private.h ../config.h ../cups/debug-private.h \ + ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \ + ../cups/http.h ../cups/array.h ../cups/http-private.h \ + ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \ + ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \ + ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \ + ../cups/snmp-private.h ../cups/backend.h ../cups/sidechannel.h \ + usb-darwin.c ../cups/file-private.h diff --git a/backend/Makefile b/backend/Makefile index 643ee0cd..e55827df 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 10425 2012-04-23 17:42:12Z mike $" +# "$Id: Makefile 10402 2012-04-12 22:54:51Z mike $" # # Backend makefile for CUPS. # @@ -21,13 +21,43 @@ include ../Makedefs # Object files... # -RBACKENDS = ipp lpd $(DNSSD_BACKEND) -UBACKENDS = $(LEGACY_BACKENDS) serial snmp socket usb -UNITTESTS = test1284 testbackend testsupplies -TARGETS = libbackend.a $(RBACKENDS) $(UBACKENDS) -LIBOBJS = ieee1284.o network.o runloop.o snmp-supplies.o -OBJS = ipp.o lpd.o dnssd.o parallel.o serial.o snmp.o \ - socket.o test1284.o testbackend.o testsupplies.o usb.o +# RBACKENDS are installed mode 0700 so cupsd will run them as root... +# +# UBACKENDS are installed mode 0755 so cupsd will run them as an unprivileged +# user... +# +# See http://www.cups.org/documentation.php/api-filter.html for more info... +RBACKENDS = \ + ipp \ + lpd \ + $(DNSSD_BACKEND) +UBACKENDS = \ + snmp \ + socket \ + usb +UNITTESTS = \ + test1284 \ + testbackend \ + testsupplies +TARGETS = \ + libbackend.a \ + $(RBACKENDS) \ + $(UBACKENDS) +LIBOBJS = \ + ieee1284.o \ + network.o \ + runloop.o \ + snmp-supplies.o +OBJS = \ + ipp.o \ + lpd.o \ + dnssd.o \ + snmp.o \ + socket.o \ + test1284.o \ + testbackend.o \ + testsupplies.o \ + usb.o # @@ -56,7 +86,7 @@ unittests: $(UNITTESTS) # clean: - $(RM) $(OBJS) $(TARGETS) $(UNITTESTS) $(LIBOBJS) http mdns + $(RM) $(OBJS) $(TARGETS) $(UNITTESTS) $(LIBOBJS) http https ipps mdns # @@ -64,7 +94,7 @@ clean: # depend: - makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1 + $(CC) -MM $(ALL_CFLAGS) $(OBJS:.o=.c) >Dependencies # @@ -98,7 +128,7 @@ install-exec: $(INSTALLXPC) $(RM) $(SERVERBIN)/backend/$$file; \ $(LN) ipp $(SERVERBIN)/backend/$$file; \ done - if test "x$(DNSSD_BACKEND)" != x -a `uname` = Darwin; then \ + if test "x$(DNSSD_BACKEND)" != x; then \ $(RM) $(SERVERBIN)/backend/mdns; \ $(LN) $(DNSSD_BACKEND) $(SERVERBIN)/backend/mdns; \ fi @@ -227,24 +257,6 @@ lpd: lpd.o ../cups/$(LIBCUPS) libbackend.a # -# parallel -# - -parallel: parallel.o ../cups/$(LIBCUPS) libbackend.a - echo Linking $@... - $(CC) $(LDFLAGS) -o parallel parallel.o libbackend.a $(LIBS) - - -# -# serial -# - -serial: serial.o ../cups/$(LIBCUPS) libbackend.a - echo Linking $@... - $(CC) $(LDFLAGS) -o serial serial.o libbackend.a $(BACKLIBS) $(LIBS) - - -# # snmp # @@ -281,5 +293,5 @@ include Dependencies # -# End of "$Id: Makefile 10425 2012-04-23 17:42:12Z mike $". +# End of "$Id: Makefile 10402 2012-04-12 22:54:51Z mike $". # diff --git a/backend/backend-private.h b/backend/backend-private.h index d3f8f514..fa829141 100644 --- a/backend/backend-private.h +++ b/backend/backend-private.h @@ -1,9 +1,9 @@ /* - * "$Id: backend-private.h 10064 2011-10-07 21:41:07Z mike $" + * "$Id: backend-private.h 10329 2012-03-05 23:18:31Z mike $" * * Backend support definitions for CUPS. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -259,6 +259,20 @@ extern "C" { #define CUPS_TC_inserts 33 #define CUPS_TC_covers 34 +#define CUPS_TC_tenThousandthsOfInches 3 +#define CUPS_TC_micrometers 4 +#define CUPS_TC_impressions 7 +#define CUPS_TC_sheets 8 +#define CUPS_TC_hours 11 +#define CUPS_TC_thousandthsOfOunces 12 +#define CUPS_TC_tenthsOfGrams 13 +#define CUPS_TC_hundrethsOfFluidOunces 14 +#define CUPS_TC_tenthsOfMilliliters 15 +#define CUPS_TC_feet 16 +#define CUPS_TC_meters 17 +#define CUPS_TC_items 18 +#define CUPS_TC_percent 19 + /* These come from RFC 3808 to define character sets we support */ /* Also see http://www.iana.org/assignments/character-sets */ #define CUPS_TC_csASCII 3 @@ -320,5 +334,5 @@ extern int backendWaitLoop(int snmp_fd, http_addr_t *addr, /* - * End of "$Id: backend-private.h 10064 2011-10-07 21:41:07Z mike $". + * End of "$Id: backend-private.h 10329 2012-03-05 23:18:31Z mike $". */ diff --git a/backend/dnssd.c b/backend/dnssd.c index 02c78754..1d6eb7ea 100644 --- a/backend/dnssd.c +++ b/backend/dnssd.c @@ -1,5 +1,5 @@ /* - * "$Id: dnssd.c 10379 2012-03-23 22:16:22Z mike $" + * "$Id: dnssd.c 10489 2012-05-21 16:05:58Z mike $" * * DNS-SD discovery backend for CUPS. * @@ -15,16 +15,19 @@ * * Contents: * - * main() - Browse for printers. - * browse_callback() - Browse devices. + * main() - Browse for printers. + * browse_callback() - Browse devices. * browse_local_callback() - Browse local devices. - * compare_devices() - Compare two devices. - * exec_backend() - Execute the backend that corresponds to the - * resolved service name. - * get_device() - Create or update a device. - * query_callback() - Process query data. - * sigterm_handler() - Handle termination signals... - * unquote() - Unquote a name string. + * client_callback() - Avahi client callback function. + * compare_devices() - Compare two devices. + * exec_backend() - Execute the backend that corresponds to the + * resolved service name. + * device_type() - Get DNS-SD type enumeration from string. + * get_device() - Create or update a device. + * query_callback() - Process query data. + * find_device() - Find a device from its name and domain. + * sigterm_handler() - Handle termination signals. + * unquote() - Unquote a name string. */ /* @@ -33,7 +36,18 @@ #include "backend-private.h" #include <cups/array.h> -#include <dns_sd.h> +#ifdef HAVE_DNSSD +# include <dns_sd.h> +#endif /* HAVE_DNSSD */ +#ifdef HAVE_AVAHI +# include <avahi-client/client.h> +# include <avahi-client/lookup.h> +# include <avahi-common/simple-watch.h> +# include <avahi-common/domain.h> +# include <avahi-common/error.h> +# include <avahi-common/malloc.h> +#define kDNSServiceMaxDomainName AVAHI_DOMAIN_NAME_MAX +#endif /* HAVE_AVAHI */ /* @@ -53,7 +67,12 @@ typedef enum typedef struct { - DNSServiceRef ref; /* Service reference for resolve */ +#ifdef HAVE_DNSSD + DNSServiceRef ref; /* Service reference for query */ +#endif /* HAVE_DNSSD */ +#ifdef HAVE_AVAHI + AvahiRecordBrowser *ref; /* Browser for query */ +#endif /* HAVE_AVAHI */ char *name, /* Service name */ *domain, /* Domain name */ *fullName, /* Full name */ @@ -72,12 +91,18 @@ typedef struct static int job_canceled = 0; /* Set to 1 on SIGTERM */ +#ifdef HAVE_AVAHI +static AvahiSimplePoll *simple_poll = NULL; + /* Poll information */ +static int got_data = 0; /* Got data from poll? */ +#endif /* HAVE_AVAHI */ /* * Local functions... */ +#ifdef HAVE_DNSSD static void browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, @@ -95,6 +120,22 @@ static void browse_local_callback(DNSServiceRef sdRef, const char *replyDomain, void *context) __attribute__((nonnull(1,5,6,7,8))); +#endif /* HAVE_DNSSD */ +#ifdef HAVE_AVAHI +static void browse_callback(AvahiServiceBrowser *browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char *serviceName, + const char *regtype, + const char *replyDomain, + AvahiLookupResultFlags flags, + void *context); +static void client_callback(AvahiClient *client, + AvahiClientState state, + void *context); +#endif /* HAVE_AVAHI */ + static int compare_devices(cups_device_t *a, cups_device_t *b); static void exec_backend(char **argv); static cups_device_t *get_device(cups_array_t *devices, @@ -102,6 +143,7 @@ static cups_device_t *get_device(cups_array_t *devices, const char *regtype, const char *replyDomain) __attribute__((nonnull(1,2,3,4))); +#ifdef HAVE_DNSSD static void query_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, @@ -111,6 +153,20 @@ static void query_callback(DNSServiceRef sdRef, const void *rdata, uint32_t ttl, void *context) __attribute__((nonnull(1,5,9,11))); +#elif defined(HAVE_AVAHI) +static int poll_callback(struct pollfd *pollfds, + unsigned int num_pollfds, int timeout, + void *context); +static void query_callback(AvahiRecordBrowser *browser, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char *name, uint16_t rrclass, + uint16_t rrtype, const void *rdata, + size_t rdlen, + AvahiLookupResultFlags flags, + void *context); +#endif /* HAVE_DNSSD */ static void sigterm_handler(int sig); static void unquote(char *dst, const char *src, size_t dstsize) __attribute__((nonnull(1,2))); @@ -125,6 +181,13 @@ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { const char *name; /* Backend name */ + cups_array_t *devices; /* Device array */ + cups_device_t *device; /* Current device */ + char uriName[1024]; /* Unquoted fullName for URI */ +#ifdef HAVE_DNSSD + int fd; /* Main file descriptor */ + fd_set input; /* Input set for select() */ + struct timeval timeout; /* Timeout for select() */ DNSServiceRef main_ref, /* Main service reference */ fax_ipp_ref, /* IPP fax service reference */ ipp_ref, /* IPP service reference */ @@ -138,12 +201,11 @@ main(int argc, /* I - Number of command-line args */ pdl_datastream_ref, /* AppSocket service reference */ printer_ref, /* LPD service reference */ riousbprint_ref; /* Remote IO service reference */ - int fd; /* Main file descriptor */ - fd_set input; /* Input set for select() */ - struct timeval timeout; /* Timeout for select() */ - cups_array_t *devices; /* Device array */ - cups_device_t *device; /* Current device */ - char uriName[1024]; /* Unquoted fullName for URI */ +#endif /* HAVE_DNSSD */ +#ifdef HAVE_AVAHI + AvahiClient *client; /* Client information */ + int error; /* Error code, if any */ +#endif /* HAVE_AVAHI */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ @@ -203,6 +265,7 @@ main(int argc, /* I - Number of command-line args */ * Browse for different kinds of printers... */ +#ifdef HAVE_DNSSD if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError) { perror("ERROR: Unable to create service connection"); @@ -263,6 +326,52 @@ main(int argc, /* I - Number of command-line args */ riousbprint_ref = main_ref; DNSServiceBrowse(&riousbprint_ref, kDNSServiceFlagsShareConnection, 0, "_riousbprint._tcp", NULL, browse_callback, devices); +#endif /* HAVE_DNSSD */ + +#ifdef HAVE_AVAHI + if ((simple_poll = avahi_simple_poll_new()) == NULL) + { + fputs("DEBUG: Unable to create Avahi simple poll object.\n", stderr); + return (1); + } + + avahi_simple_poll_set_func(simple_poll, poll_callback, NULL); + + client = avahi_client_new(avahi_simple_poll_get(simple_poll), + 0, client_callback, simple_poll, &error); + if (!client) + { + fputs("DEBUG: Unable to create Avahi client.\n", stderr); + return (1); + } + + avahi_service_browser_new(client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + "_fax-ipp._tcp", NULL, 0, + browse_callback, devices); + avahi_service_browser_new(client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + "_ipp._tcp", NULL, 0, + browse_callback, devices); + avahi_service_browser_new(client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + "_ipp-tls._tcp", NULL, 0, + browse_callback, devices); + avahi_service_browser_new(client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + "_ipps._tcp", NULL, 0, + browse_callback, devices); + avahi_service_browser_new(client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + "_pdl-datastream._tcp", + NULL, 0, + browse_callback, + devices); + avahi_service_browser_new(client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + "_printer._tcp", NULL, 0, + browse_callback, devices); +#endif /* HAVE_AVAHI */ /* * Loop until we are killed... @@ -270,11 +379,14 @@ main(int argc, /* I - Number of command-line args */ while (!job_canceled) { + int announce = 0; /* Announce printers? */ + +#ifdef HAVE_DNSSD FD_ZERO(&input); FD_SET(fd, &input); timeout.tv_sec = 0; - timeout.tv_usec = 250000; + timeout.tv_usec = 500000; if (select(fd + 1, &input, NULL, NULL, &timeout) < 0) continue; @@ -288,12 +400,36 @@ main(int argc, /* I - Number of command-line args */ DNSServiceProcessResult(main_ref); } else + announce = 1; + +#elif defined(HAVE_AVAHI) + got_data = 0; + + if ((error = avahi_simple_poll_iterate(simple_poll, 500)) > 0) + { + /* + * We've been told to exit the loop. Perhaps the connection to + * Avahi failed. + */ + + break; + } + + if (!got_data) + announce = 1; +#endif /* HAVE_DNSSD */ + +/* fprintf(stderr, "DEBUG: announce=%d\n", announce);*/ + + if (announce) { /* * Announce any devices we've found... */ +#ifdef HAVE_DNSSD DNSServiceErrorType status; /* DNS query status */ +#endif /* HAVE_DNSSD */ cups_device_t *best; /* Best matching device */ char device_uri[1024]; /* Device URI */ int count; /* Number of queries */ @@ -316,36 +452,59 @@ main(int argc, /* I - Number of command-line args */ * Found the device, now get the TXT record(s) for it... */ - if (count < 20) + if (count < 50) { - device->ref = main_ref; - fprintf(stderr, "DEBUG: Querying \"%s\"...\n", device->fullName); +#ifdef HAVE_DNSSD + device->ref = main_ref; + status = DNSServiceQueryRecord(&(device->ref), kDNSServiceFlagsShareConnection, 0, device->fullName, kDNSServiceType_TXT, kDNSServiceClass_IN, query_callback, - devices); + device); if (status != kDNSServiceErr_NoError) - { - fputs("ERROR: Unable to query for TXT records!\n", stderr); - fprintf(stderr, "DEBUG: DNSServiceQueryRecord returned %d\n", - status); - } + fprintf(stderr, + "ERROR: Unable to query \"%s\" for TXT records: %d\n", + device->fullName, status); + /* Users never see this */ else count ++; + +#else + if ((device->ref = avahi_record_browser_new(client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + device->fullName, + AVAHI_DNS_CLASS_IN, + AVAHI_DNS_TYPE_TXT, + 0, + query_callback, + device)) == NULL) + fprintf(stderr, + "ERROR: Unable to query \"%s\" for TXT records: %s\n", + device->fullName, + avahi_strerror(avahi_client_errno(client))); + /* Users never see this */ + else + count ++; +#endif /* HAVE_AVAHI */ } } else if (!device->sent) { +#ifdef HAVE_DNSSD /* * Got the TXT records, now report the device... */ DNSServiceRefDeallocate(device->ref); - device->ref = 0; +#else + avahi_record_browser_free(device->ref); +#endif /* HAVE_DNSSD */ + + device->ref = NULL; if (!best) best = device; @@ -397,6 +556,8 @@ main(int argc, /* I - Number of command-line args */ sent ++; } + fprintf(stderr, "DEBUG: sent=%d, count=%d\n", sent, count); + if (sent == cupsArrayCount(devices)) break; } @@ -406,6 +567,7 @@ main(int argc, /* I - Number of command-line args */ } +#ifdef HAVE_DNSSD /* * 'browse_callback()' - Browse devices. */ @@ -425,10 +587,7 @@ browse_callback( "interfaceIndex=%d, errorCode=%d, serviceName=\"%s\", " "regtype=\"%s\", replyDomain=\"%s\", context=%p)\n", sdRef, flags, interfaceIndex, errorCode, - serviceName ? serviceName : "(null)", - regtype ? regtype : "(null)", - replyDomain ? replyDomain : "(null)", - context); + serviceName, regtype, replyDomain, context); /* * Only process "add" data... @@ -467,10 +626,7 @@ browse_local_callback( "interfaceIndex=%d, errorCode=%d, serviceName=\"%s\", " "regtype=\"%s\", replyDomain=\"%s\", context=%p)\n", sdRef, flags, interfaceIndex, errorCode, - serviceName ? serviceName : "(null)", - regtype ? regtype : "(null)", - replyDomain ? replyDomain : "(null)", - context); + serviceName, regtype, replyDomain, context); /* * Only process "add" data... @@ -494,6 +650,97 @@ browse_local_callback( device->fullName); device->sent = 1; } +#endif /* HAVE_DNSSD */ + + +#ifdef HAVE_AVAHI +/* + * 'browse_callback()' - Browse devices. + */ + +static void +browse_callback( + AvahiServiceBrowser *browser, /* I - Browser */ + AvahiIfIndex interface, /* I - Interface index (unused) */ + AvahiProtocol protocol, /* I - Network protocol (unused) */ + AvahiBrowserEvent event, /* I - What happened */ + const char *name, /* I - Service name */ + const char *type, /* I - Registration type */ + const char *domain, /* I - Domain */ + AvahiLookupResultFlags flags, /* I - Flags */ + void *context) /* I - Devices array */ +{ + AvahiClient *client = avahi_service_browser_get_client(browser); + /* Client information */ + + + (void)interface; + (void)protocol; + (void)context; + + switch (event) + { + case AVAHI_BROWSER_FAILURE: + fprintf(stderr, "DEBUG: browse_callback: %s\n", + avahi_strerror(avahi_client_errno(client))); + avahi_simple_poll_quit(simple_poll); + break; + + case AVAHI_BROWSER_NEW: + /* + * This object is new on the network. + */ + + if (flags & AVAHI_LOOKUP_RESULT_LOCAL) + { + /* + * This comes from the local machine so ignore it. + */ + + fprintf(stderr, "DEBUG: Ignoring local service %s.\n", name); + } + else + { + /* + * Create a device entry for it if it doesn't yet exist. + */ + + get_device((cups_array_t *)context, name, type, domain); + } + break; + + case AVAHI_BROWSER_REMOVE: + case AVAHI_BROWSER_ALL_FOR_NOW: + case AVAHI_BROWSER_CACHE_EXHAUSTED: + break; + } +} + + +/* + * 'client_callback()' - Avahi client callback function. + */ + +static void +client_callback( + AvahiClient *client, /* I - Client information (unused) */ + AvahiClientState state, /* I - Current state */ + void *context) /* I - User data (unused) */ +{ + (void)client; + (void)context; + + /* + * If the connection drops, quit. + */ + + if (state == AVAHI_CLIENT_FAILURE) + { + fputs("DEBUG: Avahi connection failed.\n", stderr); + avahi_simple_poll_quit(simple_poll); + } +} +#endif /* HAVE_AVAHI */ /* @@ -574,6 +821,41 @@ exec_backend(char **argv) /* I - Command-line arguments */ /* + * 'device_type()' - Get DNS-SD type enumeration from string. + */ + +static int +device_type(const char *regtype) +{ +#ifdef HAVE_AVAHI + if (!strcmp(regtype, "_ipp._tcp")) + return (CUPS_DEVICE_IPP); + else if (!strcmp(regtype, "_ipps._tcp") || + !strcmp(regtype, "_ipp-tls._tcp")) + return (CUPS_DEVICE_IPPS); + else if (!strcmp(regtype, "_fax-ipp._tcp")) + return (CUPS_DEVICE_FAX_IPP); + else if (!strcmp(regtype, "_printer._tcp")) + return (CUPS_DEVICE_PDL_DATASTREAM); +#else + if (!strcmp(regtype, "_ipp._tcp.")) + return (CUPS_DEVICE_IPP); + else if (!strcmp(regtype, "_ipps._tcp.") || + !strcmp(regtype, "_ipp-tls._tcp.")) + return (CUPS_DEVICE_IPPS); + else if (!strcmp(regtype, "_fax-ipp._tcp.")) + return (CUPS_DEVICE_FAX_IPP); + else if (!strcmp(regtype, "_printer._tcp.")) + return (CUPS_DEVICE_PRINTER); + else if (!strcmp(regtype, "_pdl-datastream._tcp.")) + return (CUPS_DEVICE_PDL_DATASTREAM); +#endif /* HAVE_AVAHI */ + + return (CUPS_DEVICE_RIOUSBPRINT); +} + + +/* * 'get_device()' - Create or update a device. */ @@ -594,20 +876,7 @@ get_device(cups_array_t *devices, /* I - Device array */ */ key.name = (char *)serviceName; - - if (!strcmp(regtype, "_ipp._tcp.")) - key.type = CUPS_DEVICE_IPP; - else if (!strcmp(regtype, "_ipps._tcp.") || - !strcmp(regtype, "_ipp-tls._tcp.")) - key.type = CUPS_DEVICE_IPPS; - else if (!strcmp(regtype, "_fax-ipp._tcp.")) - key.type = CUPS_DEVICE_FAX_IPP; - else if (!strcmp(regtype, "_printer._tcp.")) - key.type = CUPS_DEVICE_PRINTER; - else if (!strcmp(regtype, "_pdl-datastream._tcp.")) - key.type = CUPS_DEVICE_PDL_DATASTREAM; - else - key.type = CUPS_DEVICE_RIOUSBPRINT; + key.type = device_type(regtype); for (device = cupsArrayFind(devices, &key); device; @@ -627,8 +896,14 @@ get_device(cups_array_t *devices, /* I - Device array */ free(device->domain); device->domain = strdup(replyDomain); +#ifdef HAVE_DNSSD DNSServiceConstructFullName(fullName, device->name, regtype, replyDomain); +#else /* HAVE_AVAHI */ + avahi_service_name_join(fullName, kDNSServiceMaxDomainName, + serviceName, regtype, replyDomain); +#endif /* HAVE_DNSSD */ + free(device->fullName); device->fullName = strdup(fullName); } @@ -655,13 +930,55 @@ get_device(cups_array_t *devices, /* I - Device array */ * Set the "full name" of this service, which is used for queries... */ +#ifdef HAVE_DNSSD DNSServiceConstructFullName(fullName, serviceName, regtype, replyDomain); +#else /* HAVE_AVAHI */ + avahi_service_name_join(fullName, kDNSServiceMaxDomainName, + serviceName, regtype, replyDomain); +#endif /* HAVE_DNSSD */ + device->fullName = strdup(fullName); return (device); } +#ifdef HAVE_AVAHI +/* + * 'poll_callback()' - Wait for input on the specified file descriptors. + * + * Note: This function is needed because avahi_simple_poll_iterate is broken + * and always uses a timeout of 0 (!) milliseconds. + * (Avahi Ticket #364) + */ + +static int /* O - Number of file descriptors matching */ +poll_callback( + struct pollfd *pollfds, /* I - File descriptors */ + unsigned int num_pollfds, /* I - Number of file descriptors */ + int timeout, /* I - Timeout in milliseconds (unused) */ + void *context) /* I - User data (unused) */ +{ + int val; /* Return value */ + + + (void)timeout; + (void)context; + + val = poll(pollfds, num_pollfds, 500); + + if (val < 0) + fprintf(stderr, "DEBUG: poll_callback: %s\n", strerror(errno)); + else if (val > 0) + got_data = 1; + + return (val); +} +#endif /* HAVE_AVAHI */ + + +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) +# ifdef HAVE_DNSSD /* * 'query_callback()' - Process query data. */ @@ -678,15 +995,46 @@ query_callback( uint16_t rdlen, /* I - Length of record data */ const void *rdata, /* I - Record data */ uint32_t ttl, /* I - Time-to-live */ - void *context) /* I - Devices array */ + void *context) /* I - Device */ { - cups_array_t *devices; /* Device array */ - char name[1024], /* Service name */ - *ptr; /* Pointer into string */ - cups_device_t dkey, /* Search key */ - *device; /* Device */ - +# else +/* + * 'query_callback()' - Process query data. + */ +static void +query_callback( + AvahiRecordBrowser *browser, /* I - Record browser */ + AvahiIfIndex interfaceIndex, + /* I - Interface index (unused) */ + AvahiProtocol protocol, /* I - Network protocol (unused) */ + AvahiBrowserEvent event, /* I - What happened? */ + const char *fullName, /* I - Service name */ + uint16_t rrclass, /* I - Record class */ + uint16_t rrtype, /* I - Record type */ + const void *rdata, /* I - TXT record */ + size_t rdlen, /* I - Length of TXT record */ + AvahiLookupResultFlags flags, /* I - Flags */ + void *context) /* I - Device */ +{ + AvahiClient *client = avahi_record_browser_get_client(browser); + /* Client information */ +# endif /* HAVE_DNSSD */ + char *ptr; /* Pointer into string */ + cups_device_t *device = (cups_device_t *)context; + /* Device */ + const uint8_t *data, /* Pointer into data */ + *datanext, /* Next key/value pair */ + *dataend; /* End of entire TXT record */ + uint8_t datalen; /* Length of current key/value pair */ + char key[256], /* Key string */ + value[256], /* Value string */ + make_and_model[512], /* Manufacturer and model */ + model[256], /* Model */ + device_id[2048]; /* 1284 device ID */ + + +# ifdef HAVE_DNSSD fprintf(stderr, "DEBUG2: query_callback(sdRef=%p, flags=%x, " "interfaceIndex=%d, errorCode=%d, fullName=\"%s\", " "rrtype=%u, rrclass=%u, rdlen=%u, rdata=%p, ttl=%u, " @@ -702,221 +1050,183 @@ query_callback( if (errorCode != kDNSServiceErr_NoError || !(flags & kDNSServiceFlagsAdd)) return; +# else + fprintf(stderr, "DEBUG2: query_callback(browser=%p, interfaceIndex=%d, " + "protocol=%d, event=%d, fullName=\"%s\", rrclass=%u, " + "rrtype=%u, rdata=%p, rdlen=%u, flags=%x, context=%p)\n", + browser, interfaceIndex, protocol, event, + fullName ? fullName : "(null)", rrclass, rrtype, rdata, + (unsigned)rdlen, flags, context); + /* - * Lookup the service in the devices array. + * Only process "add" data... */ - devices = (cups_array_t *)context; - dkey.name = name; + if (event != AVAHI_BROWSER_NEW) + { + if (event == AVAHI_BROWSER_FAILURE) + fprintf(stderr, "ERROR: %s\n", + avahi_strerror(avahi_client_errno(client))); - unquote(name, fullName, sizeof(name)); + return; + } +# endif /* HAVE_DNSSD */ - if ((dkey.domain = strstr(name, "._tcp.")) != NULL) - dkey.domain += 6; - else - dkey.domain = (char *)"local."; + /* + * Pull out the priority and make and model from the TXT + * record and save it... + */ - if ((ptr = strstr(name, "._")) != NULL) - *ptr = '\0'; + device_id[0] = '\0'; + make_and_model[0] = '\0'; - if (strstr(fullName, "_ipp._tcp.")) - dkey.type = CUPS_DEVICE_IPP; - else if (strstr(fullName, "_ipps._tcp.") || - strstr(fullName, "_ipp-tls._tcp.")) - dkey.type = CUPS_DEVICE_IPPS; - else if (strstr(fullName, "_fax-ipp._tcp.")) - dkey.type = CUPS_DEVICE_FAX_IPP; - else if (strstr(fullName, "_printer._tcp.")) - dkey.type = CUPS_DEVICE_PRINTER; - else if (strstr(fullName, "_pdl-datastream._tcp.")) - dkey.type = CUPS_DEVICE_PDL_DATASTREAM; - else - dkey.type = CUPS_DEVICE_RIOUSBPRINT; + strcpy(model, "Unknown"); - for (device = cupsArrayFind(devices, &dkey); - device; - device = cupsArrayNext(devices)) + for (data = rdata, dataend = data + rdlen; + data < dataend; + data = datanext) { - if (_cups_strcasecmp(device->name, dkey.name) || - _cups_strcasecmp(device->domain, dkey.domain)) - { - device = NULL; + /* + * Read a key/value pair starting with an 8-bit length. Since the + * length is 8 bits and the size of the key/value buffers is 256, we + * don't need to check for overflow... + */ + + datalen = *data++; + + if (!datalen || (data + datalen) > dataend) break; - } - else if (device->type == dkey.type) + + datanext = data + datalen; + + for (ptr = key; data < datanext && *data != '='; data ++) + *ptr++ = *data; + *ptr = '\0'; + + if (data < datanext && *data == '=') { - /* - * Found it, pull out the priority and make and model from the TXT - * record and save it... - */ + data ++; - const uint8_t *data, /* Pointer into data */ - *datanext, /* Next key/value pair */ - *dataend; /* End of entire TXT record */ - uint8_t datalen; /* Length of current key/value pair */ - char key[256], /* Key string */ - value[256], /* Value string */ - make_and_model[512], - /* Manufacturer and model */ - model[256], /* Model */ - device_id[2048];/* 1284 device ID */ + if (data < datanext) + memcpy(value, data, datanext - data); + value[datanext - data] = '\0'; + fprintf(stderr, "DEBUG2: query_callback: \"%s=%s\".\n", + key, value); + } + else + { + fprintf(stderr, "DEBUG2: query_callback: \"%s\" with no value.\n", + key); + continue; + } - device_id[0] = '\0'; - make_and_model[0] = '\0'; + if (!_cups_strncasecmp(key, "usb_", 4)) + { + /* + * Add USB device ID information... + */ - strcpy(model, "Unknown"); + ptr = device_id + strlen(device_id); + snprintf(ptr, sizeof(device_id) - (ptr - device_id), "%s:%s;", + key + 4, value); + } - for (data = rdata, dataend = data + rdlen; - data < dataend; - data = datanext) + if (!_cups_strcasecmp(key, "usb_MFG") || !_cups_strcasecmp(key, "usb_MANU") || + !_cups_strcasecmp(key, "usb_MANUFACTURER")) + strcpy(make_and_model, value); + else if (!_cups_strcasecmp(key, "usb_MDL") || !_cups_strcasecmp(key, "usb_MODEL")) + strcpy(model, value); + else if (!_cups_strcasecmp(key, "product") && !strstr(value, "Ghostscript")) + { + if (value[0] == '(') { /* - * Read a key/value pair starting with an 8-bit length. Since the - * length is 8 bits and the size of the key/value buffers is 256, we - * don't need to check for overflow... + * Strip parenthesis... */ - datalen = *data++; + if ((ptr = value + strlen(value) - 1) > value && *ptr == ')') + *ptr = '\0'; - if (!datalen || (data + datalen) > dataend) - break; - - datanext = data + datalen; + strcpy(model, value + 1); + } + else + strcpy(model, value); + } + else if (!_cups_strcasecmp(key, "ty")) + { + strcpy(model, value); - for (ptr = key; data < datanext && *data != '='; data ++) - *ptr++ = *data; + if ((ptr = strchr(model, ',')) != NULL) *ptr = '\0'; + } + else if (!_cups_strcasecmp(key, "priority")) + device->priority = atoi(value); + else if ((device->type == CUPS_DEVICE_IPP || + device->type == CUPS_DEVICE_IPPS || + device->type == CUPS_DEVICE_PRINTER) && + !_cups_strcasecmp(key, "printer-type")) + { + /* + * This is a CUPS printer! + */ - if (data < datanext && *data == '=') - { - data ++; - - if (data < datanext) - memcpy(value, data, datanext - data); - value[datanext - data] = '\0'; - - fprintf(stderr, "DEBUG2: query_callback: \"%s=%s\".\n", - key, value); - } - else - { - fprintf(stderr, "DEBUG2: query_callback: \"%s\" with no value.\n", - key); - continue; - } - - if (!_cups_strncasecmp(key, "usb_", 4)) - { - /* - * Add USB device ID information... - */ - - ptr = device_id + strlen(device_id); - snprintf(ptr, sizeof(device_id) - (ptr - device_id), "%s:%s;", - key + 4, value); - } - - if (!_cups_strcasecmp(key, "usb_MFG") || !_cups_strcasecmp(key, "usb_MANU") || - !_cups_strcasecmp(key, "usb_MANUFACTURER")) - strcpy(make_and_model, value); - else if (!_cups_strcasecmp(key, "usb_MDL") || !_cups_strcasecmp(key, "usb_MODEL")) - strcpy(model, value); - else if (!_cups_strcasecmp(key, "product") && !strstr(value, "Ghostscript")) - { - if (value[0] == '(') - { - /* - * Strip parenthesis... - */ - - if ((ptr = value + strlen(value) - 1) > value && *ptr == ')') - *ptr = '\0'; - - strcpy(model, value + 1); - } - else - strcpy(model, value); - } - else if (!_cups_strcasecmp(key, "ty")) - { - strcpy(model, value); - - if ((ptr = strchr(model, ',')) != NULL) - *ptr = '\0'; - } - else if (!_cups_strcasecmp(key, "priority")) - device->priority = atoi(value); - else if ((device->type == CUPS_DEVICE_IPP || - device->type == CUPS_DEVICE_IPPS || - device->type == CUPS_DEVICE_PRINTER) && - !_cups_strcasecmp(key, "printer-type")) - { - /* - * This is a CUPS printer! - */ - - device->cups_shared = 1; + device->cups_shared = 1; - if (device->type == CUPS_DEVICE_PRINTER) - device->sent = 1; - } - } + if (device->type == CUPS_DEVICE_PRINTER) + device->sent = 1; + } + } - if (device->device_id) - free(device->device_id); + if (device->device_id) + free(device->device_id); - if (!device_id[0] && strcmp(model, "Unknown")) - { - if (make_and_model[0]) - snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;", - make_and_model, model); - else if (!_cups_strncasecmp(model, "designjet ", 10)) - snprintf(device_id, sizeof(device_id), "MFG:HP;MDL:%s", model + 10); - else if (!_cups_strncasecmp(model, "stylus ", 7)) - snprintf(device_id, sizeof(device_id), "MFG:EPSON;MDL:%s", model + 7); - else if ((ptr = strchr(model, ' ')) != NULL) - { - /* - * Assume the first word is the make... - */ + if (!device_id[0] && strcmp(model, "Unknown")) + { + if (make_and_model[0]) + snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;", + make_and_model, model); + else if (!_cups_strncasecmp(model, "designjet ", 10)) + snprintf(device_id, sizeof(device_id), "MFG:HP;MDL:%s", model + 10); + else if (!_cups_strncasecmp(model, "stylus ", 7)) + snprintf(device_id, sizeof(device_id), "MFG:EPSON;MDL:%s", model + 7); + else if ((ptr = strchr(model, ' ')) != NULL) + { + /* + * Assume the first word is the make... + */ - memcpy(make_and_model, model, ptr - model); - make_and_model[ptr - model] = '\0'; + memcpy(make_and_model, model, ptr - model); + make_and_model[ptr - model] = '\0'; - snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s", - make_and_model, ptr + 1); - } - } + snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s", + make_and_model, ptr + 1); + } + } - if (device_id[0]) - device->device_id = strdup(device_id); - else - device->device_id = NULL; + if (device_id[0]) + device->device_id = strdup(device_id); + else + device->device_id = NULL; - if (device->make_and_model) - free(device->make_and_model); + if (device->make_and_model) + free(device->make_and_model); - if (make_and_model[0]) - { - strlcat(make_and_model, " ", sizeof(make_and_model)); - strlcat(make_and_model, model, sizeof(make_and_model)); + if (make_and_model[0]) + { + strlcat(make_and_model, " ", sizeof(make_and_model)); + strlcat(make_and_model, model, sizeof(make_and_model)); - device->make_and_model = strdup(make_and_model); - } - else - device->make_and_model = strdup(model); - break; - } + device->make_and_model = strdup(make_and_model); } - - if (!device) - fprintf(stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", fullName); + else + device->make_and_model = strdup(model); } +#endif /* HAVE_DNSSD || HAVE_AVAHI */ /* - * 'sigterm_handler()' - Handle termination signals... + * 'sigterm_handler()' - Handle termination signals. */ static void @@ -966,5 +1276,5 @@ unquote(char *dst, /* I - Destination buffer */ /* - * End of "$Id: dnssd.c 10379 2012-03-23 22:16:22Z mike $". + * End of "$Id: dnssd.c 10489 2012-05-21 16:05:58Z mike $". */ diff --git a/backend/ipp.c b/backend/ipp.c index 91524a82..83074ebd 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -1,5 +1,5 @@ /* - * "$Id: ipp.c 10509 2012-05-23 22:47:10Z mike $" + * "$Id: ipp.c 10548 2012-07-16 18:21:43Z mike $" * * IPP backend for CUPS. * @@ -45,8 +45,12 @@ # define kPMPrintUIToolAgent "com.apple.printuitool.agent" # define kPMStartJob 100 # define kPMWaitForJob 101 +# ifdef HAVE_XPC_PRIVATE_H +# include <xpc/private.h> +# else extern void xpc_connection_set_target_uid(xpc_connection_t connection, uid_t uid); +# endif /* HAVE_XPC_PRIVATE_H */ #endif /* HAVE_GSSAPI && HAVE_XPC */ @@ -165,7 +169,7 @@ static const char *password_cb(const char *); static void report_attr(ipp_attribute_t *attr); static void report_printer_state(ipp_t *ipp); #if defined(HAVE_GSSAPI) && defined(HAVE_XPC) -static int run_as_user(int argc, char *argv[], uid_t uid, +static int run_as_user(char *argv[], uid_t uid, const char *device_uri, int fd); #endif /* HAVE_GSSAPI && HAVE_XPC */ static void sigterm_handler(int sig); @@ -344,7 +348,7 @@ main(int argc, /* I - Number of command-line args */ if (uid > 0) { if (argc == 6) - return (run_as_user(argc, argv, uid, device_uri, 0)); + return (run_as_user(argv, uid, device_uri, 0)); else { int status = 0; /* Exit status */ @@ -353,7 +357,7 @@ main(int argc, /* I - Number of command-line args */ { if ((fd = open(argv[i], O_RDONLY)) >= 0) { - status = run_as_user(argc, argv, uid, device_uri, fd); + status = run_as_user(argv, uid, device_uri, fd); close(fd); } else @@ -643,6 +647,9 @@ main(int argc, /* I - Number of command-line args */ update_reasons(NULL, "-connecting-to-device"); return (CUPS_BACKEND_STOP); } + + if (job_canceled) + return (CUPS_BACKEND_OK); } http = _httpCreate(hostname, port, addrlist, cupsEncryption(), AF_UNSPEC); @@ -747,7 +754,7 @@ main(int argc, /* I - Number of command-line args */ case ECONNREFUSED : default : _cupsLangPrintFilter(stderr, "WARNING", - _("The printer is busy.")); + _("The printer is in use.")); break; } @@ -770,7 +777,9 @@ main(int argc, /* I - Number of command-line args */ } while (http->fd < 0); - if (job_canceled || !http) + if (job_canceled) + return (CUPS_BACKEND_OK); + else if (!http) return (CUPS_BACKEND_FAILED); update_reasons(NULL, "-connecting-to-device"); @@ -862,7 +871,7 @@ main(int argc, /* I - Number of command-line args */ return (CUPS_BACKEND_FAILED); } - _cupsLangPrintFilter(stderr, "INFO", _("The printer is busy.")); + _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use.")); report_printer_state(supported); @@ -880,14 +889,14 @@ main(int argc, /* I - Number of command-line args */ if (version >= 20) { _cupsLangPrintFilter(stderr, "INFO", - _("Printer does not support IPP/%d.%d, trying " + _("The printer does not support IPP/%d.%d, trying " "IPP/%s."), version / 10, version % 10, "1.1"); version = 11; } else { _cupsLangPrintFilter(stderr, "INFO", - _("Printer does not support IPP/%d.%d, trying " + _("The printer does not support IPP/%d.%d, trying " "IPP/%s."), version / 10, version % 10, "1.0"); version = 10; } @@ -968,7 +977,7 @@ main(int argc, /* I - Number of command-line args */ if (busy) { - _cupsLangPrintFilter(stderr, "INFO", _("The printer is busy.")); + _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use.")); report_printer_state(supported); @@ -1071,11 +1080,14 @@ main(int argc, /* I - Number of command-line args */ get_job_attrs = 1; } - if (!send_document) + if (create_job && !send_document) { fputs("DEBUG: Printer supports Create-Job but not Send-Document.\n", stderr); create_job = 0; + + update_reasons(NULL, "+cups-ipp-conformance-failure-report," + "cups-ipp-missing-send-document"); } if (!validate_job) @@ -1092,7 +1104,10 @@ main(int argc, /* I - Number of command-line args */ report_printer_state(supported); } - while (ipp_status > IPP_OK_CONFLICT); + while (!job_canceled && ipp_status > IPP_OK_CONFLICT); + + if (job_canceled) + return (CUPS_BACKEND_OK); /* * See if the printer is accepting jobs and is not stopped; if either @@ -1143,12 +1158,7 @@ main(int argc, /* I - Number of command-line args */ copies = atoi(argv[4]); if (copies_sup || argc < 7) - { copies_remaining = 1; - - if (argc < 7 && !_cups_strncasecmp(final_content_type, "image/", 6)) - copies = 1; - } else copies_remaining = copies; @@ -1300,7 +1310,7 @@ main(int argc, /* I - Number of command-line args */ if (ipp_status == IPP_SERVICE_UNAVAILABLE || ipp_status == IPP_PRINTER_BUSY) { - _cupsLangPrintFilter(stderr, "INFO", _("The printer is busy.")); + _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use.")); sleep(10); } else if (ipp_status == IPP_DOCUMENT_FORMAT) @@ -1451,7 +1461,7 @@ main(int argc, /* I - Number of command-line args */ ipp_status == IPP_NOT_POSSIBLE || ipp_status == IPP_PRINTER_BUSY) { - _cupsLangPrintFilter(stderr, "INFO", _("The printer is busy.")); + _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use.")); sleep(10); if (num_files == 0) @@ -1802,7 +1812,7 @@ main(int argc, /* I - Number of command-line args */ * Cancel the job as needed... */ - if (job_canceled && job_id) + if (job_canceled > 0 && job_id > 0) cancel_job(http, uri, job_id, resource, argv[2], version); /* @@ -1874,23 +1884,22 @@ main(int argc, /* I - Number of command-line args */ else if (ipp_status == IPP_CONFLICT) return (CUPS_BACKEND_FAILED); else if (ipp_status == IPP_REQUEST_VALUE || - ipp_status == IPP_DOCUMENT_FORMAT) + ipp_status == IPP_DOCUMENT_FORMAT || job_canceled < 0) { if (ipp_status == IPP_REQUEST_VALUE) _cupsLangPrintFilter(stderr, "ERROR", _("Print job too large.")); - else + else if (ipp_status == IPP_DOCUMENT_FORMAT) _cupsLangPrintFilter(stderr, "ERROR", _("Printer cannot print supplied content.")); + else + _cupsLangPrintFilter(stderr, "ERROR", _("Print job canceled at printer.")); return (CUPS_BACKEND_CANCEL); } else if (ipp_status > IPP_OK_CONFLICT && ipp_status != IPP_ERROR_JOB_CANCELED) return (CUPS_BACKEND_RETRY_CURRENT); else - { - _cupsLangPrintFilter(stderr, "INFO", _("Ready to print.")); return (CUPS_BACKEND_OK); - } } @@ -2153,7 +2162,7 @@ monitor_printer( response = cupsDoRequest(http, request, monitor->resource); - fprintf(stderr, "DEBUG: %s: %s (%s)\n", ippOpString(job_op), + fprintf(stderr, "DEBUG: (monitor) %s: %s (%s)\n", ippOpString(job_op), ippErrorString(cupsLastError()), cupsLastErrorString()); if (cupsLastError() <= IPP_OK_CONFLICT) @@ -2217,6 +2226,14 @@ monitor_printer( ippDelete(response); + fprintf(stderr, "DEBUG: (monitor) job-state=%s\n", + ippEnumString("job-state", monitor->job_state)); + + if (!job_canceled && + (monitor->job_state == IPP_JOB_CANCELED || + monitor->job_state == IPP_JOB_ABORTED)) + job_canceled = -1; + /* * Disconnect from the printer - we'll reconnect on the next poll... */ @@ -2237,7 +2254,7 @@ monitor_printer( * Cancel the job if necessary... */ - if (job_canceled && monitor->job_id > 0) + if (job_canceled > 0 && monitor->job_id > 0) if (!httpReconnect(http)) cancel_job(http, monitor->uri, monitor->job_id, monitor->resource, monitor->user, monitor->version); @@ -2465,9 +2482,46 @@ new_request( NULL, "two-sided-short-edge"); } - if (doc_handling_sup && - (!format || _cups_strncasecmp(format, "image/", 6)) && - (keyword = cupsGetOption("collate", num_options, options)) != NULL) + if ((keyword = cupsGetOption("multiple-document-handling", + num_options, options)) != NULL) + { + if (strstr(keyword, "uncollated")) + keyword = "false"; + else + keyword = "true"; + } + else if ((keyword = cupsGetOption("collate", num_options, + options)) == NULL) + keyword = "true"; + + if (format) + { + if (!_cups_strcasecmp(format, "image/gif") || + !_cups_strcasecmp(format, "image/jp2") || + !_cups_strcasecmp(format, "image/jpeg") || + !_cups_strcasecmp(format, "image/png") || + !_cups_strcasecmp(format, "image/tiff") || + !_cups_strncasecmp(format, "image/x-", 8)) + { + /* + * Collation makes no sense for single page image formats... + */ + + keyword = "false"; + } + else if (!_cups_strncasecmp(format, "image/", 6) || + !_cups_strcasecmp(format, "application/vnd.cups-raster")) + { + /* + * Multi-page image formats will have copies applied by the upstream + * filters... + */ + + copies = 1; + } + } + + if (doc_handling_sup) { if (!_cups_strcasecmp(keyword, "true")) collate_str = "separate-documents-collated-copies"; @@ -2481,6 +2535,9 @@ new_request( "multiple-document-handling", NULL, collate_str); break; } + + if (i >= doc_handling_sup->num_values) + copies = 1; } /* @@ -2529,7 +2586,7 @@ new_request( cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB); } - if (copies > 1) + if (copies > 1 && (!pc || copies <= pc->max_copies)) ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies", copies); } @@ -2782,8 +2839,7 @@ report_printer_state(ipp_t *ipp) /* I - IPP response */ */ static int /* O - Exit status */ -run_as_user(int argc, /* I - Number of command-line args */ - char *argv[], /* I - Command-line arguments */ +run_as_user(char *argv[], /* I - Command-line arguments */ uid_t uid, /* I - User ID */ const char *device_uri, /* I - Device URI */ int fd) /* I - File to print */ @@ -2974,6 +3030,8 @@ sigterm_handler(int sig) /* I - Signal */ { (void)sig; /* remove compiler warnings... */ + write(2, "DEBUG: Got SIGTERM.\n", 20); + #if defined(HAVE_GSSAPI) && defined(HAVE_XPC) if (child_pid) { @@ -2988,6 +3046,8 @@ sigterm_handler(int sig) /* I - Signal */ * Flag that the job should be canceled... */ + write(2, "DEBUG: job_canceled = 1.\n", 25); + job_canceled = 1; return; } @@ -3217,5 +3277,5 @@ update_reasons(ipp_attribute_t *attr, /* I - printer-state-reasons or NULL */ } /* - * End of "$Id: ipp.c 10509 2012-05-23 22:47:10Z mike $". + * End of "$Id: ipp.c 10548 2012-07-16 18:21:43Z mike $". */ diff --git a/backend/lpd.c b/backend/lpd.c index 7837b344..160a83ef 100644 --- a/backend/lpd.c +++ b/backend/lpd.c @@ -1,5 +1,5 @@ /* - * "$Id: lpd.c 10265 2012-02-12 07:20:10Z mike $" + * "$Id: lpd.c 10520 2012-05-31 02:53:59Z mike $" * * Line Printer Daemon backend for CUPS. * @@ -92,7 +92,7 @@ static int lpd_queue(const char *hostname, http_addrlist_t *addrlist, int mode, const char *user, const char *title, int copies, int banner, int format, int order, int reserve, int manual_copies, int timeout, - int contimeout); + int contimeout, const char *orighost); static int lpd_write(int lpd_fd, char *buffer, int length); #ifndef HAVE_RRESVPORT_AF static int rresvport_af(int *port, int family); @@ -144,6 +144,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + int num_jobopts; /* Number of job options */ + cups_option_t *jobopts = NULL; /* Job options */ /* @@ -191,6 +193,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ return (CUPS_BACKEND_FAILED); } + num_jobopts = cupsParseOptions(argv[5], 0, &jobopts); + /* * Extract the hostname and printer name from the URI... */ @@ -525,7 +529,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode, username, title, copies, banner, format, order, reserve, - manual_copies, timeout, contimeout); + manual_copies, timeout, contimeout, + cupsGetOption("job-originating-host-name", num_jobopts, + jobopts)); if (!status) fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4])); @@ -533,7 +539,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ else status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode, username, title, 1, banner, format, order, reserve, 1, - timeout, contimeout); + timeout, contimeout, + cupsGetOption("job-originating-host-name", num_jobopts, + jobopts)); /* * Remove the temporary file if necessary... @@ -608,7 +616,7 @@ lpd_command(int fd, /* I - Socket connection to LPD host */ if (recv(fd, &status, 1, 0) < 1) { - _cupsLangPrintFilter(stderr, "WARNING", _("Printer did not respond.")); + _cupsLangPrintFilter(stderr, "WARNING", _("The printer did not respond.")); status = errno; } @@ -638,7 +646,8 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ int reserve, /* I - Reserve ports? */ int manual_copies,/* I - Do copies by hand... */ int timeout, /* I - Timeout... */ - int contimeout) /* I - Connection timeout */ + int contimeout, /* I - Connection timeout */ + const char *orighost) /* I - job-originating-host-name */ { char localhost[255]; /* Local host name */ int error; /* Error number */ @@ -816,7 +825,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ case ECONNREFUSED : default : _cupsLangPrintFilter(stderr, "WARNING", - _("The printer is busy.")); + _("The printer is in use.")); break; } @@ -927,7 +936,10 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ return (CUPS_BACKEND_FAILED); } - httpGetHostname(NULL, localhost, sizeof(localhost)); + if (orighost && _cups_strcasecmp(orighost, "localhost")) + strlcpy(localhost, orighost, sizeof(localhost)); + else + httpGetHostname(NULL, localhost, sizeof(localhost)); snprintf(control, sizeof(control), "H%.31s\n" /* RFC 1179, Section 7.2 - host name <= 31 chars */ @@ -994,7 +1006,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ if (read(fd, &status, 1) < 1) { _cupsLangPrintFilter(stderr, "WARNING", - _("Printer did not respond.")); + _("The printer did not respond.")); status = errno; } } @@ -1076,7 +1088,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ if (recv(fd, &status, 1, 0) < 1) { _cupsLangPrintFilter(stderr, "WARNING", - _("Printer did not respond.")); + _("The printer did not respond.")); status = 0; } } @@ -1126,7 +1138,7 @@ lpd_queue(const char *hostname, /* I - Host to connect to */ if (read(fd, &status, 1) < 1) { _cupsLangPrintFilter(stderr, "WARNING", - _("Printer did not respond.")); + _("The printer did not respond.")); status = errno; } } @@ -1302,5 +1314,5 @@ sigterm_handler(int sig) /* I - Signal */ /* - * End of "$Id: lpd.c 10265 2012-02-12 07:20:10Z mike $". + * End of "$Id: lpd.c 10520 2012-05-31 02:53:59Z mike $". */ diff --git a/backend/network.c b/backend/network.c index d5827c46..387d5150 100644 --- a/backend/network.c +++ b/backend/network.c @@ -1,5 +1,5 @@ /* - * "$Id: network.c 9578 2011-03-04 18:44:47Z mike $" + * "$Id: network.c 10389 2012-03-28 21:57:29Z mike $" * * Common backend network APIs for CUPS. * @@ -71,7 +71,7 @@ backendNetworkSideCB( { cups_sc_command_t command; /* Request command */ cups_sc_status_t status; /* Request/response status */ - char data[2048]; /* Request/response data */ + char data[65536]; /* Request/response data */ int datalen; /* Request/response data size */ const char *device_id; /* 1284DEVICEID env var */ @@ -92,7 +92,7 @@ backendNetworkSideCB( status = CUPS_SC_STATUS_NOT_IMPLEMENTED; else if (backendDrainOutput(print_fd, device_fd)) status = CUPS_SC_STATUS_IO_ERROR; - else + else status = CUPS_SC_STATUS_OK; datalen = 0; @@ -119,8 +119,35 @@ backendNetworkSideCB( if (snmp_fd >= 0) { + char *dataptr; /* Pointer into data */ cups_snmp_t packet; /* Packet from printer */ + const char *snmp_value; /* CUPS_SNMP_VALUE env var */ + if ((snmp_value = getenv("CUPS_SNMP_VALUE")) != NULL) + { + const char *snmp_count; /* CUPS_SNMP_COUNT env var */ + int count; /* Repetition count */ + + if ((snmp_count = getenv("CUPS_SNMP_COUNT")) != NULL) + { + if ((count = atoi(snmp_count)) <= 0) + count = 1; + } + else + count = 1; + + for (dataptr = data + strlen(data) + 1; + count > 0 && dataptr < (data + sizeof(data) - 1); + count --, dataptr += strlen(dataptr)) + strlcpy(dataptr, snmp_value, sizeof(data) - (dataptr - data)); + + fprintf(stderr, "DEBUG: Returning %s %s\n", data, + data + strlen(data) + 1); + + status = CUPS_SC_STATUS_OK; + datalen = dataptr - data; + break; + } if (!_cupsSNMPStringToOID(data, packet.object_name, CUPS_SNMP_MAX_OID)) { @@ -141,7 +168,6 @@ backendNetworkSideCB( { if (_cupsSNMPRead(snmp_fd, &packet, 1.0)) { - char *dataptr; /* Pointer into data */ int i; /* Looping var */ @@ -172,7 +198,7 @@ backendNetworkSideCB( case CUPS_ASN1_OCTET_STRING : if (packet.object_value.string.num_bytes < 0) i = 0; - else if (packet.object_value.string.num_bytes < + else if (packet.object_value.string.num_bytes < (sizeof(data) - (dataptr - data))) i = packet.object_value.string.num_bytes; else @@ -296,5 +322,5 @@ backendNetworkSideCB( /* - * End of "$Id: network.c 9578 2011-03-04 18:44:47Z mike $". + * End of "$Id: network.c 10389 2012-03-28 21:57:29Z mike $". */ diff --git a/backend/parallel.c b/backend/parallel.c deleted file mode 100644 index a475f0e9..00000000 --- a/backend/parallel.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * "$Id: parallel.c 9774 2011-05-12 06:15:14Z mike $" - * - * Parallel port backend for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. - * - * 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" - * "LICENSE" which should have been included with this file. If this - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * main() - Send a file to the specified parallel port. - * list_devices() - List all parallel devices. - * side_cb() - Handle side-channel requests... - */ - -/* - * Include necessary headers. - */ - -#include "backend-private.h" - -#ifdef __hpux -# include <sys/time.h> -#else -# include <sys/select.h> -#endif /* __hpux */ - -#ifdef WIN32 -# include <io.h> -#else -# include <unistd.h> -# include <fcntl.h> -# include <termios.h> -# include <sys/socket.h> -#endif /* WIN32 */ - -#ifdef __sgi -# include <invent.h> -# ifndef INV_EPP_ECP_PLP -# define INV_EPP_ECP_PLP 6 /* From 6.3/6.4/6.5 sys/invent.h */ -# define INV_ASO_SERIAL 14 /* serial portion of SGI ASO board */ -# define INV_IOC3_DMA 16 /* DMA mode IOC3 serial */ -# define INV_IOC3_PIO 17 /* PIO mode IOC3 serial */ -# define INV_ISA_DMA 19 /* DMA mode ISA serial -- O2 */ -# endif /* !INV_EPP_ECP_PLP */ -#endif /* __sgi */ - - -/* - * Local functions... - */ - -static void list_devices(void); -static int side_cb(int print_fd, int device_fd, int snmp_fd, - http_addr_t *addr, int use_bc); - - -/* - * 'main()' - Send a file to the specified parallel port. - * - * Usage: - * - * printer-uri job-id user title copies options [file] - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments (6 or 7) */ - char *argv[]) /* I - Command-line arguments */ -{ - char method[255], /* Method in URI */ - hostname[1024], /* Hostname */ - username[255], /* Username info (not used) */ - resource[1024], /* Resource info (device and options) */ - *options; /* Pointer to options */ - int port; /* Port number (not used) */ - int print_fd, /* Print file */ - device_fd, /* Parallel device */ - use_bc; /* Read back-channel data? */ - int copies; /* Number of copies to print */ - ssize_t tbytes; /* Total number of bytes written */ - 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 */ - - - /* - * 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 (CUPS_BACKEND_OK); - } - else if (argc < 6 || argc > 7) - { - _cupsLangPrintf(stderr, - _("Usage: %s job-id user title copies options [file]"), - argv[0]); - return (CUPS_BACKEND_FAILED); - } - - /* - * If we have 7 arguments, print the file named on the command-line. - * Otherwise, send stdin instead... - */ - - if (argc == 6) - { - print_fd = 0; - copies = 1; - } - else - { - /* - * Try to open the print file... - */ - - if ((print_fd = open(argv[6], O_RDONLY)) < 0) - { - _cupsLangPrintError("ERROR", _("Unable to open print file")); - return (CUPS_BACKEND_FAILED); - } - - copies = atoi(argv[4]); - } - - /* - * Extract the device name and options from the URI... - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv), - method, sizeof(method), username, sizeof(username), - hostname, sizeof(hostname), &port, - resource, sizeof(resource)); - - /* - * See if there are any options... - */ - - if ((options = strchr(resource, '?')) != NULL) - { - /* - * Yup, terminate the device name string and move to the first - * character of the options... - */ - - *options++ = '\0'; - } - - /* - * Open the parallel port device... - */ - - fputs("STATE: +connecting-to-device\n", stderr); - - do - { -#if defined(__linux) || defined(__FreeBSD__) - /* - * The Linux and FreeBSD parallel port drivers currently are broken WRT - * select() and bidirection I/O... - */ - - device_fd = open(resource, O_WRONLY | O_EXCL); - use_bc = 0; - -#else - if ((device_fd = open(resource, O_RDWR | O_EXCL)) < 0) - { - device_fd = open(resource, O_WRONLY | O_EXCL); - use_bc = 0; - } - else - use_bc = 1; -#endif /* __linux || __FreeBSD__ */ - - if (device_fd == -1) - { - if (getenv("CLASS") != NULL) - { - /* - * If the CLASS environment variable is set, the job was submitted - * to a class and not to a specific queue. In this case, we want - * to abort immediately so that the job can be requeued on the next - * available printer in the class. - */ - - _cupsLangPrintFilter(stderr, "INFO", - _("Unable to contact printer, queuing on next " - "printer in class.")); - - /* - * Sleep 5 seconds to keep the job from requeuing too rapidly... - */ - - sleep(5); - - return (CUPS_BACKEND_FAILED); - } - - if (errno == EBUSY) - { - _cupsLangPrintFilter(stderr, "INFO", - _("Printer busy; will retry in 30 seconds.")); - sleep(30); - } - else if (errno == ENXIO || errno == EIO || errno == ENOENT) - { - _cupsLangPrintFilter(stderr, "INFO", - _("Printer not connected; will retry in 30 " - "seconds.")); - sleep(30); - } - else - { - _cupsLangPrintError("ERROR", _("Unable to open device file")); - return (CUPS_BACKEND_FAILED); - } - } - } - while (device_fd < 0); - - fputs("STATE: -connecting-to-device\n", stderr); - - /* - * Set any options provided... - */ - - tcgetattr(device_fd, &opts); - - opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */ - - /**** No options supported yet ****/ - - tcsetattr(device_fd, TCSANOW, &opts); - - /* - * Finally, send the print file... - */ - - tbytes = 0; - - while (copies > 0 && tbytes >= 0) - { - copies --; - - if (print_fd != 0) - { - fputs("PAGE: 1 1\n", stderr); - lseek(print_fd, 0, SEEK_SET); - } - - tbytes = backendRunLoop(print_fd, device_fd, -1, NULL, use_bc, 1, side_cb); - - if (print_fd != 0 && tbytes >= 0) - _cupsLangPrintFilter(stderr, "INFO", _("Print file sent.")); - } - - /* - * Close the socket connection and input file and return... - */ - - close(device_fd); - - if (print_fd != 0) - close(print_fd); - - return (CUPS_BACKEND_OK); -} - - -/* - * 'list_devices()' - List all parallel devices. - */ - -static void -list_devices(void) -{ -#if defined(__hpux) || defined(__sgi) || defined(__sun) - static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz"; - /* Funky hex numbering used for some devices */ -#endif /* __hpux || __sgi || __sun */ - -#ifdef __linux - int i; /* Looping var */ - int fd; /* File descriptor */ - char device[255], /* Device filename */ - basedevice[255], /* Base device filename for ports */ - device_id[1024], /* Device ID string */ - make_model[1024], /* Make and model */ - info[1024], /* Info string */ - uri[1024]; /* Device URI */ - - - if (!access("/dev/parallel/", 0)) - strcpy(basedevice, "/dev/parallel/"); - else if (!access("/dev/printers/", 0)) - strcpy(basedevice, "/dev/printers/"); - else - strcpy(basedevice, "/dev/lp"); - - for (i = 0; i < 4; i ++) - { - /* - * Open the port, if available... - */ - - sprintf(device, "%s%d", basedevice, i); - if ((fd = open(device, O_RDWR | O_EXCL)) < 0) - fd = open(device, O_WRONLY); - - if (fd >= 0) - { - /* - * Now grab the IEEE 1284 device ID string... - */ - - snprintf(uri, sizeof(uri), "parallel:%s", device); - - if (!backendGetDeviceID(fd, device_id, sizeof(device_id), - make_model, sizeof(make_model), - NULL, uri, sizeof(uri))) - { - snprintf(info, sizeof(info), "%s LPT #%d", make_model, i + 1); - cupsBackendReport("direct", uri, make_model, info, device_id, NULL); - } - else - { - snprintf(info, sizeof(info), "LPT #%d", i + 1); - cupsBackendReport("direct", uri, NULL, info, NULL, NULL); - } - - close(fd); - } - } -#elif defined(__sgi) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - inventory_t *inv; /* Hardware inventory info */ - - - /* - * IRIX maintains a hardware inventory of most devices... - */ - - setinvent(); - - while ((inv = getinvent()) != NULL) - { - if (inv->inv_class == INV_PARALLEL && - (inv->inv_type == INV_ONBOARD_PLP || - inv->inv_type == INV_EPP_ECP_PLP)) - { - /* - * Standard parallel port... - */ - - puts("direct parallel:/dev/plp \"Unknown\" \"Onboard Parallel Port\""); - } - else if (inv->inv_class == INV_PARALLEL && - inv->inv_type == INV_EPC_PLP) - { - /* - * EPC parallel port... - */ - - printf("direct parallel:/dev/plp%d \"Unknown\" \"Integral EPC parallel port, Ebus slot %d\"\n", - inv->inv_controller, inv->inv_controller); - } - } - - endinvent(); - - /* - * Central Data makes serial and parallel "servers" that can be - * connected in a number of ways. Look for ports... - */ - - for (i = 0; i < 10; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/lpn%d%c", j, funky_hex[n]); - else if (i == 9) /* PCI */ - sprintf(device, "/dev/lpp%d%c", j, funky_hex[n]); - else /* SCSI */ - sprintf(device, "/dev/lp%d%d%c", i, j, funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n", - device, j, n); - else if (i == 9) - printf("direct parallel:%s \"Unknown\" \"Central Data PCI Parallel Port, ID %d, port %d\"\n", - device, j, n); - else - printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__sun) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - - - /* - * Standard parallel ports... - */ - - for (i = 0; i < 10; i ++) - { - sprintf(device, "/dev/ecpp%d", i); - if (access(device, 0) == 0) - printf("direct parallel:%s \"Unknown\" \"Sun IEEE-1284 Parallel Port #%d\"\n", - device, i + 1); - } - - for (i = 0; i < 10; i ++) - { - sprintf(device, "/dev/bpp%d", i); - if (access(device, 0) == 0) - printf("direct parallel:%s \"Unknown\" \"Sun Standard Parallel Port #%d\"\n", - device, i + 1); - } - - for (i = 0; i < 3; i ++) - { - sprintf(device, "/dev/lp%d", i); - - if (access(device, 0) == 0) - printf("direct parallel:%s \"Unknown\" \"PC Parallel Port #%d\"\n", - device, i + 1); - } - - /* - * MAGMA parallel ports... - */ - - for (i = 0; i < 40; i ++) - { - sprintf(device, "/dev/pm%02d", i); - if (access(device, 0) == 0) - printf("direct parallel:%s \"Unknown\" \"MAGMA Parallel Board #%d Port #%d\"\n", - device, (i / 10) + 1, (i % 10) + 1); - } - - /* - * Central Data parallel ports... - */ - - for (i = 0; i < 9; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/sts/lpN%d%c", j, funky_hex[n]); - else - sprintf(device, "/dev/sts/lp%c%d%c", i + 'C', j, - funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n", - device, j, n); - else - printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__hpux) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - - - /* - * Standard parallel ports... - */ - - if (access("/dev/rlp", 0) == 0) - puts("direct parallel:/dev/rlp \"Unknown\" \"Standard Parallel Port (/dev/rlp)\""); - - for (i = 0; i < 7; i ++) - for (j = 0; j < 7; j ++) - { - sprintf(device, "/dev/c%dt%dd0_lp", i, j); - if (access(device, 0) == 0) - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d,%d\"\n", - device, i, j); - } - - /* - * Central Data parallel ports... - */ - - for (i = 0; i < 9; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/lpN%d%c", j, funky_hex[n]); - else - sprintf(device, "/dev/lp%c%d%c", i + 'C', j, - funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n", - device, j, n); - else - printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__osf__) - int i; /* Looping var */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - - - for (i = 0; i < 3; i ++) - { - sprintf(device, "/dev/lp%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); - } - } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) - int i; /* Looping var */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - - - for (i = 0; i < 3; i ++) - { - sprintf(device, "/dev/lpt%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (interrupt-driven)\"\n", device, i + 1); - } - - sprintf(device, "/dev/lpa%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (polled)\"\n", device, i + 1); - } - } -#elif defined(_AIX) - int i; /* Looping var */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - - - for (i = 0; i < 8; i ++) - { - sprintf(device, "/dev/lp%d", i); - if ((fd = open(device, O_WRONLY)) >= 0) - { - close(fd); - printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); - } - } -#endif -} - - -/* - * 'side_cb()' - Handle side-channel requests... - */ - -static int /* O - 0 on success, -1 on error */ -side_cb(int print_fd, /* I - Print file */ - int device_fd, /* I - Device file */ - int snmp_fd, /* I - SNMP socket (unused) */ - http_addr_t *addr, /* I - Device address (unused) */ - int use_bc) /* I - Using back-channel? */ -{ - cups_sc_command_t command; /* Request command */ - cups_sc_status_t status; /* Request/response status */ - char data[2048]; /* Request/response data */ - int datalen; /* Request/response data size */ - - - (void)snmp_fd; - (void)addr; - - datalen = sizeof(data); - - if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) - return (-1); - - switch (command) - { - case CUPS_SC_CMD_DRAIN_OUTPUT : - if (backendDrainOutput(print_fd, device_fd)) - status = CUPS_SC_STATUS_IO_ERROR; - else if (tcdrain(device_fd)) - status = CUPS_SC_STATUS_IO_ERROR; - else - status = CUPS_SC_STATUS_OK; - - datalen = 0; - break; - - case CUPS_SC_CMD_GET_BIDI : - status = CUPS_SC_STATUS_OK; - data[0] = use_bc; - datalen = 1; - break; - - case CUPS_SC_CMD_GET_DEVICE_ID : - memset(data, 0, sizeof(data)); - - if (backendGetDeviceID(device_fd, data, sizeof(data) - 1, - NULL, 0, NULL, NULL, 0)) - { - status = CUPS_SC_STATUS_NOT_IMPLEMENTED; - datalen = 0; - } - else - { - status = CUPS_SC_STATUS_OK; - datalen = strlen(data); - } - break; - - default : - status = CUPS_SC_STATUS_NOT_IMPLEMENTED; - datalen = 0; - break; - } - - return (cupsSideChannelWrite(command, status, data, datalen, 1.0)); -} - - -/* - * End of "$Id: parallel.c 9774 2011-05-12 06:15:14Z mike $". - */ diff --git a/backend/runloop.c b/backend/runloop.c index 6cb41783..90bb9558 100644 --- a/backend/runloop.c +++ b/backend/runloop.c @@ -1,5 +1,5 @@ /* - * "$Id: runloop.c 10369 2012-03-21 04:31:19Z mike $" + * "$Id: runloop.c 10434 2012-04-23 21:47:41Z mike $" * * Common run loop APIs for CUPS backends. * @@ -92,7 +92,8 @@ backendDrainOutput(int print_fd, /* I - Print file descriptor */ if (errno != EAGAIN || errno != EINTR) { - _cupsLangPrintError("ERROR", _("Unable to read print data")); + fprintf(stderr, "DEBUG: Read failed: %s\n", strerror(errno)); + _cupsLangPrintFilter(stderr, "ERROR", _("Unable to read print data.")); return (-1); } @@ -250,7 +251,7 @@ backendRunLoop( { fputs("STATE: +offline-report\n", stderr); _cupsLangPrintFilter(stderr, "INFO", - _("Printer is not currently connected.")); + _("The printer is not connected.")); offline = 1; } else if (errno == EINTR && total_bytes == 0) @@ -319,7 +320,9 @@ backendRunLoop( if (errno != EAGAIN || errno != EINTR) { - _cupsLangPrintError("ERROR", _("Unable to read print data")); + fprintf(stderr, "DEBUG: Read failed: %s\n", strerror(errno)); + _cupsLangPrintFilter(stderr, "ERROR", + _("Unable to read print data.")); return (-1); } @@ -368,7 +371,7 @@ backendRunLoop( { fputs("STATE: +offline-report\n", stderr); _cupsLangPrintFilter(stderr, "INFO", - _("Printer is not currently connected.")); + _("The printer is not connected.")); offline = 1; } } @@ -389,7 +392,8 @@ backendRunLoop( if (offline && update_state) { fputs("STATE: -offline-report\n", stderr); - _cupsLangPrintFilter(stderr, "INFO", _("Printer is now connected.")); + _cupsLangPrintFilter(stderr, "INFO", + _("The printer is now connected.")); offline = 0; } @@ -436,7 +440,7 @@ backendWaitLoop( { int nfds; /* Number of file descriptors */ fd_set input; /* Input set for reading */ - time_t curtime, /* Current time */ + time_t curtime = 0, /* Current time */ snmp_update = 0;/* Last SNMP status update */ struct timeval timeout; /* Timeout for select() */ @@ -535,5 +539,5 @@ backendWaitLoop( /* - * End of "$Id: runloop.c 10369 2012-03-21 04:31:19Z mike $". + * End of "$Id: runloop.c 10434 2012-04-23 21:47:41Z mike $". */ diff --git a/backend/serial.c b/backend/serial.c deleted file mode 100644 index 4f350a1f..00000000 --- a/backend/serial.c +++ /dev/null @@ -1,1327 +0,0 @@ -/* - * "$Id: serial.c 9793 2011-05-20 03:49:49Z mike $" - * - * Serial port backend for CUPS. - * - * Copyright 2007-2011 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. - * - * 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" - * "LICENSE" which should have been included with this file. If this - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * main() - Send a file to the printer or server. - * list_devices() - List all serial devices. - * side_cb() - Handle side-channel requests... - */ - -/* - * Include necessary headers. - */ - -#include "backend-private.h" -#include <stdio.h> - -#ifdef __hpux -# include <sys/modem.h> -#endif /* __hpux */ - -#ifdef WIN32 -# include <io.h> -#else -# include <unistd.h> -# include <fcntl.h> -# include <termios.h> -# ifdef __hpux -# include <sys/time.h> -# else -# include <sys/select.h> -# endif /* __hpux */ -# ifdef HAVE_SYS_IOCTL_H -# include <sys/ioctl.h> -# endif /* HAVE_SYS_IOCTL_H */ -#endif /* WIN32 */ - -#ifdef __sgi -# include <invent.h> -# ifndef INV_EPP_ECP_PLP -# define INV_EPP_ECP_PLP 6 /* From 6.3/6.4/6.5 sys/invent.h */ -# define INV_ASO_SERIAL 14 /* serial portion of SGI ASO board */ -# define INV_IOC3_DMA 16 /* DMA mode IOC3 serial */ -# define INV_IOC3_PIO 17 /* PIO mode IOC3 serial */ -# define INV_ISA_DMA 19 /* DMA mode ISA serial -- O2 */ -# endif /* !INV_EPP_ECP_PLP */ -#endif /* __sgi */ - -#ifndef CRTSCTS -# ifdef CNEW_RTSCTS -# define CRTSCTS CNEW_RTSCTS -# else -# define CRTSCTS 0 -# endif /* CNEW_RTSCTS */ -#endif /* !CRTSCTS */ - -#if defined(__APPLE__) -# include <CoreFoundation/CoreFoundation.h> -# include <IOKit/IOKitLib.h> -# include <IOKit/serial/IOSerialKeys.h> -# include <IOKit/IOBSD.h> -#endif /* __APPLE__ */ - -#if defined(__linux) && defined(TIOCGSERIAL) -# include <linux/serial.h> -# include <linux/ioctl.h> -#endif /* __linux && TIOCGSERIAL */ - - -/* - * Local functions... - */ - -static void list_devices(void); -static int side_cb(int print_fd, int device_fd, int use_bc); - - -/* - * 'main()' - Send a file to the printer or server. - * - * Usage: - * - * printer-uri job-id user title copies options [file] - */ - -int /* O - Exit status */ -main(int argc, /* I - Number of command-line arguments (6 or 7) */ - char *argv[]) /* I - Command-line arguments */ -{ - char method[255], /* Method in URI */ - hostname[1024], /* Hostname */ - username[255], /* Username info (not used) */ - resource[1024], /* Resource info (device and options) */ - *options, /* Pointer to options */ - *name, /* Name of option */ - *value, /* Value of option */ - sep; /* Option separator */ - int port; /* Port number (not used) */ - int copies; /* Number of copies to print */ - int side_eof = 0, /* Saw EOF on side-channel? */ - print_fd, /* Print file */ - device_fd; /* Serial device */ - int nfds; /* Maximum file descriptor value + 1 */ - fd_set input, /* Input set for reading */ - output; /* Output set for writing */ - ssize_t print_bytes, /* Print bytes read */ - bc_bytes, /* Backchannel bytes read */ - total_bytes, /* Total bytes written */ - bytes; /* Bytes written */ - int dtrdsr; /* Do dtr/dsr flow control? */ - int print_size; /* Size of output buffer for writes */ - char print_buffer[8192], /* Print data buffer */ - *print_ptr, /* Pointer into print data buffer */ - bc_buffer[1024]; /* Back-channel data buffer */ - struct termios opts; /* Serial port options */ - struct termios origopts; /* Original port options */ -#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); - - /* - * 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 (CUPS_BACKEND_OK); - } - else if (argc < 6 || argc > 7) - { - _cupsLangPrintf(stderr, - _("Usage: %s job-id user title copies options [file]"), - argv[0]); - return (CUPS_BACKEND_FAILED); - } - - /* - * If we have 7 arguments, print the file named on the command-line. - * Otherwise, send stdin instead... - */ - - if (argc == 6) - { - print_fd = 0; - copies = 1; - } - else - { - /* - * Try to open the print file... - */ - - if ((print_fd = open(argv[6], O_RDONLY)) < 0) - { - _cupsLangPrintError("ERROR", _("Unable to open print file")); - return (CUPS_BACKEND_FAILED); - } - - copies = atoi(argv[4]); - } - - /* - * Extract the device name and options from the URI... - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv), - method, sizeof(method), username, sizeof(username), - hostname, sizeof(hostname), &port, - resource, sizeof(resource)); - - /* - * See if there are any options... - */ - - if ((options = strchr(resource, '?')) != NULL) - { - /* - * Yup, terminate the device name string and move to the first - * character of the options... - */ - - *options++ = '\0'; - } - - /* - * Open the serial port device... - */ - - fputs("STATE: +connecting-to-device\n", stderr); - - do - { - if ((device_fd = open(resource, O_RDWR | O_NOCTTY | O_EXCL | - O_NDELAY)) == -1) - { - if (getenv("CLASS") != NULL) - { - /* - * If the CLASS environment variable is set, the job was submitted - * to a class and not to a specific queue. In this case, we want - * to abort immediately so that the job can be requeued on the next - * available printer in the class. - */ - - _cupsLangPrintFilter(stderr, "INFO", - _("Unable to contact printer, queuing on next " - "printer in class.")); - - /* - * Sleep 5 seconds to keep the job from requeuing too rapidly... - */ - - sleep(5); - - return (CUPS_BACKEND_FAILED); - } - - if (errno == EBUSY) - { - _cupsLangPrintFilter(stderr, "INFO", - _("Printer busy; will retry in 30 seconds.")); - sleep(30); - } - else - { - _cupsLangPrintError("ERROR", _("Unable to open device file")); - return (CUPS_BACKEND_FAILED); - } - } - } - while (device_fd < 0); - - fputs("STATE: -connecting-to-device\n", stderr); - - /* - * Set any options provided... - */ - - tcgetattr(device_fd, &origopts); - tcgetattr(device_fd, &opts); - - opts.c_lflag &= ~(ICANON | ECHO | ISIG); - /* Raw mode */ - opts.c_oflag &= ~OPOST; /* Don't post-process */ - - print_size = 96; /* 9600 baud / 10 bits/char / 10Hz */ - dtrdsr = 0; /* No dtr/dsr flow control */ - - if (options) - { - while (*options) - { - /* - * Get the name... - */ - - name = options; - - while (*options && *options != '=' && *options != '+' && *options != '&') - options ++; - - if ((sep = *options) != '\0') - *options++ = '\0'; - - if (sep == '=') - { - /* - * Get the value... - */ - - value = options; - - while (*options && *options != '+' && *options != '&') - options ++; - - if (*options) - *options++ = '\0'; - } - else - value = (char *)""; - - /* - * Process the option... - */ - - if (!_cups_strcasecmp(name, "baud")) - { - /* - * Set the baud rate... - */ - - print_size = atoi(value) / 100; - -#if B19200 == 19200 - cfsetispeed(&opts, atoi(value)); - cfsetospeed(&opts, atoi(value)); -#else - switch (atoi(value)) - { - case 1200 : - cfsetispeed(&opts, B1200); - cfsetospeed(&opts, B1200); - break; - case 2400 : - cfsetispeed(&opts, B2400); - cfsetospeed(&opts, B2400); - break; - case 4800 : - cfsetispeed(&opts, B4800); - cfsetospeed(&opts, B4800); - break; - case 9600 : - cfsetispeed(&opts, B9600); - cfsetospeed(&opts, B9600); - break; - case 19200 : - cfsetispeed(&opts, B19200); - cfsetospeed(&opts, B19200); - break; - case 38400 : - cfsetispeed(&opts, B38400); - cfsetospeed(&opts, B38400); - break; -# ifdef B57600 - case 57600 : - cfsetispeed(&opts, B57600); - cfsetospeed(&opts, B57600); - break; -# endif /* B57600 */ -# ifdef B115200 - case 115200 : - cfsetispeed(&opts, B115200); - cfsetospeed(&opts, B115200); - break; -# endif /* B115200 */ -# ifdef B230400 - case 230400 : - cfsetispeed(&opts, B230400); - cfsetospeed(&opts, B230400); - break; -# endif /* B230400 */ - default : - _cupsLangPrintFilter(stderr, "WARNING", - _("Unsupported baud rate: %s"), value); - break; - } -#endif /* B19200 == 19200 */ - } - else if (!_cups_strcasecmp(name, "bits")) - { - /* - * Set number of data bits... - */ - - switch (atoi(value)) - { - case 7 : - opts.c_cflag &= ~CSIZE; - opts.c_cflag |= CS7; - opts.c_cflag |= PARENB; - opts.c_cflag &= ~PARODD; - break; - case 8 : - opts.c_cflag &= ~CSIZE; - opts.c_cflag |= CS8; - opts.c_cflag &= ~PARENB; - break; - } - } - else if (!_cups_strcasecmp(name, "parity")) - { - /* - * Set parity checking... - */ - - if (!_cups_strcasecmp(value, "even")) - { - opts.c_cflag |= PARENB; - opts.c_cflag &= ~PARODD; - } - else if (!_cups_strcasecmp(value, "odd")) - { - opts.c_cflag |= PARENB; - opts.c_cflag |= PARODD; - } - else if (!_cups_strcasecmp(value, "none")) - opts.c_cflag &= ~PARENB; - else if (!_cups_strcasecmp(value, "space")) - { - /* - * Note: we only support space parity with 7 bits per character... - */ - - opts.c_cflag &= ~CSIZE; - opts.c_cflag |= CS8; - opts.c_cflag &= ~PARENB; - } - else if (!_cups_strcasecmp(value, "mark")) - { - /* - * Note: we only support mark parity with 7 bits per character - * and 1 stop bit... - */ - - opts.c_cflag &= ~CSIZE; - opts.c_cflag |= CS7; - opts.c_cflag &= ~PARENB; - opts.c_cflag |= CSTOPB; - } - } - else if (!_cups_strcasecmp(name, "flow")) - { - /* - * Set flow control... - */ - - if (!_cups_strcasecmp(value, "none")) - { - opts.c_iflag &= ~(IXON | IXOFF); - opts.c_cflag &= ~CRTSCTS; - } - else if (!_cups_strcasecmp(value, "soft")) - { - opts.c_iflag |= IXON | IXOFF; - opts.c_cflag &= ~CRTSCTS; - } - else if (!_cups_strcasecmp(value, "hard") || - !_cups_strcasecmp(value, "rtscts")) - { - opts.c_iflag &= ~(IXON | IXOFF); - opts.c_cflag |= CRTSCTS; - } - else if (!_cups_strcasecmp(value, "dtrdsr")) - { - opts.c_iflag &= ~(IXON | IXOFF); - opts.c_cflag &= ~CRTSCTS; - - dtrdsr = 1; - } - } - else if (!_cups_strcasecmp(name, "stop")) - { - switch (atoi(value)) - { - case 1 : - opts.c_cflag &= ~CSTOPB; - break; - - case 2 : - opts.c_cflag |= CSTOPB; - break; - } - } - } - } - - tcsetattr(device_fd, TCSANOW, &opts); - fcntl(device_fd, F_SETFL, 0); - - /* - * 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 (!print_fd) - { -#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 */ - } - - /* - * Figure out the maximum file descriptor value to use with select()... - */ - - nfds = (print_fd > device_fd ? print_fd : device_fd) + 1; - - /* - * Finally, send the print file. Ordinarily we would just use the - * backendRunLoop() function, however since we need to use smaller - * writes and may need to do DSR/DTR flow control, we duplicate much - * of the code here instead... - */ - - if (print_size > sizeof(print_buffer)) - print_size = sizeof(print_buffer); - - total_bytes = 0; - - while (copies > 0) - { - copies --; - - if (print_fd != 0) - { - fputs("PAGE: 1 1\n", stderr); - lseek(print_fd, 0, SEEK_SET); - } - - /* - * Now loop until we are out of data from print_fd... - */ - - for (print_bytes = 0, print_ptr = print_buffer;;) - { - /* - * Use select() to determine whether we have data to copy around... - */ - - FD_ZERO(&input); - if (!print_bytes) - FD_SET(print_fd, &input); - FD_SET(device_fd, &input); - if (!print_bytes && !side_eof) - FD_SET(CUPS_SC_FD, &input); - - FD_ZERO(&output); - if (print_bytes) - FD_SET(device_fd, &output); - - if (select(nfds, &input, &output, NULL, NULL) < 0) - continue; /* Ignore errors here */ - - /* - * Check if we have a side-channel request ready... - */ - - if (FD_ISSET(CUPS_SC_FD, &input)) - { - /* - * Do the side-channel request, then start back over in the select - * loop since it may have read from print_fd... - */ - - if (side_cb(print_fd, device_fd, 1)) - side_eof = 1; - continue; - } - - /* - * Check if we have back-channel data ready... - */ - - if (FD_ISSET(device_fd, &input)) - { - if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0) - { - fprintf(stderr, - "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data\n", - CUPS_LLCAST bc_bytes); - cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0); - } - } - - /* - * Check if we have print data ready... - */ - - if (FD_ISSET(print_fd, &input)) - { - if ((print_bytes = read(print_fd, print_buffer, print_size)) < 0) - { - /* - * Read error - bail if we don't see EAGAIN or EINTR... - */ - - if (errno != EAGAIN || errno != EINTR) - { - perror("DEBUG: Unable to read print data"); - - tcsetattr(device_fd, TCSADRAIN, &origopts); - - close(device_fd); - - if (print_fd != 0) - close(print_fd); - - return (CUPS_BACKEND_FAILED); - } - - print_bytes = 0; - } - else if (print_bytes == 0) - { - /* - * End of file, break out of the loop... - */ - - break; - } - - print_ptr = print_buffer; - } - - /* - * Check if the device is ready to receive data and we have data to - * send... - */ - - if (print_bytes && FD_ISSET(device_fd, &output)) - { - if (dtrdsr) - { - /* - * Check the port and sleep until DSR is set... - */ - - int status; - - - if (!ioctl(device_fd, TIOCMGET, &status)) - if (!(status & TIOCM_DSR)) - { - /* - * Wait for DSR to go high... - */ - - fputs("DEBUG: DSR is low; waiting for device...\n", stderr); - - do - { - /* - * Poll every 100ms... - */ - - usleep(100000); - - if (ioctl(device_fd, TIOCMGET, &status)) - break; - } - while (!(status & TIOCM_DSR)); - - fputs("DEBUG: DSR is high; writing to device...\n", stderr); - } - } - - if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0) - { - /* - * Write error - bail if we don't see an error we can retry... - */ - - if (errno != EAGAIN && errno != EINTR && errno != ENOTTY) - { - perror("DEBUG: Unable to write print data"); - - tcsetattr(device_fd, TCSADRAIN, &origopts); - - close(device_fd); - - if (print_fd != 0) - close(print_fd); - - return (CUPS_BACKEND_FAILED); - } - } - else - { - fprintf(stderr, "DEBUG: Wrote %d bytes...\n", (int)bytes); - - print_bytes -= bytes; - print_ptr += bytes; - total_bytes += bytes; - } - } - } - } - - /* - * Close the serial port and input file and return... - */ - - tcsetattr(device_fd, TCSADRAIN, &origopts); - - close(device_fd); - - if (print_fd != 0) - close(print_fd); - - return (CUPS_BACKEND_OK); -} - - -/* - * 'list_devices()' - List all serial devices. - */ - -static void -list_devices(void) -{ -#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) - static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz"; - /* Funky hex numbering used for some * - * devices */ -#endif /* __hpux || __sgi || __sun || __FreeBSD__ || __OpenBSD__ || __FreeBSD_kernel__ */ - - -#ifdef __linux - int i, j; /* Looping vars */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - char info[255]; /* Device info/description */ -# ifdef TIOCGSERIAL - struct serial_struct serinfo; /* serial port info */ -# endif /* TIOCGSERIAL */ - - - for (i = 0; i < 100; i ++) - { - sprintf(device, "/dev/ttyS%d", i); - - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { -# ifdef TIOCGSERIAL - /* - * See if this port exists... - */ - - serinfo.reserved_char[0] = 0; - - if (!ioctl(fd, TIOCGSERIAL, &serinfo)) - { - if (serinfo.type == PORT_UNKNOWN) - { - /* - * Nope... - */ - - close(fd); - continue; - } - } -# endif /* TIOCGSERIAL */ - - close(fd); - - snprintf(info, sizeof(info), - _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); - -# if defined(_ARCH_PPC) || defined(powerpc) || defined(__powerpc) - printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info); -# else - printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); -# endif /* _ARCH_PPC || powerpc || __powerpc */ - } - } - - for (i = 0; i < 16; i ++) - { - snprintf(info, sizeof(info), - _cupsLangString(cupsLangDefault(), _("USB Serial Port #%d")), - i + 1); - - sprintf(device, "/dev/usb/ttyUSB%d", i); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info); - } - - sprintf(device, "/dev/ttyUSB%d", i); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info); - } - } - - for (i = 0; i < 64; i ++) - { - for (j = 0; j < 8; j ++) - { - sprintf(device, "/dev/ttyQ%02de%d", i, j); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - - printf("serial serial:%s?baud=115200 \"Unknown\" " - "\"Equinox ESP %d Port #%d\"\n", device, i, j + 1); - } - } - } -#elif defined(__sgi) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - inventory_t *inv; /* Hardware inventory info */ - - - /* - * IRIX maintains a hardware inventory of most devices... - */ - - setinvent(); - - while ((inv = getinvent()) != NULL) - { - if (inv->inv_class == INV_SERIAL) - { - /* - * Some sort of serial port... - */ - - if (inv->inv_type == INV_CDSIO || inv->inv_type == INV_CDSIO_E) - { - /* - * CDSIO port... - */ - - for (n = 0; n < 6; n ++) - printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"CDSIO Board %d Serial Port #%d\"\n", - n + 5 + 8 * inv->inv_controller, inv->inv_controller, n + 1); - } - else if (inv->inv_type == INV_EPC_SERIAL) - { - /* - * Everest serial port... - */ - - if (inv->inv_unit == 0) - i = 1; - else - i = 41 + 4 * (int)inv->inv_controller; - - for (n = 0; n < (int)inv->inv_state; n ++) - printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"EPC Serial Port %d, Ebus slot %d\"\n", - n + i, n + 1, (int)inv->inv_controller); - } - else if (inv->inv_state > 1) - { - /* - * Standard serial port under IRIX 6.4 and earlier... - */ - - for (n = 0; n < (int)inv->inv_state; n ++) - printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"Onboard Serial Port %d\"\n", - n + (int)inv->inv_unit + 1, n + (int)inv->inv_unit + 1); - } - else - { - /* - * Standard serial port under IRIX 6.5 and beyond... - */ - - printf("serial serial:/dev/ttyd%d?baud=115200 \"Unknown\" \"Onboard Serial Port %d\"\n", - (int)inv->inv_controller, (int)inv->inv_controller); - } - } - } - - endinvent(); - - /* - * Central Data makes serial and parallel "servers" that can be - * connected in a number of ways. Look for ports... - */ - - for (i = 0; i < 10; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/ttydn%d%c", j, funky_hex[n]); - else if (i == 9) /* PCI */ - sprintf(device, "/dev/ttydp%d%c", j, funky_hex[n]); - else /* SCSI */ - sprintf(device, "/dev/ttyd%d%d%c", i, j, funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n", - device, j, n); - else if (i == 9) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data PCI Serial Port, ID %d, port %d\"\n", - device, j, n); - else - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__sun) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - char info[255]; /* Device info/description */ - - - /* - * Standard serial ports... - */ - - for (i = 0; i < 26; i ++) - { - sprintf(device, "/dev/cua/%c", 'a' + i); - if (!access(device, 0)) - { - snprintf(info, sizeof(info), - _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); - -# ifdef B115200 - printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); -# else - printf("serial serial:%s?baud=38400 \"Unknown\" \"%s\"\n", device, info); -# endif /* B115200 */ - } - } - - /* - * MAGMA serial ports... - */ - - for (i = 0; i < 40; i ++) - { - sprintf(device, "/dev/term/%02d", i); - if (access(device, 0) == 0) - printf("serial serial:%s?baud=38400 \"Unknown\" \"MAGMA Serial Board #%d Port #%d\"\n", - device, (i / 10) + 1, (i % 10) + 1); - } - - /* - * Central Data serial ports... - */ - - for (i = 0; i < 9; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/sts/ttyN%d%c", j, funky_hex[n]); - else - sprintf(device, "/dev/sts/tty%c%d%c", i + 'C', j, - funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n", - device, j, n); - else - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__hpux) - int i, j, n; /* Looping vars */ - char device[255]; /* Device filename */ - - - /* - * Standard serial ports... - */ - - for (i = 0; i < 10; i ++) - { - sprintf(device, "/dev/tty%dp0", i); - if (access(device, 0) == 0) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n", - device, i + 1); - } - - /* - * Central Data serial ports... - */ - - for (i = 0; i < 9; i ++) - for (j = 0; j < 8; j ++) - for (n = 0; n < 32; n ++) - { - if (i == 8) /* EtherLite */ - sprintf(device, "/dev/ttyN%d%c", j, funky_hex[n]); - else - sprintf(device, "/dev/tty%c%d%c", i + 'C', j, - funky_hex[n]); - - if (access(device, 0) == 0) - { - if (i == 8) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n", - device, j, n); - else - printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n", - device, i, j, n); - } - } -#elif defined(__osf__) - int i; /* Looping var */ - char device[255]; /* Device filename */ - - - /* - * Standard serial ports... - */ - - for (i = 0; i < 100; i ++) - { - sprintf(device, "/dev/tty%02d", i); - if (access(device, 0) == 0) - printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n", - device, i + 1); - } -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) - int i, j; /* Looping vars */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - char info[255]; /* Device info/description */ - - - /* - * SIO ports... - */ - - for (i = 0; i < 32; i ++) - { - sprintf(device, "/dev/ttyd%c", funky_hex[i]); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - - snprintf(info, sizeof(info), - _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); - - printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); - } - } - - /* - * Cyclades ports... - */ - - for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */ - for (j = 0; j < 32; j ++) - { - sprintf(device, "/dev/ttyc%d%c", i, funky_hex[j]); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Port #%d\"\n", - device, i, j + 1); - } - - sprintf(device, "/dev/ttyC%d%c", i, funky_hex[j]); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Port #%d\"\n", - device, i, j + 1); - } - } - - /* - * Digiboard ports... - */ - - for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */ - for (j = 0; j < 32; j ++) - { - sprintf(device, "/dev/ttyD%d%c", i, funky_hex[j]); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"Digiboard #%d Serial Port #%d\"\n", - device, i, j + 1); - } - } - - /* - * Stallion ports... - */ - - for (i = 0; i < 32; i ++) - { - sprintf(device, "/dev/ttyE%c", funky_hex[i]); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"Stallion Serial Port #%d\"\n", - device, i + 1); - } - } - - /* - * SX ports... - */ - - for (i = 0; i < 128; i ++) - { - sprintf(device, "/dev/ttyA%d", i + 1); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"SX Serial Port #%d\"\n", - device, i + 1); - } - } -#elif defined(__NetBSD__) - int i, j; /* Looping vars */ - int fd; /* File descriptor */ - char device[255]; /* Device filename */ - char info[255]; /* Device info/description */ - - - /* - * Standard serial ports... - */ - - for (i = 0; i < 4; i ++) - { - sprintf(device, "/dev/tty%02d", i); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - - snprintf(info, sizeof(info), - _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); - - printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); - } - } - - /* - * Cyclades-Z ports... - */ - - for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */ - for (j = 0; j < 64; j ++) - { - sprintf(device, "/dev/ttyCZ%02d%02d", i, j); - if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) - { - close(fd); - printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Prt #%d\"\n", - device, i, j + 1); - } - } -#elif defined(__APPLE__) - /* - * Standard serial ports on MacOS X... - */ - - kern_return_t kernResult; - mach_port_t masterPort; - io_iterator_t serialPortIterator; - CFMutableDictionaryRef classesToMatch; - io_object_t serialService; - - - kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); - if (KERN_SUCCESS != kernResult) - return; - - /* - * Serial devices are instances of class IOSerialBSDClient. - */ - - classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); - if (classesToMatch != NULL) - { - CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), - CFSTR(kIOSerialBSDRS232Type)); - - kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch, - &serialPortIterator); - if (kernResult == KERN_SUCCESS) - { - while ((serialService = IOIteratorNext(serialPortIterator))) - { - CFTypeRef serialNameAsCFString; - CFTypeRef bsdPathAsCFString; - CFTypeRef hiddenVal; - char serialName[128]; - char bsdPath[1024]; - Boolean result; - - - /* Check if hidden... */ - hiddenVal = IORegistryEntrySearchCFProperty(serialService, - kIOServicePlane, - CFSTR("HiddenPort"), - kCFAllocatorDefault, - kIORegistryIterateRecursively | - kIORegistryIterateParents); - if (hiddenVal) - CFRelease(hiddenVal); /* This interface should not be used */ - else - { - serialNameAsCFString = - IORegistryEntryCreateCFProperty(serialService, - CFSTR(kIOTTYDeviceKey), - kCFAllocatorDefault, 0); - if (serialNameAsCFString) - { - result = CFStringGetCString(serialNameAsCFString, serialName, - sizeof(serialName), - kCFStringEncodingASCII); - CFRelease(serialNameAsCFString); - - if (result) - { - bsdPathAsCFString = - IORegistryEntryCreateCFProperty(serialService, - CFSTR(kIOCalloutDeviceKey), - kCFAllocatorDefault, 0); - if (bsdPathAsCFString) - { - result = CFStringGetCString(bsdPathAsCFString, bsdPath, - sizeof(bsdPath), - kCFStringEncodingASCII); - CFRelease(bsdPathAsCFString); - - if (result) - printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", - bsdPath, serialName); - } - } - } - } - - IOObjectRelease(serialService); - } - - /* - * Release the iterator. - */ - - IOObjectRelease(serialPortIterator); - } - } -#endif -} - - -/* - * 'side_cb()' - Handle side-channel requests... - */ - -static int /* O - 0 on success, -1 on error */ -side_cb(int print_fd, /* I - Print file */ - int device_fd, /* I - Device file */ - int use_bc) /* I - Using back-channel? */ -{ - cups_sc_command_t command; /* Request command */ - cups_sc_status_t status; /* Request/response status */ - char data[2048]; /* Request/response data */ - int datalen; /* Request/response data size */ - - - datalen = sizeof(data); - - if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) - return (-1); - - switch (command) - { - case CUPS_SC_CMD_DRAIN_OUTPUT : - if (backendDrainOutput(print_fd, device_fd)) - status = CUPS_SC_STATUS_IO_ERROR; - else if (tcdrain(device_fd)) - status = CUPS_SC_STATUS_IO_ERROR; - else - status = CUPS_SC_STATUS_OK; - - datalen = 0; - break; - - case CUPS_SC_CMD_GET_BIDI : - status = CUPS_SC_STATUS_OK; - data[0] = use_bc; - datalen = 1; - break; - - default : - status = CUPS_SC_STATUS_NOT_IMPLEMENTED; - datalen = 0; - break; - } - - return (cupsSideChannelWrite(command, status, data, datalen, 1.0)); -} - - -/* - * End of "$Id: serial.c 9793 2011-05-20 03:49:49Z mike $". - */ diff --git a/backend/snmp-supplies.c b/backend/snmp-supplies.c index dc2b3f1a..17128acc 100644 --- a/backend/snmp-supplies.c +++ b/backend/snmp-supplies.c @@ -1,5 +1,5 @@ /* - * "$Id: snmp-supplies.c 10262 2012-02-12 05:48:09Z mike $" + * "$Id: snmp-supplies.c 10493 2012-05-21 22:33:19Z mike $" * * SNMP supplies functions for CUPS. * @@ -36,14 +36,21 @@ #define CUPS_MAX_SUPPLIES 32 /* Maximum number of supplies for a printer */ #define CUPS_SUPPLY_TIMEOUT 2.0 /* Timeout for SNMP lookups */ -#define CUPS_DEVELOPER_LOW 1 -#define CUPS_DEVELOPER_EMPTY 2 -#define CUPS_MARKER_SUPPLY_LOW 4 -#define CUPS_MARKER_SUPPLY_EMPTY 8 -#define CUPS_OPC_NEAR_EOL 16 -#define CUPS_OPC_LIFE_OVER 32 -#define CUPS_TONER_LOW 64 -#define CUPS_TONER_EMPTY 128 +#define CUPS_DEVELOPER_LOW 0x0001 +#define CUPS_DEVELOPER_EMPTY 0x0002 +#define CUPS_MARKER_SUPPLY_LOW 0x0004 +#define CUPS_MARKER_SUPPLY_EMPTY 0x0008 +#define CUPS_OPC_NEAR_EOL 0x0010 +#define CUPS_OPC_LIFE_OVER 0x0020 +#define CUPS_TONER_LOW 0x0040 +#define CUPS_TONER_EMPTY 0x0080 +#define CUPS_WASTE_ALMOST_FULL 0x0100 +#define CUPS_WASTE_FULL 0x0200 +#define CUPS_CLEANER_NEAR_EOL 0x0400 /* Proposed JPS3 */ +#define CUPS_CLEANER_LIFE_OVER 0x0800 /* Proposed JPS3 */ + +#define CUPS_SNMP_NONE 0x0000 +#define CUPS_SNMP_CAPACITY 0x0001 /* Supply levels reported as percentages */ /* @@ -75,6 +82,8 @@ static http_addr_t current_addr; /* Current address */ static int current_state = -1; /* Current device state bits */ static int charset = -1; /* Character set for supply names */ +static unsigned quirks = CUPS_SNMP_NONE; + /* Quirks we have to work around */ static int num_supplies = 0; /* Number of supplies found */ static backend_supplies_t supplies[CUPS_MAX_SUPPLIES]; @@ -146,10 +155,17 @@ static const int prtMarkerSuppliesType[] = (sizeof(prtMarkerSuppliesType) / sizeof(prtMarkerSuppliesType[0])); /* Offset to supply index */ +static const int prtMarkerSuppliesSupplyUnit[] = + { CUPS_OID_prtMarkerSuppliesSupplyUnit, -1 }, + /* Units OID */ + prtMarkerSuppliesSupplyUnitOffset = + (sizeof(prtMarkerSuppliesSupplyUnit) / + sizeof(prtMarkerSuppliesSupplyUnit[0])); + /* Offset to supply index */ static const backend_state_t const printer_states[] = { - { CUPS_TC_lowPaper, "media-low-report" }, + /* { CUPS_TC_lowPaper, "media-low-report" }, */ { CUPS_TC_noPaper | CUPS_TC_inputTrayEmpty, "media-empty-warning" }, /* { CUPS_TC_lowToner, "toner-low-report" }, */ /* now use prtMarkerSupplies */ /* { CUPS_TC_noToner, "toner-empty-warning" }, */ /* now use prtMarkerSupplies */ @@ -173,7 +189,11 @@ static const backend_state_t const supply_states[] = { CUPS_OPC_NEAR_EOL, "opc-near-eol-report" }, { CUPS_OPC_LIFE_OVER, "opc-life-over-warning" }, { CUPS_TONER_LOW, "toner-low-report" }, - { CUPS_TONER_EMPTY, "toner-empty-warning" } + { CUPS_TONER_EMPTY, "toner-empty-warning" }, + { CUPS_WASTE_ALMOST_FULL, "waste-receptacle-almost-full-report" }, + { CUPS_WASTE_FULL, "waste-receptacle-full-warning" }, + { CUPS_CLEANER_NEAR_EOL, "cleaner-life-almost-over-report" }, + { CUPS_CLEANER_LIFE_OVER, "cleaner-life-over-warning" }, }; @@ -231,6 +251,9 @@ backendSNMPSupplies( { if (supplies[i].max_capacity > 0 && supplies[i].level >= 0) percent = 100 * supplies[i].level / supplies[i].max_capacity; + else if (supplies[i].level >= 0 && supplies[i].level <= 100 && + (quirks & CUPS_SNMP_CAPACITY)) + percent = supplies[i].level; else percent = 50; @@ -245,9 +268,6 @@ backendSNMPSupplies( else new_supply_state |= CUPS_TONER_LOW; break; - case CUPS_TC_wasteToner : - case CUPS_TC_wasteInk : - break; case CUPS_TC_ink : case CUPS_TC_inkCartridge : case CUPS_TC_inkRibbon : @@ -273,13 +293,31 @@ backendSNMPSupplies( else new_supply_state |= CUPS_OPC_NEAR_EOL; break; + case CUPS_TC_wasteInk : + case CUPS_TC_wastePaper : + case CUPS_TC_wasteToner : + case CUPS_TC_wasteWater : + case CUPS_TC_wasteWax : + if (percent <= 1) + new_supply_state |= CUPS_WASTE_FULL; + else + new_supply_state |= CUPS_WASTE_ALMOST_FULL; + break; + case CUPS_TC_cleanerUnit : + case CUPS_TC_fuserCleaningPad : + if (percent <= 1) + new_supply_state |= CUPS_CLEANER_LIFE_OVER; + else + new_supply_state |= CUPS_CLEANER_NEAR_EOL; + break; } } if (i) *ptr++ = ','; - if (supplies[i].max_capacity > 0 && supplies[i].level >= 0) + if ((supplies[i].max_capacity > 0 || (quirks & CUPS_SNMP_CAPACITY)) && + supplies[i].level >= 0) sprintf(ptr, "%d", percent); else strcpy(ptr, "-1"); @@ -477,6 +515,12 @@ backend_init_supplies( return; } + if ((ppdattr = ppdFindAttr(ppd, "cupsSNMPQuirks", NULL)) != NULL) + { + if (!_cups_strcasecmp(ppdattr->value, "capacity")) + quirks |= CUPS_SNMP_CAPACITY; + } + ppdClose(ppd); /* @@ -903,7 +947,8 @@ backend_walk_cb(cups_snmp_t *packet, /* I - SNMP packet */ supplies[i - 1].level = packet->object_value.integer; } - else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesMaxCapacity)) + else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesMaxCapacity) && + !(quirks & CUPS_SNMP_CAPACITY)) { /* * Get max capacity... @@ -920,7 +965,9 @@ backend_walk_cb(cups_snmp_t *packet, /* I - SNMP packet */ if (i > num_supplies) num_supplies = i; - supplies[i - 1].max_capacity = packet->object_value.integer; + if (supplies[i - 1].max_capacity == 0 && + packet->object_value.integer > 0) + supplies[i - 1].max_capacity = packet->object_value.integer; } else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesType)) { @@ -941,6 +988,26 @@ backend_walk_cb(cups_snmp_t *packet, /* I - SNMP packet */ supplies[i - 1].type = packet->object_value.integer; } + else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesSupplyUnit)) + { + /* + * Get units for capacity... + */ + + i = packet->object_name[prtMarkerSuppliesSupplyUnitOffset]; + if (i < 1 || i > CUPS_MAX_SUPPLIES || + packet->object_type != CUPS_ASN1_INTEGER) + return; + + fprintf(stderr, "DEBUG2: prtMarkerSuppliesSupplyUnit.1.%d = %d\n", i, + packet->object_value.integer); + + if (i > num_supplies) + num_supplies = i; + + if (packet->object_value.integer == CUPS_TC_percent) + supplies[i - 1].max_capacity = 100; + } } @@ -1006,5 +1073,5 @@ utf16_to_utf8( /* - * End of "$Id: snmp-supplies.c 10262 2012-02-12 05:48:09Z mike $". + * End of "$Id: snmp-supplies.c 10493 2012-05-21 22:33:19Z mike $". */ diff --git a/backend/snmp.c b/backend/snmp.c index fbd236a1..ca3a24fe 100644 --- a/backend/snmp.c +++ b/backend/snmp.c @@ -1,5 +1,5 @@ /* - * "$Id: snmp.c 10209 2012-01-30 22:19:03Z mike $" + * "$Id: snmp.c 10535 2012-06-22 03:45:53Z mike $" * * SNMP discovery backend for CUPS. * @@ -251,7 +251,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ #ifdef AF_INET6 if ((ipv6 = _cupsSNMPOpen(AF_INET6)) < 0) - return (1); + perror("DEBUG: Unable to create IPv6 socket"); #else ipv6 = -1; #endif /* AF_INET6 */ @@ -1383,5 +1383,5 @@ update_cache(snmp_cache_t *device, /* I - Device */ /* - * End of "$Id: snmp.c 10209 2012-01-30 22:19:03Z mike $". + * End of "$Id: snmp.c 10535 2012-06-22 03:45:53Z mike $". */ diff --git a/backend/socket.c b/backend/socket.c index 5e28fc89..cde27b51 100644 --- a/backend/socket.c +++ b/backend/socket.c @@ -1,9 +1,9 @@ /* - * "$Id: socket.c 9793 2011-05-20 03:49:49Z mike $" + * "$Id: socket.c 10431 2012-04-23 19:19:19Z mike $" * * AppSocket backend for CUPS. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -371,7 +371,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ case ECONNREFUSED : default : _cupsLangPrintFilter(stderr, "WARNING", - _("The printer is busy.")); + _("The printer is in use.")); break; } @@ -472,8 +472,6 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ if (print_fd != 0) close(print_fd); - _cupsLangPrintFilter(stderr, "INFO", _("Ready to print.")); - return (CUPS_BACKEND_OK); } @@ -523,5 +521,5 @@ wait_bc(int device_fd, /* I - Socket */ /* - * End of "$Id: socket.c 9793 2011-05-20 03:49:49Z mike $". + * End of "$Id: socket.c 10431 2012-04-23 19:19:19Z mike $". */ diff --git a/backend/testbackend.c b/backend/testbackend.c index 682b8aa2..ad260701 100644 --- a/backend/testbackend.c +++ b/backend/testbackend.c @@ -1,9 +1,9 @@ /* - * "$Id: testbackend.c 9042 2010-03-24 00:45:34Z mike $" + * "$Id: testbackend.c 10389 2012-03-28 21:57:29Z mike $" * * Backend test program for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2005 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -47,7 +47,7 @@ static int job_canceled = 0; */ static void sigterm_handler(int sig); -static void usage(void); +static void usage(void) __attribute__((noreturn)); static void walk_cb(const char *oid, const char *data, int datalen, void *context); @@ -57,7 +57,7 @@ static void walk_cb(const char *oid, const char *data, int datalen, * * Usage: * - * betest [-s] [-t] device-uri job-id user title copies options [file] + * testbackend [-s] [-t] device-uri job-id user title copies options [file] */ int /* O - Exit status */ @@ -75,7 +75,9 @@ main(int argc, /* I - Number of command-line args */ const char *oid = ".1.3.6.1.2.1.43.10.2.1.4.1.1"; /* OID to lookup or walk */ char scheme[255], /* Scheme in URI == backend */ - backend[1024]; /* Backend path */ + backend[1024], /* Backend path */ + libpath[1024], /* Path for libcups */ + *ptr; /* Pointer into path */ const char *serverbin; /* CUPS_SERVERBIN environment variable */ int fd, /* Temporary file descriptor */ back_fds[2], /* Back-channel pipe */ @@ -88,6 +90,29 @@ main(int argc, /* I - Number of command-line args */ /* + * Get the current directory and point the run-time linker at the "cups" + * subdirectory... + */ + + if (getcwd(libpath, sizeof(libpath)) && + (ptr = strrchr(libpath, '/')) != NULL && !strcmp(ptr, "/backend")) + { + strlcpy(ptr, "/cups", sizeof(libpath) - (ptr - libpath)); + if (!access(libpath, 0)) + { +#ifdef __APPLE__ + fprintf(stderr, "Setting DYLD_LIBRARY_PATH to \"%s\".\n", libpath); + setenv("DYLD_LIBRARY_PATH", libpath, 1); +#else + fprintf(stderr, "Setting LD_LIBRARY_PATH to \"%s\".\n", libpath); + setenv("LD_LIBRARY_PATH", libpath, 1); +#endif /* __APPLE__ */ + } + else + perror(libpath); + } + + /* * See if we have side-channel tests to do... */ @@ -548,13 +573,13 @@ main(int argc, /* I - Number of command-line args */ length = sizeof(buffer); scstatus = cupsSideChannelSNMPGet(oid, buffer, &length, 5.0); - printf("CUPS_SC_CMD_SNMP_GET %s returned %s, %s\n", oid, - statuses[scstatus], buffer); + printf("CUPS_SC_CMD_SNMP_GET %s returned %s, %d bytes (%s)\n", oid, + statuses[scstatus], (int)length, buffer); length = sizeof(buffer); scstatus = cupsSideChannelSNMPGet(oid, buffer, &length, 5.0); - printf("CUPS_SC_CMD_SNMP_GET %s returned %s, %s\n", oid, - statuses[scstatus], buffer); + printf("CUPS_SC_CMD_SNMP_GET %s returned %s, %d bytes (%s)\n", oid, + statuses[scstatus], (int)length, buffer); } length = 0; @@ -569,7 +594,7 @@ main(int argc, /* I - Number of command-line args */ kill(data_pid, SIGTERM); kill(back_pid, SIGTERM); } - + while ((pid = wait(&status)) > 0) { if (status) @@ -613,13 +638,13 @@ sigterm_handler(int sig) /* I - Signal */ static void usage(void) { - puts("Usage: testbackend [-cancel] [-d] [-ps | -pcl] [-s [-oid OID] " + puts("Usage: testbackend [-cancel] [-d] [-ps | -pcl] [-s [-get OID] " "[-walk OID]] [-t] device-uri job-id user title copies options [file]"); puts(""); puts("Options:"); puts(" -cancel Simulate a canceled print job after 2 seconds."); puts(" -d Show log messages from backend."); - puts(" -oid OID Lookup the specified SNMP OID."); + puts(" -get OID Lookup the specified SNMP OID."); puts(" (.1.3.6.1.2.1.43.10.2.1.4.1.1 is a good one for printers)"); puts(" -pcl Send PCL+PJL query and test page to backend."); puts(" -ps Send PostScript query and test page to backend."); @@ -642,10 +667,10 @@ walk_cb(const char *oid, /* I - OID */ int datalen, /* I - Length of data */ void *context) /* I - Context (unused) */ { - printf("CUPS_SC_CMD_SNMP_WALK %s=%s (%d bytes)\n", oid, data, datalen); + printf("CUPS_SC_CMD_SNMP_WALK %s, %d bytes (%s)\n", oid, datalen, data); } /* - * End of "$Id: testbackend.c 9042 2010-03-24 00:45:34Z mike $". + * End of "$Id: testbackend.c 10389 2012-03-28 21:57:29Z mike $". */ diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c index 8b249a9f..fe2ec9f6 100644 --- a/backend/usb-darwin.c +++ b/backend/usb-darwin.c @@ -1,7 +1,7 @@ /* -* "$Id: usb-darwin.c 9887 2011-08-11 22:04:59Z mike $" +* "$Id: usb-darwin.c 10431 2012-04-23 19:19:19Z mike $" * -* Copyright 2005-2011 Apple Inc. All rights reserved. +* Copyright 2005-2012 Apple Inc. All rights reserved. * * IMPORTANT: This Apple software is supplied to you by Apple Computer, * Inc. ("Apple") in consideration of your agreement to the following @@ -820,10 +820,10 @@ print_device(const char *uri, /* I - Device URI */ /* * If it didn't exit abort the pending read and wait an additional second... */ - + if (!g.read_thread_done) { - fputs("DEBUG: Read thread still active, aborting the pending read...\n", + fputs("DEBUG: Read thread still active, aborting the pending read...\n", stderr); g.wait_eof = 0; @@ -833,7 +833,7 @@ print_device(const char *uri, /* I - Device URI */ gettimeofday(&tv, NULL); cond_timeout.tv_sec = tv.tv_sec + 1; cond_timeout.tv_nsec = tv.tv_usec * 1000; - + while (!g.read_thread_done) { if (pthread_cond_timedwait(&g.read_thread_cond, &g.read_thread_mutex, @@ -1283,7 +1283,7 @@ static Boolean find_device_cb(void *refcon, if (!keepLooking && g.status_timer != NULL) { fputs("STATE: -offline-report\n", stderr); - _cupsLangPrintFilter(stderr, "INFO", _("Printer is now online.")); + _cupsLangPrintFilter(stderr, "INFO", _("The printer is now online.")); CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), g.status_timer, kCFRunLoopDefaultMode); CFRelease(g.status_timer); g.status_timer = NULL; @@ -1304,7 +1304,7 @@ static void status_timer_cb(CFRunLoopTimerRef timer, (void)info; fputs("STATE: +offline-report\n", stderr); - _cupsLangPrintFilter(stderr, "INFO", _("Printer is offline.")); + _cupsLangPrintFilter(stderr, "INFO", _("The printer is offline.")); if (getenv("CLASS") != NULL) { @@ -2265,5 +2265,5 @@ static void get_device_id(cups_sc_status_t *status, /* - * End of "$Id: usb-darwin.c 9887 2011-08-11 22:04:59Z mike $". + * End of "$Id: usb-darwin.c 10431 2012-04-23 19:19:19Z mike $". */ diff --git a/backend/usb-libusb.c b/backend/usb-libusb.c index b9e40b25..542a07c4 100644 --- a/backend/usb-libusb.c +++ b/backend/usb-libusb.c @@ -1,5 +1,5 @@ /* - * "$Id: usb-libusb.c 10545 2012-07-16 17:16:46Z mike $" + * "$Id: usb-libusb.c 10543 2012-07-16 17:10:55Z mike $" * * LIBUSB interface code for CUPS. * @@ -13,7 +13,7 @@ * * Contents: * - * list_devices() - List the available printers. + * list_devices() - List the available printers. * print_device() - Print a file to a USB device. * close_device() - Close the connection to the USB printer. * find_device() - Find or enumerate USB printers. @@ -1144,7 +1144,7 @@ make_device_uri( if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL) if ((sern = cupsGetOption("SERN", num_values, values)) == NULL) if ((sern = cupsGetOption("SN", num_values, values)) == NULL && - ((libusb_get_device_descriptor (printer->device, &devdesc) >= 0) && + ((libusb_get_device_descriptor(printer->device, &devdesc) >= 0) && devdesc.iSerialNumber)) { /* @@ -1881,6 +1881,6 @@ static void soft_reset(void) /* - * End of "$Id: usb-libusb.c 10545 2012-07-16 17:16:46Z mike $". + * End of "$Id: usb-libusb.c 10543 2012-07-16 17:10:55Z mike $". */ diff --git a/backend/usb-unix.c b/backend/usb-unix.c index 1c280332..ea23c396 100644 --- a/backend/usb-unix.c +++ b/backend/usb-unix.c @@ -1,11 +1,11 @@ /* - * "$Id: usb-unix.c 9793 2011-05-20 03:49:49Z mike $" + * "$Id: usb-unix.c 10431 2012-04-23 19:19:19Z mike $" * * USB port backend for CUPS. * * This file is included from "usb.c" when compiled on UNIX/Linux. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -128,16 +128,12 @@ print_device(const char *uri, /* I - Device URI */ if (errno == EBUSY) { - _cupsLangPrintFilter(stderr, "INFO", - _("Printer busy, will retry in 10 seconds.")); + _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use.")); sleep(10); } else if (errno == ENXIO || errno == EIO || errno == ENOENT || errno == ENODEV) { - _cupsLangPrintFilter(stderr, "INFO", - _("Printer not connected, will retry in 30 " - "seconds.")); sleep(30); } else @@ -425,8 +421,7 @@ open_device(const char *uri, /* I - Device URI */ */ if (busy) - _cupsLangPrintFilter(stderr, "INFO", - _("Printer is busy, will retry in 5 seconds.")); + _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use.")); sleep(5); } @@ -509,8 +504,7 @@ open_device(const char *uri, /* I - Device URI */ if (busy) { - _cupsLangPrintFilter(stderr, "INFO", - _("Printer is busy, will retry in 5 seconds.")); + _cupsLangPrintFilter(stderr, "INFO", _("The printer is in use.")); sleep(5); } } @@ -619,5 +613,5 @@ side_cb(int print_fd, /* I - Print file */ /* - * End of "$Id: usb-unix.c 9793 2011-05-20 03:49:49Z mike $". + * End of "$Id: usb-unix.c 10431 2012-04-23 19:19:19Z mike $". */ diff --git a/backend/usb.c b/backend/usb.c index 2cacb744..1cacb82a 100644 --- a/backend/usb.c +++ b/backend/usb.c @@ -1,5 +1,5 @@ /* - * "$Id: usb.c 10265 2012-02-12 07:20:10Z mike $" + * "$Id: usb.c 10264 2012-02-12 07:18:31Z mike $" * * USB port backend for CUPS. * @@ -260,5 +260,5 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ /* - * End of "$Id: usb.c 10265 2012-02-12 07:20:10Z mike $". + * End of "$Id: usb.c 10264 2012-02-12 07:18:31Z mike $". */ |