From f7deaa1a21758ec90bf23314af018481ea8aea7f Mon Sep 17 00:00:00 2001 From: jlovell Date: Wed, 14 Mar 2007 16:55:44 +0000 Subject: [PATCH] Load cups into easysw/current. git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@279 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES-1.2.txt | 1088 +++++++ CHANGES.txt | 1138 +------ INSTALL.txt | 4 +- LICENSE.txt | 36 + Makedefs.in | 17 +- Makefile | 55 +- README.txt | 4 +- backend/Dependencies | 42 +- backend/Makefile | 4 +- backend/backend-private.h | 11 +- backend/easysw-firewire-design.txt | 71 + backend/easysw-firewire-linux.txt | 35 + backend/ieee1284.c | 112 +- backend/ieee1394-linux.c | 877 +++++ backend/ieee1394.c | 267 ++ backend/ieee1394.h | 103 + backend/ipp.c | 9 +- backend/lpd.c | 4 +- backend/pap.c | 2 +- backend/parallel.c | 79 +- backend/runloop.c | 25 +- backend/scsi.c | 4 +- backend/serial.c | 69 +- backend/snmp.c | 4 +- backend/socket.c | 67 +- backend/test1284.c | 4 +- backend/usb-darwin.c | 332 +- backend/usb-unix.c | 89 +- backend/usb.c | 4 +- berkeley/Dependencies | 22 +- berkeley/lpc.c | 4 +- berkeley/lpq.c | 4 +- berkeley/lpr.c | 4 +- berkeley/lprm.c | 4 +- cgi-bin/Dependencies | 83 +- cgi-bin/Makefile | 10 +- cgi-bin/admin.c | 294 +- cgi-bin/classes.c | 4 +- cgi-bin/help-index.c | 478 ++- cgi-bin/help-index.h | 17 +- cgi-bin/html.c | 4 +- cgi-bin/ipp-var.c | 144 +- cgi-bin/jobs.c | 18 +- cgi-bin/printers.c | 4 +- cgi-bin/search.c | 4 +- cgi-bin/template.c | 4 +- cgi-bin/testhi.c | 14 +- cgi-bin/testhi.html | 2 + cgi-bin/var.c | 4 +- conf/cupsd.conf.in | 7 +- conf/mime.types | 13 +- config-scripts/cups-common.m4 | 25 +- config-scripts/cups-compiler.m4 | 18 +- config-scripts/cups-defaults.m4 | 54 +- config-scripts/cups-directories.m4 | 103 +- config-scripts/cups-dnssd.m4 | 47 + config-scripts/cups-gssapi.m4 | 105 + config-scripts/cups-image.m4 | 4 +- config-scripts/cups-largefile.m4 | 8 +- config-scripts/cups-ldap.m4 | 4 +- config-scripts/cups-manpages.m4 | 4 +- config-scripts/cups-network.m4 | 6 +- config-scripts/cups-opsys.m4 | 4 +- config-scripts/cups-poll.m4 | 31 + config-scripts/cups-sharedlibs.m4 | 4 +- config-scripts/cups-ssl.m4 | 4 +- config-scripts/cups-threads.m4 | 4 +- config.h.in | 58 +- configure.in | 9 +- cups-config.in | 8 +- cups/Dependencies | 87 +- cups/Makefile | 41 +- cups/adminutil.c | 51 +- cups/adminutil.h | 7 +- cups/api-filter.shtml | 175 +- cups/array.c | 84 +- cups/array.h | 6 +- cups/attr.c | 4 +- cups/auth.c | 384 ++- cups/backchannel.c | 4 +- cups/cups.h | 19 +- cups/dest.c | 243 +- cups/emit.c | 15 +- cups/encode.c | 7 +- cups/file.c | 27 +- cups/file.h | 4 +- cups/getifaddrs.c | 4 +- cups/getputfile.c | 6 +- cups/globals.c | 11 +- cups/globals.h | 15 +- cups/http-addrlist.c | 4 +- cups/http-private.h | 81 +- cups/http-support.c | 6 +- cups/http.c | 164 +- cups/http.h | 64 +- cups/i18n.h | 4 +- cups/ipp-private.h | 4 +- cups/ipp-support.c | 4 +- cups/ipp.c | 4 +- cups/ipp.h | 4 +- cups/langprintf.c | 4 +- cups/language.c | 4 +- cups/localize.c | 4 +- cups/mark.c | 4 +- cups/md5passwd.c | 6 +- cups/notify.c | 4 +- cups/options.c | 29 +- cups/page.c | 4 +- cups/ppd.c | 4 +- cups/request.c | 19 +- cups/sidechannel.c | 340 ++ cups/sidechannel.h | 115 + cups/snprintf.c | 4 +- cups/string.c | 4 +- cups/tempfile.c | 4 +- cups/testfile.c | 4 +- cups/testhttp.c | 4 +- cups/testi18n.c | 4 +- cups/testipp.c | 4 +- cups/testppd.c | 4 +- cups/transcode.c | 4 +- cups/usersys.c | 4 +- cups/util.c | 4 +- data/testprint.ps | 15 +- doc/Makefile | 3 +- doc/cups.css | 8 + doc/fr/index.html.in | 139 - doc/help/api-array.html | 42 + doc/help/api-cups.html | 59 + doc/help/api-filter.html | 280 +- doc/help/api-httpipp.html | 3 +- doc/help/api-raster.html | 144 +- doc/help/license.html | 42 + doc/help/ref-client-conf.html | 10 +- doc/help/ref-cupsd-conf.html | 27 +- doc/help/spec-ipp.html | 170 +- doc/help/spec-pdf.html | 21 + doc/help/spec-postscript.html | 120 + doc/help/spec-ppd.html | 47 +- doc/help/standard.html.in | 4 + doc/help/translation.html | 20 + doc/help/whatsnew.html | 510 +-- doc/images/button-add-rss-subscription.gif | Bin 0 -> 717 bytes doc/images/button-cancel-subscription.gif | Bin 0 -> 663 bytes doc/pl/images/button-accept-jobs.gif | Bin 627 -> 691 bytes doc/pl/images/button-add-class.gif | Bin 536 -> 528 bytes doc/pl/images/button-add-printer.gif | Bin 571 -> 579 bytes doc/pl/images/button-add-this-printer.gif | Bin 608 -> 648 bytes doc/pl/images/button-cancel-all-jobs.gif | Bin 797 -> 768 bytes doc/pl/images/button-cancel-job.gif | Bin 531 -> 524 bytes doc/pl/images/button-change-settings.gif | Bin 580 -> 624 bytes doc/pl/images/button-clean-print-heads.gif | Bin 878 -> 943 bytes doc/pl/images/button-clear.gif | Bin 469 -> 480 bytes doc/pl/images/button-continue.gif | Bin 339 -> 447 bytes doc/pl/images/button-delete-class.gif | Bin 463 -> 477 bytes doc/pl/images/button-delete-printer.gif | Bin 513 -> 533 bytes .../images/button-edit-configuration-file.gif | Bin 673 -> 734 bytes doc/pl/images/button-export-samba.gif | Bin 657 -> 977 bytes doc/pl/images/button-help.gif | Bin 363 -> 380 bytes doc/pl/images/button-hold-job.gif | Bin 649 -> 709 bytes doc/pl/images/button-manage-classes.gif | Bin 605 -> 640 bytes doc/pl/images/button-manage-jobs.gif | Bin 697 -> 669 bytes doc/pl/images/button-manage-printers.gif | Bin 643 -> 717 bytes doc/pl/images/button-manage-server.gif | Bin 669 -> 689 bytes doc/pl/images/button-modify-class.gif | Bin 592 -> 647 bytes doc/pl/images/button-modify-printer.gif | Bin 659 -> 702 bytes doc/pl/images/button-move-job.gif | Bin 608 -> 604 bytes doc/pl/images/button-move-jobs.gif | Bin 843 -> 837 bytes doc/pl/images/button-print-self-test-page.gif | Bin 711 -> 1074 bytes doc/pl/images/button-print-test-page.gif | Bin 709 -> 788 bytes doc/pl/images/button-publish-printer.gif | Bin 579 -> 662 bytes doc/pl/images/button-reject-jobs.gif | Bin 638 -> 582 bytes doc/pl/images/button-release-job.gif | Bin 613 -> 605 bytes doc/pl/images/button-restart-job.gif | Bin 653 -> 827 bytes doc/pl/images/button-save-changes.gif | Bin 536 -> 565 bytes doc/pl/images/button-search.gif | Bin 381 -> 505 bytes doc/pl/images/button-set-allowed-users.gif | Bin 909 -> 985 bytes doc/pl/images/button-set-as-default.gif | Bin 706 -> 729 bytes doc/pl/images/button-set-printer-options.gif | Bin 691 -> 709 bytes doc/pl/images/button-show-active.gif | Bin 764 -> 866 bytes doc/pl/images/button-show-all.gif | Bin 813 -> 891 bytes doc/pl/images/button-show-completed.gif | Bin 809 -> 923 bytes doc/pl/images/button-show-next.gif | Bin 605 -> 702 bytes doc/pl/images/button-show-previous.gif | Bin 568 -> 742 bytes doc/pl/images/button-sort-ascending.gif | Bin 648 -> 576 bytes doc/pl/images/button-sort-descending.gif | Bin 673 -> 627 bytes doc/pl/images/button-start-class.gif | Bin 544 -> 579 bytes doc/pl/images/button-start-printer.gif | Bin 606 -> 636 bytes doc/pl/images/button-stop-class.gif | Bin 573 -> 624 bytes doc/pl/images/button-stop-printer.gif | Bin 638 -> 696 bytes doc/pl/images/button-unpublish-printer.gif | Bin 613 -> 694 bytes doc/pl/images/button-use-default-config.gif | Bin 930 -> 1007 bytes doc/pl/images/button-view-access-log.gif | Bin 711 -> 888 bytes doc/pl/images/button-view-error-log.gif | Bin 717 -> 893 bytes doc/pl/images/button-view-page-log.gif | Bin 793 -> 812 bytes .../images/button-view-printable-version.gif | Bin 819 -> 939 bytes filter/Dependencies | 840 +++-- filter/Makefile | 16 +- filter/common.c | 4 +- filter/common.h | 4 +- filter/error.c | 297 ++ filter/hpgl-prolog.c | 4 +- filter/image-bmp.c | 4 +- filter/image-colorspace.c | 4 +- filter/image-gif.c | 4 +- filter/image-jpeg.c | 4 +- filter/image-photocd.c | 4 +- filter/image-pix.c | 4 +- filter/image-png.c | 4 +- filter/image-pnm.c | 4 +- filter/image-private.h | 7 +- filter/image-sgi.c | 4 +- filter/image-sun.c | 4 +- filter/image-tiff.c | 4 +- filter/imagetops.c | 4 +- filter/imagetoraster.c | 4 +- filter/interpret.c | 146 +- filter/pstops.c | 17 +- filter/raster.c | 253 +- filter/raster.h | 10 +- filter/rasterbench.c | 4 +- filter/rastertolabel.c | 308 +- filter/testraster.c | 193 +- filter/texttops.c | 10 +- init/cups.sh.in | 30 +- init/org.cups.cupsd.plist | 12 +- locale/Makefile | 6 +- locale/cups.pot | 9 +- locale/cups_de.po | 15 +- locale/cups_es.po | 12 +- locale/cups_et.po | 15 +- locale/cups_fr.po | 2845 ----------------- locale/cups_it.po | 15 +- locale/cups_pl.po | 15 +- locale/cups_sv.po | 15 +- man/Makefile | 4 +- man/classes.conf.man | 4 +- man/cupsaddsmb.man.in | 4 +- man/cupsd.conf.man.in | 14 +- man/lpadmin.man | 4 +- man/printers.conf.man | 4 +- monitor/Dependencies | 8 +- notifier/Dependencies | 10 +- notifier/Makefile | 22 +- notifier/rss.c | 705 ++++ notifier/testnotify.c | 4 +- packaging/WELCOME.rtf | 2 +- packaging/cups.list.in | 8 +- packaging/cups.readme | 170 +- packaging/cups.spec.in | 7 +- pdftops/Dependencies | 4 +- pdftops/pdftops.cxx | 17 +- ppd/intelbar.ppd | 235 ++ ppd/zebra.ppd | 4 +- scheduler/Dependencies | 30 +- scheduler/Makefile | 20 +- scheduler/auth.c | 378 ++- scheduler/auth.h | 5 +- scheduler/banners.c | 4 +- scheduler/classes.c | 72 +- scheduler/client.c | 756 +++-- scheduler/client.h | 23 +- scheduler/conf.c | 69 +- scheduler/conf.h | 53 +- scheduler/cups-driverd.c | 4 +- scheduler/cups-lpd.c | 14 +- scheduler/cups-polld.c | 4 +- scheduler/cupsd.h | 27 +- scheduler/dirsvc.c | 698 +++- scheduler/dirsvc.h | 14 +- scheduler/filter.c | 61 +- scheduler/ipp.c | 789 +++-- scheduler/job.c | 156 +- scheduler/job.h | 8 +- scheduler/listen.c | 21 +- scheduler/log.c | 88 +- scheduler/main.c | 640 ++-- scheduler/mime.c | 4 +- scheduler/mime.h | 8 +- scheduler/network.c | 4 +- scheduler/network.h | 4 +- scheduler/policy.c | 4 +- scheduler/printers.c | 401 ++- scheduler/printers.h | 55 +- scheduler/process.c | 15 +- scheduler/quotas.c | 4 +- scheduler/select.c | 946 ++++++ scheduler/server.c | 15 +- scheduler/statbuf.c | 4 +- scheduler/subscriptions.c | 30 +- scheduler/subscriptions.h | 4 +- scheduler/sysman.c | 26 +- scheduler/testlpd.c | 17 +- scheduler/testmime.c | 4 +- scheduler/testsub.c | 4 +- .../src/com/easysw/cups/IPPBase64Encoder.java | 0 scripting/php/Dependencies | 6 +- standards/papi-1.0.pdf | Bin 0 -> 503784 bytes systemv/Dependencies | 68 +- systemv/Makefile | 4 +- systemv/accept.c | 4 +- systemv/cancel.c | 4 +- systemv/cupsaddsmb.c | 4 +- systemv/cupstestdsc.c | 4 +- systemv/cupstestppd.c | 163 +- systemv/lp.c | 4 +- systemv/lpadmin.c | 4 +- systemv/lpinfo.c | 4 +- systemv/lpmove.c | 4 +- systemv/lpoptions.c | 4 +- systemv/lppasswd.c | 4 +- systemv/lpstat.c | 5 +- templates/Makefile | 4 +- templates/add-printer.tmpl | 7 +- templates/add-rss-subscription.tmpl | 43 + templates/admin.tmpl | 18 +- templates/classes.tmpl | 16 +- templates/de/add-printer.tmpl | 7 +- templates/de/admin.tmpl | 5 +- templates/de/edit-config.tmpl.in | 3 +- templates/edit-config.tmpl.in | 3 +- templates/es/add-printer.tmpl | 7 +- templates/es/admin.tmpl | 5 +- templates/es/edit-config.tmpl.in | 3 +- templates/et/add-printer.tmpl | 7 +- templates/et/admin.tmpl | 5 +- templates/et/edit-config.tmpl.in | 3 +- templates/fr/add-class.tmpl | 33 - templates/fr/add-printer.tmpl | 35 +- templates/fr/admin.tmpl | 88 +- templates/fr/choose-device.tmpl | 26 - templates/fr/choose-make.tmpl | 42 - templates/fr/choose-model.tmpl | 34 - templates/fr/choose-serial.tmpl | 47 - templates/fr/choose-uri.tmpl | 42 - templates/fr/class-added.tmpl | 1 - templates/fr/class-confirm.tmpl | 7 - templates/fr/class-deleted.tmpl | 1 - templates/fr/class-jobs-header.tmpl | 1 - templates/fr/class-modified.tmpl | 1 - templates/fr/classes-header.tmpl | 1 - templates/fr/classes.tmpl | 54 - templates/fr/edit-config.tmpl.in | 94 +- templates/fr/error-op.tmpl | 3 - templates/fr/error.tmpl | 3 - templates/fr/header.tmpl.in | 63 - templates/fr/help-header.tmpl | 52 - templates/fr/help-printable.tmpl | 11 - templates/fr/job-cancel.tmpl | 1 - templates/fr/job-hold.tmpl | 1 - templates/fr/job-move.tmpl | 22 - templates/fr/job-moved.tmpl | 2 - templates/fr/job-release.tmpl | 1 - templates/fr/job-restart.tmpl | 1 - templates/fr/jobs-header.tmpl | 16 - templates/fr/jobs.tmpl | 42 - templates/fr/maintenance.tmpl | 2 - templates/fr/modify-class.tmpl | 34 - templates/fr/modify-printer.tmpl | 29 - templates/fr/norestart.tmpl | 1 - templates/fr/option-boolean.tmpl | 7 - templates/fr/option-conflict.tmpl | 7 - templates/fr/option-header.tmpl | 3 - templates/fr/option-pickmany.tmpl | 7 - templates/fr/option-pickone.tmpl | 7 - templates/fr/option-trailer.tmpl | 6 - templates/fr/pager.tmpl | 11 - templates/fr/printer-accept.tmpl | 3 - templates/fr/printer-added.tmpl | 1 - templates/fr/printer-configured.tmpl | 1 - templates/fr/printer-confirm.tmpl | 7 - templates/fr/printer-default.tmpl | 7 - templates/fr/printer-deleted.tmpl | 1 - templates/fr/printer-jobs-header.tmpl | 1 - templates/fr/printer-modified.tmpl | 1 - templates/fr/printer-purge.tmpl | 3 - templates/fr/printer-reject.tmpl | 3 - templates/fr/printer-start.tmpl | 3 - templates/fr/printer-stop.tmpl | 3 - templates/fr/printers-header.tmpl | 1 - templates/fr/printers.tmpl | 66 - templates/fr/restart.tmpl | 1 - templates/fr/samba-export.tmpl | 53 - templates/fr/samba-exported.tmpl | 1 - templates/fr/search.tmpl | 13 - templates/fr/set-printer-options-header.tmpl | 3 - templates/fr/set-printer-options-trailer.tmpl | 1 - templates/fr/test-page.tmpl | 2 - templates/fr/trailer.tmpl | 21 - templates/fr/users.tmpl | 26 - templates/it/add-printer.tmpl | 7 +- templates/it/admin.tmpl | 5 +- templates/it/edit-config.tmpl.in | 3 +- templates/ja/add-printer.tmpl | 7 +- templates/ja/admin.tmpl | 5 +- templates/ja/edit-config.tmpl.in | 3 +- templates/pl/add-printer.tmpl | 7 +- templates/pl/admin.tmpl | 5 +- templates/pl/edit-config.tmpl.in | 3 +- templates/printers.tmpl | 16 +- templates/subscription-added.tmpl | 1 + templates/subscription-canceled.tmpl | 1 + templates/sv/add-printer.tmpl | 7 +- templates/sv/admin.tmpl | 5 +- templates/sv/edit-config.tmpl.in | 3 +- test/4.2-cups-printer-ops.test | 4 +- test/4.4-subscription-ops.test | 4 +- test/Dependencies | 4 +- test/Makefile | 6 +- test/get-job-attributes.test | 2 +- test/get-jobs.test | 21 + test/ipptest.c | 4 +- test/run-stp-tests.sh | 6 +- tools/makesrcdist | 10 +- tools/testosx | 4 +- vcnet/config.h | 128 +- vcnet/testhttp.vcproj | 0 417 files changed, 14820 insertions(+), 8777 deletions(-) create mode 100644 CHANGES-1.2.txt create mode 100644 backend/easysw-firewire-design.txt create mode 100644 backend/easysw-firewire-linux.txt create mode 100644 backend/ieee1394-linux.c create mode 100644 backend/ieee1394.c create mode 100644 backend/ieee1394.h create mode 100644 config-scripts/cups-dnssd.m4 create mode 100644 config-scripts/cups-gssapi.m4 create mode 100644 config-scripts/cups-poll.m4 create mode 100644 cups/sidechannel.c create mode 100644 cups/sidechannel.h create mode 100644 doc/help/spec-pdf.html create mode 100644 doc/help/spec-postscript.html create mode 100644 doc/images/button-add-rss-subscription.gif create mode 100644 doc/images/button-cancel-subscription.gif create mode 100644 filter/error.c create mode 100644 notifier/rss.c create mode 100644 ppd/intelbar.ppd create mode 100644 scheduler/select.c delete mode 100644 scripting/java/src/com/easysw/cups/IPPBase64Encoder.java create mode 100644 standards/papi-1.0.pdf create mode 100644 templates/add-rss-subscription.tmpl create mode 100644 templates/subscription-added.tmpl create mode 100644 templates/subscription-canceled.tmpl create mode 100644 test/get-jobs.test mode change 100644 => 100755 vcnet/testhttp.vcproj diff --git a/CHANGES-1.2.txt b/CHANGES-1.2.txt new file mode 100644 index 000000000..8c0c5f145 --- /dev/null +++ b/CHANGES-1.2.txt @@ -0,0 +1,1088 @@ +CHANGES-1.2.txt +--------------- + +CHANGES IN CUPS V1.2.8 + + - Documentation fixes (STR #2141, STR #2157) + - The HTTP upgrade redirection used by the scheduler did + not work with Internet Explorer (STR #2235) + - Members of a class with Unicode names did not appear + correctly in the web interface (STR #2154) + - Changing the "Save debugging information" setting in + the web interface no longer affects the other server + settings (STR #1993) + - The scheduler did not choose SSL certificates correctly + on Mac OS X (STR #2225) + - The scheduler could get in an infinite loop when + printing to a remote class (STR #2228) + - The jobs web page did not have separating space after + the number of pages column (STR #2230) + - Added French localization (STR #2221) + - Updated Spanish localization (STR #2223) + - Updated Japanese localization (STR #2216) + - cupsBorderlessScalingFacter was limited to a range of + 0.9 to 1.1, but some printers need larger values (STR + #2222) + - Landscape printing of PDF files did not always work + (STR #2149) + - Fixed slow USB printing on Minolta printers (STR #2104, + STR #2219) + - The ZPL label printer driver could produce stretched + output (PR #6448) + - The IPP backend now clears the printer-state-message + when there are no outstanding errors or warnings (STR + #2126) + - The CUPS Java scripting support did not work with + recent versions of Java due to the use of Sun's private + Base64 class (STR #2152) + - The scheduler did not pass HTTP GET form variables to + custom CGI programs (STR #2173) + - The lpoptions command now displays the reason why a PPD + file cannot be found (STR #2184) + - The scheduler did not accept "none" as a browse + protocol name (STR #2200) + - The scheduler still loaded the remote printer cache, + even when browsing was disabled (STR #2198) + - The SNMP backend now shows OfficeJet printers with the + "HP" manufacturer prefix (STR #2151) + - Web interface HTML cleanup (STR #2153) + - The parallel backend consumed 100% CPU on FreeBSD due + to an apparently common parallel port driver bug (STR + #2161) + - ippReadIO() incorrectly returned IPP_IDLE when the + initial IPP message header could not be read (STR + #2179) + - cupsRasterInterpretPPD() did not support custom options + (STR #1960) + - Collated output produced by the PostScript filter could + lose some options (STR #2137) + - job-hold-until with time values for the next day would + be held for 60 days (STR #2144) + - Some types of Sun raster files did not print correctly + (STR #2107) + - Raw PBM files did not print correctly (STR #2106) + - The SNMP backend no longer uses IPP with HP printers, + as some recent firmware versions appear to not work + (STR #2055) + - cupsMarkOptions() did not handle the + multiple-document-handling option (STR #2135) + - lpstat did not show the local job ID of active printers + (STR #2125) + - The backends incorrectly used STATUS: + media-tray-empty-error messages for out-of-paper + conditions (STR #2123, STR #2124) + - cupsGetPPD2() returned the wrong error when the PPD + file did not exist (STR #2122) + - cupsDoAuthentication() did not translate the password + prompt (STR #2121) + - httpGetLength2() did not handle error messages without + content correctly (STR #2133) + - Added support for 32/64-bit libraries on HP-UX Itanium + systems (STR #2115) + - Fixed a configure script problem with the 32/64-bit + library support (STR #2114) + - The PostScript filter did not properly output document + setup commands for reversed output (STR #2111) + - The scheduler did not parse IPv6 netmasks properly (STR + #2117) + + +CHANGES IN CUPS V1.2.7 + + - Documentation updates (STR #2089) + - Added an Italian translation (STR #2105) + - The PostScript filter now rotates the bounding box + values as needed (STR #2079) + - The scheduler no longer loads the remote printer cache + when browsing is disabled (STR #2084) + - The scheduler no longer writes a new launchd + configuration file if it doesn't have to (STR #2083) + - Updated the USB and PAP backends for Mac OS X (STR + #2086) + - The scheduler now picks up on changes to IPv6 and DNS + configuration on Mac OS X (STR #2085) + - The lpstat program could still hang (STR #2098) + - Fixed an inefficiency in the SNMP IPP detection code + (STR #2100) + - The SSL negotiation code did not implement short + timeouts (STR #2091) + + +CHANGES IN CUPS V1.2.6 + + - The web interface was not localized on Mac OS X (STR + #2075) + - "lpc status" did not show the number of queued jobs for + disabled queues (STR #2069) + - The lpstat program could hang (STR #2073) + - The serial backend did not support the new USB serial + filenames on Linux (STR #2061) + - The parallel backend did not support bidirectional I/O + properly (STR #2056) + - The network backends now log the numeric address that + is being used (STR #2046) + - Fixed a compile error when using libpaper. + - Fixed a compile error when compiling on Solaris with + threading enabled (STR #2049, STR #2050) + - Missing printer-state-changed event for + printer-state-message updates (STR #2047) + + +CHANGES IN CUPS V1.2.5 + + - Documentation updates (STR #2038) + - The SNMP backend no longer uses IPP for Epson printers + (STR #2028) + - Updated the configure script for Tru64 UNIX 5.1 (STR + #2033) + - Tru64 5.1B's getaddrinfo() and getnameinfo() functions + leak file descriptors (STR #2034) + - cupsAddDest() didn't add the parent destination's + options and attributes. + - ppdConflicts() did not handle custom option + constraints. + - Raw printing of gzip'd files did not work (STR #2009) + - The scheduler no longer preserves default option + choices when the new PPD no longer provides the old + default choice (STR #1929) + - The Linux SCSI backend is now only built if the SCSI + development headers are installed. + - USB printing to Minolta printers did not work (STR + #2019) + - Windows clients could not monitor the queue status (STR + #2006) + - The scheduler didn't log the operation name in the + access_log file for Create-Job and Print-Job requests. + - The PostScript filter now separates collated copies + with any required JCL commands so that JCL-based + finishing options act on the individual copies and not + all of the copies as a single document. + - The PostScript filter now disables duplex printing when + printing a 1-page document. + - cups-lpd didn't pass the correct + job-originating-host-name value (STR #2023) + - Fixed some speling errors in the German message catalog + (STR #2012) + - cupstestppd did not catch PPD files with bad + UIConstraints values (STR #2016) + - The USB backend did not work with the current udev- + created printers if the first printer was disconnected + (STR #2017) + - Mirrored and rotated printing did not work with some + documents (STR #2004) + - 2-sided printing with banners did not work properly on + some printers (STR #2018) + - Updated the raw type rule to handle PJL within the + first 4k of a print job (STR #1969) + - Added an Estonian translation (STR #1957) + - Clarified the documentation for the cupsd.conf @LOCAL + and @IF(name) allow/deny functionality (STR #1992) + - The PostScript filters did not escape the Title and For + comments in the print job header (STR #1988) + - The scheduler would use 100% CPU if browsing was + disabled and the cupsd.conf file contained BrowsePoll + lines (STR #1994) + - The cupsDirRead() function did not work properly on + non-POSIX-compliant systems (STR #2001) + - The cupsFile functions didn't handle read/write errors + properly (STR #1996) + - The DBUS support now works with older versions of the + DBUS library. + + +CHANGES IN CUPS V1.2.4 + + - The --with-printcap configure option did not work (STR + #1984) + - The character set reported by cupsLangGet() did not + always reflect the default character set of a given + locale (STR #1983) + - Older Lexmark and Tektronix printers did not work with + IPP (STR #1980) + - Failsafe printing did not work (PR #6328) + - Some web interface redirects did not work (STR #1978) + - The web interface change settings button could + introduce a "Port 0" line in cupsd.conf if there was no + loopback connection available (STR #1979) + - The web interface change settings and edit + configuration file buttons would truncate the + cupsd.conf file (STR #1976) + - The German web interface used the wrong printer icon + images (STR #1973) + - The "All Documents" link in the on-line help was + missing a trailing slash (STR #1971) + - The Polish web interface translation used the wrong + URLs for the job history (STR #1963) + - The "reprint job" button did not work (STR #1956) + - The scheduler did not always report printer or job + events properly (STR #1955) + - The scheduler always stopped the queue on error, + regardless of the exit code, if the error policy was + set to "stop-printer" (STR #1959) + - ppdEmitJCL() included UTF-8 characters in the JCL job + name, which caused problems on some printers (STR + #1959) + - Fixed a buffering problem that cause high CPU usage + (STR #1968) + - The command-line applications did not convert + command-line strings to UTF-8 as needed (STR #1958) + - cupsDirRead() incorrectly aborted when reading a + symbolic link that pointed to a file/directory that did + not exist (STR #1953) + - The cupsInterpretRasterPPD() function did not handle + custom page sizes properly. + + +CHANGES IN CUPS V1.2.3 + + - The scheduler did not send job-state or + job-config-changed events when a job was held, + released, or changed (STR #1947) + - The scheduler now aborts if the configuration file and + directory checks fail (STR #1941) + - Fixed a problem with ippPort() not using the port + number that was set via the client.conf file or + CUPS_SERVER environment variable (STR #1945) + - HTTP headers were not buffered (STR #1899) + - Some IPP printers (HP) did not like UTF-8 job names + (STR #1837) + - The CUPS desktop icon is now localized for Polish (STR + #1920) + - Printer options were not always honored when printing + from Windows clients (STR #1839) + - The openssl command would lock up the scheduler when + generating an encryption certificate on some platforms + due to a lack of entropy for the random number + generator (STR #1876) + - The web admin page did not recognize that "Listen 631" + enabled remote access (STR #1908) + - The web admin page did not check whether changes were + made to the Basic Server Settings check boxes (STR + #1908) + - The IPP backend could generate N*N copies in certain + edge cases. + - The scheduler did not restore remote printers properly + when BrowseShortNames was enabled (STR #1893) + - Polling did not handle changes to the network + environment on Mac OS X (STR #1896) + - The "make test" subscription tests used invalid + notify-recipient-uri values (STR #1910) + - Printers could be left in an undefined state on system + sleep (STR #1905) + - The Berkeley and System V commands did not always use + the expected character set (STR #1915) + - Remote printing fixes (STR #1881) + - The cupstestppd utility did not validate translation + strings for custom options properly. + - Multi-language PPD files were not properly localized in + the web interface (STR #1913) + - The admin page's simple settings options did not check + for local domain socket or IPv6 addresses and did not + use "localhost" as the listen address. + - An empty BrowseProtocols, BrowseLocalProtocols, or + BrowseRemoteProtocols line would crash the scheduler + instead of disabling the corresponding browsing options. + - The scheduler now logs IPP operation status as debug + messages instead of info or error. + - cupsFileRewind() didn't clear the end-of-file state. + - cupstestppd didn't report the actual misspelling of the + 1284DeviceID attribute (STR #1849) + - BrowseRelay didn't work on Debian (STR #1887) + - configure --without-languages didn't work (STR #1879) + - Manually added remote printers did not work (STR #1881) + - The header was not installed. + - Updated the build files for Autoconf 2.60 (STR #1853) + - The scheduler incorrectly terminated the polling + processes after receiving a partial log line. + - The cups-lpd mini-daemon reported "No printer-state + attribute found" errors when reporting the queue status + (PR #6250, STR #1821) + - SNMP backend improvements (STR #1737, STR #1742, STR + #1790, STR #1835, STR #1880) + - The scheduler erroneously reported an error with the + CGI pipe (STR #1860) + - Fixed HP-UX compile problems (STR #1858, STR #1859) + - cupstestppd crashed with some PPD files (STR #1864) + - The and header files did not + work with C++. + + +CHANGES IN CUPS V1.2.2 + + - Documentation updates (STR #1765, STR #1780) + - CUPS didn't know about alternate character set names + for Asian text (STR #1819) + - The lpoptions -o and -r options did not work unless you + specified a printer. + - The lpoptions command incorrectly allowed users to set + printer attributes like printer-type (STR #1791) + - httpWait() did not flush the write buffer, causing "bad + request" errors when communicating with CUPS 1.1.x + servers (STR #1717) + - Polling did not sanitize the printer description, + location, or make and model strings like broadcasts + did. + - Polled printers did not show the server's default + job-sheets option value. + - The Samba password prompt was not properly localized + (STR #1814) + - Added a German translation (STR #1842) + - The scheduler now creates self-signed SSL certficates + automatically when using OpenSSL and CDSA for + encryption, just as for GNU TLS. + - The SNMP backend sporatically reported some printers as + "unknown" (STR #1774) + - The scheduler now forces BrowseTimeout to be at least + twice the BrowseInterval value and non-zero to avoid + common configuration errors. + - The scheduler incorrectly returned printer URIs of the + form "ipp://server/printers/classname" for classes (STR + #1813) + - Updated Japanese localization (STR #1805) + - The scheduler's SSL certificate/key directory was not + created on installation (STR #1788) + - Added a mailto.conf man page and help page (STR #1754) + - The parallel and USB backends no longer wait for the + printer to go on-line - this caused problems with + certain printers that don't follow with the IEEE-1284 + standard (STR #1738) + - The scheduler could crash on a reload when implicit + classes were present (STR #1828) + - The IPP backend incorrectly used the CUPS_ENCRYPTION + environment variable to determine the default + encryption mode when printing (STR #1820) + - USB printing did not work on Solaris (STR #1756) + - The scheduler sorted job priorities in the wrong order + (STR #1811) + - The scheduler did not automatically restart notifiers + that exited or crashed (STR #1793) + - IPv6 support did not work on NetBSD (STR #1834) + - The EPM packaging file did not work (STR #1804) + - The scheduler used up the CPU if BrowseRemoteProtocols + was empty (STR #1792) + - Custom page sizes did not work (STR #1787) + - The SNMP backend could crash on some systems when SNMP + logging was enabled (STR #1789) + - Browsing could produce some funny printer names when + ServerName was set to an IP address (STR #1799) + - Fixed the log message for BrowseRelay (STR #1798) + - Fixes to allow CUPS to compile on MirBSD (STR #1796) + - The scheduler incorrectly set the FINAL_CONTENT_TYPE + environment variable (STR #1795) + - The pdftops filter incorrectly embedded a "produced by" + comment, causing PDF printing not to work on some + operating systems (STR #1801) + - Sending raw jobs from a client system could cause the + client's scheduler to eventually crash (STR #1786) + - The scheduler now checks that the notifier exists prior + to accepting a new subscription request. + - The scheduler now reports the supported + notify-recipient schemes based on the contents of the + ServerBin/notifier directory. + - Event notifications did not include the + notify-sequence-number or other required attributes + (STR #1747) + - Allow/Deny addresses of the form "11.22.33.*" did not + work on Linux (STR #1769) + - cupsGetPPD() did not work if the scheduler was only + listening on a domain socket (STR #1766) + - The scheduler could crash advertising a class (STR + #1768) + - The scheduler could crash if the default printer was + deleted (STR #1776) + - Added a new default CUPS raster format (v3) which does + not compress the raster stream in order to provide the + same cupsRasterReadPixels() and cupsRasterWritePixels() + performance as CUPS 1.1.x. + - The cupsaddsmb man page listed the wrong files for the + CUPS driver. + - Some configure --with options did not work (STR #1746) + - "Allow @IF(name)" didn't work if "name" wasn't the + first network interface (STR #1758) + - The lpstat command did not use the correct character + set when reporting the date and time (STR #1751) + - The cupsaddsmb command and web interface did not update + the Windows PPD files properly, resulting in corrupt + PPD files for the Windows client to use (STR #1750) + - The cupsd.conf man page didn't describe the Listen + domain socket syntax (STR #1753) + - The scheduler no longer tries to support more than + FD_SETSIZE file descriptors. + - CDSA (encryption) support fixes for MacOS X. + - The lppasswd program needs to be setuid to root to + create and update the /etc/cups/passwd.md5 file (STR + #1735) + - 32/64-bit library installation was broken (STR #1741) + - The USB backend now reports a "no such device" error + when using the old filename-based USB URIs instead of + the "success" error. + - Increased the HTTP and IPP read timeouts to 10 seconds, + as 1 second was too short on congested networks (STR + #1719) + - The SNMP backend now uses the device description over + the printer-make-and-model attribute when the attribute + contains a generic name (STR #1728) + - Fixed another file descriptor leak when printing raw + files (STR #1736) + - Raw queues were not shared via LDAP (STR #1739) + - The pstops filter didn't always embed PageSetup + commands from the PPD file (STR #1740) + - "make install" didn't work if you disabled all of the + localizations. + - The scheduler didn't always choose the least costly + filter. + - Fixed parsing of IPv6 addresses in Allow, Deny, + BrowseAllow, BrowseDeny, and BrowseRelay directives + (STR #1713) + - Printers that were shared via LDAP did not get added to + the LDAP server properly (STR #1733) + - LDAP browsing would crash the scheduler if a required + value was missing (STR #1731) + - Special cases for the "localhost" hostname did not + work, causing printing to not work when the /etc/hosts + file did not contain a localhost entry (STR #1723) + - Updated the Spanish translation (STR #1720, STR #1770) + - Reverse-order page output was broken when N-up or + landscape orientations were used (STR #1725) + - The parallel, serial, socket, and USB backends needed + print data before they would report back-channel data, + causing problems with several new drivers (STR #1724) + + +CHANGES IN CUPS V1.2.1 + + - "lprm -h hostname" did not work (STR #1800) + - The web interface did not handle reloads properly for + MSIE (STR #1716) + - The configure script no longer adds linker rpath + options when they are unnecessary. + - The scheduler could crash printing a debug message on + Solaris (STR #1714) + - The --enable-32bit and --enable-64bit configure options + did not always work. + - The password prompt showed the domain socket address + instead of "localhost" for local authentication (STR + #1706) + - The web interface filtered the list of printers even if + the user wasn't logged in (STR #1700) + - The IPP backend did not work reliably with some Xerox + printers (STR #1704) + - Trailing banners were not added when printing a single + file (STR #1698) + - The web interface support programs crashed on Solaris + (STR #1699) + - cupstestppd incorrectly reported problems with + *1284DeviceID attributes (STR #1710) + - Browsing could get disabled after a restart (STR #1670) + - Custom page sizes were not parsed properly (STR #1709) + - The -U option wasn't supported by lpadmin (STR #1702) + - The -u option didn't work with lpadmin (STR #1703) + - The scheduler did not create non-blocking back-channel + pipes, which caused problems when the printer driver + did not read the back-channel data (STR #1705) + - The scheduler no longer uses chunking in responses to + clients - this caused problems with older versions of + CUPS like 1.1.17 (PR #6143) + - Automatic raw printing was broken (STR #1667) + - 6-up printing was broken (STR #1697) + - The pstops filter did not disable CTRL-D processing on + the printer/RIP. + - ppdOpen*() did not load custom options properly (STR + #1680) + - "Set Printer Options" in the web interface did not + update the DefaultImageableArea or + DefaultPaperDimension attributes in the PPD file (STR + #1689) + - Fixed compile errors (STR #1682, STR #1684, STR #1685, + STR #1690) + - The lpstat command displayed the wrong error message + for a missing destination (STR #1683) + - Revised and completed the Polish translation (STR + #1669) + - Stopped jobs did not show up in the list of active jobs + (STR #1676) + - The configure script did not use the GNU TLS + "libgnutls-config" script to find the proper compiler + and linker options. + - The imagetoraster filter did not correctly generate + several 1, 2, and 4-bit color modes. + - cupsRasterWritePixels() could lose track of the current + output row. + - cupsRasterReadPixels() did not automatically swap + 12/16-bit chunked pixel data. + - Moved the private _cups_raster_s structure out of the + public header. + - Updated the CUPS raster format specification to include + encoding rules and colorspace definitions. + - The Zebra PPD files had the wrong PostScript code for + the "default" option choices. + - The imagetoraster filter did not generate correct CIE + XYZ or Lab color data. + - The cups-config script did not work when invoked from a + source directory (STR #1673) + - The SNMP backend did not compile on systems that used + the getifaddrs emulation functions (STR #1668) + + +CHANGES IN CUPS V1.2.0 + + - Documentation updates (STR #1618, STR #1620, STR #1622, + STR #1637) + - Static file copy buffers reduced from 64k to 32k to + work around bogus MallocDebug library assumptions (STR + #1660) + - The scheduler did not decode the backend exit code + properly (STR #1648) + - The MacOS X USB backend did not report the 1284 device ID, + nor did it fix device IDs returned by HP printers. + - The scheduler started more slowly than 1.1.x with large + numbers of printers (STR #1653) + - cupsRasterInterpretPPD() didn't support the + cupsPreferredBitsPerColor attribute, and imagetoraster + didn't use the new API. + - The "make test" script did not create all of the necessary + subdirectories for testing (STR #1638) + - The scheduler did not prevent rotation of logs + redirected to /dev/null (STR #1651) + - "make test" did not include the SNMP backend in the + test environment (STR #1625) + - The EPM packaging files did not work (STR #1621) + - "Use Default Configuration" inserted a broken + configuration file (STR #1624) + - Redirects in the web interface did not always preserve + the encrypted status of a connection (STR #1603) + - Added the Apple "pap" backend. + - Added CUPS library to CUPS Image shared library + linkage to support Linux --as-needed linker option + (STR #1606) + - Fixed support for --enable-pie (STR #1609) + - The pdftops filter did not validate the length of the + encryption key (STR #1608) + - Updated the Polish localization. + - "Encryption Required" in the cupsd.conf file now only + requires encryption when the connection is not over the + loopback interface or domain socket. + - Printer names containing "+" were not quoted properly in + the web interface (STR #1600) + - The SNMP backend now reports the make and model in the + information string so that the auto-generated printer + name is more useful than just an IP address. + + +CHANGES IN CUPS V1.2rc3 + + - The cups-lpd program always did reverse lookups on the + client address, which could be a performance problem. + Added a "-n" option to disable lookups. + - When configured with SSL support, require encryption by + default when displaying the /admin location (STR #1592) + - The next job ID was not computed correctly if the job + cache file got out of sync with the spool directory + (STR #1582) + - The PNG image handling code used deprecated functions + from libpng (STR #1587) + - Added a Polish translation (STR #1584, STR #1586) + - More changes to the scheduler to improve battery life + on portable devices (STR #1583) + - Changed the default log level for status messages back + to "DEBUG" to be consistent with CUPS 1.1.x (STR #1579) + - The error string was not set properly when + cupsDoFileRequest() was given the name of a directory + (STR #1578) + - Fixed handling of job-hold-until (STR #1581) + - Added explicit notes to the cupsaddsmb man page + explaining that the driver filenames are case-sensitive + under UNIX and that they must be all lowercase (Windows + 2000) or all UPPERCASE (Windows 95/98/Me) to work (STR + #1568) + - The USB backend incorrectly split the manufacturer name + if it contained spaces (STR #1566) + - The scheduler would hang when listing PPD files for a + manufacturer whose name contained spaces (STR #1567) + - Added the SNMP backend for network printer discovery + (STR #1555) + - cupstestppd now fails PPD files with 1284DeviceId + instead of 1284DeviceID, and cups-driverd uses a + case-insensitive comparison when looking for it (STR + #1573) + - cupsDoFileRequest() and cupsDoRequest() now work + properly with non-blocking HTTP connections. + - Added Swedish translation (STR #1569) + - "make install" now installs the MIME files with world + read permissions (STR #1565) + - More CDSA encryption support fixes (STR #1563) + - Updated the default mime.types file to support printing + of files that do not have a locally-recognized MIME + media type to raw or System V queues. + - Updated the serial port detection code on Linux (STR + #1562) + - Added some more error checking to httpGetHostname() + (STR #1561) + - The title of some administration pages was not + localized (STR #1548) + - The edit-config.tmpl file was not generated or + installed for the Spanish or Japanese localizations + (STR #1547) + - The mimeDelete() function freed the types before the + filters, but the filters needed the type data (STR #1558) + - The scheduler didn't keep track of the status pipes + properly, leading to a bad select() for multi-file jobs + (STR #1559) + - The cupstestdsc program didn't validate the ordinal + page number value for %%Page: comments. + + +CHANGES IN CUPS V1.2rc2 + + - The scheduler was not always using the string pool, + causing random crashes. + - The lpmove and the web interface's Move Job button did + not work with stopped jobs (STR #1534) + - The PostScript filter did not handle the page-set + option properly with number-up printing (STR #1543) + - The scheduler now only warns about unsupported ACLs + once (STR #1532) + - The "fitplot" option did not work with output from + Mozilla (STR #1542) + - The imagetops filter did not work with Level 2 or 3 + printers (STR #1533) + - The scheduler now recognizes PostScript files with PJL + commands that do not include an ENTER LANGUAGE command. + - Added --with-printcap configure option. + - 64-bit SSL fixes for MacOS X. + - The scheduler didn't send some printer state change + events. + - The scheduler didn't send jobs to busy remote printers. + - Fixed some problems with the launchd support. + - Added new USB printer backend for MacOS X. + - The PostScript filter now handles files that start with + an incomplete PJL header (PR #6076) + - The web interface language selection code did not try + the generic language localization (STR #1531) + - The language cache, string pool, and transcoding caches + are now process global instead of per-thread to avoid + problems with GNOME and to allow for data sharing + between threads (STR #1530) + - Fixed a CUPS 1.1.x compatibility bug (STR #1528) + - The web interface redirection after certain printer + administration tasks was broken (STR #1516) + - Web interface authorization could get stuck (STR #1512) + - Localization updates (STR #1513, STR #1518, STR #1520) + - The pstops filter didn't work with some files (STR + #1523) + - "./configure --enable-static" didn't work (STR #1522) + - The scheduler was not using the configured default + Group (STR #1521) + - The web interface still did not show the localized time + and date for some locales and systems (STR #1509) + - httpAddrGetList() would crash on systems without + getaddrinfo(). + - Socket URIs without a trailing slash would cause the + port number to not be accepted (STR #1519) + - Local raw and System V printers were not advertised as + such for printer browsing (STR #1502) + - The RPM spec file incorrectly put duplicate copies of + the Japanese and Spanish web interface templates in the + main cups package (STR #1517) + - cupsSetDests() did not explicitly set the permissions + of the /etc/cups/lpoptions file (STR #1508) + - The lpq command crashed with the -h option (STR #1515) + + +CHANGES IN CUPS V1.2rc1 + + - Documentation updates (STR #1497, STR #1498) + - The scheduler now redirects browsers to https: URLs + when encryption is required. + - The scheduler would crash when printing with a banner + (STR #1500) + - cups-driverd did not use the LanguageEncoding attribute + in PPD files to convert the NickName to UTF-8 (STR + #1503) + - The lpadmin command could not set the + printer-error-policy attribute (STR #1504) + - The web interface did not show the time and date in the + correct format for the locale (STR #1505) + - CUPS no longer accepts print jobs if a printer does not + support the file format (STR #1501) + - Cleaned up the PostScript filter (pstops) so that it + properly supports %%IncludeFeature and page scaling + (STR #1453) + - Fixed the cupsFileRewind() and cupsFileSeek() functions + to work properly with uncompressed files. + - Added cupsFileGetLine(), cupsFileStderr(), + cupsFileStdin(), and cupsFileStdout() functions to the + CUPS library. + - Added a new cupstestdsc program to test the DSC + conformance of PostScript files. + - Added KDE/GNOME icons and a Manage Printers menu item. + - Added --enable-image and --enable-pdftops configure + options to control whether the image and PDF filters + are built and installed (default = yes for all + platforms but MacOS X) + - Fixed a minor memory leak in the PPD API. + - Fixed transcoding issues (STR #1493) + - The scheduler now enforces a minimum job cost of 100 + when doing FilterLimit checks. + - The scheduler would leak file descriptors when printing + to raw queues (STR #1491) + - The IPv6 support did not compile on Tru64 UNIX (STR + #1488) + - ppdOpen2() now converts the NickName and all UI text to + UTF-8 (STR #1475) + - The Set Allowed Users web page did not work (STR #1486) + - When the default policy was not set or set to a non- + existing policy, the scheduler did not set the default + policy name to "default" (STR #1484) + - The Zebra CPCL driver did not use the correct righthand + margin for the 4" wide label sizes. + - Fixed a problem with the parsing of fractional real + numbers in PPD files. + - Added Spanish localization files (STR #1480) + - Fixed localization of a few scheduler messages (STR + #1478) + - Fixed support for HEAD requests in the scheduler (STR + #1481) + + +CHANGES IN CUPS V1.2b2 + + - Updated the CUPS design description. + - Added --enable-32bit and --enable-64bit configure + options to allow building of separate 32/64-bit + libraries on systems that support both environments + (STR #1472) + - Various compiler warning fixes. + - Fixes for Solaris 10 builds against old GNU TLS and + LDAP libraries. + - Added a cupsArrayUserData() function to retrieve the + user data pointer for an array (useful for typing + arrays) + - The ppdEmitString() function did not compute the + required buffer size properly, leading to dropped + characters on the end of the printer commands in pstops + and imagetops (STR #1470) + + +CHANGES IN CUPS V1.2b1 + + - The serial backend now supports Equinox 8-port serial + hubs (STR #526) + - The IPP backend now supports a compression option to + compress print files as they are sent to the remote + server (STR #956) + - The CUPS browse protocol now supports passing of + default options and browse timeout values from the + server to the clients (STR #800) + - Implicit classes that timed out could cause the + scheduler to crash (STR #1439) + - Added DragonFly support in local device backends (STR + #1362) + - Added LDAP printer browsing support (STR #338) + - Added official support for printer maintenance commands + via the CUPS Command file format and hooks in the + printer-type and web interfaces (STR #932) + - The HP-GL/2 filter could get in an infinite loop trying + to convert HP-PCL files (STR #1415) + - CUPS now implements the HTTP/1.1 Expect header (STR + #1407) + - Options in PPD files are no longer automatically put in + an "Extra" group; rather, all options that are not + inside an Open/CloseGroup will be placed in the + "General" group (STR #1385) + - The scheduler now creates a job-uuid attribute that + uniquely identifies a job on a network (STR #1410) + - The init script now unsets the TMPDIR environment + variable to prevent user temporary directories from + being used by cupsd accidentally (STR #1424) + - Added support for launchd on MacOS X. + - Added support for notify_post on MacOS X. + - Added support for DBUS on Linux. + - All of the Berkeley (except for lpc) and System V + commands now support specification of user, host, and + port (STR #1028, STR #1029, STR #1087) + - The lpmove command now allows you to move all jobs for + a given queue (STR #56) + - The web interface now supports moving of a job or jobs + to another queue (STR #56) + - The web interface now provides searching, paging, and + changing of the sort/display order of classes, jobs, + and printers. + - cupsaddsmb now accepts a password on the command-line + and supports passwords with special characters (STR + #822, STR #1236) + - ppdLoad*() no longer tries to "fix" bad characters in + UI text (STR #1101) + - Printer names can now (reliably) contain Unicode + characters (STR #896) + - The lpstat command now shows the time and date of the + last printer state change instead of the hardcoded "Jan + 01 00:00" (STR #659) + - The scheduler now adds a job-actual-printer-uri + attribute to job objects when printing to a class (STR + #116) + - The scheduler now logs log file open errors to the + system log (STR #1289) + - The scheduler now sets the job-originating-user-name to + the authenticated username, if available (STR #1318) + - The scheduler now only updates the permissions of SSL + keys and certificates when they are under the + ServerRoot directory (STR #1324) + - The rastertodymo driver has been renamed to + rastertolabel (a symlink is installed so that existing + queues continue to work) and now also supports Zebra's + CPCL language. + - The lpstat command could show the wrong active job for + a printer (STR #1301) + - Fixed a potential crash problem in the scheduler when + aborting a CGI program (STR #1290) + - Added a "cancel all jobs" button to the class and + printer web interfaces (STR #1140) + - The add-printer web page now shows the + set-printer-options page after the printer has been + added (STR #690) + - The classes web page now provides links to each of the + member printers (STR #307) + - CUPS now handles HTTP request/response lines up to 32k + in length; this is mainly for better cookie support + (STR #1274) + - Added support for the Apache PassEnv and SetEnv + directives to cupsd.conf (STR #853) + - Added large file (64-bit) support (STR #541) + - Fixed a performance issue with the ippReadIO() + implementation (STR #1284) + - Fixed a performance issue with the scheduler's implicit + class implementation (STR #1283) + - The pdftops filter now adds the Title and Creator + fields from the PDF file to the PostScript document + comments section (STR #539, STR #830) + - Added a new cups_array_t and cupsArray*() functions to + the CUPS API to support sorted lists of data. + - Made the CUPS API library thread-safe (STR #1276) + - Added "media" option support for EFI EFMediaType option + (STR #902) + - Added write buffering to the HTTP code to improve + performance (STR #547) + - The scheduler now uses the attributes-natural-language + attribute to localize banner pages (STR #386) + - The scheduler now returns the address that was used to + connect to it (STR #1076) + - Fixed a problem with N-up printing and OpenOffice (STR + #576) + - Added support for the GCC position independent + executable options (STR #1209) + - Added new BrowseLocalProtocols and + BrowseRemoteProtocols directives to cupsd.conf, + allowing for different browse protocols for local and + remote printers (STR #877) + - PPD files can now contain strings up to 256k in length + (STR #1215) + - The pstops filter now supports the IncludeFeature DSC + comment (STR #1212) + - The pstops filter now disables the setpagedevice + procedure when doing N-up printing (STR #1161) + - The serial backend now supports "stop=1", "stop=2", + "parity=space", and "parity=mark" options (STR #1155) + - "make install" no longer overwrites an existing PAM + configuration file (STR #1064) + - The scheduler now closes all files on startup when run + in daemon mode (STR #1009) + - Added a new RGBW colorspace to the CUPS raster format + (STR #1071) + - The pdftops filter now sets the page size based on the + media box when not scaling the output (STR #912) + - The pdftops filter now supports masked images (STR + #281) + - The pdftops filter produced large output when rendering + PDF files containing lot of repeated images (STR #327) + - The pdftops filter now minimizes print processing of + PDF files when using the page-ranges option (STR #273) + - Updated pdftops filter to Xpdf 3.01. + - Added new cupsBackchannelRead() and + cupsBackchannelWrite() functions, as well as + backchannel support to the parallel, serial, socket, + and USB backends (STR #1252) + - The parallel and USB backends now treat a "no space + available" error as an out-of-paper condition (STR + #1225) + - The "lpc" command now supports the "status all" command + (STR #1004) + - ippReadIO() did not read collections properly (STR + #1249) + - The "make test" script now creates the test files in + "/tmp/cups-$USER" instead of "/tmp/$USER" (STR #981) + - All backends now abort on error when printing a job to + a class - this allows the next printer in the class to + print the job (STR #1084) + - The scheduler now verifies that a printer supports + Letter or A4 media sizes before setting them as the + initial default (STR #1250) + - The cupstestppd program now flags bad Resolution + options (STR #1269) + - The USB backend now retries printing when the printer + is disconnected or turned off (STR #1267) + - Added new httpGetHostname() function to CUPS API, and + use it instead of gethostname() so that the web + interface will work correctly on systems whose hostname + is not the FQDN (STR #1266) + - The scheduler now stops printers if the backend for the + queue is missing on startup (STR #1265) + - The configure script now supports "--disable-library" + to disable particular image file format support + libraries, even if they are available on the build + system (STR #1248) + - The IPP backend did not always report on the total + number of pages that were printed (STR #1251) + - The lpstat program could display garbage date and time + values for locales whose date format exceeded 31 + characters (STR #1263) + - The cupstestppd program would segfault when testing + certain broken PPD files (STR #1268) + - Dramatically reduced the overhead of implicit classes. + - Added new cupsDir*() functions to CUPS API. + - Printers can now be published individually for sharing. + - Fixed a bug in the scheduler's startup signalling code + which caused cupsd to send the SIGUSR1 signal to the + init process instead of the original parent process + (STR #1258) + - Added new on-line help CGI to web interface to provide + searchable help. + - Devices are now tracked dynamically, with each query + doing a new device scan. This eliminates a previous + startup delay caused by slow backends and allows new + printers to be seen without restarting the server, + however it limits the amount of device URI checking + that can be done (basically now the scheduler only + requires a URI with a method that is a listed backend) + - Added new printer auto-detection, server configuration, + and log file viewing to the administration web page. + - Added new "set allowed users" web interface to set the + list of allowed users for a printer or class. + - The scheduler, command-line, and web interfaces now + limit the list of printers and classes to those + accessible by a user. + - cupsMarkOptions() now handles more non-standard + duplexing options and choices (STR #915) + - cups-lpd now honors remote banner requests with the + "standard" banner whenever a printer does not have one + defined (STR #1220) + - The scheduler's denial-of-service checks did not work + properly with IPv6 addresses (STR #1134) + - The lp and lpr commands did not error out properly when + they were unable to write to a temporary file (STR + #1129) + - The pstops filter did not handle Adobe-specific + comments in Windows NT driver output (STR #1085) + - "lpstat -l -p" incorrectly reported the printer + interface (STR #936) + - The web interface now operates exclusively with the + UTF-8 encoding, and sends the appropriate character set + and header information to the web browser (STR #919, + STR #1007) + - Added a "set allowed users" interface to the web + interface so that you can set the list of allowed or + denied users/groups for a printer or class. + - Disallow the "#" character in printer names, since it + has special meaning in the shell, config files, and in + URIs (STR #917, STR #1202) + - Added a new application/x-csource MIME type, and + support for it to the texttops filter so that you can + pretty print plain text files without the C/C++ + keywords being highlighted. + - The pdftops filter did not compile with GCC 4.0 (STR + #1226) + - The texttops filter did not highlight preprocessor + directives followed by a tab properly. + - HP PJL output now uses both JOB DISPLAY and RDYMSG + commands to show the current job on the printer's + display (STR #1218) + - Local authentication certificates are now stored in + /var/run/cups/certs by default instead of + /etc/cups/certs (STR #1211) + - Backends now use "&" to separate options in device + URIs; "+" is still recognized but is deprecated (STR + #842) + - The USB backend no longer supports the usb:/dev/foo + format on systems that support device ID queries. + - Forced classification markings did not work when the + job-sheets parameters were "none,none". + - "lpstat -l -p" incorrectly showed all users as allowed, + even if the queue was restricted to certain users (STR + #801) + - The scheduler now automatically detects SSL/TLS clients + without using the SSLPort/SSLListen directives. + - The CUPS API and scheduler no longer support SSLv2- + encrypted connections. + - Updated the cupsaddsmb utility to correctly export the + CUPS driver for Windows. + - Fixed a signal-handling bug in httpRead() which + ultimately caused the server to print multiple copies + when it was busy (STR #1184) + - The cupsFile API now uses the O_APPEND option when + opening files in append mode (STR #990) + - The md5.h header and md5_* functions are now officially + private and have been renamed to avoid conflicts with + other implementations with the same name. + - The pdftops filter incorrectly embedded some Type1 + fonts (STR #1093) + - The scheduler didn't detect a closed connection in the + middle of an IPP request (STR #1153) + - The scheduler could block trying to read the job status + if there was input pending and the job was cancelled in + the same input cycle (STR #1157) + - The scheduler could crash when deleting a class due to + infinite recursion. + - Updated the Zebra ZPL label printer driver to use the + run-length encoding and support more options. + - Updated serial backend to scan for /dev/ttyC* as well + as /dev/ttyc* for Cyclades serial ports (STR #1049) + - The scheduler could hang reading the job status under + certain circumstances (STR #1068) + - The USB backend termination signal code was inverted + (STR #1046) + - Moved enable and disable commands to sbindir to be + consistent. + - Added new cupsRasterInterpretPPD() function for RIP + filters to setup the raster page header from + PostScript commands in a PPD file. + - The CUPS browsing protocol now offers a "delete" bit + to remove printers as soon as they are deleted on the + server or as soon as the server shuts down gracefully + (STR #793) + - The CUPS_SERVER and ServerName directives (client.conf + and ~/.cupsrc) may now contain names of the form + "server:port" and "/path/to/domain/socket". + - The "cancel -u user" command now works for ordinary + users (STR #751) + - Added test run support to "make test" target (STR #64) + - Added domain socket support (STR #656) + - Added BrowseLocalOptions directive to allow the + administrator to add printer URI options to the browse + URI, e.g. "encryption=required" (STR #732) + - Added BrowseRemoteOptions directive to allow the + administrator to add standard URI options to the + remote printer URI, e.g. "encryption=required" (STR + #732) + - Now put "-I.." compiler option in front of all others + to ensure that local CUPS headers are used before + installed headers (STR #437) + - New cupsLangPrintf() and cupsLangPuts() for localized + interfaces. + - Now support custom attributes and extended options in + PPD files. + - Now provide functions to save PPD files. + - New policy mechanism allows per-operation and + per-printer control over what users and groups are + allowed to do various IPP operations. + - New error policy mechanism to control how aborted + backend errors are handled by the scheduler + (abort-job, retry-job, requeue-job, stop-printer) + - Updated the printer test page with a better color + wheel and a separate grayscale ramp. + - A single backend process is now run to send all print + data for a job. + - Backends and filters can now send and receive + backchannel data over file descriptor 3. + - Updated the raster stream format to support more + user-defined attributes and to do compression of the + page data. diff --git a/CHANGES.txt b/CHANGES.txt index 4dd18bf0c..f5e4af6d3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,1088 +1,54 @@ -CHANGES.txt - 2007-02-06 +CHANGES.txt - 2007-02-19 ------------------------ -CHANGES IN CUPS V1.2.8 - - - Documentation fixes (STR #2141, STR #2157) - - The HTTP upgrade redirection used by the scheduler did - not work with Internet Explorer (STR #2235) - - Members of a class with Unicode names did not appear - correctly in the web interface (STR #2154) - - Changing the "Save debugging information" setting in - the web interface no longer affects the other server - settings (STR #1993) - - The scheduler did not choose SSL certificates correctly - on Mac OS X (STR #2225) - - The scheduler could get in an infinite loop when - printing to a remote class (STR #2228) - - The jobs web page did not have separating space after - the number of pages column (STR #2230) - - Added French localization (STR #2221) - - Updated Spanish localization (STR #2223) - - Updated Japanese localization (STR #2216) - - cupsBorderlessScalingFacter was limited to a range of - 0.9 to 1.1, but some printers need larger values (STR - #2222) - - Landscape printing of PDF files did not always work - (STR #2149) - - Fixed slow USB printing on Minolta printers (STR #2104, - STR #2219) - - The ZPL label printer driver could produce stretched - output (PR #6448) - - The IPP backend now clears the printer-state-message - when there are no outstanding errors or warnings (STR - #2126) - - The CUPS Java scripting support did not work with - recent versions of Java due to the use of Sun's private - Base64 class (STR #2152) - - The scheduler did not pass HTTP GET form variables to - custom CGI programs (STR #2173) - - The lpoptions command now displays the reason why a PPD - file cannot be found (STR #2184) - - The scheduler did not accept "none" as a browse - protocol name (STR #2200) - - The scheduler still loaded the remote printer cache, - even when browsing was disabled (STR #2198) - - The SNMP backend now shows OfficeJet printers with the - "HP" manufacturer prefix (STR #2151) - - Web interface HTML cleanup (STR #2153) - - The parallel backend consumed 100% CPU on FreeBSD due - to an apparently common parallel port driver bug (STR - #2161) - - ippReadIO() incorrectly returned IPP_IDLE when the - initial IPP message header could not be read (STR - #2179) - - cupsRasterInterpretPPD() did not support custom options - (STR #1960) - - Collated output produced by the PostScript filter could - lose some options (STR #2137) - - job-hold-until with time values for the next day would - be held for 60 days (STR #2144) - - Some types of Sun raster files did not print correctly - (STR #2107) - - Raw PBM files did not print correctly (STR #2106) - - The SNMP backend no longer uses IPP with HP printers, - as some recent firmware versions appear to not work - (STR #2055) - - cupsMarkOptions() did not handle the - multiple-document-handling option (STR #2135) - - lpstat did not show the local job ID of active printers - (STR #2125) - - The backends incorrectly used STATUS: - media-tray-empty-error messages for out-of-paper - conditions (STR #2123, STR #2124) - - cupsGetPPD2() returned the wrong error when the PPD - file did not exist (STR #2122) - - cupsDoAuthentication() did not translate the password - prompt (STR #2121) - - httpGetLength2() did not handle error messages without - content correctly (STR #2133) - - Added support for 32/64-bit libraries on HP-UX Itanium - systems (STR #2115) - - Fixed a configure script problem with the 32/64-bit - library support (STR #2114) - - The PostScript filter did not properly output document - setup commands for reversed output (STR #2111) - - The scheduler did not parse IPv6 netmasks properly (STR - #2117) - - -CHANGES IN CUPS V1.2.7 - - - Documentation updates (STR #2089) - - Added an Italian translation (STR #2105) - - The PostScript filter now rotates the bounding box - values as needed (STR #2079) - - The scheduler no longer loads the remote printer cache - when browsing is disabled (STR #2084) - - The scheduler no longer writes a new launchd - configuration file if it doesn't have to (STR #2083) - - Updated the USB and PAP backends for Mac OS X (STR - #2086) - - The scheduler now picks up on changes to IPv6 and DNS - configuration on Mac OS X (STR #2085) - - The lpstat program could still hang (STR #2098) - - Fixed an inefficiency in the SNMP IPP detection code - (STR #2100) - - The SSL negotiation code did not implement short - timeouts (STR #2091) - - -CHANGES IN CUPS V1.2.6 - - - The web interface was not localized on Mac OS X (STR - #2075) - - "lpc status" did not show the number of queued jobs for - disabled queues (STR #2069) - - The lpstat program could hang (STR #2073) - - The serial backend did not support the new USB serial - filenames on Linux (STR #2061) - - The parallel backend did not support bidirectional I/O - properly (STR #2056) - - The network backends now log the numeric address that - is being used (STR #2046) - - Fixed a compile error when using libpaper. - - Fixed a compile error when compiling on Solaris with - threading enabled (STR #2049, STR #2050) - - Missing printer-state-changed event for - printer-state-message updates (STR #2047) - - -CHANGES IN CUPS V1.2.5 - - - Documentation updates (STR #2038) - - The SNMP backend no longer uses IPP for Epson printers - (STR #2028) - - Updated the configure script for Tru64 UNIX 5.1 (STR - #2033) - - Tru64 5.1B's getaddrinfo() and getnameinfo() functions - leak file descriptors (STR #2034) - - cupsAddDest() didn't add the parent destination's - options and attributes. - - ppdConflicts() did not handle custom option - constraints. - - Raw printing of gzip'd files did not work (STR #2009) - - The scheduler no longer preserves default option - choices when the new PPD no longer provides the old - default choice (STR #1929) - - The Linux SCSI backend is now only built if the SCSI - development headers are installed. - - USB printing to Minolta printers did not work (STR - #2019) - - Windows clients could not monitor the queue status (STR - #2006) - - The scheduler didn't log the operation name in the - access_log file for Create-Job and Print-Job requests. - - The PostScript filter now separates collated copies - with any required JCL commands so that JCL-based - finishing options act on the individual copies and not - all of the copies as a single document. - - The PostScript filter now disables duplex printing when - printing a 1-page document. - - cups-lpd didn't pass the correct - job-originating-host-name value (STR #2023) - - Fixed some speling errors in the German message catalog - (STR #2012) - - cupstestppd did not catch PPD files with bad - UIConstraints values (STR #2016) - - The USB backend did not work with the current udev- - created printers if the first printer was disconnected - (STR #2017) - - Mirrored and rotated printing did not work with some - documents (STR #2004) - - 2-sided printing with banners did not work properly on - some printers (STR #2018) - - Updated the raw type rule to handle PJL within the - first 4k of a print job (STR #1969) - - Added an Estonian translation (STR #1957) - - Clarified the documentation for the cupsd.conf @LOCAL - and @IF(name) allow/deny functionality (STR #1992) - - The PostScript filters did not escape the Title and For - comments in the print job header (STR #1988) - - The scheduler would use 100% CPU if browsing was - disabled and the cupsd.conf file contained BrowsePoll - lines (STR #1994) - - The cupsDirRead() function did not work properly on - non-POSIX-compliant systems (STR #2001) - - The cupsFile functions didn't handle read/write errors - properly (STR #1996) - - The DBUS support now works with older versions of the - DBUS library. - - -CHANGES IN CUPS V1.2.4 - - - The --with-printcap configure option did not work (STR - #1984) - - The character set reported by cupsLangGet() did not - always reflect the default character set of a given - locale (STR #1983) - - Older Lexmark and Tektronix printers did not work with - IPP (STR #1980) - - Failsafe printing did not work (PR #6328) - - Some web interface redirects did not work (STR #1978) - - The web interface change settings button could - introduce a "Port 0" line in cupsd.conf if there was no - loopback connection available (STR #1979) - - The web interface change settings and edit - configuration file buttons would truncate the - cupsd.conf file (STR #1976) - - The German web interface used the wrong printer icon - images (STR #1973) - - The "All Documents" link in the on-line help was - missing a trailing slash (STR #1971) - - The Polish web interface translation used the wrong - URLs for the job history (STR #1963) - - The "reprint job" button did not work (STR #1956) - - The scheduler did not always report printer or job - events properly (STR #1955) - - The scheduler always stopped the queue on error, - regardless of the exit code, if the error policy was - set to "stop-printer" (STR #1959) - - ppdEmitJCL() included UTF-8 characters in the JCL job - name, which caused problems on some printers (STR - #1959) - - Fixed a buffering problem that cause high CPU usage - (STR #1968) - - The command-line applications did not convert - command-line strings to UTF-8 as needed (STR #1958) - - cupsDirRead() incorrectly aborted when reading a - symbolic link that pointed to a file/directory that did - not exist (STR #1953) - - The cupsInterpretRasterPPD() function did not handle - custom page sizes properly. - - -CHANGES IN CUPS V1.2.3 - - - The scheduler did not send job-state or - job-config-changed events when a job was held, - released, or changed (STR #1947) - - The scheduler now aborts if the configuration file and - directory checks fail (STR #1941) - - Fixed a problem with ippPort() not using the port - number that was set via the client.conf file or - CUPS_SERVER environment variable (STR #1945) - - HTTP headers were not buffered (STR #1899) - - Some IPP printers (HP) did not like UTF-8 job names - (STR #1837) - - The CUPS desktop icon is now localized for Polish (STR - #1920) - - Printer options were not always honored when printing - from Windows clients (STR #1839) - - The openssl command would lock up the scheduler when - generating an encryption certificate on some platforms - due to a lack of entropy for the random number - generator (STR #1876) - - The web admin page did not recognize that "Listen 631" - enabled remote access (STR #1908) - - The web admin page did not check whether changes were - made to the Basic Server Settings check boxes (STR - #1908) - - The IPP backend could generate N*N copies in certain - edge cases. - - The scheduler did not restore remote printers properly - when BrowseShortNames was enabled (STR #1893) - - Polling did not handle changes to the network - environment on Mac OS X (STR #1896) - - The "make test" subscription tests used invalid - notify-recipient-uri values (STR #1910) - - Printers could be left in an undefined state on system - sleep (STR #1905) - - The Berkeley and System V commands did not always use - the expected character set (STR #1915) - - Remote printing fixes (STR #1881) - - The cupstestppd utility did not validate translation - strings for custom options properly. - - Multi-language PPD files were not properly localized in - the web interface (STR #1913) - - The admin page's simple settings options did not check - for local domain socket or IPv6 addresses and did not - use "localhost" as the listen address. - - An empty BrowseProtocols, BrowseLocalProtocols, or - BrowseRemoteProtocols line would crash the scheduler - instead of disabling the corresponding browsing options. - - The scheduler now logs IPP operation status as debug - messages instead of info or error. - - cupsFileRewind() didn't clear the end-of-file state. - - cupstestppd didn't report the actual misspelling of the - 1284DeviceID attribute (STR #1849) - - BrowseRelay didn't work on Debian (STR #1887) - - configure --without-languages didn't work (STR #1879) - - Manually added remote printers did not work (STR #1881) - - The header was not installed. - - Updated the build files for Autoconf 2.60 (STR #1853) - - The scheduler incorrectly terminated the polling - processes after receiving a partial log line. - - The cups-lpd mini-daemon reported "No printer-state - attribute found" errors when reporting the queue status - (PR #6250, STR #1821) - - SNMP backend improvements (STR #1737, STR #1742, STR - #1790, STR #1835, STR #1880) - - The scheduler erroneously reported an error with the - CGI pipe (STR #1860) - - Fixed HP-UX compile problems (STR #1858, STR #1859) - - cupstestppd crashed with some PPD files (STR #1864) - - The and header files did not - work with C++. - - -CHANGES IN CUPS V1.2.2 - - - Documentation updates (STR #1765, STR #1780) - - CUPS didn't know about alternate character set names - for Asian text (STR #1819) - - The lpoptions -o and -r options did not work unless you - specified a printer. - - The lpoptions command incorrectly allowed users to set - printer attributes like printer-type (STR #1791) - - httpWait() did not flush the write buffer, causing "bad - request" errors when communicating with CUPS 1.1.x - servers (STR #1717) - - Polling did not sanitize the printer description, - location, or make and model strings like broadcasts - did. - - Polled printers did not show the server's default - job-sheets option value. - - The Samba password prompt was not properly localized - (STR #1814) - - Added a German translation (STR #1842) - - The scheduler now creates self-signed SSL certficates - automatically when using OpenSSL and CDSA for - encryption, just as for GNU TLS. - - The SNMP backend sporatically reported some printers as - "unknown" (STR #1774) - - The scheduler now forces BrowseTimeout to be at least - twice the BrowseInterval value and non-zero to avoid - common configuration errors. - - The scheduler incorrectly returned printer URIs of the - form "ipp://server/printers/classname" for classes (STR - #1813) - - Updated Japanese localization (STR #1805) - - The scheduler's SSL certificate/key directory was not - created on installation (STR #1788) - - Added a mailto.conf man page and help page (STR #1754) - - The parallel and USB backends no longer wait for the - printer to go on-line - this caused problems with - certain printers that don't follow with the IEEE-1284 - standard (STR #1738) - - The scheduler could crash on a reload when implicit - classes were present (STR #1828) - - The IPP backend incorrectly used the CUPS_ENCRYPTION - environment variable to determine the default - encryption mode when printing (STR #1820) - - USB printing did not work on Solaris (STR #1756) - - The scheduler sorted job priorities in the wrong order - (STR #1811) - - The scheduler did not automatically restart notifiers - that exited or crashed (STR #1793) - - IPv6 support did not work on NetBSD (STR #1834) - - The EPM packaging file did not work (STR #1804) - - The scheduler used up the CPU if BrowseRemoteProtocols - was empty (STR #1792) - - Custom page sizes did not work (STR #1787) - - The SNMP backend could crash on some systems when SNMP - logging was enabled (STR #1789) - - Browsing could produce some funny printer names when - ServerName was set to an IP address (STR #1799) - - Fixed the log message for BrowseRelay (STR #1798) - - Fixes to allow CUPS to compile on MirBSD (STR #1796) - - The scheduler incorrectly set the FINAL_CONTENT_TYPE - environment variable (STR #1795) - - The pdftops filter incorrectly embedded a "produced by" - comment, causing PDF printing not to work on some - operating systems (STR #1801) - - Sending raw jobs from a client system could cause the - client's scheduler to eventually crash (STR #1786) - - The scheduler now checks that the notifier exists prior - to accepting a new subscription request. - - The scheduler now reports the supported - notify-recipient schemes based on the contents of the - ServerBin/notifier directory. - - Event notifications did not include the - notify-sequence-number or other required attributes - (STR #1747) - - Allow/Deny addresses of the form "11.22.33.*" did not - work on Linux (STR #1769) - - cupsGetPPD() did not work if the scheduler was only - listening on a domain socket (STR #1766) - - The scheduler could crash advertising a class (STR - #1768) - - The scheduler could crash if the default printer was - deleted (STR #1776) - - Added a new default CUPS raster format (v3) which does - not compress the raster stream in order to provide the - same cupsRasterReadPixels() and cupsRasterWritePixels() - performance as CUPS 1.1.x. - - The cupsaddsmb man page listed the wrong files for the - CUPS driver. - - Some configure --with options did not work (STR #1746) - - "Allow @IF(name)" didn't work if "name" wasn't the - first network interface (STR #1758) - - The lpstat command did not use the correct character - set when reporting the date and time (STR #1751) - - The cupsaddsmb command and web interface did not update - the Windows PPD files properly, resulting in corrupt - PPD files for the Windows client to use (STR #1750) - - The cupsd.conf man page didn't describe the Listen - domain socket syntax (STR #1753) - - The scheduler no longer tries to support more than - FD_SETSIZE file descriptors. - - CDSA (encryption) support fixes for MacOS X. - - The lppasswd program needs to be setuid to root to - create and update the /etc/cups/passwd.md5 file (STR - #1735) - - 32/64-bit library installation was broken (STR #1741) - - The USB backend now reports a "no such device" error - when using the old filename-based USB URIs instead of - the "success" error. - - Increased the HTTP and IPP read timeouts to 10 seconds, - as 1 second was too short on congested networks (STR - #1719) - - The SNMP backend now uses the device description over - the printer-make-and-model attribute when the attribute - contains a generic name (STR #1728) - - Fixed another file descriptor leak when printing raw - files (STR #1736) - - Raw queues were not shared via LDAP (STR #1739) - - The pstops filter didn't always embed PageSetup - commands from the PPD file (STR #1740) - - "make install" didn't work if you disabled all of the - localizations. - - The scheduler didn't always choose the least costly - filter. - - Fixed parsing of IPv6 addresses in Allow, Deny, - BrowseAllow, BrowseDeny, and BrowseRelay directives - (STR #1713) - - Printers that were shared via LDAP did not get added to - the LDAP server properly (STR #1733) - - LDAP browsing would crash the scheduler if a required - value was missing (STR #1731) - - Special cases for the "localhost" hostname did not - work, causing printing to not work when the /etc/hosts - file did not contain a localhost entry (STR #1723) - - Updated the Spanish translation (STR #1720, STR #1770) - - Reverse-order page output was broken when N-up or - landscape orientations were used (STR #1725) - - The parallel, serial, socket, and USB backends needed - print data before they would report back-channel data, - causing problems with several new drivers (STR #1724) - - -CHANGES IN CUPS V1.2.1 - - - "lprm -h hostname" did not work (STR #1800) - - The web interface did not handle reloads properly for - MSIE (STR #1716) - - The configure script no longer adds linker rpath - options when they are unnecessary. - - The scheduler could crash printing a debug message on - Solaris (STR #1714) - - The --enable-32bit and --enable-64bit configure options - did not always work. - - The password prompt showed the domain socket address - instead of "localhost" for local authentication (STR - #1706) - - The web interface filtered the list of printers even if - the user wasn't logged in (STR #1700) - - The IPP backend did not work reliably with some Xerox - printers (STR #1704) - - Trailing banners were not added when printing a single - file (STR #1698) - - The web interface support programs crashed on Solaris - (STR #1699) - - cupstestppd incorrectly reported problems with - *1284DeviceID attributes (STR #1710) - - Browsing could get disabled after a restart (STR #1670) - - Custom page sizes were not parsed properly (STR #1709) - - The -U option wasn't supported by lpadmin (STR #1702) - - The -u option didn't work with lpadmin (STR #1703) - - The scheduler did not create non-blocking back-channel - pipes, which caused problems when the printer driver - did not read the back-channel data (STR #1705) - - The scheduler no longer uses chunking in responses to - clients - this caused problems with older versions of - CUPS like 1.1.17 (PR #6143) - - Automatic raw printing was broken (STR #1667) - - 6-up printing was broken (STR #1697) - - The pstops filter did not disable CTRL-D processing on - the printer/RIP. - - ppdOpen*() did not load custom options properly (STR - #1680) - - "Set Printer Options" in the web interface did not - update the DefaultImageableArea or - DefaultPaperDimension attributes in the PPD file (STR - #1689) - - Fixed compile errors (STR #1682, STR #1684, STR #1685, - STR #1690) - - The lpstat command displayed the wrong error message - for a missing destination (STR #1683) - - Revised and completed the Polish translation (STR - #1669) - - Stopped jobs did not show up in the list of active jobs - (STR #1676) - - The configure script did not use the GNU TLS - "libgnutls-config" script to find the proper compiler - and linker options. - - The imagetoraster filter did not correctly generate - several 1, 2, and 4-bit color modes. - - cupsRasterWritePixels() could lose track of the current - output row. - - cupsRasterReadPixels() did not automatically swap - 12/16-bit chunked pixel data. - - Moved the private _cups_raster_s structure out of the - public header. - - Updated the CUPS raster format specification to include - encoding rules and colorspace definitions. - - The Zebra PPD files had the wrong PostScript code for - the "default" option choices. - - The imagetoraster filter did not generate correct CIE - XYZ or Lab color data. - - The cups-config script did not work when invoked from a - source directory (STR #1673) - - The SNMP backend did not compile on systems that used - the getifaddrs emulation functions (STR #1668) - - -CHANGES IN CUPS V1.2.0 - - - Documentation updates (STR #1618, STR #1620, STR #1622, - STR #1637) - - Static file copy buffers reduced from 64k to 32k to - work around bogus MallocDebug library assumptions (STR - #1660) - - The scheduler did not decode the backend exit code - properly (STR #1648) - - The MacOS X USB backend did not report the 1284 device ID, - nor did it fix device IDs returned by HP printers. - - The scheduler started more slowly than 1.1.x with large - numbers of printers (STR #1653) - - cupsRasterInterpretPPD() didn't support the - cupsPreferredBitsPerColor attribute, and imagetoraster - didn't use the new API. - - The "make test" script did not create all of the necessary - subdirectories for testing (STR #1638) - - The scheduler did not prevent rotation of logs - redirected to /dev/null (STR #1651) - - "make test" did not include the SNMP backend in the - test environment (STR #1625) - - The EPM packaging files did not work (STR #1621) - - "Use Default Configuration" inserted a broken - configuration file (STR #1624) - - Redirects in the web interface did not always preserve - the encrypted status of a connection (STR #1603) - - Added the Apple "pap" backend. - - Added CUPS library to CUPS Image shared library - linkage to support Linux --as-needed linker option - (STR #1606) - - Fixed support for --enable-pie (STR #1609) - - The pdftops filter did not validate the length of the - encryption key (STR #1608) - - Updated the Polish localization. - - "Encryption Required" in the cupsd.conf file now only - requires encryption when the connection is not over the - loopback interface or domain socket. - - Printer names containing "+" were not quoted properly in - the web interface (STR #1600) - - The SNMP backend now reports the make and model in the - information string so that the auto-generated printer - name is more useful than just an IP address. - - -CHANGES IN CUPS V1.2rc3 - - - The cups-lpd program always did reverse lookups on the - client address, which could be a performance problem. - Added a "-n" option to disable lookups. - - When configured with SSL support, require encryption by - default when displaying the /admin location (STR #1592) - - The next job ID was not computed correctly if the job - cache file got out of sync with the spool directory - (STR #1582) - - The PNG image handling code used deprecated functions - from libpng (STR #1587) - - Added a Polish translation (STR #1584, STR #1586) - - More changes to the scheduler to improve battery life - on portable devices (STR #1583) - - Changed the default log level for status messages back - to "DEBUG" to be consistent with CUPS 1.1.x (STR #1579) - - The error string was not set properly when - cupsDoFileRequest() was given the name of a directory - (STR #1578) - - Fixed handling of job-hold-until (STR #1581) - - Added explicit notes to the cupsaddsmb man page - explaining that the driver filenames are case-sensitive - under UNIX and that they must be all lowercase (Windows - 2000) or all UPPERCASE (Windows 95/98/Me) to work (STR - #1568) - - The USB backend incorrectly split the manufacturer name - if it contained spaces (STR #1566) - - The scheduler would hang when listing PPD files for a - manufacturer whose name contained spaces (STR #1567) - - Added the SNMP backend for network printer discovery - (STR #1555) - - cupstestppd now fails PPD files with 1284DeviceId - instead of 1284DeviceID, and cups-driverd uses a - case-insensitive comparison when looking for it (STR - #1573) - - cupsDoFileRequest() and cupsDoRequest() now work - properly with non-blocking HTTP connections. - - Added Swedish translation (STR #1569) - - "make install" now installs the MIME files with world - read permissions (STR #1565) - - More CDSA encryption support fixes (STR #1563) - - Updated the default mime.types file to support printing - of files that do not have a locally-recognized MIME - media type to raw or System V queues. - - Updated the serial port detection code on Linux (STR - #1562) - - Added some more error checking to httpGetHostname() - (STR #1561) - - The title of some administration pages was not - localized (STR #1548) - - The edit-config.tmpl file was not generated or - installed for the Spanish or Japanese localizations - (STR #1547) - - The mimeDelete() function freed the types before the - filters, but the filters needed the type data (STR #1558) - - The scheduler didn't keep track of the status pipes - properly, leading to a bad select() for multi-file jobs - (STR #1559) - - The cupstestdsc program didn't validate the ordinal - page number value for %%Page: comments. - - -CHANGES IN CUPS V1.2rc2 - - - The scheduler was not always using the string pool, - causing random crashes. - - The lpmove and the web interface's Move Job button did - not work with stopped jobs (STR #1534) - - The PostScript filter did not handle the page-set - option properly with number-up printing (STR #1543) - - The scheduler now only warns about unsupported ACLs - once (STR #1532) - - The "fitplot" option did not work with output from - Mozilla (STR #1542) - - The imagetops filter did not work with Level 2 or 3 - printers (STR #1533) - - The scheduler now recognizes PostScript files with PJL - commands that do not include an ENTER LANGUAGE command. - - Added --with-printcap configure option. - - 64-bit SSL fixes for MacOS X. - - The scheduler didn't send some printer state change - events. - - The scheduler didn't send jobs to busy remote printers. - - Fixed some problems with the launchd support. - - Added new USB printer backend for MacOS X. - - The PostScript filter now handles files that start with - an incomplete PJL header (PR #6076) - - The web interface language selection code did not try - the generic language localization (STR #1531) - - The language cache, string pool, and transcoding caches - are now process global instead of per-thread to avoid - problems with GNOME and to allow for data sharing - between threads (STR #1530) - - Fixed a CUPS 1.1.x compatibility bug (STR #1528) - - The web interface redirection after certain printer - administration tasks was broken (STR #1516) - - Web interface authorization could get stuck (STR #1512) - - Localization updates (STR #1513, STR #1518, STR #1520) - - The pstops filter didn't work with some files (STR - #1523) - - "./configure --enable-static" didn't work (STR #1522) - - The scheduler was not using the configured default - Group (STR #1521) - - The web interface still did not show the localized time - and date for some locales and systems (STR #1509) - - httpAddrGetList() would crash on systems without - getaddrinfo(). - - Socket URIs without a trailing slash would cause the - port number to not be accepted (STR #1519) - - Local raw and System V printers were not advertised as - such for printer browsing (STR #1502) - - The RPM spec file incorrectly put duplicate copies of - the Japanese and Spanish web interface templates in the - main cups package (STR #1517) - - cupsSetDests() did not explicitly set the permissions - of the /etc/cups/lpoptions file (STR #1508) - - The lpq command crashed with the -h option (STR #1515) - - -CHANGES IN CUPS V1.2rc1 - - - Documentation updates (STR #1497, STR #1498) - - The scheduler now redirects browsers to https: URLs - when encryption is required. - - The scheduler would crash when printing with a banner - (STR #1500) - - cups-driverd did not use the LanguageEncoding attribute - in PPD files to convert the NickName to UTF-8 (STR - #1503) - - The lpadmin command could not set the - printer-error-policy attribute (STR #1504) - - The web interface did not show the time and date in the - correct format for the locale (STR #1505) - - CUPS no longer accepts print jobs if a printer does not - support the file format (STR #1501) - - Cleaned up the PostScript filter (pstops) so that it - properly supports %%IncludeFeature and page scaling - (STR #1453) - - Fixed the cupsFileRewind() and cupsFileSeek() functions - to work properly with uncompressed files. - - Added cupsFileGetLine(), cupsFileStderr(), - cupsFileStdin(), and cupsFileStdout() functions to the - CUPS library. - - Added a new cupstestdsc program to test the DSC - conformance of PostScript files. - - Added KDE/GNOME icons and a Manage Printers menu item. - - Added --enable-image and --enable-pdftops configure - options to control whether the image and PDF filters - are built and installed (default = yes for all - platforms but MacOS X) - - Fixed a minor memory leak in the PPD API. - - Fixed transcoding issues (STR #1493) - - The scheduler now enforces a minimum job cost of 100 - when doing FilterLimit checks. - - The scheduler would leak file descriptors when printing - to raw queues (STR #1491) - - The IPv6 support did not compile on Tru64 UNIX (STR - #1488) - - ppdOpen2() now converts the NickName and all UI text to - UTF-8 (STR #1475) - - The Set Allowed Users web page did not work (STR #1486) - - When the default policy was not set or set to a non- - existing policy, the scheduler did not set the default - policy name to "default" (STR #1484) - - The Zebra CPCL driver did not use the correct righthand - margin for the 4" wide label sizes. - - Fixed a problem with the parsing of fractional real - numbers in PPD files. - - Added Spanish localization files (STR #1480) - - Fixed localization of a few scheduler messages (STR - #1478) - - Fixed support for HEAD requests in the scheduler (STR - #1481) - - -CHANGES IN CUPS V1.2b2 - - - Updated the CUPS design description. - - Added --enable-32bit and --enable-64bit configure - options to allow building of separate 32/64-bit - libraries on systems that support both environments - (STR #1472) - - Various compiler warning fixes. - - Fixes for Solaris 10 builds against old GNU TLS and - LDAP libraries. - - Added a cupsArrayUserData() function to retrieve the - user data pointer for an array (useful for typing - arrays) - - The ppdEmitString() function did not compute the - required buffer size properly, leading to dropped - characters on the end of the printer commands in pstops - and imagetops (STR #1470) - - -CHANGES IN CUPS V1.2b1 - - - The serial backend now supports Equinox 8-port serial - hubs (STR #526) - - The IPP backend now supports a compression option to - compress print files as they are sent to the remote - server (STR #956) - - The CUPS browse protocol now supports passing of - default options and browse timeout values from the - server to the clients (STR #800) - - Implicit classes that timed out could cause the - scheduler to crash (STR #1439) - - Added DragonFly support in local device backends (STR - #1362) - - Added LDAP printer browsing support (STR #338) - - Added official support for printer maintenance commands - via the CUPS Command file format and hooks in the - printer-type and web interfaces (STR #932) - - The HP-GL/2 filter could get in an infinite loop trying - to convert HP-PCL files (STR #1415) - - CUPS now implements the HTTP/1.1 Expect header (STR - #1407) - - Options in PPD files are no longer automatically put in - an "Extra" group; rather, all options that are not - inside an Open/CloseGroup will be placed in the - "General" group (STR #1385) - - The scheduler now creates a job-uuid attribute that - uniquely identifies a job on a network (STR #1410) - - The init script now unsets the TMPDIR environment - variable to prevent user temporary directories from - being used by cupsd accidentally (STR #1424) - - Added support for launchd on MacOS X. - - Added support for notify_post on MacOS X. - - Added support for DBUS on Linux. - - All of the Berkeley (except for lpc) and System V - commands now support specification of user, host, and - port (STR #1028, STR #1029, STR #1087) - - The lpmove command now allows you to move all jobs for - a given queue (STR #56) - - The web interface now supports moving of a job or jobs - to another queue (STR #56) - - The web interface now provides searching, paging, and - changing of the sort/display order of classes, jobs, - and printers. - - cupsaddsmb now accepts a password on the command-line - and supports passwords with special characters (STR - #822, STR #1236) - - ppdLoad*() no longer tries to "fix" bad characters in - UI text (STR #1101) - - Printer names can now (reliably) contain Unicode - characters (STR #896) - - The lpstat command now shows the time and date of the - last printer state change instead of the hardcoded "Jan - 01 00:00" (STR #659) - - The scheduler now adds a job-actual-printer-uri - attribute to job objects when printing to a class (STR - #116) - - The scheduler now logs log file open errors to the - system log (STR #1289) - - The scheduler now sets the job-originating-user-name to - the authenticated username, if available (STR #1318) - - The scheduler now only updates the permissions of SSL - keys and certificates when they are under the - ServerRoot directory (STR #1324) - - The rastertodymo driver has been renamed to - rastertolabel (a symlink is installed so that existing - queues continue to work) and now also supports Zebra's - CPCL language. - - The lpstat command could show the wrong active job for - a printer (STR #1301) - - Fixed a potential crash problem in the scheduler when - aborting a CGI program (STR #1290) - - Added a "cancel all jobs" button to the class and - printer web interfaces (STR #1140) - - The add-printer web page now shows the - set-printer-options page after the printer has been - added (STR #690) - - The classes web page now provides links to each of the - member printers (STR #307) - - CUPS now handles HTTP request/response lines up to 32k - in length; this is mainly for better cookie support - (STR #1274) - - Added support for the Apache PassEnv and SetEnv - directives to cupsd.conf (STR #853) - - Added large file (64-bit) support (STR #541) - - Fixed a performance issue with the ippReadIO() - implementation (STR #1284) - - Fixed a performance issue with the scheduler's implicit - class implementation (STR #1283) - - The pdftops filter now adds the Title and Creator - fields from the PDF file to the PostScript document - comments section (STR #539, STR #830) - - Added a new cups_array_t and cupsArray*() functions to - the CUPS API to support sorted lists of data. - - Made the CUPS API library thread-safe (STR #1276) - - Added "media" option support for EFI EFMediaType option - (STR #902) - - Added write buffering to the HTTP code to improve - performance (STR #547) - - The scheduler now uses the attributes-natural-language - attribute to localize banner pages (STR #386) - - The scheduler now returns the address that was used to - connect to it (STR #1076) - - Fixed a problem with N-up printing and OpenOffice (STR - #576) - - Added support for the GCC position independent - executable options (STR #1209) - - Added new BrowseLocalProtocols and - BrowseRemoteProtocols directives to cupsd.conf, - allowing for different browse protocols for local and - remote printers (STR #877) - - PPD files can now contain strings up to 256k in length - (STR #1215) - - The pstops filter now supports the IncludeFeature DSC - comment (STR #1212) - - The pstops filter now disables the setpagedevice - procedure when doing N-up printing (STR #1161) - - The serial backend now supports "stop=1", "stop=2", - "parity=space", and "parity=mark" options (STR #1155) - - "make install" no longer overwrites an existing PAM - configuration file (STR #1064) - - The scheduler now closes all files on startup when run - in daemon mode (STR #1009) - - Added a new RGBW colorspace to the CUPS raster format - (STR #1071) - - The pdftops filter now sets the page size based on the - media box when not scaling the output (STR #912) - - The pdftops filter now supports masked images (STR - #281) - - The pdftops filter produced large output when rendering - PDF files containing lot of repeated images (STR #327) - - The pdftops filter now minimizes print processing of - PDF files when using the page-ranges option (STR #273) - - Updated pdftops filter to Xpdf 3.01. - - Added new cupsBackchannelRead() and - cupsBackchannelWrite() functions, as well as - backchannel support to the parallel, serial, socket, - and USB backends (STR #1252) - - The parallel and USB backends now treat a "no space - available" error as an out-of-paper condition (STR - #1225) - - The "lpc" command now supports the "status all" command - (STR #1004) - - ippReadIO() did not read collections properly (STR - #1249) - - The "make test" script now creates the test files in - "/tmp/cups-$USER" instead of "/tmp/$USER" (STR #981) - - All backends now abort on error when printing a job to - a class - this allows the next printer in the class to - print the job (STR #1084) - - The scheduler now verifies that a printer supports - Letter or A4 media sizes before setting them as the - initial default (STR #1250) - - The cupstestppd program now flags bad Resolution - options (STR #1269) - - The USB backend now retries printing when the printer - is disconnected or turned off (STR #1267) - - Added new httpGetHostname() function to CUPS API, and - use it instead of gethostname() so that the web - interface will work correctly on systems whose hostname - is not the FQDN (STR #1266) - - The scheduler now stops printers if the backend for the - queue is missing on startup (STR #1265) - - The configure script now supports "--disable-library" - to disable particular image file format support - libraries, even if they are available on the build - system (STR #1248) - - The IPP backend did not always report on the total - number of pages that were printed (STR #1251) - - The lpstat program could display garbage date and time - values for locales whose date format exceeded 31 - characters (STR #1263) - - The cupstestppd program would segfault when testing - certain broken PPD files (STR #1268) - - Dramatically reduced the overhead of implicit classes. - - Added new cupsDir*() functions to CUPS API. - - Printers can now be published individually for sharing. - - Fixed a bug in the scheduler's startup signalling code - which caused cupsd to send the SIGUSR1 signal to the - init process instead of the original parent process - (STR #1258) - - Added new on-line help CGI to web interface to provide - searchable help. - - Devices are now tracked dynamically, with each query - doing a new device scan. This eliminates a previous - startup delay caused by slow backends and allows new - printers to be seen without restarting the server, - however it limits the amount of device URI checking - that can be done (basically now the scheduler only - requires a URI with a method that is a listed backend) - - Added new printer auto-detection, server configuration, - and log file viewing to the administration web page. - - Added new "set allowed users" web interface to set the - list of allowed users for a printer or class. - - The scheduler, command-line, and web interfaces now - limit the list of printers and classes to those - accessible by a user. - - cupsMarkOptions() now handles more non-standard - duplexing options and choices (STR #915) - - cups-lpd now honors remote banner requests with the - "standard" banner whenever a printer does not have one - defined (STR #1220) - - The scheduler's denial-of-service checks did not work - properly with IPv6 addresses (STR #1134) - - The lp and lpr commands did not error out properly when - they were unable to write to a temporary file (STR - #1129) - - The pstops filter did not handle Adobe-specific - comments in Windows NT driver output (STR #1085) - - "lpstat -l -p" incorrectly reported the printer - interface (STR #936) - - The web interface now operates exclusively with the - UTF-8 encoding, and sends the appropriate character set - and header information to the web browser (STR #919, - STR #1007) - - Added a "set allowed users" interface to the web - interface so that you can set the list of allowed or - denied users/groups for a printer or class. - - Disallow the "#" character in printer names, since it - has special meaning in the shell, config files, and in - URIs (STR #917, STR #1202) - - Added a new application/x-csource MIME type, and - support for it to the texttops filter so that you can - pretty print plain text files without the C/C++ - keywords being highlighted. - - The pdftops filter did not compile with GCC 4.0 (STR - #1226) - - The texttops filter did not highlight preprocessor - directives followed by a tab properly. - - HP PJL output now uses both JOB DISPLAY and RDYMSG - commands to show the current job on the printer's - display (STR #1218) - - Local authentication certificates are now stored in - /var/run/cups/certs by default instead of - /etc/cups/certs (STR #1211) - - Backends now use "&" to separate options in device - URIs; "+" is still recognized but is deprecated (STR - #842) - - The USB backend no longer supports the usb:/dev/foo - format on systems that support device ID queries. - - Forced classification markings did not work when the - job-sheets parameters were "none,none". - - "lpstat -l -p" incorrectly showed all users as allowed, - even if the queue was restricted to certain users (STR - #801) - - The scheduler now automatically detects SSL/TLS clients - without using the SSLPort/SSLListen directives. - - The CUPS API and scheduler no longer support SSLv2- - encrypted connections. - - Updated the cupsaddsmb utility to correctly export the - CUPS driver for Windows. - - Fixed a signal-handling bug in httpRead() which - ultimately caused the server to print multiple copies - when it was busy (STR #1184) - - The cupsFile API now uses the O_APPEND option when - opening files in append mode (STR #990) - - The md5.h header and md5_* functions are now officially - private and have been renamed to avoid conflicts with - other implementations with the same name. - - The pdftops filter incorrectly embedded some Type1 - fonts (STR #1093) - - The scheduler didn't detect a closed connection in the - middle of an IPP request (STR #1153) - - The scheduler could block trying to read the job status - if there was input pending and the job was cancelled in - the same input cycle (STR #1157) - - The scheduler could crash when deleting a class due to - infinite recursion. - - Updated the Zebra ZPL label printer driver to use the - run-length encoding and support more options. - - Updated serial backend to scan for /dev/ttyC* as well - as /dev/ttyc* for Cyclades serial ports (STR #1049) - - The scheduler could hang reading the job status under - certain circumstances (STR #1068) - - The USB backend termination signal code was inverted - (STR #1046) - - Moved enable and disable commands to sbindir to be - consistent. - - Added new cupsRasterInterpretPPD() function for RIP - filters to setup the raster page header from - PostScript commands in a PPD file. - - The CUPS browsing protocol now offers a "delete" bit - to remove printers as soon as they are deleted on the - server or as soon as the server shuts down gracefully - (STR #793) - - The CUPS_SERVER and ServerName directives (client.conf - and ~/.cupsrc) may now contain names of the form - "server:port" and "/path/to/domain/socket". - - The "cancel -u user" command now works for ordinary - users (STR #751) - - Added test run support to "make test" target (STR #64) - - Added domain socket support (STR #656) - - Added BrowseLocalOptions directive to allow the - administrator to add printer URI options to the browse - URI, e.g. "encryption=required" (STR #732) - - Added BrowseRemoteOptions directive to allow the - administrator to add standard URI options to the - remote printer URI, e.g. "encryption=required" (STR - #732) - - Now put "-I.." compiler option in front of all others - to ensure that local CUPS headers are used before - installed headers (STR #437) - - New cupsLangPrintf() and cupsLangPuts() for localized - interfaces. - - Now support custom attributes and extended options in - PPD files. - - Now provide functions to save PPD files. - - New policy mechanism allows per-operation and - per-printer control over what users and groups are - allowed to do various IPP operations. - - New error policy mechanism to control how aborted - backend errors are handled by the scheduler - (abort-job, retry-job, requeue-job, stop-printer) - - Updated the printer test page with a better color - wheel and a separate grayscale ramp. - - A single backend process is now run to send all print - data for a job. - - Backends and filters can now send and receive - backchannel data over file descriptor 3. - - Updated the raster stream format to support more - user-defined attributes and to do compression of the - page data. +CHANGES IN CUPS V1.3 + + - Documentation updates (STR #2130, STR #2131) + - Added support for DNS-SD (aka "Bonjour") printer sharing + (STR #1171) + - Job operations (cancel, hold, release, etc.) from the + web interface now return back to the original page (STR + #2239) + - The classes or printers list is now shown after a + successful deletion from the web interface (STR #1999) + - The default configuration now allows browse packets from + any address (STR #2008) + - The web interface now provides an "allow printing from the + Internet" check box (STR #1897) + - The notify-events-default and + notify-lease-duration-default attributes can now be set + (STR #1671) + - Server-side default options are now sent to clients when + the "printer-defaults" attribute group is requested (STR + #1923) + - Added support for Linux "relro" linker option (STR #1614) + - CUPS now validates the number-up option value (STR #1329) + - The on-line help now provides better search capabilities + (STR #1701) + - The web interface "Add This Printer" button now allows you + to change the printer name, description, and location + (STR #1646) + - Added support for Mac OS X authorization services + (STR #2206) + - Added support for driver-specific pre-filters (STR #2108) + - Added a new side-channel API for drivers and backends + for basic device control and information queries (STR + #1898) + - The scheduler now uses poll(), epoll(), or /dev/kqueue + instead of select() when possible (STR #1261) + - Added new cupsArrayGetIndex() and cupsArrayGetInsert() + functions to get the current index and insertion + positions of an array. + - Added a new --with-max-copies configure option (STR + #2090) + - Added new cupsRemoveDest() and cupsSetDefaultDest() + functions. + - Added support for cupsPJLCharset attribute in PPD files + which specifies the character set that is used in PJL + strings (STR #1969) + - Moved the definition of the (private) _http_s structure + to http-private.h; code that directly accesses the + http_t members will no longer compile! + - Added support for setting the document-format-default + attribute on a per-printer basis. + - Added support for IntelliBar label printers. diff --git a/INSTALL.txt b/INSTALL.txt index b9636837c..329409b37 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -1,5 +1,5 @@ -INSTALL - CUPS v1.2.8 - 2007-02-14 ----------------------------------- +INSTALL - CUPS v1.2rc1 - 2006-03-24 +----------------------------------- This file describes how to compile and install CUPS from source code. For more information on CUPS see the file called diff --git a/LICENSE.txt b/LICENSE.txt index 4a3e913c3..aee2abed0 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -101,6 +101,42 @@ No developer is required to provide these exceptions in a derived work. +KERBEROS SUPPORT CODE + +The Kerberos support code ("KSC") is copyright 2006 by Jelmer +Vernooij and is provided 'as-is', without any express or implied +warranty. In no event will the author or Easy Software Products +be held liable for any damages arising from the use of the KSC. + +Sources files containing KSC have the following text at the top +of each source file: + + This file contains Kerberos support code, copyright 2006 by + Jelmer Vernooij. + +The KSC copyright and license apply only to Kerberos-related +feature code in CUPS. Such code is typically conditionally +compiled based on the present of the HAVE_GSSAPI preprocessor +definition. + +Permission is granted to anyone to use the KSC for any purpose, +including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + + 1. The origin of the KSC must not be misrepresented; you + must not claim that you wrote the original software. If + you use the KSC in a product, an acknowledgment in the + product documentation would be appreciated but is not + required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original + software. + + 3. This notice may not be removed or altered from any source + distribution. + + TRADEMARKS Easy Software Products has trademarked the Common UNIX Printing diff --git a/Makedefs.in b/Makedefs.in index 97c55e09c..9e49bdb31 100644 --- a/Makedefs.in +++ b/Makedefs.in @@ -1,9 +1,9 @@ # -# "$Id: Makedefs.in 5799 2006-08-03 00:54:38Z mike $" +# "$Id: Makedefs.in 6332 2007-03-12 16:08:51Z mike $" # # Common makefile definitions for the Common UNIX Printing System (CUPS). # -# Copyright 1997-2006 by Easy Software Products, all rights reserved. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the # property of Easy Software Products and are protected by Federal @@ -93,6 +93,7 @@ LIBMALLOC = @LIBMALLOC@ LIBPAPER = @LIBPAPER@ LIBPNG = @LIBPNG@ LIBSLP = @LIBSLP@ +LIBGSSAPI = @LIBGSSAPI@ LIBTIFF = @LIBTIFF@ LIBZ = @LIBZ@ @@ -129,10 +130,12 @@ CXXFLAGS = -I.. $(SSLFLAGS) @CPPFLAGS@ @CXXFLAGS@ \ CXXLIBS = @CXXLIBS@ DSOFLAGS = @DSOFLAGS@ DSOLIBS = @DSOLIBS@ $(COMMONLIBS) +DNSSDLIBS = @DNSSDLIBS@ IMGLIBS = @IMGLIBS@ IMGFILTERS = @IMGFILTERS@ +LAUNCHDLIBS = @LAUNCHDLIBS@ LDFLAGS = -L../cups -L../filter $(ARCHFLAGS) \ - @LDFLAGS@ @PIEFLAGS@ $(OPTIM) + @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM) LINKCUPS = @LINKCUPS@ $(SSLLIBS) LINKCUPSIMAGE = @LINKCUPSIMAGE@ LIBS = $(LINKCUPS) $(COMMONLIBS) @@ -144,7 +147,6 @@ PDFTOPS = @PDFTOPS@ PHPDIR = @PHPDIR@ SSLFLAGS = @SSLFLAGS@ SSLLIBS = @SSLLIBS@ -LAUNCHDLIBS = @LAUNCHDLIBS@ # # Separate 32/64-bit library support... @@ -206,6 +208,7 @@ BINDIR = $(BUILDROOT)@bindir@ CACHEDIR = $(BUILDROOT)@CUPS_CACHEDIR@ DATADIR = $(BUILDROOT)@CUPS_DATADIR@ DOCDIR = $(BUILDROOT)@CUPS_DOCROOT@ +ICONDIR = @ICONDIR@ INCLUDEDIR = $(BUILDROOT)$(includedir) INITDIR = @INITDIR@ INITDDIR = @INITDDIR@ @@ -213,7 +216,11 @@ LIBDIR = $(BUILDROOT)$(libdir) LOCALEDIR = $(BUILDROOT)@CUPS_LOCALEDIR@ LOGDIR = $(BUILDROOT)@CUPS_LOGDIR@ MANDIR = $(BUILDROOT)@mandir@ +MENUDIR = @MENUDIR@ PMANDIR = $(BUILDROOT)@PMANDIR@ +RCLEVELS = @RCLEVELS@ +RCSTART = @RCSTART@ +RCSTOP = @RCSTOP@ REQUESTS = $(BUILDROOT)@CUPS_REQUESTS@ SBINDIR = $(BUILDROOT)@sbindir@ SERVERBIN = $(BUILDROOT)@CUPS_SERVERBIN@ @@ -269,5 +276,5 @@ DBUSDIR = @DBUSDIR@ # -# End of "$Id: Makedefs.in 5799 2006-08-03 00:54:38Z mike $" +# End of "$Id: Makedefs.in 6332 2007-03-12 16:08:51Z mike $" # diff --git a/Makefile b/Makefile index 3d96ec143..c24ccdb2d 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ # -# "$Id: Makefile 6128 2006-12-05 16:07:23Z mike $" +# "$Id: Makefile 6332 2007-03-12 16:08:51Z mike $" # # Top-level Makefile for the Common UNIX Printing System (CUPS). # -# Copyright 1997-2006 by Easy Software Products, all rights reserved. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the # property of Easy Software Products and are protected by Federal @@ -69,7 +69,8 @@ distclean: clean $(RM) man/cups-deviced.man man/cups-driverd.man $(RM) man/cups-lpd.man man/cupsaddsmb.man man/cupsd.man $(RM) man/cupsd.conf.man man/lpoptions.man - $(RM) packaging/cups templates/edit-config.tmpl templates/header.tmpl + $(RM) packaging/cups.list + $(RM) templates/edit-config.tmpl templates/header.tmpl -$(RM) doc/*/index.html -$(RM) templates/*/edit-config.tmpl -$(RM) templates/*/header.tmpl @@ -103,14 +104,17 @@ install: installhdrs echo Installing init scripts...; \ $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/init.d; \ $(INSTALL_SCRIPT) init/cups.sh $(BUILDROOT)$(INITDIR)/init.d/cups; \ + for level in $(RCLEVELS); do \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc$${level}.d; \ + $(LN) ../init.d/cups $(BUILDROOT)$(INITDIR)/rc$${level}.d/S$(RCSTART)cups; \ + if test `uname` = HP-UX; then \ + level=`expr $$level - 1`; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc$${level}.d; \ + fi; \ + $(LN) ../init.d/cups $(BUILDROOT)$(INITDIR)/rc$${level}.d/K$(RCSTOP)cups; \ + done; \ $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc0.d; \ - $(INSTALL_SCRIPT) init/cups.sh $(BUILDROOT)$(INITDIR)/rc0.d/K00cups; \ - $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc2.d; \ - $(INSTALL_SCRIPT) init/cups.sh $(BUILDROOT)$(INITDIR)/rc2.d/S99cups; \ - $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc3.d; \ - $(INSTALL_SCRIPT) init/cups.sh $(BUILDROOT)$(INITDIR)/rc3.d/S99cups; \ - $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc5.d; \ - $(INSTALL_SCRIPT) init/cups.sh $(BUILDROOT)$(INITDIR)/rc5.d/S99cups; \ + $(LN) ../init.d/cups $(BUILDROOT)$(INITDIR)/rc0.d/K$(RCSTOP)cups; \ fi if test "x$(INITDIR)" = x -a "x$(INITDDIR)" != x; then \ $(INSTALL_DIR) $(BUILDROOT)$(INITDDIR); \ @@ -131,26 +135,29 @@ install: installhdrs fi if test "x$(DBUSDIR)" != x; then \ echo Installing cups.conf in $(DBUSDIR)...;\ - $(INSTALL_DIR) -m 755 $(BUILDROOT)$(DBUSDIR); \ - $(INSTALL_DATA) packaging/cups-dbus.conf $(BUILDROOT)$(DBUSDIR)/cups.conf; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(DBUSDIR)/system.d; \ + $(INSTALL_DATA) packaging/cups-dbus.conf $(BUILDROOT)$(DBUSDIR)/system.d/cups.conf; \ fi if test "x$(XINETD)" != x; then \ echo Installing xinetd configuration file for cups-lpd...; \ $(INSTALL_DIR) -m 755 $(BUILDROOT)$(XINETD); \ $(INSTALL_DATA) init/cups-lpd $(BUILDROOT)$(XINETD)/cups-lpd; \ fi - if test -d /usr/share/applications; then \ + if test "x$(MENUDIR)" != x; then \ + echo Installing desktop menu...; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(MENUDIR); \ + $(INSTALL_DATA) desktop/cups.desktop $(BUILDROOT)$(MENUDIR); \ + fi + if test "x$(ICONDIR)" != x; then \ echo Installing desktop icons...; \ - $(INSTALL_DIR) -m 755 $(BUILDROOT)/usr/share/applications; \ - $(INSTALL_DATA) desktop/cups.desktop $(BUILDROOT)/usr/share/applications; \ - $(INSTALL_DIR) -m 755 $(BUILDROOT)/usr/share/icons/hicolor/16x16/apps; \ - $(INSTALL_DATA) desktop/cups-16.png $(BUILDROOT)/usr/share/icons/hicolor/16x16/apps/cups.png; \ - $(INSTALL_DIR) -m 755 $(BUILDROOT)/usr/share/icons/hicolor/32x32/apps; \ - $(INSTALL_DATA) desktop/cups-32.png $(BUILDROOT)/usr/share/icons/hicolor/32x32/apps/cups.png; \ - $(INSTALL_DIR) -m 755 $(BUILDROOT)/usr/share/icons/hicolor/64x64/apps; \ - $(INSTALL_DATA) desktop/cups-64.png $(BUILDROOT)/usr/share/icons/hicolor/64x64/apps/cups.png; \ - $(INSTALL_DIR) -m 755 $(BUILDROOT)/usr/share/icons/hicolor/128x128/apps; \ - $(INSTALL_DATA) desktop/cups-128.png $(BUILDROOT)/usr/share/icons/hicolor/128x128/apps/cups.png; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(ICONDIR)/hicolor/16x16/apps; \ + $(INSTALL_DATA) desktop/cups-16.png $(BUILDROOT)$(ICONDIR)/hicolor/16x16/apps/cups.png; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(ICONDIR)/hicolor/32x32/apps; \ + $(INSTALL_DATA) desktop/cups-32.png $(BUILDROOT)$(ICONDIR)/hicolor/32x32/apps/cups.png; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(ICONDIR)/hicolor/64x64/apps; \ + $(INSTALL_DATA) desktop/cups-64.png $(BUILDROOT)$(ICONDIR)/hicolor/64x64/apps/cups.png; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(ICONDIR)/hicolor/128x128/apps; \ + $(INSTALL_DATA) desktop/cups-128.png $(BUILDROOT)$(ICONDIR)/hicolor/128x128/apps/cups.png; \ fi @@ -263,5 +270,5 @@ dist: all # -# End of "$Id: Makefile 6128 2006-12-05 16:07:23Z mike $". +# End of "$Id: Makefile 6332 2007-03-12 16:08:51Z mike $". # diff --git a/README.txt b/README.txt index 8d555a2f3..26f52b8e1 100644 --- a/README.txt +++ b/README.txt @@ -1,5 +1,5 @@ -README - CUPS v1.2.8 - 2007-02-14 ---------------------------------- +README - CUPS v1.3svn - 2007-01-03 +---------------------------------- Looking for compile instructions? Read the file "INSTALL.txt" instead... diff --git a/backend/Dependencies b/backend/Dependencies index 068343821..48771748a 100644 --- a/backend/Dependencies +++ b/backend/Dependencies @@ -9,31 +9,33 @@ lpd.o: ../cups/backend.h ../cups/http-private.h ../config.h ../cups/http.h lpd.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h lpd.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h lpd.o: ../cups/string.h -pap.o: ../cups/http.h ../cups/md5.h -parallel.o: backend-private.h ../cups/backend.h ../cups/cups.h ../cups/ipp.h -parallel.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h -parallel.o: ../cups/file.h ../cups/language.h ../cups/debug.h +pap.o: ../config.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +pap.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/backend.h +parallel.o: backend-private.h ../cups/backend.h ../cups/sidechannel.h +parallel.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +parallel.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h parallel.o: ../cups/string.h ../config.h scsi.o: ../cups/backend.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -scsi.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -scsi.o: ../cups/language.h ../cups/string.h ../config.h -serial.o: backend-private.h ../cups/backend.h ../cups/cups.h ../cups/ipp.h -serial.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h -serial.o: ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h -serial.o: ../config.h +scsi.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +scsi.o: ../cups/string.h ../config.h +serial.o: backend-private.h ../cups/backend.h ../cups/sidechannel.h +serial.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +serial.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +serial.o: ../cups/string.h ../config.h snmp.o: ../cups/http-private.h ../config.h ../cups/http.h ../cups/md5.h snmp.o: ../cups/ipp-private.h ../cups/ipp.h backend-private.h -snmp.o: ../cups/backend.h ../cups/cups.h ../cups/ppd.h ../cups/array.h -snmp.o: ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h -snmp.o: ../cups/array.h ../cups/file.h +snmp.o: ../cups/backend.h ../cups/sidechannel.h ../cups/cups.h ../cups/ppd.h +snmp.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +snmp.o: ../cups/string.h ../cups/array.h ../cups/file.h socket.o: ../cups/http-private.h ../config.h ../cups/http.h ../cups/md5.h socket.o: ../cups/ipp-private.h ../cups/ipp.h backend-private.h -socket.o: ../cups/backend.h ../cups/cups.h ../cups/ppd.h ../cups/array.h -socket.o: ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/string.h +socket.o: ../cups/backend.h ../cups/sidechannel.h ../cups/cups.h +socket.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +socket.o: ../cups/debug.h ../cups/string.h test1284.o: ../cups/string.h ../config.h ieee1284.c backend-private.h -test1284.o: ../cups/backend.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -test1284.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -test1284.o: ../cups/language.h ../cups/debug.h +test1284.o: ../cups/backend.h ../cups/sidechannel.h ../cups/cups.h +test1284.o: ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h +test1284.o: ../cups/file.h ../cups/language.h ../cups/debug.h usb.o: ../cups/backend.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -usb.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -usb.o: ../cups/language.h ../cups/string.h ../config.h +usb.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +usb.o: ../cups/string.h ../config.h diff --git a/backend/Makefile b/backend/Makefile index 2ea79f15c..ae8f30bbf 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 6061 2006-10-23 00:26:52Z mike $" +# "$Id: Makefile 6058 2006-10-23 00:20:09Z mike $" # # Backend makefile for the Common UNIX Printing System (CUPS). # @@ -222,5 +222,5 @@ include Dependencies # -# End of "$Id: Makefile 6061 2006-10-23 00:26:52Z mike $". +# End of "$Id: Makefile 6058 2006-10-23 00:20:09Z mike $". # diff --git a/backend/backend-private.h b/backend/backend-private.h index 14b93cc87..91a9926df 100644 --- a/backend/backend-private.h +++ b/backend/backend-private.h @@ -1,9 +1,9 @@ /* - * "$Id: backend-private.h 5771 2006-07-20 18:06:20Z mike $" + * "$Id: backend-private.h 6170 2007-01-02 17:26:41Z mike $" * * Backend support definitions for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -33,6 +33,7 @@ */ # include +# include # include # include # include @@ -59,7 +60,9 @@ extern int backendGetDeviceID(int fd, char *device_id, int device_id_size, const char *scheme, char *uri, int uri_size); extern int backendGetMakeModel(const char *device_id, char *make_model, int make_model_size); -extern ssize_t backendRunLoop(int print_fd, int device_fd, int use_bc); +extern ssize_t backendRunLoop(int print_fd, int device_fd, int use_bc, + void (*side_cb)(int print_fd, int device_fd, + int use_bc)); # ifdef __cplusplus @@ -69,5 +72,5 @@ extern ssize_t backendRunLoop(int print_fd, int device_fd, int use_bc); /* - * End of "$Id: backend-private.h 5771 2006-07-20 18:06:20Z mike $". + * End of "$Id: backend-private.h 6170 2007-01-02 17:26:41Z mike $". */ diff --git a/backend/easysw-firewire-design.txt b/backend/easysw-firewire-design.txt new file mode 100644 index 000000000..194c487ed --- /dev/null +++ b/backend/easysw-firewire-design.txt @@ -0,0 +1,71 @@ +Preliminary Design for CUPS Firewire Printer Backend - 03/19/2002 +----------------------------------------------------------------- + +OVERVIEW + + Easy Software Products will develop an IEEE-1394, a.k.a. + Firewire, printing interface for its Common UNIX Printing + System ("CUPS") for initial use under the Linux operating + system. A follow-on implementation for MacOS X is + anticipated as well. + + The operating system interfaces for IEEE-1394 ports vary + widely; the CUPS printing interface will abstract the OS + layer to a simpler interface geared towards discovering, + opening, reading from, writing to, and closing IEEE-1394 + printers. + + The initial development of the CUPS backend will be targeted + at the EPSON Stylus Pro 10000 large format printer, which + requires the bandwidth provided by Firewire in order to + print at full speed. This printer supports printing via + Serial Bus Protocol 2 (SBP-2) using the SCSI and PWG command + sets. The CUPS backend will implement the PWG command set on + LUN 0 only. + + +OS ABSTRACTION LAYER + + The OS abstraction layer will be a thin client library that + implements the following functions: + + ieee1394_list + ieee1394_open + ieee1394_close + ieee1394_read + ieee1394_write + ieee1394_error + + The "ieee1394_list" function will list all of the available + printer devices on the bus. The device information will + consist of the device URI (ieee1394:/something) used to + access the device and the make and model information, if + available, for the device ("EPSON Stylus Printer"). + + The "ieee1394_open" and "ieee1394_close" functions will open + and close a connection to the printer, respectively. + + The "ieee1394_read" and "ieee1394_write" functions will read + and write data to and from the printer, respectively. The + read function will be non-blocking, returning data only if + there is data coming back from the printer. + + The "ieee1394_error" function will return a string + describing the last error or NULL if no error occurred. + + The library will be responsible for creating any background + threads that are needed to monitor the connection to the + printer. + + +CUPS BACKEND + + The CUPS backend will use the OS abstraction layer to list + and access the Firewire printers. The "main" function will + read and write printer data, while the "list_devices" + function will be called as necessary to identify the + available devices. + + The CUPS 1.1 backend will record any status information in + the error log file, while the 1.2 backend will supply it to + the printer driver process. diff --git a/backend/easysw-firewire-linux.txt b/backend/easysw-firewire-linux.txt new file mode 100644 index 000000000..a8e461189 --- /dev/null +++ b/backend/easysw-firewire-linux.txt @@ -0,0 +1,35 @@ +Easy Software Products +44141 Airport View Drive +Suite 204 +Hollywood, Maryland 20636 ++1.301.373.9600 +March 8, 2002 + + +Subject: EPSON Firewire Printer Driver for Linux + +Currently, no Firewire printer support exists for Linux. Since +the latest EPSON printer products depend on the Firewire +interface to print at full speed, a solution is needed to +support customers using Linux as their server platform. + +The Linux Firewire subsystem provides a user-mode driver +interface that allows driver programs to access Firewire +devices. Easy Software Products will utilize this interface to +develop a "backend" program for the Common UNIX Printing System +that will allow users to print to EPSON printers using the +Firewire interface. + +After examining the Linux interface, we estimate that it will +require approximately 30 hours of development time to write, +test, and document the Firewire backend, for a total cost of +$3,000. The new backend will become a standard part of the CUPS +software distribution and will be included with at least the +following Linux distributions: + + - Caldera Linux + - Mandrake Linux + - Red Hat Linux + - SuSE Linux + +ESP will provide EPSON with binaries for Red Hat Linux 7.2. diff --git a/backend/ieee1284.c b/backend/ieee1284.c index f54149367..94b01843f 100644 --- a/backend/ieee1284.c +++ b/backend/ieee1284.c @@ -1,9 +1,9 @@ /* - * "$Id: ieee1284.c 5866 2006-08-23 03:03:49Z mike $" + * "$Id: ieee1284.c 6293 2007-02-20 13:40:55Z mike $" * * IEEE-1284 support functions for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -93,84 +93,87 @@ backendGetDeviceID( * Range check input... */ - if (fd < 0 || - !device_id || device_id_size < 32 || - !make_model || make_model_size < 32) + if (!device_id || device_id_size < 32) { DEBUG_puts("backendGetDeviceID: Bad args!"); return (-1); } - *device_id = '\0'; - *make_model = '\0'; + if (make_model) + *make_model = '\0'; if (uri) *uri = '\0'; - /* - * Get the device ID string... - */ - -#ifdef __linux - if (!ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id)) + if (fd >= 0) { /* - * Extract the length of the device ID string from the first two - * bytes. The 1284 spec says the length is stored MSB first... + * Get the device ID string... */ - length = (((unsigned)device_id[0] & 255) << 8) + - ((unsigned)device_id[1] & 255); + *device_id = '\0'; - /* - * Check to see if the length is larger than our buffer; first - * assume that the vendor incorrectly implemented the 1284 spec, - * and then limit the length to the size of our buffer... - */ +#ifdef __linux + if (!ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id)) + { + /* + * Extract the length of the device ID string from the first two + * bytes. The 1284 spec says the length is stored MSB first... + */ - if (length > (device_id_size - 2)) - length = (((unsigned)device_id[1] & 255) << 8) + - ((unsigned)device_id[0] & 255); + length = (((unsigned)device_id[0] & 255) << 8) + + ((unsigned)device_id[1] & 255); - if (length > (device_id_size - 2)) - length = device_id_size - 2; + /* + * Check to see if the length is larger than our buffer; first + * assume that the vendor incorrectly implemented the 1284 spec, + * and then limit the length to the size of our buffer... + */ - /* - * Copy the device ID text to the beginning of the buffer and - * nul-terminate. - */ + if (length > (device_id_size - 2)) + length = (((unsigned)device_id[1] & 255) << 8) + + ((unsigned)device_id[0] & 255); - memmove(device_id, device_id + 2, length); - device_id[length] = '\0'; - } + if (length > (device_id_size - 2)) + length = device_id_size - 2; + + /* + * Copy the device ID text to the beginning of the buffer and + * nul-terminate. + */ + + memmove(device_id, device_id + 2, length); + device_id[length] = '\0'; + } # ifdef DEBUG - else - printf("backendGetDeviceID: ioctl failed - %s\n", strerror(errno)); + else + printf("backendGetDeviceID: ioctl failed - %s\n", strerror(errno)); # endif /* DEBUG */ #endif /* __linux */ #if defined(__sun) && defined(ECPPIOC_GETDEVID) - did.mode = ECPP_CENTRONICS; - did.len = device_id_size - 1; - did.rlen = 0; - did.addr = device_id; + did.mode = ECPP_CENTRONICS; + did.len = device_id_size - 1; + did.rlen = 0; + did.addr = device_id; - if (!ioctl(fd, ECPPIOC_GETDEVID, &did)) - { - /* - * Nul-terminate the device ID text. - */ + if (!ioctl(fd, ECPPIOC_GETDEVID, &did)) + { + /* + * Nul-terminate the device ID text. + */ - if (did.rlen < (device_id_size - 1)) - device_id[did.rlen] = '\0'; - else - device_id[device_id_size - 1] = '\0'; - } + if (did.rlen < (device_id_size - 1)) + device_id[did.rlen] = '\0'; + else + device_id[device_id_size - 1] = '\0'; + } # ifdef DEBUG - else - printf("backendGetDeviceID: ioctl failed - %s\n", strerror(errno)); + else + printf("backendGetDeviceID: ioctl failed - %s\n", strerror(errno)); # endif /* DEBUG */ #endif /* __sun && ECPPIOC_GETDEVID */ + } DEBUG_printf(("backendGetDeviceID: device_id=\"%s\"\n", device_id)); @@ -181,7 +184,8 @@ backendGetDeviceID( * Get the make and model... */ - backendGetMakeModel(device_id, make_model, make_model_size); + if (make_model) + backendGetMakeModel(device_id, make_model, make_model_size); /* * Then generate a device URI... @@ -499,5 +503,5 @@ backendGetMakeModel( /* - * End of "$Id: ieee1284.c 5866 2006-08-23 03:03:49Z mike $". + * End of "$Id: ieee1284.c 6293 2007-02-20 13:40:55Z mike $". */ diff --git a/backend/ieee1394-linux.c b/backend/ieee1394-linux.c new file mode 100644 index 000000000..b95e8204e --- /dev/null +++ b/backend/ieee1394-linux.c @@ -0,0 +1,877 @@ +/* + * "$Id: ieee1394-linux.c 4703 2005-09-26 19:33:58Z mike $" + * + * Linux IEEE-1394 glue for the Common UNIX Printing System (CUPS). + * + * Copyright 2002 by Easy Software Products, all rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use + * of this software must display the following + * acknowledgement: + * + * This product includes software developed by Easy + * Software Products. + * + * 4. The name of Easy Software Products may not be used to + * endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Contents: + * + * get_device_id() - Get the IEEE-1284 device ID for a node... + * get_unit_type() - Get the unit type for a node... + * show_data() - Show a data node... + * show_dir() - Show a directory list... + * ieee1394_list() - List the available printer devices. + * ieee1394_open() - Open a printer device. + * ieee1394_close() - Close a printer device. + * ieee1394_read() - Read from a printer device. + * ieee1394_write() - Write data to a printer device. + * ieee1394_error() - Return the last error. + */ + +/* + * Include necessary headers. + */ + +#include "ieee1394.h" +#include +#include +#include + + +/* + * Limits... + */ + +#define MAX_NODES 100 + + +/* + * Structures... + */ + +typedef struct +{ + char uri[HTTP_MAX_URI],/* URI for this node... */ + description[128],/* Description of port */ + make_model[128];/* Make and model */ + int port, /* Port where this node is found */ + node; /* Node number */ + unsigned long long addr; /* Management address */ +} linux1394_node_t; + +typedef struct +{ + raw1394handle_t handle; /* Handle for printer device */ + int node; /* Node number for printer device */ + unsigned long long addr; /* Management address */ +} linux1394_dev_t; + + +/* + * ORB messages for communication with the device... + */ + +typedef struct /**** Login ORB Message */ +{ + unsigned char passwd_addr[8]; /* Password address */ + unsigned char resp_addr[8]; /* Login response address */ + unsigned char notify_excl; /* Notify and exclusive bits */ + unsigned char recon_func; /* Reconnect time and function */ + unsigned char lun[2]; /* Logical unit number */ + unsigned char passwd_len[2]; /* Length of password */ + unsigned char resp_len[2]; /* Length of login response */ + unsigned char fifo_addr[8]; /* Local status FIFO address */ +} login_orb_t; + +typedef struct /**** Login Response Message ****/ +{ + unsigned char length[2]; /* Length of response */ + unsigned char login_id[2]; /* Login ID */ + unsigned char cmd_addr[8]; /* Command block agent address */ + unsigned char reserved[2]; /* Reserved (0) */ + unsigned char recon_hold[2]; /* Number of seconds to hold login */ +} login_resp_t; + + +/* + * Local globals... + */ + +static char error_string[1024] = ""; +static int num_nodes; +static linux1394_node_t nodes[MAX_NODES]; + + +/* + * 'get_device_id()' - Get the IEEE-1284 device ID for a node... + */ + +static char * /* O - Device ID */ +get_device_id(raw1394handle_t handle,/* I - Handle for device */ + int node, /* I - Node number */ + unsigned long long offset,/* I - Offset to directory */ + char *id, /* O - ID string */ + int idlen) /* I - Size of ID string */ +{ + unsigned char data[1024], /* Data from ROM */ + *dataptr; /* Pointer into data */ + int length; /* Length of directory */ + int datalen; /* Length of data */ + unsigned long long dataoff; /* Offset of data */ + + + DEBUG_printf(("get_device_id(handle = %p, node = %d, offset = %llx, id = %p, idlen = %d)\n", + handle, node, offset, id, idlen)); + + *id = '\0'; + + /* + * Read the directory length from the first quadlet... + */ + + if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) + return (NULL); + + offset += 4; + + /* + * The length is in the upper 16 bits... + */ + + length = (data[0] << 8) | data[1]; + + DEBUG_printf((" length = %d\n", length)); + + /* + * Then read the directory, looking for unit directory or device tags... + */ + + while (length > 0) + { + if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) + return (NULL); + + DEBUG_printf((" data = %02X %02X %02X %02X\n", data[0], data[1], + data[2], data[3])); + + if (data[0] == 0xd1) + { + /* + * Found the unit directory... + */ + + offset += ((((data[1] << 8) | data[2]) << 8) | data[3]) << 2; + + return (get_device_id(handle, node, offset, id, idlen)); + } + else if (data[0] == 0x81) + { + /* + * Found potential IEEE-1284 device ID... + */ + + dataoff = offset + (((((data[1] << 8) | data[2]) << 8) | data[3]) << 2); + + if (raw1394_read(handle, 0xffc0 | node, dataoff, 4, (quadlet_t *)data) < 0) + return (NULL); + + dataoff += 4; + + /* + * Read the leaf value... + */ + + datalen = (data[0] << 8) | data[1]; + + if (datalen > (sizeof(data) / 4)) + datalen = sizeof(data) / 4; + + for (dataptr = data; datalen > 0; datalen --, dataptr += 4, dataoff += 4) + if (raw1394_read(handle, 0xffc0 | node, dataoff, 4, + (quadlet_t *)dataptr) < 0) + return (NULL); + + if (data[0] == 0 && memcmp(data + 8, "MFG:", 4) == 0) + { + /* + * Found the device ID... + */ + + datalen = dataptr - data - 8; + if (datalen >= idlen) + datalen --; + + memcpy(id, data + 8, datalen); + id[datalen] = '\0'; + + return (id); + } + } + + offset += 4; + length --; + } + + return (NULL); +} + + +/* + * 'get_man_addr()' - Get the management address for a node... + */ + +static int /* O - Unit type */ +get_man_addr(raw1394handle_t handle, /* I - Handle for device */ + int node, /* I - Node number */ + unsigned long long offset) /* I - Offset to directory */ +{ + unsigned char data[4]; /* Data from ROM */ + int length; /* Length of directory */ + + + DEBUG_printf(("get_man_addr(handle = %p, node = %d, offset = %llx)\n", + handle, node, offset)); + + /* + * Read the directory length from the first quadlet... + */ + + if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) + return (-1); + + offset += 4; + + /* + * The length is in the upper 16 bits... + */ + + length = (data[0] << 8) | data[1]; + + DEBUG_printf((" length = %d\n", length)); + + /* + * Then read the directory, looking for unit directory or type tags... + */ + + while (length > 0) + { + if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) + return (-1); + + DEBUG_printf((" data = %02X %02X %02X %02X\n", data[0], data[1], + data[2], data[3])); + + if (data[0] == 0xd1) + { + /* + * Found the unit directory... + */ + + offset += ((((data[1] << 8) | data[2]) << 8) | data[3]) << 2; + + return (get_man_addr(handle, node, offset)); + } + else if (data[0] == 0x54) + { + /* + * Found the management address... + */ + + return (((((data[1] << 8) | data[2]) << 8) | data[3]) << 2); + } + + offset += 4; + length --; + } + + return (-1); +} + + +/* + * 'get_unit_type()' - Get the unit type for a node... + */ + +static int /* O - Unit type */ +get_unit_type(raw1394handle_t handle,/* I - Handle for device */ + int node, /* I - Node number */ + unsigned long long offset)/* I - Offset to directory */ +{ + unsigned char data[4]; /* Data from ROM */ + int length; /* Length of directory */ + + + DEBUG_printf(("get_unit_type(handle = %p, node = %d, offset = %llx)\n", + handle, node, offset)); + + /* + * Read the directory length from the first quadlet... + */ + + if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) + return (-1); + + offset += 4; + + /* + * The length is in the upper 16 bits... + */ + + length = (data[0] << 8) | data[1]; + + DEBUG_printf((" length = %d\n", length)); + + /* + * Then read the directory, looking for unit directory or type tags... + */ + + while (length > 0) + { + if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) + return (-1); + + DEBUG_printf((" data = %02X %02X %02X %02X\n", data[0], data[1], + data[2], data[3])); + + if (data[0] == 0xd1) + { + /* + * Found the unit directory... + */ + + offset += ((((data[1] << 8) | data[2]) << 8) | data[3]) << 2; + + return (get_unit_type(handle, node, offset)); + } + else if (data[0] == 0x14) + { + /* + * Found the unit type... + */ + + return (data[1] & 0x1f); + } + + offset += 4; + length --; + } + + return (-1); +} + + +#ifdef DEBUG +/* + * 'show_data()' - Show a data node... + */ + +static void +show_data(raw1394handle_t handle, /* I - Handle for device */ + int node, /* I - Node number */ + unsigned long long offset, /* I - Offset to directory */ + int indent) /* Amount to indent */ +{ + int i; /* Looping var */ + unsigned char data[4]; /* Data from ROM */ + int length; /* Length of data */ + + + /* + * Read the data length from the first quadlet... + */ + + if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) + return; + + offset += 4; + + /* + * The length is in the upper 16 bits... + */ + + length = (data[0] << 8) | data[1]; + + /* + * Then read the data... + */ + + for (i = 0; i < indent; i ++) + putchar(' '); + + printf("LEAF (%d quadlets)\n", length); + + while (length > 0) + { + if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) + return; + + for (i = 0; i < indent; i ++) + putchar(' '); + + printf("%02X %02X %02X %02X '%c%c%c%c'\n", + data[0], data[1], data[2], data[3], + (data[0] < ' ' || data[0] >= 0x7f) ? '.' : data[0], + (data[1] < ' ' || data[1] >= 0x7f) ? '.' : data[1], + (data[2] < ' ' || data[2] >= 0x7f) ? '.' : data[2], + (data[3] < ' ' || data[3] >= 0x7f) ? '.' : data[3]); + + offset += 4; + length --; + } +} + + +/* + * 'show_dir()' - Show a directory list... + */ + +static void +show_dir(raw1394handle_t handle, /* I - Handle for device */ + int node, /* I - Node number */ + unsigned long long offset, /* I - Offset to directory */ + int indent) /* Amount to indent */ +{ + int i; /* Looping var */ + unsigned char data[4]; /* Data from ROM */ + int length; /* Length of directory */ + int value; /* Value in directory */ + + + /* + * Read the directory length from the first quadlet... + */ + + if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) + return; + + offset += 4; + + /* + * The length is in the upper 16 bits... + */ + + length = (data[0] << 8) | data[1]; + + /* + * Then read the directory... + */ + + while (length > 0) + { + if (raw1394_read(handle, 0xffc0 | node, offset, 4, (quadlet_t *)data) < 0) + return; + + for (i = 0; i < indent; i ++) + putchar(' '); + + printf("%02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]); + + value = (((data[1] << 8) | data[2]) << 8) | data[3]; + + switch (data[0] & 0xc0) + { + case 0x00 : + for (i = -4; i < indent; i ++) + putchar(' '); + + printf("IMMEDIATE %d\n", value); + break; + + case 0x40 : + for (i = -4; i < indent; i ++) + putchar(' '); + + printf("CSR OFFSET +%06X\n", value); + break; + + case 0x80 : + show_data(handle, node, offset + value * 4, indent + 4); + break; + + case 0xc0 : + show_dir(handle, node, offset + value * 4, indent + 4); + break; + } + + offset += 4; + length --; + } +} +#endif /* DEBUG */ + + +/* + * 'ieee1394_list()' - List the available printer devices. + */ + +ieee1394_info_t * /* O - Printer information */ +ieee1394_list(int *num_devices) /* O - Number of printers */ +{ + int i, j; /* Looping vars */ + raw1394handle_t handle; /* 1394 handle */ + int num_ports; /* Number of ports */ + struct raw1394_portinfo ports[100]; /* Port data... */ + unsigned char guid[8]; /* Global unique ID */ + int vendor; /* Vendor portion of GUID */ + int unit_type; /* Unit type */ + int addr; /* Management address offset */ + char id[1024], /* Device ID string */ + *idptr, /* Pointer into ID string */ + *idsep; /* Pointer to separator */ + ieee1394_info_t *devices; /* Device list */ + + + /* + * Connect to the user-mode driver interface... + */ + + handle = raw1394_new_handle(); + num_ports = raw1394_get_port_info(handle, ports, + sizeof(ports) / sizeof(ports[0])); + + DEBUG_printf(("num_ports = %d\n", num_ports)); + + /* + * Loop through the ports to discover what nodes are available. + */ + + num_nodes = 0; + + for (i = 0; i < num_ports; i ++) + { + DEBUG_printf(("ports[%d] = { nodes = %d, name = \"%s\" }\n", i, + ports[i].nodes, ports[i].name)); + + raw1394_set_port(handle, i); + + for (j = 0; j < ports[i].nodes; j ++) + { + if (raw1394_read(handle, 0xffc0 | j, + CSR_REGISTER_BASE + CSR_CONFIG_ROM + 12, 4, + (quadlet_t *)guid) < 0) + { + DEBUG_printf((" Node #%d: Unable to contact (%s)!\n", j, + strerror(errno))); + continue; + } + else + { + raw1394_read(handle, 0xffc0 | j, + CSR_REGISTER_BASE + CSR_CONFIG_ROM + 16, 4, + (quadlet_t *)(guid + 4)); + + DEBUG_printf((" Node #%d: GUID = %02X%02X%02X%02X%02X%02X%02X%02X\n", + j, guid[0], guid[1], guid[2], guid[3], guid[4], + guid[5], guid[6], guid[7])); + + vendor = (((guid[0] << 8) | guid[1]) << 8) | guid[2]; + unit_type = get_unit_type(handle, j, + CSR_REGISTER_BASE + CSR_CONFIG_ROM + 20); + + DEBUG_printf(("vendor = %x, unit_type = %d\n", vendor, unit_type)); + + if (unit_type == 2 && num_nodes < MAX_NODES) + { + /* + * Found a printer device; add it to the nodes list... + */ + +#ifdef DEBUG + show_dir(handle, j, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 20, 0); +#endif /* DEBUG */ + + memset(nodes + num_nodes, 0, sizeof(linux1394_node_t)); + + sprintf(nodes[num_nodes].uri, "ieee1394://%02X%02X%02X%02X%02X%02X%02X%02X", + guid[0], guid[1], guid[2], guid[3], guid[4], + guid[5], guid[6], guid[7]); + + nodes[num_nodes].port = i; + nodes[num_nodes].node = j; + + addr = get_man_addr(handle, j, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 20); + + if (addr < 0) + continue; + + nodes[num_nodes].addr = CSR_REGISTER_BASE + addr; + + DEBUG_printf(("Node address = %llx\n", nodes[num_nodes].addr)); + + get_device_id(handle, j, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 20, + id, sizeof(id)); + + if (id[0]) + { + /* + * Grab the manufacturer and model name from the device ID + * string... + */ + + idptr = id + 4; + idsep = strchr(id, ';'); + if (idsep) + *idsep++ = '\0'; + else + idsep = idptr; + + snprintf(nodes[num_nodes].description, + sizeof(nodes[num_nodes].description), + "%s Firewire Printer", idptr); + + if ((idptr = strstr(idsep, "DES:")) == NULL) + idptr = strstr(idsep, "MDL:"); + + if (idptr == NULL) + strcpy(nodes[num_nodes].make_model, "Unknown"); + else + { + /* + * Grab the DES or MDL code... + */ + + idptr += 4; + idsep = strchr(idptr, ';'); + if (idsep) + *idsep = '\0'; + + if (strncmp(id + 4, idptr, strlen(id + 4)) == 0) + { + /* + * Use the description directly... + */ + + strlcpy(nodes[num_nodes].make_model, idptr, + sizeof(nodes[num_nodes].make_model)); + } + else + { + /* + * Add the manufacturer to the front of the name... + */ + + snprintf(nodes[num_nodes].make_model, + sizeof(nodes[num_nodes].make_model), + "%s %s", id + 4, idptr); + } + } + } + else + { + /* + * Flag it as an unknown printer... + */ + + sprintf(nodes[num_nodes].description, + "Unknown%06X Firewire Printer", vendor); + strcpy(nodes[num_nodes].make_model, "Unknown"); + } + + num_nodes ++; + } + } + } + } + + /* + * Done querying the Firewire bus... + */ + + raw1394_destroy_handle(handle); + + /* + * Build an array of device info structures as needed... + */ + + if (num_devices == NULL) + return (NULL); + + *num_devices = num_nodes; + + if (num_nodes) + { + if ((devices = calloc(sizeof(ieee1394_info_t), num_nodes)) != NULL) + { + for (i = 0; i < num_nodes; i ++) + { + strcpy(devices[i].uri, nodes[i].uri); + strcpy(devices[i].description, nodes[i].description); + strcpy(devices[i].make_model, nodes[i].make_model); + } + } + + return (devices); + } + else + return (NULL); +} + + +/* + * 'ieee1394_open()' - Open a printer device. + */ + +ieee1394_dev_t /* O - Printer device or NULL */ +ieee1394_open(const char *uri) /* I - Device URI */ +{ + int i; /* Looping var */ + linux1394_dev_t *ldev; /* Linux device */ + + + /* + * Return early if we can't see any printers... + */ + + if (num_nodes == 0) + ieee1394_list(NULL); + + if (num_nodes == 0) + { + strcpy(error_string, "No IEEE-1394 printers found!"); + return (NULL); + } + + /* + * Look for the URI... + */ + + for (i = 0; i < num_nodes; i ++) + if (strcmp(nodes[i].uri, uri) == 0) + break; + + if (i >= num_nodes) + { + snprintf(error_string, sizeof(error_string), "Device %s not found!", uri); + return (NULL); + } + + /* + * Now create a new device structure... + */ + + if ((ldev = calloc(sizeof(linux1394_dev_t), 1)) == NULL) + { + strcpy(error_string, "Out of memory!"); + return (NULL); + } + + ldev->handle = raw1394_new_handle(); + ldev->node = nodes[i].node; + ldev->addr = nodes[i].addr; + + raw1394_set_port(ldev->handle, nodes[i].port); + + error_string[0] = '\0'; + + return ((ieee1394_dev_t)ldev); +} + + +/* + * 'ieee1394_close()' - Close a printer device. + */ + +int /* O - 0 on success, -1 on failure */ +ieee1394_close(ieee1394_dev_t dev) /* I - Printer device */ +{ + linux1394_dev_t *ldev; /* Linux device */ + + + ldev = (linux1394_dev_t *)dev; + + raw1394_destroy_handle(ldev->handle); + + free(ldev); + + return (0); +} + + +/* + * 'ieee1394_read()' - Read from a printer device. + */ + +int /* O - Number of bytes read or -1 */ +ieee1394_read(ieee1394_dev_t dev, /* I - Printer device */ + char *buffer, /* I - Read buffer */ + int len) /* I - Max bytes to read */ +{ + linux1394_dev_t *ldev; /* Linux device */ + + + ldev = (linux1394_dev_t *)dev; + + + return (0); +} + + +/* + * 'ieee1394_write()' - Write data to a printer device. + */ + +int /* O - Number of bytes written or -1 */ +ieee1394_write(ieee1394_dev_t dev, /* I - Printer device */ + char *buffer, /* I - Buffer to write */ + int len) /* I - Number of bytes to write */ +{ + linux1394_dev_t *ldev; /* Linux device */ + + + ldev = (linux1394_dev_t *)dev; + + +/* if (raw1394_write(handle, 0xffc0 | j, 0, , + (quadlet_t *)guid) < 0)*/ + + return (len); +} + + +/* + * 'ieee1394_error()' - Return the last error. + */ + +const char * /* O - Error string or NULL */ +ieee1394_error(void) +{ + if (error_string[0]) + return (error_string); + else + return (NULL); +} + + +/* + * End of "$Id: ieee1394-linux.c 4703 2005-09-26 19:33:58Z mike $". + */ diff --git a/backend/ieee1394.c b/backend/ieee1394.c new file mode 100644 index 000000000..3d88c7a08 --- /dev/null +++ b/backend/ieee1394.c @@ -0,0 +1,267 @@ +/* + * "$Id: ieee1394.c 5241 2006-03-07 22:07:44Z mike $" + * + * IEEE-1394 backend for the Common UNIX Printing System (CUPS). + * + * Copyright 2002 by Easy Software Products, all rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use + * of this software must display the following + * acknowledgement: + * + * This product includes software developed by Easy + * Software Products. + * + * 4. The name of Easy Software Products may not be used to + * endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Contents: + * + * main() - Send a file to the printer. + * list_devices() - List all known printer devices... + */ + +/* + * Include necessary headers. + */ + +#include "ieee1394.h" + + +/* + * Local functions... + */ + +void list_devices(void); + + +/* + * 'main()' - Send a file to the printer. + * + * 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 */ +{ + ieee1394_dev_t dev; /* Printer device */ + int fp; /* Print file */ + int copies; /* Number of copies to print */ + int rbytes; /* Number of bytes read from device */ + size_t nbytes, /* Number of bytes read from file */ + tbytes; /* Total number of bytes written */ + char buffer[8192]; /* Input/output buffer */ +#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); + + /* + * Check command-line... + */ + + if (argc == 1) + { + list_devices(); + + return (0); + } + else if (argc < 6 || argc > 7) + { + fprintf(stderr, "Usage: %s job-id user title copies options [file]\n", + argv[0]); + return (1); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + { + fp = 0; + copies = 1; + } + else + { + /* + * Try to open the print file... + */ + + if ((fp = open(argv[6], O_RDONLY)) < 0) + { + perror("ERROR: unable to open print file"); + return (1); + } + + copies = atoi(argv[4]); + } + + /* + * Try to open the printer device... + */ + + fputs("STATE: +connecting-to-device\n", stderr); + + do + { + if ((dev = ieee1394_open(argv[0])) == NULL) + { + fputs("INFO: Firewire printer busy; will retry in 30 seconds...\n", stderr); + sleep(30); + } + } + while (dev == NULL); + + fputs("STATE: -connecting-to-device\n", stderr); + + /* + * Now that we are "connected" to the port, ignore SIGTERM so that we + * can finish out any page data the driver sends (e.g. to eject the + * current page... Only ignore SIGTERM if we are printing data from + * stdin (otherwise you can't cancel raw jobs...) + */ + + if (argc < 7) + { +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, SIG_IGN); +#endif /* HAVE_SIGSET */ + } + + /* + * Finally, send the print file... + */ + + while (copies > 0) + { + copies --; + + if (fp != 0) + { + fputs("PAGE: 1 1\n", stderr); + lseek(fp, 0, SEEK_SET); + } + + tbytes = 0; + while ((nbytes = read(fp, buffer, sizeof(buffer))) > 0) + { + /* + * Write the print data to the printer... + */ + + tbytes += nbytes; + + if (ieee1394_write(dev, buffer, nbytes) < 0) + { + perror("ERROR: Unable to send print file to printer"); + break; + } + + if ((rbytes = ieee1394_read(dev, buffer, sizeof(buffer))) > 0) + fprintf(stderr, "INFO: Read %d bytes from printer...\n", rbytes); + + if (argc > 6) + fprintf(stderr, "INFO: Sending print file, %lu bytes...\n", + (unsigned long)tbytes); + } + } + + /* + * Close the printer device and input file and return... + */ + + ieee1394_close(dev); + + if (fp != 0) + close(fp); + + fputs("INFO: Ready to print.\n", stderr); + + return (0); +} + + +/* + * 'list_devices()' - List all known devices... + */ + +void +list_devices(void) +{ + int i, /* Looping var */ + num_info; /* Number of devices */ + ieee1394_info_t *info; /* Devices... */ + + + /* + * Get the available devices... + */ + + info = ieee1394_list(&num_info); + + /* + * List them as needed... + */ + + if (num_info > 0) + { + for (i = 0; i < num_info; i ++) + printf("direct %s \"%s\" \"%s\"\n", info[i].uri, + info[i].make_model, info[i].description); + + free(info); + } +} + + +/* + * End of "$Id: ieee1394.c 5241 2006-03-07 22:07:44Z mike $". + */ diff --git a/backend/ieee1394.h b/backend/ieee1394.h new file mode 100644 index 000000000..19181c5c0 --- /dev/null +++ b/backend/ieee1394.h @@ -0,0 +1,103 @@ +/* + * "$Id: ieee1394.h 4494 2005-02-18 02:18:11Z mike $" + * + * IEEE-1394 header for the Common UNIX Printing System (CUPS). + * + * Copyright 2002 by Easy Software Products, all rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use + * of this software must display the following + * acknowledgement: + * + * This product includes software developed by Easy + * Software Products. + * + * 4. The name of Easy Software Products may not be used to + * endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +# include +#else +# include +# include +#endif /* WIN32 */ + + +/* + * Device information structure... + */ + +typedef struct +{ + char uri[HTTP_MAX_URI], /* Device URI */ + description[128], /* Description of port */ + make_model[128]; /* Make and model */ +} ieee1394_info_t; + + +/* + * Private device connection information... + */ + +typedef void *ieee1394_dev_t; + + +/* + * Prototypes for standard IEEE-1394 interface... + */ + +extern ieee1394_info_t *ieee1394_list(int *num_devices); +extern ieee1394_dev_t ieee1394_open(const char *uri); +extern int ieee1394_close(ieee1394_dev_t dev); +extern int ieee1394_read(ieee1394_dev_t dev, char *buffer, int len); +extern int ieee1394_write(ieee1394_dev_t dev, char *buffer, int len); +extern const char *ieee1394_error(void); + + +/* + * End of "$Id: ieee1394.h 4494 2005-02-18 02:18:11Z mike $". + */ diff --git a/backend/ipp.c b/backend/ipp.c index 693911c65..c7d647d14 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -1,5 +1,5 @@ /* - * "$Id: ipp.c 6214 2007-01-23 17:01:48Z mike $" + * "$Id: ipp.c 6318 2007-03-06 04:36:55Z mike $" * * IPP backend for the Common UNIX Printing System (CUPS). * @@ -54,7 +54,6 @@ #include #include - /* * Globals... */ @@ -459,7 +458,7 @@ main(int argc, /* I - Number of command-line args */ const char *request_root; /* CUPS_REQUESTROOT env var */ char afilename[1024], /* a##### filename */ - aline[1024]; /* Line from file */ + aline[2048]; /* Line from file */ FILE *fp; /* File pointer */ @@ -1341,6 +1340,8 @@ password_cb(const char *prompt) /* I - Prompt (not used) */ unlink(pstmpname); #endif /* __APPLE__ */ + fputs("ATTR: auth-info-required=username,password\n", stderr); + exit(CUPS_BACKEND_AUTH_REQUIRED); return (NULL); /* Eliminate compiler warning */ @@ -1666,5 +1667,5 @@ sigterm_handler(int sig) /* I - Signal */ /* - * End of "$Id: ipp.c 6214 2007-01-23 17:01:48Z mike $". + * End of "$Id: ipp.c 6318 2007-03-06 04:36:55Z mike $". */ diff --git a/backend/lpd.c b/backend/lpd.c index 1e2b9405f..6366a7fcc 100644 --- a/backend/lpd.c +++ b/backend/lpd.c @@ -1,5 +1,5 @@ /* - * "$Id: lpd.c 6061 2006-10-23 00:26:52Z mike $" + * "$Id: lpd.c 6058 2006-10-23 00:20:09Z mike $" * * Line Printer Daemon backend for the Common UNIX Printing System (CUPS). * @@ -1242,5 +1242,5 @@ sigterm_handler(int sig) /* I - Signal */ /* - * End of "$Id: lpd.c 6061 2006-10-23 00:26:52Z mike $". + * End of "$Id: lpd.c 6058 2006-10-23 00:20:09Z mike $". */ diff --git a/backend/pap.c b/backend/pap.c index dd599f83f..b24ed3617 100644 --- a/backend/pap.c +++ b/backend/pap.c @@ -1,5 +1,5 @@ /* -* "$Id: pap.c 6090 2006-11-14 16:35:27Z mike $" +* "$Id: pap.c 6087 2006-11-14 15:48:34Z mike $" * * © Copyright 2004 Apple Computer, Inc. All rights reserved. * diff --git a/backend/parallel.c b/backend/parallel.c index c33fc10d2..4164e7895 100644 --- a/backend/parallel.c +++ b/backend/parallel.c @@ -1,9 +1,9 @@ /* - * "$Id: parallel.c 6181 2007-01-03 18:51:27Z mike $" + * "$Id: parallel.c 6178 2007-01-03 18:09:17Z mike $" * * Parallel port backend for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -27,6 +27,7 @@ * * main() - Send a file to the specified parallel port. * list_devices() - List all parallel devices. + * side_cb() - Handle side-channel requests... */ /* @@ -66,7 +67,8 @@ * Local functions... */ -void list_devices(void); +static void list_devices(void); +static void side_cb(int print_fd, int device_fd, int use_bc); /* @@ -284,7 +286,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ lseek(print_fd, 0, SEEK_SET); } - tbytes = backendRunLoop(print_fd, device_fd, use_bc); + tbytes = backendRunLoop(print_fd, device_fd, use_bc, side_cb); if (print_fd != 0 && tbytes >= 0) fprintf(stderr, "INFO: Sent print file, " CUPS_LLFMT " bytes...\n", @@ -308,7 +310,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ * 'list_devices()' - List all parallel devices. */ -void +static void list_devices(void) { #if defined(__hpux) || defined(__sgi) || defined(__sun) @@ -598,5 +600,70 @@ list_devices(void) /* - * End of "$Id: parallel.c 6181 2007-01-03 18:51:27Z mike $". + * 'side_cb()' - Handle side-channel requests... + */ + +static void +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)) + { + fputs("WARNING: Failed to read side-channel request!\n", stderr); + return; + } + + switch (command) + { + case CUPS_SC_CMD_DRAIN_OUTPUT : + 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 : + 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; + } + + cupsSideChannelWrite(command, status, data, datalen, 1.0); +} + + +/* + * End of "$Id: parallel.c 6178 2007-01-03 18:09:17Z mike $". */ diff --git a/backend/runloop.c b/backend/runloop.c index f613c0540..461bbb4e7 100644 --- a/backend/runloop.c +++ b/backend/runloop.c @@ -1,9 +1,9 @@ /* - * "$Id: runloop.c 6145 2006-12-06 20:10:16Z mike $" + * "$Id: runloop.c 6170 2007-01-02 17:26:41Z mike $" * * Common run loop API for the Common UNIX Printing System (CUPS). * - * Copyright 2006 by Easy Software Products, all rights reserved. + * Copyright 2006-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -45,9 +45,11 @@ */ ssize_t /* O - Total bytes on success, -1 on error */ -backendRunLoop(int print_fd, /* I - Print file descriptor */ - int device_fd, /* I - Device file descriptor */ - int use_bc) /* I - Use back-channel? */ +backendRunLoop( + int print_fd, /* I - Print file descriptor */ + int device_fd, /* I - Device file descriptor */ + int use_bc, /* I - Use back-channel? */ + void (*side_cb)(int, int, int)) /* I - Side-channel callback */ { int nfds; /* Maximum file descriptor value + 1 */ fd_set input, /* Input set for reading */ @@ -112,12 +114,14 @@ backendRunLoop(int print_fd, /* I - Print file descriptor */ FD_SET(print_fd, &input); if (use_bc) FD_SET(device_fd, &input); + if (side_cb) + FD_SET(CUPS_SC_FD, &input); FD_ZERO(&output); if (print_bytes || !use_bc) FD_SET(device_fd, &output); - if (use_bc) + if (use_bc || side_cb) { if (select(nfds, &input, &output, NULL, NULL) < 0) { @@ -137,6 +141,13 @@ backendRunLoop(int print_fd, /* I - Print file descriptor */ } } + /* + * Check if we have a side-channel request ready... + */ + + if (side_cb && FD_ISSET(CUPS_SC_FD, &input)) + (*side_cb)(print_fd, device_fd, use_bc); + /* * Check if we have back-channel data ready... */ @@ -258,5 +269,5 @@ backendRunLoop(int print_fd, /* I - Print file descriptor */ /* - * End of "$Id: runloop.c 6145 2006-12-06 20:10:16Z mike $". + * End of "$Id: runloop.c 6170 2007-01-02 17:26:41Z mike $". */ diff --git a/backend/scsi.c b/backend/scsi.c index fd06127d7..df4f1fc51 100644 --- a/backend/scsi.c +++ b/backend/scsi.c @@ -1,5 +1,5 @@ /* - * "$Id: scsi.c 6032 2006-10-12 19:19:47Z mike $" + * "$Id: scsi.c 6029 2006-10-12 17:55:17Z mike $" * * SCSI printer backend for the Common UNIX Printing System (CUPS). * @@ -220,5 +220,5 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ /* - * End of "$Id: scsi.c 6032 2006-10-12 19:19:47Z mike $". + * End of "$Id: scsi.c 6029 2006-10-12 17:55:17Z mike $". */ diff --git a/backend/serial.c b/backend/serial.c index ec1b0e6a6..a931389f8 100644 --- a/backend/serial.c +++ b/backend/serial.c @@ -1,9 +1,9 @@ /* - * "$Id: serial.c 6068 2006-10-27 17:10:34Z mike $" + * "$Id: serial.c 6170 2007-01-02 17:26:41Z mike $" * * Serial port backend for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -27,6 +27,7 @@ * * main() - Send a file to the printer or server. * list_devices() - List all serial devices. + * side_cb() - Handle side-channel requests... */ /* @@ -91,7 +92,8 @@ * Local functions... */ -void list_devices(void); +static void list_devices(void); +static void side_cb(int print_fd, int device_fd, int use_bc); /* @@ -556,6 +558,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ if (!print_bytes) FD_SET(print_fd, &input); FD_SET(device_fd, &input); + FD_SET(CUPS_SC_FD, &input); FD_ZERO(&output); if (print_bytes) @@ -564,6 +567,13 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ 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)) + side_cb(print_fd, device_fd, 1); + /* * Check if we have back-channel data ready... */ @@ -712,7 +722,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ * 'list_devices()' - List all serial devices. */ -void +static void list_devices(void) { #if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) @@ -1226,5 +1236,54 @@ list_devices(void) /* - * End of "$Id: serial.c 6068 2006-10-27 17:10:34Z mike $". + * 'side_cb()' - Handle side-channel requests... + */ + +static void +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)) + { + fputs("WARNING: Failed to read side-channel request!\n", stderr); + return; + } + + switch (command) + { + case CUPS_SC_CMD_DRAIN_OUTPUT : + 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 : + data[0] = use_bc; + datalen = 1; + break; + + default : + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + break; + } + + cupsSideChannelWrite(command, status, data, datalen, 1.0); +} + + +/* + * End of "$Id: serial.c 6170 2007-01-02 17:26:41Z mike $". */ diff --git a/backend/snmp.c b/backend/snmp.c index fd7d3922e..a269ddaba 100644 --- a/backend/snmp.c +++ b/backend/snmp.c @@ -1,5 +1,5 @@ /* - * "$Id: snmp.c 6181 2007-01-03 18:51:27Z mike $" + * "$Id: snmp.c 6180 2007-01-03 18:19:32Z mike $" * * SNMP discovery backend for the Common UNIX Printing System (CUPS). * @@ -2459,5 +2459,5 @@ update_cache(snmp_cache_t *device, /* I - Device */ /* - * End of "$Id: snmp.c 6181 2007-01-03 18:51:27Z mike $". + * End of "$Id: snmp.c 6180 2007-01-03 18:19:32Z mike $". */ diff --git a/backend/socket.c b/backend/socket.c index e6889cf8f..20fb7e31d 100644 --- a/backend/socket.c +++ b/backend/socket.c @@ -1,9 +1,9 @@ /* - * "$Id: socket.c 6061 2006-10-23 00:26:52Z mike $" + * "$Id: socket.c 6170 2007-01-02 17:26:41Z mike $" * * AppSocket backend for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -25,7 +25,8 @@ * * Contents: * - * main() - Send a file to the printer or server. + * main() - Send a file to the printer or server. + * side_cb() - Handle side-channel requests... */ /* @@ -50,6 +51,13 @@ #endif /* WIN32 */ +/* + * Local functions... + */ + +static void side_cb(int print_fd, int device_fd, int use_bc); + + /* * 'main()' - Send a file to the printer or server. * @@ -325,7 +333,7 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ lseek(print_fd, 0, SEEK_SET); } - tbytes = backendRunLoop(print_fd, device_fd, 1); + tbytes = backendRunLoop(print_fd, device_fd, 1, side_cb); if (print_fd != 0 && tbytes >= 0) fprintf(stderr, "INFO: Sent print file, " CUPS_LLFMT " bytes...\n", @@ -398,5 +406,54 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ /* - * End of "$Id: socket.c 6061 2006-10-23 00:26:52Z mike $". + * 'side_cb()' - Handle side-channel requests... + */ + +static void +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)) + { + fputs("WARNING: Failed to read side-channel request!\n", stderr); + return; + } + + switch (command) + { + case CUPS_SC_CMD_DRAIN_OUTPUT : + /* + * Our sockets disable the Nagle algorithm and data is sent immediately. + */ + + status = CUPS_SC_STATUS_OK; + datalen = 0; + break; + + case CUPS_SC_CMD_GET_BIDI : + data[0] = use_bc; + datalen = 1; + break; + + default : + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + break; + } + + cupsSideChannelWrite(command, status, data, datalen, 1.0); +} + + +/* + * End of "$Id: socket.c 6170 2007-01-02 17:26:41Z mike $". */ diff --git a/backend/test1284.c b/backend/test1284.c index dc1845e90..4622e5d21 100644 --- a/backend/test1284.c +++ b/backend/test1284.c @@ -1,5 +1,5 @@ /* - * "$Id: test1284.c 5591 2006-05-26 19:51:59Z mike $" + * "$Id: test1284.c 5590 2006-05-26 19:48:26Z mike $" * * IEEE-1284 support functions test program for the Common UNIX Printing * System (CUPS). @@ -92,5 +92,5 @@ main(int argc, /* I - Number of command-line args */ /* - * End of "$Id: test1284.c 5591 2006-05-26 19:51:59Z mike $". + * End of "$Id: test1284.c 5590 2006-05-26 19:48:26Z mike $". */ diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c index d1da59b9b..4e0697752 100644 --- a/backend/usb-darwin.c +++ b/backend/usb-darwin.c @@ -1,5 +1,5 @@ /* - * "$Id: usb-darwin.c 6090 2006-11-14 16:35:27Z mike $" + * "$Id: usb-darwin.c 6302 2007-02-22 19:36:36Z mike $" * * © Copyright 2005-2006 Apple Computer, Inc. All rights reserved. * @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,7 @@ #include + /* * WAITEOF_DELAY is number of seconds we'll wait for responses from * the printer after we've finished sending all the data @@ -86,6 +88,7 @@ #define kUSBGenericTOPrinterClassDriver CFSTR("/System/Library/Printers/Libraries/USBGenericTOPrintingClass.plugin") #define kUSBPrinterClassDeviceNotOpen -9664 /*kPMInvalidIOMContext*/ +#define kWriteBufferSize 2048 #pragma mark - @@ -183,6 +186,17 @@ typedef struct printer_data_s { /**** Printer context data ****/ UInt32 location; Boolean waitEOF; + pthread_cond_t reqWaitCompCond; + pthread_mutex_t reqWaitMutex; + pthread_mutex_t waitCloseMutex; + pthread_mutex_t writeCompMutex; + int writeDone; + int reqWaitDone; + int reqWqitFlag; + int directionalFlag; /* 0=uni, 1=bidi */ + ssize_t dataSize; + ssize_t dataOffset; + char dataBuffer[kWriteBufferSize]; } printer_data_t; @@ -208,6 +222,12 @@ static CFStringRef cfstr_create_and_trim(const char *cstr); static void parse_options(const char *options, char *serial, UInt32 *location, Boolean *waitEOF); static void setup_cfLanguage(void); static void *read_thread(void *reference); +static void *reqestWait_thread(void *reference); +static void usbSoftReset(printer_data_t *userData, cups_sc_status_t *status); +static void usbDrainOutput(printer_data_t *userData, cups_sc_status_t *status); +static void usbGetBidirectional(printer_data_t *userData, cups_sc_status_t *status, char *data, int *datalen); +static void usbGetDeviceID(printer_data_t *userData, cups_sc_status_t *status, char *data, int *datalen); +static void usbGetDevState(printer_data_t *userData, cups_sc_status_t *status, char *data, int *datalen); #if defined(__i386__) @@ -257,6 +277,12 @@ print_device(const char *uri, /* I - Device URI */ pthread_cond_t *readCompleteConditionPtr = NULL; /* Read complete condition */ pthread_mutex_t *readMutexPtr = NULL; /* Read mutex */ CFStringRef driverBundlePath; /* Class driver path */ + int reqWait_create = 0; /* RequestWait thread created? */ + pthread_t reqWaitThread; /* RequestWait thread */ + pthread_cond_t *reqWaitCompCondPtr = NULL; /* RequestWait complete condition */ + pthread_mutex_t *reqWaitMutexPtr = NULL; /* RequestWait mutex */ + pthread_mutex_t *waitCloseMutexPtr = NULL; /* wait close mutex */ + pthread_mutex_t *writeCompMutexPtr = NULL; /* write complete mutex */ setup_cfLanguage(); parse_options(options, serial, &printer_data.location, &printer_data.waitEOF); @@ -358,17 +384,45 @@ print_device(const char *uri, /* I - Device URI */ if (pthread_mutex_init(&printer_data.readMutex, NULL) == 0) readMutexPtr = &printer_data.readMutex; + printer_data.done = 0; + if (pthread_create(&thr, NULL, read_thread, &printer_data) == 0) thread_created = 1; if (thread_created == 0) fprintf(stderr, "WARNING: Couldn't create read channel\n"); + + if (pthread_cond_init(&printer_data.reqWaitCompCond, NULL) == 0) + reqWaitCompCondPtr = &printer_data.reqWaitCompCond; + + if (pthread_mutex_init(&printer_data.reqWaitMutex, NULL) == 0) + reqWaitMutexPtr = &printer_data.reqWaitMutex; + + printer_data.reqWaitDone = 0; + printer_data.reqWqitFlag = 0; + + if (pthread_create(&reqWaitThread, NULL, reqestWait_thread, &printer_data) == 0) + reqWait_create = 1; + + if (reqWait_create == 0) + fprintf(stderr, "WARNING: Couldn't create sidechannel thread!\n"); + + if (pthread_mutex_init(&printer_data.waitCloseMutex, NULL) == 0) + waitCloseMutexPtr = &printer_data.waitCloseMutex; + + if (pthread_mutex_init(&printer_data.writeCompMutex, NULL) == 0) + writeCompMutexPtr = &printer_data.writeCompMutex; } /* * The main thread sends the print file... */ + printer_data.writeDone = 0; + printer_data.dataSize = 0; + printer_data.dataOffset = 0; + pthread_mutex_lock(writeCompMutexPtr); + while (status == noErr && copies-- > 0) { UInt32 wbytes; /* Number of bytes written */ ssize_t nbytes; /* Number of bytes read */ @@ -386,6 +440,15 @@ print_device(const char *uri, /* I - Device URI */ tbytes += nbytes; while (nbytes > 0 && status == noErr) { + if (printer_data.writeDone) { + printer_data.dataSize = nbytes; + printer_data.dataOffset = bufptr - buffer; + memcpy(printer_data.dataBuffer, buffer, nbytes); + + status = -1; + break; + } + wbytes = nbytes; status = (*(printer_data.printerDriver))->WritePipe( printer_data.printerDriver, (UInt8*)bufptr, &wbytes, 0 /* nbytes > wbytes? 0: feof(fp) */ ); if (wbytes < 0 || noErr != status) { @@ -403,6 +466,9 @@ print_device(const char *uri, /* I - Device URI */ } } + printer_data.writeDone = 1; + pthread_mutex_unlock(writeCompMutexPtr); + if (thread_created) { /* Signal the read thread that we are done... */ printer_data.done = 1; @@ -420,6 +486,35 @@ print_device(const char *uri, /* I - Device URI */ pthread_join( thr,NULL); /* wait for the child thread to return */ } + if (reqWait_create) { + /* Signal the cupsSideChannelDoRequest wait thread that we are done... */ + printer_data.reqWaitDone = 1; + + /* + * Give the cupsSideChannelDoRequest wait thread WAITEOF_DELAY seconds to complete + * all the data. If we are not signaled in that time then force the thread to exit + * by setting the waiteof to be false. Plese note that this relies on us using the + * timeout class driver. + */ + struct timespec reqWaitSleepUntil = { time(NULL) + WAITEOF_DELAY, 0 }; + pthread_mutex_lock(&printer_data.reqWaitMutex); + + while (!printer_data.reqWqitFlag) { + if (pthread_cond_timedwait(&printer_data.reqWaitCompCond, + &printer_data.reqWaitMutex, + (const struct timespec *)&reqWaitSleepUntil) != 0) { + printer_data.waitEOF = false; + printer_data.reqWqitFlag = 1; + } + } + pthread_mutex_unlock(&printer_data.reqWaitMutex); + pthread_join(reqWaitThread,NULL); /* wait for the child thread to return */ + } + + /* interface close wait mutex(for softreset) */ + pthread_mutex_lock(waitCloseMutexPtr); + pthread_mutex_unlock(waitCloseMutexPtr); + /* * Close the connection and input file and general clean up... */ @@ -434,6 +529,18 @@ print_device(const char *uri, /* I - Device URI */ if (readMutexPtr != NULL) pthread_mutex_destroy(&printer_data.readMutex); + if (waitCloseMutexPtr != NULL) + pthread_mutex_destroy(&printer_data.waitCloseMutex); + + if (writeCompMutexPtr != NULL) + pthread_mutex_destroy(&printer_data.writeCompMutex); + + if (reqWaitCompCondPtr != NULL) + pthread_cond_destroy(&printer_data.reqWaitCompCond); + + if (reqWaitMutexPtr != NULL) + pthread_mutex_destroy(&printer_data.reqWaitMutex); + if (printer_data.make != NULL) CFRelease(printer_data.make); @@ -465,16 +572,27 @@ static Boolean list_device_callback(void *refcon, io_service_t obj) copy_devicestring(obj, &deviceIDString, &deviceLocation); if (deviceIDString != NULL) { CFStringRef make = NULL, model = NULL, serial = NULL; - char uristr[1024], makestr[1024], modelstr[1024], serialstr[1024], optionsstr[1024]; - char idstr[1024]; + char uristr[1024], makestr[1024], modelstr[1024], serialstr[1024]; + char optionsstr[1024], idstr[1024]; copy_deviceinfo(deviceIDString, &make, &model, &serial); modelstr[0] = '/'; - CFStringGetCString(deviceIDString, idstr, sizeof(idstr), kCFStringEncodingUTF8); - CFStringGetCString(make, makestr, sizeof(makestr), kCFStringEncodingUTF8); - CFStringGetCString(model, &modelstr[1], sizeof(modelstr)-1, kCFStringEncodingUTF8); + CFStringGetCString(deviceIDString, idstr, sizeof(idstr), + kCFStringEncodingUTF8); + + if (make) + CFStringGetCString(make, makestr, sizeof(makestr), + kCFStringEncodingUTF8); + else + strcpy(makestr, "Unknown"); + + if (model) + CFStringGetCString(model, &modelstr[1], sizeof(modelstr)-1, + kCFStringEncodingUTF8); + else + strcpy(modelstr + 1, "Printer"); /* * Fix common HP 1284 bug... @@ -792,6 +910,8 @@ static kern_return_t load_printerdriver(printer_data_t *printer, CFStringRef *dr static kern_return_t registry_open(printer_data_t *printer, CFStringRef *driverBundlePath) { + printer->directionalFlag = 0; + kern_return_t kr = load_printerdriver(printer, driverBundlePath); if (kr != kIOReturnSuccess) { kr = -2; @@ -807,6 +927,8 @@ static kern_return_t registry_open(printer_data_t *printer, CFStringRef *driverB kr = -1; } } + } else { + printer->directionalFlag = 1; } } @@ -1392,5 +1514,201 @@ static void *read_thread(void *reference) } /* - * End of "$Id: usb-darwin.c 6090 2006-11-14 16:35:27Z mike $". + * 'reqestWait_thread()' - A thread cupsSideChannelDoRequest wait. + */ +static void *reqestWait_thread(void *reference) { + printer_data_t *userData = (printer_data_t *)reference; + int datalen; + cups_sc_command_t command; + cups_sc_status_t status; + uint64_t start, delay; + struct mach_timebase_info timeBaseInfo; + char data[2048]; + + /* + * Calculate what 100 milliSeconds are in mach absolute time... + */ + mach_timebase_info(&timeBaseInfo); + delay = ((uint64_t)100000000 * (uint64_t)timeBaseInfo.denom) / (uint64_t)timeBaseInfo.numer; + + /* interface close wait mutex lock. */ + pthread_mutex_lock(&(userData->waitCloseMutex)); + + do { + /* + * Remember when we started so we can throttle the loop after the cupsSideChannelDoRequest call... + */ + start = mach_absolute_time(); + + /* Poll for a command... */ + command=0; + datalen = sizeof(data); + bzero(data, sizeof(data)); + + if (!cupsSideChannelRead(&command, &status, data, &datalen, 0.0)) { + datalen = sizeof(data); + + switch (command) { + case CUPS_SC_CMD_SOFT_RESET: + /* do a soft reset */ + usbSoftReset(userData, &status); + datalen = 0; + userData->reqWaitDone = 1; + break; + case CUPS_SC_CMD_DRAIN_OUTPUT: + /* drain all pending output */ + usbDrainOutput(userData, &status); + datalen = 0; + break; + case CUPS_SC_CMD_GET_BIDI: + /* return whether the connection is bidirectional */ + usbGetBidirectional(userData, &status, data, &datalen); + break; + case CUPS_SC_CMD_GET_DEVICE_ID: + /* return the IEEE-1284 device ID */ + usbGetDeviceID(userData, &status, data, &datalen); + break; + case CUPS_SC_CMD_GET_STATE: + /* return the device state */ + usbGetDevState(userData, &status, data, &datalen); + break; + default: + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + break; + } + + if (userData->writeDone) { + status = CUPS_SC_STATUS_NONE; + } + + /* Send a response... */ + cupsSideChannelWrite(command, status, data, datalen, 1.0); + } + + /* + * Make sure this loop executes no more than once every 500 miliseconds... + */ + if ((userData->waitEOF) || (!userData->reqWaitDone)) { + mach_wait_until(start + delay); + } + } while(!userData->reqWaitDone); + + sleep(1); + pthread_mutex_lock(&userData->reqWaitMutex); + userData->reqWqitFlag = 1; + pthread_cond_signal(&userData->reqWaitCompCond); + pthread_mutex_unlock(&userData->reqWaitMutex); + + /* interface close wait mutex unlock. */ + pthread_mutex_unlock(&(userData->waitCloseMutex)); + + return NULL; +} + +#pragma mark - +/* + * 'usbSoftReset' + */ +static void usbSoftReset(printer_data_t *userData, cups_sc_status_t *status) { + OSStatus err; + + /* write stop. */ + userData->writeDone = 1; + + /* Abort (print_device()-WritePipe kIOReturnAborted return) */ + if (userData->printerDriver != NULL) + err = (*(userData->printerDriver))->Abort(userData->printerDriver); + + /* print_device() WritePipe_Loop break wait. */ + pthread_mutex_lock(&(userData->writeCompMutex)); + pthread_mutex_unlock(&(userData->writeCompMutex)); + + /* SoftReset */ + if (userData->printerDriver != NULL) + (*(userData->printerDriver))->SoftReset(userData->printerDriver, 0); + + if (status != NULL) + *status = CUPS_SC_STATUS_OK; +} + +/* + * 'usbDrainOutput' + */ +static void usbDrainOutput(printer_data_t *userData, cups_sc_status_t *status) { + OSStatus osSts = noErr; /* Function results */ + OSStatus err = noErr; + UInt32 wbytes; /* Number of bytes written */ + ssize_t nbytes; /* Number of bytes read */ + char *bufptr; + + bufptr = userData->dataBuffer+userData->dataOffset; + nbytes = userData->dataSize; + + while((nbytes > 0) && (osSts == noErr)) { + wbytes = nbytes; + osSts = (*(userData->printerDriver))->WritePipe(userData->printerDriver, (UInt8*)bufptr, &wbytes, 0); + + if (wbytes < 0 || noErr != osSts) { + if (osSts != kIOReturnAborted) { + err = (*(userData->printerDriver))->Abort(userData->printerDriver); + break; + } + } + + nbytes -= wbytes; + bufptr += wbytes; + } + + if (status != NULL) { + if ((osSts != noErr) || (err != noErr)) { + *status = CUPS_SC_STATUS_IO_ERROR; + } else { + *status = CUPS_SC_STATUS_OK; + } + } +} + +/* + * 'usbGetBidirectional' + */ +static void usbGetBidirectional(printer_data_t *userData, cups_sc_status_t *status, char *data, int *datalen) { + *data = userData->directionalFlag; + *datalen = 1; + + if (status != NULL) + *status = CUPS_SC_STATUS_OK; +} + +/* + * 'usbGetDeviceID' + */ +static void usbGetDeviceID(printer_data_t *userData, cups_sc_status_t *status, char *data, int *datalen) { + UInt32 deviceLocation = 0; + CFStringRef deviceIDString = NULL; + + /* GetDeviceID */ + copy_devicestring(userData->printerObj, &deviceIDString, &deviceLocation); + CFStringGetCString(deviceIDString, data, *datalen, kCFStringEncodingUTF8); + *datalen = strlen(data); + + if (status != NULL) { + *status = CUPS_SC_STATUS_OK; + } +} + +/* + * 'usbGetDevState' + */ +static void usbGetDevState(printer_data_t *userData, cups_sc_status_t *status, char *data, int *datalen) { + *data = CUPS_SC_STATE_ONLINE; + *datalen = 1; + + if (status != NULL) { + *status = CUPS_SC_STATUS_OK; + } +} + +/* + * End of "$Id: usb-darwin.c 6302 2007-02-22 19:36:36Z mike $". */ diff --git a/backend/usb-unix.c b/backend/usb-unix.c index 7e78a3f27..5efa30ff9 100644 --- a/backend/usb-unix.c +++ b/backend/usb-unix.c @@ -1,11 +1,11 @@ /* - * "$Id: usb-unix.c 6234 2007-02-05 20:25:50Z mike $" + * "$Id: usb-unix.c 6293 2007-02-20 13:40:55Z mike $" * * USB port backend for the Common UNIX Printing System (CUPS). * * This file is included from "usb.c" when compiled on UNIX/Linux. * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -30,6 +30,7 @@ * print_device() - Print a file to a USB device. * list_devices() - List all USB devices. * open_device() - Open a USB device... + * side_cb() - Handle side-channel requests... */ /* @@ -44,7 +45,8 @@ * Local functions... */ -int open_device(const char *uri, int *use_bc); +static int open_device(const char *uri, int *use_bc); +static void side_cb(int print_fd, int device_fd, int use_bc); /* @@ -79,12 +81,14 @@ print_device(const char *uri, /* I - Device URI */ do { /* - * Disable backchannel data when printing to Canon or Minolta USB - * printers - apparently these printers will return the IEEE-1284 - * device ID over and over and over when they get a read request... + * Disable backchannel data when printing to Brother, Canon, or + * Minolta USB printers - apparently these printers will return + * the IEEE-1284 device ID over and over and over when they get + * a read request... */ - use_bc = strcasecmp(hostname, "Canon") && + use_bc = strcasecmp(hostname, "Brother") && + strcasecmp(hostname, "Canon") && strcasecmp(hostname, "Konica Minolta") && strcasecmp(hostname, "Minolta"); @@ -162,7 +166,7 @@ print_device(const char *uri, /* I - Device URI */ lseek(print_fd, 0, SEEK_SET); } - tbytes = backendRunLoop(print_fd, device_fd, use_bc); + tbytes = backendRunLoop(print_fd, device_fd, use_bc, side_cb); if (print_fd != 0 && tbytes >= 0) fprintf(stderr, "INFO: Sent print file, " CUPS_LLFMT " bytes...\n", @@ -288,7 +292,7 @@ list_devices(void) * 'open_device()' - Open a USB device... */ -int /* O - File descriptor or -1 on error */ +static int /* O - File descriptor or -1 on error */ open_device(const char *uri, /* I - Device URI */ int *use_bc) /* O - Set to 0 for unidirectional */ { @@ -526,5 +530,70 @@ open_device(const char *uri, /* I - Device URI */ /* - * End of "$Id: usb-unix.c 6234 2007-02-05 20:25:50Z mike $". + * 'side_cb()' - Handle side-channel requests... + */ + +static void +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)) + { + fputs("WARNING: Failed to read side-channel request!\n", stderr); + return; + } + + switch (command) + { + case CUPS_SC_CMD_DRAIN_OUTPUT : + 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 : + 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; + } + + cupsSideChannelWrite(command, status, data, datalen, 1.0); +} + + +/* + * End of "$Id: usb-unix.c 6293 2007-02-20 13:40:55Z mike $". */ diff --git a/backend/usb.c b/backend/usb.c index cee5d86ca..ad6d95d07 100644 --- a/backend/usb.c +++ b/backend/usb.c @@ -1,5 +1,5 @@ /* - * "$Id: usb.c 5591 2006-05-26 19:51:59Z mike $" + * "$Id: usb.c 5590 2006-05-26 19:48:26Z mike $" * * USB port backend for the Common UNIX Printing System (CUPS). * @@ -270,5 +270,5 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */ /* - * End of "$Id: usb.c 5591 2006-05-26 19:51:59Z mike $". + * End of "$Id: usb.c 5590 2006-05-26 19:48:26Z mike $". */ diff --git a/berkeley/Dependencies b/berkeley/Dependencies index 767d33e1c..2c5dd988d 100644 --- a/berkeley/Dependencies +++ b/berkeley/Dependencies @@ -1,16 +1,14 @@ # DO NOT DELETE -lpc.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -lpc.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h -lpc.o: ../cups/i18n.h ../cups/transcode.h ../cups/debug.h ../cups/string.h -lpc.o: ../config.h +lpc.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +lpc.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h +lpc.o: ../cups/transcode.h ../cups/debug.h ../cups/string.h ../config.h lpq.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h -lpq.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h -lpq.o: ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h -lpq.o: ../cups/debug.h +lpq.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +lpq.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h lpr.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h -lpr.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h -lpr.o: ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h -lprm.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -lprm.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h -lprm.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +lpr.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +lpr.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +lprm.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +lprm.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h +lprm.o: ../cups/transcode.h ../cups/string.h ../config.h diff --git a/berkeley/lpc.c b/berkeley/lpc.c index 3c51c6a54..808ed674d 100644 --- a/berkeley/lpc.c +++ b/berkeley/lpc.c @@ -1,5 +1,5 @@ /* - * "$Id: lpc.c 6073 2006-11-02 20:01:54Z mike $" + * "$Id: lpc.c 6070 2006-11-02 16:20:46Z mike $" * * "lpc" command for the Common UNIX Printing System (CUPS). * @@ -471,5 +471,5 @@ show_status(http_t *http, /* I - HTTP connection to server */ /* - * End of "$Id: lpc.c 6073 2006-11-02 20:01:54Z mike $". + * End of "$Id: lpc.c 6070 2006-11-02 16:20:46Z mike $". */ diff --git a/berkeley/lpq.c b/berkeley/lpq.c index 1feacaaf4..719e3b249 100644 --- a/berkeley/lpq.c +++ b/berkeley/lpq.c @@ -1,5 +1,5 @@ /* - * "$Id: lpq.c 5926 2006-09-05 20:45:47Z mike $" + * "$Id: lpq.c 5925 2006-09-05 19:43:11Z mike $" * * "lpq" command for the Common UNIX Printing System (CUPS). * @@ -676,5 +676,5 @@ usage(void) /* - * End of "$Id: lpq.c 5926 2006-09-05 20:45:47Z mike $". + * End of "$Id: lpq.c 5925 2006-09-05 19:43:11Z mike $". */ diff --git a/berkeley/lpr.c b/berkeley/lpr.c index 1597aef2f..893c62bf3 100644 --- a/berkeley/lpr.c +++ b/berkeley/lpr.c @@ -1,5 +1,5 @@ /* - * "$Id: lpr.c 5926 2006-09-05 20:45:47Z mike $" + * "$Id: lpr.c 5925 2006-09-05 19:43:11Z mike $" * * "lpr" command for the Common UNIX Printing System (CUPS). * @@ -529,5 +529,5 @@ sighandler(int s) /* I - Signal number */ /* - * End of "$Id: lpr.c 5926 2006-09-05 20:45:47Z mike $". + * End of "$Id: lpr.c 5925 2006-09-05 19:43:11Z mike $". */ diff --git a/berkeley/lprm.c b/berkeley/lprm.c index 0551dbbd4..23fbbb37d 100644 --- a/berkeley/lprm.c +++ b/berkeley/lprm.c @@ -1,5 +1,5 @@ /* - * "$Id: lprm.c 5926 2006-09-05 20:45:47Z mike $" + * "$Id: lprm.c 5925 2006-09-05 19:43:11Z mike $" * * "lprm" command for the Common UNIX Printing System (CUPS). * @@ -294,5 +294,5 @@ main(int argc, /* I - Number of command-line arguments */ /* - * End of "$Id: lprm.c 5926 2006-09-05 20:45:47Z mike $". + * End of "$Id: lprm.c 5925 2006-09-05 19:43:11Z mike $". */ diff --git a/cgi-bin/Dependencies b/cgi-bin/Dependencies index 7e976859d..e87f276b8 100644 --- a/cgi-bin/Dependencies +++ b/cgi-bin/Dependencies @@ -1,57 +1,56 @@ # DO NOT DELETE help-index.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -help-index.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -help-index.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -help-index.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h -help-index.o: ../cups/dir.h +help-index.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +help-index.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +help-index.o: ../cups/transcode.h ../cups/string.h ../config.h ../cups/dir.h html.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -html.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -html.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -html.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +html.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +html.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +html.o: ../cups/transcode.h ../cups/string.h ../config.h ipp-var.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -ipp-var.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -ipp-var.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -ipp-var.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +ipp-var.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +ipp-var.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +ipp-var.o: ../cups/transcode.h ../cups/string.h ../config.h search.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -search.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -search.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -search.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +search.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +search.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +search.o: ../cups/transcode.h ../cups/string.h ../config.h template.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -template.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -template.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -template.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +template.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +template.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +template.o: ../cups/transcode.h ../cups/string.h ../config.h var.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -var.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -var.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -var.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +var.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +var.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +var.o: ../cups/transcode.h ../cups/string.h ../config.h admin.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -admin.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -admin.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -admin.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h -admin.o: ../cups/adminutil.h ../cups/cups.h ../cups/file.h +admin.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +admin.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +admin.o: ../cups/transcode.h ../cups/string.h ../config.h ../cups/adminutil.h +admin.o: ../cups/cups.h ../cups/file.h classes.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -classes.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -classes.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -classes.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +classes.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +classes.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +classes.o: ../cups/transcode.h ../cups/string.h ../config.h help.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -help.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -help.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -help.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +help.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +help.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +help.o: ../cups/transcode.h ../cups/string.h ../config.h jobs.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -jobs.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -jobs.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -jobs.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +jobs.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +jobs.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +jobs.o: ../cups/transcode.h ../cups/string.h ../config.h printers.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -printers.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h -printers.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h -printers.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h -testcgi.o: cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -testcgi.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h -testcgi.o: ../cups/array.h help-index.h -testhi.o: cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -testhi.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h -testhi.o: ../cups/array.h help-index.h +printers.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +printers.o: ../cups/array.h help-index.h ../cups/debug.h ../cups/i18n.h +printers.o: ../cups/transcode.h ../cups/string.h ../config.h +testcgi.o: cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +testcgi.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/array.h +testcgi.o: help-index.h +testhi.o: cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +testhi.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/array.h +testhi.o: help-index.h testtemplate.o: cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -testtemplate.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h +testtemplate.o: ../cups/ppd.h ../cups/array.h ../cups/file.h testtemplate.o: ../cups/language.h ../cups/array.h help-index.h diff --git a/cgi-bin/Makefile b/cgi-bin/Makefile index 9497bb59f..bf884689c 100644 --- a/cgi-bin/Makefile +++ b/cgi-bin/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5229 2006-03-05 16:48:12Z mike $" +# "$Id: Makefile 6055 2006-10-23 00:11:55Z mike $" # # CGI makefile for the Common UNIX Printing System (CUPS). # @@ -139,7 +139,7 @@ printers.cgi: printers.o ../Makedefs ../cups/$(LIBCUPS) libcgi.a testcgi: testcgi.o ../Makedefs libcgi.a ../cups/libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testcgi.o libcgi.a ../cups/libcups.a \ - $(COMMONLIBS) $(SSLLIBS) $(LIBZ) + $(COMMONLIBS) $(SSLLIBS) $(LIBZ) $(LIBGSSAPI) # @@ -149,7 +149,7 @@ testcgi: testcgi.o ../Makedefs libcgi.a ../cups/libcups.a testhi: testhi.o ../Makedefs libcgi.a ../cups/libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testhi.o libcgi.a ../cups/libcups.a \ - $(COMMONLIBS) $(SSLLIBS) $(LIBZ) + $(COMMONLIBS) $(SSLLIBS) $(LIBZ) $(LIBGSSAPI) # @@ -159,7 +159,7 @@ testhi: testhi.o ../Makedefs libcgi.a ../cups/libcups.a testtemplate: testtemplate.o ../Makedefs libcgi.a ../cups/libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testtemplate.o libcgi.a ../cups/libcups.a \ - $(COMMONLIBS) $(SSLLIBS) $(LIBZ) + $(COMMONLIBS) $(SSLLIBS) $(LIBZ) $(LIBGSSAPI) # @@ -170,5 +170,5 @@ include Dependencies # -# End of "$Id: Makefile 5229 2006-03-05 16:48:12Z mike $". +# End of "$Id: Makefile 6055 2006-10-23 00:11:55Z mike $". # diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c index 6536c86f7..de4bcd112 100644 --- a/cgi-bin/admin.c +++ b/cgi-bin/admin.c @@ -1,9 +1,9 @@ /* - * "$Id: admin.c 5878 2006-08-24 15:55:42Z mike $" + * "$Id: admin.c 6304 2007-02-22 22:06:23Z mike $" * * Administration CGI for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -24,8 +24,10 @@ * Contents: * * main() - Main entry for CGI. + * do_add_rss_subscription() - Add a RSS subscription. * do_am_class() - Add or modify a class. * do_am_printer() - Add or modify a printer. + * do_cancel_subscription() - Cancel a subscription. * do_config_printer() - Configure the default options for a printer. * do_config_server() - Configure server settings. * do_delete_class() - Delete a class... @@ -55,8 +57,10 @@ * Local functions... */ +static void do_add_rss_subscription(http_t *http); static void do_am_class(http_t *http, int modify); static void do_am_printer(http_t *http, int modify); +static void do_cancel_subscription(http_t *http); static void do_config_printer(http_t *http); static void do_config_server(http_t *http); static void do_delete_class(http_t *http); @@ -186,6 +190,10 @@ main(int argc, /* I - Number of command-line arguments */ do_config_server(http); else if (!strcmp(op, "export-samba")) do_export(http); + else if (!strcmp(op, "add-rss-subscription")) + do_add_rss_subscription(http); + else if (!strcmp(op, "cancel-subscription")) + do_cancel_subscription(http); else { /* @@ -222,6 +230,165 @@ main(int argc, /* I - Number of command-line arguments */ } +/* + * 'do_add_rss_subscription()' - Add a RSS subscription. + */ + +static void +do_add_rss_subscription(http_t *http) /* I - HTTP connection */ +{ + ipp_t *request, /* IPP request data */ + *response; /* IPP response data */ + char rss_uri[1024]; /* RSS notify-recipient URI */ + int num_events; /* Number of events */ + const char *events[12], /* Subscribed events */ + *subscription_name, /* Subscription name */ + *printer_uri, /* Printer URI */ + *ptr, /* Pointer into name */ + *user; /* Username */ + int max_events; /* Maximum number of events */ + + + /* + * See if we have all of the required information... + */ + + subscription_name = cgiGetVariable("SUBSCRIPTION_NAME"); + printer_uri = cgiGetVariable("PRINTER_URI"); + num_events = 0; + + if (cgiGetVariable("EVENT_JOB_CREATED")) + events[num_events ++] = "job-created"; + if (cgiGetVariable("EVENT_JOB_COMPLETED")) + events[num_events ++] = "job-completed"; + if (cgiGetVariable("EVENT_JOB_STOPPED")) + events[num_events ++] = "job-stopped"; + if (cgiGetVariable("EVENT_JOB_CONFIG_CHANGED")) + events[num_events ++] = "job-config-changed"; + if (cgiGetVariable("EVENT_PRINTER_STOPPED")) + events[num_events ++] = "printer-stopped"; + if (cgiGetVariable("EVENT_PRINTER_ADDED")) + events[num_events ++] = "printer-added"; + if (cgiGetVariable("EVENT_PRINTER_MODIFIED")) + events[num_events ++] = "printer-modified"; + if (cgiGetVariable("EVENT_PRINTER_DELETED")) + events[num_events ++] = "printer-deleted"; + if (cgiGetVariable("EVENT_SERVER_STARTED")) + events[num_events ++] = "server-started"; + if (cgiGetVariable("EVENT_SERVER_STOPPED")) + events[num_events ++] = "server-stopped"; + if (cgiGetVariable("EVENT_SERVER_RESTARTED")) + events[num_events ++] = "server-restarted"; + if (cgiGetVariable("EVENT_SERVER_AUDIT")) + events[num_events ++] = "server-audit"; + + if ((ptr = cgiGetVariable("MAX_EVENTS")) != NULL) + max_events = atoi(ptr); + else + max_events = 0; + + if (!subscription_name || !printer_uri || !num_events || + max_events <= 0 || max_events > 9999) + { + /* + * Don't have everything we need, so get the available printers + * and classes and (re)show the add page... + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + response = cupsDoRequest(http, request, "/"); + + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + + ippDelete(response); + + cgiStartHTML(cgiText(_("Add RSS Subscription"))); + + cgiCopyTemplateLang("add-rss-subscription.tmpl"); + + cgiEndHTML(); + return; + } + + /* + * Validate the subscription name... + */ + + for (ptr = subscription_name; *ptr; ptr ++) + if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || + *ptr == '?' || *ptr == '#') + break; + + if (*ptr) + { + cgiSetVariable("ERROR", + cgiText(_("The subscription name may not " + "contain spaces, slashes (/), question marks (?), " + "or the pound sign (#)."))); + cgiStartHTML(_("Add RSS Subscription")); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + /* + * Add the subscription... + */ + + ptr = subscription_name + strlen(subscription_name) - 4; + if (ptr < subscription_name || strcmp(ptr, ".rss")) + httpAssembleURIf(HTTP_URI_CODING_ALL, rss_uri, sizeof(rss_uri), "rss", + NULL, NULL, 0, "/%s.rss?max_events=%d", subscription_name, + max_events); + else + httpAssembleURIf(HTTP_URI_CODING_ALL, rss_uri, sizeof(rss_uri), "rss", + NULL, NULL, 0, "/%s?max_events=%d", subscription_name, + max_events); + + request = ippNewRequest(IPP_CREATE_PRINTER_SUBSCRIPTION); + + if (!strcasecmp(printer_uri, "#ALL#")) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/"); + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, printer_uri); + + if ((user = getenv("REMOTE_USER")) == NULL) + user = "guest"; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, user); + + ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, "notify-recipient", + NULL, rss_uri); + ippAddStrings(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events", + num_events, NULL, events); + ippAddInteger(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-lease-duration", 0); + + ippDelete(cupsDoRequest(http, request, "/")); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(_("Add RSS Subscription")); + cgiShowIPPError(_("Unable to add RSS subscription:")); + } + else + { + /* + * Redirect successful updates back to the admin page... + */ + + cgiSetVariable("refresh_page", "5;URL=/admin"); + cgiStartHTML(_("Add RSS Subscription")); + cgiCopyTemplateLang("subscription-added.tmpl"); + } + + cgiEndHTML(); +} + + /* * 'do_am_class()' - Add or modify a class. */ @@ -259,14 +426,10 @@ do_am_class(http_t *http, /* I - HTTP connection */ * * attributes-charset * attributes-natural-language - * printer-uri */ request = ippNewRequest(CUPS_GET_PRINTERS); - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", - NULL, "ipp://localhost/printers"); - /* * Do the request and get back a response... */ @@ -651,8 +814,6 @@ do_am_printer(http_t *http, /* I - HTTP connection */ * Do the request and get back a response... */ - fprintf(stderr, "DEBUG: http=%p (%s)\n", http, http->hostname); - if ((response = cupsDoRequest(http, request, "/")) != NULL) { fputs("DEBUG: Got device list!\n", stderr); @@ -1063,6 +1224,76 @@ do_am_printer(http_t *http, /* I - HTTP connection */ } +/* + * 'do_cancel_subscription()' - Cancel a subscription. + */ + +static void +do_cancel_subscription(http_t *http)/* I - HTTP connection */ +{ + ipp_t *request; /* IPP request data */ + const char *var, /* Form variable */ + *user; /* Username */ + int id; /* Subscription ID */ + + + /* + * See if we have all of the required information... + */ + + if ((var = cgiGetVariable("NOTIFY_SUBSCRIPTION_ID")) != NULL) + id = atoi(var); + else + id = 0; + + if (id <= 0) + { + cgiSetVariable("ERROR", cgiText(_("Bad subscription ID!"))); + cgiStartHTML(_("Cancel RSS Subscription")); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + /* + * Cancel the subscription... + */ + + request = ippNewRequest(IPP_CANCEL_SUBSCRIPTION); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/"); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, + "notify-subscription-id", id); + + if ((user = getenv("REMOTE_USER")) == NULL) + user = "guest"; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, user); + + ippDelete(cupsDoRequest(http, request, "/")); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(_("Cancel RSS Subscription")); + cgiShowIPPError(_("Unable to cancel RSS subscription:")); + } + else + { + /* + * Redirect successful updates back to the admin page... + */ + + cgiSetVariable("refresh_page", "5;URL=/admin"); + cgiStartHTML(_("Cancel RSS Subscription")); + cgiCopyTemplateLang("subscription-canceled.tmpl"); + } + + cgiEndHTML(); +} + + /* * 'do_config_printer()' - Configure the default options for a printer. */ @@ -1599,6 +1830,7 @@ do_config_server(http_t *http) /* I - HTTP connection */ cups_option_t *settings; /* Server settings */ const char *debug_logging, /* DEBUG_LOGGING value */ *remote_admin, /* REMOTE_ADMIN value */ + *remote_any, /* REMOTE_ANY value */ *remote_printers, /* REMOTE_PRINTERS value */ *share_printers,/* SHARE_PRINTERS value */ @@ -1612,6 +1844,7 @@ do_config_server(http_t *http) /* I - HTTP connection */ debug_logging = cgiGetVariable("DEBUG_LOGGING") ? "1" : "0"; remote_admin = cgiGetVariable("REMOTE_ADMIN") ? "1" : "0"; + remote_any = cgiGetVariable("REMOTE_ANY") ? "1" : "0"; remote_printers = cgiGetVariable("REMOTE_PRINTERS") ? "1" : "0"; share_printers = cgiGetVariable("SHARE_PRINTERS") ? "1" : "0"; user_cancel_any = cgiGetVariable("USER_CANCEL_ANY") ? "1" : "0"; @@ -1639,6 +1872,8 @@ do_config_server(http_t *http) /* I - HTTP connection */ num_settings, settings)) || strcmp(remote_admin, cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings, settings)) || + strcmp(remote_any, cupsGetOption(CUPS_SERVER_REMOTE_ANY, + num_settings, settings)) || strcmp(remote_printers, cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS, num_settings, settings)) || strcmp(share_printers, cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, @@ -1657,6 +1892,8 @@ do_config_server(http_t *http) /* I - HTTP connection */ debug_logging, num_settings, &settings); num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, remote_admin, num_settings, &settings); + num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, + remote_any, num_settings, &settings); num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS, remote_printers, num_settings, &settings); num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, @@ -1948,6 +2185,15 @@ do_delete_class(http_t *http) /* I - HTTP connection */ * Show the results... */ + if (cupsLastError() <= IPP_OK_CONFLICT) + { + /* + * Redirect successful updates back to the classes page... + */ + + cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&URL=/classes"); + } + cgiStartHTML(cgiText(_("Delete Class"))); if (cupsLastError() > IPP_OK_CONFLICT) @@ -2019,6 +2265,15 @@ do_delete_printer(http_t *http) /* I - HTTP connection */ * Show the results... */ + if (cupsLastError() <= IPP_OK_CONFLICT) + { + /* + * Redirect successful updates back to the printers page... + */ + + cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&URL=/printers"); + } + cgiStartHTML(cgiText(_("Delete Printer"))); if (cupsLastError() > IPP_OK_CONFLICT) @@ -2202,6 +2457,10 @@ do_menu(http_t *http) /* I - HTTP connection */ settings)) != NULL && atoi(val)) cgiSetVariable("REMOTE_ADMIN", "CHECKED"); + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, num_settings, + settings)) != NULL && atoi(val)) + cgiSetVariable("REMOTE_ANY", "CHECKED"); + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS, num_settings, settings)) != NULL && atoi(val)) cgiSetVariable("REMOTE_PRINTERS", "CHECKED"); @@ -2342,7 +2601,7 @@ do_menu(http_t *http) /* I - HTTP connection */ * suitable name. */ - strcpy(options, "PRINTER_NAME="); + strcpy(options, "TEMPLATE_NAME="); options_ptr = options + strlen(options); if (strncasecmp(device_info, "unknown", 7)) @@ -2461,6 +2720,21 @@ do_menu(http_t *http) /* I - HTTP connection */ else perror(filename); + /* + * Subscriptions... + */ + + request = ippNewRequest(IPP_GET_SUBSCRIPTIONS); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/"); + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + ippDelete(response); + } + /* * Finally, show the main menu template... */ @@ -2951,5 +3225,5 @@ match_string(const char *a, /* I - First string */ /* - * End of "$Id: admin.c 5878 2006-08-24 15:55:42Z mike $". + * End of "$Id: admin.c 6304 2007-02-22 22:06:23Z mike $". */ diff --git a/cgi-bin/classes.c b/cgi-bin/classes.c index f639525cc..1c22d513e 100644 --- a/cgi-bin/classes.c +++ b/cgi-bin/classes.c @@ -1,5 +1,5 @@ /* - * "$Id: classes.c 5572 2006-05-22 18:47:09Z mike $" + * "$Id: classes.c 5571 2006-05-22 18:46:55Z mike $" * * Class status CGI for the Common UNIX Printing System (CUPS). * @@ -463,5 +463,5 @@ show_class(http_t *http, /* I - Connection to server */ /* - * End of "$Id: classes.c 5572 2006-05-22 18:47:09Z mike $". + * End of "$Id: classes.c 5571 2006-05-22 18:46:55Z mike $". */ diff --git a/cgi-bin/help-index.c b/cgi-bin/help-index.c index 8daf99049..df909a406 100644 --- a/cgi-bin/help-index.c +++ b/cgi-bin/help-index.c @@ -1,9 +1,9 @@ /* - * "$Id: help-index.c 5665 2006-06-16 00:59:10Z mike $" + * "$Id: help-index.c 6258 2007-02-11 01:16:31Z mike $" * * On-line help index routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -28,13 +28,16 @@ * helpLoadIndex() - Load a help index from disk. * helpSaveIndex() - Save a help index to disk. * helpSearchIndex() - Search an index. + * help_add_word() - Add a word to a node. * help_compile_search() - Convert a search string into a regular expression. * help_delete_node() - Free all memory used by a node. + * help_delete_word() - Free all memory used by a word. * help_load_directory() - Load a directory of files into an index. * help_load_file() - Load a HTML files into an index. * help_new_node() - Create a new node and add it to an index. * help_sort_nodes_by_name() - Sort nodes by section, filename, and anchor. * help_sort_nodes_by_score() - Sort nodes by score and text. + * help_sort_words() - Sort words alphabetically. */ /* @@ -45,11 +48,118 @@ #include +/* + * List of common English words that should not be indexed... + */ + +static char help_common_words[][6] = + { + "about", + "all", + "an", + "and", + "are", + "as", + "at", + "be", + "been", + "but", + "by", + "call", + "can", + "come", + "could", + "day", + "did", + "do", + "down", + "each", + "find", + "first", + "for", + "from", + "go", + "had", + "has", + "have", + "he", + "her", + "him", + "his", + "hot", + "how", + "if", + "in", + "is", + "it", + "know", + "like", + "long", + "look", + "make", + "many", + "may", + "more", + "most", + "my", + "no", + "now", + "of", + "on", + "one", + "or", + "other", + "out", + "over", + "said", + "see", + "she", + "side", + "so", + "some", + "sound", + "than", + "that", + "the", + "their", + "them", + "then", + "there", + "these", + "they", + "thing", + "this", + "time", + "to", + "two", + "up", + "use", + "was", + "water", + "way", + "we", + "were", + "what", + "when", + "which", + "who", + "will", + "with", + "word", + "would", + "write", + "you", + "your" + }; + + /* * Local functions... */ +static help_word_t *help_add_word(help_node_t *n, const char *text); static void help_delete_node(help_node_t *n); +static void help_delete_word(help_word_t *w); static int help_load_directory(help_index_t *hi, const char *directory, const char *relative); @@ -63,6 +173,7 @@ static help_node_t *help_new_node(const char *filename, const char *anchor, size_t length); static int help_sort_by_name(help_node_t *p1, help_node_t *p2); static int help_sort_by_score(help_node_t *p1, help_node_t *p2); +static int help_sort_words(help_word_t *w1, help_word_t *w2); /* @@ -84,9 +195,6 @@ helpDeleteIndex(help_index_t *hi) /* I - Help index */ node; node = (help_node_t *)cupsArrayNext(hi->nodes)) { - cupsArrayRemove(hi->nodes, node); - cupsArrayRemove(hi->sorted, node); - if (!hi->search) help_delete_node(node); } @@ -157,6 +265,7 @@ helpLoadIndex(const char *hifile, /* I - Index filename */ size_t length; /* Length in bytes */ int update; /* Update? */ help_node_t *node; /* Current node */ + help_word_t *word; /* Current word */ DEBUG_printf(("helpLoadIndex(hifile=\"%s\", directory=\"%s\")\n", @@ -192,12 +301,14 @@ helpLoadIndex(const char *hifile, /* I - Index filename */ cupsFileLock(fp, 1); - if (cupsFileGets(fp, line, sizeof(line)) && !strcmp(line, "HELPV1")) + if (cupsFileGets(fp, line, sizeof(line)) && !strcmp(line, "HELPV2")) { /* * Got a valid header line, now read the data lines... */ + node = NULL; + while (cupsFileGets(fp, line, sizeof(line))) { /* @@ -205,77 +316,97 @@ helpLoadIndex(const char *hifile, /* I - Index filename */ * * filename mtime offset length "section" "text" * filename#anchor offset length "text" + * SP count word */ - filename = line; - - if ((ptr = strchr(line, ' ')) == NULL) - break; - - while (isspace(*ptr & 255)) - *ptr++ = '\0'; - - if ((anchor = strrchr(filename, '#')) != NULL) + if (line[0] == ' ') { - *anchor++ = '\0'; - mtime = 0; - } - else - mtime = strtol(ptr, &ptr, 10); - - offset = strtoll(ptr, &ptr, 10); - length = strtoll(ptr, &ptr, 10); + /* + * Read a word in the current node... + */ - while (isspace(*ptr & 255)) - ptr ++; + if (!node || (ptr = strrchr(line, ' ')) == NULL) + continue; - if (!anchor) + if ((word = help_add_word(node, ptr + 1)) != NULL) + word->count = atoi(line + 1); + } + else { /* - * Get section... + * Add a node... */ - if (*ptr != '\"') - break; + filename = line; - ptr ++; - sectptr = ptr; + if ((ptr = strchr(line, ' ')) == NULL) + break; - while (*ptr && *ptr != '\"') - ptr ++; - - if (*ptr != '\"') - break; + while (isspace(*ptr & 255)) + *ptr++ = '\0'; - *ptr++ = '\0'; + if ((anchor = strrchr(filename, '#')) != NULL) + { + *anchor++ = '\0'; + mtime = 0; + } + else + mtime = strtol(ptr, &ptr, 10); - strlcpy(section, sectptr, sizeof(section)); + offset = strtoll(ptr, &ptr, 10); + length = strtoll(ptr, &ptr, 10); while (isspace(*ptr & 255)) ptr ++; - } - if (*ptr != '\"') - break; + if (!anchor) + { + /* + * Get section... + */ - ptr ++; - text = ptr; + if (*ptr != '\"') + break; - while (*ptr && *ptr != '\"') - ptr ++; + ptr ++; + sectptr = ptr; - if (*ptr != '\"') - break; + while (*ptr && *ptr != '\"') + ptr ++; + + if (*ptr != '\"') + break; - *ptr++ = '\0'; + *ptr++ = '\0'; - if ((node = help_new_node(filename, anchor, section, text, - mtime, offset, length)) == NULL) - break; + strlcpy(section, sectptr, sizeof(section)); - node->score = -1; + while (isspace(*ptr & 255)) + ptr ++; + } - cupsArrayAdd(hi->nodes, node); + if (*ptr != '\"') + break; + + ptr ++; + text = ptr; + + while (*ptr && *ptr != '\"') + ptr ++; + + if (*ptr != '\"') + break; + + *ptr++ = '\0'; + + if ((node = help_new_node(filename, anchor, section, text, + mtime, offset, length)) == NULL) + break; + + node->score = -1; + + cupsArrayAdd(hi->nodes, node); + } } } @@ -339,6 +470,7 @@ helpSaveIndex(help_index_t *hi, /* I - Index */ { cups_file_t *fp; /* Index file */ help_node_t *node; /* Current node */ + help_word_t *word; /* Current word */ DEBUG_printf(("helpSaveIndex(hi=%p, hifile=\"%s\")\n", hi, hifile)); @@ -356,7 +488,7 @@ helpSaveIndex(help_index_t *hi, /* I - Index */ cupsFileLock(fp, 1); - cupsFilePuts(fp, "HELPV1\n"); + cupsFilePuts(fp, "HELPV2\n"); for (node = (help_node_t *)cupsArrayFirst(hi->nodes); node; @@ -382,6 +514,16 @@ helpSaveIndex(help_index_t *hi, /* I - Index */ node->section ? node->section : "", node->text) < 0) break; } + + /* + * Then write the words associated with the node... + */ + + for (word = (help_word_t *)cupsArrayFirst(node->words); + word; + word = (help_word_t *)cupsArrayNext(node->words)) + if (cupsFilePrintf(fp, " %d %s\n", word->count, word->text) < 0) + break; } cupsFileFlush(fp); @@ -407,6 +549,7 @@ helpSearchIndex(help_index_t *hi, /* I - Index */ { help_index_t *search; /* Search index */ help_node_t *node; /* Current node */ + help_word_t *word; /* Current word */ void *sc; /* Search context */ int matches; /* Number of matches */ @@ -487,16 +630,27 @@ helpSearchIndex(help_index_t *hi, /* I - Index */ continue; else if (filename && strcmp(node->filename, filename)) continue; - else if ((matches = cgiDoSearch(sc, node->text)) > 0) + else { - /* - * Found a match, add the node to the search index... - */ + matches = cgiDoSearch(sc, node->text); + + for (word = (help_word_t *)cupsArrayFirst(node->words); + word; + word = (help_word_t *)cupsArrayNext(node->words)) + if (cgiDoSearch(sc, word->text) > 0) + matches += word->count; - node->score = matches; + if (matches > 0) + { + /* + * Found a match, add the node to the search index... + */ - cupsArrayAdd(search->nodes, node); - cupsArrayAdd(search->sorted, node); + node->score = matches; + + cupsArrayAdd(search->nodes, node); + cupsArrayAdd(search->sorted, node); + } } /* @@ -513,6 +667,61 @@ helpSearchIndex(help_index_t *hi, /* I - Index */ } +/* + * 'help_add_word()' - Add a word to a node. + */ + +static help_word_t * /* O - New word */ +help_add_word(help_node_t *n, /* I - Node */ + const char *text) /* I - Word text */ +{ + help_word_t *w, /* New word */ + key; /* Search key */ + + + DEBUG_printf(("help_add_word(n=%p, text=\"%s\")\n", n, text)); + + /* + * Create the words array as needed... + */ + + if (!n->words) + n->words = cupsArrayNew((cups_array_func_t)help_sort_words, NULL); + + /* + * See if the word is already added... + */ + + key.text = (char *)text; + + if ((w = (help_word_t *)cupsArrayFind(n->words, &key)) == NULL) + { + /* + * Create a new word... + */ + + if ((w = calloc(1, sizeof(help_word_t))) == NULL) + return (NULL); + + if ((w->text = strdup(text)) == NULL) + { + free(w); + return (NULL); + } + + cupsArrayAdd(n->words, w); + } + + /* + * Bump the counter for this word and return it... + */ + + w->count ++; + + return (w); +} + + /* * 'help_delete_node()' - Free all memory used by a node. */ @@ -520,6 +729,9 @@ helpSearchIndex(help_index_t *hi, /* I - Index */ static void help_delete_node(help_node_t *n) /* I - Node */ { + help_word_t *w; /* Current word */ + + DEBUG_printf(("help_delete_node(n=%p)\n", n)); if (!n) @@ -537,10 +749,36 @@ help_delete_node(help_node_t *n) /* I - Node */ if (n->text) free(n->text); + for (w = (help_word_t *)cupsArrayFirst(n->words); + w; + w = (help_word_t *)cupsArrayNext(n->words)) + help_delete_word(w); + + cupsArrayDelete(n->words); + free(n); } +/* + * 'help_delete_word()' - Free all memory used by a word. + */ + +static void +help_delete_word(help_word_t *w) /* I - Word */ +{ + DEBUG_printf(("help_delete_word(w=%p)\n", w)); + + if (!w) + return; + + if (w->text) + free(w->text); + + free(w); +} + + /* * 'help_load_directory()' - Load a directory of files into an index. */ @@ -667,6 +905,8 @@ help_load_file( *text; /* Text for anchor */ off_t offset; /* File offset */ char quote; /* Quote character */ + help_word_t *word; /* Current word */ + int wordlen; /* Length of word */ DEBUG_printf(("help_load_file(hi=%p, filename=\"%s\", relative=\"%s\", mtime=%ld)\n", @@ -818,6 +1058,17 @@ help_load_file( if (node->text) free(node->text); + if (node->words) + { + for (word = (help_word_t *)cupsArrayFirst(node->words); + word; + word = (help_word_t *)cupsArrayNext(node->words)) + help_delete_word(word); + + cupsArrayDelete(node->words); + node->words = NULL; + } + node->section = section[0] ? strdup(section) : NULL; node->text = strdup(text); node->mtime = mtime; @@ -861,9 +1112,97 @@ help_load_file( */ cupsArrayAdd(hi->nodes, node); + + if (!anchor) + node = NULL; break; } + if (node) + { + /* + * Scan this line for words... + */ + + for (ptr = line; *ptr; ptr ++) + { + /* + * Skip HTML stuff... + */ + + if (*ptr == '<') + { + if (!strncmp(ptr, "")) == NULL) + ptr += strlen(ptr) - 1; + else + ptr = text + 2; + } + else + { + /* + * Skip HTML element... + */ + + for (ptr ++; *ptr && *ptr != '>'; ptr ++) + if (*ptr == '\"' || *ptr == '\'') + { + for (quote = *ptr++; *ptr && *ptr != quote; ptr ++); + + if (!*ptr) + ptr --; + } + + if (!*ptr) + ptr --; + } + + continue; + } + else if (*ptr == '&') + { + /* + * Skip HTML entity... + */ + + for (ptr ++; *ptr && *ptr != ';'; ptr ++); + + if (!*ptr) + ptr --; + + continue; + } + else if (!isalnum(*ptr & 255)) + continue; + + /* + * Found the start of a word, search until we find the end... + */ + + for (text = ptr, ptr ++; *ptr && isalnum(*ptr & 255); ptr ++); + + wordlen = ptr - text; + + if (*ptr) + *ptr = '\0'; + else + ptr --; + + if (wordlen > 1 && !bsearch(text, help_common_words, + (sizeof(help_common_words) / + sizeof(help_common_words[0])), + sizeof(help_common_words[0]), + (int (*)(const void *, const void *)) + strcasecmp)) + help_add_word(node, text); + } + } + /* * Get the offset of the next line... */ @@ -979,5 +1318,20 @@ help_sort_by_score(help_node_t *n1, /* I - First node */ /* - * End of "$Id: help-index.c 5665 2006-06-16 00:59:10Z mike $". + * 'help_sort_words()' - Sort words alphabetically. + */ + +static int /* O - Difference */ +help_sort_words(help_word_t *w1, /* I - Second word */ + help_word_t *w2) /* I - Second word */ +{ + DEBUG_printf(("help_sort_words(w1=%p(\"%s\"), w2=%p(\"%s\"))\n", + w1, w1->text, w2, w2->text)); + + return (strcasecmp(w1->text, w2->text)); +} + + +/* + * End of "$Id: help-index.c 6258 2007-02-11 01:16:31Z mike $". */ diff --git a/cgi-bin/help-index.h b/cgi-bin/help-index.h index d564663a0..c7cbe2b54 100644 --- a/cgi-bin/help-index.h +++ b/cgi-bin/help-index.h @@ -1,9 +1,9 @@ /* - * "$Id: help-index.h 5143 2006-02-21 19:13:01Z mike $" + * "$Id: help-index.h 6257 2007-02-11 01:11:57Z mike $" * * On-line help index definitions for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -36,19 +36,26 @@ * Data structures... */ -typedef struct /**** Help node structure... ****/ +typedef struct help_word_s /**** Help word structure... ****/ +{ + int count; /* Number of occurrences */ + char *text; /* Word text */ +} help_word_t; + +typedef struct help_node_s /**** Help node structure... ****/ { char *filename; /* Filename, relative to help dir */ char *section; /* Section name (NULL if none) */ char *anchor; /* Anchor name (NULL if none) */ char *text; /* Text in anchor */ + cups_array_t *words; /* Words after this node */ time_t mtime; /* Last modification time */ off_t offset; /* Offset in file */ size_t length; /* Length in bytes */ int score; /* Search score */ } help_node_t; -typedef struct /**** Help index structure ****/ +typedef struct help_index_s /**** Help index structure ****/ { int search; /* 1 = search index, 0 = normal */ cups_array_t *nodes; /* Nodes sorted by filename */ @@ -73,5 +80,5 @@ extern help_index_t *helpSearchIndex(help_index_t *hi, const char *query, #endif /* !_CUPS_HELP_INDEX_H_ */ /* - * End of "$Id: help-index.h 5143 2006-02-21 19:13:01Z mike $". + * End of "$Id: help-index.h 6257 2007-02-11 01:11:57Z mike $". */ diff --git a/cgi-bin/html.c b/cgi-bin/html.c index da5f7cd20..62e0cc517 100644 --- a/cgi-bin/html.c +++ b/cgi-bin/html.c @@ -1,5 +1,5 @@ /* - * "$Id: html.c 5549 2006-05-19 19:39:28Z mike $" + * "$Id: html.c 5548 2006-05-19 19:38:31Z mike $" * * HTML support functions for the Common UNIX Printing System (CUPS). * @@ -183,5 +183,5 @@ cgi_null_passwd(const char *prompt) /* I - Prompt string (unused) */ /* - * End of "$Id: html.c 5549 2006-05-19 19:39:28Z mike $". + * End of "$Id: html.c 5548 2006-05-19 19:38:31Z mike $". */ diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c index 4639643de..f9dc54ca7 100644 --- a/cgi-bin/ipp-var.c +++ b/cgi-bin/ipp-var.c @@ -1,9 +1,9 @@ /* - * "$Id: ipp-var.c 6244 2007-02-06 21:08:59Z mike $" + * "$Id: ipp-var.c 6304 2007-02-22 22:06:23Z mike $" * * CGI <-> IPP variable routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -828,6 +828,144 @@ cgiSetIPPObjectVars( cgiSetArray("job_printer_name", element, valptr); } + /* + * Localize event names in "notify_events" variable... + */ + + if (!strcmp(name, "notify_events")) + { + size_t remaining; /* Remaining bytes in buffer */ + + + value[0] = '\0'; + valptr = value; + + for (i = 0; i < attr->num_values; i ++) + { + if (valptr >= (value + sizeof(value) - 3)) + break; + + if (i) + { + *valptr++ = ','; + *valptr++ = ' '; + } + + remaining = sizeof(value) - (valptr - value); + + if (!strcmp(attr->values[i].string.text, "printer-stopped")) + strlcpy(valptr, _("Printer Stopped"), remaining); + else if (!strcmp(attr->values[i].string.text, "printer-added")) + strlcpy(valptr, _("Printer Added"), remaining); + else if (!strcmp(attr->values[i].string.text, "printer-modified")) + strlcpy(valptr, _("Printer Modified"), remaining); + else if (!strcmp(attr->values[i].string.text, "printer-deleted")) + strlcpy(valptr, _("Printer Deleted"), remaining); + else if (!strcmp(attr->values[i].string.text, "job-created")) + strlcpy(valptr, _("Job Created"), remaining); + else if (!strcmp(attr->values[i].string.text, "job-completed")) + strlcpy(valptr, _("Job Completed"), remaining); + else if (!strcmp(attr->values[i].string.text, "job-stopped")) + strlcpy(valptr, _("Job Stopped"), remaining); + else if (!strcmp(attr->values[i].string.text, "job-config-changed")) + strlcpy(valptr, _("Job Options Changed"), remaining); + else if (!strcmp(attr->values[i].string.text, "server-restarted")) + strlcpy(valptr, _("Server Restarted"), remaining); + else if (!strcmp(attr->values[i].string.text, "server-started")) + strlcpy(valptr, _("Server Started"), remaining); + else if (!strcmp(attr->values[i].string.text, "server-stopped")) + strlcpy(valptr, _("Server Stopped"), remaining); + else if (!strcmp(attr->values[i].string.text, "server-audit")) + strlcpy(valptr, _("Server Security Auditing"), remaining); + else + strlcpy(valptr, attr->values[i].string.text, remaining); + + valptr += strlen(valptr); + } + + cgiSetArray("notify_events", element, value); + continue; + } + + /* + * Add "notify_printer_name" variable if we have a "notify_printer_uri" + * attribute... + */ + + if (!strcmp(name, "notify_printer_uri")) + { + if ((valptr = strrchr(attr->values[0].string.text, '/')) == NULL) + valptr = "unknown"; + else + valptr ++; + + cgiSetArray("notify_printer_name", element, valptr); + } + + /* + * Add "notify_recipient_name" variable if we have a "notify_recipient_uri" + * attribute, and rewrite recipient URI... + */ + + if (!strcmp(name, "notify_recipient_uri")) + { + char uri[1024], /* New URI */ + scheme[32], /* Scheme portion of URI */ + userpass[256], /* Username/password portion of URI */ + host[1024], /* Hostname portion of URI */ + resource[1024], /* Resource portion of URI */ + *options; /* Options in URI */ + int port; /* Port number */ + + + httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, + scheme, sizeof(scheme), userpass, sizeof(userpass), + host, sizeof(host), &port, resource, sizeof(resource)); + + if (!strcmp(scheme, "rss")) + { + /* + * RSS notification... + */ + + if ((options = strchr(resource, '?')) != NULL) + *options = '\0'; + + if (host[0]) + { + /* + * Link to remote feed... + */ + + httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "http", + userpass, host, port, resource); + strlcpy(name, uri, sizeof(name)); + } + else + { + /* + * Link to local feed... + */ + + snprintf(uri, sizeof(uri), "/rss%s", resource); + strlcpy(name, resource + 1, sizeof(name)); + } + } + else + { + /* + * Other... + */ + + strlcpy(uri, attr->values[0].string.text, sizeof(uri)); + strlcpy(name, resource, sizeof(name)); + } + + cgiSetArray("notify_recipient_uri", element, uri); + cgiSetArray("notify_recipient_name", element, name); + continue; + } + /* * Add "admin_uri" variable if we have a "printer_uri_supported" * attribute... @@ -1280,5 +1418,5 @@ cgiText(const char *message) /* I - Message */ /* - * End of "$Id: ipp-var.c 6244 2007-02-06 21:08:59Z mike $". + * End of "$Id: ipp-var.c 6304 2007-02-22 22:06:23Z mike $". */ diff --git a/cgi-bin/jobs.c b/cgi-bin/jobs.c index ed379b001..f86aa9bb9 100644 --- a/cgi-bin/jobs.c +++ b/cgi-bin/jobs.c @@ -1,5 +1,5 @@ /* - * "$Id: jobs.c 5104 2006-02-15 03:21:04Z mike $" + * "$Id: jobs.c 6277 2007-02-14 16:07:28Z mike $" * * Job status CGI for the Common UNIX Printing System (CUPS). * @@ -181,6 +181,20 @@ do_job_op(http_t *http, /* I - HTTP connection */ ippDelete(cupsDoRequest(http, request, "/jobs")); + if (cupsLastError() <= IPP_OK_CONFLICT && getenv("HTTP_REFERER")) + { + /* + * Redirect successful updates back to the parent page... + */ + + char url[1024]; /* Encoded URL */ + + + strcpy(url, "5;URL="); + cgiFormEncode(url + 6, getenv("HTTP_REFERER"), sizeof(url) - 6); + cgiSetVariable("refresh_page", url); + } + cgiStartHTML(cgiText(_("Jobs"))); if (cupsLastError() > IPP_OK_CONFLICT) @@ -199,5 +213,5 @@ do_job_op(http_t *http, /* I - HTTP connection */ /* - * End of "$Id: jobs.c 5104 2006-02-15 03:21:04Z mike $". + * End of "$Id: jobs.c 6277 2007-02-14 16:07:28Z mike $". */ diff --git a/cgi-bin/printers.c b/cgi-bin/printers.c index e8ec0d2b3..50dc2b322 100644 --- a/cgi-bin/printers.c +++ b/cgi-bin/printers.c @@ -1,5 +1,5 @@ /* - * "$Id: printers.c 5572 2006-05-22 18:47:09Z mike $" + * "$Id: printers.c 5571 2006-05-22 18:46:55Z mike $" * * Printer status CGI for the Common UNIX Printing System (CUPS). * @@ -638,5 +638,5 @@ show_printer(http_t *http, /* I - Connection to server */ /* - * End of "$Id: printers.c 5572 2006-05-22 18:47:09Z mike $". + * End of "$Id: printers.c 5571 2006-05-22 18:46:55Z mike $". */ diff --git a/cgi-bin/search.c b/cgi-bin/search.c index 205a40cff..25a410f7d 100644 --- a/cgi-bin/search.c +++ b/cgi-bin/search.c @@ -1,5 +1,5 @@ /* - * "$Id: search.c 5963 2006-09-17 19:01:47Z mike $" + * "$Id: search.c 5962 2006-09-17 19:01:26Z mike $" * * Search routines for the Common UNIX Printing System (CUPS). * @@ -366,5 +366,5 @@ cgiFreeSearch(void *search) /* I - Search context */ /* - * End of "$Id: search.c 5963 2006-09-17 19:01:47Z mike $". + * End of "$Id: search.c 5962 2006-09-17 19:01:26Z mike $". */ diff --git a/cgi-bin/template.c b/cgi-bin/template.c index 82cf0e45d..d2fd9b8e3 100644 --- a/cgi-bin/template.c +++ b/cgi-bin/template.c @@ -1,5 +1,5 @@ /* - * "$Id: template.c 5549 2006-05-19 19:39:28Z mike $" + * "$Id: template.c 5548 2006-05-19 19:38:31Z mike $" * * CGI template function. * @@ -670,5 +670,5 @@ cgi_puturi(const char *s, /* I - String to output */ /* - * End of "$Id: template.c 5549 2006-05-19 19:39:28Z mike $". + * End of "$Id: template.c 5548 2006-05-19 19:38:31Z mike $". */ diff --git a/cgi-bin/testhi.c b/cgi-bin/testhi.c index dad5d70b7..1d6e23f04 100644 --- a/cgi-bin/testhi.c +++ b/cgi-bin/testhi.c @@ -1,9 +1,9 @@ /* - * "$Id: testhi.c 5143 2006-02-21 19:13:01Z mike $" + * "$Id: testhi.c 6257 2007-02-11 01:11:57Z mike $" * * Help index test program for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2005 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -105,14 +105,18 @@ list_nodes(const char *title, /* I - Title string */ for (i = 1, node = (help_node_t *)cupsArrayFirst(nodes); node; i ++, node = (help_node_t *)cupsArrayNext(nodes)) + { if (node->anchor) - printf(" %d: %s#%s \"%s\"\n", i, node->filename, node->anchor, + printf(" %d: %s#%s \"%s\"", i, node->filename, node->anchor, node->text); else - printf(" %d: %s \"%s\"\n", i, node->filename, node->text); + printf(" %d: %s \"%s\"", i, node->filename, node->text); + + printf(" (%d words)\n", cupsArrayCount(node->words)); + } } /* - * End of "$Id: testhi.c 5143 2006-02-21 19:13:01Z mike $". + * End of "$Id: testhi.c 6257 2007-02-11 01:11:57Z mike $". */ diff --git a/cgi-bin/testhi.html b/cgi-bin/testhi.html index 747b5ea31..b45399fdb 100644 --- a/cgi-bin/testhi.html +++ b/cgi-bin/testhi.html @@ -19,6 +19,8 @@ up to 1024 bytes in length.

This is some text for the first anchor.

+

John asked Mary to the dance.

+

This is the Third Anchor

diff --git a/cgi-bin/var.c b/cgi-bin/var.c index 17d507756..113b8d026 100644 --- a/cgi-bin/var.c +++ b/cgi-bin/var.c @@ -1,5 +1,5 @@ /* - * "$Id: var.c 5549 2006-05-19 19:39:28Z mike $" + * "$Id: var.c 5548 2006-05-19 19:38:31Z mike $" * * CGI form variable and array functions. * @@ -1027,5 +1027,5 @@ cgi_unlink_file(void) /* - * End of "$Id: var.c 5549 2006-05-19 19:39:28Z mike $". + * End of "$Id: var.c 5548 2006-05-19 19:38:31Z mike $". */ diff --git a/conf/cupsd.conf.in b/conf/cupsd.conf.in index 21f43b2cc..ee0b28fb4 100644 --- a/conf/cupsd.conf.in +++ b/conf/cupsd.conf.in @@ -1,5 +1,5 @@ # -# "$Id: cupsd.conf.in 5454 2006-04-23 21:46:38Z mike $" +# "$Id: cupsd.conf.in 6268 2007-02-12 02:46:11Z mike $" # # Sample configuration file for the Common UNIX Printing System (CUPS) # scheduler. See "man cupsd.conf" for a complete description of this @@ -12,6 +12,7 @@ LogLevel info # Administrator user group... SystemGroup @CUPS_SYSTEM_GROUPS@ +@CUPS_SYSTEM_AUTHKEY@ # Only listen for connections from the local machine. Listen localhost:@DEFAULT_IPP_PORT@ @@ -20,7 +21,7 @@ Listen localhost:@DEFAULT_IPP_PORT@ # Show shared printers on the local network. Browsing On BrowseOrder allow,deny -BrowseAllow @LOCAL +BrowseAllow all # Default authentication type, when authentication is required... DefaultAuthType Basic @@ -73,5 +74,5 @@ DefaultAuthType Basic # -# End of "$Id: cupsd.conf.in 5454 2006-04-23 21:46:38Z mike $". +# End of "$Id: cupsd.conf.in 6268 2007-02-12 02:46:11Z mike $". # diff --git a/conf/mime.types b/conf/mime.types index e5a522df5..c36dbb95d 100644 --- a/conf/mime.types +++ b/conf/mime.types @@ -1,5 +1,5 @@ # -# "$Id: mime.types 6003 2006-10-02 16:26:04Z mike $" +# "$Id: mime.types 6301 2007-02-22 13:45:17Z mike $" # # MIME types file for the Common UNIX Printing System (CUPS). # @@ -140,6 +140,15 @@ text/html html htm printable(0,1024) +\ text/plain txt printable(0,1024) text/css css + +######################################################################## +# +# RSS feed type... +# + +application/rss+xml rss + + ######################################################################## # # CUPS-specific types... @@ -167,5 +176,5 @@ application/vnd.cups-raw (string(0,<1B>E) + !string(2,<1B>%0B)) \ application/octet-stream # -# End of "$Id: mime.types 6003 2006-10-02 16:26:04Z mike $". +# End of "$Id: mime.types 6301 2007-02-22 13:45:17Z mike $". # diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4 index 8610523ba..03a348031 100644 --- a/config-scripts/cups-common.m4 +++ b/config-scripts/cups-common.m4 @@ -1,9 +1,9 @@ dnl -dnl "$Id: cups-common.m4 6145 2006-12-06 20:10:16Z mike $" +dnl "$Id: cups-common.m4 6304 2007-02-22 22:06:23Z mike $" dnl dnl Common configuration stuff for the Common UNIX Printing System (CUPS). dnl -dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. +dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. dnl dnl These coded instructions, statements, and computer programs are the dnl property of Easy Software Products and are protected by Federal @@ -28,9 +28,12 @@ AC_PREREQ(2.50) dnl Set the name of the config header file... AC_CONFIG_HEADER(config.h) -dnl Version number information... -CUPS_VERSION="1.2.8" +dnl Versio number information... +CUPS_VERSION="1.3svn" CUPS_REVISION="" +if test -z "$CUPS_REVISION" -a -d .svn; then + CUPS_REVISION="-r`svnversion . | awk -F: '{print $NF}' | sed -e '1,$s/[[a-zA-Z]]*//g'`" +fi AC_SUBST(CUPS_VERSION) AC_SUBST(CUPS_REVISION) @@ -189,6 +192,7 @@ dnl Extra platform-specific libraries... BACKLIBS="" CUPSDLIBS="" DBUSDIR="" +CUPS_SYSTEM_AUTHKEY="" AC_ARG_ENABLE(dbus, [ --enable-dbus enable DBUS support, default=auto]) @@ -219,6 +223,12 @@ case $uname in dnl Check for notify_post support AC_CHECK_HEADER(notify.h,AC_DEFINE(HAVE_NOTIFY_H)) AC_CHECK_FUNCS(notify_post) + + dnl Check for Authorization Services support + AC_CHECK_HEADER(Security/Authorization.h, [ + AC_DEFINE(HAVE_AUTHORIZATION_H) + CUPS_SYSTEM_AUTHKEY="SystemGroupAuthKey system.preferences"]) + AC_CHECK_HEADER(Security/SecBasePriv.h,AC_DEFINE(HAVE_SECBASEPRIV_H)) ;; Linux*) @@ -232,7 +242,8 @@ case $uname in AC_DEFINE(HAVE_DBUS) CFLAGS="$CFLAGS `$PKGCONFIG --cflags dbus-1` -DDBUS_API_SUBJECT_TO_CHANGE" CUPSDLIBS="`$PKGCONFIG --libs dbus-1`" - DBUSDIR="/etc/dbus-1/system.d" + AC_ARG_WITH(dbusdir, [ --with-dbusdir set DBUS configuration directory ], dbusdir="$withval", dbusdir="/etc/dbus-1") + DBUSDIR="$dbusdir" AC_CHECK_LIB(dbus-1, dbus_message_iter_init_append, AC_DEFINE(HAVE_DBUS_MESSAGE_ITER_INIT_APPEND)) @@ -244,6 +255,8 @@ case $uname in ;; esac +AC_SUBST(CUPS_SYSTEM_AUTHKEY) + dnl See if we have POSIX ACL support... SAVELIBS="$LIBS" LIBS="" @@ -264,5 +277,5 @@ AC_SUBST(DEFAULT_IPP_PORT) AC_DEFINE_UNQUOTED(CUPS_DEFAULT_IPP_PORT,$DEFAULT_IPP_PORT) dnl -dnl End of "$Id: cups-common.m4 6145 2006-12-06 20:10:16Z mike $". +dnl End of "$Id: cups-common.m4 6304 2007-02-22 22:06:23Z mike $". dnl diff --git a/config-scripts/cups-compiler.m4 b/config-scripts/cups-compiler.m4 index 9a15cb535..1af623a16 100644 --- a/config-scripts/cups-compiler.m4 +++ b/config-scripts/cups-compiler.m4 @@ -1,9 +1,9 @@ dnl -dnl "$Id: cups-compiler.m4 6145 2006-12-06 20:10:16Z mike $" +dnl "$Id: cups-compiler.m4 6264 2007-02-11 17:11:15Z mike $" dnl dnl Compiler stuff for the Common UNIX Printing System (CUPS). dnl -dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. +dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. dnl dnl These coded instructions, statements, and computer programs are the dnl property of Easy Software Products and are protected by Federal @@ -56,9 +56,12 @@ AC_ARG_WITH(arch64flags, [ --with-arch64flags="flags" ARCH64FLAGS="" AC_SUBST(ARCH64FLAGS) -dnl Position-Independent Executable support on Linux and *BSD... +dnl Position-Independent Executable support on Linux... AC_ARG_ENABLE(pie, [ --enable-pie use GCC -fPIE option, default=no]) +dnl Read-only data/program support on Linux... +AC_ARG_ENABLE(relro, [ --enable-relro use GCC relro option, default=no]) + dnl Update compiler options... CXXLIBS="" AC_SUBST(CXXLIBS) @@ -66,6 +69,9 @@ AC_SUBST(CXXLIBS) PIEFLAGS="" AC_SUBST(PIEFLAGS) +RELROFLAGS="" +AC_SUBST(RELROFLAGS) + if test -n "$GCC"; then # Add GCC-specific compiler options... if test -z "$OPTIM"; then @@ -86,6 +92,10 @@ if test -n "$GCC"; then if test x$enable_pie = xyes; then PIEFLAGS="-pie -fPIE" fi + + if test x$enable_relro = xyes; then + RELROFLAGS="-Wl,-z,relro" + fi ;; *) @@ -435,5 +445,5 @@ case $uname in esac dnl -dnl End of "$Id: cups-compiler.m4 6145 2006-12-06 20:10:16Z mike $". +dnl End of "$Id: cups-compiler.m4 6264 2007-02-11 17:11:15Z mike $". dnl diff --git a/config-scripts/cups-defaults.m4 b/config-scripts/cups-defaults.m4 index 48b3aea5f..393204563 100644 --- a/config-scripts/cups-defaults.m4 +++ b/config-scripts/cups-defaults.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-defaults.m4 6234 2007-02-05 20:25:50Z mike $" +dnl "$Id: cups-defaults.m4 6309 2007-02-24 03:11:56Z mike $" dnl dnl Default cupsd configuration settings for the Common UNIX Printing System dnl (CUPS). @@ -62,16 +62,46 @@ AC_SUBST(CUPS_BROWSING) dnl Default BrowseLocalProtocols AC_ARG_WITH(local_protocols, [ --with-local-protocols set default BrowseLocalProtocols, default="CUPS"], - CUPS_BROWSE_LOCAL_PROTOCOLS="$withval", - CUPS_BROWSE_LOCAL_PROTOCOLS="CUPS") + default_local_protocols="$withval", + default_local_protocols="default") + +if test x$with_local_protocols != xno; then + if test "x$default_local_protocols" = "xdefault"; then + if test "x$DNSSDLIBS" != "x"; then + CUPS_BROWSE_LOCAL_PROTOCOLS="CUPS dnssd" + else + CUPS_BROWSE_LOCAL_PROTOCOLS="CUPS" + fi + else + CUPS_BROWSE_LOCAL_PROTOCOLS="$default_local_protocols" + fi +else + CUPS_BROWSE_LOCAL_PROTOCOLS="" +fi + AC_SUBST(CUPS_BROWSE_LOCAL_PROTOCOLS) AC_DEFINE_UNQUOTED(CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS, "$CUPS_BROWSE_LOCAL_PROTOCOLS") dnl Default BrowseRemoteProtocols AC_ARG_WITH(remote_protocols, [ --with-remote-protocols set default BrowseRemoteProtocols, default="CUPS"], - CUPS_BROWSE_REMOTE_PROTOCOLS="$withval", - CUPS_BROWSE_REMOTE_PROTOCOLS="CUPS") + default_remote_protocols="$withval", + default_remote_protocols="default") + +if test x$with_remote_protocols != xno; then + if test "x$default_remote_protocols" = "xdefault"; then + if test "$uname" = "Darwin" -a $uversion -ge 90; then + CUPS_BROWSE_REMOTE_PROTOCOLS="" + else + CUPS_BROWSE_REMOTE_PROTOCOLS="CUPS" + fi + else + CUPS_BROWSE_REMOTE_PROTOCOLS="$default_remote_protocols" + fi +else + CUPS_BROWSE_REMOTE_PROTOCOLS="" +fi + AC_SUBST(CUPS_BROWSE_REMOTE_PROTOCOLS) AC_DEFINE_UNQUOTED(CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS, "$CUPS_BROWSE_REMOTE_PROTOCOLS") @@ -251,6 +281,18 @@ fi AC_DEFINE_UNQUOTED(CUPS_DEFAULT_PRINTCAP, "$CUPS_DEFAULT_PRINTCAP") +dnl Default MaxCopies value... +AC_ARG_WITH(max-copies, [ --with-max-copies set max copies value, default=100 ], + CUPS_MAX_COPIES="$withval", + if test "x$uname" = xDarwin; then + CUPS_MAX_COPIES="999" + else + CUPS_MAX_COPIES="100" + fi) + +AC_SUBST(CUPS_MAX_COPIES) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_MAX_COPIES, $CUPS_MAX_COPIES) + dnl -dnl End of "$Id: cups-defaults.m4 6234 2007-02-05 20:25:50Z mike $". +dnl End of "$Id: cups-defaults.m4 6309 2007-02-24 03:11:56Z mike $". dnl diff --git a/config-scripts/cups-directories.m4 b/config-scripts/cups-directories.m4 index 595512b43..09f3d9697 100644 --- a/config-scripts/cups-directories.m4 +++ b/config-scripts/cups-directories.m4 @@ -1,9 +1,9 @@ dnl -dnl "$Id: cups-directories.m4 5905 2006-08-29 20:48:59Z mike $" +dnl "$Id: cups-directories.m4 6332 2007-03-12 16:08:51Z mike $" dnl dnl Directory stuff for the Common UNIX Printing System (CUPS). dnl -dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. +dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. dnl dnl These coded instructions, statements, and computer programs are the dnl property of Easy Software Products and are protected by Federal @@ -123,24 +123,24 @@ fi dnl Setup init.d locations... AC_ARG_WITH(rcdir, [ --with-rcdir set path for rc scripts],rcdir="$withval",rcdir="") +AC_ARG_WITH(rclevels, [ --with-rclevels set run levels for rc scripts],rclevels="$withval",rclevels="2 3 5") +AC_ARG_WITH(rcstart, [ --with-rcstart set start number for rc scripts],rcstart="$withval",rcstart="99") +AC_ARG_WITH(rcstop, [ --with-rcstop set stop number for rc scripts],rcstop="$withval",rcstop="00") + +INITDIR="" +INITDDIR="" +RCLEVELS="$rclevels" +RCSTART="$rcstart" +RCSTOP="$rcstop" if test x$rcdir = x; then case "$uname" in - FreeBSD* | OpenBSD* | MirBsD* | ekkoBSD*) - # FreeBSD and OpenBSD - INITDIR="" - INITDDIR="" - ;; - - NetBSD*) - # NetBSD - INITDIR="" - INITDDIR="/etc/rc.d" + AIX*) + INITDIR="/etc/rc.d" ;; Darwin*) # Darwin and MacOS X... - INITDIR="" if test -x /sbin/launchd; then INITDDIR="/System/Library/LaunchDaemons" else @@ -148,53 +148,80 @@ if test x$rcdir = x; then fi ;; + FreeBSD* | OpenBSD* | MirBsD* | ekkoBSD*) + # FreeBSD and OpenBSD + ;; + + HP-UX*) + INITDIR="/sbin" + RCLEVELS="2" + RCSTART="620" + RCSTOP="380" + ;; + + IRIX*) + # IRIX + INITDIR="/etc" + RCSTART="60" + RCSTOP="25" + ;; + Linux | GNU) # Linux/HURD seems to choose an init.d directory at random... if test -d /sbin/init.d; then # SuSE INITDIR="/sbin/init.d" - INITDDIR=".." else if test -d /etc/init.d; then # Others INITDIR="/etc" - INITDDIR="../init.d" else # RedHat INITDIR="/etc/rc.d" - INITDDIR="../init.d" fi fi + RCSTART="81" + RCSTOP="36" ;; - OSF1* | HP-UX*) + NetBSD*) + # NetBSD + INITDDIR="/etc/rc.d" + ;; + + OSF1*) INITDIR="/sbin" - INITDDIR="../init.d" ;; - AIX*) - INITDIR="/etc/rc.d" - INITDDIR=".." + SunOS*) + # Solaris + INITDIR="/etc" + RCSTART="81" ;; *) INITDIR="/etc" - INITDDIR="../init.d" ;; esac else - INITDIR="" - INITDDIR="$rcdir" + if test "x$rclevels" = x; then + INITDDIR="$rcdir" + else + INITDIR="$rcdir" + fi fi AC_SUBST(INITDIR) AC_SUBST(INITDDIR) +AC_SUBST(RCLEVELS) +AC_SUBST(RCSTART) +AC_SUBST(RCSTOP) dnl Xinetd support... -XINETD="" +AC_ARG_WITH(xinetd, [ --with-xinetd set path for xinetd config files],XINETD="$withval",XINETD="") -if test ! -x /sbin/launchd; then +if test "x$XINETD" = x -a ! -x /sbin/launchd; then for dir in /private/etc/xinetd.d /etc/xinetd.d /usr/local/etc/xinetd.d; do if test -d $dir; then XINETD="$dir" @@ -226,6 +253,28 @@ CUPS_DATADIR="$datadir/cups" AC_DEFINE_UNQUOTED(CUPS_DATADIR, "$datadir/cups") AC_SUBST(CUPS_DATADIR) +# Icon directory +AC_ARG_WITH(icondir, [ --with-icondir set path for application icons],icondir="$withval",icondir="") + +if test "x$icondir" = x -a -d /usr/share/icons; then + ICONDIR="/usr/share/icons" +else + ICONDIR="$icondir" +fi + +AC_SUBST(ICONDIR) + +# Menu directory +AC_ARG_WITH(menudir, [ --with-menudir set path for application menus],menudir="$withval",menudir="") + +if test "x$menudir" = x -a -d /usr/share/applications; then + MENUDIR="/usr/share/applications" +else + MENUDIR="$menudir" +fi + +AC_SUBST(MENUDIR) + # Documentation files AC_ARG_WITH(docdir, [ --with-docdir set path for documentation],docdir="$withval",docdir="") @@ -316,5 +365,5 @@ AC_DEFINE_UNQUOTED(CUPS_STATEDIR, "$localstatedir/run/cups") AC_SUBST(CUPS_STATEDIR) dnl -dnl End of "$Id: cups-directories.m4 5905 2006-08-29 20:48:59Z mike $". +dnl End of "$Id: cups-directories.m4 6332 2007-03-12 16:08:51Z mike $". dnl diff --git a/config-scripts/cups-dnssd.m4 b/config-scripts/cups-dnssd.m4 new file mode 100644 index 000000000..360910a0d --- /dev/null +++ b/config-scripts/cups-dnssd.m4 @@ -0,0 +1,47 @@ +dnl +dnl "$Id$" +dnl +dnl DNS Service Discovery (aka Bonjour) stuff for the Common UNIX Printing System (CUPS). +dnl +dnl http://www.dns-sd.org +dnl http://www.multicastdns.org/ +dnl http://developer.apple.com/networking/bonjour/ +dnl +dnl Copyright ... +dnl +dnl + +AC_ARG_ENABLE(dnssd, [ --enable-dnssd turn on DNS Service Discovery support, default=yes]) +AC_ARG_WITH(dnssd-libs, [ --with-dnssd-libs set directory for DNS Service Discovery library], + LDFLAGS="-L$withval $LDFLAGS" + DSOFLAGS="-L$withval $DSOFLAGS",) +AC_ARG_WITH(dnssd-includes, [ --with-dnssd-includes set directory for DNS Service Discovery includes], + CFLAGS="-I$withval $CFLAGS" + CXXFLAGS="-I$withval $CXXFLAGS" + CPPFLAGS="-I$withval $CPPFLAGS",) + +DNSSDLIBS="" + +if test x$enable_dnssd != xno; then + AC_CHECK_HEADER(dns_sd.h, [ + AC_DEFINE(HAVE_DNSSD) + case "$uname" in + Darwin*) + # Darwin and MacOS X... + DNSSDLIBS="-framework CoreFoundation -framework SystemConfiguration" + AC_DEFINE(HAVE_COREFOUNDATION) + AC_DEFINE(HAVE_SYSTEMCONFIGURATION) + ;; + *) + # All others... + DNSSDLIBS="???" + ;; + esac + ]) +fi + +AC_SUBST(DNSSDLIBS) + +dnl +dnl End of "$Id$". +dnl diff --git a/config-scripts/cups-gssapi.m4 b/config-scripts/cups-gssapi.m4 new file mode 100644 index 000000000..ebb8c12fc --- /dev/null +++ b/config-scripts/cups-gssapi.m4 @@ -0,0 +1,105 @@ +dnl +dnl "$Id$" +dnl +dnl GSSAPI/Kerberos library detection. +dnl +dnl Copyright 2006-2007 by Easy Software Products. +dnl +dnl This file contains Kerberos support code, copyright 2006 by +dnl Jelmer Vernooij. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Easy Software Products and are protected by Federal +dnl copyright law. Distribution and use rights are outlined in the file +dnl "LICENSE.txt" which should have been included with this file. If this +dnl file is missing or damaged please contact Easy Software Products +dnl at: +dnl +dnl Attn: CUPS Licensing Information +dnl Easy Software Products +dnl 44141 Airport View Drive, Suite 204 +dnl Hollywood, Maryland 20636 USA +dnl +dnl Voice: (301) 373-9600 +dnl EMail: cups-info@cups.org +dnl WWW: http://www.cups.org +dnl + +AC_ARG_ENABLE(gssapi, [ --enable-gssapi turn on GSSAPI support, default=yes]) + +LIBGSSAPI="" + +if test x$enable_gssapi != xno; then + AC_PATH_PROG(KRB5CONFIG, krb5-config) + if test "x$KRB5CONFIG" != x; then + CFLAGS="`$KRB5CONFIG --cflags gssapi` $CFLAGS" + CPPFLAGS="`$KRB5CONFIG --cflags gssapi` $CPPFLAGS" + LIBGSSAPI="`$KRB5CONFIG --libs gssapi`" + AC_DEFINE(HAVE_GSSAPI, 1, [Whether GSSAPI is available]) + else + # Solaris provides its own GSSAPI implementation... + AC_CHECK_LIB(gss, gss_display_status, + AC_DEFINE(HAVE_GSSAPI, 1, [Whether GSSAPI is available]) + LIBGSSAPI="-lgss") + fi + + if test "x$LIBGSSAPI" != x; then + AC_CHECK_HEADER(krb5.h, AC_DEFINE(HAVE_KRB5_H)) + AC_CHECK_HEADER(gssapi.h, AC_DEFINE(HAVE_GSSAPI_H)) + AC_CHECK_HEADER(gssapi/gssapi.h, AC_DEFINE(HAVE_GSSAPI_GSSAPI_H)) + AC_CHECK_HEADER(gssapi/gssapi_generic.h, AC_DEFINE(HAVE_GSSAPI_GSSAPI_GENERIC_H)) + AC_CHECK_HEADER(gssapi/gssapi_krb5.h, AC_DEFINE(HAVE_GSSAPI_GSSAPI_KRB5_H)) + + SAVELIBS="$LIBS" + LIBS="$LIBS $LIBGSSAPI" + + AC_CHECK_FUNC(gsskrb5_register_acceptor_identity, + AC_DEFINE(HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY)) + + AC_MSG_CHECKING(for GSS_C_NT_HOSTBASED_SERVICE) + if test $ac_cv_header_gssapi_gssapi_h = yes; then + AC_TRY_COMPILE([ #include ], + [ gss_OID foo = GSS_C_NT_HOSTBASED_SERVICE; ], + AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + else + AC_TRY_COMPILE([ #include ], + [ gss_OID foo = GSS_C_NT_HOSTBASED_SERVICE; ], + AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + fi + + LIBS="$SAVELIBS" + + AC_MSG_CHECKING(for Heimdal Kerberos) + AC_TRY_COMPILE([ #include ], + [ char *tmp = heimdal_version; ], + AC_DEFINE(HAVE_HEIMDAL) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + fi +fi + +dnl Default GSS service name... +AC_ARG_WITH(gssservicename, [ --with-gssservicename set default gss service name], + default_gssservicename="$withval", + default_gssservicename="default") + +if test x$default_gssservicename != xno; then + if test "x$default_gssservicename" = "xdefault"; then + CUPS_DEFAULT_GSSSERVICENAME="IPP" + else + CUPS_DEFAULT_GSSSERVICENAME="$default_gssservicename" + fi +else + CUPS_DEFAULT_GSSSERVICENAME="" +fi + +AC_SUBST(LIBGSSAPI) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_GSSSERVICENAME, "$CUPS_DEFAULT_GSSSERVICENAME") + +dnl +dnl End of "$Id$". +dnl diff --git a/config-scripts/cups-image.m4 b/config-scripts/cups-image.m4 index 22cb798f4..8c63cc9a5 100644 --- a/config-scripts/cups-image.m4 +++ b/config-scripts/cups-image.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-image.m4 5580 2006-05-23 19:30:23Z mike $" +dnl "$Id: cups-image.m4 5579 2006-05-23 19:27:28Z mike $" dnl dnl Image library/filter stuff for the Common UNIX Printing System (CUPS). dnl @@ -114,5 +114,5 @@ AC_SUBST(EXPORT_LIBZ) AC_CHECK_HEADER(stdlib.h,AC_DEFINE(HAVE_STDLIB_H)) dnl -dnl End of "$Id: cups-image.m4 5580 2006-05-23 19:30:23Z mike $". +dnl End of "$Id: cups-image.m4 5579 2006-05-23 19:27:28Z mike $". dnl diff --git a/config-scripts/cups-largefile.m4 b/config-scripts/cups-largefile.m4 index 25400ce2d..f5f6bf1ad 100644 --- a/config-scripts/cups-largefile.m4 +++ b/config-scripts/cups-largefile.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-largefile.m4 4732 2005-09-30 23:23:25Z mike $" +dnl "$Id: cups-largefile.m4 6330 2007-03-12 14:50:45Z mike $" dnl dnl Large file support stuff for the Common UNIX Printing System (CUPS). dnl @@ -30,11 +30,11 @@ LARGEFILE="" if test x$enable_largefile != xno; then LARGEFILE="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE" - if test $ac_cv_sys_large_files = 1; then + if test x$ac_cv_sys_large_files = x1; then LARGEFILE="$LARGEFILE -D_LARGE_FILES" fi - if test $ac_cv_sys_file_offset_bits = 64; then + if test x$ac_cv_sys_file_offset_bits = x64; then LARGEFILE="$LARGEFILE -D_FILE_OFFSET_BITS=64" fi fi @@ -57,5 +57,5 @@ fi AC_CHECK_FUNC(strtoll, AC_DEFINE(HAVE_STRTOLL)) dnl -dnl End of "$Id: cups-largefile.m4 4732 2005-09-30 23:23:25Z mike $". +dnl End of "$Id: cups-largefile.m4 6330 2007-03-12 14:50:45Z mike $". dnl diff --git a/config-scripts/cups-ldap.m4 b/config-scripts/cups-ldap.m4 index c78e17509..d2171eb30 100644 --- a/config-scripts/cups-ldap.m4 +++ b/config-scripts/cups-ldap.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-ldap.m4 5564 2006-05-22 00:59:11Z mike $" +dnl "$Id: cups-ldap.m4 5563 2006-05-21 17:18:40Z mike $" dnl dnl LDAP configuration stuff for the Common UNIX Printing System (CUPS). dnl @@ -46,5 +46,5 @@ AC_SUBST(LIBLDAP) dnl -dnl End of "$Id: cups-ldap.m4 5564 2006-05-22 00:59:11Z mike $". +dnl End of "$Id: cups-ldap.m4 5563 2006-05-21 17:18:40Z mike $". dnl diff --git a/config-scripts/cups-manpages.m4 b/config-scripts/cups-manpages.m4 index 41e8190cb..71f1e60ba 100644 --- a/config-scripts/cups-manpages.m4 +++ b/config-scripts/cups-manpages.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-manpages.m4 5799 2006-08-03 00:54:38Z mike $" +dnl "$Id: cups-manpages.m4 5798 2006-08-03 00:53:58Z mike $" dnl dnl Manpage stuff for the Common UNIX Printing System (CUPS). dnl @@ -109,5 +109,5 @@ AC_SUBST(MAN8EXT) AC_SUBST(MAN8DIR) dnl -dnl End of "$Id: cups-manpages.m4 5799 2006-08-03 00:54:38Z mike $". +dnl End of "$Id: cups-manpages.m4 5798 2006-08-03 00:53:58Z mike $". dnl diff --git a/config-scripts/cups-network.m4 b/config-scripts/cups-network.m4 index abe2ebcf0..10cf68281 100644 --- a/config-scripts/cups-network.m4 +++ b/config-scripts/cups-network.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-network.m4 6049 2006-10-20 15:07:21Z mike $" +dnl "$Id: cups-network.m4 6046 2006-10-20 14:43:30Z mike $" dnl dnl Networking stuff for the Common UNIX Printing System (CUPS). dnl @@ -51,7 +51,7 @@ else maxfiles=4096 fi -AC_ARG_WITH(maxfiles, [ --with-maxfiles=N set maximum number of file descriptors for scheduler (deprecated) ], +AC_ARG_WITH(maxfiles, [ --with-maxfiles=N set maximum number of file descriptors for scheduler ], maxfiles=$withval) AC_DEFINE_UNQUOTED(CUPS_MAX_FDS, $maxfiles) @@ -90,5 +90,5 @@ AC_SUBST(CUPS_DEFAULT_DOMAINSOCKET) AC_SUBST(CUPS_LISTEN_DOMAINSOCKET) dnl -dnl End of "$Id: cups-network.m4 6049 2006-10-20 15:07:21Z mike $". +dnl End of "$Id: cups-network.m4 6046 2006-10-20 14:43:30Z mike $". dnl diff --git a/config-scripts/cups-opsys.m4 b/config-scripts/cups-opsys.m4 index 8d510da91..964fe74bf 100644 --- a/config-scripts/cups-opsys.m4 +++ b/config-scripts/cups-opsys.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-opsys.m4 6145 2006-12-06 20:10:16Z mike $" +dnl "$Id: cups-opsys.m4 6135 2006-12-06 18:22:38Z mike $" dnl dnl Operating system stuff for the Common UNIX Printing System (CUPS). dnl @@ -40,5 +40,5 @@ case "$uname" in esac dnl -dnl "$Id: cups-opsys.m4 6145 2006-12-06 20:10:16Z mike $" +dnl "$Id: cups-opsys.m4 6135 2006-12-06 18:22:38Z mike $" dnl diff --git a/config-scripts/cups-poll.m4 b/config-scripts/cups-poll.m4 new file mode 100644 index 000000000..d0b6e9760 --- /dev/null +++ b/config-scripts/cups-poll.m4 @@ -0,0 +1,31 @@ +dnl +dnl "$Id$" +dnl +dnl Select/poll stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Easy Software Products and are protected by Federal +dnl copyright law. Distribution and use rights are outlined in the file +dnl "LICENSE.txt" which should have been included with this file. If this +dnl file is missing or damaged please contact Easy Software Products +dnl at: +dnl +dnl Attn: CUPS Licensing Information +dnl Easy Software Products +dnl 44141 Airport View Drive, Suite 204 +dnl Hollywood, Maryland 20636 USA +dnl +dnl Voice: (301) 373-9600 +dnl EMail: cups-info@cups.org +dnl WWW: http://www.cups.org +dnl + +AC_CHECK_FUNC(poll, AC_DEFINE(HAVE_POLL)) +AC_CHECK_FUNC(epoll_create, AC_DEFINE(HAVE_EPOLL)) +AC_CHECK_FUNC(kqueue, AC_DEFINE(HAVE_KQUEUE)) + +dnl +dnl End of "$Id$". +dnl diff --git a/config-scripts/cups-sharedlibs.m4 b/config-scripts/cups-sharedlibs.m4 index ca695aa13..940fdac28 100644 --- a/config-scripts/cups-sharedlibs.m4 +++ b/config-scripts/cups-sharedlibs.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-sharedlibs.m4 6145 2006-12-06 20:10:16Z mike $" +dnl "$Id: cups-sharedlibs.m4 6135 2006-12-06 18:22:38Z mike $" dnl dnl Shared library support for the Common UNIX Printing System (CUPS). dnl @@ -192,5 +192,5 @@ AC_SUBST(IMGLIBS) AC_SUBST(EXPORT_LDFLAGS) dnl -dnl End of "$Id: cups-sharedlibs.m4 6145 2006-12-06 20:10:16Z mike $". +dnl End of "$Id: cups-sharedlibs.m4 6135 2006-12-06 18:22:38Z mike $". dnl diff --git a/config-scripts/cups-ssl.m4 b/config-scripts/cups-ssl.m4 index 2522e9b16..a208b712f 100644 --- a/config-scripts/cups-ssl.m4 +++ b/config-scripts/cups-ssl.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-ssl.m4 6238 2007-02-06 16:04:25Z mike $" +dnl "$Id: cups-ssl.m4 6237 2007-02-06 15:56:14Z mike $" dnl dnl OpenSSL/GNUTLS stuff for the Common UNIX Printing System (CUPS). dnl @@ -133,5 +133,5 @@ AC_SUBST(EXPORT_SSLLIBS) dnl -dnl End of "$Id: cups-ssl.m4 6238 2007-02-06 16:04:25Z mike $". +dnl End of "$Id: cups-ssl.m4 6237 2007-02-06 15:56:14Z mike $". dnl diff --git a/config-scripts/cups-threads.m4 b/config-scripts/cups-threads.m4 index dbf5afaf2..a779aad84 100644 --- a/config-scripts/cups-threads.m4 +++ b/config-scripts/cups-threads.m4 @@ -1,5 +1,5 @@ dnl -dnl "$Id: cups-threads.m4 6061 2006-10-23 00:26:52Z mike $" +dnl "$Id: cups-threads.m4 6057 2006-10-23 00:17:26Z mike $" dnl dnl Threading stuff for the Common UNIX Printing System (CUPS). dnl @@ -59,5 +59,5 @@ fi AC_SUBST(PTHREAD_FLAGS) dnl -dnl End of "$Id: cups-threads.m4 6061 2006-10-23 00:26:52Z mike $". +dnl End of "$Id: cups-threads.m4 6057 2006-10-23 00:17:26Z mike $". dnl diff --git a/config.h.in b/config.h.in index bad25cb09..e2a76addd 100644 --- a/config.h.in +++ b/config.h.in @@ -1,5 +1,5 @@ /* - * "$Id: config.h.in 6238 2007-02-06 16:04:25Z mike $" + * "$Id: config.h.in 6304 2007-02-22 22:06:23Z mike $" * * Configuration file for the Common UNIX Printing System (CUPS). * @@ -77,6 +77,13 @@ #define CUPS_DEFAULT_PRINTCAP "/etc/printcap" +/* + * Default MaxCopies value... + */ + +#define CUPS_DEFAULT_MAX_COPIES 100 + + /* * Maximum number of file descriptors to support. */ @@ -271,6 +278,7 @@ * What Security framework headers do we have? */ +#undef HAVE_AUTHORIZATION_H #undef HAVE_SECPOLICY_H #undef HAVE_SECPOLICYPRIV_H #undef HAVE_SECBASEPRIV_H @@ -306,6 +314,21 @@ #undef HAVE_LIBPAPER +/* + * Do we have DNS Service Discovery (aka Bonjour)? + */ + +#undef HAVE_DNSSD + + +/* + * Do we have Darwin's CoreFoundation and SystemConfiguration frameworks? + */ + +#undef HAVE_COREFOUNDATION +#undef HAVE_SYSTEMCONFIGURATION + + /* * Do we have ? */ @@ -468,8 +491,39 @@ #undef HAVE_APPLETALK_AT_PROTO_H +/* + * Do we have the GSSAPI support library (for Kerberos support)? + */ + +#undef HAVE_GSSAPI +#undef HAVE_GSSAPI_H +#undef HAVE_GSSAPI_GSSAPI_H +#undef HAVE_GSSAPI_GSSAPI_GENERIC_H +#undef HAVE_GSSAPI_GSSAPI_KRB5_H +#undef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY +#undef HAVE_GSS_C_NT_HOSTBASED_SERVICE +#undef HAVE_KRB5_H +#undef HAVE_HEIMDAL + + +/* + * Default GSS service name... + */ + +#define CUPS_DEFAULT_GSSSERVICENAME "" + + +/* + * Select/poll interfaces... + */ + +#undef HAVE_POLL +#undef HAVE_EPOLL +#undef HAVE_KQUEUE + + #endif /* !_CUPS_CONFIG_H_ */ /* - * End of "$Id: config.h.in 6238 2007-02-06 16:04:25Z mike $". + * End of "$Id: config.h.in 6304 2007-02-22 22:06:23Z mike $". */ diff --git a/configure.in b/configure.in index b96b42272..2472ce6fc 100644 --- a/configure.in +++ b/configure.in @@ -1,9 +1,9 @@ dnl -dnl "$Id: configure.in 6145 2006-12-06 20:10:16Z mike $" +dnl "$Id: configure.in 6291 2007-02-19 21:54:27Z mike $" dnl dnl Configuration script for the Common UNIX Printing System (CUPS). dnl -dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. +dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. dnl dnl These coded instructions, statements, and computer programs are the dnl property of Easy Software Products and are protected by Federal @@ -36,12 +36,15 @@ sinclude(config-scripts/cups-compiler.m4) sinclude(config-scripts/cups-image.m4) sinclude(config-scripts/cups-network.m4) +sinclude(config-scripts/cups-poll.m4) sinclude(config-scripts/cups-slp.m4) +sinclude(config-scripts/cups-gssapi.m4) sinclude(config-scripts/cups-ldap.m4) sinclude(config-scripts/cups-ssl.m4) sinclude(config-scripts/cups-pam.m4) sinclude(config-scripts/cups-threads.m4) sinclude(config-scripts/cups-largefile.m4) +sinclude(config-scripts/cups-dnssd.m4) sinclude(config-scripts/cups-launchd.m4) sinclude(config-scripts/cups-defaults.m4) sinclude(config-scripts/cups-pap.m4) @@ -84,5 +87,5 @@ AC_OUTPUT(Makedefs packaging/cups.list init/cups.sh init/cups-lpd cups-config chmod +x cups-config dnl -dnl End of "$Id: configure.in 6145 2006-12-06 20:10:16Z mike $". +dnl End of "$Id: configure.in 6291 2007-02-19 21:54:27Z mike $". dnl diff --git a/cups-config.in b/cups-config.in index 81a982b47..98e80a88f 100755 --- a/cups-config.in +++ b/cups-config.in @@ -1,6 +1,6 @@ #! /bin/sh # -# "$Id: cups-config.in 5799 2006-08-03 00:54:38Z mike $" +# "$Id: cups-config.in 5919 2006-08-31 04:20:45Z mike $" # # CUPS configuration utility. # @@ -24,7 +24,7 @@ # VERSION="@CUPS_VERSION@" -APIVERSION="1.2" +APIVERSION="1.3" prefix=@prefix@ exec_prefix=@exec_prefix@ @@ -43,7 +43,7 @@ INSTALLSTATIC=@INSTALLSTATIC@ # flags for C++ compiler: CFLAGS="" LDFLAGS="@EXPORT_LDFLAGS@" -LIBS="@EXPORT_SSLLIBS@ @EXPORT_LIBZ@ @LIBS@" +LIBS="@LIBGSSAPI@ @EXPORT_SSLLIBS@ @EXPORT_LIBZ@ @LIBS@" IMGLIBS="@EXPORT_LIBTIFF@ @EXPORT_LIBJPEG@ @EXPORT_LIBPNG@" # Check for local invocation... @@ -151,5 +151,5 @@ while test $# -gt 0; do done # -# End of "$Id: cups-config.in 5799 2006-08-03 00:54:38Z mike $". +# End of "$Id: cups-config.in 5919 2006-08-31 04:20:45Z mike $". # diff --git a/cups/Dependencies b/cups/Dependencies index cedd9bded..0efee6e4a 100644 --- a/cups/Dependencies +++ b/cups/Dependencies @@ -1,14 +1,14 @@ # DO NOT DELETE -adminutil.o: adminutil.h cups.h ipp.h http.h md5.h ppd.h array.h file.h -adminutil.o: language.h globals.h string.h ../config.h http-private.h +adminutil.o: adminutil.h cups.h ipp.h http.h ppd.h array.h file.h language.h +adminutil.o: globals.h string.h ../config.h http-private.h md5.h adminutil.o: ipp-private.h i18n.h transcode.h debug.h array.o: array.h string.h ../config.h debug.h attr.o: ppd.h array.h file.h debug.h string.h ../config.h auth.o: globals.h string.h ../config.h http-private.h http.h md5.h auth.o: ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h auth.o: transcode.h debug.h -backchannel.o: cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h +backchannel.o: cups.h ipp.h http.h ppd.h array.h file.h language.h backend.o: backend.h string.h ../config.h custom.o: globals.h string.h ../config.h http-private.h http.h md5.h custom.o: ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h @@ -18,14 +18,14 @@ dest.o: ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h dest.o: transcode.h dir.o: dir.h string.h ../config.h debug.h emit.o: ppd.h array.h file.h string.h ../config.h debug.h -encode.o: cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h -encode.o: ipp-private.h string.h ../config.h debug.h +encode.o: cups.h ipp.h http.h ppd.h array.h file.h language.h ipp-private.h +encode.o: string.h ../config.h debug.h file.o: http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.h file.o: string.h cups.h ppd.h array.h file.h language.h i18n.h transcode.h file.o: debug.h getifaddrs.o: http-private.h ../config.h http.h md5.h ipp-private.h ipp.h -getputfile.o: cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h -getputfile.o: string.h ../config.h debug.h +getputfile.o: http-private.h ../config.h http.h md5.h ipp-private.h ipp.h +getputfile.o: cups.h ppd.h array.h file.h language.h string.h debug.h globals.o: http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.o: globals.h string.h cups.h ppd.h array.h file.h language.h i18n.h globals.o: transcode.h debug.h @@ -56,14 +56,15 @@ language.o: transcode.h debug.h localize.o: globals.h string.h ../config.h http-private.h http.h md5.h localize.o: ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h localize.o: transcode.h debug.h -mark.o: cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h string.h +mark.o: cups.h ipp.h http.h ppd.h array.h file.h language.h string.h mark.o: ../config.h debug.h md5.o: md5.h string.h ../config.h -md5passwd.o: http.h md5.h string.h ../config.h +md5passwd.o: http-private.h ../config.h http.h md5.h ipp-private.h ipp.h +md5passwd.o: string.h notify.o: globals.h string.h ../config.h http-private.h http.h md5.h notify.o: ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h notify.o: transcode.h -options.o: cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h string.h +options.o: cups.h ipp.h http.h ppd.h array.h file.h language.h string.h options.o: ../config.h debug.h page.o: ppd.h array.h file.h string.h ../config.h ppd.o: globals.h string.h ../config.h http-private.h http.h md5.h @@ -72,6 +73,7 @@ ppd.o: transcode.h debug.h request.o: globals.h string.h ../config.h http-private.h http.h md5.h request.o: ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h request.o: transcode.h debug.h +sidechannel.o: sidechannel.h string.h ../config.h snprintf.o: string.h ../config.h string.o: array.h debug.h string.h ../config.h tempfile.o: globals.h string.h ../config.h http-private.h http.h md5.h @@ -86,27 +88,26 @@ usersys.o: transcode.h debug.h util.o: globals.h string.h ../config.h http-private.h http.h md5.h util.o: ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h util.o: transcode.h debug.h -testadmin.o: adminutil.h cups.h ipp.h http.h md5.h ppd.h array.h file.h -testadmin.o: language.h string.h ../config.h +testadmin.o: adminutil.h cups.h ipp.h http.h ppd.h array.h file.h language.h +testadmin.o: string.h ../config.h testarray.o: ../cups/string.h ../config.h string.h array.h dir.h debug.h testfile.o: string.h ../config.h file.h debug.h -testhttp.o: http.h md5.h string.h ../config.h +testhttp.o: http.h string.h ../config.h testi18n.o: i18n.h transcode.h language.h array.h string.h ../config.h testipp.o: ../cups/string.h ../config.h string.h ipp-private.h ipp.h http.h -testipp.o: md5.h testlang.o: i18n.h transcode.h language.h array.h testppd.o: ../cups/string.h ../config.h string.h ppd.h array.h file.h # DO NOT DELETE -adminutil.32.o: adminutil.c adminutil.h cups.h ipp.h http.h md5.h ppd.h array.h file.h -adminutil.32.o: adminutil.c language.h globals.h string.h ../config.h http-private.h +adminutil.32.o: adminutil.c adminutil.h cups.h ipp.h http.h ppd.h array.h file.h language.h +adminutil.32.o: adminutil.c globals.h string.h ../config.h http-private.h md5.h adminutil.32.o: adminutil.c ipp-private.h i18n.h transcode.h debug.h array.32.o: array.c array.h string.h ../config.h debug.h attr.32.o: attr.c ppd.h array.h file.h debug.h string.h ../config.h auth.32.o: auth.c globals.h string.h ../config.h http-private.h http.h md5.h auth.32.o: auth.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h auth.32.o: auth.c transcode.h debug.h -backchannel.32.o: backchannel.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h +backchannel.32.o: backchannel.c cups.h ipp.h http.h ppd.h array.h file.h language.h backend.32.o: backend.c backend.h string.h ../config.h custom.32.o: custom.c globals.h string.h ../config.h http-private.h http.h md5.h custom.32.o: custom.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h @@ -116,14 +117,14 @@ dest.32.o: dest.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i1 dest.32.o: dest.c transcode.h dir.32.o: dir.c dir.h string.h ../config.h debug.h emit.32.o: emit.c ppd.h array.h file.h string.h ../config.h debug.h -encode.32.o: encode.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h -encode.32.o: encode.c ipp-private.h string.h ../config.h debug.h +encode.32.o: encode.c cups.h ipp.h http.h ppd.h array.h file.h language.h ipp-private.h +encode.32.o: encode.c string.h ../config.h debug.h file.32.o: file.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.h file.32.o: file.c string.h cups.h ppd.h array.h file.h language.h i18n.h transcode.h file.32.o: file.c debug.h getifaddrs.32.o: getifaddrs.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h -getputfile.32.o: getputfile.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h -getputfile.32.o: getputfile.c string.h ../config.h debug.h +getputfile.32.o: getputfile.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h +getputfile.32.o: getputfile.c cups.h ppd.h array.h file.h language.h string.h debug.h globals.32.o: globals.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.32.o: globals.c globals.h string.h cups.h ppd.h array.h file.h language.h i18n.h globals.32.o: globals.c transcode.h debug.h @@ -154,14 +155,15 @@ language.32.o: language.c transcode.h debug.h localize.32.o: localize.c globals.h string.h ../config.h http-private.h http.h md5.h localize.32.o: localize.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h localize.32.o: localize.c transcode.h debug.h -mark.32.o: mark.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h string.h +mark.32.o: mark.c cups.h ipp.h http.h ppd.h array.h file.h language.h string.h mark.32.o: mark.c ../config.h debug.h md5.32.o: md5.c md5.h string.h ../config.h -md5passwd.32.o: md5passwd.c http.h md5.h string.h ../config.h +md5passwd.32.o: md5passwd.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h +md5passwd.32.o: md5passwd.c string.h notify.32.o: notify.c globals.h string.h ../config.h http-private.h http.h md5.h notify.32.o: notify.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h notify.32.o: notify.c transcode.h -options.32.o: options.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h string.h +options.32.o: options.c cups.h ipp.h http.h ppd.h array.h file.h language.h string.h options.32.o: options.c ../config.h debug.h page.32.o: page.c ppd.h array.h file.h string.h ../config.h ppd.32.o: ppd.c globals.h string.h ../config.h http-private.h http.h md5.h @@ -170,6 +172,7 @@ ppd.32.o: ppd.c transcode.h debug.h request.32.o: request.c globals.h string.h ../config.h http-private.h http.h md5.h request.32.o: request.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h request.32.o: request.c transcode.h debug.h +sidechannel.32.o: sidechannel.c sidechannel.h string.h ../config.h snprintf.32.o: snprintf.c string.h ../config.h string.32.o: string.c array.h debug.h string.h ../config.h tempfile.32.o: tempfile.c globals.h string.h ../config.h http-private.h http.h md5.h @@ -184,27 +187,26 @@ usersys.32.o: usersys.c transcode.h debug.h util.32.o: util.c globals.h string.h ../config.h http-private.h http.h md5.h util.32.o: util.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h util.32.o: util.c transcode.h debug.h -testadmin.32.o: testadmin.c adminutil.h cups.h ipp.h http.h md5.h ppd.h array.h file.h -testadmin.32.o: testadmin.c language.h string.h ../config.h +testadmin.32.o: testadmin.c adminutil.h cups.h ipp.h http.h ppd.h array.h file.h language.h +testadmin.32.o: testadmin.c string.h ../config.h testarray.32.o: testarray.c ../cups/string.h ../config.h string.h array.h dir.h debug.h testfile.32.o: testfile.c string.h ../config.h file.h debug.h -testhttp.32.o: testhttp.c http.h md5.h string.h ../config.h +testhttp.32.o: testhttp.c http.h string.h ../config.h testi18n.32.o: testi18n.c i18n.h transcode.h language.h array.h string.h ../config.h testipp.32.o: testipp.c ../cups/string.h ../config.h string.h ipp-private.h ipp.h http.h -testipp.32.o: testipp.c md5.h testlang.32.o: testlang.c i18n.h transcode.h language.h array.h testppd.32.o: testppd.c ../cups/string.h ../config.h string.h ppd.h array.h file.h # DO NOT DELETE -adminutil.64.o: adminutil.c adminutil.h cups.h ipp.h http.h md5.h ppd.h array.h file.h -adminutil.64.o: adminutil.c language.h globals.h string.h ../config.h http-private.h +adminutil.64.o: adminutil.c adminutil.h cups.h ipp.h http.h ppd.h array.h file.h language.h +adminutil.64.o: adminutil.c globals.h string.h ../config.h http-private.h md5.h adminutil.64.o: adminutil.c ipp-private.h i18n.h transcode.h debug.h array.64.o: array.c array.h string.h ../config.h debug.h attr.64.o: attr.c ppd.h array.h file.h debug.h string.h ../config.h auth.64.o: auth.c globals.h string.h ../config.h http-private.h http.h md5.h auth.64.o: auth.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h auth.64.o: auth.c transcode.h debug.h -backchannel.64.o: backchannel.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h +backchannel.64.o: backchannel.c cups.h ipp.h http.h ppd.h array.h file.h language.h backend.64.o: backend.c backend.h string.h ../config.h custom.64.o: custom.c globals.h string.h ../config.h http-private.h http.h md5.h custom.64.o: custom.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h @@ -214,14 +216,14 @@ dest.64.o: dest.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i1 dest.64.o: dest.c transcode.h dir.64.o: dir.c dir.h string.h ../config.h debug.h emit.64.o: emit.c ppd.h array.h file.h string.h ../config.h debug.h -encode.64.o: encode.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h -encode.64.o: encode.c ipp-private.h string.h ../config.h debug.h +encode.64.o: encode.c cups.h ipp.h http.h ppd.h array.h file.h language.h ipp-private.h +encode.64.o: encode.c string.h ../config.h debug.h file.64.o: file.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.h file.64.o: file.c string.h cups.h ppd.h array.h file.h language.h i18n.h transcode.h file.64.o: file.c debug.h getifaddrs.64.o: getifaddrs.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h -getputfile.64.o: getputfile.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h -getputfile.64.o: getputfile.c string.h ../config.h debug.h +getputfile.64.o: getputfile.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h +getputfile.64.o: getputfile.c cups.h ppd.h array.h file.h language.h string.h debug.h globals.64.o: globals.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h globals.64.o: globals.c globals.h string.h cups.h ppd.h array.h file.h language.h i18n.h globals.64.o: globals.c transcode.h debug.h @@ -252,14 +254,15 @@ language.64.o: language.c transcode.h debug.h localize.64.o: localize.c globals.h string.h ../config.h http-private.h http.h md5.h localize.64.o: localize.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h localize.64.o: localize.c transcode.h debug.h -mark.64.o: mark.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h string.h +mark.64.o: mark.c cups.h ipp.h http.h ppd.h array.h file.h language.h string.h mark.64.o: mark.c ../config.h debug.h md5.64.o: md5.c md5.h string.h ../config.h -md5passwd.64.o: md5passwd.c http.h md5.h string.h ../config.h +md5passwd.64.o: md5passwd.c http-private.h ../config.h http.h md5.h ipp-private.h ipp.h +md5passwd.64.o: md5passwd.c string.h notify.64.o: notify.c globals.h string.h ../config.h http-private.h http.h md5.h notify.64.o: notify.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h notify.64.o: notify.c transcode.h -options.64.o: options.c cups.h ipp.h http.h md5.h ppd.h array.h file.h language.h string.h +options.64.o: options.c cups.h ipp.h http.h ppd.h array.h file.h language.h string.h options.64.o: options.c ../config.h debug.h page.64.o: page.c ppd.h array.h file.h string.h ../config.h ppd.64.o: ppd.c globals.h string.h ../config.h http-private.h http.h md5.h @@ -268,6 +271,7 @@ ppd.64.o: ppd.c transcode.h debug.h request.64.o: request.c globals.h string.h ../config.h http-private.h http.h md5.h request.64.o: request.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h request.64.o: request.c transcode.h debug.h +sidechannel.64.o: sidechannel.c sidechannel.h string.h ../config.h snprintf.64.o: snprintf.c string.h ../config.h string.64.o: string.c array.h debug.h string.h ../config.h tempfile.64.o: tempfile.c globals.h string.h ../config.h http-private.h http.h md5.h @@ -282,13 +286,12 @@ usersys.64.o: usersys.c transcode.h debug.h util.64.o: util.c globals.h string.h ../config.h http-private.h http.h md5.h util.64.o: util.c ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h i18n.h util.64.o: util.c transcode.h debug.h -testadmin.64.o: testadmin.c adminutil.h cups.h ipp.h http.h md5.h ppd.h array.h file.h -testadmin.64.o: testadmin.c language.h string.h ../config.h +testadmin.64.o: testadmin.c adminutil.h cups.h ipp.h http.h ppd.h array.h file.h language.h +testadmin.64.o: testadmin.c string.h ../config.h testarray.64.o: testarray.c ../cups/string.h ../config.h string.h array.h dir.h debug.h testfile.64.o: testfile.c string.h ../config.h file.h debug.h -testhttp.64.o: testhttp.c http.h md5.h string.h ../config.h +testhttp.64.o: testhttp.c http.h string.h ../config.h testi18n.64.o: testi18n.c i18n.h transcode.h language.h array.h string.h ../config.h testipp.64.o: testipp.c ../cups/string.h ../config.h string.h ipp-private.h ipp.h http.h -testipp.64.o: testipp.c md5.h testlang.64.o: testlang.c i18n.h transcode.h language.h array.h testppd.64.o: testppd.c ../cups/string.h ../config.h string.h ppd.h array.h file.h diff --git a/cups/Makefile b/cups/Makefile index e0064b42e..36c170baa 100644 --- a/cups/Makefile +++ b/cups/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5801 2006-08-03 02:20:57Z mike $" +# "$Id: Makefile 6304 2007-02-22 22:06:23Z mike $" # # API library Makefile for the Common UNIX Printing System (CUPS). # @@ -63,6 +63,7 @@ LIBOBJS = \ page.o \ ppd.o \ request.o \ + sidechannel.o \ snprintf.o \ string.o \ tempfile.o \ @@ -101,8 +102,8 @@ HEADERS = \ i18n.h \ ipp.h \ language.h \ - md5.h \ ppd.h \ + sidechannel.h \ transcode.h @@ -231,7 +232,7 @@ uninstall64bit: libcups.so.2 libcups.sl.2: $(LIBOBJS) echo Linking $@... - $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) $(RM) `basename $@ .2` $(LN) $@ `basename $@ .2` @@ -243,7 +244,7 @@ libcups.so.2 libcups.sl.2: $(LIBOBJS) 32bit/libcups.so.2: $(LIB32OBJS) echo Linking 32-bit $@... -mkdir 32bit - $(DSO) $(ARCH32FLAGS) $(DSO32FLAGS) -o $@ $(LIB32OBJS) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(DSO) $(ARCH32FLAGS) $(DSO32FLAGS) -o $@ $(LIB32OBJS) $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) $(RM) 32bit/libcups.so $(LN) libcups.so.2 32bit/libcups.so @@ -255,7 +256,7 @@ libcups.so.2 libcups.sl.2: $(LIBOBJS) 64bit/libcups.so.2: $(LIB64OBJS) echo Linking 64-bit $@... -mkdir 64bit - $(DSO) $(ARCH64FLAGS) $(DSO64FLAGS) -o $@ $(LIB64OBJS) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(DSO) $(ARCH64FLAGS) $(DSO64FLAGS) -o $@ $(LIB64OBJS) $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) $(RM) 64bit/libcups.so $(LN) libcups.so.2 64bit/libcups.so @@ -268,9 +269,9 @@ libcups.2.dylib: $(LIBOBJS) echo Linking $@... $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ -install_name $(libdir)/$@ \ - -current_version 2.7.0 \ + -current_version 2.8.0 \ -compatibility_version 2.0.0 \ - $(LIBOBJS) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(LIBOBJS) $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) $(RM) libcups.dylib $(LN) $@ libcups.dylib @@ -281,7 +282,7 @@ libcups.2.dylib: $(LIBOBJS) libcups_s.a: $(LIBOBJS) libcups_s.exp echo Creating $@... - $(DSO) $(DSOFLAGS) -Wl,-bexport:libcups_s.exp -o libcups_s.o $(LIBOBJS) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) -lm + $(DSO) $(DSOFLAGS) -Wl,-bexport:libcups_s.exp -o libcups_s.o $(LIBOBJS) $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) -lm $(RM) $@ $(AR) $(ARFLAGS) $@ libcups_s.o @@ -293,7 +294,7 @@ libcups_s.a: $(LIBOBJS) libcups_s.exp libcups.la: $(LIBOBJS) echo Linking $@... $(CC) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) -rpath $(LIBDIR) \ - -version-info 2:7 $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + -version-info 2:8 $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) # @@ -338,7 +339,7 @@ php_cups_wrap.c: cups.h testadmin: testadmin.o libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testadmin.o libcups.a \ - $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) # @@ -348,7 +349,7 @@ testadmin: testadmin.o libcups.a testarray: testarray.o libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testarray.o libcups.a \ - $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) # @@ -358,7 +359,7 @@ testarray: testarray.o libcups.a testfile: testfile.o libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testfile.o libcups.a \ - $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) # @@ -368,7 +369,7 @@ testfile: testfile.o libcups.a testhttp: testhttp.o libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testhttp.o libcups.a \ - $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) # @@ -378,7 +379,7 @@ testhttp: testhttp.o libcups.a testipp: testipp.o libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testipp.o libcups.a \ - $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) # @@ -388,7 +389,7 @@ testipp: testipp.o libcups.a testi18n: testi18n.o libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testi18n.o libcups.a \ - $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) # @@ -398,7 +399,7 @@ testi18n: testi18n.o libcups.a testlang: testlang.o libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testlang.o libcups.a \ - $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) # @@ -408,7 +409,7 @@ testlang: testlang.o libcups.a testppd: testppd.o libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testppd.o libcups.a \ - $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) # @@ -422,7 +423,7 @@ apihelp: array.h array.c >../doc/help/api-array.html mxmldoc --section "Programming" --title "CUPS API" \ --intro api-cups.shtml \ - cups.h dest.c getputfile.c language.c \ + cups.h dest.c getputfile.c language.c notify.c \ options.c tempfile.c usersys.c \ util.c >../doc/help/api-cups.html mxmldoc --section "Programming" --title "File and Directory APIs" \ @@ -439,7 +440,7 @@ apihelp: request.c >../doc/help/api-httpipp.html mxmldoc --section "Programming" --title "Filter and Backend APIs" \ --intro api-filter.shtml \ - backchannel.c >../doc/help/api-filter.html + backchannel.c sidechannel.c sidechannel.h >../doc/help/api-filter.html # @@ -450,5 +451,5 @@ include Dependencies # -# End of "$Id: Makefile 5801 2006-08-03 02:20:57Z mike $". +# End of "$Id: Makefile 6304 2007-02-22 22:06:23Z mike $". # diff --git a/cups/adminutil.c b/cups/adminutil.c index e697e6a1d..8b96fcb6c 100644 --- a/cups/adminutil.c +++ b/cups/adminutil.c @@ -1,5 +1,5 @@ /* - * "$Id: adminutil.c 6262 2007-02-11 16:59:33Z mike $" + * "$Id: adminutil.c 6270 2007-02-12 14:27:47Z mike $" * * Administration utility API definitions for the Common UNIX Printing * System (CUPS). @@ -768,6 +768,7 @@ _cupsAdminGetServerSettings( int remote_access = 0, /* Remote access allowed? */ remote_admin = 0, /* Remote administration allowed? */ + remote_any = 0, /* Remote access from anywhere allowed? */ browsing = 1, /* Browsing enabled? */ browse_allow = 1, /* Browse address set? */ browse_address = 0, /* Browse address set? */ @@ -900,6 +901,9 @@ _cupsAdminGetServerSettings( ) { remote_admin = 1; + + if (!strcasecmp(value, "all")) + remote_any = 1; } else if (line[0] != '<' && !in_location && !in_policy) cg->cupsd_num_settings = cupsAddOption(line, value, @@ -920,6 +924,11 @@ _cupsAdminGetServerSettings( cg->cupsd_num_settings, &(cg->cupsd_settings)); + cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, + remote_any ? "1" : "0", + cg->cupsd_num_settings, + &(cg->cupsd_settings)); + cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS, (browsing && browse_allow) ? "1" : "0", @@ -992,6 +1001,7 @@ _cupsAdminSetServerSettings( int remote_printers, /* Show remote printers */ share_printers, /* Share local printers */ remote_admin, /* Remote administration allowed? */ + remote_any, /* Remote access from anywhere? */ user_cancel_any, /* Cancel-job policy set? */ debug_logging; /* LogLevel debug set? */ int wrote_port_listen, /* Wrote the port/listen lines? */ @@ -1060,6 +1070,12 @@ _cupsAdminSetServerSettings( else old_remote_admin = 0; + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, cupsd_num_settings, + cupsd_settings)) != NULL) + remote_any = atoi(val); + else + remote_any = 0; + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS, cupsd_num_settings, cupsd_settings)) != NULL) old_remote_printers = atoi(val); @@ -1101,12 +1117,16 @@ _cupsAdminSetServerSettings( else debug_logging = -1; + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, num_settings, + settings)) != NULL) + remote_any = atoi(val); + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings, settings)) != NULL) { remote_admin = atoi(val); - if (remote_admin == old_remote_admin) + if (remote_admin == old_remote_admin && remote_any < 0) { /* * No change to this setting... @@ -1140,7 +1160,7 @@ _cupsAdminSetServerSettings( { share_printers = atoi(val); - if (share_printers == old_share_printers) + if (share_printers == old_share_printers && remote_any < 0) { /* * No change to this setting... @@ -1278,7 +1298,7 @@ _cupsAdminSetServerSettings( cupsFilePuts(temp, "BrowseOrder allow,deny\n"); if (remote_printers > 0) - cupsFilePuts(temp, "BrowseAllow @LOCAL\n"); + cupsFilePuts(temp, "BrowseAllow all\n"); if (share_printers > 0) cupsFilePuts(temp, "BrowseAddress @LOCAL\n"); @@ -1366,7 +1386,8 @@ _cupsAdminSetServerSettings( cupsFilePuts(temp, " Order allow,deny\n"); if (remote_admin) - cupsFilePuts(temp, " Allow @LOCAL\n"); + cupsFilePrintf(temp, " Allow %s\n", + remote_any > 0 ? "all" : "@LOCAL"); else cupsFilePuts(temp, " Allow localhost\n"); } @@ -1384,7 +1405,8 @@ _cupsAdminSetServerSettings( cupsFilePuts(temp, " Order allow,deny\n"); if (remote_admin) - cupsFilePuts(temp, " Allow @LOCAL\n"); + cupsFilePrintf(temp, " Allow %s\n", + remote_any > 0 ? "all" : "@LOCAL"); else cupsFilePuts(temp, " Allow localhost\n"); } @@ -1405,7 +1427,8 @@ _cupsAdminSetServerSettings( cupsFilePuts(temp, " Order allow,deny\n"); if (remote_admin > 0 || share_printers > 0) - cupsFilePuts(temp, " Allow @LOCAL\n"); + cupsFilePrintf(temp, " Allow %s\n", + remote_any > 0 ? "all" : "@LOCAL"); else cupsFilePuts(temp, " Allow localhost\n"); } @@ -1564,7 +1587,7 @@ _cupsAdminSetServerSettings( cupsFilePuts(temp, "BrowseOrder allow,deny\n"); if (remote_printers > 0) - cupsFilePuts(temp, "BrowseAllow @LOCAL\n"); + cupsFilePuts(temp, "BrowseAllow all\n"); if (share_printers > 0) cupsFilePuts(temp, "BrowseAddress @LOCAL\n"); @@ -1626,7 +1649,7 @@ _cupsAdminSetServerSettings( " Order allow,deny\n"); if (remote_admin > 0 || share_printers > 0) - cupsFilePuts(temp, " Allow @LOCAL\n"); + cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); else cupsFilePuts(temp, " Allow localhost\n"); @@ -1644,7 +1667,7 @@ _cupsAdminSetServerSettings( " Order allow,deny\n"); if (remote_admin) - cupsFilePuts(temp, " Allow @LOCAL\n"); + cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); else cupsFilePuts(temp, " Allow localhost\n"); @@ -1665,7 +1688,7 @@ _cupsAdminSetServerSettings( " Order allow,deny\n"); if (remote_admin) - cupsFilePuts(temp, " Allow @LOCAL\n"); + cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); else cupsFilePuts(temp, " Allow localhost\n"); @@ -1769,6 +1792,10 @@ _cupsAdminSetServerSettings( old_remote_admin ? "1" : "0", cupsd_num_settings, &cupsd_settings); + cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, + remote_any ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + if (remote_printers >= 0) cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS, remote_printers ? "1" : "0", @@ -2128,5 +2155,5 @@ write_option(cups_file_t *dstfp, /* I - PPD file */ /* - * End of "$Id: adminutil.c 6262 2007-02-11 16:59:33Z mike $". + * End of "$Id: adminutil.c 6270 2007-02-12 14:27:47Z mike $". */ diff --git a/cups/adminutil.h b/cups/adminutil.h index 8b66d1b8d..2a0392d00 100644 --- a/cups/adminutil.h +++ b/cups/adminutil.h @@ -1,5 +1,5 @@ /* - * "$Id: adminutil.h 5235 2006-03-06 13:02:23Z mike $" + * "$Id: adminutil.h 6268 2007-02-12 02:46:11Z mike $" * * Administration utility API definitions for the Common UNIX Printing * System (CUPS). @@ -7,7 +7,7 @@ * MANY OF THE FUNCTIONS IN THIS HEADER ARE PRIVATE AND SUBJECT TO * CHANGE AT ANY TIME. USE AT YOUR OWN RISK. * - * Copyright 2001-2006 by Easy Software Products. + * Copyright 2001-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -53,6 +53,7 @@ extern "C" { # define CUPS_SERVER_DEBUG_LOGGING "_debug_logging" # define CUPS_SERVER_REMOTE_ADMIN "_remote_admin" +# define CUPS_SERVER_REMOTE_ANY "_remote_any" # define CUPS_SERVER_REMOTE_PRINTERS "_remote_printers" # define CUPS_SERVER_SHARE_PRINTERS "_share_printers" # define CUPS_SERVER_USER_CANCEL_ANY "_user_cancel_any" @@ -85,5 +86,5 @@ extern int _cupsAdminSetServerSettings(http_t *http, #endif /* !_CUPS_ADMINUTIL_H_ */ /* - * End of "$Id: adminutil.h 5235 2006-03-06 13:02:23Z mike $". + * End of "$Id: adminutil.h 6268 2007-02-12 02:46:11Z mike $". */ diff --git a/cups/api-filter.shtml b/cups/api-filter.shtml index 66f5e0a09..66b65267e 100644 --- a/cups/api-filter.shtml +++ b/cups/api-filter.shtml @@ -1,5 +1,5 @@ +

 CUPS 1.3 cupsArrayGetIndex()

+

Description

+

Get the index of the current element. + +

+

Syntax

+
+int
+cupsArrayGetIndex(
+    cups_array_t * a);
+
+

Arguments

+
+ + + +
NameDescription
aArray
+

Returns

+

Index of the current element

+ +

 CUPS 1.3 cupsArrayGetInsert()

+

Description

+

Get the index of the last inserted element. + +

+

Syntax

+
+int
+cupsArrayGetInsert(
+    cups_array_t * a);
+
+

Arguments

+
+ + + +
NameDescription
aArray
+

Returns

+

Index of the last inserted element

+

cupsArrayIndex()

Description

Get the N-th element in the array.

diff --git a/doc/help/api-cups.html b/doc/help/api-cups.html index 7466fa322..fafea6149 100644 --- a/doc/help/api-cups.html +++ b/doc/help/api-cups.html @@ -158,8 +158,10 @@ CUPS 1.1 or higher.

  • cupsPrintFiles2()  CUPS 1.1.21 
  • cupsPutFd()  CUPS 1.1.20 
  • cupsPutFile()  CUPS 1.1.20 
  • +
  • cupsRemoveDest()  CUPS 1.3 
  • cupsRemoveOption()  CUPS 1.2 
  • cupsServer()
  • +
  • cupsSetDefaultDest()  CUPS 1.3 
  • cupsSetDests()
  • cupsSetDests2()  CUPS 1.1.21 
  • cupsSetEncryption()
  • @@ -1034,6 +1036,37 @@ cupsPutFile(

    Returns

    HTTP status

    +

     CUPS 1.3 cupsRemoveDest()

    +

    Description

    +

    Remove a destination from the destination list. + +Removing a destination/instance does not delete the class or printer +queue, merely the lpoptions for that destination/instance. Use the +cupsSetDests() or cupsSetDests2() functions to save the new options +for the user. + +

    +

    Syntax

    +
    +int
    +cupsRemoveDest(
    +    const char * name,
    +    const char * instance,
    +    int num_dests,
    +    cups_dest_t ** dests);
    +
    +

    Arguments

    +
    + + + + + + +
    NameDescription
    nameDestination name
    instanceInstance name or NULL
    num_destsNumber of destinations
    destsDestinations
    +

    Returns

    +

    New number of destinations

    +

     CUPS 1.2 cupsRemoveOption()

    Description

    Remove an option from an option array. @@ -1074,6 +1107,32 @@ cupsServer(void);

    Returns

    Server name

    +

     CUPS 1.3 cupsSetDefaultDest()

    +

    Description

    +

    Set the default destination. + +

    +

    Syntax

    +
    +void
    +cupsSetDefaultDest(
    +    const char * name,
    +    const char * instance,
    +    int num_dests,
    +    cups_dest_t * dests);
    +
    +

    Arguments

    +
    + + + + + + +
    NameDescription
    nameDestination name
    instanceInstance name or NULL
    num_destsNumber of destinations
    destsDestinations
    +

    Returns

    +

    Nothing.

    +

    cupsSetDests()

    Description

    Save the list of destinations for the default server. diff --git a/doc/help/api-filter.html b/doc/help/api-filter.html index 63607f38b..dcf032034 100644 --- a/doc/help/api-filter.html +++ b/doc/help/api-filter.html @@ -52,6 +52,9 @@ used when writing backends, filters, and port monitors.

    use the CUPS_BACKEND_ constants and cupsBackChannel functions, respectively.

    +

    The <cups/sidechannel.h> header file must be +included to use the CUPS_SC_ constants and cupsSideChannel functions.

    +

    Programs using these functions must be linked to the CUPS library: libcups.a, libcups.so.2, libcups.2.dylib, libcups_s.a, or @@ -63,9 +66,177 @@ library:

    gcc -o myprogram myprogram.c -lcups +

    Compatibility

    -

    All of these functions require CUPS 1.2 or higher.

    +

    The cupsBackChannel functions require CUPS 1.2 or higher. The cupsSideChannel functions require CUPS 1.3 or higher.

    + + +

    Using the cupsBackChannel APIs

    + +

    The cupsBackChannel APIs allow your filters, drivers, and port monitors to read data back from a printer and your backends to send data from a printer to the filters, drivers, and port monitors associated with the current job. Back-channel data is normally sent by the printer in response to a command sent from your program to the printer via stdout.

    + +

    The cupsBackChannelRead() function reads data from the printer via the backend. You provide a timeout in seconds along with a buffer pointer and the size of that buffer. It returns the number of bytes or -1 if there was an error. The following code example shows how to poll for back-channel data in your program:

    + +
    +#include <cups/cups.h>
    +
    +char buffer[8192];
    +ssize_t bytes;
    +
    +/* Use a timeout of 0.0 seconds to poll for back-channel data */
    +bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
    +
    + +

    If you are writing a backend, the cupsBackChannelWrite() function sends any back-channel data you have received from the printer to upstream filters in the print filter chain. We recommend using a timeout of 1.0 seconds:

    + +
    +#include <cups/cups.h>
    +
    +char buffer[8192];
    +ssize_t bytes;
    +
    +/* Use a timeout of 1.0 seconds to give filters a chance to read */
    +cupsBackChannelWrite(buffer, bytes, 1.0);
    +
    + + +

    Using the cupsSideChannel APIs

    + +

    The cupsSideChannel APIs allow your filters, drivers, port monitors, and backend to send and receive the following out-of-band commands:

    + +
      + +
    • CUPS_SC_CMD_SOFT_RESET - Do a soft reset
    • +
    • CUPS_SC_CMD_DRAIN_OUTPUT - Drain all pending output
    • +
    • CUPS_SC_CMD_GET_BIDI - Return bidirectional capabilities
    • +
    • CUPS_SC_CMD_GET_DEVICE_ID - Return the IEEE-1284 device ID
    • +
    • CUPS_SC_CMD_GET_STATE - Return the device state
    • + +
    + + +

    Sending Commands from a Filter, Driver, or Port Monitor

    + +

    The cupsSideChannelDoRequest() function is used by filters, drivers, and port monitors to send a command to the backend and read back a response:

    + +
    +cups_sc_status_t cupsSideChannelDoRequest(cups_sc_command_t command,
    +                                          char *data, int *datalen,
    +                                          double timeout);
    +
    + +

    The CUPS_SC_CMD_SOFT_RESET and CUPS_SC_CMD_DRAIN_OUTPUT commands do not return any data values, while the others return one or more bytes. The timeout parameter allows your program to poll or wait for the command to complete - use a timeout of 30 seconds for CUPS_SC_CMD_SOFT_RESET and CUPS_SC_CMD_DRAIN_OUTPUT and a timeout of 1 second for all other commands.

    + +

    CUPS_SC_CMD_GET_BIDI returns a single char value that tells you whether the backend supports bidirectional communications:

    + +
    +#include <cups/sidechannel.h>
    +
    +char data;
    +int datalen;
    +cups_sc_bidi_t bidi;
    +cups_sc_status_t status;
    +
    +/* Tell cupsSideChannelDoRequest() how big our buffer is... */
    +datalen = 1;
    +
    +/* Get the bidirectional capabilities, waiting for up to 1 second */
    +status  = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, &data, &datalen, 1.0);
    +
    +/* Use the returned value if OK was returned and the length is still 1 */
    +if (status == CUPS_SC_STATUS_OK && datalen == 1)
    +  bidi = (cups_sc_bidi_t)data;
    +else
    +  bidi = CUPS_SC_BIDI_NOT_SUPPORTED;
    +
    + +

    CUPS_SC_CMD_GET_DEVICE_ID returns a string of characters containing the IEEE-1284 device ID for the connected printer:

    + +
    +#include <cups/sidechannel.h>
    +
    +char data[2049];
    +int datalen;
    +cups_sc_status_t status;
    +
    +/* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for nul-termination... */
    +datalen = sizeof(data) - 1;
    +
    +/* Get the IEEE-1284 device ID, waiting for up to 1 second */
    +status  = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, data, &datalen, 1.0);
    +
    +/* Use the returned value if OK was returned and the length is non-zero */
    +if (status == CUPS_SC_STATUS_OK && datalen > 0)
    +  data[datalen] = '\0';
    +else
    +  data[0] = '\0';
    +
    + +

    CUPS_SC_CMD_GET_STATE returns a single char value that tells you the current device state:

    + +
    +#include <cups/sidechannel.h>
    +
    +char data;
    +int datalen;
    +cups_sc_state_t state;
    +cups_sc_status_t status;
    +
    +/* Tell cupsSideChannelDoRequest() how big our buffer is... */
    +datalen = 1;
    +
    +/* Get the bidirectional capabilities, waiting for up to 1 second */
    +status  = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE, &data, &datalen, 1.0);
    +
    +/* Use the returned value if OK was returned and the length is still 1 */
    +if (status == CUPS_SC_STATUS_OK && datalen == 1)
    +  state = (cups_sc_state_t)data;
    +else
    +  state = CUPS_SC_STATE_OFFLINE;
    +
    + + +

    Handling Commands in your Backend

    + +

    The cupsSideChannelRead() function is used by backends to read a command from a filter, driver, or port monitor:

    + +
    +int cupsSideChannelRead(cups_sc_command_t &command,
    +                        cups_sc_status_t  &status,
    +                        char *data, int *datalen, double timeout);
    +
    + +

    Backends can either poll for commands using a timeout of 0.0, wait indefinitely for commands using a timeout of -1.0 (probably in a separate thread for that purpose), or use select() or poll() on the CUPS_SC_FD file descriptor (4) to handle input and output on several file descriptors at the same time. Backends can pass NULL for the data and datalen parameters, since none of the commands sent by upstream filters contain any data at this time.

    + +

    Once a command is processed, the backend uses the cupsSideChannelWrite() function to send its response:

    + +
    +#include <cups/sidechannel.h>
    +
    +cups_sc_command_t command;
    +cups_sc_status_t status;
    +
    +/* Poll for a command... */
    +if (!cupsSideChannelRead(&command, &status, NULL, NULL, 0.0))
    +{
    +  char data[2048];
    +  int datalen;
    +
    +  switch (command)
    +  {
    +    ... handle supported commands, file data/datalen/status with values as needed ...
    +
    +    default :
    +        status  = CUPS_SC_STATUS_NOT_IMPLEMENTED;
    +	datalen = 0;
    +	break;
    +  }
    +
    +  /* Send a response... */
    +  cupsSideChannelWrite(command, status, data, datalen, 1.0);
    +}
    +

    Contents

    • Functions
    • @@ -75,6 +246,9 @@ library:

       CUPS 1.2 cupsBackChannelRead()

      @@ -134,5 +308,109 @@ cupsBackChannelWrite(

      Returns

      Bytes written or -1 on error

      + +

       CUPS 1.3 cupsSideChannelDoRequest()

      +

      Description

      +

      Send a side-channel command to a backend and wait for a response. + +This function is normally only called by filters, drivers, or port +monitors in order to communicate with the backend used by the current +printer. Programs must be prepared to handle timeout or "not +implemented" status codes, which indicate that the backend or device +do not support the specified side-channel command. + +The "datalen" parameter must be initialized to the size of the buffer +pointed to by the "data" parameter. cupsSideChannelDoRequest() will +update the value to contain the number of data bytes in the buffer. + +

      +

      Syntax

      +
      +cups_sc_status_t
      +cupsSideChannelDoRequest(
      +    cups_sc_command_t command,
      +    char * data,
      +    int * datalen,
      +    double timeout);
      +
      +

      Arguments

      +
      + + + + + + +
      NameDescription
      commandCommand to send
      dataResponse data buffer pointer
      datalenSize of data buffer on entry, number of bytes in buffer on return
      timeoutTimeout in seconds
      +

      Returns

      +

      Status of command

      + +

       CUPS 1.3 cupsSideChannelRead()

      +

      Description

      +

      Read a side-channel message. + +This function is normally only called by backend programs to read +commands from a filter, driver, or port monitor program. The +caller must be prepared to handle incomplete or invalid messages +and return the corresponding status codes. + +The "datalen" parameter must be initialized to the size of the buffer +pointed to by the "data" parameter. cupsSideChannelDoRequest() will +update the value to contain the number of data bytes in the buffer. + +

      +

      Syntax

      +
      +int
      +cupsSideChannelRead(
      +    cups_sc_command_t * command,
      +    cups_sc_status_t * status,
      +    char * data,
      +    int * datalen,
      +    double timeout);
      +
      +

      Arguments

      +
      + + + + + + + +
      NameDescription
      commandCommand code
      statusStatus code
      dataData buffer pointer
      datalenSize of data buffer on entry, number of bytes in buffer on return
      timeoutTimeout in seconds
      +

      Returns

      +

      0 on success, -1 on error

      + +

       CUPS 1.3 cupsSideChannelWrite()

      +

      Description

      +

      Write a side-channel message. + +This function is normally only called by backend programs to send +responses to a filter, driver, or port monitor program. + +

      +

      Syntax

      +
      +int
      +cupsSideChannelWrite(
      +    cups_sc_command_t command,
      +    cups_sc_status_t status,
      +    const char * data,
      +    int datalen,
      +    double timeout);
      +
      +

      Arguments

      +
      + + + + + + + +
      NameDescription
      commandCommand code
      statusStatus code
      dataData buffer pointer
      datalenNumber of bytes of data
      timeoutTimeout in seconds
      +

      Returns

      +

      0 on success, -1 on error

      diff --git a/doc/help/api-httpipp.html b/doc/help/api-httpipp.html index 43c538560..3d756b672 100644 --- a/doc/help/api-httpipp.html +++ b/doc/help/api-httpipp.html @@ -101,6 +101,7 @@ require CUPS 1.1 or higher.

      HTTP_AUTH_MD5_INT Digest authentication in use for body HTTP_AUTH_MD5_SESS MD5-session authentication in use HTTP_AUTH_MD5_SESS_INT MD5-session authentication in use for body +HTTP_AUTH_NEGOTIATE  CUPS 1.3 GSSAPI authentication in use HTTP_AUTH_NONE No authentication in use @@ -3011,7 +3012,7 @@ typedef enum http_encryption_e http_encryption_

      http_t

      Description

      -

      HTTP connection structure.

      +

      HTTP connection type

      Definition

       typedef struct _http_s http_t;
      diff --git a/doc/help/api-raster.html b/doc/help/api-raster.html
      index 26ea439f4..19262f39b 100644
      --- a/doc/help/api-raster.html
      +++ b/doc/help/api-raster.html
      @@ -87,11 +87,18 @@ information.

      cups_adv_e

      Description

      -

      AdvanceMedia attribute values

      +

      Values

      @@ -114,6 +121,126 @@ information.

      NameDescription
      CUPS_TRUE Logical true
      +

      cups_cspace_e

      +

      Description

      +

      +

      Values

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameDescription
      CUPS_CSPACE_CIELab  CUPS 1.1.19 CIE Lab
      CUPS_CSPACE_CIEXYZ  CUPS 1.1.19 CIE XYZ
      CUPS_CSPACE_CMY Cyan, magenta, yellow
      CUPS_CSPACE_CMYK Cyan, magenta, yellow, black
      CUPS_CSPACE_GMCK Gold, magenta, yellow, black
      CUPS_CSPACE_GMCS Gold, magenta, yellow, silver
      CUPS_CSPACE_GOLD Gold foil
      CUPS_CSPACE_ICC1  CUPS 1.1.19 ICC-based, 1 color
      CUPS_CSPACE_ICC2  CUPS 1.1.19 ICC-based, 2 colors
      CUPS_CSPACE_ICC3  CUPS 1.1.19 ICC-based, 3 colors
      CUPS_CSPACE_ICC4  CUPS 1.1.19 ICC-based, 4 colors
      CUPS_CSPACE_ICC5  CUPS 1.1.19 ICC-based, 5 colors
      CUPS_CSPACE_ICC6  CUPS 1.1.19 ICC-based, 6 colors
      CUPS_CSPACE_ICC7  CUPS 1.1.19 ICC-based, 7 colors
      CUPS_CSPACE_ICC8  CUPS 1.1.19 ICC-based, 8 colors
      CUPS_CSPACE_ICC9  CUPS 1.1.19 ICC-based, 9 colors
      CUPS_CSPACE_ICCA  CUPS 1.1.19 ICC-based, 10 colors
      CUPS_CSPACE_ICCB  CUPS 1.1.19 ICC-based, 11 colors
      CUPS_CSPACE_ICCC  CUPS 1.1.19 ICC-based, 12 colors
      CUPS_CSPACE_ICCD  CUPS 1.1.19 ICC-based, 13 colors
      CUPS_CSPACE_ICCE  CUPS 1.1.19 ICC-based, 14 colors
      CUPS_CSPACE_ICCF  CUPS 1.1.19 ICC-based, 15 colors
      CUPS_CSPACE_K Black
      CUPS_CSPACE_KCMY Black, cyan, magenta, yellow
      CUPS_CSPACE_KCMYcm Black, cyan, magenta, yellow, * +light-cyan, light-magenta
      CUPS_CSPACE_RGB Red, green, blue
      CUPS_CSPACE_RGBA Red, green, blue, alpha
      CUPS_CSPACE_RGBW  CUPS 1.2 Red, green, blue, white
      CUPS_CSPACE_SILVER Silver foil
      CUPS_CSPACE_W Luminance
      CUPS_CSPACE_WHITE White ink (as black)
      CUPS_CSPACE_YMC Yellow, magenta, cyan
      CUPS_CSPACE_YMCK Yellow, magenta, cyan, black
      + +

      cups_cut_e

      +

      Description

      +

      +

      Values

      +
      + + + + + + + +
      NameDescription
      CUPS_CUT_FILE Cut the roll after this file
      CUPS_CUT_JOB Cut the roll after this job
      CUPS_CUT_NONE Never cut the roll
      CUPS_CUT_PAGE Cut the roll after this page
      CUPS_CUT_SET Cut the roll after this set
      + +

      cups_edge_e

      +

      Description

      +

      +

      Values

      +
      + + + + + + +
      NameDescription
      CUPS_EDGE_BOTTOM Leading edge is the bottom of the page
      CUPS_EDGE_LEFT Leading edge is the left of the page
      CUPS_EDGE_RIGHT Leading edge is the right of the page
      CUPS_EDGE_TOP Leading edge is the top of the page
      + +

      cups_jog_e

      +

      Description

      +

      +

      Values

      +
      + + + + + + +
      NameDescription
      CUPS_JOG_FILE Move pages after this file
      CUPS_JOG_JOB Move pages after this job
      CUPS_JOG_NONE Never move pages
      CUPS_JOG_SET Move pages after this set
      + +

      cups_mode_e

      +

      Description

      +

      Raster modes

      +

      Values

      +
      + + + + + +
      NameDescription
      CUPS_RASTER_READ Open stream for reading
      CUPS_RASTER_WRITE Open stream for writing
      CUPS_RASTER_WRITE_COMPRESSED  CUPS 1.3 Open stream for compressed writing
      + +

      cups_order_e

      +

      Description

      +

      +

      Values

      +
      + + + + + +
      NameDescription
      CUPS_ORDER_BANDED CCC MMM YYY KKK ...
      CUPS_ORDER_CHUNKED CMYK CMYK CMYK ...
      CUPS_ORDER_PLANAR CCC ... MMM ... YYY ... KKK ...
      + +

      cups_orient_e

      +

      Description

      +

      +

      Values

      +
      + + + + + + +
      NameDescription
      CUPS_ORIENT_0 Don't rotate the page
      CUPS_ORIENT_180 Turn the page upside down
      CUPS_ORIENT_270 Rotate the page clockwise
      CUPS_ORIENT_90 Rotate the page counter-clockwise
      +

      Functions

      • cupsRasterClose()
      • @@ -160,10 +287,6 @@ can make changes to the cups_page_header2_t data as needed to use a supported raster format and then returns 0 on success and -1 if the requested attributes cannot be supported. -cupsRasterInterpretPPD() supports a subset of the PostScript language. -Currently only the [, ], <<, >>, {, }, cleartomark, copy, dup, index, -pop, roll, setpagedevice, and stopped operators are supported. -

        Syntax

        @@ -463,7 +586,7 @@ factor not applied) 
         
         

        cups_page_header_s

        Description

        -

        Version 1 Page Header

        +

        Definition

         struct cups_page_header_s
        @@ -558,7 +681,6 @@ struct cups_page_header_s
         
         
        @@ -578,14 +700,6 @@ typedef int (*cups_interpret_cb_t)(cups_page_head
         typedef struct cups_page_header2_s cups_page_header2_t;
         
        -

        cups_page_header_t

        -

        Description

        -

        Version 1 Page Header

        -

        Definition

        -
        -typedef struct cups_page_header_s cups_page_header_t;
        -
        -

        cups_raster_t

        Description

        Raster stream data

        diff --git a/doc/help/license.html b/doc/help/license.html index 224a39386..96881559d 100644 --- a/doc/help/license.html +++ b/doc/help/license.html @@ -131,6 +131,48 @@ Products grants the following special exceptions:

        derived work.

        +

        Kerberos Support Code

        + +

        The Kerberos support code ("KSC") is copyright 2006 by Jelmer +Vernooij and is provided 'as-is', without any express or implied +warranty. In no event will the author or Easy Software Products +be held liable for any damages arising from the use of the +KSC.

        + +

        Sources files containing KSC have the following text at the top +of each source file:

        + +
        This file contains Kerberos support code, copyright +2006 by Jelmer Vernooij.
        + +

        The KSC copyright and license apply only to +Kerberos-related feature code in CUPS. Such code is typically +conditionally compiled based on the present of the +HAVE_GSSAPI preprocessor definition.

        + +

        Permission is granted to anyone to use the KSC for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following +restrictions:

        + +
          + +
        1. The origin of the KSC must not be misrepresented; you + must not claim that you wrote the original software. If + you use the KSC in a product, an acknowledgment in the + product documentation would be appreciated but is not + required.
        2. + +
        3. Altered source versions must be plainly marked as + such, and must not be misrepresented as being the + original software.
        4. + +
        5. This notice may not be removed or altered from any + source distribution.
        6. + +
        + +

        Trademarks

        Easy Software Products has trademarked the Common UNIX diff --git a/doc/help/ref-client-conf.html b/doc/help/ref-client-conf.html index 20eac9629..90207ba72 100644 --- a/doc/help/ref-client-conf.html +++ b/doc/help/ref-client-conf.html @@ -38,16 +38,16 @@ encryption settings for the client.

         ServerName foo.bar.com
         ServerName 11.22.33.44
        +ServerName foo.bar.com:8631
         

        Description

        -

        The ServerName directive specifies sets the -remote server that is to be used for all client operations. That -is, it redirects all client requests to the remote server.

        +

        The ServerName directive specifies sets the remote server that is to be used for all client operations. That is, it redirects all client requests to the remote server.

        -

        The default is to use the local server -("localhost") or domain socket, if so configured.

        +

        The default port number is 631 but can be overridden by adding a colon followed by the desired port number to the value.

        + +

        The default is to use the local server ("localhost") or domain socket, if so configured.

        diff --git a/doc/help/ref-cupsd-conf.html b/doc/help/ref-cupsd-conf.html index ff8058cd5..8e07d0620 100644 --- a/doc/help/ref-cupsd-conf.html +++ b/doc/help/ref-cupsd-conf.html @@ -236,6 +236,7 @@ HREF="#Require">Require directive instead.

        AuthType Basic AuthType Digest AuthType BasicDigest + AuthType Negotiate </Location>
        @@ -260,12 +261,15 @@ authentication to perform:

        should be performed using the /etc/cups/passwd.md5 file +
      • Negotiate - Kerberos authentication + should be performed
      • +
      -

      When using Basic, Digest, or -BasicDigest authentication, clients connecting -through the localhost interface can also -authenticate using certificates.

      +

      When using Basic, Digest, +BasicDigest, or Negotiate authentication, +clients connecting through the localhost interface can +also authenticate using certificates.

      The AuthType directive must appear inside a Location or DefaultAuthType Basic DefaultAuthType BasicDigest DefaultAuthType Digest +DefaultAuthType Negotiate

      Description

      @@ -1184,6 +1189,20 @@ system-specific but is usually lp or nobody.

      +

      CUPS 1.3GSSServiceName

      + +

      Examples

      + +
      +GSSServiceName IPP
      +GSSServiceName HTTP
      +
      + +

      Description

      + +

      The GSSServiceName directive specifies the Kerberos service name that is used when passing authorization tickets. The default name is IPP.

      + +

      CUPS 1.1.10HideImplicitMembers

      Examples

      diff --git a/doc/help/spec-ipp.html b/doc/help/spec-ipp.html index 47a2a5ac5..fb5b1ebc2 100644 --- a/doc/help/spec-ipp.html +++ b/doc/help/spec-ipp.html @@ -11,7 +11,7 @@ CUPS IPP specification for the Common UNIX Printing System (CUPS). - Copyright 1997-2006 by Easy Software Products. + Copyright 1997-2007 by Easy Software Products. These coded instructions, statements, and computer programs are the property of Easy Software Products and are protected by Federal @@ -359,6 +359,10 @@ Print-Job request:
      +
      "auth-info" (1setOf text(MAX)):CUPS 1.3 + +
      The client OPTIONALLY supplies one or more authentication values as specified by the "auth-info-required" attribute. +
      "job-billing" (text(MAX)):CUPS 1.1
      The client OPTIONALLY supplies a billing string that is logged @@ -423,6 +427,16 @@ Response:
      +

      Group 3: Unsupported Attributes (status=client-eror-attributes-or-values-not-supported) + +

      + +
      auth-info-required (1setOf Type2 keyword) + +
      The required authentication information. + +
      CUPS 1.1Create-Job Operation

      The Create-Job operation (0x0005) creates a new, empty print job. @@ -452,6 +466,10 @@ Create-Job request:

      +
      "auth-info" (1setOf text(MAX)):CUPS 1.3 + +
      The client OPTIONALLY supplies one or more authentication values as specified by the "auth-info-required" attribute. +
      "job-billing" (text(MAX)):CUPS 1.1
      The client OPTIONALLY supplies a billing string that is logged @@ -514,6 +532,16 @@ Create-Job Response:
      +

      Group 3: Unsupported Attributes (status=client-eror-attributes-or-values-not-supported) + +

      + +
      auth-info-required (1setOf Type2 keyword) + +
      The required authentication information. + +
      CUPS 1.1Set-Job-Attributes Operation

      The Set-Job-Attributes operation (0x0014) changes the attributes of @@ -604,7 +632,7 @@ subscription for printer or server event notifications. CUPS provides several additional events in addition to the standard events in the IPP notifications specification.

      -

      Request

      +

      Create-Printer-Subscription Request

      The following groups of attributes are supplied as part of the request:

      @@ -657,7 +685,7 @@ request:

      -

      Response

      +

      Create-Printer-Subscription Response

      The following groups of attributes are send as part of the response:

      @@ -864,6 +892,10 @@ CUPS-Add-Modify-Printer request:
      +
      "auth-info-required" (1setOf type2 keyword):CUPS 1.3 + +
      The client OPTIONALLY supplies one or more authentication keywords that are required to communicate with the printer/remote queue. +
      "job-sheets-default" (1setOf name(127)): CUPS 1.1.7 @@ -1109,6 +1141,10 @@ CUPS-Add-Modify-Class request:
      +
      "auth-info-required" (1setOf type2 keyword):CUPS 1.3 + +
      The client OPTIONALLY supplies one or more authentication keywords that are required to communicate with the printer/remote queue. +
      "member-uris" (1setof uri):
      The client OPTIONALLY supplies the "member-uris" set @@ -1608,6 +1644,16 @@ CUPS-Authenticate-Job request:
      +

      Group 2: Job Attributes + +

      + +
      "auth-info" (1setOf text(MAX)):CUPS 1.3 + +
      The client OPTIONALLY supplies one or more authentication values as specified by the "auth-info-required" attribute. + +
      +

      CUPS-Authenticate-Job Response

      The following groups of attributes are send as part of the @@ -1629,6 +1675,16 @@ CUPS-Authenticate-Job Response:

      +

      Group 2: Unsupported Attributes (status=client-eror-attributes-or-values-not-supported) + +

      + +
      auth-info-required (1setOf Type2 keyword) + +
      The required authentication information. + +
      Attributes

      CUPS provides many extension attributes to support multiple @@ -1641,7 +1697,7 @@ classes.

      operation and enumerate all of the available hardware devices and network protocols that are supported by the server.

      -

      device-class (type2 keyword)

      +

      device-class (type2 keyword)

      The device-class attribute specifies the class of device and can be one of the following: @@ -1661,24 +1717,24 @@ one of the following:

    -

    device-id (text(127))

    +

    device-id (text(127))CUPS 1.2

    The device-id attribute specifies the IEEE-1284 device ID string for the device.

    -

    device-info (text(127))

    +

    device-info (text(127))

    The device-info attribute specifies a human-readable string describing the device, e.g. "Parallel Port #1". -

    device-make-and-model (text(127))

    +

    device-make-and-model (text(127))

    The device-makr-and-model attribute specifies a device identification string provided by the printer connected to the device. If the device or printer does not support identification then this attribute contains the string "unknown". -

    device-uri (uri)

    +

    device-uri (uri)

    The device-uri attribute specifies a unique identifier for the device. The actual format of the device-uri string depends on the value @@ -1726,13 +1782,17 @@ of the device-class attribute:

    Job Template Attributes

    -

    blackplot (boolean)

    +

    auth-info (1setOf text(MAX))CUPS 1.3

    + +

    The auth-info attribute specifies the authentication information to use when printing to a remote device. The order and content of each text value is specifed by the auth-info-required printer attribute. + +

    blackplot (boolean)

    The blackplot attribute specifies whether HP-GL/2 plot files should be rendered entirely in black ink (blackplot=true) or using the colors and shades specified in the file (blackplot=false). The default value is false. -

    brightness (integer(0:200))

    +

    brightness (integer(0:200))

    The brightness attribute specifies the overall brightness of the printed output in percent. A brightness of 100 is normal, while 200 is twice as @@ -1741,24 +1801,24 @@ bright and 50 is half as bright. The default value is 100.

    Brightness is applied to the Cyan, Magenta, Yellow, and Black values using the function "f(x) = brightness / 100 * x". -

    columns (integer(1:4))

    +

    columns (integer(1:4))

    The columns attribute specifies the number of columns to generate when printing text files. The default value is 1. -

    cpi (type2 enum)

    +

    cpi (type2 enum)

    The cpi attribute specifies the number of characters per inch when printing text files. Only the values 10, 12, and 17 are currently supported. The default value is 10. -

    fitplot (boolean)

    +

    fitplot (boolean)

    The fitplot attribute specifies whether to scale HP-GL/2 plot files to fit on the selected media (fitplot=true) or use the physical scale specified in the plot file (fitplot=false). The default value is false. -

    gamma (integer(1:10000))

    +

    gamma (integer(1:10000))

    The gamma attribute specifies the luminance correction for the output. A value of 1000 specifies no correction, while values of 2000 and 500 will @@ -1768,17 +1828,17 @@ generate lighter and darker output, respectively. The default value is

    Gamma is applied to the Red, Green, and Blue values (or luminance for grayscale output) using the function "f(x) = x(1000/gamma)". -

    hue (integer(-180:180))

    +

    hue (integer(-180:180))

    The hue attribute specifies a color hue rotation when printing image files. The default value is 0. -

    job-billing (text(MAX))CUPS 1.1

    +

    job-billing (text(MAX))CUPS 1.1

    The job-billing attribute provides a text value to associate with a job for billing purposes. -

    job-hold-until (keyword | name(MAX))CUPS 1.1

    +

    job-hold-until (keyword | name(MAX))CUPS 1.1

    The job-hold-until attribute specifies a hold time. In addition to the standard IPP/1.1 keyword names, CUPS supports name values of the form @@ -1787,7 +1847,7 @@ Greenwich Mean Time (GMT) and not in the local time zone. If the specified time is less than the current time, the job is held until the next day. -

    job-sheets (1setof type3 keyword | name(MAX))CUPS 1.1

    +

    job-sheets (1setof type3 keyword | name(MAX))CUPS 1.1

    The job-sheets attribute specifies one or two banner files that are printed before and after a job. The reserved value of "none" disables banner printing. @@ -1797,7 +1857,7 @@ The default value is stored in the job-sheets-default attribute. If two values are supplied, the first value is used as the starting banner file and the second as the ending banner file. -

    job-originating-host-name (name(MAX))

    +

    job-originating-host-name (name(MAX))

    (CUPS 1.1.5 and higher) @@ -1809,19 +1869,19 @@ resolution is enabled. The localhost address (127.0.0.1) is

    This attribute is read-only. -

    lpi (type2 enum)

    +

    lpi (type2 enum)

    The lpi attribute specifies the number of lines per inch when printing text files. Only the values 6 and 8 are currently supported. The default value is 6. -

    mirror (boolean)

    +

    mirror (boolean)

    The mirror attribute specifies whether pages are mirrored on their X axis, which is useful for printing transfer images on special media. The default value is false. -

    natural-scaling (integer(1:1000))CUPS 1.1.9

    +

    natural-scaling (integer(1:1000))CUPS 1.1.9

    The natural-scaling attribute specifies the scaling of image files with respect to the natural image size. A value of 100 specifies that the image file should exactly the natural size, while 50 is half the natural size @@ -1830,7 +1890,7 @@ and 200 is twice the natural size. The default value is 100.

    The ppi option can be used to override the natural resolution of the image, which controls the natural size. -

    number-up-layout (type2 keyword)CUPS 1.1.15

    +

    number-up-layout (type2 keyword)CUPS 1.1.15

    The number-up-layout attribute specifies the order each input page is placed on each output page. The following keywords are presently defined: @@ -1855,7 +1915,7 @@ presently defined: -

    page-border (type2 keyword)CUPS 1.1.15

    +

    page-border (type2 keyword)CUPS 1.1.15

    The page-border attribute specifies whether a border is draw around each page. The following keywords are presently defined: @@ -1874,44 +1934,44 @@ defined: -

    page-bottom (integer(0:MAX))

    +

    page-bottom (integer(0:MAX))

    The page-bottom attribute specifies the bottom margin in points (72 points equals 1 inch). The default value is the device physical margin. -

    page-label (text(MAX))CUPS 1.1.7

    +

    page-label (text(MAX))CUPS 1.1.7

    The page-label attribute provides a text value to place in the header and footer on each page. If a classification level is set on the server, then this classification is printed before the page label. -

    page-left (integer(0:MAX))

    +

    page-left (integer(0:MAX))

    The page-left attribute specifies the left margin in points (72 points equals 1 inch). The default value is the device physical margin. -

    page-right (integer(0:MAX))

    +

    page-right (integer(0:MAX))

    The page-right attribute specifies the right margin in points (72 points equals 1 inch). The default value is the device physical margin. -

    page-set (type2 keyword)

    +

    page-set (type2 keyword)

    The page-set attribute specifies which pages to print in a file. The supported keywords are "all", "even", and "odd". The default value is "all". -

    page-top (integer(0:MAX))

    +

    page-top (integer(0:MAX))

    The page-top attribute specifies the top margin in points (72 points equals 1 inch). The default value is the device physical margin. -

    penwidth (integer(0:MAX))

    +

    penwidth (integer(0:MAX))

    The penwidth attribute specifies the default pen width in micrometers when printing HP-GL/2 plot files. The default value is 1000 (1 millimeter). -

    position (type2 keyword)

    +

    position (type2 keyword)

    The position attribute specifies the location of image files on the media. The following keyword values are recognized: @@ -1943,26 +2003,26 @@ media. The following keyword values are recognized: -

    ppi (integer(1:MAX))

    +

    ppi (integer(1:MAX))

    The ppi attribute specifies the resolution of an image file in pixels per inch. The default value is the resolution included with the file or 128 if no resolution information is available. -

    prettyprint (boolean)

    +

    prettyprint (boolean)

    The prettyprint attribute specifies whether text files should be printed with a shaded header and keyword highlighting (prettyprint=true) or without additional formatting (prettyprint=false). The default value is false. -

    saturation (integer(0:200))

    +

    saturation (integer(0:200))

    The saturation attribute specifies the color saturation when printing image files. A saturation of 100 is normal, while values of 50 and 200 will be half and twice as colorful, respectively. The default value is 100. -

    scaling (integer(1:1000))

    +

    scaling (integer(1:1000))

    The scaling attribute specifies the scaling of image files with respect to the selected media. A value of 100 specifies that the image @@ -1971,7 +2031,7 @@ image dimensions. The default value is unspecified.

    The scaling attribute overrides the ppi attribute if specified. -

    wrap (boolean)

    +

    wrap (boolean)

    The wrap attribute specifies whether long lines should be wrapped (wrap=true) or not (wrap=false) when printing text files. The default @@ -1979,32 +2039,32 @@ value is true.

    PPD Attributes

    -

    ppd-device-id (text(127))

    +

    ppd-device-id (text(127))

    The ppd-device-id attribute specifies the IEEE-1284 device ID string for the device described by the PPD file.

    -

    ppd-natural-language (naturalLanguage)

    +

    ppd-natural-language (naturalLanguage)

    The ppd-natural-language attribute specifies the language encoding of the PPD file (the LanguageVersion attribute in the PPD file). If the language is unknown or undefined then "en" (English) is assumed. -

    ppd-make (text(127))

    +

    ppd-make (text(127))

    The ppd-make attribute specifies the manufacturer of the printer (the Manufacturer attribute in the PPD file). If the manufacturer is not specified in the PPD file then an educated guess is made using the NickName attribute in the PPD file. -

    ppd-make-and-model (text(127))

    +

    ppd-make-and-model (text(127))

    The ppd-make-and-model attribute specifies the manufacturer and model name of the PPD file (the NickName attribute in the PPD file). If the make and model is not specified in the PPD file then the ModelName or ShortNickName attributes are used instead. -

    ppd-name (name(255))

    +

    ppd-name (name(255))

    The ppd-name attribute specifies the PPD filename on the server relative to the model directory. The forward slash (/) is used to @@ -2012,31 +2072,47 @@ delineate directories.

    Printer Attributes

    -

    job-k-limit (integer)CUPS 1.1

    +

    auth-info-required (1setOf type2 keyword)CUPS 1.3

    + +

    The auth-info-required attribute specifies the authentication information that is required for printing a job. The following keywords are recognized:

    + +
      + +
    • domain - A domain name is required.
    • + +
    • none - No authentication is required - this keyword can only appear by itself.
    • + +
    • password - A password is required.
    • + +
    • username - A username is required.
    • + +
    + +

    job-k-limit (integer)CUPS 1.1

    The job-k-limit attribute specifies the maximum number of kilobytes that may be printed by a user, including banner files. The default value of 0 specifies that there is no limit. -

    job-page-limit (integer)CUPS 1.1

    +

    job-page-limit (integer)CUPS 1.1

    The job-page-limit attribute specifies the maximum number of pages that may be printed by a user, including banner files. The default value of 0 specifies that there is no limit. -

    job-quota-period (integer)CUPS 1.1

    +

    job-quota-period (integer)CUPS 1.1

    The job-quota-period attribute specifies the time period used for quota calculations, in seconds. The default value of 0 specifies that the limits apply to all jobs that have been printed by a user that are still known to the system. -

    job-sheets-supported (1setof type3 keyword | name(MAX))CUPS 1.1

    +

    job-sheets-supported (1setof type3 keyword | name(MAX))CUPS 1.1

    The job-sheets-supported attribute specifies the available banner files. There will always be at least one banner file available called "none". -

    printer-type (type2 enum)

    +

    printer-type (type2 enum)

    The printer-type attribute specifies printer type and capability bits for the printer or class. The default value is diff --git a/doc/help/spec-pdf.html b/doc/help/spec-pdf.html new file mode 100644 index 000000000..862eb0cb6 --- /dev/null +++ b/doc/help/spec-pdf.html @@ -0,0 +1,21 @@ + + + + CUPS PDF Format + + + + +

    CUPS PDF files (application/vnd.cups-pdf) are device-dependent +PDF/A files that contain a job ticket information. These files +are typically produced by the CUPS pdftopdf filter +which handles job ticket generation, imposition, page labeling, +scaling, and other formatting options requested by the user. CUPS +PDF files are intended for direct consumption by a PDF-capable +printer, PDF RIP, or the pdftops filter.

    + +

    More information will be posted here as the PDF workflow +filters are added to CUPS.

    + + + diff --git a/doc/help/spec-postscript.html b/doc/help/spec-postscript.html new file mode 100644 index 000000000..7e9f9a802 --- /dev/null +++ b/doc/help/spec-postscript.html @@ -0,0 +1,120 @@ + + + + + Generating PostScript for CUPS + + + + + + +

    Introduction

    + +

    This document describes how to generate PostScript output for +CUPS and is largely based on the +Adobe TechNote #5001: PostScript Language Document Structuring +Conventions Specification Version 3.0. While CUPS can +generally print any PostScript file, following the rules in the +Adobe TechNote and this document will ensure that your PostScript +output will work reliably.

    + +
    Note: While PostScript is currently the +defacto-standard print job file format/language for UNIX-based +applications, it is slowly being phased out in favor of Adobe's +Portable Document Format ("PDF") which offers many advantages +over PostScript. MacOS X uses PDF as the primary print job file +format, and we expect Linux to soon follow. Both PostScript and +PDF are complex formats, and we highly recommend using high-level +toolkits whenever possible.
    + +

    Anatomy of a PostScript File

    + +

    PostScript files are ASCII text files starting with a header +line (%!PS-Adobe-3.0) followed by a combination of +comment lines starting with two percent signs (%%) and +PostScript code lines. The lines themselves should not exceed 255 +characters to conform to the DSC. The following short PostScript +file produces a box with a smiley face in it:

    + +
    +%!PS-Adobe-3.0
    +%%BoundingBox: 36 36 576 756
    +%%Pages: 1
    +%%LanguageLevel: 2
    +%%EndComments
    +%%Page: (1) 1
    +% Draw a black box around the page
    +0 setgray
    +1 setlinewidth
    +36 36 540 720 rectstroke
    +
    +% Draw a two inch blue circle in the middle of the page
    +0 0 1 setrgbcolor
    +306 396 144 0 360 arc closepath fill
    +
    +% Draw two half inch yellow circles for eyes
    +1 1 0 setrgbcolor
    +252 432 36 0 360 arc closepath fill
    +360 432 36 0 360 arc closepath fill
    +
    +% Draw the smile
    +1 setlinecap
    +18 setlinewidth
    +306 396 99 200 340 arc stroke
    +
    +% Print it!
    +showpage
    +%%EOF
    +
    + + + + +

    Embedding Printer Options

    + + +

    Embedding Fonts and Text

    + + +

    Embedding Images

    + + +
    Note: While some printers support arbitrary +binary data in PostScript files, we do not recommend this +practice because it does not work with all printers or +interfaces. In most cases, the Base-85 encoding and compression +filters can be used to embed images with very little, if any, +increase in data size.
    + + + + + diff --git a/doc/help/spec-ppd.html b/doc/help/spec-ppd.html index 4e5569a04..16c054544 100644 --- a/doc/help/spec-ppd.html +++ b/doc/help/spec-ppd.html @@ -8,11 +8,11 @@ - What's New in CUPS 1.2 + What's New in CUPS 1.3 -

    CUPS 1.2 adds over 90 changes and new features to CUPS 1.1.x. +

    CUPS 1.3 adds over ??? changes and new features to CUPS 1.2.x. This page provides a high-level outline of these changes. If you have never used CUPS before, read the "Overview of CUPS" document instead.

    -

    Changes in CUPS 1.2

    +

    Changes in CUPS 1.3

    Networking
      -
    1. IPv6; CUPS now supports IPv6 - connectivity when the host operating system - provides it
    2. +
    3. Kerberos; CUPS now supports Kerberos authentication
    4. -
    5. Domain Sockets; CUPS now supports - the much faster UNIX domain sockets for local - printing
    6. +
    7. Mac OS X Improvements; CUPS now supports the Authorization Services framework, providing role-based access control in addition to the tradition UNIX model
    8. -
    9. Auto-SSL; CUPS now automatically - detects when a client is connecting with SSL - encryption, so it can support both unencrypted, - SSL-encrypted, and TLS-encrypted connections over - a single port
    10. +
    11. ;
    12. -
    13. Network Printer Discovery; CUPS can - now find printers on the LAN using SNMP
    14. +
    15. ;
    16. + +
    17. ;
    @@ -40,40 +33,13 @@ HREF="overview.html">"Overview of CUPS" document instead.

    Browsing
      -
    1. LDAP Support; CUPS now supports - printer sharing via the Lightweight Directory - Access Protocol, version 3
    2. - -
    3. Printer Lease Times; The server's - BrowseTimeout value is now included
    4. - -
    5. Network Default Options; The server - now advertises a printer's default options such - as job-sheets, media, and so forth
    6. - -
    7. Network Default Printer; CUPS now - advertises server-default printers so that - clients can choose the correct default network - printer
    8. - -
    9. "Delete Printer" Message; CUPS now - sends a final "delete printer" message to all - clients when a printer is deleted, allowing for - extremely long BrowseTimeout values without - side-effects
    10. - -
    11. BrowseLocalOptions and - BrowseRemoteOptions Support; You can - configure CUPS to use specific IPP options for - local and remote printers, for example to - compress print jobs that are sent over a slow WAN - link
    12. - -
    13. BrowseLocalProtocols and - BrowseRemoteProtocols Support; You can - configure CUPS to use different protocols for - advertising local shared printers and discovering - remote shared printers
    14. +
    15. CUPS Browsing; The default configuration now shows shared printers from any address (not just @LOCAL)
    16. + +
    17. ;
    18. + +
    19. ;
    20. + +
    21. ;
    @@ -81,92 +47,19 @@ HREF="overview.html">"Overview of CUPS" document instead.

    Web Interface
      -
    1. Improved Look and Feel; The web - interface has improved readability and a more - consistent design
    2. - -
    3. New Searchable On-Line Help; The - on-line help has been reorganized into - categorized articles and references and can be - searched
    4. - -
    5. Add This Printer; The administration - page offers a new Add This Printer - button for automatically-discovered printers, - making printer configuration even easier than - before
    6. - -
    7. Export Printers to Samba; The - administration page now offers an Export - Printers to Samba button and function which - allows administrators to export printer drivers - to Windows clients via Samba
    8. - -
    9. Change Settings; The administration - page offers a new simple server settings form for - controlling common configuration settings such as - printer sharing and remote administration
    10. - -
    11. Edit Configuration File; The - administration page now provides a form for - editing the cupsd.conf file from your - web browser
    12. - -
    13. View Log Files; The administration - page now provides access to the - access_log, error_log, and - page_log log files
    14. - -
    15. Searchable Classes, Jobs, and - Printers; the class, job, and printer pages - can now be searched and shown in ascending or - descending order, with the results displayed in - groups of 10
    16. - -
    17. Links for Class Members; When - viewing a printer class, we now provide - hyperlinks to each of the class members - - previously only the names were shown
    18. - -
    19. Print Self-Test Page; When the - printer driver supports the CUPS command file - format, you can now print the printer's self-test - page
    20. - -
    21. Clean Print Heads; When the printer - driver supports the CUPS command file format, you - can now clean the printer's heads
    22. - -
    23. Set Default Options; You can now set - the default options for a printer, including the - new operation and error policies (the previous - incarnation of this was confusingly called - "Configure Printer")
    24. - -
    25. Set Default Printer; You can now - make a printer the default printer on the - network
    26. - -
    27. Set Allowed Users; You can now set - the list of users and/or groups that are allowed - or not allowed to access a printer or class
    28. - -
    29. Cancel All Jobs; You can now cancel - all jobs on a printer or class
    30. - -
    31. Move Job; You can now move an active - job to a different printer or class
    32. - -
    33. Move All Jobs; You can now move all - active jobs to a different printer or class
    34. - -
    35. Per-Printer Sharing; You can now - share (Publish) or hide (Unpublish) printers - individually
    36. - -
    37. Show All Jobs; You can now view all - jobs in addition to just the active or completed - jobs
    38. +
    39. Internet Printer Sharing; You can now share printers over the Internet via the basic server settings
    40. + +
    41. Improved On-Line Help; Searching the on-line help now shows results for all text, not just headings and links
    42. + +
    43. Printer Setup; The Add This Printer button now allows you to change the default name, location, and description
    44. + +
    45. ;
    46. + +
    47. ;
    48. + +
    49. ;
    50. + +
    51. ;
    @@ -174,99 +67,17 @@ HREF="overview.html">"Overview of CUPS" document instead.

    IPP Support
      -
    1. IPP Notifications; CUPS now supports - the complete IPP notification specification to - provide asynchronous event notification to - clients and users
    2. - -
    3. ippget Notification Scheme; CUPS now - supports the required ippget pull - method for event notification, allowing - applications to receive events asychronously
    4. - -
    5. mailto Notification Scheme; CUPS now - supports mailto recipients as - proposed by the Printer Working Group, allowing - users to receive event notifications via - email
    6. - -
    7. CUPS Extensions to IPP - Notifications; CUPS adds several server - events (start, stop, restart, and audit) that can - be monitored via the IPP notification - operations
    8. - -
    9. CUPS-Get-Printers Improvements; The - CUPS-Get-Printers operation now returns all - queues by default and filters the results based - on the requesting-user-name - attribute
    10. - -
    11. Proxy Authentication; CUPS provides - the new CUPS-Authenticate-Job operation to - support proxy authentication of print jobs
    12. - -
    13. Unique Job IDs; CUPS maintains a new - job-uuid attribute which provides a - unique identifier that can be used to track a job - on your network or anywhere in the world
    14. - -
    15. port-monitor; CUPS now supports the - per-printer port-monitor and - port-monitor-supported attributes - for device-specific data/transport encoding
    16. - -
    17. printer-op-policy; CUPS supports new - printer-op-policy and - printer-op-policy-supported - attributes which provide per-printer fine-grained - access control policies
    18. - -
    19. printer-error-policy; CUPS supports - new printer-error-policy and - printer-error-policy-supported - attributes which provide per-printer control over - job error handling
    20. - -
    21. printer-is-shared; CUPS supports a - new printer-is-shared attribute - which provides per-printer sharing
    22. - -
    23. printer-state-change-time; CUPS now - tracks the last time and date of a change to the - printer configuration, enabled/disabled state, or - accepting/rejecting state
    24. - -
    25. printer-uri-supported; CUPS now - reports the IP address or hostname used by the - client in the printer-uri-supported - attribute - this prevents hostname resolution - issues on complex networks
    26. - -
    27. requested-attributes; CUPS now fully - supports limiting of attributes by name or group - - previously CUPS would only limit common - attributes and did not support attribute group - names
    28. - -
    29. Default Job Template Attributes; - CUPS now supports arbitrary default job template - attributes and applies them to print jobs as - needed
    30. - -
    31. which-jobs; The Get-Jobs operation - now supports a which-jobs value of - "all" to return all jobs regardless of state
    32. - -
    33. document-format-supported; The - document-format-supported attribute - now reflects the formats that are actually - supported by the printer
    34. - -
    35. printer-type; The - printer-type attribute now provides - bits for "not shared", "authenticated", and - "supports commands"
    36. +
    37. Printer Defaults; The document-forma-default, notify-events-default, and notify-lease-duration-default attributes can be set for each printer and class
    38. + +
    39. Server-Side Options; Server-side default options can now be retrieved using the "printer-defaults" group keyword
    40. + +
    41. ;
    42. + +
    43. ;
    44. + +
    45. ;
    46. + +
    47. ;
    @@ -274,106 +85,13 @@ HREF="overview.html">"Overview of CUPS" document instead.

    Scheduler
      -
    1. Remote Printer Caching; The scheduler - now maintains a remote printer cache so that - remote printers are not lost when the scheduler - or system is restarted
    2. - -
    3. Job Caching; The scheduler now - maintains a job cache so that completed jobs do - not need to be loaded into memory all of the time - - jobs are loaded and unloaded automatically for - optimum performance and memory usage
    4. - -
    5. Other Performance Improvements; - Thanks to new CUPS API interfaces, the schedule - now uses less memory, less CPU, and scales to - even larger installations
    6. - -
    7. Improved Logging; CUPS now logs the - IPP operation and status in in the - access_log file
    8. - -
    9. Policies; CUPS now provides - per-printer and server access control policies - based on IPP operations in addition to the - traditional location-based access control - available in previous releases
    10. - -
    11. DefaultAuthType; In conjunction with - the new policy support, CUPS now supports a - default authentication type that is used for IPP - operations requiring a username
    12. - -
    13. DefaultEncryption; When - authenticating a request, CUPS now uses the - DefaultEncryption setting in - addition to any location or policy encryption - setting in effect
    14. - -
    15. Per-Printer - document-format-supported; CUPS now - maintains per-printer - document-format-supported attributes - that reflect the formats that can be printed by a - particular printer
    16. - -
    17. Server-side Default Options; CUPS - now supports server-side default options for each - printer or class that are applied to new - jobs
    18. - -
    19. POSIX ACL Support; CUPS now uses - POSIX ACLs, when available, to allows multiple - system groups to be used for local certificate - authentication
    20. - -
    21. RunAsUser Removed; The insecure - RunAsUser mode has been removed in favor of OS - mechanisms such as SELinux
    22. - -
    23. Launchd Support; The schedule now - supports running via the MacOS X launchd program, - delaying cupsd startup until needed
    24. - -
    25. Dynamic Device Lookup; The scheduler - now queries the backends for devices as - needed - no more restarting to get new devices!
    26. - -
    27. Dynamic PPD/Printer Driver Lookup; - The scheduler now scans for PPD files and/or - printer drivers as needed - no more restarting - after installing drivers, and PPD files can be - generated dynamically!
    28. - -
    29. Port Monitor Support; CUPS now - supports "port monitor" filters between the - printer driver filters and backend to do printer- - and device-specific encoding and transport - functions.
    30. - -
    31. Multi-File Job Improvements; CUPS - now sends multi-file jobs in a single connection - to the printer or remote server, preserving the - order of jobs
    32. - -
    33. Environment Variable Support; The - scheduler now supports setting environment - variables for filters and CGI programs via the - Apache PassEnv and - SetEnv directives
    34. - -
    35. Improved CGI Support; The scheduler - now supports more of the CGI/1.1 - specification
    36. - -
    37. Log Files; Log files are now - accessible via HTTP requests using the - /conf/log/filename resource
    38. - -
    39. Power Management; The scheduler now - responds to power management events from the - operating system (currently MacOS X only)
    40. +
    41. Client Support; The scheduler now uses poll(), epoll(), or /dev/kqueue on platforms that provide them to support large numbers of clients
    42. + +
    43. ;
    44. + +
    45. ;
    46. + +
    47. ;
    @@ -381,16 +99,13 @@ HREF="overview.html">"Overview of CUPS" document instead.

    LPD Client Support
      -
    1. Performance Improvements; CUPS no - longer loads every available printer before - accepting a print job
    2. +
    3. ;
    4. + +
    5. ;
    6. -
    7. Banner Support; Banner pages can now - be requested by an LPD client, with server-side - overrides as desired
    8. +
    9. ;
    10. -
    11. Multi-File Support; CUPS now creates - a single IPP job for multi-file LPD jobs
    12. +
    13. ;
    @@ -398,17 +113,13 @@ HREF="overview.html">"Overview of CUPS" document instead.

    Localization and Internationalization
      -
    1. Command-Line Programs; All - command-line programs are now fully - localized
    2. +
    3. ;
    4. + +
    5. ;
    6. -
    7. Character Set Support; CUPS now - supports a wider range of character sets - including Big5 and Shift-JIS
    8. +
    9. ;
    10. -
    11. Globalized PPD Support; PPD files - can now contain multiple language - localizations
    12. +
    13. ;
    @@ -416,34 +127,19 @@ HREF="overview.html">"Overview of CUPS" document instead.

    Printer Drivers
      -
    1. New Drivers; CUPS 1.2 adds Zebra - CPCL and EPL label printer drivers
    2. +
    3. Side-Channel API; This new API provides out-of-band control of devices
    4. -
    5. Driver Interfaces; CUPS now supports - driver interfaces which allow a driver to - advertise the printers it supports and - automatically generate the PPD file as - needed
    6. +
    7. PJL Support; New cupsPJLCharset attribute controls character set for PJL strings
    8. -
    9. High-Definition Range Color; CUPS - 1.2 adds 16-bit per channel color support
    10. +
    11. HTTP API; The http_t structure is now completely private
    12. -
    13. Raster Compression; The CUPS raster - format has been updated to use data - compression for faster printing
    14. +
    15. Label Printer Driver; Added support for the Intellibar label printers
    16. -
    17. Extended Printer Attributes; The - CUPS raster format has been extended to support - additional per-page printer-specific - attributes
    18. +
    19. ;
    20. -
    21. Back-Channel Data Support; Printer - drivers can now read data back from the printer - device
    22. +
    23. ;
    24. -
    25. Custom PPD Options; PPD files can - now contain options that accept custom - values
    26. +
    27. ;
    @@ -451,86 +147,16 @@ HREF="overview.html">"Overview of CUPS" document instead.

    CUPS API
      -
    1. Thread Safety; All of the CUPS API - is now thread-safe on systems that support POSIX - threads
    2. - -
    3. Performance Improvements; Many of - the existing APIs have been optimized for - speed
    4. - -
    5. Array API; The new array API - provides a generic array container and is used to - implement many of the new CUPS 1.2 features and - performance improvements
    6. - -
    7. Directory API; The new directory API - allows applications to portably list the contents - of a directory
    8. - -
    9. File API; The new file API supports - optionally-compressed file IO and simple socket - communications without the limitations of - stdio
    10. - -
    11. HTTP API; The HTTP API now provides - many new URI and address handling functions, - accessor functions to key http_t - information, write-buffering functions, and large - file APIs
    12. - -
    13. IPP API; The IPP API now provides - functions to encode arbitrary options, add - octetString attributes, create - common IPP requests, convert IPP status and - operation code values to/from strings, and read - and write IPP messages via callbacks.
    14. - -
    15. PPD API; The PPD API has been - updated with new functions to support reading - from CUPS files, localization of globalized PPD - files, emission of arbitrary ranges of options, - custom option support, enhanced JCL support, and - access to all options in the PPD file
    16. - -
    17. Error Handling; The CUPS API now - provides a convenience function to get the full - error message of the last request
    18. - -
    19. Back-Channel API; The new - back-channel API provides backends and filters - with access to information sent back from a - printer
    20. +
    21. Array API; New cupsArrayGetIndex() and cupsArrayGetInsert() functions
    22. -
    - - -
    CUPS Imaging API
    -
      +
    1. Destination API; New cupsRemoveDest() and cupsSetDefaultDest() functions
    2. -
    3. Image API; The new image API - provides access to image files of arbitrary size - and is based on the CUPS 1.1.x private image - filter APIs
    4. +
    5. ;
    6. -
    7. Raster API; The raster API provides - new functions to read and write the version 2 - raster page headers, and a new function to - generate a page header from marked PPD - options
    8. +
    9. ;
    -
    Scripting Support
    -
      - -
    1. PHP Bindings; The PHP language - bindings have been revamped to be more consistent - with the CUPS API and are now officially - supported and installed by default if you have - PHP installed on your system
    2. - -
    diff --git a/doc/images/button-add-rss-subscription.gif b/doc/images/button-add-rss-subscription.gif new file mode 100644 index 0000000000000000000000000000000000000000..07fff27d14d7c6e903583a28bcacf6d8fe6baf07 GIT binary patch literal 717 zc-nLKbhEHboW~%-&?3N)k!p~gWmQ_@(%2B%)*jd089se#^5khntCn}|-m~76&O z9J_z->dP1RKYV)o=il%DBm%{sER0+X0t`9~KmfASf%Tt)N?(8?L&mCgIj{E>=$tRf zUG3!9_uSfsg<(;nkPX|4!^{aTOjB0RKm0M{3q!NZKB08!_{&)lp*A=jPI4f^Joy-zxI*~2)K8o`qkV4n1^)yN zZ+mBct~#C&9!CbosM(xlS?M=K1W1_}pG zY|T7nrdG7zPo)x%5*HKSx+N7mnpSkTKVR_Y0JA=;M@6B{TAi7~_f)N|Kl{AB$<%bA zKH=~=3-xU$_|~UhUKN}DLZ^Rg!Q*e)yO}R8s?K`yYsHC<9G?B%Op9tKb{||TR`LF( zB)j*VbtUXF$_;yzuBYfs4EGJ$B58O%qAlZK!~_P1RU+H^3>BtC9eCB2E>T~y;Q@op zt!>dyR@FX@nI(TGX1bY>io*_;#2#jTfrhLCwx#QZvUy{9w=-}_?H2g!#64f(`2?#c zQJ+doSX~Mh=x@1azU`x@Lu2$yDlo cA?1kDt1BM&>2o}r#%aT*8P1p2%D`X^0I^9-y#N3J literal 0 Hc-jL100001 diff --git a/doc/images/button-cancel-subscription.gif b/doc/images/button-cancel-subscription.gif new file mode 100644 index 0000000000000000000000000000000000000000..aebdb2a9f020348347756160964f1d17db4497a1 GIT binary patch literal 663 zc-nLKbhEHboWdZ&&?3N)k!p~gX<1t0(%2Z<(GfFgO2PE0$t#w1Y~4EN;Gs3gPwlvI z_1J^^*WSE-^y$loKmUIJClM(AWMSlD5Ma<@00NMm4y^waRQd!I88TL_%Xz)8K<9i3 zFE@+jymud144arAJQkE=IGDU3$cV9ZA^#336)AqU;;v7E(^oht|FrmU;{3bj<6mu$ z-WRzpDJLFyeD;Zi*T4TaG&bq8sTiNyV{K6>1$Y{0{=%hbuwt!}qJN@LBsOB>hUzFw3adOhyKkrh0*S+gVe zvM|VQ(G(Uq&>VYh#e+lNRpVxf2_!8@Ubuu|g3X;5cOETgn#4UpYsGSX(YPe*v)D`YNeKJ=l{y{YF8)ey zV2(E2)5IF0x3XJ9j!{6v!Y`YFoqe0>tA+d*ZY=aTCj0k^)5-JEKG$@AT+(i6@?{V@ z!TrIrv5A3E>_E}$1jk0>J2f_TVJjbN?dzIp@GVg1z@f7|S}RwzCNXAR<>!)rSJwQb zi|K^O+9f-8tGL`<^ZVSn8eRS=E{i*?PP?50umR0}w=oqIT zN5+!UhM6i|;g${p4{n^g?s;k2qHnd955KKExnbusDf^t4`ZBFo8yX8#r&zM6iA6Lw aIz%pg&@8Yh;99VnOUA+g3mZ`;25SINJ30;k literal 0 Hc-jL100001 diff --git a/doc/pl/images/button-accept-jobs.gif b/doc/pl/images/button-accept-jobs.gif index 5b8cd5b217b72db7ac0113641d84564d17fa70ea..8013e5de5cd0f6e5b6a6a863fcdf546dcd98f4f1 100644 GIT binary patch delta 649 zc-jGp0(SlL1hWM_M@dFFIbnqW6aa(}005Z)0G$mLq!=EmDK@e?L9stov`1XNTy({5 zht7nc*`T`Px!Ca7=Jn|F`t<$({E%MR- z&vgBs1*wmy?f<}_&=%N<48x>y$&49v$fk}{29G7VhW7Dp zr<0;lovoRN`YIq+-e-J1MG!Ov4+lPfer0AUidQ9o3=2I63=R#50G61VWC0AC0SXQe z3n_mD3=N@<2MrAb01ICUZH@!BDhCd{4-P4unWzg43~Rxj1+xkOw#YFiGYJj?Qvw0I zsMpy5WC_eE3k%m}0S<@+YYz+r2@EJ}xn#L40u2e;*uMb{2)6(Pw*BhHpg=kSwgT#l zktIete^}D(k=P9ZofH8cRMYjqAc20}#0Y=T*sY8_TxtGV1Q1szfW!k2di-&jvLk?u zC?}?b!*Eg^0}B)=NC{MEO$OiqjI4v;fl#4H)?};}Z|A(7D-tx=2%zXt02WoO@miD7 z)h$84!f5!SDI<&|+e~d%v%opHZ#Ttcv1VyWx+q5GWC1f4+-hxLqQE)V)}6DBv8sRU z<6>k20hq6i448n-W&xeckSUx(!MH%66r8}^jY@)3031*mSwPv@6$2bVOz}DN$UL(K z^j2p!=kUBNa=?HI=8KrlnTP>^en9#fcZ-KQfGuD_se;{njZ4v4%usf>RdnXX3k7xQ zyE0vW5S_u_lD6L4e<4CoqcOMlvX&(XDnUXN4bqTD4GlN|VT3<$ jF~WrycIe>>8tUNRha@&)pb;XNFk*=;27!YSApih7bM6v| delta 584 zc-jF-0=NCM1@i+orbSx6tg--tyh&_UZip`;kE`kx&GYZ4G~e02BZK1^yr;j?fSQXsWJk>%MR- z&$Js1WImpC@BhHyET9t+gvg|F=_2Hg%&2rqbB=xwsw}JJ&b%q`Y8MMUcqs8w9Wy9Y z2$jM>W4r7&k?im|sPIC7EddTG0uKWz4QMffe?BEL3Vop{oU@0IF#zn8Gk7F$0whiNpW~&blX>ya)jS z32(v(0@<_A!_RPZ0hNmY1#tikuK)rLCkF=9tJmYl`O)|+j4lau41hb9ER8>O00@m! z7|v2Y6$9QFh!YDy0%x*dtwWekT*HD7gP?y4&>+kKcl_~$rD7G*%PNO#m?aue5*G@R z*y7=P8OBl{lpzPfD6sMY6hsG{vGb>Mg%^e$(YS1(0GOfz+b$i*h@xr7KT^{SNZRwo z4Hyfcq_fE-!6#k^sNq6z5LAgicL}DlFyLSvF9*ABGH90q;5!67QT%)r z5crwfln^19Eu=!Hmj!+R94N(L-RMqlJ3T0@f=^!t4;mN{yuysq0S|y$w0UzuY(Dsw z#hyJ5bkH#n{AqFM!_f-`N|z71BAtcv!Igjr;9Z>s3ANpi$Kcc~$mQ@Wtc(DUzPll5N! diff --git a/doc/pl/images/button-add-class.gif b/doc/pl/images/button-add-class.gif index ce7ea6ccf4c2d6a095df4ad448d17a13805d66b3..ca9b8c616f085e7bdde577ff8eb1e9b71b078ef0 100644 GIT binary patch delta 485 zc-jHw0UG|81ds$hM@dFFIbm1;6aa(}0BB_}ZEHJqb3=Z9Qiq6Qi-}i{l5LljW22ye zt*el@xuMR^zunu>=;z+>@$LNn`;kE`kx&GYZ4G}|02BZK1^yr;j!+>0XsWJk>%MTT z3I%D8r>yUMzX~_e!AC3_SqIzj$O`lZ&QxH)Y$ZpphxWlR>>gCs;K2f`#?=-s3mqgL zUYWTWSItrA^iKr4D;PR=a$$I6dMhP;gkw$v3|wK34Gm@plnw|0d3I0@UU`-em?#OC z2>^cq3JwknIW8uOQf3UN34j5k0A>VK2o9QtoC*ttD7*l^00L$KCw~C}3koo{1Oy5VOm~cV*lxclW(Euk7K{s4t^u)P0R9Cu zL_lBz0=fVOoJK7ciebtgZ2N}bTSh2m(2#%YXCN0EeZY=X1W53!!6_Xy6g6WRh86%@ zzz{^s_JDu@1z<+%8sLoznq@wL4iI3#NivoY)xoIIM+>V(j~ImU<)A14pbZc#Xdu)K zJpp;Ziftf(!72t2Z&GRpLqxShE`;id7R3b+K6qaUuoO6jqrPfJEGfKVRh_^A8t@sj bqJ**KB3EwQz08@#-ykDkbskM4NC*HsGk3a4 delta 493 zc-jH&0TTX@1egRpM@dFFIbmx66aa(}0BB_}Yic@lazcK7QiX+Ei-}j4m1B~XaiyVw zuB?%^wVlAhtI^QF=jPq<^Y8ut{E0XsWJk>%MR- z$3j8g<2mnq@BaV+PGkTYk4T^4R!lmdP}Fi1Z3!HSs`iz8Jyu^-SjNa62MmXUf!Mx; z5ZG9pn!8a02Ot%ZT>*Nb1F*p63!Mm_4d6C$&j1CY2m}z2z@GwV0lc+}1EbahJt`8YLD7KH zK8BGTOd9&oP6}_T8u$VUfWV~&2t+aXs$dWrp(!h<{N}Ni&g<=$Ou=XQwOnuBLo0D?##q> diff --git a/doc/pl/images/button-add-printer.gif b/doc/pl/images/button-add-printer.gif index 0f284487f7a42cd2397f2ccf8fe0bca294ac3a5e..1e099e647ae049ce64d0d697b77fd750b78acb5b 100644 GIT binary patch delta 536 zc-jFN0_Xj^1j7V9M@dFFIbmx66aa(}0BB_}ZEHJqb3=Z9Qiq6Oi-}i^jb@jXW0aV7 zrlW+px}wd_zTMl==;z+>^6mZq{E0XsWJk>%MR- z$3j8g<2mnq@BaV+PILeok4WF)R!ph_MyPBc-BEwb(d)r|FbuoLpfz~F#4@j*n3`h` z2@Zbr)5;H009aP4huRiCXgrrXbcL3h5@tyXa-}apsFd$pUtHV z1EH&>aSJKW0MX6a#oj1|0RaohFTi?(<^m5V^8u++Yykvj+bQ_mnh}teg4L;ay7;Xc z*z6z*2MP!fP|yGg8%f*Djk^W_0fPk#`b~d}<)C0Uf&sxFH2C)KW5|HbRu**0j>a%T z-{#eO5Fi21Ag$1Z@)zspyp!8*H8a4>97;8Fm^El8qlTaW0(jXumP}fLbzhDW1G9An%awDO)fkE=2q#Q1 z%#kBxahe`bZ6N}olNX3T16fz41)xBpVF*A_F*OoOrCE?@;+jP-Shb@xDCr{02->-W a3s2$uhUekPk(?ePLRj+WK57gJ0RTJR1mq_G delta 528 zc-jFF0`L991iJ)1M@dFFIbnDJ6aa(}0BB_}Yic@lazlK3P=<$Ii-}j4m1C2YaipMt zt*el=w3@%bs>{o`=jPq-@$LQp{E0XsWJk>%MR- z&#_RD_;}KM@BcuTASW^ekI1AFWxyGi(5ST498FV?SXR3Ab$`0oW9(QAyub0IeC~aD z@7@ps%LWFC#*P-3+3|XAKz%$Vbt(x9DFF)(WdSJ)4i61om6QZ1V=P~ZSO=8=Ut3)Y z2q=G-4Vj{#S*51{k`D}fEhdL40}hc10RagLCTc;nu%*?@tsU3Yy$OIoC9q=yFh~HvFI9tE6f;B) zAgcje7a~GlX)$y25<)5F(DD2t00Nbyl~{#A;z?>1lT^J{a$u5+DkEIa-aQ*P4$ZuS SD-lgZ#4X{-gV-Pv0suR{4BSuv diff --git a/doc/pl/images/button-add-this-printer.gif b/doc/pl/images/button-add-this-printer.gif index dc00856bd5ec775d88874a9831f743fe70274565..4fa4e4d4ba77682d7b7d2a6c17c7185c1fc88faa 100644 GIT binary patch delta 606 zc-jG80-^oj1c(JaM@dFFIbnJL6aa(}0BB_}ZEHJqb3=Z9Qiq6Pi-}i|l5UrkW2dBr zwzi(Xz^cyAzunu>>FD3^^6mZq`;kE`kx&GYZ4G~V02BZK1^yr;j!+>0XsWJk>%MR- z&$CdF_;}KM@BcuUASXHmkI1A_b-)>yr~vdOl?|%2>#sR_J-!cyf%X`*29IS~w&t~c zI`4Imc#PR*R^YBOV99wfZ!?2DLlA<22@HgRcs_+Kk%>VilqhIY0}Nq#n+*+X2%!!L z0BC*?;&h+TbmH})8*)n}=imX`~HWCF8kibEnY1J5^K|rpIK>~csh%H&qLB{|lQw)DD z{I2VRik#l*GIKa_<(ZosKaSkuhM+I70&VJq0#~kZO%W_;u(+C?dZ8Zt1o|p;8wE{| ztyR$AM4bk*F)}qn{Dd&wFhoq9vZD661%IdmA(wr{Aw=3+2rz&V#-{G!d7O_v;z{}x sy<_}x@P2y(`YyP%ug|}~4E;Dv=id^5;eAJh2+t4)s2~(J5D@|ZJ9+UB;s5{u delta 565 zc-jFq0?Pe}1>gidM@dFFIbn;l{=jPq-@$LQp{E0XsWJk>%MR- z&vcCn1*wmx?f<}_&?eZ448x>y$&?v%$fk5k1wKbrz$3QJ+PXgQkN0|*9g9KuXKtHk zZM6Ce6#I%0*fuaoG8$4rl=>3JwnqV49f(C~q!ymk$hp zDPn()rw5u^DqUa-2q>Hlo?5G0u(AN7r7$LpDFY6c2>}5K3MdH(#{_oB4X0&|3IdUj zD`LZ^)}OB500?uCexKg0;&aK@3)wEFEn)#+4m|?I01cJlD)iH#R2%|;kHtJNViJBE zz;DIBbPF2}EGT4KK8WcQ0vNEM0VaghPPu;(WD#J$j0xVzZS45*n$+U+69ELa^aUO2@@dqgGH@{BqhKH}W5|>NSkP>M zf-VjS1Q39Ls63n20uW$e5CB)NVj7fP@CwC(11Qq2ZR^r6U|woG4Od5ZZDBWpb zkSReITtMB{g*2+c;g}EPfJ;F@lit2|86*IJ`E23Ts{?fY+(HCRFa88^!QDi+3OtN? zJ4CRvMq1%Yj=vxg1v$@7J`P}VE=0QTDuhzMZg(`Uh9Bm@9E D=NgN0X`H?{^kx&GYZ4G~?02BZK1^yr;j?fSQXsWJk>%MR- z&vb3i!9ecgdH=wma7d&Dc%ngZ$!t2GI+F4U5Kx=etF{#t#SD*ZP4IA$x3sY8OjXa= zv|g<7INac@DVm#dr}R#KGJrBi5HSJ{2n}~-dpB-^Tar#CF$f4`dJh8&4+vF`0AXiv zq@sT)3@|i;7JeQ_j>)jzz?do;An1qbfl31?n*tg@O92bin^|L{ii(A56>69|V)&8GL*G_x zuE_DCnhL<11ptKSiR^N4WLJ2tb*mroaR|wHRN+9~z$qfZ9=jFXQG*00#0G*4C|KJ#k+>2-GY-TR-!v&8 z;L?QM?FEJsYAhnpZVEW?z%MFXmLd0wz9v$zRb?c+1uCU=j8nU`;kE`kx&GYZ4H0C02BZK1^yr;j?fSQXsWJk>%MR- z&vb3ycQBCrc;djIa7Zi~Q-PjnaBMoC(CBMNVoI;rtTsj!;T}-%wkB4Ux933LNm&u;~hT{M?liwo-+Fqe%%K7$ub| zDWWsc`W$LRfB|A`3Umu_fPow_18gy{lD25Vl9~kkn}i~-EGxnm*vd}k285bJl&jSk}ra}Ojl=whCEv}Hj z90eo@Vgn)?RAV9{95=>@Q6RwElP*X}rGO(`=^tEI1hAQw)qVM76<`7sV-_d}=vbx- mX=>TU5^KgOr<+PZ;N+Zm<{3mIbuMwIo`43r%MR- zzX3ts<2mnq@B0Cqi0~^Kk3}1ah;#{>P@_^5J3O8}!Na+2UU%AFF6MX~d|}rB`rWO0 zK}bxCaG<-Y@J~`Q?O}Th7YP=Ao!az%Z z0zlq6gifcSk(?gjL!mQ(m7EVYEx1zjXvcpJ6r9lIN{)*K!-yt*`XoUuY-zkU0E-8O zm3?M26Bn5HjQG_mFSQD3c#eIRV(Gp8)yJaMf4r9pErpCyJ}u)>>I$_*xsBl8uV Xa$~RL%Rd4O8Dbf;XKj>6ga80L!;QzZ delta 488 zc-jHz0T=#^1d{|kM@dFFIbm`D6aa(}0003185tBTE-Oz^Jy%&)XJ}?{a&Lfwe~gZc zmzkERs;9BDu)@T_(9+M_-P!y7`jJ5_kx&GYZ4G~N02BZK1^yr;j?fSQXsWJk>%MR- z&ucJ{_;}KM@BctlASW6GkH}>3Mlvd&(CCUOlCmB#tQDo5bz{0%;IaFCX9R`npi&TM zXIR`dgvbn!LU0ZXI8tK*DGp^>JbW!BG7Sa|Dh~t=4-J90*;g^4+tj(jj2oJxnKypMU}Y={Rw*z!m@k zr6Qtepho}#i9G-PoVel@v{VjIiE;og!J7a>jRo~7(P@ku;r2Z|p-$H%jm5k+02>m} z18~{IAyCuifdf1t#ggr^VBQN67q`eck|3sD6?N?Vl@TmRfQExvG)e4YBQGEbY%&~1 eL8Zv#%Y!SE$cwr2kHAEVaP~~Pg$*Jh0028{!Nh+6 diff --git a/doc/pl/images/button-change-settings.gif b/doc/pl/images/button-change-settings.gif index 73de99527d7687050eee99b40815191d6ceb6452..8abeb0774aeb7e0870a6999a202c3000d2f1716d 100644 GIT binary patch delta 581 zc-jF)0=oUg1n>ksM@dFFIbnGK6aa(}0BB_}ZEQSsb3}f9Qig|Li-}i`k7$>bW0skB zr=*3uyQIs_yxrW==;z+>@$CHm`;kE`kx&GYZ4G~U02BZK1^yr;j!+>0XsWJk>%MR- z&$3XE_;}KM@BhG;ASXHmkI1Alb-)>yw80Ka{WV9fz+=lb#0HO8f)S{G!%;L%_X@ZJ z3&%9;eGSM*M7bBJ&-y(>5Hki32xdSJ1Bgi_G64+>DTWOX2?h=hhhQiK3=RzmC=Uh< z4+?)PoTG~g4i65Zrj`H+m9PMz09vR3nrNP&q5!0(sH(NE!Y(E<3J+5c34!>x;yCr2CNPM3X%xX00a%&-Ra=s&#LaU;0cj2PT4R5+8> zl@I_uaRhFWT2)SsqFsw7WkeBRoWlkH7Epf+kU#;ahXn2-ikf)NoGy}R5ehLO@T83Cl#*nIe-(~hC&M1IVGU5fHF1FF!USg1m2^NQ8alq zP)d;i0}I`HnJmEBBBG+`Wn;X+@wcmenUd=Klf{h}^tf#Ck{HEeG}pF-gWNh^QOmLz z)N$s;8LR~$zv?;#I5$7usZkhDfc%Asu8gv44}@jA_wO-CJONLh{FM>o%d2N}9tZaI T@Ph~}2*QQ7j( delta 537 zc-jFO0_Oej1jGbAM@dFFIbnkU6aa(}0BB_}Yic@lazcH5QH6$Hi-}i}l5LljW2K>i zuB?%@wVb}csnF2B=jPq<^Y8ut{E0XsWJk>%MR- z&$KHPWImpC@BhHyOrR4Tgvg|F={n?&%&2rqbB?Bup(8=1Wqse;?)4~}!%7C1g$A@& z?{1I?sUa3}RXd*I=Y1tK1`K@$4Gsu~4hAS;3JwnpJP!yB4-Euta3}60G5}T zqXT~c0uQJI4Q?rqk&~6BjVYvBnCT1}i^?Avy7*#akW$wCYywWCH~QmW5f601s7X)(|En3RNnM8!#4(Gdc8F zf&|NYZDlbiTCbG}q8UTsAk(4%0uY2Dun1*cvuLx`L__j!-kvyM+{9Vd; diff --git a/doc/pl/images/button-clean-print-heads.gif b/doc/pl/images/button-clean-print-heads.gif index 2f45608d8ebb47781af49a95f59a286a0b6a8a1c..0daf9a9ac2c66b59b5f12818924d33af253e6ef3 100644 GIT binary patch delta 903 zc-jGn19<%I2CoM_M@dFFIbps46aa(}0BB_}Y-&1mazcH5QizCMj*n=Um1CBfcc-O> zwY8kU!K=>BzTMl>>FD3^@$LKl`jJ5_kx&GYZ4H0E02BZK1^yr;ju0ULXsWJk>%MR- z&vb3yI3N&YKc2aua7Zi~i2|R|f)ETV&!wJ{}Oj*x4M0Cj7OdIAd$50VED&CLMBD0z^L4zW7O z$}9s64ao(3Y}^l(01dGL53a(@ciEBv1Pl)6+ue;?4+swJD1?Cl8XQ0|u3Wuz>*^q= zcFhrk2jXZgd|(ZR2^b7qEkM9bzyJr39Eg7@&;Z4P1p@xOsQBn=-^h}2v;+WhGNq*e z6#+PM6DuPCMVFS5i`T$VO_c&F61au4VZKUBQ~VpC03HCJK&t{^wunGUa3THWN#&6i z*nKd7yik;GK%4`S0Ho8iz*Soo0T?h4GZ&hxI123CZNaRJqXm89oKSqAq=E!*5(Izl zGZ+Q40+@4JmZLMDo=yMu0a2_&RpU#L14vHMiI%U234=EArdZDR({!{ET5&zD)d0o@f4`OmBC5Z zUji9A;2v=dwJp-&Mv(xYWoz(MwwZq?2LQN&Y9I;zs6s~o@Znr(ixJm=0*ff%Mp<&* zQkZgb#MD`XwD93sPNb1GVTBiZXb33sB}PbWEbI`&L*1oP5(+py&>b`jxb>Mn2PV^< z00oGF7LPuz5Jv*zJb0BWKwSbPS0I|yBaw2Iw~8QqAaKl7rD66^c+7l(RWN@%Z8cOJ z1qc9Hc;NlPrkl5{z(Wj>0g(@enzW0BTis&0JGV#gbKG z(+oTVAojpCD(u4#m{K;d6r2h)u*yT_Ktc$mKW!RGNi1eT3uNakaAON1;D$-jHk#0~9-X%&o*m3k3;QFW^AHIyYQPTO-QkBJH$&W<`-HJdh;Wg+^wx{R4oZXo06Q-qf?xmu delta 837 zc-jF)1G@aL2kr(vM@dFFIbp~E6aa(}0BB_}Y->Aob3=W7QHF+Fmz86dm~^G0f~~BP zwY8kTz^c*F!Q$cA>+0e0^Y8ut`;kE`kx&GYZ4H0O02BZK1^yr;ju0ULXsWJk>%MR- z&vb3ycq|ZPKc2aua7Zi~k1c^uR6shP(5SRl=ryO%jKXOgHWS<0Wc6Rz(fF;x;1|=pz6#;QKbG>I52n!mn~5UBGxi=U<|K_ zYffea5K}<5cx_Z*I+Os&K6AWi9YtDeKmb-Kbf)b269&r_1aKXQXbXS>fVWU6I8(6& zsctC3dLo z($EosatqLU6lJ%uBnIv_2k6}F0Rw8UP&iPk2-&^C034R%ROHr|@? zDq6jOQ{A52djt+_k83`5f&o6ghn;_XGVBmTO)?SfWXNY9@q_?Mbtphh84NTC+$hj> z2O(CVh%$g->OA;Vf&^s3jEP8TxKnpNrKFoG2@nX!NyXVFVN{{ixL76u2ynm}Do%w! ziy9q7iB;lUlB5a>6v>KdWGpwAM%tLR-IEMh6Ob?rB)CR4+d$^fLc0jZ6FqrZrbW*{ z%01JFZ>3#iTL6E=`Qu{qJkS6FZeV%FlWevi!c{l)6@;OlBzi<)EigyJBu5G%K#?{~ zs_3Of1aLr^Ds2}830E9CAr3cUYAOy~dYVFbyyf7<2%(-T>#Ux<+5@4q=BjHEkS-wt PLc0blY^6N-5CQ-@9@SJO diff --git a/doc/pl/images/button-clear.gif b/doc/pl/images/button-clear.gif index e15a4bb3ddd3b399131d94750fdd62ef23aad5bb..9e1c36d36fec58c7adb8e81b7f91c39658b7fd92 100644 GIT binary patch delta 436 zc-jH90ZabX1Kn;@kx&GYZ4G})02BZK1^yr;ju0ULXsWJk>%K4` z5M(``ajx&NV2cNya7aAVg2be5Fjz5N#*vGWNGToxlmM%Q6&%f!z+rgZT!==h@hG4W zjP6U&2wTf@(W~${4IU0v0160lhAbs70S{$x3Tgmg3<_&*0t*fgaRv{aodA=S00@~5 zg))DbnlL6XRGVEB%mb`#*7$j@bGAXbS)E}aSUFh4SaAaMF5jp3}hjNLYK-_ z5Mm_g6Y&8hE4IWe=oDwCr+fJd(&;2n%TQHjARHtzFG0XsWJk>%Qr3?oF0f#CFn5nC+01dDMWdN_Svo3Qkvj|n73UGp$3SJJSEQis|D9$Jj z2-E=3bfbC%4FC(#sj&_?4=n-=#O49$D3lMcDC#@JEnwm(yM%iP`o!55YQeHD0WqZr zaDa_2g2M{LXy^q%f@~_-sY<~o7#9U$SZG~bC1`*wejQU~{bNBRhJXho2f$pRV5Oi2 z^r|>|q@rfeL<|lhz{#K@3laH>C|j~LN*Xmx1lSZJl@5s{NtaZZX@LD6O T*s}nh{t)2_ZP*z1-2M@dFFIblu!6aa(}0BB_}Yic@lb3%T7Qiq6Ni-}i{k!zQgW2&f% zw6vPR!mQ8Fzueo==jPq=^zr@w{E0XsWJk>%Q=NUlnn+1 z4<~Lqq0#(e+wat;^w{`)VIKaQY+H%@d2n*!lmRaTZ&@3}{009jQI05hkO4P7nU{C~b z;6T{HHh~BX8qllMM13o0^t0w*p0z=Kzzs)BunT~KRrEcEDR{6*&dQeMT!_Fmr$r(x x&h|a2nMT_Z0j;)-NWzl^0c1=VI$YsoXwj!Sn%1BR6{?yaBQRAhI^#zO06SJss+s@* delta 294 zc-jFb0one)1JeRMM@dFFIbk&b6aa(}0BB_}YH2xib3=Q3PlbhBi-}i~lx~-mW2>o+ zw6mDN!K=>CzUAcG?d|9B^zi-v{E0XsWJk+X@9K zkEd(jI4aEIk^ex}LFNk@gTvAB_P{k=G}~j^Pz-XqbAj+O5RjLp<+xK z1XMQRcr0qun<%8gl1GpOnSBZjb(L~c zrkYwfjx3OCDGUh&h@=3Qt2Z!SUSpgU-twtDGJE%pF*6|mJ7NuTmjD0& diff --git a/doc/pl/images/button-delete-class.gif b/doc/pl/images/button-delete-class.gif index 934b8d66b5416a52d47b736acd2d9f04d1fd0379..38f69eca1315cc0b0f1cda6236e523d2d78fcfef 100644 GIT binary patch delta 433 zc-jH60Z#tU1Kk5XM@dFFIbl@*6aa(}000318X6WVD=A7#L0@5BZ*gvbf`5&VjGCO8 zsH&&6x3k2?!_m~x+}_*g>E`_Y`;kE`kx&GYZ4G}_02BZK1^yr;j?fSQXsWJk>%MRd z1OsW0r>yUMj|Ml#TTu@K3l9h^Tnq$>Cmf>hyVu;4he5n zr7M4VPGKi~YK#m60}rKH2MH*BCIAEuGpnFq01A;Wr>KIA2U@LMjf<$fIjy*g56USH z2eAhYd&qJM4-8Svj8l5zx6~+(2?>gA;*1OK3B<)P4NHk{2EBa&nw?9dW`KiDeYi{m z;156p13PHIFfeY00tGXc@bVSwk-2AZ1juC~M<$>N16f-n?&?Ko3BeULVi;&(2*HT} z3q-*}fk2)>kSVxu3()6)CIt;}>ReKQCL|aljQN@R0wWANcc^NGAt2ZbC0oO`V9?8j b6(M5N$~a3xs@kwvg9vf^mI{p^Apih7ysoGy delta 419 zc-jG@0bKsw1J46JM@dFFIbmM_6aa(}000318X6TVEh|k=Lt|xPa&vHhfqsmRi=CgG zsjH~7wX(dvyUx(f*xT3U=;i$W`jJ5_kx&GYZ4G~402BZK1^yr;j?fSQXsWJk>%MRt z2Lox3r>yUMF9$c#z(*_^bv4rP$ZRr`BInOxkXiw_*JHIUCJHWr!tqEDuD__3iv|cB zXTV_5j+J2DR9C=wI1ng#09_9R4G#?hEMG2#hl47F1&0bb00v~0FeZ3x01iU|V32x& z2Pc073@i?oTn0IUgs%VxfS0GVwl1wLf~0Vsfx@N1EU}Tp009mt4LQq9zFh--3`@tP z$tkRX4|&+b*xuv5EW9g;DFO{E1kBl_;3RUFvz$L5rKyFREY7$po+GZ z4PFLX;Kyc1l_y(>*jJ}$IfpNRs42=c=Bj=|M?h^_=V*$O{%lO8$`wfv2t>PzMWOVo Nkg#Lx&c diff --git a/doc/pl/images/button-delete-printer.gif b/doc/pl/images/button-delete-printer.gif index f7c6984186825ae6669814888c6557d0d884a8ab..7e5bf74ea00b04d9e70fc801062abe71e1e28af0 100644 GIT binary patch delta 490 zc-jH#0Tup%1eF9mM@dFFIbmo36aa(}000318XFcVD=A7$Lt$fJZg6dYf`5&VjGCO8 zsH&&6x3t8@!qU{y+~3>i>*xIc`;kE`kx&GYZ4G~D02BZK1^yr;j?fSQXsWJk>%MR- zyTL%-<2mnq@AmQtzNP$n9B)uL~6xLT*#J1n;4D8EY#pIblAxpd5 z;bIU1OT(Lh`%3>7_eynWQUwhT4g~-L4=Gy@0}BrbECLG*4UGj31B+TxTMPs!1Pl)j zp?QCqic+8`2ZjkyEhd2~SOH)sij1BN1Dmk`rk!~U0=mOk2MH;&1P)roc>>C2#Snks^l_ZWMgxYNT0qSf!rkJmI(tvr7;DNiHV;THewjK(x9^8Trj5%}&D_)F(Qj8^xBM%;C g@XUph5g8?GR($zJ;LV_c2)QvUv}qYNgoFS9JDU*6761SM delta 470 zc-jHh0V)2K1c3xSM@dFFIbm`D6aa(}000318XFcYEh|h;OHWWeVq{@&ac+NsevFQb znw*)ivah+jxXjMW)z{PD;@|uI`jJ5_kx&GYZ4G~N02BZK1^yr;jt~(5XsWJk>%MR- z&uc)C_;}KM@BctlASWUOkH}>3Mlvd&(CCUOlDYzqgY^OA26ZoQO6*e@T933NvEz~5 z#~}pvek;8KgQGpO_mL%ZD|ieKYba!14+RYm4FW7=2MJ>XjR1*=DF+28jSmcvn3h~( zoG5<>4i5@^EGB{~UJe5Q0cV)8hzKVJ43R1U4r2#9nYaK2qACUrh{T%6q6fPG2$V0a zzqtSoo!ijH-_Xb7$6U(Vndrho>_K%X1BDH=&rfc>n3P_fs!2tm$2#$Z*sB8}n8!&$cEPy0nK|O;5*fr<`P-Ho1 z0aCRgGqV-~kqPR}s#U<|v7o4)2~YszMhuCDya7m{DijIOZcM@dFFIboLo6aa(}0BB_}YiT-kazcK7Qiq6Oi-}i_j%b&aW0aV7 zrlNzox}(p}zueo==jPq;^6vfr`;kE`kx&GYZ4G~y02BZK1^yr;j!+>0XsWJk>%MR- z&vZQt1*wmx?f<}_aJUleLp?CrSP!gk@Q|?q zZ$Nsi_9YyP`1h@6@#q18foOFr2t6zT25xPND0425J`M%~j$Z(dmn}vRFp`mlDxg1o za-x5us57LPG$o&^0}KrfX$uM|4Fn8i3VLa#a(4~{aBXpE0SyR*%FJ-Q3~CPsytuUw z330Lw4%EL`*$x8M3Mf=kU@dq!Im@vr~z1j?i9az z!DPl1U{V~)es_B81Ta*l&5CVWzSQ_{&Vynp0!SnZ%485$Aotx8;GhT6egkr13E=PM zg9ZoDpiL2nY`AG}`DM+x5fTChB9FOLVb#UY6E^K;Ah@yPww=JitI^TH<>cD%^6mZq{E0XsWJk>%MR- z&vb3OLP751dH=wma7cU!cp^h_$!t1{hMn?Bty-_q(eOd!%Dmt!YS4Ii#i_8X_cFWB zDtJpib2}CRfSevrB@{pn2zh8XM-VW4D~f49UIPjYdW(rD2Ma+Cg+V2iEeZ|~3|t73 zDGYxIdT)KIEN22-YG(?meFO}I009dQcZ3fJWeo%0Rex-3IhSb)Oq0ISu|2tZ?AN-MRp0)HGOlFq^6vcp`;kE`kx&GYZ4H0T02BZK1^yr;j*uY$XsWJk>%MR- z&vb3yxGflDKc2aua7Zi~k1~NzWI#Hf(5N)XBQ>Xkz%-|oWo_SDcdHuPsv_4yky1Rm zf;a6kAg=}w7+ton^-*|wbuj}A4i63t2SI-}KQ0LjDGd(=C#6t5I}zfc%VVM0`dOTJt*00&7^rPOu%4}0KftS z2?Y#rP|bms0u2BNXh&}k9R-<$?g;?ofj0#~0nh{x2_U{{bp!@fn1YqNgZQ*EM4F;N z9e7r=98GEwfY*gmYgS!BfD!`)AkFqni{Qb6LfD)VNJs$Q&!{dyLSle5&H+qrsV#q~ znXmu>0z~xznWjJ$wKxJmE7kH~-X5`S6LvBBO{_V1irwl0Xc{&kt|(M56dkA8DFyLn z1(p!gK@@3_^bp=|u zr`aED03N^r2HO?(`F;`i-i7BC699iyx#2e+T>l{cmmUh#*`xq=F~rux_|s1qGxtT>;cXPzzHkdJLAYqd zwzib??YdEz3xgFw5Kxm5Z5ojhyZ9m@ZwzQKk?+3%2TVl2BwQ=-!3YOD?h;HGobbaC LKe59SApih7Titx* delta 615 zc-jGH0+{{L2ayFmM@dFFIboFm6aa(}0BB_}Y->Aob3=T5P=<$Ji-}j4m1C2YaHXPw zt*nu@ww}PjtIp59=H=Y*@$LQp{E0XsWJk>%MR- z&vYFN1*wmx?f<}_aF`P8LdOEfqno10|^a1Gj{<20tXFwL?whQVF`EybZ%&f4-5e)0SgXp zp@4soTV`b{UaTu=2@5Hsr3qz;vJh2n;HBFD8|+C4F`q^ zodR;R0163>2?}Tmimt6GdT9d=Dc|AaD+~z)iYoz#odE|A;E>w*W(8WIHwK+YAXH$oGau-WyeAkWuaJ*O_HSq zC;@2dRczzOmp<35e5pu+*opvxUnvhzlt?kF z0H#9G;0jYTg-jG?nZ9sY4d=F@Y+nv^m*DLS9MCu}=!r9cCNu=XE%OErU%WLAel>qU zU`RpUXiF8nbIiipi2%yrCKiAI@6-p0_jLnsmSBt=ein8NFb@E!USL1f0Vj%-DWCun z)Y&=ta;q|Ka@P920>SMD3QnbJAe`uF2D^1FSPVnN)+K|8(EUPX0ocD;sDu{+S}yq} z0=T~*Aw>|CsIK2TQPA@RmJ#*oC*T`^R~!MscLXL7s9+0x7%0Ls3r4sg4o8Fl06X6b B`CI@1 diff --git a/doc/pl/images/button-help.gif b/doc/pl/images/button-help.gif index d2d4f85307814ff2a5dc8f1053e9183333f333ef..f5e239e0ece00f1da4e6636ab7c777b63fef1178 100644 GIT binary patch delta 329 zc-jF;0k;0@0{j9!M@dFFIbl5j6aa(}0BB_}YH2xhaY1=_OMQJ&i-}i{k!+WhW2d8o zwX~VY%e&Xp#M|1?=jYw_`1Sq&{EM;RsNZJjm@qNCn8>WNBPR4IZZf!@(G! z9)^YkVQ@I40CIG800Ihr3pXZgCf7uD`E3j#x*=j(nu9x-AY8bDgb{`d bmyCD_@r%S61}g>$(__RUjX7fU2mt^)TAqr2 delta 312 zc-jFt0muIQ0_y@jM@dFFIbl5j6aa(}0BB_}Y->AnazcWFSc{2Qmz86cmU6DGk+!y= z!NRQ6(!=22*6Zrv?(ggL_VfM!`;kE`kx&GYZ4-a!AS8|uApmHqu59bJ0zuB>`QCWW z3ba`0z#y(L`w5T86mgVnB5SXQw2=rnojl0xff5`PS7&LP5^w_vhog#m7#NPj+hIVV z)oj2(;dm(OE+%AM4gd%T0RaaHZHNXBjtnS=iHj%;28nwwHcK< diff --git a/doc/pl/images/button-hold-job.gif b/doc/pl/images/button-hold-job.gif index 2ab556492963ccaf8028641cb9f77a858da0ee59..5219e686845c7edad00817d227fae787bd023eda 100644 GIT binary patch delta 667 zc-jG*0%ZM(1;qtDM@dFFIbnkU6aa(}0L=gZ&jSh38X49lDbGVR**`zeSx4VmTH|nW z=!uB!prP-xvi8u=`sC&M?d|>i`H?{^kx&GYZ4G~e02BZK1^yr;ju0UPK&q~6>%MR- z&ve}e0zvMhVE@3Na99)YL#F+i(r zy;p*vYCH<5!{T)?pH%^POKdfPKSmHR1!4ec4PO8X2rqk z4Gw<}lM4?IldTR3s16Sf0A4Ahcn=4s2L-4Hc?`6{X)Fh_w8F$G0}BjxZ3n{+!2ox| z3XN|A&<)lvCNT_O3kU~d17!k)I4PA63z!L-@0D}c6IN_1>4o?~s z2bnwPYKY`Ss!-6Sj&6aG8p|e<^!9y2UVk~Nkf`Nhs)||x?1g|521Py$oP@q7g zSVG1;>C{73O*~3CI{`ZBYYU1+MT);UG4|MyXh6+}PMM9d-m0 zm}a5wDFEOCgbzs5XVn1Y%5Ou=*Z?37#VmBl5RQe@VF3(KRZJmVR~zB9P+?I}hH}r# zUmtv1Kx#92R%MR- z&vdN@1gVdw?f<}_@E6#L48x>y$)p){$fk5k6+TDRZ0wQc(!4UB>!45}REon3teug~ zX!VS}r4=EsKqED93{nj}Ep%-#dVGF>f^}atB`^zr00{^QC;|*90}BrhWdIMMp$80H zqM?5%Zz*Y@1q==cuCOVk4-5q;s4I~ul$HRP0IDdglMWA@xum8lUSJ7wE+#P0C<_1# zCkMX`xC3Xoxe1HHzW@!A1ACz31rOt-EC`w5E7btk+2ttcn(GL11~?m6ub!6!lJdkD zP-fetGYN2=J3!7Ei%n*JCHMuVBRxAv2s-mPEj}-0LYSisYz;))|mkbN;{T@$Iyd>0tKu(b}Iz}2gjP7viFJY-kfeT zOMT7ffov5CdVf~%paFu?no2P^0DS>C7b3_Na-m?S5JEM&Z@+cG&@$CHm`jJ5_kx&GYZ4G~Z02BZK1^yr;j!+>0XsWJk>%MR- z&vYsjWImpC@BhG{OP~`Sgvg|FnL6Z-%wHfmn5F`QXwNxv1s>qAL5q51XM+dJtV)yH zYS-=+s0S7fo|Ziej8}XpZf_`lFGLVC1`h~?fk2Oggfb;E0Syc(2@MYp31tZm3SnR< z2%LYOf(#7~W(cHlo1LGMDQ1_AgR-drp|dEvp8$-U2?h=hxp6KgGNWez23etH4ON1o zCa%u0D}h&{s?8tM%TZhD+aRAM>1ZPL3~~@1Ym8W zzA0WMF0@gVXuvYZgt(L8U$qEu$eRo1U!Eo z09i%6#?Okn!h6~A009Q3Q0t5sZ?CIwSKxT@3f7oWo)~mvGm4bxS*+eAGgCXv6xa!5 zYtEvefq+54Weea0^-uEIih-eqAwugUZwip`z3u~1BJL^DVeBE`6!;`0pn$)G^arv= k=Ywz=p+3I-`vB(Wu#Uff6z@fd(2NRy1R`-m5g`BoJJ*o{%>V!Z delta 562 zc-jFn0?qw^1>FQaM@dFFIbn|g6aa(}0BB_}YiT)jazlcGSc{2QkdbSbm1CNmdZ?y| zwX~YPzp2vF!r|c7>FD3_^Y8ut{E%MR- z&vd;C1gVdw?f<}_5GdG*48x>y$*dW4$fk5k9X>}@;RCqMCc7=(>p?Dqz31d$;czSv z-e3_@Lnz{?v~b`!1Of#Mct9mIfhrAT3ddiIkrY1q}`evVD0lCNpaRECH!`39Kjwca{Rb4JZhH0Rw5pzQDLE4#O%B z!qn8+$O^_O$-#ixfXa|C*DeAK>L>x5EW9o7C=I>a0Q0_JdJp(4PGQ?7zyUvM^#CN) z<0HU=0XGydz!XmfyI}$(Qp^YDqD75lQs{rNmM0{~f#}=bb;&rk$0O%3LPDwBe;Te@{8F-SmnK%xc*HfeH@0H0^WPO+j8F>{dYhPSy4nnPz$3kOGs z{9-UA_Yx9Oe5*LnW(Xz*!I>COa%Dtv<=C@3F#@5s_V3tvb1&f?ym=`&jD!FHJKLe| AfB*mh diff --git a/doc/pl/images/button-manage-jobs.gif b/doc/pl/images/button-manage-jobs.gif index 7aefeddaf30070dba892829e05df8d4a89c46337..f8f6f0d8bca56c717b8e27f68e1f8a8221a425ba 100644 GIT binary patch delta 627 zc-jGT0*w8+1)T*wM@dFFIbnPM@bT>U`u6?*{E%MR- z&vcCn1gVdw?f<}_&?eZ448x>y$&?v%$fhqKol&c{=g1X!c)tbgV?Y}`l;iUGXMXWs zfp|dC=tsB3=1g;3=RzlC=Un@2@aqS4k!ng znJ9k)3k(fo2cQn3D3+L-Z7QyzqX4s~0I92KyqbyymkPdX!keWI2n7udh_)^!GM{z@ zWC#tL3*U(!>16KQiVOvY0=D>@77Xa5V1NP!@Lt$? zL4XqrKWiTR2{7pj3Wxw)UBN?ffkglqr>TGF_z|PVO=SKq8rr01j7W^cke#rUFbGA2 zw-zW+5HTfy1a(pn*vZpe3OqpV9MD-*WQwFImhL?B4rNBBJyF_{T2v7kTQr>tg3-w* z009oZX3gjzkT-aps0c{o>JM7AHKVpoaTl%wxnug;!sGIc;H+Q~idBK*#Q;wNA`5>A zFt>n!1ZmPd9+sl*<-!OAEO6P3vBb{o;`o0o;BvJ}LeiBj8N6{xSKtO|te~)M!F+zX{Ht3)eMnK@+gA_VwUxX!0 NSmB0M;9x`u06XzZ6*d3> delta 655 zc-jGv0&xAE1-S)1M@dFFIbopy6aa(}0BB_}Y-&1nb3}rISc{2QkdkYcm1CNmdZ?y| zwX~bQzp2pC!QtQ5>FD3^^6vfr{E%MR- z&vb3K0zvNMdH=wma7c6scp^h_$!t1_hMn?Bty-EDVPL34AC53;+m|C<_QEqYtH+nyf0OqI3YMp{xZB4hYN+$BqCdGXo0& zECC1&e+h~x2YsRf+ugSZ0RaPR;@aFPcd`Hhwut}-aRCjmh1m${)|vYDhgd;;uu_=w z7NEd`1P#wk1NWj9MTNyyT+5~nOaqR?2w{I~5kSnHYq$R5%u}#x761itkb%s2@L-n# zAXSt+xRV~uAORL6q@{qtr=I{Ust{20Xw8sG8GvJIwAIrTwq5}k&}}5Wj{zL`AoG*# z9|S|GI)!TTDvOIN7OX;*U_iN_L5Cu%dl!X+nJDtEXu!88R5_Utxq*YgC4j&2o<4s7 zybLX(!Zh0+eoFv`0$wZ}6bK*y!A}LpREQ>R8UEXK%U4oHLm06WrA5)S|X diff --git a/doc/pl/images/button-manage-printers.gif b/doc/pl/images/button-manage-printers.gif index f884f7f6068bc69d41e459f06b576d67e2f8db6d..041efc2159eb1745c89e330e5c4ee2a0f4f42b92 100644 GIT binary patch delta 675 zc-jG@0$lxr1PM@bT^V`uF|+{E%MR- z&ve}i1gVdw?f<}_P$<}m48x>y$@Cd?$fhsQq{;|Z8dj=$j$DCe1~1({l3k0QT$v$f3x$?btg4%O*`q zpdiJ+c4yv&8NkrtI*1Pz3{a(DfC2^q6W)Kgl8Qy3We@%Y0r<2a%gRRpc3FYL(&fpJ zD`YY|Q-<6zc6|oIHEI9U5grOHO2 z*PU*BHe=8*#n`S2Besn-6>i#POwFt2;Wz&=kBJj1zO8v~y-Gmta z^+ks9B;b+_0?5MQh$@f}MTVbL=tDTrkjSAIBb?~sj5N{!qYe_*sAG+c7%_r5I|ex- J4n~9k06X#>FxdbA delta 601 zc-jG30;c`V1%m}WM@dFFIbosz6aa(}0BB_}YiT)jb3=W7QHF0XsWJk>%MR- z&vb3OLP751dH=wma7cU!cp^h_$!t1{hMn?Bty-_q(G~dMKD$3KQOxSS9_TdLx)!D# zi@~iuqdSj~8e*|U*~0(<0|^a2G=DINOeHi23@Qz14FrA%kpOCB3=R*IDGHnnV40AT zl$d{QWD0zhmt>=#2q=-Arw^80VhXYVw4Ruj4hX>qelR980}KHy0fc@EhA4X~3Iom! zCEL6%Ggl5P*Q>0;(zk4=#+tuOJ0r4zqty zOxP*LKm!!uJlcSp%7c;tP-c8IGS$&}c_Px0C=(c5R!NdV0UI(30iqft7^NmfZOi1) zz(GldK%~wg86*JkJ17d1%bPb<4MRlKK9`rE#m?P`mhOPL3JHMVANcbsNK8SGfYT68 nztE%4GGe{_`}l{@-*G*^|NkuDfy506$N*@de>orm5dr`^>~Z~F diff --git a/doc/pl/images/button-manage-server.gif b/doc/pl/images/button-manage-server.gif index ba6e31cdc83fe2645602a2a2c3aeb9f2a89111f0..cb6d760478cadf100e87ad8fe82b3a9f5556ced4 100644 GIT binary patch delta 647 zc-jGn0(kwM1+fJ^M@dFFIbn$a6aa(}0BB_}Y->ApbVPl9Qiq6Oi-}i_k7<{cW0skB zr=*3sxuVO=yx!c>>FD3^@$LKl`jJ5_kx&GYZ4G~k02BZK1^yr;j!+>0XsWJk>%MR- z&onI*WImpC@BhFcP@oeXgvg|FNjv0@%wHf%tpc1QSKz_z8mx~2ZSb&~UAtFc9auPc z)G#gZJ=;@6$jtCSnB{kYJtZ;$4GSp=4G#_pC=Uq^3SC?%2#bv<0}Kp{0|=C50E&!` zWGsKAnE(U~4h@a~kPeUlTM8%+1FWvFvbwFWkC%`J4i0`VCNh(71Y(ho373;+WS>htW<_GDu10|^fc1}u>G0?rFEuv7#f zAnE~u6ahF z56MhXghb;C1PtCa6bV4Vn-m1zEhq!+kw~L(fC~M%BI$z$5C17$;75+R0dE=@V1PiY z(yq?{o{c4j98VYqQF*H+ha8}oDjKw9`e4e}lqf0IEklk)0Hc68vPIEAfjkAwF0Ox& zBU!~@6mMPJIQT$;fX@QZITSF7-`<3e2#^kgunlWkct)2lj6#5co!bm8NM{ z9pb%MH}T7(8oIF7=UTZXqJBox@0!CkQ(gdFV0V017BDR)YX44QK`lPy}MgEkGE9jDu8Q hF+zkGcIY7s8s^~Nha}!nU=boHQ{swM+)zXa06S|^1y%q6 delta 627 zc-jGT0*w8!1)T*wM@dFFIboUr6aa(}0BB_}Y-&1mb3=uNSeKP!la_I$p@6Qek+rp( zzQ3u+%emLo#o*u7>gnL{^6mZq`;kE`kx&GYZ4G~#02BZK1^yr;j?f?gXsWJk>%MR- z&vb1I1F4Uv?f<}_aOe{3Lp?Dizh`0~(Rer% z2JqAfsTmUT^l)Ji1Ox>Pa#JNV1qv!{4-5k+4+U)iW@!r!i;XApJ&%zMjRFsi0}Yv$sg96dr?!%i4hFpiFeWnt3#BUo2eXn0Jt=o8&B@CL1_1#B zdeF$qDWeMq!zu^T33$vs2yq4u2LJ{L0OWq=j?F0ZYv&IK0R{a2mKB*HfPph)omdn* zh7d&qhG`bI2ykYU05)!RHRvJ0fg=?I5P^Ral%UZ@6dnFQrZ@>8r6d#-VUF?( zOs)WG-gH>jj~53JVcHzq_AJ_oURbKoli&cJ1PIRQO}g@+(26i{z(^2>g@Xcr4Df$M zkwC19$C14-{)0fXApb3=Z9Qih0Ni-}i}lWv!lW2U2o zwY8kSzp2d4z1`c<=;z+>^6vcq`;kE`kx&GYZ4G~S02BZK1^yr;j!+>0XsWJk>%MR- z&#+LC_;}KM@BhG-ASXHmkI1AFaKIUtvOsSj{ZUnc0W{SdxdM-{*pPf^TL{Nu@IaYk zY}Pv!-=cJ{fIhHr?2dCR4h8}N1a4<}hbw^qb#_A#GX@W2Wr>WK0F6A2k9H+d4GSri z4Gw<@1`dNL0}KxgXRZwmW(x`_4Ft6h2z6!w4P=jIpNPT3Z2$pr;3Z(O;1IF$4t;z&i(f|}rsHINDI$+%8`=~&GA9=q<(Mee>WhtdB0T^JgV8K7Dx;9a*ii_ck1f1UZ#F^2e z0B}+WYEgyYp2%Npqq0FMCoVpF8CgXRAH~pjPFr<=qVq zK4>s^-x~$N>ws<0HaLS-3>HCq(A9;AYj$EROtNnYpWZ^eWCzUYheq1jU4dso;>q|I rHkIUlAI!mvE+gE(-_KtLejM2KCm<1jkq|LLHUlOGxP=Wwga80L<~RO7 delta 549 zc-jFa0^0qD1<(XNM@dFFIbnMM6aa(}0BB_}Y-&1lazcH4QH6zEi-}j4m1C5abfuwz zt*el>wVc1es?X5C<>cG&@$LQp{E0XsWJk>%MR- z&$LjG_;}KM@BhG@y z2$6p&d0$;!aw!UWVqUE)3<)j|2Wzr&mUug&q`)mEe*q4+gaKI!362R0C<${jj*3S%Ik1x^i#m1s9QA)g*b7{@ljP38vBDyeB#LEnSka>QN7{p1 z{4N5_#}Y*|f)ZyDKtKS?!k#K@wUl*qBF2$2Y}5qMZks4)0idB+0B3*#FajD}3)*eL z0Zd)LB27UckbnRK#;HjwG=P8vs1&e+1mnh3h@3ou@>eR8m<6bMa-*u00GBs%SwLC3 z)8ODl0FKWfm{rPwf;jCcpM4>s-k1eNm%x;wXl;u=ek2iw5&%JiDXmdBNIhx96G;k2 nC!x$6N^SszT37KcySZ~JL?D=cPJIgO=q09C-~Ph}kq`hoX0zW` diff --git a/doc/pl/images/button-modify-printer.gif b/doc/pl/images/button-modify-printer.gif index e3d5346630b20235f2014a9b91b194fd3f708bbc..acbb6daac0920e9e49d1c9619da33875b447f9f5 100644 GIT binary patch delta 660 zc-jG!0&D$~1-=D6M@dFFIbn(b6aa(}0BB_}Y->Aob3=Z9Qig|Li-}i_k7$>bW0jb8 zrlW+qyQIv`z1`c<=;z+>^6vfr{E0XsWJk>%MR- z&vY#mWImpC@BhGHP@oeXgvg|FSv%y8%vhi|m?EvQDizx#xdM-{*pPe-TnWcw@IaZf z?bkatr`3DAS70AlICw&LDh>t$0b~GzEQc_PERJ$#KSU5S1`h~Ikb;mkohhG>l0PLf z0S$i(pa=~P2?h=hnE(R}4-AsD4Gm@s3MmZ)yAKI$ZdDDL#m34ixw~h>v2lse$Fd2# zt!`;-)&KztunT}KCNklpwgU+dYYPl04898R0ov4QQw9yjvvFn$QuzZlfEfyV3HqsH z_6DFp00z#aadQjIfPg6I?db)BoC`JyK@orOHw7C20T2F8pbUWEffX}g$Ser?Mp-l- z3=2*}(efpzmY=!pm3mo009O3gq(t>qGlYE$}CRo*UKIct8P%G$Y~J3 zR%&R2J`kG%0fPk#{z+Q<&=y>d9bvE=)lZp8lqy}an}YHTf>w3U*nAaIS+}x-Pd0y4 z9H(0%#s|Toy?n2MuNgO9uu&kOw4t*j6yO>O}SCL6nLme4n(E^xePDJBdV%_e8nx`iT*G)dvGXnq6rMDhlYcXo%xe9n2x zyu3l<@QIWN{&;|)cG0029MNE9jn delta 617 zc-jGJ0+#*01(O9mM@dFFIbn_f6aa(}0BB_}Y-&1mazcE3P=<$Ji-}j4m1C5abEKhx ztgDc0XsWJk>%MR- z&vdN{1*wmx?f<}_@F&=b48x>y$)p){$fk5k6+TB*z#}$jJhs{zxH-0!eZ1GB5m0$) zXI2BzM#arv$70~S%ltD%5HJr82q^~+fGdjt4va%v0RssQJ#avcF(rhRbqxuU3l4g9 z01AJK3|j~cDh!8Tv34m6uqt3*EM*A`DGvv4Ww^A50A6bZcEDR>wJ4|$43{k?gaHl- z0Eq!x3JC!L2?{6)bO8jC4SWCt4t2v}00`^CzPc*yz6w3{@$)O;8ra!4OWrzh0s<`P z^!MK9M255i0We-vcZYBN;f@Eh(1RW*%1pfH!5F9B0pD*a9Aob3=Z9Qi_aak&j)ImUE<{gSfe( z$jiIh*2mx8)$8iv@$&EZ`uF|+{E0XsWJk>%MR- z&#_RD_;}KM@BcuTASWsWkI1AFbt4&<(9~d{3`AE=(d)r|I2Z=#;1MGK;44JDb2AP@;D6I|+s{;xP41c$|qNE6>WT>8?FeZ^Gy9uIvcLNQ?0>J|g zR1XUT1P=mj)}hz~0)GKJEYrlOR0jVrPdlx26A+Y4OTn`2~JF*`1EdGQ{@O)Nvfi*3UdSmAjnxMfC4p$75`;v zOC|tby>nCCsJi0M;#ngHBq(?j4dZ5`zZlq)iJMS@nXJ?SrGNpe1`P~&{&Ju;Uy7$h zlYSvWAfw~Rfeev}&!C^eR_aMuO6zTrGe8BA^LI40emc;TV delta 565 zc-jFq0?Pf|1mFZcM@dFFIbnbR6aa(}0BB_}ZEHJpb3=T5QH6$Gi-}j4m1CKjcdMz4 zwY8kTz^cv9zTn^0>FD3@@$CKo{E0XsWJk>%MR- z&-5x3WImpC@BhFcOrR4Pgvg|FxiaLA%&2r4bB?IBhfLr=U;$cMShjmT&JIQ38(Vl+ zhlT2mS{%e#8W92u4-#^0K3pjS4+JR<~NumA%NYX}Dc0R+R%zry|i4#<1qtc4bG3EVY8 zL14ieaSsW3dp8WCG6yKSJY>-@pgUOr6p(+Kg+hTl0PEgTR8;w|lr|-q8oXI3fPu42 znE(PDhBJ(+2Mmm@xb+GEfd&8=JcO6e0jQRZqW(fKFh;=@3n#u?Kq}EysooU12yg%+ z3p+@~#o2^_WX6pvf5H7l06|xR1(LNaDfFBGeSyG+k@dGDE^S9!lsyT6lQ{tm;-zU& zfbUP-qzK3ynIymft3N= zzz}g&knt8GkE__jN4aww-JX+x^89({=T=5gug?8=_8i5#i&w(DhzMlk(+9axBm@9E DU7h4P diff --git a/doc/pl/images/button-move-jobs.gif b/doc/pl/images/button-move-jobs.gif index 36029ac30866cd37479cbed72319027f08da6abf..4600b780fa4690ca6e08cf687df65f9edef7eb4b 100644 GIT binary patch delta 796 zc-jFR1LOS52E_(FM@dFFIbpT{6aa(}0BB_}Y->Aob3=Z8Qiq6Pi-}i_k7$>bW0skB zrlf_rx}(j`zT@KA@bT>U`uF|+{E0XsWJk>%MR- z&vb3yu~3lwc;djIa7Zi;1wGNh$ZR^F(AR;tj1mU}Yi$tFs=CqX==CT+91H_<@Q4u_ zS+DF7N3o-H+P&r@a{~hk4q!w9YA*r|b#g2SV0kHqc#ANSHAoOJkN^RjjGr!$o?4?$ zC7OSAY+Vlt4uTF2XD9>=4Gjq>4+adb0DH8yxBv+au)-+}xB%I%Mc?t2ty1dwX_YU$dOrWx}U_mZLUgFP3`&1v;Hv@0EFS(PV({)@Y&#?0g4vU4dn*oW2k8hA8kWHZb27m1hTHvl?zK7tXdN+Q$Ps? zf}#sr1xTP^ETyVlmZ?e0$<-oJ#D3fX`{r0A23EgNj5eriq`?5VCiW^AU64|XL7IO= z(W+oUb2RT%wrq~T0yI-ooHUtcLFdm5LMxbz;@Ywwozgl5y(TbMpy!ZHq+ zGhu_^z1NjA^63Xyfs0ru+5-d#pg?|NfwK{cD&}DvOfarkRth`(r$QbpPE*(bpP`|~ zjPt;fMj}RvM_ES?FvN>&Jx&A0YG5EK8vud~nS}xjBt?*shoBH8EL{k4%K}hE5z_zy zJpMyoQAC>g<_jV?1lM&@$CKo{E0XsWJk>%MR- z&vb3yI4l%oKc2aua7Zi~k1T;tbU-?v(5RGl=ryOupeUkfHIXhQl_>#Y4+sslb#;Lb4-7!IxD5nwDGI&6Ch8_00;!LU?dS}w^`XyIEQX5!Cmm$vpyh@0D2nh zFSv*L-uApv&iNq2Veei?fq&GYut0w!fh3^QTFL3k6U~8{+!g?6Eo3LiL1(4lAcS}k zsKRB>SojczaS@Zo0=3~};8O6YAfYi8uGT<@0w#6IWWz>$_iFjs^DBW zTowmT0|@BzWpXTtK#(SQw(wS-F6^ntB$V(e=!Pi{T2`T4kZ^^ed=AK{l^Sy4#R!W& gYU!m}OxnYpn0D%E4uCEpf@YU(CD_z(gBJ9s=(sQ>@~ diff --git a/doc/pl/images/button-print-self-test-page.gif b/doc/pl/images/button-print-self-test-page.gif index bcea1ba01aa6288f82651a3c78fb25110aff8389..1aa3349f10a5544aabc67d62a2d60dc40db136b1 100644 GIT binary patch delta 1035 zc-jFA1oZpI1+oY|M@dFFIbrGm6aa(}0BB_}ZEHJqb3=Z8QizCOjgM%Tm1C8dcc-L< zwY8kV!mQ2CzTMo?=;z+>@$LNn`;kE`kx&GYZ4H0w02BZK1^yr;ju0ULXsWJk>%MR- z&vb3yc&@VoLH?uDZb&Q|kI1A^02CRN(5Q4ut)dLSCp0h{aILtnEieFE$zL%MJ8~@) zDaGR}n8zOFd;T?em{oW!eJ+E4QwR%Rfkr_t2@EL>4+SWQGK(;nE&-H=0GcVBgnmZ{ zYJYzMi7B8vOb{;wc6|;BC<+LddoQe>F1#>>M!%lJI3+IulK_YckN^$?Z;=E50}Kt4 zWe*4r2c)0cUJVD;-*~|(2$BxC%j@kA2Mz264&5l$4-9$M*m&L#0{SULfPsSsxC%{T z@Bj_~c@NmJP!|yw!w0ptLCd!f#lnUF0w{m5w?GIWZVvvaed0ENW1e{PYJDoe&>=*L zuuQgKP-_7KZvqB5SmuCBfd(OQ2GZBkTsQ>_@Hs^XpiY?pLJE}O=5Zf_2MeM(;|btV zQh0lW)*2*0VxOiS8x)9jg22|HDy)VSvWRH_vSvTYrTZvA0BI{8G$4=w>8E{vYXyH+ zOu!p8#d9Cjy$eHUi^6#79I%v((t=vv6ltRtY$-P(t>LOjra%{p0I@u>wxh19X5Rr) zd(88f0hdAE<`Q71uoEWS-)=Y5)t6eG6Lq*K14oMhW5<9fUH@eLclMbm8f0|72l|i# zlN>XE+U`vN2Pe1=2Ul*Dwgyp2023=rGT6rUXs#R84Z;2WJrHe?#CaN zc8sZBCT6x-2AkUD@#dHSlqsVNJ;cBeIRL;1-hKC!gTP@i)=>aWDta^LB#g?If&c|@ z!Ih!{BoO0+@<|3sABP^;R67C&0N@ENdAQ#snQB6*rFd<(2w={P$qgmAv4Dq20nX~_ zezAnJY5}di1gz(6OOBD4TfRl0)@ zLmd&-4IY{bG)I#QIDna|{Gp@{cvW@#Eee`avWQD+20{_DfJ9W1ngD;|?Y=jvd+!S( zcy0XsWJk>%MR- z&vb3yv`~=zc;djIa7Zi~1wE0$$ZR^FP?>?Zj9RbQ>})!+K5AdBSQx&QQ|FcM^=La5 z19MT}_{GxqwjO_H>ECfSd@_SBNDwez0RssQb~A-F2@eU7K#_@l0E>-}gqJrZnJEbi zXa|1{UuR)u3J3tJC~YncjViIQdI1X#ZvlNO3JwnpKLn|7vU;~FrKhQ|%+V;WD5(z( z1hS~ADb=&3TO%phkJ7Hyc|VLLnl8vKeX^664>x%QwqhV8)7uS)BsYpP2VP5m*zqknk z4xkO7X@FxXbgxi!+w>XNw^s+&9Y6qr&KOy%WU(WW8#r*eqV61kK_&6m+tLvlpe6b; z33~17wLqwgG>wP_=7kM&{Kr`V5?)a%<6%@@CEPSdfZJ6ELZ$`;Z;io`gcMdN!y$-R zm_h&uAg1Am7Lrhfg~QAP;)xV;F~W!_w&)@hD)JEFi!|1FVG=xqW8;oIhPFcwApih7 DVrL(5 diff --git a/doc/pl/images/button-print-test-page.gif b/doc/pl/images/button-print-test-page.gif index 57ac13be7778b697bc175e8f748769754a4e9392..8eb7ec39848e3f1c0f5c95cf9e45c269dff08b75 100644 GIT binary patch delta 747 zc-jH$0u=ql1(XIoM@dFFIbodu6aa(}0BB_}Yic@lazcK7Qiq6Pi-}i|l5LljW2dEu zwzZtW!mQ8Fzunx@=;+??^6vcq`;kE`kx&GYZ4G~&02BZK1^yr;j!+>0XsWJk>%MR- z&vb34LP751dH=wma7a`Mc%nmb$!t1-hn?~X2+RgnsumW&qO!&4$hADq0So0=;4?Wkg{dn%7DJG!6Mh5CDUQqKYaI;NZm0V7uNxjp^_q(}+@05Lj^197e&w0tkQ0 zHiyB2%VtbgoD4vjjBj^7tT>v0))apMA(^s*4lyK?U{)1Wso)J5W z3I;my+Y6Uq5=3ov2v8R!w+xBQj|oVb0tr+6kkTpKol=E6Eqqr8F`2C(#t0u-da34` dr<}P1k8H*%=MPCDA;LX#=BX!=I`9wz06V>NJEi~t delta 667 zc-jG*0%ZM^2E_$EM@dFFIbo&%6aa(}0BB_}Y-&1mb3=T5QH6$Hi-}i~m2j7pW2K^k zuB?%^ww}PjtIp27=H=Y*^6mZq`;kE`kx&GYZ4G~>02BZK1^yr;j!+>0XsWJk>%MR- z&vb3eLP751dH=wma7dg9c%nmb$!t2Ehn@0Cty-_D=*ar0b+O=ZtM_`C9gD&38w@BK z4+jI0Vsp)S`%GUwLSS710|^a2G<-I50s#UB4RvAwh}5K3Zx1H0kkOfiwl}A?DTU5uz>+V3CzWt zR}UT?1P&4+um=DiJ!vo4`AQLh4Y+n)@|k~YS5Ae1H*x+LkSk}$fe!)PN_Iq12nEbC zDry3_3BUmYc3)iDj7fmOG(rFt+)^=fh@EXCOR`L`QmV%n0SF)ksREo=RXFQ_1;ELm zxsMG3JaTCiz<>n}bWJjujUPa(vRD#8uvAjst1z0fR3UU{OmKx`wA6?qfPt9h3iE%g zm?>#P01c=vnrpMbC4@SqHb5Xq!6y_84A3M!z;sla22SW}+w+#4h4d(bi?^s~Sbhn5 zx25VBqk~(xF9RUpK=tFL#~C5u3_u5_=72;906S~q B6bJwS diff --git a/doc/pl/images/button-publish-printer.gif b/doc/pl/images/button-publish-printer.gif index c12abe87e6d1bc8ffe9fea6393a8e11384ef64bd..909702fb496c325876a3208094373eb88fc56a1b 100644 GIT binary patch delta 620 zc-jGM0+ap21eOIoM@dFFIbnbR6aa(}0BB_}Y-&1mb3%T8QiOzAi-}i@jb@jXW0jb8 zrlW^6vfr{E0XsWJk>%MR- z&-5x3WImpC@BhFcOrR4Tgvg|FxjN*I%vC^2SP`a3Z0y?O`kW&eVexn@2EGS6HFyBp zD0K|}lE>^cd~f#}I1&N^2@Y#{g>P;F262ZiiZFUEk#~(WL=Z3w3MvW_Zj1oFz$gjIe{q9t z1HZum3JwknJT4}EuPUu*4-Ezi4Z_dr2F(V%&T5?~wZzUT0oKsz7z`l5&(;8ZDChwg z6h|OBgbEl02%u>Qj5b;Tpo6wZzyksLIHG@OprGD02R#1t6$8)=i!E9O(+v`bLXo{i z&}O30Wq_T#ARCRDlY=g#9R?-c^lIQKU(A&Z;h{0gR0RSC3&=c!R<&W)iWXmhMS)Nb zMmpI5j!a;Z<3F@&pqlfTZmP4i4-EXH`_4|@e+?2?Dsb^nAZ&52;Pcp%fk6NU;wpc& zH=tP+#s(bkThRs(nYsWlYX)dJbY1}p9+Q4hWzeDkRbJrOLdHyNXb-^gNZo*7ItL6G z!0d~r-3i{lS1$b43^V}bkBvW9mtcWAzr`DzpjKwn3lTJHoQlGRA9)}YGqSjZ>Bo5T z0&txda!maS5>R>on%{ysfAqP$0LCB)`Tb|$fj=hvbIS*F&-wj2C G0029SVgkhg delta 536 zc-jFN0_Xjf1;YeAM@dFFIbnhT6aa(}0BB_}YiT)jazlK4QH6(Ji-}j4m1C2Ya-^Yv ztg4T-w3@)dtIp27=;z0XsWJk>%MR- z&vYvkWImpC@BhG{OrR4Pgvg|F*)rsg%&2rabB>gcRu-_`&b&-;P2AhP9%#pcr){gq zJ@i98@WEyG84&{84ipS$ZYgr78o%o(i0- zTh1%V4c6EI+W-mI0Sl-vy)0RX3JTE70K&|j0|A7r#PNsG`NaVCS_J5XFCZ))^MuH0 zkYFD{dh`-JbBJ#R7-|(Ma*;S~L4#cnH%@=#A_q+jb^gIT-GhiCfVY2K2q2)PGNZH< z3eZ7YSxhEP01XrjKo;_W&lC<&+9&`_MFRwg7IYyHAix211h*_W01N5>sTuLLTNL(b zRDxSkIG`#3K~WTGag`eo=mn0ZDF|eG+J(U!1uL_*WYAErEVp4v%~>!KjA6da0uW3F zpepFwLz4q2*wujR3lU1G)EFpQ%A-AeN&^Xi;H7FMYhjRp@|p(ck+p*y*yX~?2->-W a3-4V7Lg?Yhsh}=i;&}4sKyDNX0RTHy6yPlY diff --git a/doc/pl/images/button-reject-jobs.gif b/doc/pl/images/button-reject-jobs.gif index a81848bdee5cf3f704a304bd7844cdc16f867010..bcff455807c99e6f26f145a6d10bd587a04ba0a0 100644 GIT binary patch delta 539 zc-jFQ0_6Sv1jYnCM@dFFIbm-A6aa(}0L=gZ&jbn48X49lDbGVR**`zeSx4VjSK()9 z=Y@psprY`#wf4@;`sC&N?e6{k`jJ5_kx&GYZ4G~K02BZK1^yr;jt~(9K&q~6>%MR- z&-6)<_=wVc@BctnASW^ekH{p_fHNXbNx?t~fKpq`QEaeyJQmZ|BODYo3e+)g@bKwi z0|!DNKsd-MbugefT=g>nXgxy^F$)PR2@7I)S3!V}Dp{k?+2MnVKDVm&9va~4=1+xmJZLza*F(z;iJ1Ld}0S&bPoea$>0uG6$ zyi*Gc0s)RH)`9Q4vuw*KzOdqg*$PbeBm#d*&_IB#gJZ<@!60ce#eoG16toGc=4DJ_ zdQu9rDKiE~7l;%wLh#R{9)E*^8B7RH1yX@(Oc6!F%wx8k158;x*pa{%IRWb235Fm* zmnl(;h3n-@4Yy`VZKkH$C3@%>4sIb$(pI-oXM}<#9 zA#<7Fm??2!ROFevw40Q`h|#ml48r=qh+@3+cZcx!OgojfGi_+ d`yMU{I1bpvlm940WP}Oi%A@lOa3e+Jsi`;kE`kx&GYZ4G~h02BZK1^yr;j!+>4K&q~6>%MR- z&vXq3LP74MVE@3Na0nFeLsi|WtUTC2UcmSsl3zv7Vr!UZtl1V#+EBc$EMqF_9~a zDF}f91Ih^~D+j)$ttqjBXe$8-!R0K`o(lmCDC3^j0E;Nw>EGeb-W@PB?L>?R;Zg+f zQjb-$7HAR%1mGZHi-itX4489|7k~t}0Q7%Kk$_yocN6?k0vI4MhM*V@B>iI4tmQ*& zy39F5$U;B@2BE;bp*O3|fO_*3HV{;il+BbkA0Uu<^92q}nzVIls!~M&HY|9)Tgrk# z0+txxvAE-ImYfy5MyB8zwbfGs2nd|HLWZK@Nbn4rtQ8Cb`Sijo9We(4a2$US z>Vgotj|~p%W57VB;Kgd)4lW#TZwnnV(4+#ZP{D%+2nyp;rQ&F<$qL)m@PhSQ69nf* zpV^%MR- z&+ zK~!6f`m5OJ%L{}F1jseFjNjU40H#&DrnP8876TlJL|86hra=J|pdl>4@H(RNq@HGw z3*!b1ie0#Tq3Een3Qe5E_JvH-VTypOR-p(uO92CayY{d);QH}8GXfMi$mZ6Ch^C5W z)C`{F4DYr;#{oRMcOb@zh%nLpyLmfzh=c$DJIXrd AdH?_b delta 570 zc-jFv0>%B^1my%hM@dFFIbnGK6aa(}005Z)0G$mNr5Q4%MR- z&vbkaWIm#G@BhFcET9t+gvg|FsUqZ#%&2twa*n7nfdhf1J$hf-?qyJ{4l9Krs6hM5 z=k(eOt`Q+ahf44ms2V(7ECG5ce10i_HDPo$B{2*FDF_D%h72hWnwlyP1`H1jhye)> z4hereq5y{g1DGq3la-eM1`8_-XaNWg4+~)r1r1+}0Kh5;b1x<_$p8Ti&?p65D+ZRC z2?7BJuaqYT)sz4S4`>F}$ZOKk0MyS7lB*6V2L?C52t38dwTMH3TnsRS4#2ns|5_~w z#3(=*dMOB{7ziL2CWI^~7CeY(7JvlR6lH%J*=fZwW-{YW*ubP}0HB3?V3wTufQLgB z(EvFRaBC1tKQ05v3;>AGK87Td8q0J*Udn(j6cl&`fI$H>5f>y}IuqivLLU)W0*Q@< zRH|07%JK-nD_4F0>CkFq)a^VfzwT#l!hT?3Y7|JkD*2+-O4nJ1U<7pXi!e6t562| z33c2;gls{`S71y&=nC`ahH^s(Kmy8i diff --git a/doc/pl/images/button-restart-job.gif b/doc/pl/images/button-restart-job.gif index 42b7568ecf8b4bea868f7845ed1cce07eab75965..5d5a7c0313339648474e7d695ae7980b4928890d 100644 GIT binary patch delta 786 zc-jFH1MU2c1-k}4M@dFFIbpN_6aa(}0BB_}Y->AoazcK6QizCMj*n@Vm1CBfcc-L< zwX~bS!K=*8z1-W;=;z+>@$CHm`;kE`kx&GYZ4H0402BZK1^yr;ju0ULXsWJk>%MR- z&vb3yuRxIec;djIa7Zi$1wE0$$ZR^F(3XL>j9QC<*&usOaiP=E>p>IKEv0XjXMFg)V}0Z!?KCNDzjL00D<-ZIXJH0F_Q9ktu5@0}Kxg ziw}PVqzWjbrEd)glMe|f4r{3ot8)MZ3=Xg>z?8HAzpE%`0HX~JaSsR%2X~uqZUGGk z%F}MUDbi(k2+a<$$_&hL;t%8~sH)m1y}#uyCZFaDC=9d-4DDwH9-P<*pdSDQ`K0+H z&|nilfpY|~BX9^I0EN6@{Q*#*VE}g2Hkp5-n8Miri}3#14d}LFfCFL$-awlKGEPhY zGaVKPC?MiQPAPtjDbpZ976AeQAU%OfVMe;6Z={tC~`qBW-5^kSL@cta?=e zB{U0YN#o)SO*d!Ie!N{dO+^3(3;+pYvsR^-fb9lxcK!PA@}c0I2nfI%V^Hlx3S-i| zfs}=qsR7_;1qe_TT@g;Wp@`rSI7tHsDwCiJJKU!RDW(jl8jXtpr{OF%!ZrYJ4Px# delta 611 zc-jGD0-XK328{(hM@dFFIbo3i6aa(}0BB_}Y->Aob3=W6QH6$Gi-}j4m1CBeb)}(! zt*nu@ww}PjtIf~9=H=V)^6mZq{E0XsWJk>%MR- z&ve}i1*wmx?f<}_P$<}m48x>y$@Cd?$fk5kRX#^m)uXnhb+f`RjpsTrR0$R1;N=b< zaK|D5mKGr|fg?3=5K;|2GGZ}=K3xL|XLU^_FbxAJ3JD7+0}TKOizo~TC$}<^YfC6t0demDv3q?#6 zGc5vOkO0$0nj}RU+cQL4Bm$TiZ&U% zEEv>UtZ^99jEYGeZRU!qWiBZK2!83ZtFo_6nMBz=otd%HM}1_U%D@rBAV>h9Jf(jS z(4d${1T7ViB!<}~$pvgecGm0{DnNl&t=I|Ky<+N-P}`DXcr>V0{O{EMa}Z%@8B6CKzR9v x=*yFc5=6oG@}Zo?2Xkcv{rvz2NJAHYI*2FWfdZ-wXM_mWAm|`^I2aKE06SUG{hR;* diff --git a/doc/pl/images/button-save-changes.gif b/doc/pl/images/button-save-changes.gif index 2f1fee1704193adc9582f3d1f8d369e915a9b1ae..5056b80beffe421794309faa251eb6b737b03a73 100644 GIT binary patch delta 522 zc-jF90`>iv1hoV`M@dFFIbmr46aa(}0BB_}Y->ApbVPoBQiq6Pi-}i_k7$>bW0jeA zrlW+px}?s|zT@K9@bT^U`S$(){E0XsWJk>%MR- zzd}LY<2mnq@B0Fr=3IGeLD2Oj6G71i91Sf`s3j=NkF2xcky8dE!N(Nvgf03AEWjcZ z0W_jO@E}nOo<2>2^!LtzOo%T(MoQ3UT!9w@;t7~4fLKof3O*84(C3Q)1O2i^MW|xz zijSd08oQcRSW=0O?7*<`g69=0S!M}3Q;O1p6J7ybOq5lU1A8b6O9F=$B2kEXnPxtF zo45gD7a~^vc!{SCs~B`C$n#8zRi0^XdxnE M^&U>c296K_J7Ou-B>(^b delta 493 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 diff --git a/doc/pl/images/button-show-active.gif b/doc/pl/images/button-show-active.gif index 82751977db94cfa4a2431fb6d9ba3212575d5165..ac9d4e05f446d3b64929884a0c20ecbe722b2705 100644 GIT binary patch delta 825 zc-jFu1IGOP1>y!hM@dFFIbp2;6aa(}0BB_}Y->Aob3=Z8QizCNjgM%Tm1CBeccY+y zt*el=wVlAhtIf{6%MR- z&vb3ys9=!%c;djIa7Zl91U-?#$ZR^F&>d;{91Mzqt85T}db?h!$i-Ns77wr>{VF)L zuEAqFmp$O#=A9<3=a

    ?$*uN;j$;%JTZ-so1 z(V!HA1kVHvaFEMEmjZ&;TnTVuL851Z2)KU(Ai$fPE35wMs3>p+0Yy~QaG4Q>rsb09&YTZSI4TL9+( z#Zze#ke&1Fr$}WfT?7dA&85{nV9B8}i!(u5Gq_;3CGeI-I0j%)%w@|4W{Sn%Al-k_ z23bgfLN6P5tXJmN4+7R22-E0bQ2_=A`uJtQ8nt6>C=Rr)(=*Xb6rCTOAZ^;UraP-! zk6W>zbPCz5=McM%+}bxSlj}5BSrx`D%_tNU(_+@^iU8VCXil^MjYP(Yp96rcbvgJ^`>IOALxB5Cd&IU9rmv zV^*2imh13{;CkhRnZkCQT#D(YDNGRr0X%Yg1E`{MDuxoJrm89?r;@Pfs<6h|NfJCPBApih7 DSuJDq delta 723 zc-jHe0xbRF2K)s*M@dFFIbo~-6aa(}0BB_}Y->Aob3=W7QHF0XsWJk>%MR- z&vb3yfKZV9c;djIa7Zl51U-?#$ZR^FPXliWty-_xm2^~mWWCui3OpmH%q!pP!FDVH zYa5y+aQw!t`Srk1B~%OtGhr4H+eH{!$qP zpb1Vaa1Q<;*!MuefB?`?=o6r7po)h9d^LZ7b6{V{Yz_VaBtU?V06GOf%%DTj&)p$V z00In9u+I)XJQrJ_QbB-$D;5i6O{5g`AU6~XCKVkAaKSAyLjjEZxnkMa5 zLD=x(wsFw~ZU^JqiaCb$jv;{H)+~!0!31Dny2Sxu=|-34Z0~7`sNHa9p5=K(AYZfi zd`w^)fP=G{k-s9{I+Tui!|~~Jw?L3_0s#ad08<@CpcKN}c1PjBwBCg%2$Tn)-t=YS z9H+8C;9y@l2eML}_m@I)(uzB){h`hSyr9$A3UwS+*a@mJ zFi9l!ge8tyIRS?mX1xq!9fiwelA;O=h_f1mk;D}lgxfKw;fO4V(3>Srh{fXzKK_VE zB0pAX1YT F06RsmGs6G? diff --git a/doc/pl/images/button-show-all.gif b/doc/pl/images/button-show-all.gif index 0473ee62638671fecb3a840bc9de6167c8f0a551..0bd0388225c1d2d1bccf716023c6da51b23ad176 100644 GIT binary patch delta 851 zc-jF|1FZb52Kxp*M@dFFIbpK^6aa(}0BB_}Y->Aob3=Z9QizCNjgM%Tm1CBfcch?z ztgDc=ww}PjtIf{7%MR- z&vb3yu3(V-c;djIa7Ziy1wE0$$ZR^FP}YvLd=3W105%#M1h}hjbSiQ&6sg5SELgt^ zj;(9(kkP@gha7N+>S=v6J}wCjDGd(=CNDwas zZghVRXaEZdcz>9gDxa>AP9-k^i2#fXh5&I43n>l+00|Bc4y_Fc0J*9T2Xz1h4Gs>? z3=a|0SyOy)796_D(C2nh}b9t7+Cv*z+b*Zh=lbi zm@JR*pKt@(;5-hkQ?dr*9E?2l+l_2hdXOZMF_<~klE5Ndv{-B$Pz+D!C#h`x( zUWw{z25Vf^NS+;xtn_;Vfi<}G^qbk`QcD`c6%04PAV#jV*e z>rtF;v_MT(%Wh<0fn|E+D*K$ohaZ1&D7g3BWCD`PXDdc|#o!Xtm%ShYw` zEcOvlnuI9@^lA#2yy!IN4 dt|WNs>#)S$aB31t2wUv3%n}C$tOy|h06VG8atZ(d delta 772 zc-jF31N;2@2CW7?M@dFFIbpW|6aa(}0BB_}Y->Aob3=W7QHFcG&@$LQp{E0XsWJk>%MR- z&vb3yvQUuxc;djIa7Zi?1wE0$$ZR^FP?&+Yj9RbQY-~CzKD6NPN(=^&WoJ}c<$FEe zjzz$2TcZvPRYJu$SjBcTczS$(Gl4CLEl3bBVgm|!E{Zh*4k-f;11SwZP=G;}n3|lP zF_eEQs4FFoDFI&r3l4E}W+@5?C=G871Zr<@Ee)Fh3JD7+0}UtyyK%q3C{*x&BC$+!E@pq+_)UyKd;|Uk#A9WL;beE7Jq1ADH>LJK~{?Lp6H3II~tA`cuiK#eKL^4V70q_F@sS&7q& zg4qzqz#e2IG>(Co;h2n*IRaVSX9;`=05%Qa$KsK%u^_^2WoSWHm@CL=hFkQt@` zK&rV&n`Mwtg_~KBNT&;SlF7vgbKdFapJ43C1DJpoYA6tBCLsbphc@bH3_2tc0suQR CsY!|e diff --git a/doc/pl/images/button-show-completed.gif b/doc/pl/images/button-show-completed.gif index 5481f4d9a7101bb8e0e948153f9a0da0991e7af1..d27b3074c54f6122418b0e41d9620ade9e908ff5 100644 GIT binary patch delta 883 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 Ph_Lm$xQ`n}LI40e%n;ad diff --git a/doc/pl/images/button-sort-ascending.gif b/doc/pl/images/button-sort-ascending.gif index 5a88283f334ef865cfbf6e24ca1f232cfd7939f4..993cf6a93aee0df7aa31ea9636166b7e70a71e1d 100644 GIT binary patch delta 533 zc-jFK0_y#U1;7M7M@dFFIbn7H6aa(}0BB_}Y-&1mazcH5QHO|Ni-}i{kZPBeW2dEu zwzizl&%fN;(dg&i@$>HZ`u6?*{E0XsWJk>%MR- z&#zFB_;}KM@BcuSASXHmkI1C*fHNwe(CCXfdOfZW2g4wJ4IbUF&N>JL1_?(1YS^&? z+^}>AfjtJPz#Y1m`&lJ+cqm^d0}Bodg9r=`4hV#ZiYN~V4h>leUnzH+E0qodhlz`g zkCcA~hzckMjSY|h0t$|+0Hc#HCW4W*3kd)T3$c3vJHEie01t|Kc%I6lV4uv#!NYjP zlv@N3Cj@v14JZl<0%s`I$u4d#S&j?|YXaTF0s;=2Df1`$$^?|oq(OVe>0iHn_wsRy z(+5BRZVnsPn;1kQA!*G35SYc_pQns{_B?;{#49NDpNKaXe3iJZX!hPCP;L{B+rp!O4vJ==EDyU>A#Yu?(yUhwhiPmH-?Wd|-gU z0;8V>VHKbi09UYk#0p5Thui?RU6H}KVRgkVq=;5VBE>Wf7mi<|9UVMLK;Vu{_gG1K z#ehMqSq^Ibg&`v6A07n51o(x7PMyy_*joOBhGq~FPEgZm&>)VV01RpYp)w-2?BAbx XAoazcZHT8oKSj*w}Wm1CKkdZnU* zuC0={x1hkmtIyBA<>cG(^6vcq`;kE`kx&GYZ4G~w02BZK1^yr;ju0ULXsWJk>%MR- z&vYFN1gVdw?f<}_aF`P8L}5K3a$!$uPUvrDXjvI+}_~g01X8J0}0~;0lX>X;Oz|vz8M41?OQk))iAx- z)&dYT7m{-ELE)f>00*vCm{Z45BMJe@QdEEZh!KDT1l#^(r9&}`;wh09OEzTH2}nX~ zG3q5~mu_Rno*mEWxfc`_iUPgd00kgmK?7kvi>_30Qz66`4p~KegJ&euk}F@mL>KF* zgJ@nast9lZ>^T$-5)4p;rvbyXGFN1M*a8P4npRabIB-JWp@Q%-s&McNU_Aw7Jr;j+ zpp4+Vg8&jJLaJEt*+mHOBnVg!3}Vb?03(w|Xr}6#DG-brrr;DaTb)saX51@u(cHN1 z-F60GHZh|ekq%4HYUlE0wTSC|4LgMhhA67Cx>l)WrLvZ&b7$J+dk}r?%!~YGo`e+j sHH00951{Q-EL=vsr_aB?jQl!a=id^5{0(x%2-6S;sNi=v91#KlJHdhdCjbBd diff --git a/doc/pl/images/button-sort-descending.gif b/doc/pl/images/button-sort-descending.gif index 61c85de29e5f18df35e7a837b823327065ccba1d..fbc5e966dd052c37317b90b7b865d756389ea0da 100644 GIT binary patch delta 584 zc-jF-0=NC41@i^6vcp`;kE`kx&GYZ4G~X02BZK1^yr;j!+>0XsWJk>%MR- z&om$uWImpC@BhFcOP~`Sgvg|F2{`1A%xE$&kj9*&*JHbF7_6?rBPkA#tvl@?Kvg&b zOa#0Y_#(@6yOaolJ*p@He@ug5D0qf0C4PVaVsHZt4-9|_4G#_phmw>i4+#zqTMCGO zh$(*$2o0GAp$I6Jn3{M53=R#mXR5L&0t=!Go0E+#CXAcG01OHM3Jf-b0X)mi&j7=M zRiy)`o|Fj>3j+(*234SrV*;7!+-C&m4k!x?0#qo}&M-V$Tn!3v1Uxt)kj(>9DFhOH z0OtV#Puk90bH~DAIyjb81RyY`41xy+2oQhBbZX<6Y%1{-LYo7mkP18~2`qTf;33RG zg$8ZwHZdKn1}G3Ppx1E>IC}ID;2B5s;>$BAU+`<;GU33LDFV2Gwy+@}ooB>QTmkkc z0F-4sGJJ}nLBz9FRTh+5;24X1&jc92C{GzPeLb&z5oo}Gq_HZ>0?0^MfC5t|8`OMr zG!~@eLF5ML#rM~m3mkS=L>gwp)-5}uI|Y9HWu{xm72hrf+Kgs`1+NeNqG|37s7wuj z`r48#H8B<iGfFqDN%-_x{zHJOMAm7i7yu9n2`JQSxJoo$qhujiMt~2`zWs{y WIh4Df4@PAoazccJTZ@TTmz86dmvpA1gs!cU zwzi$Wz^c&DzvAK8>FM9_^6vfr`;kE`kx&GYZ4G~x02BZK1^yr;ju0ULXsWJk>%MR- z&vY#d1gVdw?f<}_aHtaOL*5bkKdKXsMLpc^xx85{(#bXiD zX+kTIXgnN?gRQ)81XK)sEP`PxZ*X05D@G75XmD#<2Lb^C1`K;YcX}uW4umS8g(;6} zE+v01hj5C6e=GqC4h{;g4+eGsX`v`wg9v^o3~3i}#}3wHNE$tiq_k4xSzkdI*1TFfd`sTqgckj6vWafH0IQ{tav(lH^Gg zG6A$)5fa777pf8oDRu5efB^_F!5m1)-maS{_eJ|NMt}kapPc5>HP9;7XZfBw`Vu3f zAur)#uEcZZ5l3i0G?gf$dQ%a)wdgoQV0d zS#pO*ukC%MR- z&+ti*_=wVc@BctRASWsWkI3Y&fHNv(r>APLO9ckf6>|i8U{&5=I6F=a9@&+y`%RU7 zZ{_=(Rt+JscbvCJ&e3%#C3$TCVGjom27rcG0SOKd3T^}o4+$v(mJ0%I1`Q7e1P+QV zUIBj%1^{#bpAV$~iLVDj2&4*CE+&L4hYJI&jQ|P?0#|Mg1OyMA3kU%S3vRy$mjVgW zEM5qhtAGT?1`YrMVF8`dCkov!QEa_f4+P#|RLt7*0jKxnDDvJY4m2>8Xh$$1%Y-~Y zKqZ9(1j-N$tdYx98-4Mx1oP5Q+ZQiqQ0RZ_6o!>RQw_l;nE_N_L4pL|6g)^~$mL6R zF5JDKxzeA;2Pn$fDDjRbpaCr!0p`JwXhHxnH(1IkvxG$f zr>tPpI)j$2B%qTX7yTqBPXK~bCIX0y*nLTv*G_GGKvfH6xtN-hBksxEEV; a^B!I&IF8%IlVc@xM@dFFIbnAI6aa(}005Z)0G$mNr5P!zDm%MR- z&-8l|WIm#G@BhG{E1(kYVGjs_ z3_O1U35Gl`CVirC36-z_40izpc@GK#0i`Jl2qy>%u>l4TvIPw-4g#LCaJ0$23dH~k zvXBcgC$B1_w9<*J;{X9+4yX>}=#O&`<>H~><^k*g4eQaK$jdU_gK} zn%*=JCO|=$1j26Wq7`h|HIp4v)CoEOX+EAl;n?)W4O@aIGsWpl-E zfz5)Q*qyWCvcu=X*zeZo_2~Tn`;kE`kx&GYZ4G~Z02BZK1^yr;jt~(9K&q~6>%MR- z&vXr(1gVdx?f<}_@D7JPzn1&*T!1OUjp z6`&iQgbn+V67T>8LWLCpAZWlsQV%j07lMC;q$~ipO~Cpb^l*@1TLO**mEi#t@fJo( z6qT6?BMe1DQe@<9WC6*U7?H9X*h^7>fdU1SY#vf7hXFN#d}OZBrlO}!uN3cGc zLGeI<1t7%~=9F2IW`qI~WDew6qXQF*U*zEP@__>dALBr6AgmJROz&)ldPWMZWSDDL zl{PcGwoL^MP>A-mfFoG|$WLs1;3xnSJKDG2-N!pI0Oa`MuY$WJF5llJpcdz delta 563 zc-jFo0?hsV1l|NaM@dFFIbn(b6aa(}005Z)0G$mOr5P-&FhQ_9SF=V_yHj7kUvI{5 zg3N%G)t0y7xY+O4<@D$B`0xGy{E%MR- z&vZ?n1gVdx?f<}_P#D;W3d5vw$+Q)8$fk5k9X?0Z*CU(U0=+>V44fi=tB-U;A^4eV zZ(9)(GskWBE+8;KFxq%Qc{C+;EM5-=3|nMg0}Boh3kCoW2a5~@DFF%&4hlUF1Pl%b zqYi(RhbsvRDv67gD~Kuy2PumWnPrNMw6*~W4U#=CCWf+Q38BaU3kNt0m23fiDGCTD ztjPfc56T4$Eo1@>uF7T1UIzm#)Zvxqu>k8S3Cf(UFek^Z=>7i=i22*&r9qDX<>UqM zvQXTLh6CmK+cH3)3W$vWR8+y>V8R#s#t?tQ$ZVp;jFsFD&Kme;+((oX5dcadKmh|` zE6d1~m8NHmkS`dpOEKVGBVt}Us`_VeQ$jFM9n#7tG37r|2sGVFP?4l70$Eiwy`lAm zfdv&Gr6R)sTTL$su;fhQ6r)YARvL#h;8{QSg9bD0}}xbz06V8@ B?R@|M diff --git a/doc/pl/images/button-stop-class.gif b/doc/pl/images/button-stop-class.gif index 8031731a4599854d145b198dffd905d053e451f3..c1f96cc85bd5223e81abded6cb55c3279d760b86 100644 GIT binary patch delta 581 zc-jF)0=oUZ1n>ksM@dFFIbm@C6aa(}0L=gZ&jJY18X49mD$heS**`zeSx4VnTjOzZ z=!uE$prP-wvG>x^`sC*N?e6{k`jJ5_kx&GYZ4G~M02BZK1^yr;ju0UPK&q~6>%MR- z&vY6H1gVcg?f<}_FeTWD48x>yDKzMi%;<1{QUwN5m2>n8Jig#UcKT>Nu&P0M4B&MG z@PMLGZ5`@tRzS=;uhe-(5Htl32QYqlHHj&Jc_lLe3=35U3=R&53l9zm01pTb378I? z01JN!HVtBimj?xyhX9tb0FEnXl8278nJEYjn4WUMlrbhVqdh4FCkGBGi4P1^M542F z00j&v(*vOj0tyVw&d|3iX9)|9Ys~@A00MqD014ay3koqOGHS9b_N#l!sM7-T`FKToqg9uHjsK;Wc>x z5Gpd77dc>D1@lEr-Ucftk79)-FDVCA6rfJW_^Zy(p%a(p<_PuzjF%iBHHd)0mwhlq zI91d_fmq52mt^)%o^`e delta 530 zc-jFH0`2|q1ib`3M@dFFIbnbR6aa(}0L=gZ&jbq58X49sEzd(V**`zeSx4VmTjO$b z=6`?bkB;!OviH{2`QzmJ?d|^l`;kE`kx&GYZ4G~b02BZK1^yr;jt~(5XsWJk>%MR- z&-5A)WImpC@BhFcET9t^gvg|FxiaLA%&2r4bB?H3*drUVV1)n$mcTrl zr$PXOUBC1=;88E$!Gsl6MDvu9VZ3~e91VYovEa}O1_`?c6kB+YAd3VD+AZ`r2Bk`x zEEa^CS&CJIa1alS0l-xrZ+XkvEkM@(r?RGmHk9TabVf+Hzzd4mcH*!dbu?`sL>O?e6{l`;kE`kx&GYZ4G~f02BZK1^yr;ju0UPK&q~6>%MR- z&vfku0zvMhVE@3NaA*_oLcwC?g2anieFkAoJ z!5-LZRW!7$1Kzv}lwojcY&L;EMi4Xw4+nsQd_aXSkusAtB{KmG3s(mW4i1b94-NTNb`F~{ zCNru&DFr774#|TL3|s&Lsk?Uo1q>+V1E>lD3Jl)h;=g?jy2a-EOtD#$V1bHn0m3CS z7iK`g6bar1SfC)r2`r0R_(2Be!5;vbu!Vmqqo9{?pislI0@v>H$dpvuyj$jNNQASUh$5jr2WP(b<2OZ_%XvkYU z=6`?bkdN@PviR24`QzmJ?Ct*l{E%MR- z&vb3Ofk2S_DBQrHa7Zks1U-?#$ZR^FH3M%6ty-@|=?KehJ*wYeSm=X2&gk(=-JPKu zirnRD(0ScWkCo=*Ig~?;;SR8}4CxwCp=mLca zK!;&C7HS+OoER_O0B9>D&H`{z#kC_2Vg!G{h+_e}aSHqxI5_i=jQ|GzsEu^s2;f5j zDOcKrIIbMUjhPVm!>N*GMM^@`X@ZeMd1hU)Uy3ZLq`k+w^%qRkYk$)2kg|~b@39W*`0g)iVc?oSRpkG5afSQ z5O6Sn!~*;tt!SCviDSg_n5h&dmeer_9IRA|hQ+F diff --git a/doc/pl/images/button-unpublish-printer.gif b/doc/pl/images/button-unpublish-printer.gif index 2842a3e1806fcf40b2d28af24d42f4863783f3dc..fdb48f32de5030ea1c496aae3f532ea25b503bd8 100644 GIT binary patch delta 652 zc-jGs0(1T41hxe|M@dFFIbnwY6aa(}0BB_}Y-&1mazcK7QiFq8i-}i@jb@jXW0jb8 zrlW^6vfr{E0XsWJk>%MR- z&$KKQWImpC@BhG{PoNVWgvg|FDLdqj!az@|3J_KVYIK(Eb$!kejIek-7FX6|P+O}8 z4*(qHhRt7fSbnyz?Op>82?7EM4s0uZdWa}<0S0u8E{}^cij_Y^5HJf0Dhdl~k}-RC zDVKjes4A*0tS}`n0S{>?1P@XK3=Iu#4~7nqro9La4xV#&YXJ=ia&eKSDY?77h6v99 zy#ve5013Q;bcS%-%m4uj4h{=EE+&AtRm$PnY!3|v3JuPu_W0KZkUd)isu8v|(azE9 z#ejgVe)S5X2axqvhP1YgGPvK@#vlfG~TI05nh_P@DrE zFB77Slr7jndxk`wGcYiwubU{08OXOUh%8zFYy~g`(M`se^-wUN87EnTPzL)Yq{`C` z)_Y)4AYibd49{#|PqA(5DI}-5C<-Qs$I>1fl6S~um6@PsPkMn7VneZ4O5d!BVbXtl zoD9(e1N0gspmD>FAVTAu4Ju%Bd1?2=iM@dFFIboFm6aa(}0BB_}YiT)jazcE3QH6(Ji-}i~lyR4pW2K>i ztgDc^6&ls{E0XsWJk>%MR- z&vYFN1*wmx?f<}_aF`P8L59)5HJr61Sx+mT>}aXYj!J%GFt%y2@Q2Kl8QbhgaZu$XQL)3@jdnGiK$+zFwsLHa232@l@usg zN6X;3EdxZ&6Von50E*tMMQm|#B7lwaw4i@L;D}b7le**LG^obV<}071ep1Ofyw(90x>1qKM(Wn>j0qoic&-X#SXg@e2T5Rh*D z8(64{9BNT8Xn3hmWt?kc)%~*BfdYwsoieD#_L$_eZuSHv(|RAob3=Z9QizCNj*n=Um1C8dcBZ3* zwX~bS!K=>Czueo==jPq;^6vcp`;kE`kx&GYZ4H0j02BZK1^yr;j*uY$XsWJk>%MR- z&vb3ycs>gT>5nI!a7Zi~k4T;1Co&|T(5Q3@?U9_+RscE}00Q2u3cMO@Yi2RkDtbM_ zs5c7HfDIlnIkMpJ-qk68e*k(kg*FHd3xiRDcrHM0aD-t41TX;wd6Pr}43&?7f0=Qd zF^7LO4g~_FQlzadOAwnXs6w_!jB2`+Hn=jsfGZ`mDQ|ZV$qoPu3MmZ)yZ{3X4GnVC z51(-d4Gsu=4hPK6D9`|O58u;|4+RVl#A6UF{Yr4ZmC0Xhd;3e@2h;G-M{ zE)y__^9jL&MGJN&idjd1oB$^VJ!nvXzykp+@7*zDQxi@AI$10wkYFYrr2`a@G})_G z*s%bvW+lYb=?QFjYThGMKqH|~nY<)Iv0wo!KVL(|IyI?K-z@?5EpW-}z=JbyjGlim zy5+&Z$LQ)L*0lIbJUB`$6Om?W?q1QsF=|sQ}v?V zD2FT;3l=VPMF1FmeZjz7#yKDkf@J^{z<6G$wNr<4)bWLs4GB=d7JHdUi9vsUO{3uh z31nkcPFtE4fLJAg<(L;n74VKi1Kf#%mMZn)n^A4Tqne)Z1em7)3CPixhME}3LJyd9 zrH%sBC6mk<3cy6=3IX|`Xc$tYjU0}~+t06T!Ul(zr? delta 890 zc-jGa1BLwW2cic(M@dFFIbreu6aa(}0BB_}Y-&1lazcB1P=+9k0^6&ls{E%MR- z&vb3yc&^g|LH?uDZb&Q|kI1A_B>;*F%cyipty)usAN0!YdcWT6sQLh>1P%nMYzDC3 z<^kiuzQSF>SADJ8-{=nx3IkIMYJ7Hdf&p$Telv9l2{{Z0jBPGW5HNm^I%NR^2n|AH zTx@@$3ypm^Yz7KC4wx||oQ`XNYzL|-3kPnGdkC;70SXR_YX%Jt2g?oy0J|!_00eV_ zhz|#I3fhntSACycagt)!PX1y>d9{058k+dQkWZeN82(s4e0#4 zcP<(oL@rF&a+l&&u?BQ4R)V3RjLcyU`6j|1BAOsDf0O{D!1z;CNGqME%qac-ZaVa)@8{dBl zm0;3RoLuv+VQ|-QUs-q+Yjd0#Z&(+iIYI^73Ml{q49K<|8JV?dkYEeeN!Nh35Ch$! zoi3g0p=q|k=rpLQ4ME1-PF_XC{co7*d{` zkzNZ1EP#_#!YLr!3b2va9!sKJ2tZXvK}6p>44CL#0LxT|$a+1gRo6^v4OP@t0$wNL zS(XftfJbtnz~WU;RVQLl=nzR6TMiHqfB**wR+NszMYIVF2Z+-QSGla9055;kkr~J! zD(J(Gi)o&z!ZH3#x8F_)Eg+l#=y;RPG5Z8rT>yqy(@mDEF-44<9Z_@#pLMcvjX#K* zcF=N>B*dAGEr=lA5DIK4S{0#E;nystf|kUnFKF_m5q!3(Qx&mBVMzc9yoYKMx8|yZ zRx*&VMG*;%D9%Du6f4CX<9sf diff --git a/doc/pl/images/button-view-access-log.gif b/doc/pl/images/button-view-access-log.gif index 5d89af521454b3ce89ebf558d88a8baed7eb372f..b6ffd0ab49f4341c4418aa2e3d270e6fd67bc714 100644 GIT binary patch delta 837 zc-jF)1G@aj1^5O%M@dFFIbp5<6aa(}0BB_}Y->AoazcK7QizCNjgM%Tm1CBfcc`U^ zwzi$X!K=>BzTMo@>FD3@@$LNn`;kE`kx&GYZ5Mx#ApmHqu59bRa4gSsZQrS2koaz^VLwEzknI9TxG0Rn~0HvK|j z0tSOv3lLlrFu(yZ2VDv@0PqG&fD;P-AYFe;M4&+)0S@@t!D0(riU7}0bm|!EWz2gt z8x&x5;(<`2fCi*wffHV!ivSRj40KW_7DNF8C==CyK!TAHd!hL80_&bP2Oa^K)+pmt z1#}LKRFI$z0=Rds4JDAX=89`!1_fZipi3UT1o+Y#CW_{zJ%ApPO##^In-iDcz*T<{ z2v*{+IvZUME2IFUk=|0mO9S%Ji)a&`DHNgr1#~eT8?>x+&sxxF;@FFQI3xgUS2$E7j0~|u({evjhYvcr*nz-}PsJh? ziYmf4%tMU?AYeXAy-|QX6G@>840Zi54L!1eG}bl_FmQ=(SiI5Gh6^}gR3mwH6(G(> zG3`;8I&JtdK$~wO$Q+PK(bvFabY8PxKxvX`CJJ#j1CDpE^hjT9S&BgD4O84^V zFh-Uzq_QOt|8Z*SseKd{9uQOn;T5W|o~jRg#9S(a8A`;e>#m&QN`kGt1}p3hq9&mP Pu)`*+EJ?nK5CQ-@yo6kZ delta 659 zc-jGz0&M;G2FC?GM@dFFIbp5<6aa(}0BB_}Yic@lazcB1P=$tFi-}j4m1C2Za;2ex zt*nu?wVc4htI*KD=jPq;^6vfr{E9DoJ~7$uMe z0H3~43Gyk}r_Dtrgp3rJbMWI^Hh(St0>FPEzyK6NWO7)#wD+*&yfP}!0mw=73(A)$ zcmg2lZJq-JmBctIs?#J*oqtYEeA+XCIsgL}G^kZZz|uDf=Xv{DaFsBMaLzuk8YV2o zbIpDoKx=0B zuIR5B-&Cvf0S_iyz@btILYm%@8kw>ME)O%9cwkooGO^(Cxms7JHCwPJ%Rh&BDy%wv zR3!5R9z~~Lik;^`0MkGe3Ila0M&L(MTn*F)g9v)zA>o9U?1h6MgHWj9hB7#ym}xSQ tPz8r1mI#1n!r{Qh2qT*4;)^z{$U}rM)(9hpNr=FWjXavDLlPkX06Veg9jgEU diff --git a/doc/pl/images/button-view-error-log.gif b/doc/pl/images/button-view-error-log.gif index c99078ad81bec964609dc5feed96ed4b2b7e592a..bbdd548f4183a08f0925135ca6bdbd7cb324e3c1 100644 GIT binary patch delta 853 zc-jF~1FHPZ1^os+M@dFFIbo>)6aa(}0BB_}Y->AoazcK7QizCNj*n=Um1CBfcc`X_ zwY8kU!K=;Az1`f?>FD3@@$LNn`;kE`kx&GYZ4G~^02BZK1^yr;j*uY$XsWJk>%MR- z&vb3qf=@p91Mzq>ni|d4Y)3FDmxPcvSyl8m5d zmIRHL4#Ew>0S~{|2h9Ww4&VR`597uI3=Nk9=I-tQgXrqQtp)9G`~l3@3{Zdu2Ut8f z(7+c#1pyQ|aInBfym`gic>=Ib963BMOu&C&@M{4Aa{~SbIB4X6OMwOe=v)bKLcsz6 z<|+|r;75Qrf>(+)8}qYO9+kg({@fF^K>=MS9yoyS|nQJb6ojy%a##kF4*AaDJ={Hw_>3D&GXcQ#HkK0V0c2e zFvNvNVHzY(Z{EiwSjkaAB?WP$G+2Kf%Ulu5aa_p!gwq4tpb!~>(4~gmc9`AK&oL-~ z<_BmiAPC%gtnJd@e*wBh#S87cN1JVDO!S@r1#od*R|{6+$3Ye46I3R#?12C++g(V| z8Qqlc=IZ03MD1N?Q59D~S7r&ALii5`<_HPBfr4mieRGYDMrKtOu( znU6+VvZqyIBI+%;*zyditTGV~Bu-2b1Oc43YHJe*@z=!~N!;q| fufOt2!l%F%YwQrHB9R2K$2JM;EDJdx5dr`^R~=;T delta 675 zc-jG@0$lz52F(RMM@dFFIbo*&6aa(}0BB_}Y-&1mb3=W7QH6$Fi-}j4m1C2Za-^Yv zt*nu?wVc1es?X29=H=V)@$LQp{E0XsWJk>%MR- z&vb3iLP751dH=wma7d&Hcp^h_$!t2GhMn?Bty-_E=&1O>!n#W^_%@c61&&0p_jQq}o&z80SOGZLB0w1e z3|85pR|ls~FqKI48)MU%G-q9C>btYR#{!@*`!)E9;-yd&H~|XiK5;^y1eotjRs&UxtA1Qq>Q-2D!QQr5O{xW zpkRQ&Z4A6J&X`Y9=A8f>6V8iQOk~Zyjye;a!U5ILQBy3)1z>jP7CFwP_~`B=m<54C z69^yx!SCRFCn;!K8#%xP0<#Jx9nCIq#sU)9%eyW*#RVH#dSur-1px=M&ZAzTLw8?P zs+M@dFFIboy#6aa(}0BB_}Y->AoazcK7QizCNj*n=Um1CBecc`X_ zwY8kU!K=;AzTMo@>FD3^@$LNn`jJ5_kx&GYZ4G~<02BZK1^yr;j*uY$XsWJk>%MR- z&vb3Wf*UaP0SyN%2*$0~%$x{s+z*W?47n4Aq5&}%CSWj7 zwE)300RtTHa~ZLI8pS>NLf#;>ATV1T7n|=0KvLyB4TgqX5o=_@%g{fb+IFqD!0Bt9Nh}cnuV_Ab{E6P`!Gl z((Y5)lo1%qB%?_14aI?Dx>E#5AQ3Aob3=W7QHF+Ii-}j4m1C8db)=zz zt*el=wVlAhtI*KE=H=Y*@$LQp{E0XsWJk>%MR- z&vb3yw@{G$c;djIa7Zi~Q-YqzaBMoC(CEv+V@j{stTsj+6(8Fc*f<_z%`&t~;7A00 zuZP^R2*hn_mHa^;g!L~63@UCZ3mZr*aJhD0^~ZgbOLZX15Lx3_lMD4G+A&&Ck8IzA3mX z4WS47mUb$P8r%&eg=$DA)nAw5NUo4}Rb;Cax%=xCIE1KtVhNrd}lo zr{aLO6=+DYa0m}TK>_r$)Ju-hRg90IodEx#V*g0S@fHoAQ>?A-ikU$v) z%K*JIi7vswg7R`9Xd}*`3s08-Y*Jv*!4FZ@I<|nNf&hbB5LHmEdbOfTfDYm*C5d7y zNvSNX7VQaO0kv)@78Lp#4~<=GXaP6{i$ZOqaBhX{X;A2{tpo|bEogwui~v-@MumSx z0=aH6vF{9*LHr`+zHnWYstmCAU0t1ZIad^`GNk}=NB^lP{n!@)1k?aD;D~Wd00y~P zpn+Q!cvjs=F_S%Q>vnJzhZyP>q=Fl9y;zsq%5EEX3fj`;4igVUhwN)U2^t-<0Fhn- z0R$jm?>_0$%I$@tNRR;I085(bL{@)(EDU87Iu4we15g7m#YNKq3TW5BgAv91KyZF^G`dA5>NuSd}$E5($=EhVfdLG>~8gm}EksKz$@-w$Q~0 iW2Wimn^3ID!<2B=X(tU@Dj|YDclPP$8awn50suR9;5e=T diff --git a/doc/pl/images/button-view-printable-version.gif b/doc/pl/images/button-view-printable-version.gif index 27ae97c763e3a512c98bb9506cbc1b0f9f8680a8..726cd3a744f67ba6dbabe6aae31ee809d47f57a6 100644 GIT binary patch delta 899 zc-jGj1AP3m2CD}>M@dFFIbpT{6aa(}0BB_}Y->AoazcK6Qiq6MjgM%Tm1C8dcc`U@ zwY8kU!K=;9z1`f?>FD3^@$LNn`jJ5_kx&GYZ4H0602BZK1^yr;j*uY$XsWJk>%MR- z&vb3yv0#w=c;djIa7Zi;1wE0$$ZR^F(ASQ%d=3W105%E?%m!Yjb~qKe7K)VO5f-pt z1;^Gkc*yEpyzMc6@tb-=J}wCiDGd(=Ct#|0SyNz<~@J}pqsXD1JI#T z7cCLCGyo2ygJA*&162zUKoc;)fiDMM3N(KJ;08;86AJzsK{G_40UiPQ0MxmM1yst2 z1En>932-JkNIp->v{NWR0AeZvBztuaXf$#(Z=$#epb&tYD|G@WfW_Ru=37e2f6%46NdqBP=5!$0c+&}-)c}7mSFOQOUvH@Xu-pm*8lr%Kn5{qyVjkhqfHN%= z=S4~1>ETl%OOa%Xh$l2ypeY>U0pAvXxCCAcI>dktKwIr*ngb8eC_n*Tbhkz;S*_Cm zJTl#*NGw0%WQadRUh&}3Xs%*)Tv!aag#aiif)Grbu2~)d#4E&J0j!SWjXz(2>z7 zbSDeu3$f`F$MGypFm@E_SE715>17}U!ggAob3=W7QH6$Gi-}j4m1CBecBG+! zt*nr>wVl7gs?E;6<>cG&@$LQp`;kE`kx&GYZ4H0C02BZK1^yr;j!+>0XsWJk>%MR- z&vb3yw@{G$c;djIa7Zi~Q-YqzaBMoC(CEv+V@j{stTsj+6(3t77&i`=W#^mk^=La5 z0k$ojIxtiT72^viY zR-iNiJXMhvXj6ZbR#;WXHP2TR#ZWBB6E-MNp+dn#^$Qq?uLgXJK1hHN-GTv#h!&T1EGLDTSb5aaorx(Ep^Q9=!1}lW;ZNB-sRO%hws$;_k-~+bmUf+AmBiu z3kW#?DFDHk_%RST;0v#8tppm)6&rtJ0bnK+F#&S2rf)!|L!OSizK!=JG3W!!`7bDPF=b(g=2`CR;7OLo?MVP6C2>dWA>7+L3 IphO4&JBE)yr~m)} diff --git a/filter/Dependencies b/filter/Dependencies index 867919f09..7e7b6a9b1 100644 --- a/filter/Dependencies +++ b/filter/Dependencies @@ -1,447 +1,393 @@ -# DO NOT DELETE THIS LINE -- make depend depends on it. -hpgl-attr.o: hpgl-attr.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -hpgl-config.o: hpgl-config.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-main.o: hpgl-main.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -hpgl-prolog.o: hpgl-prolog.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-char.o: hpgl-char.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -hpgl-input.o: hpgl-input.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-polygon.o: hpgl-polygon.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-vector.o: hpgl-vector.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -image-bmp.o: image-bmp.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-colorspace.o: image-colorspace.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-gif.o: image-gif.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-jpeg.o: image-jpeg.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-photocd.o: image-photocd.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-pix.o: image-pix.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-png.o: image-png.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-pnm.o: image-pnm.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-sgi.o: image-sgi.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h image-sgi.h -image-sgilib.o: image-sgilib.c image-sgi.h -image-sun.o: image-sun.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-tiff.o: image-tiff.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-zoom.o: image-zoom.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image.o: image.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -interpret.o: interpret.c ../cups/string.h ../config.h image-private.h \ - image.h raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/debug.h -raster.o: raster.c raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h -form-main.o: form-main.c form.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -form-ps.o: form-ps.c form.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -form-tree.o: form-tree.c form.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -gziptoany.o: gziptoany.c ../cups/string.h ../config.h -imagetops.o: imagetops.c common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h image.h raster.h -imagetoraster.o: imagetoraster.c common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h image-private.h image.h raster.h ../cups/debug.h -common.o: common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/language.h ../cups/string.h ../config.h -pstops.o: pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \ - ../cups/file.h ../cups/array.h -rasterbench.o: rasterbench.c raster.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h -rastertoepson.o: rastertoepson.c ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/ppd.h ../cups/string.h \ - ../config.h raster.h -rastertohp.o: rastertohp.c ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/string.h ../config.h raster.h -rastertolabel.o: rastertolabel.c ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/string.h ../config.h raster.h -testimage.o: testimage.c image.h raster.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h -testraster.o: testraster.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -textcommon.o: textcommon.c textcommon.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -texttops.o: texttops.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -# DO NOT DELETE THIS LINE -- make depend depends on it. -hpgl-attr.32.o: hpgl-attr.c hpgl-attr.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -hpgl-config.32.o: hpgl-config.c hpgl-config.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-main.32.o: hpgl-main.c hpgl-main.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -hpgl-prolog.32.o: hpgl-prolog.c hpgl-prolog.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-char.32.o: hpgl-char.c hpgl-char.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -hpgl-input.32.o: hpgl-input.c hpgl-input.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-polygon.32.o: hpgl-polygon.c hpgl-polygon.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-vector.32.o: hpgl-vector.c hpgl-vector.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -image-bmp.32.o: image-bmp.c image-bmp.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-colorspace.32.o: image-colorspace.c image-colorspace.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-gif.32.o: image-gif.c image-gif.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-jpeg.32.o: image-jpeg.c image-jpeg.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-photocd.32.o: image-photocd.c image-photocd.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-pix.32.o: image-pix.c image-pix.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-png.32.o: image-png.c image-png.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-pnm.32.o: image-pnm.c image-pnm.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-sgi.32.o: image-sgi.c image-sgi.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h image-sgi.h -image-sgilib.32.o: image-sgilib.c image-sgilib.c image-sgi.h -image-sun.32.o: image-sun.c image-sun.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-tiff.32.o: image-tiff.c image-tiff.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-zoom.32.o: image-zoom.c image-zoom.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image.32.o: image.c image.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -interpret.32.o: interpret.c interpret.c ../cups/string.h ../config.h image-private.h \ - image.h raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/debug.h -raster.32.o: raster.c raster.c raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h -form-main.32.o: form-main.c form-main.c form.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -form-ps.32.o: form-ps.c form-ps.c form.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -form-tree.32.o: form-tree.c form-tree.c form.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -gziptoany.32.o: gziptoany.c gziptoany.c ../cups/string.h ../config.h -imagetops.32.o: imagetops.c imagetops.c common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h image.h raster.h -imagetoraster.32.o: imagetoraster.c imagetoraster.c common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h image-private.h image.h raster.h ../cups/debug.h -common.32.o: common.c common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/language.h ../cups/string.h ../config.h -pstops.32.o: pstops.c pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \ - ../cups/file.h ../cups/array.h -rasterbench.32.o: rasterbench.c rasterbench.c raster.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h -rastertoepson.32.o: rastertoepson.c rastertoepson.c ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/ppd.h ../cups/string.h \ - ../config.h raster.h -rastertohp.32.o: rastertohp.c rastertohp.c ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/string.h ../config.h raster.h -rastertolabel.32.o: rastertolabel.c rastertolabel.c ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/string.h ../config.h raster.h -testimage.32.o: testimage.c testimage.c image.h raster.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h -testraster.32.o: testraster.c testraster.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -textcommon.32.o: textcommon.c textcommon.c textcommon.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -texttops.32.o: texttops.c texttops.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -# DO NOT DELETE THIS LINE -- make depend depends on it. -hpgl-attr.64.o: hpgl-attr.c hpgl-attr.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -hpgl-config.64.o: hpgl-config.c hpgl-config.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-main.64.o: hpgl-main.c hpgl-main.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -hpgl-prolog.64.o: hpgl-prolog.c hpgl-prolog.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-char.64.o: hpgl-char.c hpgl-char.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -hpgl-input.64.o: hpgl-input.c hpgl-input.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-polygon.64.o: hpgl-polygon.c hpgl-polygon.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -hpgl-vector.64.o: hpgl-vector.c hpgl-vector.c hpgltops.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -image-bmp.64.o: image-bmp.c image-bmp.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-colorspace.64.o: image-colorspace.c image-colorspace.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-gif.64.o: image-gif.c image-gif.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-jpeg.64.o: image-jpeg.c image-jpeg.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-photocd.64.o: image-photocd.c image-photocd.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-pix.64.o: image-pix.c image-pix.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-png.64.o: image-png.c image-png.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-pnm.64.o: image-pnm.c image-pnm.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-sgi.64.o: image-sgi.c image-sgi.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h image-sgi.h -image-sgilib.64.o: image-sgilib.c image-sgilib.c image-sgi.h -image-sun.64.o: image-sun.c image-sun.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-tiff.64.o: image-tiff.c image-tiff.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image-zoom.64.o: image-zoom.c image-zoom.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -image.64.o: image.c image.c image-private.h image.h raster.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -interpret.64.o: interpret.c interpret.c ../cups/string.h ../config.h image-private.h \ - image.h raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/debug.h -raster.64.o: raster.c raster.c raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h -form-main.64.o: form-main.c form-main.c form.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -form-ps.64.o: form-ps.c form-ps.c form.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -form-tree.64.o: form-tree.c form-tree.c form.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h -gziptoany.64.o: gziptoany.c gziptoany.c ../cups/string.h ../config.h -imagetops.64.o: imagetops.c imagetops.c common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h image.h raster.h -imagetoraster.64.o: imagetoraster.c imagetoraster.c common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h image-private.h image.h raster.h ../cups/debug.h -common.64.o: common.c common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/language.h ../cups/string.h ../config.h -pstops.64.o: pstops.c pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/language.h ../cups/string.h ../config.h \ - ../cups/file.h ../cups/array.h -rasterbench.64.o: rasterbench.c rasterbench.c raster.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h -rastertoepson.64.o: rastertoepson.c rastertoepson.c ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/ppd.h ../cups/string.h \ - ../config.h raster.h -rastertohp.64.o: rastertohp.c rastertohp.c ../cups/cups.h ../cups/ipp.h ../cups/http.h \ - ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h \ - ../cups/language.h ../cups/string.h ../config.h raster.h -rastertolabel.64.o: rastertolabel.c rastertolabel.c ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/string.h ../config.h raster.h -testimage.64.o: testimage.c testimage.c image.h raster.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h -testraster.64.o: testraster.c testraster.c image-private.h image.h raster.h \ - ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h \ - ../cups/string.h ../config.h -textcommon.64.o: textcommon.c textcommon.c textcommon.h common.h ../cups/cups.h \ - ../cups/ipp.h ../cups/http.h ../cups/md5.h ../cups/ppd.h \ - ../cups/array.h ../cups/file.h ../cups/language.h ../cups/language.h \ - ../cups/string.h ../config.h -texttops.64.o: texttops.c texttops.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h \ - ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h \ - ../cups/file.h ../cups/language.h ../cups/language.h ../cups/string.h \ - ../config.h +# DO NOT DELETE + +hpgl-attr.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-attr.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-attr.o: ../cups/language.h ../cups/string.h ../config.h +hpgl-config.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-config.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-config.o: ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-config.o: ../config.h +hpgl-main.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-main.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-main.o: ../cups/language.h ../cups/string.h ../config.h +hpgl-prolog.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-prolog.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-prolog.o: ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-prolog.o: ../config.h +hpgl-char.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-char.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-char.o: ../cups/language.h ../cups/string.h ../config.h +hpgl-input.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-input.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-input.o: ../cups/language.h ../cups/string.h ../config.h +hpgl-polygon.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-polygon.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-polygon.o: ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-polygon.o: ../config.h +hpgl-vector.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-vector.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-vector.o: ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-vector.o: ../config.h +image-bmp.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-bmp.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-bmp.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-colorspace.o: image-private.h image.h raster.h ../cups/cups.h +image-colorspace.o: ../cups/ipp.h ../cups/http.h ../cups/ppd.h +image-colorspace.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-colorspace.o: ../cups/debug.h ../cups/string.h ../config.h +image-gif.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-gif.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-gif.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-jpeg.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-jpeg.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-jpeg.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-photocd.o: image-private.h image.h raster.h ../cups/cups.h +image-photocd.o: ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h +image-photocd.o: ../cups/file.h ../cups/language.h ../cups/debug.h +image-photocd.o: ../cups/string.h ../config.h +image-pix.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-pix.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-pix.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-png.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-png.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-png.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-pnm.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-pnm.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-pnm.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-sgi.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-sgi.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-sgi.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-sgi.o: image-sgi.h +image-sgilib.o: image-sgi.h +image-sun.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-sun.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-sun.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-tiff.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-tiff.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-tiff.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-zoom.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-zoom.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-zoom.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +error.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +error.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +error.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +interpret.o: ../cups/string.h ../config.h image-private.h image.h raster.h +interpret.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +interpret.o: ../cups/array.h ../cups/file.h ../cups/language.h +interpret.o: ../cups/debug.h +raster.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +raster.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +raster.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +form-main.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-main.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +form-main.o: ../cups/language.h ../cups/string.h ../config.h +form-ps.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-ps.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +form-ps.o: ../cups/language.h ../cups/string.h ../config.h +form-tree.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-tree.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +form-tree.o: ../cups/language.h ../cups/string.h ../config.h +gziptoany.o: ../cups/string.h ../config.h +imagetops.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetops.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +imagetops.o: ../cups/language.h ../cups/string.h ../config.h image.h raster.h +imagetoraster.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetoraster.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +imagetoraster.o: ../cups/language.h ../cups/language.h ../cups/string.h +imagetoraster.o: ../config.h image-private.h image.h raster.h ../cups/debug.h +common.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +common.o: ../cups/array.h ../cups/file.h ../cups/language.h +common.o: ../cups/language.h ../cups/string.h ../config.h +pstops.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +pstops.o: ../cups/array.h ../cups/file.h ../cups/language.h +pstops.o: ../cups/language.h ../cups/string.h ../config.h ../cups/file.h +pstops.o: ../cups/array.h +rasterbench.o: raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +rasterbench.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +rasterbench.o: ../cups/language.h +rastertoepson.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +rastertoepson.o: ../cups/array.h ../cups/file.h ../cups/language.h +rastertoepson.o: ../cups/ppd.h ../cups/string.h ../config.h raster.h +rastertohp.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +rastertohp.o: ../cups/array.h ../cups/file.h ../cups/language.h +rastertohp.o: ../cups/string.h ../config.h raster.h +rastertolabel.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +rastertolabel.o: ../cups/array.h ../cups/file.h ../cups/language.h +rastertolabel.o: ../cups/string.h ../config.h raster.h +testimage.o: image.h raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +testimage.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +testraster.o: image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +testraster.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +testraster.o: ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +textcommon.o: textcommon.h common.h ../cups/cups.h ../cups/ipp.h +textcommon.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +textcommon.o: ../cups/language.h ../cups/language.h ../cups/string.h +textcommon.o: ../config.h +texttops.o: textcommon.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +texttops.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +texttops.o: ../cups/language.h ../cups/string.h ../config.h +# DO NOT DELETE + +hpgl-attr.32.o: hpgl-attr.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-attr.32.o: hpgl-attr.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-attr.32.o: hpgl-attr.c ../cups/language.h ../cups/string.h ../config.h +hpgl-config.32.o: hpgl-config.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-config.32.o: hpgl-config.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-config.32.o: hpgl-config.c ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-config.32.o: hpgl-config.c ../config.h +hpgl-main.32.o: hpgl-main.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-main.32.o: hpgl-main.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-main.32.o: hpgl-main.c ../cups/language.h ../cups/string.h ../config.h +hpgl-prolog.32.o: hpgl-prolog.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-prolog.32.o: hpgl-prolog.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-prolog.32.o: hpgl-prolog.c ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-prolog.32.o: hpgl-prolog.c ../config.h +hpgl-char.32.o: hpgl-char.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-char.32.o: hpgl-char.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-char.32.o: hpgl-char.c ../cups/language.h ../cups/string.h ../config.h +hpgl-input.32.o: hpgl-input.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-input.32.o: hpgl-input.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-input.32.o: hpgl-input.c ../cups/language.h ../cups/string.h ../config.h +hpgl-polygon.32.o: hpgl-polygon.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-polygon.32.o: hpgl-polygon.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-polygon.32.o: hpgl-polygon.c ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-polygon.32.o: hpgl-polygon.c ../config.h +hpgl-vector.32.o: hpgl-vector.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-vector.32.o: hpgl-vector.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-vector.32.o: hpgl-vector.c ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-vector.32.o: hpgl-vector.c ../config.h +image-bmp.32.o: image-bmp.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-bmp.32.o: image-bmp.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-bmp.32.o: image-bmp.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-colorspace.32.o: image-colorspace.c image-private.h image.h raster.h ../cups/cups.h +image-colorspace.32.o: image-colorspace.c ../cups/ipp.h ../cups/http.h ../cups/ppd.h +image-colorspace.32.o: image-colorspace.c ../cups/array.h ../cups/file.h ../cups/language.h +image-colorspace.32.o: image-colorspace.c ../cups/debug.h ../cups/string.h ../config.h +image-gif.32.o: image-gif.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-gif.32.o: image-gif.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-gif.32.o: image-gif.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-jpeg.32.o: image-jpeg.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-jpeg.32.o: image-jpeg.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-jpeg.32.o: image-jpeg.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-photocd.32.o: image-photocd.c image-private.h image.h raster.h ../cups/cups.h +image-photocd.32.o: image-photocd.c ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h +image-photocd.32.o: image-photocd.c ../cups/file.h ../cups/language.h ../cups/debug.h +image-photocd.32.o: image-photocd.c ../cups/string.h ../config.h +image-pix.32.o: image-pix.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-pix.32.o: image-pix.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-pix.32.o: image-pix.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-png.32.o: image-png.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-png.32.o: image-png.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-png.32.o: image-png.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-pnm.32.o: image-pnm.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-pnm.32.o: image-pnm.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-pnm.32.o: image-pnm.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-sgi.32.o: image-sgi.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-sgi.32.o: image-sgi.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-sgi.32.o: image-sgi.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-sgi.32.o: image-sgi.c image-sgi.h +image-sgilib.32.o: image-sgilib.c image-sgi.h +image-sun.32.o: image-sun.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-sun.32.o: image-sun.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-sun.32.o: image-sun.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-tiff.32.o: image-tiff.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-tiff.32.o: image-tiff.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-tiff.32.o: image-tiff.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-zoom.32.o: image-zoom.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-zoom.32.o: image-zoom.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-zoom.32.o: image-zoom.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image.32.o: image.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image.32.o: image.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image.32.o: image.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +error.32.o: error.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +error.32.o: error.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +error.32.o: error.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +interpret.32.o: interpret.c ../cups/string.h ../config.h image-private.h image.h raster.h +interpret.32.o: interpret.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +interpret.32.o: interpret.c ../cups/array.h ../cups/file.h ../cups/language.h +interpret.32.o: interpret.c ../cups/debug.h +raster.32.o: raster.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +raster.32.o: raster.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +raster.32.o: raster.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +form-main.32.o: form-main.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-main.32.o: form-main.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +form-main.32.o: form-main.c ../cups/language.h ../cups/string.h ../config.h +form-ps.32.o: form-ps.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-ps.32.o: form-ps.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +form-ps.32.o: form-ps.c ../cups/language.h ../cups/string.h ../config.h +form-tree.32.o: form-tree.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-tree.32.o: form-tree.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +form-tree.32.o: form-tree.c ../cups/language.h ../cups/string.h ../config.h +gziptoany.32.o: gziptoany.c ../cups/string.h ../config.h +imagetops.32.o: imagetops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetops.32.o: imagetops.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +imagetops.32.o: imagetops.c ../cups/language.h ../cups/string.h ../config.h image.h raster.h +imagetoraster.32.o: imagetoraster.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetoraster.32.o: imagetoraster.c ../cups/ppd.h ../cups/array.h ../cups/file.h +imagetoraster.32.o: imagetoraster.c ../cups/language.h ../cups/language.h ../cups/string.h +imagetoraster.32.o: imagetoraster.c ../config.h image-private.h image.h raster.h ../cups/debug.h +common.32.o: common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +common.32.o: common.c ../cups/array.h ../cups/file.h ../cups/language.h +common.32.o: common.c ../cups/language.h ../cups/string.h ../config.h +pstops.32.o: pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +pstops.32.o: pstops.c ../cups/array.h ../cups/file.h ../cups/language.h +pstops.32.o: pstops.c ../cups/language.h ../cups/string.h ../config.h ../cups/file.h +pstops.32.o: pstops.c ../cups/array.h +rasterbench.32.o: rasterbench.c raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +rasterbench.32.o: rasterbench.c ../cups/ppd.h ../cups/array.h ../cups/file.h +rasterbench.32.o: rasterbench.c ../cups/language.h +rastertoepson.32.o: rastertoepson.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +rastertoepson.32.o: rastertoepson.c ../cups/array.h ../cups/file.h ../cups/language.h +rastertoepson.32.o: rastertoepson.c ../cups/ppd.h ../cups/string.h ../config.h raster.h +rastertohp.32.o: rastertohp.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +rastertohp.32.o: rastertohp.c ../cups/array.h ../cups/file.h ../cups/language.h +rastertohp.32.o: rastertohp.c ../cups/string.h ../config.h raster.h +rastertolabel.32.o: rastertolabel.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +rastertolabel.32.o: rastertolabel.c ../cups/array.h ../cups/file.h ../cups/language.h +rastertolabel.32.o: rastertolabel.c ../cups/string.h ../config.h raster.h +testimage.32.o: testimage.c image.h raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +testimage.32.o: testimage.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +testraster.32.o: testraster.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +testraster.32.o: testraster.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +testraster.32.o: testraster.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +textcommon.32.o: textcommon.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h +textcommon.32.o: textcommon.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +textcommon.32.o: textcommon.c ../cups/language.h ../cups/language.h ../cups/string.h +textcommon.32.o: textcommon.c ../config.h +texttops.32.o: texttops.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +texttops.32.o: texttops.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +texttops.32.o: texttops.c ../cups/language.h ../cups/string.h ../config.h +# DO NOT DELETE + +hpgl-attr.64.o: hpgl-attr.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-attr.64.o: hpgl-attr.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-attr.64.o: hpgl-attr.c ../cups/language.h ../cups/string.h ../config.h +hpgl-config.64.o: hpgl-config.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-config.64.o: hpgl-config.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-config.64.o: hpgl-config.c ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-config.64.o: hpgl-config.c ../config.h +hpgl-main.64.o: hpgl-main.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-main.64.o: hpgl-main.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-main.64.o: hpgl-main.c ../cups/language.h ../cups/string.h ../config.h +hpgl-prolog.64.o: hpgl-prolog.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-prolog.64.o: hpgl-prolog.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-prolog.64.o: hpgl-prolog.c ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-prolog.64.o: hpgl-prolog.c ../config.h +hpgl-char.64.o: hpgl-char.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-char.64.o: hpgl-char.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-char.64.o: hpgl-char.c ../cups/language.h ../cups/string.h ../config.h +hpgl-input.64.o: hpgl-input.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-input.64.o: hpgl-input.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-input.64.o: hpgl-input.c ../cups/language.h ../cups/string.h ../config.h +hpgl-polygon.64.o: hpgl-polygon.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-polygon.64.o: hpgl-polygon.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-polygon.64.o: hpgl-polygon.c ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-polygon.64.o: hpgl-polygon.c ../config.h +hpgl-vector.64.o: hpgl-vector.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-vector.64.o: hpgl-vector.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +hpgl-vector.64.o: hpgl-vector.c ../cups/language.h ../cups/language.h ../cups/string.h +hpgl-vector.64.o: hpgl-vector.c ../config.h +image-bmp.64.o: image-bmp.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-bmp.64.o: image-bmp.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-bmp.64.o: image-bmp.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-colorspace.64.o: image-colorspace.c image-private.h image.h raster.h ../cups/cups.h +image-colorspace.64.o: image-colorspace.c ../cups/ipp.h ../cups/http.h ../cups/ppd.h +image-colorspace.64.o: image-colorspace.c ../cups/array.h ../cups/file.h ../cups/language.h +image-colorspace.64.o: image-colorspace.c ../cups/debug.h ../cups/string.h ../config.h +image-gif.64.o: image-gif.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-gif.64.o: image-gif.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-gif.64.o: image-gif.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-jpeg.64.o: image-jpeg.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-jpeg.64.o: image-jpeg.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-jpeg.64.o: image-jpeg.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-photocd.64.o: image-photocd.c image-private.h image.h raster.h ../cups/cups.h +image-photocd.64.o: image-photocd.c ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h +image-photocd.64.o: image-photocd.c ../cups/file.h ../cups/language.h ../cups/debug.h +image-photocd.64.o: image-photocd.c ../cups/string.h ../config.h +image-pix.64.o: image-pix.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-pix.64.o: image-pix.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-pix.64.o: image-pix.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-png.64.o: image-png.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-png.64.o: image-png.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-png.64.o: image-png.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-pnm.64.o: image-pnm.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-pnm.64.o: image-pnm.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-pnm.64.o: image-pnm.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-sgi.64.o: image-sgi.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-sgi.64.o: image-sgi.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-sgi.64.o: image-sgi.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-sgi.64.o: image-sgi.c image-sgi.h +image-sgilib.64.o: image-sgilib.c image-sgi.h +image-sun.64.o: image-sun.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-sun.64.o: image-sun.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-sun.64.o: image-sun.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-tiff.64.o: image-tiff.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-tiff.64.o: image-tiff.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-tiff.64.o: image-tiff.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image-zoom.64.o: image-zoom.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image-zoom.64.o: image-zoom.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image-zoom.64.o: image-zoom.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +image.64.o: image.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +image.64.o: image.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +image.64.o: image.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +error.64.o: error.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +error.64.o: error.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +error.64.o: error.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +interpret.64.o: interpret.c ../cups/string.h ../config.h image-private.h image.h raster.h +interpret.64.o: interpret.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +interpret.64.o: interpret.c ../cups/array.h ../cups/file.h ../cups/language.h +interpret.64.o: interpret.c ../cups/debug.h +raster.64.o: raster.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +raster.64.o: raster.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +raster.64.o: raster.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +form-main.64.o: form-main.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-main.64.o: form-main.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +form-main.64.o: form-main.c ../cups/language.h ../cups/string.h ../config.h +form-ps.64.o: form-ps.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-ps.64.o: form-ps.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +form-ps.64.o: form-ps.c ../cups/language.h ../cups/string.h ../config.h +form-tree.64.o: form-tree.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-tree.64.o: form-tree.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +form-tree.64.o: form-tree.c ../cups/language.h ../cups/string.h ../config.h +gziptoany.64.o: gziptoany.c ../cups/string.h ../config.h +imagetops.64.o: imagetops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetops.64.o: imagetops.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +imagetops.64.o: imagetops.c ../cups/language.h ../cups/string.h ../config.h image.h raster.h +imagetoraster.64.o: imagetoraster.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetoraster.64.o: imagetoraster.c ../cups/ppd.h ../cups/array.h ../cups/file.h +imagetoraster.64.o: imagetoraster.c ../cups/language.h ../cups/language.h ../cups/string.h +imagetoraster.64.o: imagetoraster.c ../config.h image-private.h image.h raster.h ../cups/debug.h +common.64.o: common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +common.64.o: common.c ../cups/array.h ../cups/file.h ../cups/language.h +common.64.o: common.c ../cups/language.h ../cups/string.h ../config.h +pstops.64.o: pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +pstops.64.o: pstops.c ../cups/array.h ../cups/file.h ../cups/language.h +pstops.64.o: pstops.c ../cups/language.h ../cups/string.h ../config.h ../cups/file.h +pstops.64.o: pstops.c ../cups/array.h +rasterbench.64.o: rasterbench.c raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +rasterbench.64.o: rasterbench.c ../cups/ppd.h ../cups/array.h ../cups/file.h +rasterbench.64.o: rasterbench.c ../cups/language.h +rastertoepson.64.o: rastertoepson.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +rastertoepson.64.o: rastertoepson.c ../cups/array.h ../cups/file.h ../cups/language.h +rastertoepson.64.o: rastertoepson.c ../cups/ppd.h ../cups/string.h ../config.h raster.h +rastertohp.64.o: rastertohp.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +rastertohp.64.o: rastertohp.c ../cups/array.h ../cups/file.h ../cups/language.h +rastertohp.64.o: rastertohp.c ../cups/string.h ../config.h raster.h +rastertolabel.64.o: rastertolabel.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +rastertolabel.64.o: rastertolabel.c ../cups/array.h ../cups/file.h ../cups/language.h +rastertolabel.64.o: rastertolabel.c ../cups/string.h ../config.h raster.h +testimage.64.o: testimage.c image.h raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +testimage.64.o: testimage.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +testraster.64.o: testraster.c image-private.h image.h raster.h ../cups/cups.h ../cups/ipp.h +testraster.64.o: testraster.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +testraster.64.o: testraster.c ../cups/language.h ../cups/debug.h ../cups/string.h ../config.h +textcommon.64.o: textcommon.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h +textcommon.64.o: textcommon.c ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +textcommon.64.o: textcommon.c ../cups/language.h ../cups/language.h ../cups/string.h +textcommon.64.o: textcommon.c ../config.h +texttops.64.o: texttops.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +texttops.64.o: texttops.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +texttops.64.o: texttops.c ../cups/language.h ../cups/string.h ../config.h diff --git a/filter/Makefile b/filter/Makefile index ae7b7322f..f657bd185 100644 --- a/filter/Makefile +++ b/filter/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 6158 2006-12-17 01:44:21Z mike $" +# "$Id: Makefile 6315 2007-03-03 00:12:26Z mike $" # # Filter makefile for the Common UNIX Printing System (CUPS). # @@ -43,7 +43,7 @@ HPGLOBJS = hpgl-attr.o hpgl-config.o hpgl-main.o hpgl-prolog.o \ IMAGEOBJS = image-bmp.o image-colorspace.o image-gif.o image-jpeg.o \ image-photocd.o image-pix.o image-png.o image-pnm.o \ image-sgi.o image-sgilib.o image-sun.o image-tiff.o \ - image-zoom.o image.o interpret.o raster.o + image-zoom.o image.o error.o interpret.o raster.o IMAGE32OBJS = $(IMAGEOBJS:.o=.32.o) IMAGE64OBJS = $(IMAGEOBJS:.o=.64.o) FORMOBJS = form-attr.o form-main.o form-ps.o form-text.o form-tree.o @@ -243,7 +243,7 @@ libcupsimage.2.dylib: $(IMAGEOBJS) echo Linking $@... $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ -install_name $(libdir)/$@ \ - -current_version 2.2.0 \ + -current_version 2.3.0 \ -compatibility_version 2.0.0 \ $(IMAGEOBJS) $(DSOLIBS) -L../cups $(LINKCUPS) -lm $(RM) libcupsimage.dylib @@ -270,7 +270,7 @@ libcupsimage.la: $(IMAGEOBJS) echo Linking $@... $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS:.o=.lo) $(DSOLIBS) \ -L../cups $(LINKCUPS) \ - -rpath $(LIBDIR) -version-info 2:2 + -rpath $(LIBDIR) -version-info 2:3 # @@ -359,16 +359,16 @@ rastertohp: rastertohp.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) testraster: testraster.o ../cups/libcups.a libcupsimage.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testraster.o libcupsimage.a ../cups/libcups.a \ - $(IMGLIBS) $(DSOLIBS) $(LIBS) + $(IMGLIBS) $(DSOLIBS) $(COMMONLIBS) $(SSLLIBS) $(LIBGSSAPI) # # rasterbench # -rasterbench: rasterbench.o raster.o +rasterbench: rasterbench.o libcupsimage.a echo Linking $@... - $(CC) $(LDFLAGS) -o $@ rasterbench.o raster.o + $(CC) $(LDFLAGS) -o $@ rasterbench.o libcupsimage.a $(LIBS) # @@ -389,5 +389,5 @@ include Dependencies # -# End of "$Id: Makefile 6158 2006-12-17 01:44:21Z mike $". +# End of "$Id: Makefile 6315 2007-03-03 00:12:26Z mike $". # diff --git a/filter/common.c b/filter/common.c index c60e0a517..5ec13118c 100644 --- a/filter/common.c +++ b/filter/common.c @@ -1,5 +1,5 @@ /* - * "$Id: common.c 6003 2006-10-02 16:26:04Z mike $" + * "$Id: common.c 5997 2006-10-02 15:33:05Z mike $" * * Common filter routines for the Common UNIX Printing System (CUPS). * @@ -540,5 +540,5 @@ WriteTextComment(const char *name, /* I - Comment name ("Title", etc.) */ /* - * End of "$Id: common.c 6003 2006-10-02 16:26:04Z mike $". + * End of "$Id: common.c 5997 2006-10-02 15:33:05Z mike $". */ diff --git a/filter/common.h b/filter/common.h index 4ccf6b3a4..9e8bb5925 100644 --- a/filter/common.h +++ b/filter/common.h @@ -1,5 +1,5 @@ /* - * "$Id: common.h 6003 2006-10-02 16:26:04Z mike $" + * "$Id: common.h 5997 2006-10-02 15:33:05Z mike $" * * Common filter definitions for the Common UNIX Printing System (CUPS). * @@ -89,5 +89,5 @@ extern void WriteTextComment(const char *name, const char *value); /* - * End of "$Id: common.h 6003 2006-10-02 16:26:04Z mike $". + * End of "$Id: common.h 5997 2006-10-02 15:33:05Z mike $". */ diff --git a/filter/error.c b/filter/error.c new file mode 100644 index 000000000..6d68a6edb --- /dev/null +++ b/filter/error.c @@ -0,0 +1,297 @@ +/* + * "$Id: error.c 6274 2007-02-13 21:05:28Z mike $" + * + * Raster error handling for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9600 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsRasterAddError() - Add an error message to the error buffer. + * _cupsRasterClearError() - Clear the error buffer. + * cupsRasterErrorString() - Return the last error from a raster function. + * get_error_buffer() - Return a pointer to thread local storage. + * raster_init() - Initialize error buffer once. + * raster_destructor() - Free memory allocated by get_error_buffer(). + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" +#include + + +/* + * Local structures... + */ + +typedef struct _cups_raster_error_s /**** Error buffer structure ****/ +{ + char *start, /* Start of buffer */ + *current, /* Current position in buffer */ + *end; /* End of buffer */ +} _cups_raster_error_t; + + +/* + * Local functions... + */ + +static _cups_raster_error_t *get_error_buffer(void); + + +/* + * '_cupsRasterAddError()' - Add an error message to the error buffer. + */ + +void +_cupsRasterAddError(const char *f, /* I - Printf-style error message */ + ...) /* I - Additional arguments as needed */ +{ + _cups_raster_error_t *buf = get_error_buffer(); + /* Error buffer */ + va_list ap; /* Pointer to additional arguments */ + char s[2048]; /* Message string */ + size_t bytes; /* Bytes in message string */ + + + va_start(ap, f); + bytes = vsnprintf(s, sizeof(s), f, ap); + va_end(ap); + + if (bytes <= 0) + return; + + bytes ++; + + if (bytes >= sizeof(s)) + return; + + if (bytes > (buf->end - buf->current)) + { + /* + * Allocate more memory... + */ + + char *temp; /* New buffer */ + size_t size; /* Size of buffer */ + + + size = buf->end - buf->start + 2 * bytes + 1024; + + if (buf->start) + temp = realloc(buf->start, size); + else + temp = malloc(size); + + if (!temp) + return; + + /* + * Update pointers... + */ + + buf->end = temp + size; + buf->current = temp + (buf->current - buf->start); + buf->start = temp; + } + + /* + * Append the message to the end of the current string... + */ + + memcpy(buf->current, s, bytes); + buf->current += bytes - 1; +} + + +/* + * '_cupsRasterClearError()' - Clear the error buffer. + */ + +void +_cupsRasterClearError(void) +{ + _cups_raster_error_t *buf = get_error_buffer(); + /* Error buffer */ + + + buf->current = buf->start; + + if (buf->start) + *(buf->start) = '\0'; +} + + +/* + * 'cupsRasterErrorString()' - Return the last error from a raster function. + * + * If there are no recent errors, NULL is returned. + * + * @since CUPS 1.3@ + */ + +const char * /* O - Last error */ +cupsRasterErrorString(void) +{ + _cups_raster_error_t *buf = get_error_buffer(); + /* Error buffer */ + + + if (buf->current == buf->start) + return (NULL); + else + return (buf->start); +} + + +#ifdef HAVE_PTHREAD_H +/* + * Implement per-thread globals... + */ + +# include + + +/* + * Local globals... + */ + +static pthread_key_t raster_key = -1; + /* Thread local storage key */ +static pthread_once_t raster_key_once = PTHREAD_ONCE_INIT; + /* One-time initialization object */ + + +/* + * Local functions... + */ + +static void raster_init(void); +static void raster_destructor(void *value); + + +/* + * 'get_error_buffer()' - Return a pointer to thread local storage. + */ + +_cups_raster_error_t * /* O - Pointer to error buffer */ +get_error_buffer(void) +{ + _cups_raster_error_t *buf; /* Pointer to error buffer */ + + + /* + * Initialize the global data exactly once... + */ + + DEBUG_printf(("get_error_buffer(): raster_key_once=%d\n", + raster_key_once)); + + pthread_once(&raster_key_once, raster_init); + + /* + * See if we have allocated the data yet... + */ + + if ((buf = (_cups_raster_error_t *)pthread_getspecific(raster_key)) + == NULL) + { + DEBUG_puts("get_error_buffer: allocating memory for thread..."); + + /* + * No, allocate memory as set the pointer for the key... + */ + + buf = calloc(1, sizeof(_cups_raster_error_t)); + pthread_setspecific(raster_key, buf); + + DEBUG_printf((" buf=%p\n", buf)); + } + + /* + * Return the pointer to the data... + */ + + return (buf); +} + + +/* + * 'raster_init()' - Initialize error buffer once. + */ + +static void +raster_init(void) +{ + pthread_key_create(&raster_key, raster_destructor); + + DEBUG_printf(("raster_init(): raster_key=%x(%u)\n", raster_key, + raster_key)); +} + + +/* + * 'raster_destructor()' - Free memory allocated by get_error_buffer(). + */ + +static void +raster_destructor(void *value) /* I - Data to free */ +{ + _cups_raster_error_t *buf = (_cups_raster_error_t *)value; + /* Error buffer */ + + + DEBUG_printf(("raster_destructor(value=%p)\n", value)); + + if (buf->start) + free(buf->start); + + free(value); +} + + +#else +/* + * Implement static globals... + */ + +/* + * 'get_error_buffer()' - Return a pointer to thread local storage. + */ + +_cups_raster_error_t * /* O - Pointer to error buffer */ +get_error_buffer(void) +{ + static _cups_raster_error_t buf = { 0, 0, 0 }; + /* Error buffer */ + + + return (&buf); +} +#endif /* HAVE_PTHREAD_H */ + + +/* + * End of "$Id: error.c 6274 2007-02-13 21:05:28Z mike $". + */ diff --git a/filter/hpgl-prolog.c b/filter/hpgl-prolog.c index bfd079f87..20b1a1d01 100644 --- a/filter/hpgl-prolog.c +++ b/filter/hpgl-prolog.c @@ -1,5 +1,5 @@ /* - * "$Id: hpgl-prolog.c 6003 2006-10-02 16:26:04Z mike $" + * "$Id: hpgl-prolog.c 5997 2006-10-02 15:33:05Z mike $" * * HP-GL/2 prolog routines for for the Common UNIX Printing System (CUPS). * @@ -373,5 +373,5 @@ Outputf(const char *format, /* I - Printf-style string */ /* - * End of "$Id: hpgl-prolog.c 6003 2006-10-02 16:26:04Z mike $". + * End of "$Id: hpgl-prolog.c 5997 2006-10-02 15:33:05Z mike $". */ diff --git a/filter/image-bmp.c b/filter/image-bmp.c index dab979a65..1dc524763 100644 --- a/filter/image-bmp.c +++ b/filter/image-bmp.c @@ -1,5 +1,5 @@ /* - * "$Id: image-bmp.c 5509 2006-05-11 11:41:36Z mike $" + * "$Id: image-bmp.c 5508 2006-05-11 11:41:16Z mike $" * * BMP image routines for the Common UNIX Printing System (CUPS). * @@ -535,5 +535,5 @@ read_long(FILE *fp) /* I - File to read from */ /* - * End of "$Id: image-bmp.c 5509 2006-05-11 11:41:36Z mike $". + * End of "$Id: image-bmp.c 5508 2006-05-11 11:41:16Z mike $". */ diff --git a/filter/image-colorspace.c b/filter/image-colorspace.c index 2cb4ced01..cc442944e 100644 --- a/filter/image-colorspace.c +++ b/filter/image-colorspace.c @@ -1,5 +1,5 @@ /* - * "$Id: image-colorspace.c 5519 2006-05-12 15:06:42Z mike $" + * "$Id: image-colorspace.c 5520 2006-05-12 16:37:36Z mike $" * * Colorspace conversions for the Common UNIX Printing System (CUPS). * @@ -1573,5 +1573,5 @@ zshear(float mat[3][3], /* I - Matrix */ /* - * End of "$Id: image-colorspace.c 5519 2006-05-12 15:06:42Z mike $". + * End of "$Id: image-colorspace.c 5520 2006-05-12 16:37:36Z mike $". */ diff --git a/filter/image-gif.c b/filter/image-gif.c index b56dd0c88..09784a60e 100644 --- a/filter/image-gif.c +++ b/filter/image-gif.c @@ -1,5 +1,5 @@ /* - * "$Id: image-gif.c 5509 2006-05-11 11:41:36Z mike $" + * "$Id: image-gif.c 5508 2006-05-11 11:41:16Z mike $" * * GIF image routines for the Common UNIX Printing System (CUPS). * @@ -695,5 +695,5 @@ gif_read_lzw(FILE *fp, /* I - File to read from */ /* - * End of "$Id: image-gif.c 5509 2006-05-11 11:41:36Z mike $". + * End of "$Id: image-gif.c 5508 2006-05-11 11:41:16Z mike $". */ diff --git a/filter/image-jpeg.c b/filter/image-jpeg.c index 7db80ae1f..5a07a7bbd 100644 --- a/filter/image-jpeg.c +++ b/filter/image-jpeg.c @@ -1,5 +1,5 @@ /* - * "$Id: image-jpeg.c 5509 2006-05-11 11:41:36Z mike $" + * "$Id: image-jpeg.c 5508 2006-05-11 11:41:16Z mike $" * * JPEG image routines for the Common UNIX Printing System (CUPS). * @@ -320,5 +320,5 @@ _cupsImageReadJPEG( /* - * End of "$Id: image-jpeg.c 5509 2006-05-11 11:41:36Z mike $". + * End of "$Id: image-jpeg.c 5508 2006-05-11 11:41:16Z mike $". */ diff --git a/filter/image-photocd.c b/filter/image-photocd.c index 195f0da39..00171ecc1 100644 --- a/filter/image-photocd.c +++ b/filter/image-photocd.c @@ -1,5 +1,5 @@ /* - * "$Id: image-photocd.c 5509 2006-05-11 11:41:36Z mike $" + * "$Id: image-photocd.c 5508 2006-05-11 11:41:16Z mike $" * * PhotoCD routines for the Common UNIX Printing System (CUPS). * @@ -313,5 +313,5 @@ _cupsImageReadPhotoCD( /* - * End of "$Id: image-photocd.c 5509 2006-05-11 11:41:36Z mike $". + * End of "$Id: image-photocd.c 5508 2006-05-11 11:41:16Z mike $". */ diff --git a/filter/image-pix.c b/filter/image-pix.c index 64e595623..ac471669d 100644 --- a/filter/image-pix.c +++ b/filter/image-pix.c @@ -1,5 +1,5 @@ /* - * "$Id: image-pix.c 5509 2006-05-11 11:41:36Z mike $" + * "$Id: image-pix.c 5508 2006-05-11 11:41:16Z mike $" * * Alias PIX image routines for the Common UNIX Printing System (CUPS). * @@ -232,5 +232,5 @@ read_short(FILE *fp) /* I - File to read from */ /* - * End of "$Id: image-pix.c 5509 2006-05-11 11:41:36Z mike $". + * End of "$Id: image-pix.c 5508 2006-05-11 11:41:16Z mike $". */ diff --git a/filter/image-png.c b/filter/image-png.c index 97cbfc13f..3b4469bc9 100644 --- a/filter/image-png.c +++ b/filter/image-png.c @@ -1,5 +1,5 @@ /* - * "$Id: image-png.c 5509 2006-05-11 11:41:36Z mike $" + * "$Id: image-png.c 5508 2006-05-11 11:41:16Z mike $" * * PNG image routines for the Common UNIX Printing System (CUPS). * @@ -280,5 +280,5 @@ _cupsImageReadPNG( /* - * End of "$Id: image-png.c 5509 2006-05-11 11:41:36Z mike $". + * End of "$Id: image-png.c 5508 2006-05-11 11:41:16Z mike $". */ diff --git a/filter/image-pnm.c b/filter/image-pnm.c index b418f68e3..12c294c1c 100644 --- a/filter/image-pnm.c +++ b/filter/image-pnm.c @@ -1,5 +1,5 @@ /* - * "$Id: image-pnm.c 6149 2006-12-06 20:25:42Z mike $" + * "$Id: image-pnm.c 6146 2006-12-06 20:19:52Z mike $" * * Portable Any Map file routines for the Common UNIX Printing System (CUPS). * @@ -301,5 +301,5 @@ _cupsImageReadPNM( /* - * End of "$Id: image-pnm.c 6149 2006-12-06 20:25:42Z mike $". + * End of "$Id: image-pnm.c 6146 2006-12-06 20:19:52Z mike $". */ diff --git a/filter/image-private.h b/filter/image-private.h index f84ace850..c91b1834c 100644 --- a/filter/image-private.h +++ b/filter/image-private.h @@ -1,5 +1,5 @@ /* - * "$Id: image-private.h 6158 2006-12-17 01:44:21Z mike $" + * "$Id: image-private.h 6274 2007-02-13 21:05:28Z mike $" * * Private image library definitions for the Common UNIX Printing * System (CUPS). @@ -217,10 +217,11 @@ extern cups_izoom_t *_cupsImageZoomNew(cups_image_t *img, int xc0, int yc0, extern int _cupsRasterExecPS(cups_page_header2_t *h, int *preferred_bits, const char *code); - +extern void _cupsRasterAddError(const char *f, ...); +extern void _cupsRasterClearError(void); #endif /* !_CUPS_IMAGE_PRIVATE_H_ */ /* - * End of "$Id: image-private.h 6158 2006-12-17 01:44:21Z mike $". + * End of "$Id: image-private.h 6274 2007-02-13 21:05:28Z mike $". */ diff --git a/filter/image-sgi.c b/filter/image-sgi.c index 234868512..288af2618 100644 --- a/filter/image-sgi.c +++ b/filter/image-sgi.c @@ -1,5 +1,5 @@ /* - * "$Id: image-sgi.c 5509 2006-05-11 11:41:36Z mike $" + * "$Id: image-sgi.c 5508 2006-05-11 11:41:16Z mike $" * * SGI image file routines for the Common UNIX Printing System (CUPS). * @@ -279,5 +279,5 @@ _cupsImageReadSGI( /* - * End of "$Id: image-sgi.c 5509 2006-05-11 11:41:36Z mike $". + * End of "$Id: image-sgi.c 5508 2006-05-11 11:41:16Z mike $". */ diff --git a/filter/image-sun.c b/filter/image-sun.c index bcc354a8f..c8ee70278 100644 --- a/filter/image-sun.c +++ b/filter/image-sun.c @@ -1,5 +1,5 @@ /* - * "$Id: image-sun.c 6149 2006-12-06 20:25:42Z mike $" + * "$Id: image-sun.c 6147 2006-12-06 20:21:46Z mike $" * * Sun Raster image file routines for the Common UNIX Printing System (CUPS). * @@ -389,5 +389,5 @@ read_unsigned(FILE *fp) /* I - File to read from */ /* - * End of "$Id: image-sun.c 6149 2006-12-06 20:25:42Z mike $". + * End of "$Id: image-sun.c 6147 2006-12-06 20:21:46Z mike $". */ diff --git a/filter/image-tiff.c b/filter/image-tiff.c index 223324bbf..184cf9621 100644 --- a/filter/image-tiff.c +++ b/filter/image-tiff.c @@ -1,5 +1,5 @@ /* - * "$Id: image-tiff.c 5509 2006-05-11 11:41:36Z mike $" + * "$Id: image-tiff.c 5508 2006-05-11 11:41:16Z mike $" * * TIFF file routines for the Common UNIX Printing System (CUPS). * @@ -1720,5 +1720,5 @@ _cupsImageReadTIFF( /* - * End of "$Id: image-tiff.c 5509 2006-05-11 11:41:36Z mike $". + * End of "$Id: image-tiff.c 5508 2006-05-11 11:41:16Z mike $". */ diff --git a/filter/imagetops.c b/filter/imagetops.c index 666a91453..ed8761064 100644 --- a/filter/imagetops.c +++ b/filter/imagetops.c @@ -1,5 +1,5 @@ /* - * "$Id: imagetops.c 6003 2006-10-02 16:26:04Z mike $" + * "$Id: imagetops.c 5997 2006-10-02 15:33:05Z mike $" * * Image file to PostScript filter for the Common UNIX Printing System (CUPS). * @@ -1063,5 +1063,5 @@ ps_ascii85(cups_ib_t *data, /* I - Data to print */ /* - * End of "$Id: imagetops.c 6003 2006-10-02 16:26:04Z mike $". + * End of "$Id: imagetops.c 5997 2006-10-02 15:33:05Z mike $". */ diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c index 32bc9a7c7..db9298231 100644 --- a/filter/imagetoraster.c +++ b/filter/imagetoraster.c @@ -1,5 +1,5 @@ /* - * "$Id: imagetoraster.c 5522 2006-05-15 05:02:15Z mike $" + * "$Id: imagetoraster.c 5523 2006-05-15 05:02:43Z mike $" * * Image file to raster filter for the Common UNIX Printing System (CUPS). * @@ -4310,5 +4310,5 @@ raster_cb( /* - * End of "$Id: imagetoraster.c 5522 2006-05-15 05:02:15Z mike $". + * End of "$Id: imagetoraster.c 5523 2006-05-15 05:02:43Z mike $". */ diff --git a/filter/interpret.c b/filter/interpret.c index 6f9c9f855..f3c092d92 100644 --- a/filter/interpret.c +++ b/filter/interpret.c @@ -1,5 +1,5 @@ /* - * "$Id: interpret.c 6282 2007-02-14 16:33:54Z mike $" + * "$Id: interpret.c 6281 2007-02-14 16:32:42Z mike $" * * PPD command interpreter for the Common UNIX Printing System (CUPS). * @@ -31,6 +31,9 @@ * cleartomark_stack() - Clear to the last mark ([) on the stack. * copy_stack() - Copy the top N stack objects. * delete_stack() - Free memory used by a stack. + * error_object() - Add an object's value to the current error + * message. + * error_stack() - Add a stack to the current error message. * index_stack() - Copy the Nth value on the stack. * new_stack() - Create a new stack. * pop_stock() - Pop the top object off the stack. @@ -107,6 +110,8 @@ typedef struct static int cleartomark_stack(_cups_ps_stack_t *st); static int copy_stack(_cups_ps_stack_t *st, int count); static void delete_stack(_cups_ps_stack_t *st); +static void error_object(_cups_ps_obj_t *obj); +static void error_stack(_cups_ps_stack_t *st, const char *title); static _cups_ps_obj_t *index_stack(_cups_ps_stack_t *st, int n); static _cups_ps_stack_t *new_stack(void); static _cups_ps_obj_t *pop_stack(_cups_ps_stack_t *st); @@ -167,8 +172,13 @@ cupsRasterInterpretPPD( * Range check input... */ + _cupsRasterClearError(); + if (!h) + { + _cupsRasterAddError("Page header cannot be NULL!\n"); return (-1); + } /* * Reset the page header to the defaults... @@ -304,7 +314,10 @@ cupsRasterInterpretPPD( */ if (func && (*func)(h, preferred_bits)) + { + _cupsRasterAddError("Page header callback returned error.\n"); return (-1); + } /* * Check parameters... @@ -317,7 +330,10 @@ cupsRasterInterpretPPD( h->cupsBitsPerColor != 16) || h->cupsBorderlessScalingFactor < 0.5 || h->cupsBorderlessScalingFactor > 2.0) + { + _cupsRasterAddError("Page header uses unsupported values.\n"); return (-1); + } /* * Compute the bitmap parameters... @@ -431,10 +447,14 @@ _cupsRasterExecPS( */ if ((codecopy = strdup(code)) == NULL) + { + _cupsRasterAddError("Unable to duplicate code string.\n"); return (-1); + } if ((st = new_stack()) == NULL) { + _cupsRasterAddError("Unable to create stack.\n"); free(codecopy); return (-1); } @@ -462,7 +482,8 @@ _cupsRasterExecPS( case CUPS_PS_CLEARTOMARK : pop_stack(st); - cleartomark_stack(st); + if (cleartomark_stack(st)) + _cupsRasterAddError("cleartomark: Stack underflow!\n"); #ifdef DEBUG fputs(" dup: ", stdout); @@ -554,6 +575,7 @@ _cupsRasterExecPS( break; case CUPS_PS_OTHER : + _cupsRasterAddError("Unknown operator \"%s\"!\n", obj->value.other); DEBUG_printf((" Unknown operator \"%s\"!\n", obj->value.other)); break; } @@ -570,6 +592,8 @@ _cupsRasterExecPS( if (st->num_objs > 0) { + error_stack(st, "Stack not empty:"); + #ifdef DEBUG fputs(" Stack not empty:", stdout); DEBUG_stack(st); @@ -652,6 +676,122 @@ delete_stack(_cups_ps_stack_t *st) /* I - Stack */ } +/* + * 'error_object()' - Add an object's value to the current error message. + */ + +static void +error_object(_cups_ps_obj_t *obj) /* I - Object to add */ +{ + switch (obj->type) + { + case CUPS_PS_NAME : + _cupsRasterAddError(" /%s", obj->value.name); + break; + + case CUPS_PS_NUMBER : + _cupsRasterAddError(" %g", obj->value.number); + break; + + case CUPS_PS_STRING : + _cupsRasterAddError(" (%s)", obj->value.string); + break; + + case CUPS_PS_BOOLEAN : + if (obj->value.boolean) + _cupsRasterAddError(" true"); + else + _cupsRasterAddError(" false"); + break; + + case CUPS_PS_NULL : + _cupsRasterAddError(" null"); + break; + + case CUPS_PS_START_ARRAY : + _cupsRasterAddError(" ["); + break; + + case CUPS_PS_END_ARRAY : + _cupsRasterAddError(" ]"); + break; + + case CUPS_PS_START_DICT : + _cupsRasterAddError(" <<"); + break; + + case CUPS_PS_END_DICT : + _cupsRasterAddError(" >>"); + break; + + case CUPS_PS_START_PROC : + _cupsRasterAddError(" {"); + break; + + case CUPS_PS_END_PROC : + _cupsRasterAddError(" }"); + break; + + case CUPS_PS_COPY : + _cupsRasterAddError(" --copy--"); + break; + + case CUPS_PS_CLEARTOMARK : + _cupsRasterAddError(" --cleartomark--"); + break; + + case CUPS_PS_DUP : + _cupsRasterAddError(" --dup--"); + break; + + case CUPS_PS_INDEX : + _cupsRasterAddError(" --index--"); + break; + + case CUPS_PS_POP : + _cupsRasterAddError(" --pop--"); + break; + + case CUPS_PS_ROLL : + _cupsRasterAddError(" --roll--"); + break; + + case CUPS_PS_SETPAGEDEVICE : + _cupsRasterAddError(" --setpagedevice--"); + break; + + case CUPS_PS_STOPPED : + _cupsRasterAddError(" --stopped--"); + break; + + case CUPS_PS_OTHER : + _cupsRasterAddError(" --%s--", obj->value.other); + break; + } +} + + +/* + * 'error_stack()' - Add a stack to the current error message... + */ + +static void +error_stack(_cups_ps_stack_t *st, /* I - Stack */ + const char *title) /* I - Title string */ +{ + int c; /* Looping var */ + _cups_ps_obj_t *obj; /* Current object on stack */ + + + _cupsRasterAddError(title); + + for (obj = st->objs, c = st->num_objs; c > 0; c --, obj ++) + error_object(obj); + + _cupsRasterAddError("\n"); +} + + /* * 'index_stack()' - Copy the Nth value on the stack. */ @@ -1500,5 +1640,5 @@ DEBUG_stack(_cups_ps_stack_t *st) /* I - Stack */ /* - * End of "$Id: interpret.c 6282 2007-02-14 16:33:54Z mike $". + * End of "$Id: interpret.c 6281 2007-02-14 16:32:42Z mike $". */ diff --git a/filter/pstops.c b/filter/pstops.c index f81fcdda3..c7ee6fcaf 100644 --- a/filter/pstops.c +++ b/filter/pstops.c @@ -1,5 +1,5 @@ /* - * "$Id: pstops.c 6247 2007-02-07 20:54:37Z mike $" + * "$Id: pstops.c 6320 2007-03-08 13:36:56Z mike $" * * PostScript filter for the Common UNIX Printing System (CUPS). * @@ -937,13 +937,20 @@ copy_dsc(cups_file_t *fp, /* I - File to read from */ ppdEmitJCL(ppd, stdout, doc->job_id, doc->user, doc->title); puts("%!PS-Adobe-3.0"); - - pageinfo = (pstops_page_t *)cupsArrayFirst(doc->pages); - copy_bytes(doc->temp, 0, pageinfo->offset); number = 0; } + /* + * Copy the prolog as needed... + */ + + if (!number) + { + pageinfo = (pstops_page_t *)cupsArrayFirst(doc->pages); + copy_bytes(doc->temp, 0, pageinfo->offset); + } + /* * Then copy all of the pages... */ @@ -3281,5 +3288,5 @@ write_labels(pstops_doc_t *doc, /* I - Document information */ /* - * End of "$Id: pstops.c 6247 2007-02-07 20:54:37Z mike $". + * End of "$Id: pstops.c 6320 2007-03-08 13:36:56Z mike $". */ diff --git a/filter/raster.c b/filter/raster.c index 1118e7e1e..32155073b 100644 --- a/filter/raster.c +++ b/filter/raster.c @@ -1,5 +1,5 @@ /* - * "$Id: raster.c 6061 2006-10-23 00:26:52Z mike $" + * "$Id: raster.c 6274 2007-02-13 21:05:28Z mike $" * * Raster file routines for the Common UNIX Printing System (CUPS). * @@ -43,6 +43,7 @@ * cups_raster_read_header() - Read a raster page header. * cups_raster_update() - Update the raster header and row count for the * current page. + * cups_raster_write() - Write a row of raster data... * cups_read() - Read bytes from a file. * cups_swap() - Swap bytes in raster data... * cups_write() - Write bytes to a file. @@ -52,7 +53,7 @@ * Include necessary headers... */ -#include "raster.h" +#include "image-private.h" #include #include #include @@ -98,6 +99,7 @@ static unsigned cups_raster_read_header(cups_raster_t *r); static int cups_raster_read(cups_raster_t *r, unsigned char *buf, int bytes); static void cups_raster_update(cups_raster_t *r); +static int cups_raster_write(cups_raster_t *r, const unsigned char *pixels); static int cups_read(int fd, unsigned char *buf, int bytes); static void cups_swap(unsigned char *buf, int bytes); static int cups_write(int fd, const unsigned char *buf, int bytes); @@ -134,11 +136,17 @@ cupsRasterOpen(int fd, /* I - File descriptor */ cups_raster_t *r; /* New stream */ + _cupsRasterClearError(); + if ((r = calloc(sizeof(cups_raster_t), 1)) == NULL) + { + _cupsRasterAddError("Unable to allocate memory for raster stream: %s\n", + strerror(errno)); return (NULL); + } r->fd = fd; - r->mode = mode; + r->mode = mode == CUPS_RASTER_WRITE_COMPRESSED ? CUPS_RASTER_WRITE : mode; if (mode == CUPS_RASTER_READ) { @@ -148,6 +156,8 @@ cupsRasterOpen(int fd, /* I - File descriptor */ if (!cups_read(r->fd, (unsigned char *)&(r->sync), sizeof(r->sync))) { + _cupsRasterAddError("Unable to read header from raster stream: %s\n", + strerror(errno)); free(r); return (NULL); } @@ -159,6 +169,7 @@ cupsRasterOpen(int fd, /* I - File descriptor */ r->sync != CUPS_RASTER_SYNCv2 && r->sync != CUPS_RASTER_REVSYNCv2) { + _cupsRasterAddError("Unknown raster format %08x!\n", r->sync); free(r); return (NULL); } @@ -178,11 +189,19 @@ cupsRasterOpen(int fd, /* I - File descriptor */ * Open for write - put sync word... */ - r->sync = CUPS_RASTER_SYNC; + if (mode == CUPS_RASTER_WRITE_COMPRESSED) + { + r->compressed = 1; + r->sync = CUPS_RASTER_SYNCv2; + } + else + r->sync = CUPS_RASTER_SYNC; if (cups_write(r->fd, (unsigned char *)&(r->sync), sizeof(r->sync)) < sizeof(r->sync)) { + _cupsRasterAddError("Unable to write raster stream header: %s\n", + strerror(errno)); free(r); return (NULL); } @@ -524,6 +543,10 @@ cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */ unsigned char *p, /* I - Bytes to write */ unsigned len)/* I - Number of bytes to write */ { + int bytes; /* Bytes read */ + unsigned remaining; /* Bytes remaining */ + + #ifdef DEBUG fprintf(stderr, "cupsRasterWritePixels(r=%p, p=%p, len=%u), remaining=%u\n", r, p, len, r->remaining); @@ -532,13 +555,113 @@ cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */ if (r == NULL || r->mode != CUPS_RASTER_WRITE || r->remaining == 0) return (0); + if (!r->compressed) + { + /* + * Without compression, just write the raster data raw... + */ + + r->remaining -= len / r->header.cupsBytesPerLine; + + return (cups_write(r->fd, p, len)); + } + /* - * No write compression, just write the raster data raw... + * Otherwise, compress each line... */ - r->remaining -= len / r->header.cupsBytesPerLine; + for (remaining = len; remaining > 0; remaining -= bytes, p += bytes) + { + /* + * Figure out the number of remaining bytes on the current line... + */ + + if ((bytes = remaining) > (r->pend - r->pcurrent)) + bytes = r->pend - r->pcurrent; + + if (r->count > 0) + { + /* + * Check to see if this line is the same as the previous line... + */ + + if (memcmp(p, r->pcurrent, bytes)) + { + if (!cups_raster_write(r, r->pixels)) + return (0); + + r->count = 0; + } + else + { + /* + * Mark more bytes as the same... + */ + + r->pcurrent += bytes; + + if (r->pcurrent >= r->pend) + { + /* + * Increase the repeat count... + */ + + r->count ++; + r->pcurrent = r->pixels; + + /* + * Flush out this line if it is the last one... + */ + + r->remaining --; + + if (r->remaining == 0) + return (cups_raster_write(r, r->pixels)); + else if (r->count == 256) + { + if (cups_raster_write(r, r->pixels) == 0) + return (0); - return (cups_write(r->fd, p, len)); + r->count = 0; + } + } + + continue; + } + } + + if (r->count == 0) + { + /* + * Copy the raster data to the buffer... + */ + + memcpy(r->pcurrent, p, bytes); + + r->pcurrent += bytes; + + if (r->pcurrent >= r->pend) + { + /* + * Increase the repeat count... + */ + + r->count ++; + r->pcurrent = r->pixels; + + /* + * Flush out this line if it is the last one... + */ + + r->remaining --; + + if (r->remaining == 0) + return (cups_raster_write(r, r->pixels)); + } + } + } + + return (len); } @@ -839,6 +962,120 @@ cups_raster_update(cups_raster_t *r) /* I - Raster stream */ } +/* + * 'cups_raster_write()' - Write a row of compressed raster data... + */ + +static int /* O - Number of bytes written */ +cups_raster_write( + cups_raster_t *r, /* I - Raster stream */ + const unsigned char *pixels) /* I - Pixel data to write */ +{ + const unsigned char *start, /* Start of sequence */ + *ptr, /* Current pointer in sequence */ + *pend, /* End of raster buffer */ + *plast; /* Pointer to last pixel */ + unsigned char *wptr; /* Pointer into write buffer */ + int bpp, /* Bytes per pixel */ + count, /* Count */ + maxrun; /* Maximum run of 128 * bpp */ + + +#ifdef DEBUG + fprintf(stderr, "cups_raster_write(r=%p, pixels=%p)\n", r, pixels); +#endif /* DEBUG */ + + /* + * Allocate a write buffer as needed... + */ + + count = r->header.cupsBytesPerLine * 2; + if (count > r->bufsize) + { + if (r->buffer) + wptr = realloc(r->buffer, count); + else + wptr = malloc(count); + + if (!wptr) + return (-1); + + r->buffer = wptr; + r->bufsize = count; + } + + /* + * Write the row repeat count... + */ + + bpp = r->bpp; + pend = pixels + r->header.cupsBytesPerLine; + plast = pend - bpp; + wptr = r->buffer; + *wptr++ = r->count - 1; + maxrun = 128 * bpp; + + /* + * Write using a modified TIFF "packbits" compression... + */ + + for (ptr = pixels; ptr < pend;) + { + start = ptr; + ptr += bpp; + + if (ptr == pend) + { + /* + * Encode a single pixel at the end... + */ + + *wptr++ = 0; + for (count = bpp; count > 0; count --) + *wptr++ = *start++; + } + else if (!memcmp(start, ptr, bpp)) + { + /* + * Encode a sequence of repeating pixels... + */ + + for (count = 2; count < 128 && ptr < plast; count ++, ptr += bpp) + if (memcmp(ptr, ptr + bpp, bpp)) + break; + + *wptr++ = count - 1; + for (count = bpp; count > 0; count --) + *wptr++ = *ptr++; + } + else + { + /* + * Encode a sequence of non-repeating pixels... + */ + + for (count = 1; count < 127 && ptr < plast; count ++, ptr += bpp) + if (!memcmp(ptr, ptr + bpp, bpp)) + break; + + if (ptr >= plast && count < 128) + { + count ++; + ptr += bpp; + } + + *wptr++ = 257 - count; + + count *= bpp; + memcpy(wptr, start, count); + wptr += count; + } + } + + return (cups_write(r->fd, r->buffer, wptr - r->buffer)); +} + + /* * 'cups_read()' - Read bytes from a file. */ @@ -928,5 +1165,5 @@ cups_write(int fd, /* I - File descriptor */ /* - * End of "$Id: raster.c 6061 2006-10-23 00:26:52Z mike $". + * End of "$Id: raster.c 6274 2007-02-13 21:05:28Z mike $". */ diff --git a/filter/raster.h b/filter/raster.h index 27e276a15..e76bf46c2 100644 --- a/filter/raster.h +++ b/filter/raster.h @@ -1,5 +1,5 @@ /* - * "$Id: raster.h 6158 2006-12-17 01:44:21Z mike $" + * "$Id: raster.h 6274 2007-02-13 21:05:28Z mike $" * * Raster file definitions for the Common UNIX Printing System (CUPS). * @@ -159,7 +159,8 @@ typedef enum cups_jog_e /**** Jog attribute values ****/ typedef enum cups_mode_e /**** Raster modes ****/ { CUPS_RASTER_READ = 0, /* Open stream for reading */ - CUPS_RASTER_WRITE = 1 /* Open stream for writing */ + CUPS_RASTER_WRITE = 1, /* Open stream for writing */ + CUPS_RASTER_WRITE_COMPRESSED = 2 /* Open stream for compressed writing @since CUPS 1.3@ */ } cups_mode_t; typedef enum cups_order_e /**** cupsColorOrder attribute values ****/ @@ -331,6 +332,9 @@ extern unsigned cupsRasterReadHeader2(cups_raster_t *r, extern unsigned cupsRasterWriteHeader2(cups_raster_t *r, cups_page_header2_t *h); +/**** New in CUPS 1.3 ****/ +extern const char *cupsRasterErrorString(void); + # ifdef __cplusplus } # endif /* __cplusplus */ @@ -338,5 +342,5 @@ extern unsigned cupsRasterWriteHeader2(cups_raster_t *r, #endif /* !_CUPS_RASTER_H_ */ /* - * End of "$Id: raster.h 6158 2006-12-17 01:44:21Z mike $". + * End of "$Id: raster.h 6274 2007-02-13 21:05:28Z mike $". */ diff --git a/filter/rasterbench.c b/filter/rasterbench.c index b26836b4e..f954f63e0 100644 --- a/filter/rasterbench.c +++ b/filter/rasterbench.c @@ -1,5 +1,5 @@ /* - * "$Id: rasterbench.c 5671 2006-06-16 11:17:39Z mike $" + * "$Id: rasterbench.c 5667 2006-06-16 10:21:49Z mike $" * * Raster benchmark program for the Common UNIX Printing System (CUPS). * @@ -351,5 +351,5 @@ write_test(int fd) /* I - File descriptor to write to */ /* - * End of "$Id: rasterbench.c 5671 2006-06-16 11:17:39Z mike $". + * End of "$Id: rasterbench.c 5667 2006-06-16 10:21:49Z mike $". */ diff --git a/filter/rastertolabel.c b/filter/rastertolabel.c index bc4ca7c97..015447224 100644 --- a/filter/rastertolabel.c +++ b/filter/rastertolabel.c @@ -1,5 +1,5 @@ /* - * "$Id: rastertolabel.c 6236 2007-02-05 21:04:04Z mike $" + * "$Id: rastertolabel.c 6235 2007-02-05 21:03:49Z mike $" * * Label printer filter for the Common UNIX Printing System (CUPS). * @@ -30,6 +30,7 @@ * EndPage() - Finish a page of graphics. * CancelJob() - Cancel the current job... * OutputLine() - Output a line of graphics. + * PCLCompress() - Output a PCL (mode 3) compressed line. * ZPLCompress() - Output a run-length compression sequence. * main() - Main entry and processing of driver. */ @@ -48,16 +49,20 @@ /* - * This driver filter currently supports Dymo and Zebra label printers. + * This driver filter currently supports Dymo, Intellitech, and Zebra + * label printers. * * The Dymo portion of the driver has been tested with the 300, 330, - * and 330 Turbo label printers; it may also work with older models. + * and 330 Turbo label printers; it may also work with other models. * The Dymo printers support printing at 136, 203, and 300 DPI. * - * The Zebra portion of the driver has been tested with the LP-2844Z label - * printer; it may also work with other models. The driver supports EPL - * line mode, EPL page mode, ZPL, and CPCL as defined in Zebra's on-line - * developer documentation. + * The Intellitech portion of the driver has been tested with the + * Intellibar 408, 412, and 808 and supports their PCL variant. + * + * The Zebra portion of the driver has been tested with the LP-2844, + * LP-2844Z, QL-320, and QL-420 label printers; it may also work with + * other models. The driver supports EPL line mode, EPL page mode, + * ZPL, and CPCL as defined in Zebra's on-line developer documentation. */ /* @@ -71,6 +76,8 @@ #define ZEBRA_ZPL 0x12 /* Zebra ZPL-based printers */ #define ZEBRA_CPCL 0x13 /* Zebra CPCL-based printers */ +#define INTELLITECH_PCL 0x20 /* Intellitech PCL-based printers */ + /* * Globals... @@ -95,6 +102,7 @@ void StartPage(ppd_file_t *ppd, cups_page_header_t *header); void EndPage(ppd_file_t *ppd, cups_page_header_t *header); void CancelJob(int sig); void OutputLine(ppd_file_t *ppd, cups_page_header_t *header, int y); +void PCLCompress(unsigned char *line, int length); void ZPLCompress(char repeat_char, int repeat_count); @@ -147,6 +155,15 @@ Setup(ppd_file_t *ppd) /* I - PPD file */ case ZEBRA_CPCL : break; + + case INTELLITECH_PCL : + /* + * Send a PCL reset sequence. + */ + + putchar(0x1b); + putchar('E'); + break; } } @@ -213,6 +230,9 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */ fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header->cupsColorOrder); fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header->cupsColorSpace); fprintf(stderr, "DEBUG: cupsCompression = %d\n", header->cupsCompression); + fprintf(stderr, "DEBUG: cupsRowCount = %d\n", header->cupsRowCount); + fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", header->cupsRowFeed); + fprintf(stderr, "DEBUG: cupsRowStep = %d\n", header->cupsRowStep); /* * Register a signal handler to eject the current page if the @@ -355,6 +375,120 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */ printf("PAGE-WIDTH %d\r\n", header->cupsWidth); printf("PAGE-HEIGHT %d\r\n", header->cupsWidth); break; + + case INTELLITECH_PCL : + /* + * Set the media size... + */ + + printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */ + printf("\033&l0O"); /* Set portrait orientation */ + + switch (header->PageSize[1]) + { + case 540 : /* Monarch Envelope */ + printf("\033&l80A"); /* Set page size */ + break; + + case 624 : /* DL Envelope */ + printf("\033&l90A"); /* Set page size */ + break; + + case 649 : /* C5 Envelope */ + printf("\033&l91A"); /* Set page size */ + break; + + case 684 : /* COM-10 Envelope */ + printf("\033&l81A"); /* Set page size */ + break; + + case 756 : /* Executive */ + printf("\033&l1A"); /* Set page size */ + break; + + case 792 : /* Letter */ + printf("\033&l2A"); /* Set page size */ + break; + + case 842 : /* A4 */ + printf("\033&l26A"); /* Set page size */ + break; + + case 1008 : /* Legal */ + printf("\033&l3A"); /* Set page size */ + break; + + default : /* Custom size */ + printf("\033!f%dZ", header->PageSize[1] * 300 / 72); + break; + } + + printf("\033&l%dP", /* Set page length */ + header->PageSize[1] / 12); + printf("\033&l0E"); /* Set top margin to 0 */ + printf("\033&l%dX", header->NumCopies); + /* Set number copies */ + printf("\033&l0L"); /* Turn off perforation skip */ + + /* + * Print settings... + */ + + if (Page == 1) + { + if (header->cupsRowFeed) /* inPrintRate */ + printf("\033!p%dS", header->cupsRowFeed); + + if (header->cupsCompression != ~0) + /* inPrintDensity */ + printf("\033&d%dA", 30 * header->cupsCompression / 100 - 15); + + if ((choice = ppdFindMarkedChoice(ppd, "inPrintMode")) != NULL) + { + if (!strcmp(choice->choice, "Standard")) + fputs("\033!p0M", stdout); + else if (!strcmp(choice->choice, "Tear")) + { + fputs("\033!p1M", stdout); + + if (header->cupsRowCount) /* inTearInterval */ + printf("\033!n%dT", header->cupsRowCount); + } + else + { + fputs("\033!p2M", stdout); + + if (header->cupsRowStep) /* inCutInterval */ + printf("\033!n%dC", header->cupsRowStep); + } + } + } + + /* + * Setup graphics... + */ + + printf("\033*t%dR", header->HWResolution[0]); + /* Set resolution */ + + printf("\033*r%dS", header->cupsWidth); + /* Set width */ + printf("\033*r%dT", header->cupsHeight); + /* Set height */ + + printf("\033&a0H"); /* Set horizontal position */ + printf("\033&a0V"); /* Set vertical position */ + printf("\033*r1A"); /* Start graphics */ + printf("\033*b3M"); /* Set compression */ + + /* + * Allocate compression buffers... + */ + + CompBuffer = malloc(2 * header->cupsBytesPerLine + 1); + LastBuffer = malloc(header->cupsBytesPerLine); + LastSet = 0; + break; } /* @@ -596,6 +730,11 @@ EndPage(ppd_file_t *ppd, /* I - PPD file */ puts("PRINT\r"); break; + + case INTELLITECH_PCL : + printf("\033*rB"); /* End GFX */ + printf("\014"); /* Eject current page */ + break; } fflush(stdout); @@ -799,7 +938,160 @@ OutputLine(ppd_file_t *ppd, /* I - PPD file */ fflush(stdout); } break; + + case INTELLITECH_PCL : + if (Buffer[0] || + memcmp(Buffer, Buffer + 1, header->cupsBytesPerLine - 1)) + { + if (Feed) + { + printf("\033*b%dY", Feed); + Feed = 0; + LastSet = 0; + } + + PCLCompress(Buffer, header->cupsBytesPerLine); + } + else + Feed ++; + break; + } +} + + +/* + * 'PCLCompress()' - Output a PCL (mode 3) compressed line. + */ + +void +PCLCompress(unsigned char *line, /* I - Line to compress */ + int length) /* I - Length of line */ +{ + unsigned char *line_ptr, /* Current byte pointer */ + *line_end, /* End-of-line byte pointer */ + *comp_ptr, /* Pointer into compression buffer */ + *start, /* Start of compression sequence */ + *seed; /* Seed buffer pointer */ + int count, /* Count of bytes for output */ + offset; /* Offset of bytes for output */ + + + /* + * Do delta-row compression... + */ + + line_ptr = line; + line_end = line + length; + + comp_ptr = CompBuffer; + seed = LastBuffer; + + while (line_ptr < line_end) + { + /* + * Find the next non-matching sequence... + */ + + start = line_ptr; + + if (!LastSet) + { + /* + * The seed buffer is invalid, so do the next 8 bytes, max... + */ + + offset = 0; + + if ((count = line_end - line_ptr) > 8) + count = 8; + + line_ptr += count; + } + else + { + /* + * The seed buffer is valid, so compare against it... + */ + + while (*line_ptr == *seed && + line_ptr < line_end) + { + line_ptr ++; + seed ++; + } + + if (line_ptr == line_end) + break; + + offset = line_ptr - start; + + /* + * Find up to 8 non-matching bytes... + */ + + start = line_ptr; + count = 0; + while (*line_ptr != *seed && + line_ptr < line_end && + count < 8) + { + line_ptr ++; + seed ++; + count ++; + } + } + + /* + * Place mode 3 compression data in the buffer; see HP manuals + * for details... + */ + + if (offset >= 31) + { + /* + * Output multi-byte offset... + */ + + *comp_ptr++ = ((count - 1) << 5) | 31; + + offset -= 31; + while (offset >= 255) + { + *comp_ptr++ = 255; + offset -= 255; + } + + *comp_ptr++ = offset; + } + else + { + /* + * Output single-byte offset... + */ + + *comp_ptr++ = ((count - 1) << 5) | offset; + } + + memcpy(comp_ptr, start, count); + comp_ptr += count; } + + line_ptr = CompBuffer; + line_end = comp_ptr; + + /* + * Set the length of the data and write it... + */ + + printf("\033*b%dW", comp_ptr - CompBuffer); + fwrite(CompBuffer, comp_ptr - CompBuffer, 1, stdout); + + /* + * Save this line as a "seed" buffer for the next... + */ + + memcpy(LastBuffer, line, length); + LastSet = 1; } @@ -1014,5 +1306,5 @@ main(int argc, /* I - Number of command-line arguments */ /* - * End of "$Id: rastertolabel.c 6236 2007-02-05 21:04:04Z mike $". + * End of "$Id: rastertolabel.c 6235 2007-02-05 21:03:49Z mike $". */ diff --git a/filter/testraster.c b/filter/testraster.c index dd1c76ae8..f6d9db8a4 100644 --- a/filter/testraster.c +++ b/filter/testraster.c @@ -1,9 +1,9 @@ /* - * "$Id: testraster.c 6158 2006-12-17 01:44:21Z mike $" + * "$Id: testraster.c 6331 2007-03-12 16:07:31Z mike $" * * Raster test program routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2005 by Easy Software Products. + * Copyright 1997-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -49,7 +49,13 @@ * Test PS commands and header... */ -static const char *test_code = +static const char *dsc_code = +"[{\n" +"%%BeginFeature: *PageSize Tabloid\n" +"<>setpagedevice\n" +"%%EndFeature\n" +"} stopped cleartomark\n"; +static const char *setpagedevice_code = "<<" "/MediaClass(Media Class)" "/MediaColor((Media Color))" @@ -138,7 +144,7 @@ static const char *test_code = "/cupsPreferredBitsPerColor 17" ">> setpagedevice"; -static cups_page_header2_t test_header = +static cups_page_header2_t setpagedevice_header = { "Media Class", /* MediaClass */ "(Media Color)", /* MediaColor */ @@ -199,6 +205,10 @@ static cups_page_header2_t test_header = * Local functions... */ +static int do_ppd_tests(const char *filename, int num_options, + cups_option_t *options); +static int do_ps_tests(void); +static int do_raster_tests(void); static void print_changes(cups_page_header2_t *header, cups_page_header2_t *expected); @@ -208,19 +218,121 @@ static void print_changes(cups_page_header2_t *header, */ int /* O - Exit status */ -main(void) +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ { - int page, x, y; /* Looping vars */ - FILE *fp; /* Raster file */ - cups_raster_t *r; /* Raster stream */ - cups_page_header2_t header, /* Page header */ - expected; /* Expected page header */ - unsigned char data[2048]; /* Raster data */ - int preferred_bits; /* Preferred bits */ - int errors; /* Number of errors */ + int errors; /* Number of errors */ + + + if (argc == 1) + { + errors = do_ps_tests(); + errors += do_raster_tests(); + } + else + { + int i; /* Looping var */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + + + for (errors = 0, num_options = 0, options = NULL, i = 1; i < argc; i ++) + { + if (argv[i][0] == '-') + { + if (argv[i][1] == 'o') + { + if (argv[i][2]) + num_options = cupsParseOptions(argv[i] + 2, num_options, &options); + else + { + i ++; + if (i < argc) + num_options = cupsParseOptions(argv[i], num_options, &options); + else + { + puts("Usage: testraster [-o name=value ...] [filename.ppd ...]"); + return (1); + } + } + } + else + { + puts("Usage: testraster [-o name=value ...] [filename.ppd ...]"); + return (1); + } + } + else + errors += do_ppd_tests(argv[i], num_options, options); + } + + cupsFreeOptions(num_options, options); + } + + return (errors); +} + + +/* + * 'do_ppd_tests()' - Test the default option commands in a PPD file. + */ + +static int /* O - Number of errors */ +do_ppd_tests(const char *filename, /* I - PPD file */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + ppd_file_t *ppd; /* PPD file data */ + cups_page_header2_t header; /* Page header */ + + + printf("\"%s\": ", filename); + fflush(stdout); + + if ((ppd = ppdOpenFile(filename)) == NULL) + { + ppd_status_t status; /* Status from PPD loader */ + int line; /* Line number containing error */ + + + status = ppdLastError(&line); + + puts("FAIL (bad PPD file)"); + printf(" %s on line %d\n", ppdErrorString(status), line); + + return (1); + } + + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, NULL)) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + + return (1); + } + else + { + puts("PASS"); + + return (0); + } +} + + +/* + * 'do_ps_tests()' - Test standard PostScript commands. + */ + +static int +do_ps_tests(void) +{ + cups_page_header2_t header; /* Page header */ + int preferred_bits; /* Preferred bits */ + int errors = 0; /* Number of errors */ - errors = 0; /* * Test PS exec code... @@ -233,12 +345,14 @@ main(void) header.Collate = CUPS_TRUE; preferred_bits = 0; - if (_cupsRasterExecPS(&header, &preferred_bits, test_code)) + if (_cupsRasterExecPS(&header, &preferred_bits, setpagedevice_code)) { puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); errors ++; } - else if (preferred_bits != 17 || memcmp(&header, &test_header, sizeof(header))) + else if (preferred_bits != 17 || + memcmp(&header, &setpagedevice_header, sizeof(header))) { puts("FAIL (bad header)"); @@ -246,7 +360,7 @@ main(void) printf(" cupsPreferredBitsPerColor %d, expected 17\n", preferred_bits); - print_changes(&test_header, &header); + print_changes(&setpagedevice_header, &header); errors ++; } else @@ -262,6 +376,7 @@ main(void) "setpagedevice\n")) { puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); errors ++; } else if (header.PageSize[0] != 792 || header.PageSize[1] != 612) @@ -284,6 +399,7 @@ main(void) "pop pop pop")) { puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); errors ++; } else @@ -310,6 +426,24 @@ main(void) puts("PASS"); } + fputs("_cupsRasterExecPS(\"%%Begin/EndFeature code\"): ", stdout); + fflush(stdout); + + if (_cupsRasterExecPS(&header, &preferred_bits, dsc_code)) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + errors ++; + } + else if (header.PageSize[0] != 792 || header.PageSize[1] != 1224) + { + printf("FAIL (bad PageSize [%d %d], expected [792 1224])\n", + header.PageSize[0], header.PageSize[1]); + errors ++; + } + else + puts("PASS"); + #if 0 fputs("_cupsRasterExecPS(\"\"): ", stdout); fflush(stdout); @@ -397,6 +531,26 @@ main(void) puts("PASS"); #endif /* 0 */ + return (errors); +} + + +/* + * 'do_raster_tests()' - Test reading and writing of raster data. + */ + +static int /* O - Number of errors */ +do_raster_tests(void) +{ + int page, x, y; /* Looping vars */ + FILE *fp; /* Raster file */ + cups_raster_t *r; /* Raster stream */ + cups_page_header2_t header, /* Page header */ + expected; /* Expected page header */ + unsigned char data[2048]; /* Raster data */ + int errors = 0; /* Number of errors */ + + /* * Test writing... */ @@ -690,11 +844,10 @@ main(void) cupsRasterClose(r); fclose(fp); - return (errors > 0); + return (errors); } - /* * 'print_changes()' - Print differences in the page header. */ @@ -935,5 +1088,5 @@ print_changes( /* - * End of "$Id: testraster.c 6158 2006-12-17 01:44:21Z mike $". + * End of "$Id: testraster.c 6331 2007-03-12 16:07:31Z mike $". */ diff --git a/filter/texttops.c b/filter/texttops.c index 80c58014d..33fc4116b 100644 --- a/filter/texttops.c +++ b/filter/texttops.c @@ -1,9 +1,9 @@ /* - * "$Id: texttops.c 6003 2006-10-02 16:26:04Z mike $" + * "$Id: texttops.c 6288 2007-02-19 12:59:55Z mike $" * * Text to PostScript filter for the Common UNIX Printing System (CUPS). * - * Copyright 1993-2005 by Easy Software Products. + * Copyright 1993-2007 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -812,7 +812,7 @@ WriteProlog(const char *title, /* I - Title of job */ puts("% Reencode base fonts"); - for (i = 1 + PrettyPrint; i >= 0; i --) + for (i = PrettyPrint ? 2 : 1; i >= 0; i --) for (j = 0; j < NumFonts; j ++) { printf("/%s findfont\n", Fonts[j][i]); @@ -831,7 +831,7 @@ WriteProlog(const char *title, /* I - Title of job */ puts("% Create composite fonts..."); - for (i = 1 + PrettyPrint; i >= 0; i --) + for (i = PrettyPrint ? 2 : 1; i >= 0; i --) { puts("8 dict begin"); puts("/FontType 0 def/FontMatrix[1.0 0 0 1.0 0 0]def/FMapType 2 def/Encoding["); @@ -1307,5 +1307,5 @@ write_text(const char *s) /* I - String to write */ /* - * End of "$Id: texttops.c 6003 2006-10-02 16:26:04Z mike $". + * End of "$Id: texttops.c 6288 2007-02-19 12:59:55Z mike $". */ diff --git a/init/cups.sh.in b/init/cups.sh.in index 975af256c..cef5ad2d0 100755 --- a/init/cups.sh.in +++ b/init/cups.sh.in @@ -1,10 +1,10 @@ #!/bin/sh # -# "$Id: cups.sh.in 5118 2006-02-16 14:29:53Z mike $" +# "$Id: cups.sh.in 6332 2007-03-12 16:08:51Z mike $" # # Startup/shutdown script for the Common UNIX Printing System (CUPS). # -# Copyright 1997-2005 by Easy Software Products, all rights reserved. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the # property of Easy Software Products and are protected by Federal @@ -135,6 +135,20 @@ fi unset TMPDIR +# +# Make sure we have the standard program directories in the path +# since some operating systems (this means YOU HP-UX!) don't +# provide a standard path on boot-up... +# + +if "x$PATH" = x; then + PATH="/bin:/usr/bin:/sbin:/usr/sbin" +else + PATH="/bin:/usr/bin:/sbin:/usr/sbin:$PATH" +fi + +export PATH + # # See if the CUPS server (cupsd) is running... # @@ -201,6 +215,16 @@ case $1 in fi ;; + start_msg) + # HP-UX non-standard... + echo "Starting CUPS Server" + ;; + + stop_msg) + # HP-UX non-standard... + echo "Starting CUPS Server" + ;; + *) echo "Usage: cups {reload|restart|start|status|stop}" exit 1 @@ -215,5 +239,5 @@ exit 0 # -# End of "$Id: cups.sh.in 5118 2006-02-16 14:29:53Z mike $". +# End of "$Id: cups.sh.in 6332 2007-03-12 16:08:51Z mike $". # diff --git a/init/org.cups.cupsd.plist b/init/org.cups.cupsd.plist index c4341fc15..856ee96e5 100644 --- a/init/org.cups.cupsd.plist +++ b/init/org.cups.cupsd.plist @@ -6,13 +6,21 @@ org.cups.cupsd OnDemand + KeepAlive + + PathState + + /private/var/run/cups/cupsd + + + + RunAtLoad + ProgramArguments /usr/sbin/cupsd -l - RunAtLoad - ServiceIPC Sockets diff --git a/locale/Makefile b/locale/Makefile index 0d3a6f663..87d56d55a 100644 --- a/locale/Makefile +++ b/locale/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5609 2006-05-30 20:31:10Z mike $" +# "$Id: Makefile 6209 2007-01-23 15:38:01Z mike $" # # Locale file makefile for the Common UNIX Printing System (CUPS). # @@ -87,7 +87,7 @@ pot: --msgid-bugs-address="http://www.cups.org/str.php" \ */*.c (cat cups.header; \ - tail +6 cups.pot | sed -e '1,$$s/PACKAGE VERSION/CUPS 1.2/' \ + tail +6 cups.pot | sed -e '1,$$s/PACKAGE VERSION/CUPS 1.3/' \ -e '1,$$s/charset=CHARSET/charset=utf-8/'; \ cat cups.footer) > cups.pot.N mv cups.pot.N cups.pot @@ -112,5 +112,5 @@ translate.o: ../cups/http.h ../cups/i18n.h ../cups/language.h ../cups/string.h # -# End of "$Id: Makefile 5609 2006-05-30 20:31:10Z mike $". +# End of "$Id: Makefile 6209 2007-01-23 15:38:01Z mike $". # diff --git a/locale/cups.pot b/locale/cups.pot index c8459bd81..fc90515cd 100644 --- a/locale/cups.pot +++ b/locale/cups.pot @@ -29,7 +29,7 @@ msgid "" msgstr "" "Project-Id-Version: CUPS 1.2\n" "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2007-01-23 09:19-0500\n" +"POT-Creation-Date: 2007-01-23 09:44-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -2631,6 +2631,9 @@ msgstr "" msgid "Unable to run \"%s\": %s\n" msgstr "" +msgid "Enter your username and password or the root username and password to access this page. If you are using Kerberos authentication, make sure you have a valid Kerberos ticket." +msgstr "" + #, c-format msgid "Job #%d is already canceled - can't cancel." msgstr "" @@ -2653,6 +2656,10 @@ msgid "" " REF: Page 72, section 5.5\n" msgstr "" +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr "" + #, c-format msgid "lpoptions: Unable to get PPD file for %s: %s\n" msgstr "" diff --git a/locale/cups_de.po b/locale/cups_de.po index 0b9237974..dd14f004a 100644 --- a/locale/cups_de.po +++ b/locale/cups_de.po @@ -25,7 +25,7 @@ msgid "" msgstr "" "Project-Id-Version: CUPS 1.2\n" "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2007-01-23 09:19-0500\n" +"POT-Creation-Date: 2007-01-23 09:44-0500\n" "PO-Revision-Date: 2006-07-17 19:55+0200\n" "Last-Translator: Bernd Krumböck \n" "Language-Team: Deutsch\n" @@ -2973,6 +2973,15 @@ msgstr "Kann Windows Druckertreiber nicht setzen (%d)!\n" msgid "Unable to run \"%s\": %s\n" msgstr "cupsaddsmb: Kann \"%s\" nicht ausführen: %s\n" +#, fuzzy +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Für Zugang Benutzername und Passwort (oder Benutzername und Passwort für " +"root) eingeben." + #, fuzzy, c-format msgid "Job #%d is already canceled - can't cancel." msgstr "Auftrag #%d wurde bereits abgebrochen - abbrechen nicht möglich." @@ -2997,6 +3006,10 @@ msgstr "" " **FEHLGESCHLAGEN** 1284DeviceId muss 1284DeviceID sein!\n" " REF: Seite 72, Kapitel 5.5\n" +#, fuzzy, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d FEHLER%s GEFUNDEN\n" + #, fuzzy, c-format msgid "lpoptions: Unable to get PPD file for %s: %s\n" msgstr "lpoptions: Kann PPD für %s nicht öffnen!\n" diff --git a/locale/cups_es.po b/locale/cups_es.po index 1c88e6ab4..a66c2ef7f 100644 --- a/locale/cups_es.po +++ b/locale/cups_es.po @@ -25,14 +25,13 @@ msgid "" msgstr "" "Project-Id-Version: CUPS 1.2\n" "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2007-01-23 09:19-0500\n" -"PO-Revision-Date: 2007-01-29 22:15+0100\n" +"POT-Creation-Date: 2007-01-23 09:44-0500\n" +"PO-Revision-Date: 2007-01-29 22:21+0100\n" "Last-Translator: Juan Pablo González Riopedre \n" "Language-Team: Spanish\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Bookmarks: -1,-1,-1,-1,-1,693,-1,-1,-1,-1\n" msgid "Options Installed" msgstr "Opciones instaladas" @@ -2842,6 +2841,9 @@ msgstr "No se ha podido configurar el controlador de impresora de Windows (%d)." msgid "Unable to run \"%s\": %s\n" msgstr "No se ha podido ejecutar \"%s\": %s\n" +msgid "Enter your username and password or the root username and password to access this page. If you are using Kerberos authentication, make sure you have a valid Kerberos ticket." +msgstr "Introduzca su nombre de usuario y contraseña o el nombre de usuario y contraseña de root para poder acceder a esta página. Si está usando autentificación Kerberos, asegúrese de que tiene un ticket Kerberos válido." + #, c-format msgid "Job #%d is already canceled - can't cancel." msgstr "El trabajo #%d ya está cancelado - no se puede cancelar." @@ -2866,6 +2868,10 @@ msgstr "" " **FALLO** %s debe ser 1284DeviceID.\n" " REF: Página 72, sección 5.5\n" +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d ERRORES ENCONTRADOS\n" + #, c-format msgid "lpoptions: Unable to get PPD file for %s: %s\n" msgstr "lpoptions: No se ha podido obtener el archivo PPD para %s: %s\n" diff --git a/locale/cups_et.po b/locale/cups_et.po index f9a972bd7..69296a24b 100644 --- a/locale/cups_et.po +++ b/locale/cups_et.po @@ -25,7 +25,7 @@ msgid "" msgstr "" "Project-Id-Version: CUPS 1.2\n" "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2007-01-23 09:19-0500\n" +"POT-Creation-Date: 2007-01-23 09:44-0500\n" "PO-Revision-Date: 2006-09-93 01:41+0200\n" "Last-Translator: Marek Laane \n" "Language-Team: Estonian \n" @@ -2930,6 +2930,15 @@ msgstr "Ei õnnestu määrata Windowsi printeridraiverit (%d)!\n" msgid "Unable to run \"%s\": %s\n" msgstr "cupsaddsmb: \"%s\" käivitamine ebaõnnestus: %s\n" +#, fuzzy +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Selle lehekülje avamiseks andke enda või administraatori (root) kasutajanimi " +"ja parool." + #, fuzzy, c-format msgid "Job #%d is already canceled - can't cancel." msgstr "Töö nr %d on juba katkestatud - enam ei saa katkestada." @@ -2954,6 +2963,10 @@ msgstr "" " **EBAÕNN** 1284DeviceId peab olema 1284DeviceID!\n" " Viide: lk 72, sektsioon 5.5\n" +#, fuzzy, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d VIGA%s LEITUD\n" + #, fuzzy, c-format msgid "lpoptions: Unable to get PPD file for %s: %s\n" msgstr "lpoptions: ei õnnestu avada PPD-faili %s jaoks!\n" diff --git a/locale/cups_fr.po b/locale/cups_fr.po index cb1e3e3d4..1859f5ffa 100644 --- a/locale/cups_fr.po +++ b/locale/cups_fr.po @@ -2840,2851 +2840,6 @@ msgstr "" " REF: Page 72, section 5.5\n" -# -# End of "$Id$". -# -# -# "$Id$" -# -# Message catalog template for the Common UNIX Printing System (CUPS). -# -# Copyright 2005-2006 by Easy Software Products. -# -# These coded instructions, statements, and computer programs are the -# property of Easy Software Products and are protected by Federal -# copyright law. Distribution and use rights are outlined in the file -# "LICENSE.txt" which should have been included with this file. If this -# file is missing or damaged please contact Easy Software Products -# at: -# -# Attn: CUPS Licensing Information -# Easy Software Products -# 44141 Airport View Drive, Suite 204 -# Hollywood, Maryland 20636 USA -# -# Voice: (301) 373-9600 -# EMail: cups-info@cups.org -# WWW: http://www.cups.org -# -# -# NDT: I did not translate the messages used in conformance, DSC and PPD tests, -# because they are destined to developers only, as far as I understand. -# - -msgid "" -msgstr "" -"Project-Id-Version: CUPS 1.2\n" -"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2006-05-21 10:08-0400\n" -"PO-Revision-Date: 2007-01-25 19:55+0200\n" -"Last-Translator: Philippe Combes \n" -"Language-Team: Français\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "Options Installed" -msgstr "Options Installées" - -msgid "Class" -msgstr "Classe" - -msgid "Printer" -msgstr "Imprimante" - -msgid "Extra" -msgstr "Supplémentaire" - -msgid "General" -msgstr "Généralités" - -msgid "Media Size" -msgstr "Taille du support" - -msgid "Media Type" -msgstr "Type de support" - -msgid "Media Source" -msgstr "Source du support" - -msgid "Output Mode" -msgstr "Mode de sortie" - -msgid "Resolution" -msgstr "Résolution" - -msgid "Variable" -msgstr "Variable" - -msgid "Yes" -msgstr "Oui" - -msgid "No" -msgstr "Non" - -msgid "Auto" -msgstr "Auto" - -msgid "Enter your username and password or the root username and password to access this page." -msgstr "Entrez votre nom d'utilisateur et votre mot de passe UNIX ou bien identifiez-vous en tant que « root » pour accéder à cette page." - -msgid "You must use a https: URL to access this page." -msgstr "Vous devez utiliser une URL https: pour accéder à cette page." - -#, c-format -msgid "Bad request version number %d.%d!" -msgstr "La requête a un numéro de version erroné : %d.%d !" - -msgid "No attributes in request!" -msgstr "Aucun attribut dans la requête !" - -#, c-format -msgid "Attribute groups are out of order (%x < %x)!" -msgstr "Les groupes d'attributs ne sont pas dans le bon ordre (%x < %x) !" - -msgid "Missing required attributes!" -msgstr "Il manque des attributs indispensables !" - -#, c-format -msgid "%s not supported!" -msgstr "%s: opération non gérée !" - -msgid "The printer or class was not found." -msgstr "L'imprimante ou la classe n'a pas été trouvée." - -msgid "The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." -msgstr "L'URI de l'imprimante doit suivre le format « ipp://NOM_MACHINE/classes/NOM_CLASSE »." - -#, c-format -msgid "The printer-uri \"%s\" contains invalid characters." -msgstr "L'URI de l'imprimante « %s » contient des caractères ." - -#, c-format -msgid "A printer named \"%s\" already exists!" -msgstr "Il existe déjà une imprimante appelée « %s » !" - -#, c-format -msgid "Attempt to set %s printer-state to bad value %d!" -msgstr "Tentative de donner une valeur erronée au paramètre « printer-state » : %d !" - -#, c-format -msgid "add_class: Unknown printer-op-policy \"%s\"." -msgstr "add_class: L'attribut « printer-op-policy » a une valeur non comprise : « %s »." - -#, c-format -msgid "add_class: Unknown printer-error-policy \"%s\"." -msgstr "add_class: L'attribut « printer-error-policy » a une valeur non comprise : « %s »." - -msgid "Unable to allocate memory for file types!" -msgstr "Impossible d'allouer de la mémoire pour les types de fichiers !" - -#, c-format -msgid "Character set \"%s\" not supported!" -msgstr "Jeu de caractères « %s » non géré !" - -#, c-format -msgid "Language \"%s\" not supported!" -msgstr "Langue « %s » non gérée !" - -#, c-format -msgid "The notify-user-data value is too large (%d > 63 octets)!" -msgstr "La valeur de l'attribut « notify-user-data » est trop grande ( %d > 63 octets ) !" - -msgid "The notify-lease-duration attribute cannot be used with job subscriptions." -msgstr "L'attribut « notify-lease-duration » ne peut pas être utilisé dans une souscription de tâche." - -msgid "The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." -msgstr "L'URI de l'imprimante doit suivre le format « ipp://NOM_MACHINE/printers/NOM_CLASSE »." - -#, c-format -msgid "A class named \"%s\" already exists!" -msgstr ""Il existe déjà une classe appelée « %s » !" - -#, c-format -msgid "File device URIs have been disabled! To enable, see the FileDevice directive in \"%s/cupsd.conf\"." -msgstr "L'impression dans un fichier a été désactivée ! Pour l'activer, cf. la directive « FileDevice » dans « %s/cupsd.conf »." - -#, c-format -msgid "Bad device-uri \"%s\"!" -msgstr "Valeur erronée pour le paramètre « device-uri » : « %s » !" - -#, c-format -msgid "Bad port-monitor \"%s\"!" -msgstr "Valeur erronée pour le paramètre « port-monitor » : « %s » !" - -#, c-format -msgid "Bad printer-state value %d!" -msgstr "Valeur erronée pour le paramètre « printer-state » : « %s » !" - -#, c-format -msgid "Unknown printer-op-policy \"%s\"." -msgstr "L'attribut « printer-op-policy » a une valeur non comprise : « %s »." - -#, c-format -msgid "Unknown printer-error-policy \"%s\"." -msgstr "L'attribut « printer-error-policy » a une valeur non comprise : « %s »." - -#, c-format -msgid "Unable to copy interface script - %s!" -msgstr "Impossible de copier le « script » d'interface - « %s » !" - -#, c-format -msgid "Unable to copy PPD file - %s!" -msgstr "Impossible de copier le fichier PPD - « %s » !" - -msgid "Unable to copy PPD file!" -msgstr "Impossible de copier le fichier PPD !" - -msgid "Got a printer-uri attribute but no job-id!" -msgstr "Attribut « printer-uri » trouvé mais pas de « job-id »" - -#, c-format -msgid "Bad job-uri attribute \"%s\"!" -msgstr "Valeur erronée pour l'attribut « job-uri » : « %s » !" - -#, c-format -msgid "Job #%d doesn't exist!" -msgstr "La tâche n°%d n'existe pas !" - -#, c-format -msgid "Job #%d is not held for authentication!" -msgstr "La tâche n°%d n'est pas en attente d'authentification !" - -#, c-format -msgid "You are not authorized to authenticate job #%d owned by \"%s\"!" -msgstr "Vous n'avez pas l'autorisation d'authentifier la tâche n°%d appartenant à « %s » !" - -msgid "The printer-uri attribute is required!" -msgstr "L'attribut « printer-uri » est indispensable !" - -msgid "Missing requesting-user-name attribute!" -msgstr "Il manque l'attribut « requesting-user-name » !" - -#, c-format -msgid "The printer-uri \"%s\" is not valid." -msgstr "L'attribut « printer-uri » est incorrect : « %s »." - -#, c-format -msgid "No active jobs on %s!" -msgstr "Il n'y a pas de tâche en cours sur « %s » !" - -#, c-format -msgid "You are not authorized to delete job #%d owned by \"%s\"!" -msgstr "Vous n'avez pas l'autorisation de supprimer la tâche n°%d appartenant à « %s » !" - -#, c-format -msgid "Job #%d is already %s - can't cancel." -msgstr "La tâche n°%d est déjà « %s » - impossible de l'annuler." - -msgid "The printer or class is not shared!" -msgstr "L'imprimante ou la classe n'est pas partagée !" - -#, c-format -msgid "Destination \"%s\" is not accepting jobs." -msgstr "La destination « %s » n'accepte aucune tâche." - -#, c-format -msgid "Bad copies value %d." -msgstr "Nombre de copies erroné : %d." - -#, c-format -msgid "Bad page-ranges values %d-%d." -msgstr "Intervalle de pages erroné : %d-%d." - -msgid "Too many active jobs." -msgstr "Trop de tâches en cours." - -msgid "Quota limit reached." -msgstr "Quota atteint." - -#, c-format -msgid "Unable to add job for destination \"%s\"!" -msgstr "Impossible d'ajouter une tâche pour la destination « %s » !" - -msgid "No subscription attributes in request!" -msgstr "Pas d'attribut de souscription dans la requête !" - -msgid "notify-events not specified!" -msgstr "Attribut « notify-events » non renseigné !" - -#, c-format -msgid "Job %d not found!" -msgstr "La tâche n°%d n'a pas été trouvée !" - -msgid "No default printer" -msgstr "Pas d'imprimante par défaut" - -msgid "cups-deviced failed to execute." -msgstr "L'exécution de « cups-deviced » a échouée." - -msgid "cups-driverd failed to execute." -msgstr "L'exécution de « cups-driverd » a échouée." - -msgid "No destinations added." -msgstr "Aucune destination ajoutée." - -#, c-format -msgid "notify-subscription-id %d no good!" -msgstr "Valeur erronée pour l'attribut « notify-subscription-id » : %d !" - -#, c-format -msgid "Job #%s does not exist!" -msgstr "La tâche n°%s n'existe pas !" - -#, c-format -msgid "Job #%d does not exist!" -msgstr "La tâche n°%d n'existe pas !" - -msgid "No subscriptions found." -msgstr "Aucune souscription trouvée." - -#, c-format -msgid "Not authorized to hold job #%d owned by \"%s\"!" -msgstr "Vous n'avez pas l'autorisation de retenir la tâche n°%d appartenant à « %s » !" - -#, c-format -msgid "Job #%d is finished and cannot be altered!" -msgstr "La tâche n°%d est terminée et ne peut plus être modifiée !" - -#, c-format -msgid "You are not authorized to move job #%d owned by \"%s\"!" -msgstr "Vous n'avez pas l'autorisation de transférer la tâche n°%d appartenant à « %s » !" - -msgid "job-printer-uri attribute missing!" -msgstr "Il manque l'attribut « job-printer-uri » !" - -#, c-format -msgid "Unsupported compression \"%s\"!" -msgstr "La compression « %s » n'est pas gérée !" - -msgid "No file!?!" -msgstr "Pas de fichier !?!" - -#, c-format -msgid "Could not scan type \"%s\"!" -msgstr "Impossible de comprendre le format « %s » !" - -#, c-format -msgid "Unsupported format '%s/%s'!" -msgstr "Le format « %s » n'est pas géré !" - -msgid "Printer not shared!" -msgstr "L'imprimante n'est pas partagée !" - -#, c-format -msgid "Too many jobs - %d jobs, max jobs is %d." -msgstr "Trop de tâches - %d tâches pour un maximum de %d." - -#, c-format -msgid "Job #%d is not held!" -msgstr "La tâche n°%d n'est pas retenue !" - -#, c-format -msgid "You are not authorized to release job id %d owned by \"%s\"!" -msgstr "Vous n'avez pas l'autorisation de libérer la tâche n°%d appartenant à « %s » !" - -#, c-format -msgid "Job #%d is not complete!" -msgstr "La tâche n°%d n'est pas terminée !" - -#, c-format -msgid "Job #%d cannot be restarted - no files!" -msgstr "La tâche n°%d ne peut être redémarrée - aucun fichier !" - -#, c-format -msgid "You are not authorized to restart job id %d owned by \"%s\"!" -msgstr "Vous n'avez pas l'autorisation de redémarrer la tâche n°%d appartenant à « %s » !" - -#, c-format -msgid "You are not authorized to send document for job #%d owned by \"%s\"!" -msgstr "Vous n'avez pas l'autorisation d'envoyer un document pour la tâche n°%d appartenant à « %s » !" - -#, c-format -msgid "Bad document-format \"%s\"!" -msgstr "Format de document erroné : « %s » !" - -#, c-format -msgid "You are not authorized to alter job id %d owned by \"%s\"!" -msgstr "Vous n'avez pas l'autorisation de modifier la tâche n°%d appartenant à « %s » !" - -#, c-format -msgid "%s cannot be changed." -msgstr "Impossible de modifier « %s »" - -msgid "Bad job-priority value!" -msgstr "Valeur erronée pour l'attribut « job-priority » !" - -msgid "Job is completed and cannot be changed." -msgstr "La tâche est terminée et ne peut être modifiée." - -msgid "Bad job-state value!" -msgstr "Valeur erronée pour l'attribut « job-state » !" - -msgid "Job state cannot be changed." -msgstr "L'état de la tâche ne peut être modifié." - -#, c-format -msgid "Unsupported compression attribute %s!" -msgstr "L'attribute de compression %s n'est pas géré !" - -#, c-format -msgid "Unsupported format \"%s\"!" -msgstr "Le format « %s » n'est pas géré !" - -#, c-format -msgid "%s is not implemented by the CUPS version of lpc.\n" -msgstr "« %s » n'est pas implanté dans la version CUPS de lpc.\n" - -msgid "" -"Commands may be abbreviated. Commands are:\n" -"\n" -"exit help quit status ?\n" -msgstr "" -"Les commandes peuvent être abrégée. Elles sont:\n" -"\n" -"exit help quit status ?\n" - -msgid "help\t\tget help on commands\n" -msgstr "help\t\tobtenir de l'aide sur les commandes\n" - -msgid "status\t\tshow status of daemon and queue\n" -msgstr "status\t\taffiche l'état du démon et de la file\n" - -msgid "?Invalid help command unknown\n" -msgstr "?Commande d'aide inconnue\n" - -#, c-format -msgid "\tprinter is on device '%s' speed -1\n" -msgstr "\tl'imprimante est sur le périphérique '%s', vitesse -1\n" - -msgid "\tqueuing is enabled\n" -msgstr "\tla mise en file d'attente est permise\n" - -msgid "\tqueuing is disabled\n" -msgstr "\tla mise en file d'attente est refusée\n" - -msgid "\tprinting is enabled\n" -msgstr "\tl'impression est permise\n" - -msgid "\tprinting is disabled\n" -msgstr "\tl'impression est refusée\n" - -msgid "\tno entries\n" -msgstr "\taucune entrée\n" - -#, c-format -msgid "\t%d entries\n" -msgstr "\t%d entrées\n" - -msgid "\tdaemon present\n" -msgstr "\tdémon présent\n" - -msgid "lpq: Unable to contact server!\n" -msgstr "lpq: Impossible de contacter le serveur !\n" - -#, c-format -msgid "%s: Sorry, no encryption support compiled in!\n" -msgstr "%s: Désolé, la gestion du cryptage n'a pas été compilée !\n" - -#, c-format -msgid "lpq: Unknown destination \"%s/%s\"!\n" -msgstr lpq: Destination « %s/%s » inconnue !\n"" - -#, c-format -msgid "lpq: Unknown destination \"%s\"!\n" -msgstr "lpq: Destination « %s » inconnue !\n" - -#, c-format -msgid "lp: error - %s environment variable names non-existent destination \"%s\"!\n" -msgstr "lp: erreur - la variable d'environnement %s désigne une destination inexistente « %s » !\n" - -msgid "lpq: error - no default destination available.\n" -msgstr "lpq: erreur - aucune destination par défaut n'est disponible.\n" - -#, c-format -msgid "lpq: get-jobs failed: %s\n" -msgstr "lpq: « get-jobs » a échoué: %s\n" - -msgid "Rank Owner Pri Job Files Total Size\n" -msgstr "Rang Propr. Prio Tâche Fichiers Taille totale\n" - -msgid "Rank Owner Job File(s) Total Size\n" -msgstr "Rang Propr. Tâche Fichiers Taille totale\n" - -#, c-format -msgid "%s: %-33.33s [job %d localhost]\n" -msgstr "%s: %-33.33s [tâche %d localhost]\n" - -#, c-format -msgid " %-39.39s %.0f bytes\n" -msgstr " %-39.39s %.0f octets\n" - -#, c-format -msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" -msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f octets\n" - -#, c-format -msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" -msgstr "%-7s %-7.7s %-7d %-31.31s %.0f octets\n" - -msgid "no entries\n" -msgstr "aucune entrée\n" - -#, c-format -msgid "lpq: get-printer-attributes failed: %s\n" -msgstr "lpq: get-printer-attributes a échoué : %s\n" - -#, c-format -msgid "%s is ready\n" -msgstr "%s est prête\n" - -#, c-format -msgid "%s is ready and printing\n" -msgstr "%s est prête et en cours d'impression\n" - -#, c-format -msgid "%s is not ready\n" -msgstr "%s n'est pas prête\n" - -msgid "Usage: lpq [-P dest] [-l] [+interval]\n" -msgstr "Utilisation : lpq [-P dest] [-l] [+intervalle]\n" - -#, c-format -msgid "lpr: error - expected value after -%c option!\n" -msgstr "lpr: erreur - il faut une valeur après l'option '-%c' !\n" - -#, c-format -msgid "lpr: warning - '%c' format modifier not supported - output may not be correct!\n" -msgstr "lpr: attention - le modificateur de format '%c' n'est pas géré - l'affichage pourrait être incorrect !\n" - -msgid "lpr: error - expected option=value after -o option!\n" -msgstr "lpr: erreur - il faut un argument du type option=valeur après l'option '-o' !\n" - -msgid "lpr: warning - email notification is not currently supported!\n" -msgstr "lpr: attention - la notification par courriel n'est pas encore gérée !\n" - -msgid "lpr: error - expected destination after -P option!\n" -msgstr "lpr: erreur - il faut une destination après l'option '-P' !\n" - -msgid "lpr: error - expected copy count after -# option!\n" -msgstr "lpr: erreur - il faut un nombre de copies après l'option '-#' !\n" - -#, c-format -msgid "lpr: error - expected name after -%c option!\n" -msgstr "lpr: erreur - il faut un nom après l'option '-%c' !\n" - -msgid "lpr: error - expected username after -U option!\n" -msgstr "lpr: erreur - il faut un nom d'utilisateur après l'option '-U' !\n" - -#, c-format -msgid "lpr: error - unknown option '%c'!\n" -msgstr "lpr: erreur - option '%c' inconnue !\n" - -#, c-format -msgid "lpr: error - unable to access \"%s\" - %s\n" -msgstr "lpr: erreur - impossible d'accéder à « %s » - %s\n" - -#, c-format -msgid "lpr: error - too many files - \"%s\"\n" -msgstr "lpr: erreur - trop de fichiers - « %s »\n" - -#, c-format -msgid "lpr: error - %s environment variable names non-existent destination \"%s\"!\n" -msgstr "lpr: erreur - la variable d'environnement %s désigne une destination inexistente « %s » !\n" - -msgid "lpr: error - no default destination available.\n" -msgstr "lpr: erreur - aucune destination par défaut n'est disponible.\n" - -msgid "lpr: error - scheduler not responding!\n" -msgstr "lpr: erreur - l'ordonnanceur ne répond pas !\n" - -#, c-format -msgid "lpr: error - unable to create temporary file \"%s\" - %s\n" -msgstr "lpr: erreur - impossible de créer le fichier temporaire « %s » - %s\n" - -#, c-format -msgid "lpr: error - unable to write to temporary file \"%s\" - %s\n" -msgstr "lpr: erreur - impossible d'écrire dans le fichier temporaire « %s » - %s\n" - -msgid "lpr: error - stdin is empty, so no job has been sent.\n" -msgstr "lpr: erreur - stdin est vide, donc aucune tâche n'a été envoyée.\n" - -#, c-format -msgid "lpr: error - unable to print file: %s\n" -msgstr "lpr: erreur - impossible d'imprimer le fichier : %s\n" - -msgid "lprm: Unable to contact server!\n" -msgstr "lprm: Impossible de contacter le serveur !\n" - -#, c-format -msgid "lprm: Unknown destination \"%s\"!\n" -msgstr "lprm: Destination « %s » inconnue !\n" - -#, c-format -msgid "lprm: Unknown option '%c'!\n" -msgstr "lprm: Option '%c' inconnue !\n" - -msgid "lprm: Job or printer not found!\n" -msgstr "lprm: La tâche ou l'imprimante n'a pas été trouvée !\n" - -msgid "lprm: Not authorized to lprm job(s)!\n" -msgstr "lprm: Vous n'avez pas l'autorisation de supprimer cette(ces) tâche(s) !\n" - -#, c-format -msgid "lprm: You don't own job ID %d!\n" -msgstr lprm: La tâche n°%d ne vous appartient pas !\n"" - -msgid "lprm: Unable to lprm job(s)!\n" -msgstr "lprm: Impossible de supprimer cette(ces) tâche(s) !\n" - -msgid "lprm: Unable to cancel job(s)!\n" -msgstr "lprm: Impossible d'annuler cette(ces) tâche(s) !\n" - -#, c-format -msgid "%s: Don't know what to do!\n" -msgstr "%s: Je ne sais que faire !" - -#, c-format -msgid "%s: Expected server name after -h!\n" -msgstr "%s: Il faut un nom de serveur après l'option '-h' !\n" - -#, c-format -msgid "%s: Expected reason text after -r!\n" -msgstr "%s: Il faut le texte de la raison après l'option '-r' !\n" - -#, c-format -msgid "%s: Unknown option '%c'!\n" -msgstr "%s: Option '%c' inconnue !\n" - -#, c-format -msgid "%s: Unable to connect to server: %s\n" -msgstr "%s: Impossible de se connecter au serveur : %s\n" - -#, c-format -msgid "%s: Operation failed: %s\n" -msgstr "%s: L'opération a échoué : %s\n" - -msgid "cancel: Error - expected hostname after '-h' option!\n" -msgstr "annulation: erreur - il faut un nom de machine après l'option '-h' !\n" - -msgid "cancel: Error - expected username after '-u' option!\n" -msgstr "annulation: erreur - il faut un nom d'utilisateur après l'option '-u' !\n" - -#, c-format -msgid "cancel: Unknown option '%c'!\n" -msgstr "annulation: Option '%c' inconnue !" - -#, c-format -msgid "cancel: Unknown destination \"%s\"!\n" -msgstr "annulation: Destination inconnue « %s » !" - -msgid "cancel: Unable to contact server!\n" -msgstr "annulation: Impossible de contacter le serveur !\n" - -#, c-format -msgid "cancel: %s failed: %s\n" -msgstr "annulation: %s a échoué :%s\n" - -#, c-format -msgid "cupsaddsmb: Missing value on line %d!\n" -msgstr "cupsaddsmb: Il manque une valeur à la ligne n°%d !\n" - -#, c-format -msgid "cupsaddsmb: Missing double quote on line %d!\n" -msgstr "cupsaddsmb: Il manque un \" à la ligne n°%d !\n" - -#, c-format -msgid "cupsaddsmb: Bad option + choice on line %d!\n" -msgstr "cupsaddsmb: Option et choix erronés à la ligne n°%d !\n" - -#, c-format -msgid "cupsaddsmb: Unable to connect to server \"%s\" for %s - %s\n" -msgstr "cupsaddsmb: Impossible de se connecter au serveur « %s » pour %s - %s\n" - -#, c-format -msgid "cupsaddsmb: No PPD file for printer \"%s\" - skipping!\n" -msgstr "cupsaddsmb: Aucun fichier PPD pour l'imprimante « %s » - ignorée !\n" - -#, c-format -msgid "cupsaddsmb: get-printer-attributes failed for \"%s\": %s\n" -msgstr "cupsaddsmb: get-printer-attributes a échoué pour « %s » : %s\n" - -#, c-format -msgid "cupsaddsmb: Unable to convert PPD file for %s - %s\n" -msgstr "cupsaddsmb: Impossible de convertir le fichier PPD pour %s - %s\n" - -#, c-format -msgid "cupsaddsmb: Unable to copy Windows 2000 printer driver files (%d)!\n" -msgstr "cupsaddsmb: Impossible de copier les fichiers du pilote d'impression pour Windows 2000 (%d) !\n" - -#, c-format -msgid "cupsaddsmb: Unable to copy CUPS printer driver files (%d)!\n" -msgstr "cupsaddsmb: Impossible de copier les fichiers du pilote d'impression pour CUPS (%d) !\n" - -#, c-format -msgid "cupsaddsmb: Unable to install Windows 2000 printer driver files (%d)!\n" -msgstr "cupsaddsmb: Impossible d'installer les fichiers du pilote d'impression pour Windows 2000 (%d) !\n" - -#, c-format -msgid "cupsaddsmb: Unable to copy Windows 9x printer driver files (%d)!\n" -msgstr "cupsaddsmb: Impossible de copier les fichiers du pilote d'impression pour Windows 9x (%d) !\n" - -#, c-format -msgid "cupsaddsmb: Unable to install Windows 9x printer driver files (%d)!\n" -msgstr "cupsaddsmb: Impossible d'installer les fichiers du pilote d'impression pour Windows 9x (%d) !\n" - -#, c-format -msgid "cupsaddsmb: Unable to set Windows printer driver (%d)!\n" -msgstr "cupsaddsmb: Impossible de paramétrer le pilote d'impression pour Windows (%d) !\n" - -msgid "" -"Usage: cupsaddsmb [options] printer1 ... printerN\n" -" cupsaddsmb [options] -a\n" -"\n" -"Options:\n" -" -H samba-server Use the named SAMBA server\n" -" -U samba-user Authenticate using the named SAMBA user\n" -" -a Export all printers\n" -" -h cups-server Use the named CUPS server\n" -" -v Be verbose (show commands)\n" -msgstr "" -"Utilisation : cupsaddsmb [options] imprimante1 ... imprimanteN\n" -" cupsaddsmb [options] -a\n" -"\n" -"Options:\n" -" -H serveur-samba Utiliser le serveur SAMBA désigné\n" -" -U utilisateur-samba S'authentifier avec l'utilisateur SAMBA désigné\n" -" -a Exporter toutes les imprimantes\n" -" -h serveur-CUPS Utiliser le serveur CUPS désigné\n" -" -v Être locace ( afficher les commandes )\n" - -msgid "cupstestppd: The -q option is incompatible with the -v option.\n" -msgstr "cupstestppd: L'option est -q incomptaible avec l'option -v.\n" - -msgid "cupstestppd: The -v option is incompatible with the -q option.\n" -msgstr "cupstestppd: L'option est -v incomptaible avec l'option -q.\n" - -#, c-format -msgid "" -" FAIL\n" -" **FAIL** Unable to open PPD file - %s\n" -msgstr "" -" FAIL\n" -" **FAIL** Unable to open PPD file - %s\n" - -#, c-format -msgid "" -" FAIL\n" -" **FAIL** Unable to open PPD file - %s on line %d.\n" -msgstr "" -" FAIL\n" -" **FAIL** Unable to open PPD file - %s on line %d.\n" - -msgid " REF: Page 42, section 5.2.\n" -msgstr " REF: Page 42, section 5.2.\n" - -msgid " REF: Page 20, section 3.4.\n" -msgstr " REF: Page 20, section 3.4.\n" - -msgid " REF: Pages 45-46, section 5.2.\n" -msgstr " REF: Pages 45-46, section 5.2.\n" - -msgid " REF: Pages 42-45, section 5.2.\n" -msgstr " REF: Pages 42-45, section 5.2.\n" - -msgid " REF: Pages 48-49, section 5.2.\n" -msgstr " REF: Pages 48-49, section 5.2.\n" - -msgid " REF: Pages 52-54, section 5.2.\n" -msgstr " REF: Pages 52-54, section 5.2.\n" - -msgid " REF: Page 15, section 3.2.\n" -msgstr " REF: Page 15, section 3.2.\n" - -msgid " REF: Page 15, section 3.1.\n" -msgstr " REF: Page 15, section 3.1.\n" - -msgid " REF: Pages 16-17, section 3.2.\n" -msgstr " REF: Pages 16-17, section 3.2.\n" - -msgid " REF: Page 19, section 3.3.\n" -msgstr " REF: Page 19, section 3.3.\n" - -msgid " REF: Page 27, section 3.5.\n" -msgstr " REF: Page 27, section 3.5.\n" - -msgid "" -"\n" -" DETAILED CONFORMANCE TEST RESULTS\n" -msgstr "" -"\n" -" DETAILED CONFORMANCE TEST RESULTS\n" - -#, c-format -msgid " WARN %s has no corresponding options!\n" -msgstr " WARN %s has no corresponding options!\n" - -msgid " FAIL\n" -msgstr " FAIL\n" - -msgid "" -" **FAIL** REQUIRED DefaultImageableArea\n" -" REF: Page 102, section 5.15.\n" -msgstr "" -" **FAIL** REQUIRED DefaultImageableArea\n" -" REF: Page 102, section 5.15.\n" - -#, c-format -msgid "" -" **FAIL** BAD DefaultImageableArea %s!\n" -" REF: Page 102, section 5.15.\n" -msgstr "" -" **FAIL** BAD DefaultImageableArea %s!\n" -" REF: Page 102, section 5.15.\n" - -msgid " PASS DefaultImageableArea\n" -msgstr " PASS DefaultImageableArea\n" - -msgid "" -" **FAIL** REQUIRED DefaultPaperDimension\n" -" REF: Page 103, section 5.15.\n" -msgstr "" -" **FAIL** REQUIRED DefaultPaperDimension\n" -" REF: Page 103, section 5.15.\n" - -#, c-format -msgid "" -" **FAIL** BAD DefaultPaperDimension %s!\n" -" REF: Page 103, section 5.15.\n" -msgstr "" -" **FAIL** BAD DefaultPaperDimension %s!\n" -" REF: Page 103, section 5.15.\n" - -msgid " PASS DefaultPaperDimension\n" -msgstr " PASS DefaultPaperDimension\n" - -#, c-format -msgid "" -" **FAIL** BAD Default%s %s\n" -" REF: Page 40, section 4.5.\n" -msgstr "" -" **FAIL** BAD Default%s %s\n" -" REF: Page 40, section 4.5.\n" - -#, c-format -msgid " PASS Default%s\n" -msgstr " PASS Default%s\n" - -#, c-format -msgid "" -" **FAIL** REQUIRED Default%s\n" -" REF: Page 40, section 4.5.\n" -msgstr "" -" **FAIL** REQUIRED Default%s\n" -" REF: Page 40, section 4.5.\n" - -msgid " PASS FileVersion\n" -msgstr " PASS FileVersion\n" - -msgid "" -" **FAIL** REQUIRED FileVersion\n" -" REF: Page 56, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED FileVersion\n" -" REF: Page 56, section 5.3.\n" - -msgid " PASS FormatVersion\n" -msgstr " PASS FormatVersion\n" - -msgid "" -" **FAIL** REQUIRED FormatVersion\n" -" REF: Page 56, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED FormatVersion\n" -" REF: Page 56, section 5.3.\n" - -msgid " PASS LanguageEncoding\n" -msgstr " PASS LanguageEncoding\n" - -msgid "" -" **FAIL** REQUIRED LanguageEncoding\n" -" REF: Pages 56-57, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED LanguageEncoding\n" -" REF: Pages 56-57, section 5.3.\n" - -msgid " PASS LanguageVersion\n" -msgstr " PASS LanguageVersion\n" - -msgid "" -" **FAIL** REQUIRED LanguageVersion\n" -" REF: Pages 57-58, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED LanguageVersion\n" -" REF: Pages 57-58, section 5.3.\n" - -msgid "" -" **FAIL** BAD Manufacturer (should be \"HP\")\n" -" REF: Page 211, table D.1.\n" -msgstr "" -" **FAIL** BAD Manufacturer (should be \"HP\")\n" -" REF: Page 211, table D.1.\n" - -msgid " PASS Manufacturer\n" -msgstr " PASS Manufacturer\n" - -msgid "" -" **FAIL** REQUIRED Manufacturer\n" -" REF: Pages 58-59, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED Manufacturer\n" -" REF: Pages 58-59, section 5.3.\n" - -#, c-format -msgid "" -" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" -" REF: Pages 59-60, section 5.3.\n" -msgstr "" -" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" -" REF: Pages 59-60, section 5.3.\n" - -msgid " PASS ModelName\n" -msgstr " PASS ModelName\n" - -msgid "" -" **FAIL** REQUIRED ModelName\n" -" REF: Pages 59-60, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED ModelName\n" -" REF: Pages 59-60, section 5.3.\n" - -msgid " PASS NickName\n" -msgstr " PASS NickName\n" - -msgid "" -" **FAIL** REQUIRED NickName\n" -" REF: Page 60, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED NickName\n" -" REF: Page 60, section 5.3.\n" - -msgid " PASS PageSize\n" -msgstr " PASS PageSize\n" - -msgid "" -" **FAIL** REQUIRED PageSize\n" -" REF: Pages 99-100, section 5.14.\n" -msgstr "" -" **FAIL** REQUIRED PageSize\n" -" REF: Pages 99-100, section 5.14.\n" - -msgid " PASS PageRegion\n" -msgstr " PASS PageRegion\n" - -msgid "" -" **FAIL** REQUIRED PageRegion\n" -" REF: Page 100, section 5.14.\n" -msgstr "" -" **FAIL** REQUIRED PageRegion\n" -" REF: Page 100, section 5.14.\n" - -msgid " PASS PCFileName\n" -msgstr " PASS PCFileName\n" - -msgid "" -" **FAIL** REQUIRED PCFileName\n" -" REF: Pages 61-62, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED PCFileName\n" -" REF: Pages 61-62, section 5.3.\n" - -msgid "" -" **FAIL** BAD Product - not \"(string)\".\n" -" REF: Page 62, section 5.3.\n" -msgstr "" -" **FAIL** BAD Product - not \"(string)\".\n" -" REF: Page 62, section 5.3.\n" - -msgid " PASS Product\n" -msgstr " PASS Product\n" - -msgid "" -" **FAIL** REQUIRED Product\n" -" REF: Page 62, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED Product\n" -" REF: Page 62, section 5.3.\n" - -msgid "" -" **FAIL** BAD PSVersion - not \"(string) int\".\n" -" REF: Pages 62-64, section 5.3.\n" -msgstr "" -" **FAIL** BAD PSVersion - not \"(string) int\".\n" -" REF: Pages 62-64, section 5.3.\n" - -msgid " PASS PSVersion\n" -msgstr " PASS PSVersion\n" - -msgid "" -" **FAIL** REQUIRED PSVersion\n" -" REF: Pages 62-64, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED PSVersion\n" -" REF: Pages 62-64, section 5.3.\n" - -msgid "" -" **FAIL** BAD ShortNickName - longer than 31 chars.\n" -" REF: Pages 64-65, section 5.3.\n" -msgstr "" -" **FAIL** BAD ShortNickName - longer than 31 chars.\n" -" REF: Pages 64-65, section 5.3.\n" - -msgid " PASS ShortNickName\n" -msgstr " PASS ShortNickName\n" - -msgid "" -" **FAIL** REQUIRED ShortNickName\n" -" REF: Page 64-65, section 5.3.\n" -msgstr "" -" **FAIL** REQUIRED ShortNickName\n" -" REF: Page 64-65, section 5.3.\n" - -msgid "" -" **FAIL** BAD JobPatchFile attribute in file\n" -" REF: Page 24, section 3.4.\n" -msgstr "" -" **FAIL** BAD JobPatchFile attribute in file\n" -" REF: Page 24, section 3.4.\n" - -msgid "" -" **FAIL** REQUIRED PageSize\n" -" REF: Page 41, section 5.\n" -" REF: Page 99, section 5.14.\n" -msgstr "" -" **FAIL** REQUIRED PageSize\n" -" REF: Page 41, section 5.\n"\n" -" REF: Page 99, section 5.14.\n" - -#, c-format -msgid "" -" **FAIL** REQUIRED ImageableArea for PageSize %s\n" -" REF: Page 41, section 5.\n" -" REF: Page 102, section 5.15.\n" -msgstr "" -" **FAIL** REQUIRED ImageableArea for PageSize %s\n" -" REF: Page 41, section 5.\n" -" REF: Page 102, section 5.15.\n" - -#, c-format -msgid "" -" **FAIL** REQUIRED PaperDimension for PageSize %s\n" -" REF: Page 41, section 5.\n" -" REF: Page 103, section 5.15.\n" -msgstr "" -" **FAIL** REQUIRED PaperDimension for PageSize %s\n" -" REF: Page 41, section 5.\n" -" REF: Page 103, section 5.15.\n" - -#, c-format -msgid "" -" **FAIL** Bad %s choice %s!\n" -" REF: Page 84, section 5.9\n" -msgstr "" -" **FAIL** Bad %s choice %s!\n" -" REF: Page 84, section 5.9\n" - -#, c-format -msgid "" -" **FAIL** REQUIRED %s does not define choice None!\n" -" REF: Page 122, section 5.17\n" -msgstr "" -" **FAIL** REQUIRED %s does not define choice None!\n" -" REF: Page 122, section 5.17\n" - -#, c-format -msgid "" -" **FAIL** Bad %s choice %s!\n" -" REF: Page 122, section 5.17\n" -msgstr "" -" **FAIL** Bad %s choice %s!\n" -" REF: Page 122, section 5.17\n" - -msgid " PASS\n" -msgstr " PASS\n" - -#, c-format -msgid "" -" WARN Duplex option keyword %s should be named Duplex or JCLDuplex!\n" -" REF: Page 122, section 5.17\n" -msgstr "" -" WARN Duplex option keyword %s should be named Duplex or JCLDuplex!\n" -" REF: Page 122, section 5.17\n" - -msgid " WARN Default choices conflicting!\n" -msgstr "" - -#, c-format -msgid "" -" WARN Obsolete PPD version %.1f!\n" -" REF: Page 42, section 5.2.\n" -msgstr "" -" WARN Obsolete PPD version %.1f!\n" -" REF: Page 42, section 5.2.\n" - -msgid "" -" WARN LanguageEncoding required by PPD 4.3 spec.\n" -" REF: Pages 56-57, section 5.3.\n" -msgstr "" -" WARN LanguageEncoding required by PPD 4.3 spec.\n" -" REF: Pages 56-57, section 5.3.\n" - -msgid "" -" WARN Manufacturer required by PPD 4.3 spec.\n" -" REF: Pages 58-59, section 5.3.\n" -msgstr "" -" WARN Manufacturer required by PPD 4.3 spec.\n" -" REF: Pages 58-59, section 5.3.\n" - -msgid "" -" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" -" REF: Pages 61-62, section 5.3.\n" -msgstr "" -" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" -" REF: Pages 61-62, section 5.3.\n" - -msgid "" -" WARN ShortNickName required by PPD 4.3 spec.\n" -" REF: Pages 64-65, section 5.3.\n" -msgstr "" -" WARN ShortNickName required by PPD 4.3 spec.\n" -" REF: Pages 64-65, section 5.3.\n" - -msgid "" -" WARN Protocols contains both PJL and BCP; expected TBCP.\n" -" REF: Pages 78-79, section 5.7.\n" -msgstr "" -" WARN Protocols contains both PJL and BCP; expected TBCP.\n" -" REF: Pages 78-79, section 5.7.\n" - -msgid "" -" WARN Protocols contains PJL but JCL attributes are not set.\n" -" REF: Pages 78-79, section 5.7.\n" -msgstr "" -" WARN Protocols contains PJL but JCL attributes are not set.\n" -" REF: Pages 78-79, section 5.7.\n" - -#, c-format -msgid "" -" WARN %s shares a common prefix with %s\n" -" REF: Page 15, section 3.2.\n" -msgstr "" -" WARN %s shares a common prefix with %s\n" -" REF: Page 15, section 3.2.\n" - -#, c-format -msgid " %d ERROR%s FOUND\n" -msgstr " %d ERROR%s FOUND\n" - -msgid " NO ERRORS FOUND\n" -msgstr " NO ERRORS FOUND\n" - -#, c-format -msgid "" -" WARN \"%s %s\" conflicts with \"%s %s\"\n" -" (constraint=\"%s %s %s %s\")\n" -msgstr "" -" WARN \"%s %s\" conflicts with \"%s %s\"\n" -" (constraint=\"%s %s %s %s\")\n" -msgid "" -"Usage: cupstestppd [-q] [-r] [-v[v]] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" -" program | cupstestppd [-q] [-r] [-v[v]] -\n" -msgstr "" -"Utilisation : cupstestppd [-q] [-r] [-v[v]] fichier1.ppd[.gz] [... fichierN.ppd[.gz]]\n" -" programme | cupstestppd [-q] [-r] [-v[v]] -\n" - -msgid "lpstat: Need \"completed\" or \"not-completed\" after -W!\n" -msgstr "lpstat: Il faut « completed » ou « not-completed » après l'option -W !\n" - -msgid "lpstat: The -b option requires a destination argument.\n" -msgstr "lpstat: Il faut une destination après l'option '-b' !\n" - -msgid "Error: need hostname after '-h' option!\n" -msgstr "Erreur : Il faut un nom d'hôte après l'option '-h' !\n" - -#, c-format -msgid "lpstat: Unknown option '%c'!\n" -msgstr "lpstat: Option '%c inconnue !\n" - -#, c-format -msgid "lpstat: Invalid destination name in list \"%s\"!\n" -msgstr "lpstat: Nom de destination incorrect dans la liste « %s » !\n" - -#, c-format -msgid "lpstat: Unknown destination \"%s\"!\n" -msgstr "lpstat: Destination « %s » inconnue !\n" - -#, c-format -msgid "lpstat: Unable to connect to server %s on port %d: %s\n" -msgstr "lpstat: Impossible de se connecter au serveur « %s » sur le port %d : %s\n" - -#, c-format -msgid "lpstat: get-printers failed: %s\n" -msgstr "lpstat: get-printers a échoué: %s\n" - -#, c-format -msgid "%s accepting requests since Jan 01 00:00\n" -msgstr "%s accepte les requêtes depuis le Jan 01 00:00\n" - -#, c-format -msgid "" -"%s not accepting requests since Jan 01 00:00 -\n" -"\t%s\n" -msgstr "" -"%s n'accepte pas les requêtes depuis le Jan 01 00:00 -\n" -"\t%s\n" - -#, c-format -msgid "%s/%s accepting requests since Jan 01 00:00\n" -msgstr "%s/%s accepte les requêtes depuis le Jan 01 00:00\n" - -#, c-format -msgid "" -"%s/%s not accepting requests since Jan 01 00:00 -\n" -"\t%s\n" -msgstr "" -"%s/%s n'accepte pas les requêtes depuis le Jan 01 00:00 -\n" -"\t%s\n" - -#, c-format -msgid "lpstat: get-classes failed: %s\n" -msgstr "lpstat: get-classes a échoué : %s !\n" - -#, c-format -msgid "members of class %s:\n" -msgstr "membres de la classe %s :\n" - -#, c-format -msgid "system default destination: %s/%s\n" -msgstr "destination par défaut du système : %s/%s\n" - -#, c-format -msgid "system default destination: %s\n" -msgstr "destination par défaut du système : %s\n" - -#, c-format -msgid "lpstat: error - %s environment variable names non-existent destination \"%s\"!\n" -msgstr "" -"lpstat: erreur - la variable d'environnement désigne une destination\n" -" inexistente « %s » !\n" - -msgid "no system default destination\n" -msgstr "le système n'a pas de destination par défaut\n" - -#, c-format -msgid "Output for printer %s is sent to remote printer %s on %s\n" -msgstr "" -"Ce qui est envoyé à l'imprimante %s est redirigé vers l'imprimante\n" -"distante %s sur %s\n" - -#, c-format -msgid "Output for printer %s is sent to %s\n" -msgstr "Ce qui est envoyé à l'imprimante %s est redirigé vers %s\n" - -#, c-format -msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" -msgstr "" -"Ce qui est envoyé à l'imprimante %s/%s est redirigé vers l'imprimante\n" -"distante %s sur %s\n" - -#, c-format -msgid "Output for printer %s/%s is sent to %s\n" -msgstr "Ce qui est envoyé à l'imprimante %s/%s est redirigé vers %s\n" - -#, c-format -msgid "device for %s: %s\n" -msgstr "périphérique pour %s : %s\n" - -#, c-format -msgid "device for %s/%s: %s\n" -msgstr "périphérique pour %s/%s : %s \n" - -#, c-format -msgid "lpstat: get-jobs failed: %s\n" -msgstr "lpstat: get-jobs a échoué : %s !\n" - -#, c-format -msgid "\tqueued for %s\n" -msgstr "\tmis en file d'attente pour %s\n" - -#, c-format -msgid "printer %s is idle. enabled since %s\n" -msgstr "l'imprimante %s ne fait rien ; elle est activée depuis le %s\n" - -#, c-format -msgid "printer %s now printing %s-%d. enabled since %s\n" -msgstr "l'imprimante %s est en train d'imprimer %s-%d ; elle est activée depuis le %s\n"" - -#, c-format -msgid "printer %s disabled since %s -\n" -msgstr "l'imprimante %s est désactivée depuis le %s -\n" - -msgid "\treason unknown\n" -msgstr "\traison inconnue\n" - -msgid "" -"\tForm mounted:\n" -"\tContent types: any\n" -"\tPrinter types: unknown\n" -msgstr "" -"\tFormat monté :\n" -"\tTypes de contenu : any\n" -"\tTypes d'imprimante : unknown\n" - -#, c-format -msgid "\tDescription: %s\n" -msgstr "\tDescription : %s\n" - -msgid "\tAlerts:" -msgstr "\tAlertes :" - -#, c-format -msgid "\tLocation: %s\n" -msgstr "\tLieu : %s\n" - -msgid "\tConnection: remote\n" -msgstr "\tConnexion : distante\n" - -#, c-format -msgid "\tInterface: %s.ppd\n" -msgstr "\tInterface : %s.ppd\n" - -msgid "\tConnection: direct\n" -msgstr "\tConnexion : directe\n" - -#, c-format -msgid "\tInterface: %s/interfaces/%s\n" -msgstr "\tInterface : %s/interfaces/%s\n" - -#, c-format -msgid "\tInterface: %s/ppd/%s.ppd\n" -msgstr "\tInterface : %s/ppd/%s.ppd\n" - -msgid "\tOn fault: no alert\n" -msgstr "\tEn cas d'erreur : pas d'alerte\n" - -msgid "\tAfter fault: continue\n" -msgstr "\tAprès une erreur : poursuivre\n" - -msgid "\tUsers allowed:\n" -msgstr "\tUtilisateurs autorisés :\n" - -msgid "\tUsers denied:\n" -msgstr "\tUtilisateurs refusés :\n" - -msgid "\t\t(all)\n" -msgstr "\t\t( tous )\n" - -msgid "\tForms allowed:\n" -msgstr "\tFormats autorisés :\n" - -msgid "\t\t(none)\n" -msgstr "\t\t( aucun )\n" - -msgid "\tBanner required\n" -msgstr "\tBannière requise\n" - -msgid "\tCharset sets:\n" -msgstr "\tJeux de caractères :\n" - -msgid "\tDefault pitch:\n" -msgstr "\t« pitch » par défaut :\n" - -msgid "\tDefault page size:\n" -msgstr "\tTaille de papier par défaut :\n" - -msgid "\tDefault port settings:\n" -msgstr "\tParamètres par défaut du port :\n" - -#, c-format -msgid "printer %s/%s is idle. enabled since %s\n" -msgstr "l'imprimante %s/%s ne fait rien ; elle est activée depuis le %s\n" - -#, c-format -msgid "printer %s/%s now printing %s-%d. enabled since %s\n" -msgstr "l'imprimante %s/%s est en train d'imprimer %s-%d ; elle est activée depuis le %s\n"" - -#, c-format -msgid "printer %s/%s disabled since %s -\n" -msgstr "l'imprimante %s/%s est désactivée depuis le %s -\n" - -msgid "scheduler is running\n" -msgstr "l'ordonnanceur tourne\n" - -msgid "scheduler is not running\n" -msgstr "l'ordonnanceur est arrêté\n" - -#, c-format -msgid "lpadmin: Unable to connect to server: %s\n" -msgstr "lpadmin: Impossible de se connecter au serveur « %s » !\n" - -msgid "" -"lpadmin: Unable to add a printer to the class:\n" -" You must specify a printer name first!\n" -msgstr "" -"lpadmin: Impossible d'ajouter une imprimante à la classe :\n" -" Vous devez d'abord préciser un nom d'imprimante !\n" - -msgid "lpadmin: Expected class name after '-c' option!\n" -msgstr "lpadmin: Il faut un nom de classe après l'option '-c' !\n" - -msgid "lpadmin: Class name can only contain printable characters!\n" -msgstr "lpadmin: Un nom de classe ne peut comporter que des caractères imprimables !\n" - -msgid "lpadmin: Expected printer name after '-d' option!\n" -msgstr "lpadmin: Il faut un nom d'imprimante après l'option '-d' !\n" - -msgid "lpadmin: Printer name can only contain printable characters!\n" -msgstr "lpadmin: Un nom d'imprimante ne peut comporter que des caractères imprimables !\n" - -msgid "lpadmin: Expected hostname after '-h' option!\n" -msgstr "lpadmin: Il faut un nom d'hôte après l'option 'h' !\n" - -msgid "" -"lpadmin: Unable to set the interface script:\n" -" You must specify a printer name first!\n" -msgstr "" -"lpadmin: Impossible de définir le script d'interface :\n" -" Vous devez d'abord préciser un nom d'imprimante !\n" - -msgid "lpadmin: Expected interface after '-i' option!\n" -msgstr "lpadmin: Il faut une interface après l'option '-i' !\n" - -msgid "" -"lpadmin: Unable to set the interface script or PPD file:\n" -" You must specify a printer name first!\n" -msgstr "" -"lpadmin: Impossible de définir le script d'interface ou le fichier PPD :\n" -" Vous devez d'abord préciser un nom d'imprimante !\n" - -msgid "lpadmin: Expected model after '-m' option!\n" -msgstr "lpadmin: Il faut un modèle après l'option '-m' !\n" - -msgid "lpadmin: Expected name=value after '-o' option!\n" -msgstr "lpadmin: Il faut un argument du type option=valeur après l'option '-o' !\n" - -msgid "lpadmin: Expected printer after '-p' option!\n" -msgstr "lpadmin: Il faut une imprimante après l'option '-p' !\n" - -msgid "" -"lpadmin: Unable to remove a printer from the class:\n" -" You must specify a printer name first!\n" -msgstr "" -"lpadmin: Impossible de supprimer une imprimante de la classe :\n" -" Vous devez d'abord préciser un nom d'imprimante !\n" - -msgid "lpadmin: Expected class after '-r' option!\n" -msgstr "lpadmin: Il faut une classe après l'option '-r' !\n" - -msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" -msgstr "" -"lpadmin: Il faut un argument du type allow/deny:liste_utilisateurs\n" -" après l'option '-u' !\n" - -#, c-format -msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" -msgstr "lpadmin: Option allow/deny « %s » inconnue !\n" - -msgid "" -"lpadmin: Unable to set the device URI:\n" -" You must specify a printer name first!\n" -msgstr "" -"lpadmin: Impossible de définir l'URI du périphérique :\n" -" Vous devez d'abord préciser un nom d'imprimante !\n" - -msgid "lpadmin: Expected device URI after '-v' option!\n" -msgstr "lpadmin: Il faut un URI de périphérique après l'option '-v' !\n" - -msgid "lpadmin: Expected printer or class after '-x' option!\n" -msgstr "lpadmin: Il faut une imprimante ou une classe après l'option '-x' !\n" - -msgid "" -"lpadmin: Unable to set the printer description:\n" -" You must specify a printer name first!\n" -msgstr "" -"lpadmin: Impossible de définir la description de l'imprimante :\n" -" Vous devez d'abord préciser un nom d'imprimante !\n" - -msgid "lpadmin: Expected description after '-D' option!\n" -msgstr "lpadmin: Il faut une description après l'option '-D' !\n" - -msgid "lpadmin: Expected file type(s) after '-I' option!\n" -msgstr "lpadmin: Il faut un ou plusieurs types de fichier après l'option '-I' !\n" - -msgid "lpadmin: Warning - content type list ignored!\n" -msgstr "lpadmin: Attention - les types de contenu sont ignorés !\n" - -msgid "" -"lpadmin: Unable to set the printer location:\n" -" You must specify a printer name first!\n" -msgstr "" -"lpadmin: Impossible de définir le lieu de l'imprimante :\n" -" Vous devez d'abord préciser un nom d'imprimante !\n" - -msgid "lpadmin: Expected location after '-L' option!\n" -msgstr "lpadmin: Il faut un lieu après l'option '-L' !\n" - -msgid "" -"lpadmin: Unable to set the PPD file:\n" -" You must specify a printer name first!\n" -msgstr "" -"lpadmin: Impossible de définir le fichier PPD :\n" -" Vous devez d'abord préciser un nom d'imprimante !\n" - -msgid "lpadmin: Expected PPD after '-P' option!\n" -msgstr "lpadmin: Il faut un fichier PPD après l'option '-P' !\n" - -#, c-format -msgid "lpadmin: Unknown option '%c'!\n" -msgstr "lpadmin: Option '%c' inconnue !\n" - -#, c-format -msgid "lpadmin: Unknown argument '%s'!\n" -msgstr "lpadmin: Argument « %s » inconnu !\n" - -msgid "" -"lpadmin: Unable to set the printer options:\n" -" You must specify a printer name first!\n" -msgstr "" -"lpadmin: Impossible de définir les options de l'imprimante :\n" -" Vous devez d'abord préciser un nom d'imprimante !\n" - -msgid "" -"Usage:\n" -"\n" -" lpadmin [-h server] -d destination\n" -" lpadmin [-h server] -x destination\n" -" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" -" [-r remove-class] [-v device] [-D description]\n" -" [-P ppd-file] [-o name=value]\n" -" [-u allow:user,user] [-u deny:user,user]\n" -"\n" -msgstr "" -"Utilisation :\n" -"\n" -" lpadmin [-h serveur] -d destination\n" -" lpadmin [-h serveur] -x destination\n" -" lpadmin [-h serveur] -p imprimante [-c classe] [-i interface] [-m modèle]\n" -" [-r classe] [-v URI] [-D description]\n" -" [-P fichier-ppd] [-o option=valeur]\n" -" [-u allow:util.,util.] [-u deny:util.,util.]\n" -"\n" - -#, c-format -msgid "lpadmin: Unable to create temporary file: %s\n" -msgstr "lpadmin: Impossible de créer un fichier temporaire : %s\n" - -#, c-format -msgid "lpadmin: Unable to open file \"%s\": %s\n" -msgstr "lpadmin: Impossible d'ouvrir le fichier « %s » : %s\n" - -#, c-format -msgid "lpadmin: add-printer (set model) failed: %s\n" -msgstr "lpadmin: add-printer ( définition du modèle ) a échoué : %s\n" - -#, c-format -msgid "lpadmin: add-printer (set description) failed: %s\n" -msgstr "lpadmin: add-printer ( définition de la description ) a échoué : %s\n" - -#, c-format -msgid "lpadmin: add-printer (set location) failed: %s\n" -msgstr "lpadmin: add-printer ( définition du lieu ) a échoué : %s\n" - -#, c-format -msgid "lpadmin: Unable to create temporary file - %s\n" -msgstr "lpadmin: Impossible de créer un fichier temporaire : %s\n" - -#, c-format -msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" -msgstr "lpadmin: Impossible d'ouvrir le fichier PPD « %s » : %s\n" - -#, c-format -msgid "lpadmin: %s failed: %s\n" -msgstr "lpadmin: %s a échoué : %s\n" - -msgid "lp: Expected destination after -d option!\n" -msgstr "lp: Il faut une destination après l'option '-d' !\n" - -msgid "lp: Expected form after -f option!\n" -msgstr "lp: Il faut un format après l'option '-f' !\n" - -msgid "lp: Expected hostname after -h option!\n" -msgstr "lp: Il faut un nom d'hôte après l'option '-h' !\n" - -msgid "lp: Expected job ID after -i option!\n" -msgstr "lp: Il faut un numéro de tâche après l'option '-i' !\n" - -msgid "lp: Error - cannot print files and alter jobs simultaneously!\n" -msgstr "lp: Erreur - impossible d'imprimer et modifier les tâches en même temps !\n" - -msgid "lp: Error - bad job ID!\n" -msgstr "lp: Erreur - numéro de tâche incorrect !\n" - -msgid "lp: Expected copies after -n option!\n" -msgstr "lp: Il faut un nombre de copies après l'option '-n' !\n" - -msgid "lp: Expected option string after -o option!\n" -msgstr "lp: Il faut une chaîne d'option \"nom=valeur\" après l'option '-o' !\n" - -#, c-format -msgid "lp: Expected priority after -%c option!\n" -msgstr "lp: Il faut une priorité après l'option '-%c' !\n" - -msgid "lp: Priority must be between 1 and 100.\n" -msgstr "lp: La priorité doit être comprise entre 1 et 100.\n" - -msgid "lp: Expected title after -t option!\n" -msgstr "lp: Il faut un titre après l'option '-t' !\n" - -msgid "lp: Expected mode list after -y option!\n" -msgstr "lp: Il faut une liste de modes après l'option '-y' !\n" - -msgid "lp: Warning - mode option ignored!\n" -msgstr "lp: Attention - l'option « mode » est ignorée !\n" - -msgid "lp: Expected hold name after -H option!\n" -msgstr "lp: Il faut un code de retenue après l'option '-H' !\n" - -msgid "lp: Need job ID (-i) before \"-H restart\"!\n" -msgstr "lp: Il faut un numéro de tâche ( '-i' ) avant '-H restart' !\n" - -msgid "lp: Expected page list after -P option!\n" -msgstr "lp: Il faut une liste de pages après l'option '-P' !\n" - -msgid "lp: Expected character set after -S option!\n" -msgstr "lp: Il faut un jeu de caractères après l'option '-S' !\n" - -msgid "lp: Warning - character set option ignored!\n" -msgstr "lp: Attention - l'option « jeu de caractères » est ignorée !\n" - -msgid "lp: Expected content type after -T option!\n" -msgstr "lp: Il faut un type de contenu après l'option '-T' !\n" - -msgid "lp: Warning - content type option ignored!\n" -msgstr "lp: Attention - l'option « type de contenu » est ignorée !\n" - -#, c-format -msgid "lp: Unknown option '%c'!\n" -msgstr "lp: Option '%c' inconnue !\n" - -msgid "lp: Error - cannot print from stdin if files or a job ID are provided!\n" -msgstr "" -"lp: Erreur - impossible d'imprimer depuis l'entrée standard si un fichier\n" -" ou un numéro de tâche est spécifié !\n" - -#, c-format -msgid "lp: Unable to access \"%s\" - %s\n" -msgstr "lp: Impossible d'accéder à « %s » - %s\n" - -#, c-format -msgid "lp: Too many files - \"%s\"\n" -msgstr "lp: Trop de fichiers - « %s »\n" - -msgid "lp: error - no default destination available.\n" -msgstr "lp: Erreur - aucune destination par défaut n'est disponible.\n" - -msgid "lp: error - scheduler not responding!\n" -msgstr "lp: Erreur - l'odonnanceur ne répond pas !\n" - -#, c-format -msgid "lp: Error - unable to create temporary file \"%s\" - %s\n" -msgstr "lp: Erreur - impossible de créer le fichier temporaire « %s » - %s\n" - -#, c-format -msgid "lp: error - unable to write to temporary file \"%s\" - %s\n" -msgstr "lp: Erreur - impossible d'écrire dans le fichier temporaire « %s » - %s\n" - -msgid "lp: stdin is empty, so no job has been sent.\n" -msgstr "lp: l'entrée standard est vide, donc aucune tâche n'a été envoyée.\n" - -#, c-format -msgid "lp: unable to print file: %s\n" -msgstr "lp: impossible d'imprimer le fichier - %s\n" - -#, c-format -msgid "request id is %s-%d (%d file(s))\n" -msgstr "l'identifiant de requête est %s-%d ( %d fichier(s) )\n" - -#, c-format -msgid "lp: restart-job failed: %s\n" -msgstr "lp: restart-job a échoué : %s\n" - -#, c-format -msgid "lp: set-job-attributes failed: %s\n" -msgstr "lp: set-job-attributes a échoué : %s\n" - -#, c-format -msgid "lpinfo: Unable to connect to server: %s\n" -msgstr "lpinfo: Impossible de se connecter au serveur : %s\n" - -#, c-format -msgid "lpinfo: Unknown option '%c'!\n" -msgstr "lpinfo: Option '%c' inconnue !\n" - -#, c-format -msgid "lpinfo: Unknown argument '%s'!\n" -msgstr "lpinfo: Argument '%s' inconnu !\n" - -#, c-format -msgid "lpinfo: cups-get-devices failed: %s\n" -msgstr "lpinfo: cups-get-devices a échoué : %s\n" - -#, c-format -msgid "" -"Device: uri = %s\n" -" class = %s\n" -" info = %s\n" -" make-and-model = %s\n" -msgstr "" -"Matériel : URI = %s\n" -" classe = %s\n" -" info = %s\n" -" marque/modèle = %s\n" - -#, c-format -msgid "lpinfo: cups-get-ppds failed: %s\n" -msgstr "lpinfo: cups-get-ppds a échoué : %s\n" - -#, c-format -msgid "" -"Model: name = %s\n" -" natural_language = %s\n" -" make-and-model = %s\n" -msgstr "" -"Modèle : nom = %s\n" -" langue naturelle = %s\n" -" marque/modèle = %s\n" - -#, c-format -msgid "lpmove: Unknown option '%c'!\n" -msgstr "lpmove: Option '%c' inconnue !\n" - -#, c-format -msgid "lpmove: Unknown argument '%s'!\n" -msgstr "lpmove: Argument '%s' inconnu !\n" - -msgid "Usage: lpmove job dest\n" -msgstr "Utilisation : lpmove tâche destination\n" - -#, c-format -msgid "lpmove: Unable to connect to server: %s\n" -msgstr "lpmove: Impossible de se connecter au serveur : %s\n" - -#, c-format -msgid "lpmove: move-job failed: %s\n" -msgstr "lpmove: move-job a échoué : %s\n"" - -msgid "lpoptions: Unknown printer or class!\n" -msgstr "lpoptions: Imprimante ou classe inconnue !\n" - -msgid "lpoptions: No printers!?!\n" -msgstr "lpoptions: Pas d'imprimante !?!\n" - -#, c-format -msgid "lpoptions: Unable to add printer or instance: %s\n" -msgstr "lpoptions: Impossible d'ajouter l'imprimante ou l'instance : %s\n" - -#, c-format -msgid "lpoptions: Destination %s has no PPD file!\n" -msgstr "lpoptions: La destination %s n'a pas de fichier PPD !\n" - -#, c-format -msgid "lpoptions: Unable to open PPD file for %s!\n" -msgstr "lpoptions: Impossible d'ouvrir le fichier PPD pour %s !\n" - -msgid "" -"Usage: lpoptions [-h server] [-E] -d printer\n" -" lpoptions [-h server] [-E] [-p printer] -l\n" -" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" -" lpoptions [-h server] [-E] -x printer\n" -msgstr "" -"Utilisation : lpoptions [-h serveur] [-E] -d imprimante\n" -" lpoptions [-h serveur] [-E] [-p imprimante] -l\n" -" lpoptions [-h serveur] [-E] -p imprimante -o option[=valeur] ...\n" -" lpoptions [-h serveur] [-E] -x imprimante\n" - -msgid "lppasswd: Only root can add or delete passwords!\n" -msgstr "lppasswd: Seul l'utilisateur « root » peut ajouter ou supprimer des mots de passe !\n" - -msgid "Enter old password:" -msgstr "Ancien mot de passe :" - -#, c-format -msgid "lppasswd: Unable to copy password string: %s\n" -msgstr "lppasswd: Impossible de copier le mot de passe : %s\n" - -msgid "Enter password:" -msgstr "Entrez le nouveau mot de passe :" - -msgid "Enter password again:" -msgstr "Confirmez le nouveau mot de passe :" - -msgid "lppasswd: Sorry, passwords don't match!\n" -msgstr "lppasswd: Désolé, les mots de passe sont différents !\n" - -msgid "" -"lppasswd: Sorry, password rejected.\n" -"Your password must be at least 6 characters long, cannot contain\n" -"your username, and must contain at least one letter and number.\n" -msgstr "" -"lppasswd: Désolé, mot de passe refusé.\n" -"Votre mot de passe doit comporter au moins 6 caractères, au moins une lettre\n" -"et un nombre, et ne peut contenir votre nom d'utilisateur.\n" - -msgid "lppasswd: Password file busy!\n" -msgstr "lppasswd: Le fichier des mots de passe exidte déjà !\n" - -#, c-format -msgid "lppasswd: Unable to open password file: %s\n" -msgstr "lppasswd: Impossible d'ouvrir le fichier des mots de passe: %s\n" - -#, c-format -msgid "lppasswd: Unable to write to password file: %s\n" -msgstr "lppasswd: Impossible d'écrire dans le fichier des mots de passe : %s\n" - -#, c-format -msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" -msgstr "lppasswd: l'utilisateur « %s » et/ou le groupe « %s » n'existe(nt) pas !\n" - -msgid "lppasswd: Sorry, password doesn't match!\n" -msgstr "lppasswd: Désolé, le mot de passe est erroné !\n" - -msgid "lppasswd: Password file not updated!\n" -msgstr "lppasswd: Le fichier des mots de passe n'a pas été mis-à-jour !\n" - -#, c-format -msgid "lppasswd: failed to backup old password file: %s\n" -msgstr "lppasswd: impossible de sauvegarder l'ancien fichier des mots de passe : %s\n" - -#, c-format -msgid "lppasswd: failed to rename password file: %s\n" -msgstr "lppasswd: impossible de renommer le fichier des mots de passe : %s\n" - -msgid "Usage: lppasswd [-g groupname]\n" -msgstr "Utilisation : lppasswd [-g nom_groupe]\n" - -msgid "" -"Usage: lppasswd [-g groupname] [username]\n" -" lppasswd [-g groupname] -a [username]\n" -" lppasswd [-g groupname] -x [username]\n" -msgstr "" -"Utilisation : lppasswd [-g nom_groupe] [nom_utilisateur]\n" -" lppasswd [-g nom_groupe] -a [nom_utilisateur]\n" -" lppasswd [-g nom_groupe] -x [nom_utilisateur]\n" - -msgid "Start Printer" -msgstr "Démarrer l'imprimante" - -msgid "Stop Printer" -msgstr "Arrêter l'imprimante" - -msgid "Start Class" -msgstr "Démarrer la classe" - -msgid "Stop Class" -msgstr "Arrêter la classe" - -msgid "Accept Jobs" -msgstr "Accepter les tâches" - -msgid "Reject Jobs" -msgstr "Refuser les tâches" - -msgid "Purge Jobs" -msgstr "Effacer les tâches" - -msgid "Set As Default" -msgstr "Choisir par défaut" - -msgid "Administration" -msgstr "Administration" - -msgid "Modify Class" -msgstr "Modifier la classe" - -msgid "Add Class" -msgstr "Ajouter une classe" - -msgid "The class name may only contain up to 127 printable characters and may not contain spaces, slashes (/), or the pound sign (#)." -msgstr "Le nom de classe doit comporter au plus 127 caractères, tous imprimables, sans espace, '/' ni '#'." - -msgid "Unable to modify class:" -msgstr "Impossible de modifier la classe :" - -msgid "Unable to add class:" -msgstr "Impossible d'ajouter la classe :" - -msgid "Modify Printer" -msgstr "Modifier l'imprimante" - -msgid "Add Printer" -msgstr "Ajouter une imprimante" - -msgid "The printer name may only contain up to 127 printable characters and may not contain spaces, slashes (/), or the pound sign (#)." -msgstr "Le nom d'imprimante doit comporter au plus 127 caractères, tous imprimables, sans espace, '/' ni '#'." - -msgid "Unable to get list of printer drivers:" -msgstr "Impossible d'obtenir la liste des pilotes pour l'imprimante:" - -msgid "Unable to modify printer:" -msgstr "Impossible de modifier l'imprimante :" - -msgid "Unable to add printer:" -msgstr "Impossible d'ajouter l'imprimante :" - -msgid "Set Printer Options" -msgstr "Définir les options de l'imprimante" - -msgid "Missing form variable!" -msgstr "Un champ du formulaire HTML n'a pas été rempli !" - -msgid "Unable to get PPD file!" -msgstr "Impossible de trouver le fichier PPD !" - -msgid "Unable to open PPD file:" -msgstr "Impossible d'ouvrir le fichier PPD :" - -msgid "Banners" -msgstr "Bannières" - -msgid "Starting Banner" -msgstr "Début de la bannière" - -msgid "Ending Banner" -msgstr "Fin de la bannière" - -msgid "Policies" -msgstr "Politiques" - -msgid "Error Policy" -msgstr "Politique d'erreur" - -msgid "Operation Policy" -msgstr "Politique des opérations" - -msgid "PS Binary Protocol" -msgstr "Protocole binaire PS" - -msgid "None" -msgstr "Auncun(e)" - -msgid "Unable to set options:" -msgstr "Impossible de définir les options :" - -msgid "Change Settings" -msgstr "Modifier les paramètres" - -msgid "Unable to change server settings:" -msgstr "Impossible de modifier les paramètres du serveur :" - -msgid "Unable to upload cupsd.conf file:" -msgstr "Impossible de transmettre le fichier cupsd.conf :" - -msgid "Edit Configuration File" -msgstr "Éditer le fichier de configuration" - -msgid "Unable to create temporary file:" -msgstr "Impossible de créer le fichier temporaire :" - -msgid "Unable to access cupsd.conf file:" -msgstr "Impossible d'accéder au fichier cupsd.conf :" - -msgid "Unable to edit cupsd.conf files larger than 1MB!" -msgstr "Impossible d'éditer des fichiers cupsd.conf de taille supérieure à 1Mo !" - -msgid "Delete Class" -msgstr "Supprimer la classe" - -msgid "Unable to delete class:" -msgstr "Impossible de supprimer la classe :" - -msgid "Delete Printer" -msgstr "Supprimer l'imprimante" - -msgid "Unable to delete printer:" -msgstr "Impossible de supprimer l'imprimante :" - -msgid "Export Printers to Samba" -msgstr "Exporter les imprimantes vers SAMBA" - -msgid "Unable to fork process!" -msgstr "Impossible de faire un « fork » !" - -msgid "Unable to connect to server!" -msgstr "Impossible de se connecter au serveur !" - -msgid "Unable to get printer attributes!" -msgstr "Impossible de récupérer les attributs de l'imprimante !" - -msgid "Unable to convert PPD file!" -msgstr "Impossible de convertir le fichier PPD !" - -msgid "Unable to copy Windows 2000 printer driver files!" -msgstr "Impossible de copier les fichiers de pilote d'impression pour Windows 2000 !" - -msgid "Unable to install Windows 2000 printer driver files!" -msgstr "Impossible d'installer les fichiers de pilote d'impression pour Windows 2000 !" - -msgid "Unable to copy Windows 9x printer driver files!" -msgstr "Impossible de copier les fichiers de pilote d'impression pour Windows 9x !" - -msgid "Unable to install Windows 9x printer driver files!" -msgstr "Impossible d'installer les fichiers de pilote d'impression pour Windows 9x !" - -msgid "Unable to set Windows printer driver!" -msgstr "Impossible d'installer les fichiers de pilote d'impression pour Windows !" - -msgid "No printer drivers found!" -msgstr "Aucun pilote trouvé pour l'imprimante !" - -msgid "Unable to execute cupsaddsmb command!" -msgstr "Impossible d'exécuter la commande cupsaddsmb !" - -#, c-format -msgid "cupsaddsmb failed with status %d" -msgstr "cupsaddsmb a échoué avec le statut %d" - -#, c-format -msgid "cupsaddsmb crashed on signal %d" -msgstr "cupsaddsmb s'est terminé inopinément sur réception du signal %d" - -msgid "A Samba username is required to export printer drivers!" -msgstr "Il faut un nom d'utilisateur SAMBA pour exporter les pilotes d'imprimante !" - -msgid "A Samba password is required to export printer drivers!" -msgstr "Il faut un mot de passe SAMBA pour exporter les pilotes d'imprimante !" - -msgid "Unable to open cupsd.conf file:" -msgstr "Impossible d'ouvrir le fichier cupsd.conf :" - -msgid "Unable to change printer:" -msgstr "Impossible de modifier l'imprimante :" - -msgid "Set Allowed Users" -msgstr "Définir les autorisations" - -msgid "Unable to get printer attributes:" -msgstr "Impossible de récupérer les attributs de l'imprimante :" - -msgid "Set Publishing" -msgstr "Publier" - -msgid "Unable to change printer-is-shared attribute:" -msgstr "Impossible de modifier l'attribut « printer-is-shared » :" - -msgid "Classes" -msgstr "Classes" - -msgid "Unable to get class list:" -msgstr "Impossible d'obtenir la liste des classes :" - -msgid "Unable to get class status:" -msgstr "Impossible d'obtenir l'état de la classe :" - -msgid "Move Job" -msgstr "Transférer la tâche" - -msgid "Unable to find destination for job!" -msgstr "Impossible de trouver la destination de la tâche !" - -msgid "Move All Jobs" -msgstr "Transférer toutes les tâches" - -msgid "Unable to move job" -msgstr "Impossible de transférer la tâche !" - -msgid "Unable to move jobs" -msgstr "Impossible de transférer les tâches !" - -msgid "Print Test Page" -msgstr "Imprimer la page de test" - -msgid "Unable to print test page:" -msgstr "Impossible d'imprimer la page de test :" - -msgid "Jobs" -msgstr "Tâches" - -msgid "Job operation failed:" -msgstr "L'opération sur la tâche a échoué :" - -msgid "Printers" -msgstr "Imprimantes" - -msgid "Unable to get printer list:" -msgstr "Impossible d'obtenir la liste des imprimantes :" - -msgid "Unable to get printer status:" -msgstr "Impossible d'obtenir l'état de l'imprimante :" - -msgid "OK" -msgstr "OK" - -msgid "Unable to open PPD file" -msgstr "Impossible d'ouvrir le fichier PPD !" - -msgid "NULL PPD file pointer" -msgstr "Pointeur de fichier PPD NUL !" - -msgid "Memory allocation error" -msgstr "Problème d'allocation de mémoire" - -msgid "Missing PPD-Adobe-4.x header" -msgstr "Il manque l'entête PPD-Adobe-4.x" - -msgid "Missing value string" -msgstr "Il manque la valeur" - -msgid "Internal error" -msgstr "Erreur interne" - -msgid "Bad OpenGroup" -msgstr "OpenGroup erroné" - -msgid "OpenGroup without a CloseGroup first" -msgstr "OpenGroup sans de CloseGroup d'abord" - -msgid "Bad OpenUI/JCLOpenUI" -msgstr "OpenUI/JCLOpenUI erroné" - -msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" -msgstr "OpenUI/JCLOpenUI sans de CloseUI/JCLCloseUI d'abord" - -msgid "Bad OrderDependency" -msgstr "OrderDependency erroné" - -msgid "Bad UIConstraints" -msgstr "UIConstraints erroné" - -msgid "Missing asterisk in column 1" -msgstr "Il manque un astérisque à la colonne 1" - -msgid "Line longer than the maximum allowed (255 characters)" -msgstr "Ligne plus longue que les 255 caractères autorisés" - -msgid "Illegal control character" -msgstr "Caractère de contrôle incorrect" - -msgid "Illegal main keyword string" -msgstr "Mot-clé essentiel incorrect" - -msgid "Illegal option keyword string" -msgstr "Mot-clé d'option incorrect" - -msgid "Illegal translation string" -msgstr "Traduction incorrecte" - -msgid "Illegal whitespace character" -msgstr "Caractère « espace blanc » incorrect" - -msgid "Bad custom parameter" -msgstr "Paramètre de personnalisation incorrect" - -msgid "Unknown" -msgstr "Inconnu(e)" - -msgid "Custom" -msgstr "Personnalisation" - -msgid "JCL" -msgstr "JCL ( Langage de contrôle de tâche )" - -msgid "No authentication information provided!" -msgstr "Pas d'information d'authentification !" - -#, c-format -msgid "Password for %s required to access %s via SAMBA: " -msgstr "Il faut un mot de passe à %s pour accéder à %s via SAMBA : " - -#, c-format -msgid "Running command: %s %s -N -U '%s%%%s' -c '%s'\n" -msgstr "Exécute la commande : %s %s -N -U '%s%%%s' -c '%s'\n" - -#, c-format -msgid "cupsaddsmb: Unable to run \"%s\": %s\n" -msgstr "cupsaddsmb: Impossible d'exécuter « %s » : %s\n" - -msgid "cupsaddsmb: No Windows printer drivers are installed!\n" -msgstr "cupsaddsmb: Aucun pilote d'impression pour Windows n'est installé !\n" - -msgid "cupsaddsmb: Warning, no Windows 2000 printer drivers are installed!\n" -msgstr "cupsaddsmb: Attention, aucun pilote d'impression pour Windows 2000 n'est installé !\n" - -#, c-format -msgid "lpadmin: Printer %s is already a member of class %s.\n" -msgstr "lpadmin: L'imprimante %s est déjà membre de la classe %s.\n" - -msgid "lpadmin: No member names were seen!\n" -msgstr "lpadmin: Aucun nom de membre trouvé !\n" - -#, c-format -msgid "lpadmin: Printer %s is not a member of class %s.\n" -msgstr "lpadmin: L'imprimante %s n'est pas membre de la classe %s.\n" - -#, c-format -msgid "" -"Device: uri = %s\n" -" class = %s\n" -" info = %s\n" -" make-and-model = %s\n" -" device-id = %s\n" -msgstr "" -"Matériel : URI = %s\n" -" classe = %s\n" -" info = %s\n" -" marque/modèle = %s\n" -" ID matériel = %s\n" - -#, c-format -msgid "" -"Model: name = %s\n" -" natural_language = %s\n" -" make-and-model = %s\n" -" device-id = %s\n" -msgstr "" -"Modèle : nom = %s\n" -" langue naturelle = %s\n" -" marque/modèle = %s\n" -" ID matériel = %s\n" - - -msgid "Usage: lpmove job/src dest\n" -msgstr "Utilisation : lpmove tâche/source destination\n" - -msgid "lpstat: Need \"completed\", \"not-completed\", or \"all\" after -W!\n" -msgstr "lpstat: Il faut « completed » ou « not-completed » après l'option -W !\n" - -#, c-format -msgid "%s accepting requests since %s\n" -msgstr "%s accepte les requêtes depuis le %s\n" - -#, c-format -msgid "" -"%s not accepting requests since %s -\n" -"\t%s\n" -msgstr "" -"%s n'accepte pas les requêtes depuis le %s -\n" -"\t%s\n" - -#, c-format -msgid "%s/%s accepting requests since %s\n" -msgstr "%s/%s accepte les requêtes depuis le %s\n" - -#, c-format -msgid "" -"%s/%s not accepting requests since %s -\n" -"\t%s\n" -msgstr "" -"%s/%s n'accepte pas les requêtes depuis le %s -\n" -"\t%s\n" - -msgid "lpc> " -msgstr "lpc> " - -#, c-format -msgid "%s: Unable to contact server!\n" -msgstr "%s: Impossible de contacter le serveur !\n" - -#, c-format -msgid "%s: Error - expected username after '-U' option!\n" -msgstr "%s: Erreur - il faut un nom d'utilisateur après l'option '-U' !\n" - -#, c-format -msgid "%s: Error - unknown destination \"%s/%s\"!\n" -msgstr "%s: Erreur - destination « %s/%s » inconnue !\n" - -#, c-format -msgid "%s: Unknown destination \"%s\"!\n" -msgstr "%s: Destination « %s » inconnue !\n" - -#, c-format -msgid "%s: Error - expected hostname after '-h' option!\n" -msgstr "%s: Erreur - il faut un nom de machine après l'option '-h' !\n" - -#, c-format -msgid "%s: error - %s environment variable names non-existent destination \"%s\"!\n" -msgstr "%s: Erreur - la variable d'environnement %s désigne une destination inexistente « %s » !\n" - -#, c-format -msgid "%s: error - no default destination available.\n" -msgstr "%s: Erreur - aucune destination par défaut n'est disponible.\n" - -msgid "Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" -msgstr "Utilisation : lpq [-P dest] [-U nom_utilisateur] [-h nom_machine[:port]] [-l] [+intervalle]\n" - -#, c-format -msgid "%s: Error - expected hostname after '-H' option!\n" -msgstr "%s: Erreur - il faut un nom de machine après l'option '-H' !\n" - -#, c-format -msgid "%s: Error - expected value after '-%c' option!\n" -msgstr "%s: Erreur - il faut une valeur après l'option '-%c' !\n" - -#, c-format -msgid "%s: Warning - '%c' format modifier not supported - output may not be correct!\n" -msgstr "%s: Attention - le modificateur de format '%c' n'est pas géré - l'affichage pourrait être incorrect !\n" - -#, c-format -msgid "%s: error - expected option=value after '-o' option!\n" -msgstr "%s: Erreur - il faut un argument du type option=valeur après l'option '-o' !\n" - -#, c-format -msgid "%s: Error - expected destination after '-P' option!\n" -msgstr "%s: Erreur - il faut une destination après l'option '-P' !\n" - -#, c-format -msgid "%s: Error - expected copy count after '-#' option!\n" -msgstr "%s: Erreur - il faut un nombre de copies après l'option '-#' !\n" - -#, c-format -msgid "%s: Error - expected name after '-%c' option!\n" -msgstr "%s: Erreur - il faut un nom après l'option '-%c' !\n" - -#, c-format -msgid "%s: Error - unknown option '%c'!\n" -msgstr "%s: Erreur - option '%c' inconnue !\n" - -#, c-format -msgid "%s: Error - unable to access \"%s\" - %s\n" -msgstr "%s: Erreur - impossible d'accéder à « %s » - %s\n" - -#, c-format -msgid "%s: Error - too many files - \"%s\"\n" -msgstr "%s: Erreur - trop de fichiers - « %s »\n" - -#, c-format -msgid "%s: Error - %s environment variable names non-existent destination \"%s\"!\n" -msgstr "%s: Erreur - la variable d'environnement %s désigne une destination inexistente « %s » !\n" - -#, c-format -msgid "%s: Error - no default destination available.\n" -msgstr "%s: Erreur - aucune destination par défaut n'est disponible.\n" - -#, c-format -msgid "%s: Error - scheduler not responding!\n" -msgstr "%s: Erreur - l'ordonnanceur ne répond pas !\n" - -#, c-format -msgid "%s: Error - unable to create temporary file \"%s\" - %s\n" -msgstr "%s: Erreur - impossible de créer le fichier temporaire « %s » - %s\n" - -#, c-format -msgid "%s: Error - unable to write to temporary file \"%s\" - %s\n" -msgstr "%s: Erreur - impossible d'écrire dans le fichier temporaire « %s » - %s\n" - -#, c-format -msgid "%s: Error - stdin is empty, so no job has been sent.\n" -msgstr "%s: Erreur - stdin est vide, donc aucune tâche n'a été envoyée.\n" - -#, c-format -msgid "%s: Error - unknown destination \"%s\"!\n" -msgstr "%s: Erreur - destination « %s » inconnue !\n" - -#, c-format -msgid "%s: Error - expected reason text after '-r' option!\n" -msgstr "%s: Erreur - il faut le texte de la raison après l'option '-r' !\n" - -#, c-format -msgid "%s: Error - expected username after '-u' option!\n" -msgstr "%s: Erreur - il faut un nom d'utilisateur après l'option '-u' !\n" - -#, c-format -msgid "%s: %s failed: %s\n" -msgstr ""%s: %s a échoué : %s" - -#, c-format -msgid "%s: Error - expected destination after '-d' option!\n" -msgstr "%s: Erreur - il faut une destination après l'option '-d' !\n" - -#, c-format -msgid "%s: Error - expected form after '-f' option!\n" -msgstr "%s: Erreur - il faut un format après l'option '-f' !\n" - -#, c-format -msgid "%s: Warning - form option ignored!\n" -msgstr "%s: Attention - l'option « format » est ignorée !\n" - -#, c-format -msgid "%s: Expected job ID after '-i' option!\n" -msgstr "%s: Il faut un numéro de tâche après l'option '-i' !\n" - -#, c-format -msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" -msgstr "%s: Erreur - impossible d'imprimer et modifier les tâches en même temps !\n" - -#, c-format -msgid "%s: Error - bad job ID!\n" -msgstr "%s: Erreur - numéro de tâche incorrect !\n" - -#, c-format -msgid "%s: Error - expected copies after '-n' option!\n" -msgstr "%s: Erreur - il faut un nombre de copies après l'option '-n' !\n" - -#, c-format -msgid "%s: Error - expected option string after '-o' option!\n" -msgstr "%s: Erreur - il faut une chaîne d'option \"nom=valeur\" après l'option '-o' !\n" - -#, c-format -msgid "%s: Error - expected priority after '-%c' option!\n" -msgstr "%s: Erreur - il faut une priorité après l'option '-%c' !\n" - -#, c-format -msgid "%s: Error - priority must be between 1 and 100.\n" -msgstr "%s: Erreur - la priorité doit être comprise entre 1 et 100.\n" - -#, c-format -msgid "%s: Error - expected title after '-t' option!\n" -msgstr "%s: Erreur - il faut un titre après l'option '-t' !\n" - -#, c-format -msgid "%s: Error - expected mode list after '-y' option!\n" -msgstr "%s: Erreur - il faut une liste de modes après l'option '-y' !\n" - -#, c-format -msgid "%s: Warning - mode option ignored!\n" -msgstr "%s: Attention - l'option « mode » est ignorée !\n" - -#, c-format -msgid "%s: Error - expected hold name after '-H' option!\n" -msgstr "%s: Erreur - il faut un code de retenue après l'option '-H' !\n" - -#, c-format -msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" -msgstr "%s: Il faut un numéro de tâche ( '-i' ) avant '-H restart' !\n" - -#, c-format -msgid "%s: Error - expected page list after '-P' option!\n" -msgstr "%s: Erreur - il faut une liste de pages après l'option '-P' !\n" - -#, c-format -msgid "%s: Error - expected character set after '-S' option!\n" -msgstr "%s: Erreur - il faut un jeu de caractères après l'option '-S' !\n" - -#, c-format -msgid "%s: Warning - character set option ignored!\n" -msgstr "%s: Attention - l'option « jeu de caractères » est ignorée !\n" - -#, c-format -msgid "%s: Error - expected content type after '-T' option!\n" -msgstr "%s: Erreur - il faut un type de contenu après l'option '-T' !\n" - -#, c-format -msgid "%s: Warning - content type option ignored!\n" -msgstr "%s: Attention - l'option « type de contenu » est ignorée !\n" - -#, c-format -msgid "%s: Error - cannot print from stdin if files or a job ID are provided!\n" -msgstr "" -"%s: Erreur - impossible d'imprimer depuis l'entrée standard si un fichier\n" -" ou un numéro de tâche est spécifié !\n" - -#, c-format -msgid "%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' option!\n" -msgstr "%s: Erreur - il faut « completed », « not-completed », ou « all » après l'option -W !\n" - -#, c-format -msgid "%s: Error - expected destination after '-b' option!\n" -msgstr "%s: Erreur - il faut une destination après l'option '-b' !\n" - -#, c-format -msgid "%s: Invalid destination name in list \"%s\"!\n" -msgstr "%s: Erreur - nom de destination incorrect dans la liste « %s » !\n" - -#, c-format -msgid "%s: Unable to connect to server\n" -msgstr "%s: Impossible de se connecter au serveur !\n" - -msgid "Print Job:" -msgstr "Imprimer la tâche :" - -msgid "pending" -msgstr "en attente" - -msgid "held" -msgstr "retenue" - -msgid "processing" -msgstr "en cours" - -msgid "stopped" -msgstr "arrêtée" - -msgid "canceled" -msgstr "annulée" - -msgid "aborted" -msgstr "abandonnée" - -msgid "completed" -msgstr "terminée" - -msgid "unknown" -msgstr "inconnue" - -msgid "untitled" -msgstr "sans titre" - -msgid "Printer:" -msgstr "Imprimante :" - -msgid "idle" -msgstr "inactive" - -msgid "Missing notify-subscription-ids attribute!" -msgstr "Il manque l'attibut notify-subscription-ids" - -msgid "Job subscriptions cannot be renewed!" -msgstr "Les souscriptions de tâche ne peuvent être renouvelées !" - - -I AM HERE - - -msgid "cupsd: Expected config filename after \"-c\" option!\n" -msgstr "cupsd: Il faut un nom de fichier de configuration après l'option '-c' !\n" - -msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" -msgstr "cupsd: la gestion de launchd(8) n'a pas été compilée - exécution en mode normal.\n" - -#, c-format -msgid "cupsd: Unknown option \"%c\" - aborting!\n" -msgstr "cupsd: Option « %c » inconnue - abandon !\n" - -#, c-format -msgid "cupsd: Unknown argument \"%s\" - aborting!\n" -msgstr "cupsd: Argument « %s » inconnu - abandon !\n" - -msgid "" -"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" -"\n" -"-c config-file Load alternate configuration file\n" -"-f Run in the foreground\n" -"-F Run in the foreground but detach\n" -"-h Show this usage message\n" -"-l Run cupsd from launchd(8)\n" -msgstr "" -"Utilisation : cupsd [-c fichier-config] [-f] [-F] [-h] [-l]\n" -"\n" -"-c fichier-config Charge un autre fichier de configuration\n" -"-f Exécution au premier plan\n" -"-F Exécution au premier plan mais détaché\n" -"-h Affiche the message d'aide\n" -"-l Exécute cupsd depuis launchd(8)\n" - -#, c-format -msgid " WARN Line %d only contains whitespace!\n" -msgstr " WARN Line %d only contains whitespace!\n" - -msgid " WARN File contains a mix of CR, LF, and CR LF line endings!\n" -msgstr " WARN File contains a mix of CR, LF, and CR LF line endings!\n" - -msgid " WARN Non-Windows PPD files should use lines ending with only LF, not CR LF!\n" -msgstr " WARN Non-Windows PPD files should use lines ending with only LF, not CR LF!\n" - -msgid "Printer Maintenance" -msgstr "Maintenance de l'imprimante" - -msgid "Unable to send maintenance job:" -msgstr "Impossible d'envoyer la tâche de maintenance :" - -#, c-format -msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" -msgstr "cupsaddsmb: Pas de fichier PPD pour l'imprimante « %s » - %s\n" - -#, c-format -msgid " **FAIL** %s %s does not exist!\n" -msgstr " **FAIL** %s %s does not exist!\n" - -#, c-format -msgid " **FAIL** Bad language \"%s\"!\n" -msgstr " **FAIL** Bad language \"%s\"!\n" - -#, c-format -msgid " **FAIL** Missing \"%s\" translation string for option %s!\n" -msgstr " **FAIL** Missing \"%s\" translation string for option %s!\n" - -#, c-format -msgid " **FAIL** Default translation string for option %s contains 8-bit characters!\n" -msgstr " **FAIL** Default translation string for option %s contains 8-bit characters!\n" - -#, c-format -msgid " **FAIL** Missing \"%s\" translation string for option %s, choice %s!\n" -msgstr " **FAIL** Missing \"%s\" translation string for option %s, choice %s!\n" - -#, c-format -msgid " **FAIL** Default translation string for option %s choice %s contains 8-bit characters!\n" -msgstr " **FAIL** Default translation string for option %s choice %s contains 8-bit characters!\n" - -#, c-format -msgid " **FAIL** Bad cupsFilter value \"%s\"!\n" -msgstr " **FAIL** Bad cupsFilter value \"%s\"!\n" - -msgid "Help" -msgstr "Aide" - -#, c-format -msgid "Missing value on line %d!\n" -msgstr "Il manque une valeur à la ligne %d !\n" - -#, c-format -msgid "Missing double quote on line %d!\n" -msgstr "Il manque un \" à la ligne %d !\n" - -#, c-format -msgid "Bad option + choice on line %d!\n" -msgstr "Couple option + choix incorrect à la ligne %d !\n" - -#, c-format -msgid "Unable to copy Windows 2000 printer driver files (%d)!\n" -msgstr "Impossible de copier les fichiers de pilote d'impression pour Windows 2000 ( %d ) !\n" - -#, c-format -msgid "Unable to copy CUPS printer driver files (%d)!\n" -msgstr "Impossible de copier les fichiers de pilote d'impression pour CUPS ( %d ) !\n" - -#, c-format -msgid "Unable to install Windows 2000 printer driver files (%d)!\n" -msgstr "Impossible d'installer les fichiers de pilote d'impression pour Windows 2000 ( %d ) !\n" - -#, c-format -msgid "Unable to copy Windows 9x printer driver files (%d)!\n" -msgstr "Impossible de copier les fichiers de pilote d'impression pour Windows 9x ( %d ) !\n" - -#, c-format -msgid "Unable to install Windows 9x printer driver files (%d)!\n" -msgstr "Impossible d'installer les fichiers de pilote d'impression pour Windows 9x ( %d ) !\n" - -msgid "No Windows printer drivers are installed!\n" -msgstr "Aucun pilote d'impression pour Windows n'est installé !\n" - -msgid "Warning, no Windows 2000 printer drivers are installed!\n" -msgstr "Attention, aucun pilote d'impression pour Windows 2000 n'est installé !\n" - -#, c-format -msgid "Unable to set Windows printer driver (%d)!\n" -msgstr "Impossible d'installer les fichiers de pilote d'impression pour Windows ( %d ) !\n"" - -msgid "" -"Usage: cupsaddsmb [options] printer1 ... printerN\n" -" cupsaddsmb [options] -a\n" -"\n" -"Options:\n" -" -E Encrypt the connection to the server\n" -" -H samba-server Use the named SAMBA server\n" -" -U samba-user Authenticate using the named SAMBA user\n" -" -a Export all printers\n" -" -h cups-server Use the named CUPS server\n" -" -v Be verbose (show commands)\n" -msgstr "" -"Utilisation : cupsaddsmb [options] imprimante1 ... imprimanteN\n" -" cupsaddsmb [options] -a\n" -"\n" -"Options:\n" -" -E Crypter la connexion au serveur\n" -" -H serveur-samba Utiliser le serveur SAMBA désigné\n" -" -U utilisateur-samba S'authentifier avec l'utilisateur SAMBA désigné\n" -" -a Exporter toutes les imprimantes\n" -" -h serveur-CUPS Utiliser le serveur CUPS désigné\n" -" -v Être locace ( afficher les commandes )\n" - -#, c-format -msgid "Unable to copy Windows 2000 printer driver files (%d)!" -msgstr "Impossible de copier les fichiers de pilote d'impression pour Windows 2000 ( %d ) !" - -#, c-format -msgid "Unable to copy CUPS printer driver files (%d)!" -msgstr "Impossible de copier les fichiers de pilote d'impression pour CUPS ( %d ) !" - -#, c-format -msgid "Unable to install Windows 2000 printer driver files (%d)!" -msgstr "Impossible d'installer les fichiers de pilote d'impression pour Windows 2000 ( %d ) !" - -#, c-format -msgid "Unable to copy Windows 9x printer driver files (%d)!" -msgstr "Impossible de copier les fichiers de pilote d'impression pour Windows 9x ( %d ) !" - -#, c-format -msgid "Unable to install Windows 9x printer driver files (%d)!" -msgstr "Impossible d'installer les fichiers de pilote d'impression pour Windows 9x ( %d ) !" - -msgid "No Windows printer drivers are installed!" -msgstr "Aucun pilote d'impression pour Windows n'est installé !" - -msgid "Warning, no Windows 2000 printer drivers are installed!" -msgstr "Attention, aucun pilote d'impression pour Windows 2000 n'est installé !" - -#, c-format -msgid "open of %s failed: %s" -msgstr "l'ouverture de %s a échoué : %s" - -#, c-format -msgid "Running command: %s %s -N -A %s -c '%s'\n" -msgstr "Exécution de la commande : %s %s -N -A %s -c '%s'\n" - -#, c-format -msgid "stat of %s failed: %s" -msgstr "stat sur %s a échoué : %s" - -#, c-format -msgid "Job #%d is already cancelled - can't cancel." -msgstr "La tâche n°%d est déjà annulée - impossible de l'annuler." - -#, c-format -msgid "Job #%d is already aborted - can't cancel." -msgstr "La tâche n°%d est déjà abandonnée - impossible de l'annuler." - -#, c-format -msgid "Job #%d is already completed - can't cancel." -msgstr "La tâche n°%d est déjà terminée - impossible de l'annuler." - -#, c-format -msgid "You must access this page using the URL https://%s:%d%s." -msgstr "Vous devez accéder à cette page avec l'URL https://%s:%d%s." - -#, c-format -msgid "Unsupported format '%s'!" -msgstr "Format non géré '%s' !" - -msgid "FAIL\n" -msgstr "ÉCHEC" - -#, c-format -msgid "" -" Line %d is longer than 255 characters (%d)!\n" -" REF: Page 25, Line Length\n" -msgstr "" -" Line %d is longer than 255 characters (%d)!\n" -" REF: Page 25, Line Length\n" - -msgid "" -" Missing %!PS-Adobe-3.0 on first line!\n" -" REF: Page 17, 3.1 Conforming Documents\n" -msgstr "" -" Missing %!PS-Adobe-3.0 on first line!\n" -" REF: Page 17, 3.1 Conforming Documents\n" - -#, c-format -msgid "" -" Bad %%%%Pages: on line %d!\n" -" REF: Page 43, %%%%Pages:\n" -msgstr "" -" Bad %%%%Pages: on line %d!\n" -" REF: Page 43, %%%%Pages:\n" - -#, c-format -msgid "" -" Bad %%%%BoundingBox: on line %d!\n" -" REF: Page 39, %%%%BoundingBox:\n" -msgstr "" -" Bad %%%%BoundingBox: on line %d!\n" -" REF: Page 39, %%%%BoundingBox:\n" - -#, c-format -msgid "" -" Bad %%%%Page: on line %d!\n" -" REF: Page 53, %%%%Page:\n" -msgstr "" -" Bad %%%%Page: on line %d!\n" -" REF: Page 53, %%%%Page:\n" - -#, c-format -msgid "" -" Missing or bad %%BoundingBox: comment!\n" -" REF: Page 39, %%BoundingBox:\n" -msgstr "" -" Missing or bad %%BoundingBox: comment!\n" -" REF: Page 39, %%BoundingBox:\n" - -#, c-format -msgid "" -" Missing or bad %%Pages: comment!\n" -" REF: Page 43, %%Pages:\n" -msgstr "" -" Missing or bad %%Pages: comment!\n" -" REF: Page 43, %%Pages:\n" - -#, c-format -msgid "" -" Missing %%EndComments comment!\n" -" REF: Page 41, %%EndComments\n" -msgstr "" -" Missing %%EndComments comment!\n" -" REF: Page 41, %%EndComments\n" - -#, c-format -msgid "" -" Missing or bad %%Page: comments!\n" -" REF: Page 53, %%Page:\n" -msgstr "" -" Missing or bad %%Page: comments!\n" -" REF: Page 53, %%Page:\n" - -#, c-format -msgid " Too many %%EndDocument comments!\n" -msgstr " Too many %%EndDocument comments!\n" - -#, c-format -msgid " Too many %%BeginDocument comments!\n" -msgstr " Too many %%BeginDocument comments!\n" - -#, c-format -msgid " Saw %d lines that exceeded 255 characters!\n" -msgstr " Saw %d lines that exceeded 255 characters!\n" - -msgid "PASS\n" -msgstr "OK" - -msgid " Warning: file contains binary data!\n" -msgstr " Warning: file contains binary data!\n" - -#, c-format -msgid " Warning: obsolete DSC version %.1f in file!\n" -msgstr " Warning: obsolete DSC version %.1f in file!\n" - -#, c-format -msgid " Warning: no %%EndComments comment in file!\n" -msgstr " Warning: no %%EndComments comment in file!\n" - -msgid "" -"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" -" cupstestdsc [options] -\n" -"\n" -"Options:\n" -"\n" -" -h Show program usage\n" -"\n" -" Note: this program only validates the DSC comments, not the PostScript itself.\n" -msgstr "" -"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" -" cupstestdsc [options] -\n" -"\n" -"Options:\n" -"\n" -" -h Show program usage\n" -"\n" -" Note: this program only validates the DSC comments, not the PostScript itself.\n" - - -#, c-format -msgid "Password for %s on %s? " -msgstr "Mot de passe pour %s sur %s? " - -msgid "" -" **FAIL** 1284DeviceId must be 1284DeviceID!\n" -" REF: Page 72, section 5.5\n" -msgstr "" -" **FAIL** 1284DeviceId must be 1284DeviceID!\n" -" REF: Page 72, section 5.5\n" - - # # End of "$Id$". # diff --git a/locale/cups_it.po b/locale/cups_it.po index 60d920327..f4bafde80 100644 --- a/locale/cups_it.po +++ b/locale/cups_it.po @@ -22,7 +22,7 @@ msgid "" msgstr "" "Project-Id-Version: cups_it\n" "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2007-01-23 09:19-0500\n" +"POT-Creation-Date: 2007-01-23 09:44-0500\n" "PO-Revision-Date: 2006-11-16 00:34+0100\n" "Last-Translator: Vincenzo Reale \n" "Language-Team: Italian \n" @@ -2972,6 +2972,15 @@ msgstr "Impossibile configurare il driver di stampa di Windows (%d)!\n" msgid "Unable to run \"%s\": %s\n" msgstr "cupsaddsmb: Impossibile eseguire \"%s\": %s\n" +#, fuzzy +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Inserisci il tuo nome utente e la tua password o il nome utente e la " +"password di root per accedere a questa pagina." + #, fuzzy, c-format msgid "Job #%d is already canceled - can't cancel." msgstr "L'operazione #%d è già annullata - impossibile annullare." @@ -2996,6 +3005,10 @@ msgstr "" " **FAIL** 1284DeviceId deve essere 1284DeviceID!\n" " RIF: Pagina 72, sezione 5.5\n" +#, fuzzy, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d ERROR%s TROVATI\n" + #, fuzzy, c-format msgid "lpoptions: Unable to get PPD file for %s: %s\n" msgstr "lpoptions: Impossibile aprire il file PPD per %s!\n" diff --git a/locale/cups_pl.po b/locale/cups_pl.po index 7ee8c6b2f..dd3ad603c 100644 --- a/locale/cups_pl.po +++ b/locale/cups_pl.po @@ -25,7 +25,7 @@ msgid "" msgstr "" "Project-Id-Version: CUPS 1.2\n" "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2007-01-23 09:19-0500\n" +"POT-Creation-Date: 2007-01-23 09:44-0500\n" "PO-Revision-Date: 2006-05-09 17:20+0200\n" "Last-Translator: Piotr Drąg \n" "Language-Team: Polish \n" @@ -2972,6 +2972,15 @@ msgstr "Nie można ustawić sterownika drukarki Windows (%d)!\n" msgid "Unable to run \"%s\": %s\n" msgstr "cupsaddsmb: nie można uruchomić \"%s\": %s\n" +#, fuzzy +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Podaj swoją nazwę użytkownika i hasło lub nazwę użytkownika root i hasło, " +"aby uzyskać dostęp do tej strony." + #, fuzzy, c-format msgid "Job #%d is already canceled - can't cancel." msgstr "Zadanie #%d zostało już anulowane - nie można anulować." @@ -2996,6 +3005,10 @@ msgstr "" " **ZAWIÓDŁ** Błędny %s wybór %s!\n" " REF: strona 122, sekcja 5.17\n" +#, fuzzy, c-format +msgid " %d ERRORS FOUND\n" +msgstr " ZNALEZIONO %d BŁĘDÓW%s\n" + #, fuzzy, c-format msgid "lpoptions: Unable to get PPD file for %s: %s\n" msgstr "lpoptions: nie można otworzyć pliku PPD dla %s!\n" diff --git a/locale/cups_sv.po b/locale/cups_sv.po index 4e03b07c8..ce22e56e4 100644 --- a/locale/cups_sv.po +++ b/locale/cups_sv.po @@ -26,10 +26,10 @@ # Daniel Nylander , 2006, 2007. msgid "" msgstr "" -"Project-Id-Version: CUPS 1.2\n" +"Project-Id-Version: CUPS 1.3\n" "Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" -"POT-Creation-Date: 2007-01-23 09:19-0500\n" -"PO-Revision-Date: 2007-01-23 16:23+0100\n" +"POT-Creation-Date: 2007-01-23 09:44-0500\n" +"PO-Revision-Date: 2007-01-23 16:31+0100\n" "Last-Translator: Daniel Nylander \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" @@ -2828,7 +2828,7 @@ msgstr "Saknar värde på rad %d!" #, c-format msgid "Missing double quote on line %d!" -msgstr "Saknar citationstecken på rad %d!\n" +msgstr "Saknar dubbla citationstecken på rad %d!" #, c-format msgid "Bad option + choice on line %d!" @@ -2845,6 +2845,9 @@ msgstr "Kunde inte ställa in Windows-skrivardrivrutin (%d)!" msgid "Unable to run \"%s\": %s\n" msgstr "Kunde inte köra \"%s\": %s\n" +msgid "Enter your username and password or the root username and password to access this page. If you are using Kerberos authentication, make sure you have a valid Kerberos ticket." +msgstr "Ange ditt användarnamn och lösenord eller root-användarnamnet och lösenord för att komma åt denna sida. Om du använder Kerberos-autentisering, kontrollera att du har en giltig Kerberos-biljett." + #, c-format msgid "Job #%d is already canceled - can't cancel." msgstr "Jobb #%d är redan avbrutet - kan inte avbryta." @@ -2869,6 +2872,10 @@ msgstr "" " **FEL** %s måste vara 1284DeviceID!\n" " REF: Sida 72, sektion 5.5\n" +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d FEL HITTADES\n" + #, c-format msgid "lpoptions: Unable to get PPD file for %s: %s\n" msgstr "lpoptions: Kunde inte hämta PPD-fil för %s: %s\n" diff --git a/man/Makefile b/man/Makefile index 709e0ac7e..f60d35d7e 100644 --- a/man/Makefile +++ b/man/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5728 2006-07-12 20:45:13Z mike $" +# "$Id: Makefile 5727 2006-07-12 20:44:30Z mike $" # # Man page makefile for the Common UNIX Printing System (CUPS). # @@ -184,5 +184,5 @@ mantohtml: mantohtml.o # -# End of "$Id: Makefile 5728 2006-07-12 20:45:13Z mike $". +# End of "$Id: Makefile 5727 2006-07-12 20:44:30Z mike $". # diff --git a/man/classes.conf.man b/man/classes.conf.man index 4df347ade..6cd391120 100644 --- a/man/classes.conf.man +++ b/man/classes.conf.man @@ -1,5 +1,5 @@ .\" -.\" "$Id: classes.conf.man 5970 2006-09-19 20:11:08Z mike $" +.\" "$Id: classes.conf.man 5969 2006-09-19 20:09:24Z mike $" .\" .\" classes.conf man page for the Common UNIX Printing System (CUPS). .\" @@ -123,5 +123,5 @@ http://localhost:631/help .SH COPYRIGHT Copyright 1997-2006 by Easy Software Products, All Rights Reserved. .\" -.\" End of "$Id: classes.conf.man 5970 2006-09-19 20:11:08Z mike $". +.\" End of "$Id: classes.conf.man 5969 2006-09-19 20:09:24Z mike $". .\" diff --git a/man/cupsaddsmb.man.in b/man/cupsaddsmb.man.in index 9fd43137d..e1a1f08bb 100644 --- a/man/cupsaddsmb.man.in +++ b/man/cupsaddsmb.man.in @@ -1,5 +1,5 @@ .\" -.\" "$Id: cupsaddsmb.man.in 6049 2006-10-20 15:07:21Z mike $" +.\" "$Id: cupsaddsmb.man.in 6047 2006-10-20 14:52:55Z mike $" .\" .\" cupsaddsmb man page for the Common UNIX Printing System (CUPS). .\" @@ -215,5 +215,5 @@ http://www.cups.org/windows/ .SH COPYRIGHT Copyright 1997-2006 by Easy Software Products, All Rights Reserved. .\" -.\" End of "$Id: cupsaddsmb.man.in 6049 2006-10-20 15:07:21Z mike $". +.\" End of "$Id: cupsaddsmb.man.in 6047 2006-10-20 14:52:55Z mike $". .\" diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in index f17a4dcb3..757f71a7c 100644 --- a/man/cupsd.conf.man.in +++ b/man/cupsd.conf.man.in @@ -1,5 +1,5 @@ .\" -.\" "$Id: cupsd.conf.man.in 5638 2006-06-06 20:08:13Z mike $" +.\" "$Id: cupsd.conf.man.in 5919 2006-08-31 04:20:45Z mike $" .\" .\" cupsd.conf man page for the Common UNIX Printing System (CUPS). .\" @@ -83,8 +83,10 @@ AuthType Basic AuthType BasicDigest .TP 5 AuthType Digest +.TP 5 +AuthType Kerberos .br -Specifies the authentication type (None, Basic, BasicDigest, Digest) +Specifies the authentication type (None, Basic, BasicDigest, Digest, Kerberos) .TP 5 AutoPurgeJobs Yes .TP 5 @@ -220,6 +222,8 @@ DefaultAuthType Basic DefaultAuthType BasicDigest .TP 5 DefaultAuthType Digest +.TP 5 +DefaultAuthType Kerberos .br Specifies the default type of authentication to use. .TP 5 @@ -350,6 +354,10 @@ KeepAliveTimeout seconds .br Specifies the amount of time that connections are kept alive. .TP 5 +Krb5Keytab filename +.br +Overrides the Kerberos key tab location. +.TP 5 ... .br Specifies the IPP operations that are being limited inside a policy. @@ -609,5 +617,5 @@ http://localhost:631/help .SH COPYRIGHT Copyright 1997-2006 by Easy Software Products, All Rights Reserved. .\" -.\" End of "$Id: cupsd.conf.man.in 5638 2006-06-06 20:08:13Z mike $". +.\" End of "$Id: cupsd.conf.man.in 5919 2006-08-31 04:20:45Z mike $". .\" diff --git a/man/lpadmin.man b/man/lpadmin.man index 82677fcb6..d4e18c485 100644 --- a/man/lpadmin.man +++ b/man/lpadmin.man @@ -1,5 +1,5 @@ .\" -.\" "$Id: lpadmin.man 5970 2006-09-19 20:11:08Z mike $" +.\" "$Id: lpadmin.man 5969 2006-09-19 20:09:24Z mike $" .\" .\" lpadmin man page for the Common UNIX Printing System (CUPS). .\" @@ -205,5 +205,5 @@ http://localhost:631/help .SH COPYRIGHT Copyright 1997-2006 by Easy Software Products, All Rights Reserved. .\" -.\" End of "$Id: lpadmin.man 5970 2006-09-19 20:11:08Z mike $". +.\" End of "$Id: lpadmin.man 5969 2006-09-19 20:09:24Z mike $". .\" diff --git a/man/printers.conf.man b/man/printers.conf.man index 0a0469247..7e1f12d27 100644 --- a/man/printers.conf.man +++ b/man/printers.conf.man @@ -1,5 +1,5 @@ .\" -.\" "$Id: printers.conf.man 5970 2006-09-19 20:11:08Z mike $" +.\" "$Id: printers.conf.man 5969 2006-09-19 20:09:24Z mike $" .\" .\" printers.conf man page for the Common UNIX Printing System (CUPS). .\" @@ -127,5 +127,5 @@ http://localhost:631/help .SH COPYRIGHT Copyright 1997-2006 by Easy Software Products, All Rights Reserved. .\" -.\" End of "$Id: printers.conf.man 5970 2006-09-19 20:11:08Z mike $". +.\" End of "$Id: printers.conf.man 5969 2006-09-19 20:09:24Z mike $". .\" diff --git a/monitor/Dependencies b/monitor/Dependencies index 52599cfa1..251caa2e7 100644 --- a/monitor/Dependencies +++ b/monitor/Dependencies @@ -1,8 +1,8 @@ # DO NOT DELETE bcp.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h -bcp.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h -bcp.o: ../cups/file.h ../cups/language.h +bcp.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +bcp.o: ../cups/language.h tbcp.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h -tbcp.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h -tbcp.o: ../cups/file.h ../cups/language.h +tbcp.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +tbcp.o: ../cups/language.h diff --git a/notifier/Dependencies b/notifier/Dependencies index 4ee88b776..fb1754ab4 100644 --- a/notifier/Dependencies +++ b/notifier/Dependencies @@ -1,8 +1,8 @@ # DO NOT DELETE -mailto.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -mailto.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h -mailto.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h -testnotify.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -testnotify.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +mailto.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +mailto.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h +mailto.o: ../cups/transcode.h ../cups/string.h ../config.h +testnotify.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +testnotify.o: ../cups/array.h ../cups/file.h ../cups/language.h testnotify.o: ../cups/language.h ../cups/string.h ../config.h diff --git a/notifier/Makefile b/notifier/Makefile index ecfd7a51f..f2b221605 100644 --- a/notifier/Makefile +++ b/notifier/Makefile @@ -1,9 +1,9 @@ # -# "$Id: Makefile 5229 2006-03-05 16:48:12Z mike $" +# "$Id: Makefile 6304 2007-02-22 22:06:23Z mike $" # # Notifier makefile for the Common UNIX Printing System (CUPS). # -# Copyright 1997-2006 by Easy Software Products, all rights reserved. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the # property of Easy Software Products and are protected by Federal @@ -25,8 +25,8 @@ include ../Makedefs -TARGETS = mailto testnotify -OBJS = mailto.o testnotify.o +TARGETS = mailto rss testnotify +OBJS = mailto.o rss.o testnotify.o # @@ -53,6 +53,8 @@ install: all for file in $(TARGETS); do \ $(INSTALL_BIN) $$file $(SERVERBIN)/notifier; \ done + $(INSTALL_DIR) -m 755 $(CACHEDIR)/rss + -chgrp $(CUPS_GROUP) $(CACHEDIR)/rss # @@ -65,6 +67,7 @@ uninstall: done -$(RMDIR) $(SERVERBIN)/notifier -$(RMDIR) $(SERVERBIN) + -$(RMDIR) $(CACHEDIR)/rss # @@ -84,6 +87,15 @@ mailto: mailto.o ../cups/$(LIBCUPS) $(CC) $(LDFLAGS) -o mailto mailto.o $(LIBS) +# +# rss +# + +rss: rss.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o rss rss.o $(LIBS) + + # # testnotify # @@ -99,5 +111,5 @@ include Dependencies # -# End of "$Id: Makefile 5229 2006-03-05 16:48:12Z mike $". +# End of "$Id: Makefile 6304 2007-02-22 22:06:23Z mike $". # diff --git a/notifier/rss.c b/notifier/rss.c new file mode 100644 index 000000000..e9abfa3d3 --- /dev/null +++ b/notifier/rss.c @@ -0,0 +1,705 @@ +/* + * "$Id: rss.c 6326 2007-03-11 17:50:18Z mike $" + * + * RSS notifier for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9600 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry for the test notifier. + * compare_rss() - Compare two messages. + * delete_message() - Free all memory used by a message. + * load_rss() - Load an existing RSS feed file. + * new_message() - Create a new RSS message. + * password_cb() - Return the cached password. + * save_rss() - Save messages to a RSS file. + * xml_escape() - Copy a string, escaping &, <, and > as needed. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include + + +/* + * Structures... + */ + +typedef struct _cups_rss_s /**** RSS message data ****/ +{ + int sequence_number; /* notify-sequence-number */ + char *subject, /* Message subject/summary */ + *text, /* Message text */ + *link_url; /* Link to printer */ + time_t event_time; /* When the event occurred */ +} _cups_rss_t; + + +/* + * Local globals... + */ + +static char *rss_password; /* Password for remote RSS */ + + +/* + * Local functions... + */ + +static int compare_rss(_cups_rss_t *a, _cups_rss_t *b); +static void delete_message(_cups_rss_t *rss); +static void load_rss(cups_array_t *rss, const char *filename); +static _cups_rss_t *new_message(int sequence_number, char *subject, + char *text, char *link_url, + time_t event_time); +static const char *password_cb(const char *prompt); +static int save_rss(cups_array_t *rss, const char *filename, + const char *baseurl); +static char *xml_escape(const char *s); + + +/* + * 'main()' - Main entry for the test notifier. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + ipp_t *event; /* Event from scheduler */ + ipp_state_t state; /* IPP event state */ + char scheme[32], /* URI scheme ("rss") */ + username[256], /* Username for remote RSS */ + host[1024], /* Hostname for remote RSS */ + resource[1024], /* RSS file */ + *options; /* Options */ + int port, /* Port number for remote RSS */ + max_events; /* Maximum number of events */ + http_t *http; /* Connection to remote server */ + http_status_t status; /* HTTP GET/PUT status code */ + char filename[1024], /* Local filename */ + newname[1024]; /* filename.N */ + cups_lang_t *language; /* Language information */ + ipp_attribute_t *printer_up_time, /* Timestamp on event */ + *notify_sequence_number,/* Sequence number */ + *notify_printer_uri; /* Printer URI */ + char *subject, /* Subject for notification message */ + *text, /* Text for notification message */ + link_url[1024], /* Link to printer */ + link_scheme[32], /* Scheme for link */ + link_username[256], /* Username for link */ + link_host[1024], /* Host for link */ + link_resource[1024]; /* Resource for link */ + int link_port; /* Link port */ + cups_array_t *rss; /* RSS message array */ + _cups_rss_t *msg; /* RSS message */ + char baseurl[1024]; /* Base URL */ + + + fprintf(stderr, "DEBUG: argc=%d\n", argc); + for (i = 0; i < argc; i ++) + fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); + + /* + * See whether we are publishing this RSS feed locally or remotely... + */ + + if (httpSeparateURI(HTTP_URI_CODING_ALL, argv[1], scheme, sizeof(scheme), + username, sizeof(username), host, sizeof(host), &port, + resource, sizeof(resource)) < HTTP_URI_OK) + { + fprintf(stderr, "ERROR: Bad RSS URI \"%s\"!\n", argv[1]); + return (1); + } + + max_events = 20; + + if ((options = strchr(resource, '?')) != NULL) + { + *options++ = '\0'; + + if (!strncmp(options, "max_events=", 11)) + { + max_events = atoi(options + 11); + + if (max_events <= 0) + max_events = 20; + } + } + + rss = cupsArrayNew((cups_array_func_t)compare_rss, NULL); + + if (host[0]) + { + /* + * Remote feed, see if we can get the current file... + */ + + int fd; /* Temporary file */ + + + if ((rss_password = strchr(username, ':')) != NULL) + *rss_password++ = '\0'; + + cupsSetPasswordCB(password_cb); + cupsSetUser(username); + + if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) + { + fprintf(stderr, "ERROR: Unable to create temporary file: %s\n", + strerror(errno)); + + return (1); + } + + if ((http = httpConnect(host, port)) == NULL) + { + fprintf(stderr, "ERROR: Unable to connect to %s on port %d: %s\n", + host, port, strerror(errno)); + + close(fd); + unlink(filename); + + return (1); + } + + status = cupsGetFd(http, resource, fd); + + close(fd); + + if (status != HTTP_OK && status != HTTP_NOT_FOUND) + { + fprintf(stderr, "ERROR: Unable to GET %s from %s on port %d: %d %s\n", + resource, host, port, status, httpStatus(status)); + + httpClose(http); + unlink(filename); + + return (1); + } + + strlcpy(newname, filename, sizeof(newname)); + + httpAssembleURI(HTTP_URI_CODING_ALL, baseurl, sizeof(baseurl), "http", + NULL, host, port, resource); + } + else + { + const char *cachedir, /* CUPS_CACHEDIR */ + *server_name, /* SERVER_NAME */ + *server_port; /* SERVER_PORT */ + + + http = NULL; + + if ((cachedir = getenv("CUPS_CACHEDIR")) == NULL) + cachedir = CUPS_CACHEDIR; + + if ((server_name = getenv("SERVER_NAME")) == NULL) + server_name = "localhost"; + + if ((server_port = getenv("SERVER_PORT")) == NULL) + server_port = "631"; + + snprintf(filename, sizeof(filename), "%s/rss%s", cachedir, resource); + snprintf(newname, sizeof(newname), "%s.N", filename); + + httpAssembleURIf(HTTP_URI_CODING_ALL, baseurl, sizeof(baseurl), "http", + NULL, server_name, atoi(server_port), "/rss%s", resource); + } + + /* + * Load the previous RSS file, if any... + */ + + load_rss(rss, filename); + + /* + * Localize for the user's chosen language... + */ + + language = cupsLangDefault(); + + /* + * Read events and update the RSS file until we are out of events. + */ + + for (;;) + { + /* + * Read the next event... + */ + + event = ippNew(); + while ((state = ippReadFile(0, event)) != IPP_DATA) + { + if (state <= IPP_IDLE) + break; + } + + if (state == IPP_ERROR) + fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr); + + if (state <= IPP_IDLE) + { + ippDelete(event); + + if (http) + unlink(filename); + + httpClose(http); + + return (0); + } + + /* + * Collect the info from the event... + */ + + printer_up_time = ippFindAttribute(event, "printer-up-time", + IPP_TAG_INTEGER); + notify_sequence_number = ippFindAttribute(event, "notify-sequence-number", + IPP_TAG_INTEGER); + notify_printer_uri = ippFindAttribute(event, "notify-printer-uri", + IPP_TAG_URI); + subject = cupsNotifySubject(language, event); + text = cupsNotifyText(language, event); + + if (printer_up_time && notify_sequence_number && subject && text) + { + /* + * Create a new RSS message... + */ + + if (notify_printer_uri) + { + httpSeparateURI(HTTP_URI_CODING_ALL, + notify_printer_uri->values[0].string.text, + link_scheme, sizeof(link_scheme), + link_username, sizeof(link_username), + link_host, sizeof(link_host), &link_port, + link_resource, sizeof(link_resource)); + httpAssembleURI(HTTP_URI_CODING_ALL, link_url, sizeof(link_url), + "http", link_username, link_host, link_port, + link_resource); + } + + msg = new_message(notify_sequence_number->values[0].integer, + xml_escape(subject), xml_escape(text), + notify_printer_uri ? xml_escape(link_url) : NULL, + printer_up_time->values[0].integer); + + if (!msg) + { + fprintf(stderr, "ERROR: Unable to create message: %s\n", + strerror(errno)); + + ippDelete(event); + + if (http) + unlink(filename); + + httpClose(http); + + return (1); + } + + /* + * Add it to the array... + */ + + cupsArrayAdd(rss, msg); + + /* + * Trim the array as needed... + */ + + while (cupsArrayCount(rss) > max_events) + { + msg = cupsArrayFirst(rss); + + cupsArrayRemove(rss, msg); + + delete_message(msg); + } + + /* + * Save the messages to the file again, uploading as needed... + */ + + if (save_rss(rss, newname, baseurl)) + { + if (http) + { + /* + * Upload the RSS file... + */ + + if ((status = cupsPutFile(http, resource, filename)) != HTTP_CREATED) + fprintf(stderr, "ERROR: Unable to PUT %s from %s on port %d: %d %s\n", + resource, host, port, status, httpStatus(status)); + } + else + { + /* + * Move the new RSS file over top the old one... + */ + + if (rename(newname, filename)) + fprintf(stderr, "ERROR: Unable to rename %s to %s: %s\n", + newname, filename, strerror(errno)); + } + } + } + + if (subject) + free(subject); + + if (text) + free(text); + + ippDelete(event); + } +} + + +/* + * 'compare_rss()' - Compare two messages. + */ + +static int /* O - Result of comparison */ +compare_rss(_cups_rss_t *a, /* I - First message */ + _cups_rss_t *b) /* I - Second message */ +{ + return (a->sequence_number - b->sequence_number); +} + + +/* + * 'delete_message()' - Free all memory used by a message. + */ + +static void +delete_message(_cups_rss_t *msg) /* I - RSS message */ +{ + if (msg->subject) + free(msg->subject); + + if (msg->text) + free(msg->text); + + if (msg->link_url) + free(msg->link_url); + + free(msg); +} + + +/* + * 'load_rss()' - Load an existing RSS feed file. + */ + +static void +load_rss(cups_array_t *rss, /* I - RSS messages */ + const char *filename) /* I - File to load */ +{ + FILE *fp; /* File pointer */ + char line[4096], /* Line from file */ + *subject, /* Subject */ + *text, /* Text */ + *link_url, /* Link URL */ + *start, /* Start of element */ + *end; /* End of element */ + time_t event_time; /* Event time */ + int sequence_number; /* Sequence number */ + int in_item; /* In an item */ + _cups_rss_t *msg; /* New message */ + + + if ((fp = fopen(filename, "r")) == NULL) + { + if (errno != ENOENT) + fprintf(stderr, "ERROR: Unable to open %s: %s\n", filename, + strerror(errno)); + + return; + } + + subject = NULL; + text = NULL; + link_url = NULL; + event_time = 0; + sequence_number = 0; + in_item = 0; + + while (fgets(line, sizeof(line), fp)) + { + if (strstr(line, "")) + in_item = 1; + else if (strstr(line, "") && in_item) + { + if (subject && text) + { + msg = new_message(sequence_number, subject, text, link_url, + event_time); + + if (msg) + cupsArrayAdd(rss, msg); + + } + else + { + if (subject) + free(subject); + + if (text) + free(text); + + if (link_url) + free(link_url); + } + + subject = NULL; + text = NULL; + link_url = NULL; + event_time = 0; + sequence_number = 0; + in_item = 0; + } + else if (!in_item) + continue; + else if ((start = strstr(line, "")) != NULL) + { + start += 7; + if ((end = strstr(start, "")) != NULL) + { + *end = '\0'; + subject = strdup(start); + } + } + else if ((start = strstr(line, "")) != NULL) + { + start += 13; + if ((end = strstr(start, "")) != NULL) + { + *end = '\0'; + text = strdup(start); + } + } + else if ((start = strstr(line, "")) != NULL) + { + start += 6; + if ((end = strstr(start, "")) != NULL) + { + *end = '\0'; + link_url = strdup(start); + } + } + else if ((start = strstr(line, "")) != NULL) + { + start += 9; + if ((end = strstr(start, "")) != NULL) + { + *end = '\0'; + event_time = httpGetDateTime(start); + } + } + else if ((start = strstr(line, "")) != NULL) + sequence_number = atoi(start + 6); + } + + fclose(fp); +} + + +/* + * 'new_message()' - Create a new RSS message. + */ + +static _cups_rss_t * /* O - New message */ +new_message(int sequence_number, /* I - notify-sequence-number */ + char *subject, /* I - Subject/summary */ + char *text, /* I - Text */ + char *link_url, /* I - Link to printer */ + time_t event_time) /* I - Date/time of event */ +{ + _cups_rss_t *msg; /* New message */ + + + if ((msg = calloc(1, sizeof(_cups_rss_t))) == NULL) + return (NULL); + + msg->sequence_number = sequence_number; + msg->subject = subject; + msg->text = text; + msg->link_url = link_url; + msg->event_time = event_time; + + return (msg); +} + + +/* + * 'password_cb()' - Return the cached password. + */ + +static const char * /* O - Cached password */ +password_cb(const char *prompt) /* I - Prompt string, unused */ +{ + (void)prompt; + + return (rss_password); +} + + +/* + * 'save_rss()' - Save messages to a RSS file. + */ + +static int /* O - 1 on success, 0 on failure */ +save_rss(cups_array_t *rss, /* I - RSS messages */ + const char *filename, /* I - File to save to */ + const char *baseurl) /* I - Base URL */ +{ + FILE *fp; /* File pointer */ + _cups_rss_t *msg; /* Current message */ + char date[1024]; /* Current date */ + + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "ERROR: Unable to create %s: %s\n", filename, + strerror(errno)); + return (0); + } + + fputs("\n", fp); + fputs("\n", fp); + fputs(" \n", fp); + fputs(" CUPS RSS Feed\n", fp); + fprintf(fp, " %s\n", baseurl); + fputs(" CUPS RSS Feed\n", fp); + fputs(" " CUPS_SVERSION "\n", fp); + fputs(" 1\n", fp); + + fprintf(fp, " %s\n", + httpGetDateString2(time(NULL), date, sizeof(date))); + + for (msg = (_cups_rss_t *)cupsArrayLast(rss); + msg; + msg = (_cups_rss_t *)cupsArrayPrev(rss)) + { + fputs(" \n", fp); + fprintf(fp, " %s\n", msg->subject); + fprintf(fp, " %s\n", msg->text); + if (msg->link_url) + fprintf(fp, " %s\n", msg->link_url); + fprintf(fp, " %s\n", + httpGetDateString2(msg->event_time, date, sizeof(date))); + fprintf(fp, " %d\n", msg->sequence_number); + fputs(" \n", fp); + } + + fputs(" \n", fp); + fputs("\n", fp); + + return (!fclose(fp)); +} + + +/* + * 'xml_escape()' - Copy a string, escaping &, <, and > as needed. + */ + +static char * /* O - Escaped string */ +xml_escape(const char *s) /* I - String to escape */ +{ + char *e, /* Escaped string */ + *eptr; /* Pointer into escaped string */ + const char *sptr; /* Pointer into string */ + size_t bytes; /* Bytes needed for string */ + + + /* + * First figure out how many extra bytes we need... + */ + + for (bytes = 0, sptr = s; *sptr; sptr ++) + if (*sptr == '&') + bytes += 4; /* & */ + else if (*sptr == '<' || *sptr == '>') + bytes += 3; /* < and > */ + + /* + * If there is nothing to escape, just strdup() it... + */ + + if (bytes == 0) + return (strdup(s)); + + /* + * Otherwise allocate memory and copy... + */ + + if ((e = malloc(bytes + 1 + strlen(s))) == NULL) + return (NULL); + + for (eptr = e, sptr = s; *sptr; sptr ++) + if (*sptr == '&') + { + *eptr++ = '&'; + *eptr++ = 'a'; + *eptr++ = 'm'; + *eptr++ = 'p'; + *eptr++ = ';'; + } + else if (*sptr == '<') + { + *eptr++ = '&'; + *eptr++ = 'l'; + *eptr++ = 't'; + *eptr++ = ';'; + } + else if (*sptr == '>') + { + *eptr++ = '&'; + *eptr++ = 'g'; + *eptr++ = 't'; + *eptr++ = ';'; + } + else + *eptr++ = *sptr; + + *eptr = '\0'; + + return (e); +} + + +/* + * End of "$Id: rss.c 6326 2007-03-11 17:50:18Z mike $". + */ diff --git a/notifier/testnotify.c b/notifier/testnotify.c index d0a502b20..e9fec26c0 100644 --- a/notifier/testnotify.c +++ b/notifier/testnotify.c @@ -1,5 +1,5 @@ /* - * "$Id: testnotify.c 5716 2006-07-11 17:56:57Z mike $" + * "$Id: testnotify.c 5715 2006-07-11 17:56:13Z mike $" * * Test notifier for the Common UNIX Printing System (CUPS). * @@ -289,5 +289,5 @@ print_attributes(ipp_t *ipp, /* I - IPP request */ /* - * End of "$Id: testnotify.c 5716 2006-07-11 17:56:57Z mike $". + * End of "$Id: testnotify.c 5715 2006-07-11 17:56:13Z mike $". */ diff --git a/packaging/WELCOME.rtf b/packaging/WELCOME.rtf index 832780032..a949db828 100644 --- a/packaging/WELCOME.rtf +++ b/packaging/WELCOME.rtf @@ -10,7 +10,7 @@ \f1\b WARNING\ \f0\b0 \ -Because MacOS X packages cannot be uninstalled, you will need to reinstall MacOS X to revert to the original CUPS 1.1.x software.\ +This is pre-release software and should not be used in production environments. Because MacOS X packages cannot be uninstalled, you will need to reinstall MacOS X to revert to the original CUPS 1.1.x software.\ \ Please report all problems using the Bugs & Features page on the CUPS home page:\ \ diff --git a/packaging/cups.list.in b/packaging/cups.list.in index 24f623513..48d2479dd 100644 --- a/packaging/cups.list.in +++ b/packaging/cups.list.in @@ -1,5 +1,5 @@ # -# "$Id: cups.list.in 6234 2007-02-05 20:25:50Z mike $" +# "$Id: cups.list.in 6332 2007-03-12 16:08:51Z mike $" # # ESP Package Manager (EPM) file list for the Common UNIX Printing # System (CUPS). @@ -353,6 +353,7 @@ d 0755 root sys $LOGDIR - d 0710 root $CUPS_GROUP $REQUESTS - d 1770 root $CUPS_GROUP $REQUESTS/tmp - d 0775 root $CUPS_GROUP $CACHEDIR - +d 0775 root $CUPS_GROUP $CACHEDIR/rss - #d 0755 root $CUPS_GROUP $CACHEDIR/ppd - d 0755 root $CUPS_GROUP $STATEDIR - d 0511 root $CUPS_PRIMARY_SYSTEM_GROUP $STATEDIR/certs - @@ -486,7 +487,6 @@ f 0644 root sys $INCLUDEDIR/cups/http.h cups/http.h f 0644 root sys $INCLUDEDIR/cups/image.h filter/image.h f 0644 root sys $INCLUDEDIR/cups/ipp.h cups/ipp.h f 0644 root sys $INCLUDEDIR/cups/language.h cups/language.h -f 0644 root sys $INCLUDEDIR/cups/md5.h cups/md5.h f 0644 root sys $INCLUDEDIR/cups/ppd.h cups/ppd.h f 0644 root sys $INCLUDEDIR/cups/raster.h filter/raster.h f 0644 root sys $INCLUDEDIR/cups/transcode.h cups/transcode.h @@ -635,7 +635,7 @@ EOF %subpackage %system !darwin -i 0755 root sys cups init/cups.sh +i 0755 root sys cups init/cups.sh start(@RCSTART@) stop(@RCSTOP) runlevels(@RCLEVELS@) %subpackage lpd %if XINETD f 0644 root sys $XINETD/cups-lpd init/cups-lpd @@ -643,5 +643,5 @@ f 0644 root sys $XINETD/cups-lpd init/cups-lpd %subpackage # -# End of "$Id: cups.list.in 6234 2007-02-05 20:25:50Z mike $". +# End of "$Id: cups.list.in 6332 2007-03-12 16:08:51Z mike $". # diff --git a/packaging/cups.readme b/packaging/cups.readme index 958bd7b10..c2f964832 100644 --- a/packaging/cups.readme +++ b/packaging/cups.readme @@ -1,21 +1,86 @@ +README - CUPS v1.2.0b1 - 01/10/2006 +----------------------------------- + +***************************************************************** +***************************************************************** +**** **** +**** WARNING: THIS IS BETA RELEASE SOFTWARE AND MAY BE **** +**** TOTALLY UNSTABLE. DO NOT USE IN ENVIRONMENTS **** +**** WHERE RELIABLE SOFTWARE IS REQUIRED! **** +**** **** +***************************************************************** +***************************************************************** + +Looking for compile instructions? Read the file "INSTALL.txt" +instead... + +***************************************************************** +***************************************************************** +**** **** +**** IF YOU HAVE A NON-POSTSCRIPT PRINTER, YOU WILL ALSO **** +**** NEED TO INSTALL ESP GHOSTSCRIPT OR A PATCHED VERSION **** +**** OF A STANDARD GHOSTSCRIPT RELEASE. **** +**** **** +***************************************************************** +***************************************************************** + + +INTRODUCTION + +CUPS provides a portable printing layer for UNIX(r)-based +operating systems. It has been developed by Easy Software +Products to promote a standard printing solution for all UNIX +vendors and users. CUPS provides the System V and Berkeley +command-line interfaces. + +CUPS uses the Internet Printing Protocol ("IPP") as the basis +for managing print jobs and queues. The Line Printer Daemon +("LPD") Server Message Block ("SMB"), and AppSocket (a.k.a. +JetDirect) protocols are also supported with reduced +functionality. CUPS adds network printer browsing and +PostScript Printer Description ("PPD") based printing options to +support real-world printing under UNIX. + +CUPS includes an image file RIP that supports printing of image +files to non-PostScript printers. A customized version of GNU +Ghostscript for CUPS called ESP Ghostscript is available +separately to support printing of PostScript files within the +CUPS driver framework. Sample drivers for Dymo, EPSON, HP, and +OKIDATA printers are included that use these filters. + +Drivers for thousands of printers are provided with our ESP +Print Pro software, available at: + + http://www.easysw.com/printpro/ + +CUPS is licensed under the GNU General Public License and GNU +Library General Public License. Please contact Easy Software +Products for commercial support and "binary distribution" +rights. + + SYSTEM REQUIREMENTS Binary distributions require a minimum of 10MB of free disk space. We do not recommend using CUPS on a workstation with less than 32MB of RAM or a PC with less than 16MB of RAM. +If you are installing from source you'll need ANSI-compliant C +and C++ compilers and optionally one or more image file support +libraries. Complete source installation instructions can be +found in the file "INSTALL.txt". + SOFTWARE REQUIREMENTS The following operating system software is required to install one of the binary distributions from Easy Software Products: - - AIX 5.2 or higher + - AIX 4.3 or higher - HP-UX 11.00 or higher - IRIX 6.5 or higher - - Linux 2.4 with glibc 2.3 or higher (LSB 3.1) - - MacOS X 10.4 or higher (PowerPC or Intel) - - Solaris 8 or higher (SPARC or Intel) + - Linux 2.4 with glibc 2.2 or higher + - Solaris 7 or higher (SPARC or Intel) INSTALLING "PORTABLE" CUPS DISTRIBUTIONS @@ -25,7 +90,7 @@ distributions in TAR format with installation and removal scripts generated by our ESP Package Manager (EPM) software, which is available from: - http://www.easysw.com/epm/ + http://www.easysw.com/epm WARNING: Installing CUPS will overwrite your existing printing system. Backup files are made by the installation script and @@ -47,9 +112,10 @@ be installed and the scheduler will be started automatically. INSTALLING HOST-SPECIFIC (RPM, DEBIAN, ETC.) DISTRIBUTIONS -The host-specific distributions use the operating system software -installation tools. To install a host-specific distribution -please consult your operating system documentation. +The host-specific distributions use the operating system +software installation tools. To install a host-specific +distribution please consult the CUPS Software Administrators +Manual or your operating system documentation. READING THE DOCUMENTATION @@ -98,7 +164,93 @@ shown a menu of available functions. DO NOT use the hostname for your machine - it will not work with the default CUPS configuration. To enable administration access -on other addresses, consult the on-line help. +on other addresses, consult the CUPS Software Administrators +Manual. + + +SETTING UP PRINTER QUEUES FROM THE COMMAND-LINE + +CUPS works best with PPD (PostScript Printer Description) +files. In a pinch you can also use System V style printer +interface scripts. + +Six sample PPD files are provided with this distribution that +utilize the PostScript and image file RIPs and the sample EPSON +and HP printer drivers. To add the sample DeskJet driver to the +system for a printer connected to the parallel port, use one of +the following commands: + + HP-UX: + + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/c2t0d0_lp -E + + IRIX: + + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/plp -E + + Linux: + + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp0 -E + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp1 -E + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp2 -E + + Solaris: + + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/bpp0 -E + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/ecpp0 -E + +Similarly, for the other sample drivers you can use: + + Driver PPD File + ----------------------------- ------------ + Dymo Label Printers dymo.ppd + EPSON Stylus Color Series stcolor.ppd + EPSON Stylus Photo Series stphoto.ppd + EPSON Stylus New Color Series stcolor2.ppd + EPSON Stylus New Photo Series stphoto2.ppd + EPSON 9-pin Series epson9.ppd + EPSON 24-pin Series epson24.ppd + HP DeskJet Series deskjet.ppd + HP New DeskJet Series deskjet2.ppd + HP LaserJet Series laserjet.ppd + OKIDATA 9-Pin Series okidata9.ppd + OKIDATA 24-Pin Series okidat24.ppd + +These sample drivers provide basic printing capabilities, but +generally do not exercise the full potential of the printers or +CUPS. For commercial printer drivers check out our ESP Print +Pro software at: + + http://www.easysw.com/printpro/ + + +PRINTING FILES + +CUPS provides both the System V "lp" and Berkeley "lpr" commands +for printing: + + lp filename + lpr filename + +Both the "lp" and "lpr" commands support printing options for +the driver: + + lp -omedia=A4 -oresolution=600dpi filename + lpr -omedia=A4 -oresolution=600dpi filename + +CUPS recognizes many types of images files as well as PDF, +PostScript, HP-GL/2, and text files, so you can print those +files directly rather than through an application. + +If you have an application that generates output specifically +for your printer then you need to use the "-oraw" or "-l" +options: + + lp -oraw filename + lpr -l filename + +This will prevent the filters from misinterpreting your print +file. LEGAL STUFF diff --git a/packaging/cups.spec.in b/packaging/cups.spec.in index 0c00b8cd1..a63e725bd 100644 --- a/packaging/cups.spec.in +++ b/packaging/cups.spec.in @@ -1,11 +1,11 @@ # -# "$Id: cups.spec.in 6240 2007-02-06 16:09:05Z mike $" +# "$Id: cups.spec.in 6300 2007-02-22 04:46:59Z mike $" # # RPM "spec" file for the Common UNIX Printing System (CUPS). # # Original version by Jason McMullan . # -# Copyright 1999-2006 by Easy Software Products, all rights reserved. +# Copyright 1999-2007 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the # property of Easy Software Products and are protected by Federal @@ -366,6 +366,7 @@ rm -rf $RPM_BUILD_ROOT /usr/share/man/man8/reject.8.gz %dir /var/cache/cups +%attr(0775,root,sys) %dir /var/cache/cups/rss %dir /var/log/cups %dir /var/run/cups %attr(0711,lp,sys) %dir /var/run/cups/certs @@ -497,5 +498,5 @@ rm -rf $RPM_BUILD_ROOT # -# End of "$Id: cups.spec.in 6240 2007-02-06 16:09:05Z mike $". +# End of "$Id: cups.spec.in 6300 2007-02-22 04:46:59Z mike $". # diff --git a/pdftops/Dependencies b/pdftops/Dependencies index a36824a85..70b1e0acd 100644 --- a/pdftops/Dependencies +++ b/pdftops/Dependencies @@ -3,8 +3,8 @@ pdftops.o: ../cups/string.h ../config.h parseargs.h gtypes.h GString.h gmem.h pdftops.o: Object.h Array.h Dict.h Stream.h XRef.h Catalog.h Page.h PDFDoc.h pdftops.o: PSOutputDev.h GlobalParams.h CharTypes.h OutputDev.h Error.h -pdftops.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -pdftops.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +pdftops.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +pdftops.o: ../cups/array.h ../cups/file.h ../cups/language.h Annot.o: ../config.h gmem.h Object.h gtypes.h GString.h Array.h Dict.h Annot.o: Stream.h Catalog.h Gfx.h Lexer.h Annot.h Array.o: ../config.h gmem.h Object.h gtypes.h GString.h Array.h Dict.h diff --git a/pdftops/pdftops.cxx b/pdftops/pdftops.cxx index b9459cfa9..cb3b55e4c 100644 --- a/pdftops/pdftops.cxx +++ b/pdftops/pdftops.cxx @@ -1,5 +1,5 @@ // -// "$Id: pdftops.cxx 4906 2006-01-10 20:53:28Z mike $" +// "$Id: pdftops.cxx 6324 2007-03-11 02:09:46Z mike $" // // PDF to PostScript filter front-end for the Common UNIX Printing // System (CUPS). @@ -279,9 +279,16 @@ main(int argc, // I - Number of command-line args globalParams = new GlobalParams(buffer); - globalParams->setPSPaperWidth(width); - globalParams->setPSPaperHeight(length); - globalParams->setPSImageableArea(left, bottom, right, top); + if (fit || globalParams->getPSPaperWidth() > 0) + { + // Only set paper size and area if we are fitting to the job's + // page size or the pdftops.conf file does not contain + // "psPaperSize match"... + globalParams->setPSPaperWidth(width); + globalParams->setPSPaperHeight(length); + globalParams->setPSImageableArea(left, bottom, right, top); + } + globalParams->setPSDuplex(duplex); globalParams->setPSExpandSmaller(fit); globalParams->setPSShrinkLarger(fit); @@ -341,5 +348,5 @@ main(int argc, // I - Number of command-line args // -// End of "$Id: pdftops.cxx 4906 2006-01-10 20:53:28Z mike $". +// End of "$Id: pdftops.cxx 6324 2007-03-11 02:09:46Z mike $". // diff --git a/ppd/intelbar.ppd b/ppd/intelbar.ppd new file mode 100644 index 000000000..cc2ea6db3 --- /dev/null +++ b/ppd/intelbar.ppd @@ -0,0 +1,235 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Sample IntelliBar label printer driver PPD file for the Common UNIX +*% Printing System (CUPS). +*% +*% Copyright 2001-2006 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Easy Software Products and are protected by Federal +*% copyright law. Distribution and use rights are outlined in the file +*% "LICENSE.txt" which should have been included with this file. If this +*% file is missing or damaged please contact Easy Software Products +*% at: +*% +*% Attn: CUPS Licensing Information +*% Easy Software Products +*% 44141 Airport View Drive, Suite 204 +*% Hollywood, Maryland 20636 USA +*% +*% Voice: (301) 373-9600 +*% EMail: cups-info@cups.org +*% WWW: http://www.cups.org +*% +*FormatVersion: "4.3" +*FileVersion: "1.2" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "INTELBAR.PPD" +*Manufacturer: "Intellitech" +*Product: "(GNU Ghostscript)" +*Product: "(ESP Ghostscript)" +*cupsVersion: 1.2 +*cupsManualCopies: False +*cupsFilter: "application/vnd.cups-raster 0 rastertolabel" +*cupsModelNumber: 32 +*ModelName: "Intellitech IntelliBar Series Label Printer" +*ShortNickName: "Intellitech IntelliBar Series" +*NickName: "Intellitech IntelliBar Series Label Printer v1.2" +*PSVersion: "(3010.000) 81501" +*LanguageLevel: "3" +*ColorDevice: False +*DefaultColorSpace: Gray +*FileSystem: False +*Throughput: "8" +*LandscapeOrientation: Plus90 +*TTRasterizer: Type42 + +*OpenUI *PageSize/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: w288h432 +*PageSize w288h432/Label - 4.00x6.00": "<>setpagedevice" +*CloseUI: *PageSize + +*OpenUI *PageRegion: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: w288h432 +*PageRegion w288h432/Label - 4.00x6.00": "<>setpagedevice" +*CloseUI: *PageRegion + +*DefaultImageableArea: w288h432 +*ImageableArea w288h432/Label - 4.00x6.00": "0 5.76 288 426.24" + +*DefaultPaperDimension: w288h432 +*PaperDimension w288h432/Label - 4.00x6.00": "288 432" + +*MaxMediaWidth: "630" +*MaxMediaHeight: "7128" +*HWMargins: 0 5.76 0 5.76 +*CustomPageSize True: "pop pop pop <>setpagedevice" +*ParamCustomPageSize Width: 1 points 36 630 +*ParamCustomPageSize Height: 2 points 36 7128 +*ParamCustomPageSize WidthOffset: 3 points 0 0 +*ParamCustomPageSize HeightOffset: 4 points 0 0 +*ParamCustomPageSize Orientation: 5 int 0 0 + +*OpenUI *Resolution/Output Resolution: PickOne +*OrderDependency: 20 AnySetup *Resolution +*DefaultResolution: 300dpi +*Resolution 300dpi/300 DPI: "<>setpagedevice" +*CloseUI: *Resolution + +*OpenGroup: PrinterSettings/Printer Settings +*OpenUI *inPrintDensity/Print Density: PickOne +*OrderDependency: 20 DocumentSetup *inPrintDensity +*DefaultinPrintDensity: Default +*inPrintDensity Default/PrinterDefault: "<>setpagedevice" +*inPrintDensity -15: "<>setpagedevice" +*inPrintDensity -14: "<>setpagedevice" +*inPrintDensity -13: "<>setpagedevice" +*inPrintDensity -12: "<>setpagedevice" +*inPrintDensity -11: "<>setpagedevice" +*inPrintDensity -10: "<>setpagedevice" +*inPrintDensity -9: "<>setpagedevice" +*inPrintDensity -8: "<>setpagedevice" +*inPrintDensity -7: "<>setpagedevice" +*inPrintDensity -6: "<>setpagedevice" +*inPrintDensity -5: "<>setpagedevice" +*inPrintDensity -4: "<>setpagedevice" +*inPrintDensity -3: "<>setpagedevice" +*inPrintDensity -2: "<>setpagedevice" +*inPrintDensity -1: "<>setpagedevice" +*inPrintDensity 0: "<>setpagedevice" +*inPrintDensity 1: "<>setpagedevice" +*inPrintDensity 2: "<>setpagedevice" +*inPrintDensity 3: "<>setpagedevice" +*inPrintDensity 4: "<>setpagedevice" +*inPrintDensity 5: "<>setpagedevice" +*inPrintDensity 6: "<>setpagedevice" +*inPrintDensity 7: "<>setpagedevice" +*inPrintDensity 8: "<>setpagedevice" +*inPrintDensity 9: "<>setpagedevice" +*inPrintDensity 10: "<>setpagedevice" +*inPrintDensity 11: "<>setpagedevice" +*inPrintDensity 12: "<>setpagedevice" +*inPrintDensity 13: "<>setpagedevice" +*inPrintDensity 14: "<>setpagedevice" +*inPrintDensity 15: "<>setpagedevice" +*CloseUI: *inPrintDensity + +*OpenUI *inPrintRate/Print Speed: PickOne +*OrderDependency: 20 DocumentSetup *inPrintRate +*DefaultinPrintRate: Default +*inPrintRate Default/PrinterDefault: "<>setpagedevice" +*inPrintRate 15/15 mm/sec.: "<>setpagedevice" +*inPrintRate 20/20 mm/sec.: "<>setpagedevice" +*inPrintRate 30/30 mm/sec.: "<>setpagedevice" +*inPrintRate 40/40 mm/sec.: "<>setpagedevice" +*inPrintRate 60/60 mm/sec.: "<>setpagedevice" +*inPrintRate 80/80 mm/sec.: "<>setpagedevice" +*inPrintRate 100/100 mm/sec.: "<>setpagedevice" +*inPrintRate 120/120 mm/sec.: "<>setpagedevice" +*inPrintRate 150/150 mm/sec.: "<>setpagedevice" +*inPrintRate 200/200 mm/sec.: "<>setpagedevice" +*inPrintRate 250/250 mm/sec.: "<>setpagedevice" +*inPrintRate 300/300 mm/sec.: "<>setpagedevice" +*CloseUI: *inPrintRate + +*OpenUI *inPrintMode/Print Mode: PickOne +*OrderDependency: 20 DocumentSetup *inPrintMode +*DefaultinPrintMode: Standard +*inPrintMode Standard: "" +*inPrintMode Tear: "" +*inPrintMode Cut: "" +*CloseUI: *inPrintMode + +*OpenUI *inTearInterval/Print and Tear: PickOne +*OrderDependency: 20 DocumentSetup *inTearInterval +*DefaultinTearInterval: None +*inTearInterval None/Disabled: "<>setpagedevice" +*inTearInterval 1/Every Label: "<>setpagedevice" +*inTearInterval 2/Every 2 Labels: "<>setpagedevice" +*inTearInterval 3/Every 3 Labels: "<>setpagedevice" +*inTearInterval 4/Every 4 Labels: "<>setpagedevice" +*inTearInterval 5/Every 5 Labels: "<>setpagedevice" +*inTearInterval 6/Every 6 Labels: "<>setpagedevice" +*inTearInterval 7/Every 7 Labels: "<>setpagedevice" +*inTearInterval 8/Every 8 Labels: "<>setpagedevice" +*inTearInterval 9/Every 9 Labels: "<>setpagedevice" +*inTearInterval 10/Every 10 Labels: "<>setpagedevice" +*CloseUI: *inTearInterval + +*CustominTearInterval True: "<>setpagedevice" +*ParamCustominTearInterval Interval: 1 int 1 99 + +*OpenUI *inCutInterval/Print and Cut: PickOne +*OrderDependency: 20 DocumentSetup *inCutInterval +*DefaultinCutInterval: None +*inCutInterval None/Disabled: "<>setpagedevice" +*inCutInterval 1/Every Label: "<>setpagedevice" +*inCutInterval 2/Every 2 Labels: "<>setpagedevice" +*inCutInterval 3/Every 3 Labels: "<>setpagedevice" +*inCutInterval 4/Every 4 Labels: "<>setpagedevice" +*inCutInterval 5/Every 5 Labels: "<>setpagedevice" +*inCutInterval 6/Every 6 Labels: "<>setpagedevice" +*inCutInterval 7/Every 7 Labels: "<>setpagedevice" +*inCutInterval 8/Every 8 Labels: "<>setpagedevice" +*inCutInterval 9/Every 9 Labels: "<>setpagedevice" +*inCutInterval 10/Every 10 Labels: "<>setpagedevice" +*CloseUI: *inCutInterval + +*CustominCutInterval True: "<>setpagedevice" +*ParamCustominCutInterval Interval: 1 int 1 99 +*CloseGroup: *PrinterSettings + +*UIConstraints: *inCutInterval *inPrintMode Standard +*UIConstraints: *inCutInterval *inPrintMode Tear +*UIConstraints: *inPrintMode Standard *inCutInterval +*UIConstraints: *inPrintMode Tear *inCutInterval + +*UIConstraints: *inTearInterval *inPrintMode Standard +*UIConstraints: *inTearInterval *inPrintMode Cut +*UIConstraints: *inPrintMode Standard *inTearInterval +*UIConstraints: *inPrintMode Cut *inTearInterval + +*DefaultFont: Courier +*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM +*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM +*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM +*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM +*Font Bookman-Demi: Standard "(001.004S)" Standard ROM +*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM +*Font Bookman-Light: Standard "(001.004S)" Standard ROM +*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM +*Font Courier: Standard "(002.004S)" Standard ROM +*Font Courier-Bold: Standard "(002.004S)" Standard ROM +*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM +*Font Courier-Oblique: Standard "(002.004S)" Standard ROM +*Font Helvetica: Standard "(001.006S)" Standard ROM +*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM +*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM +*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM +*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM +*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM +*Font Palatino-Bold: Standard "(001.005S)" Standard ROM +*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM +*Font Palatino-Italic: Standard "(001.005S)" Standard ROM +*Font Palatino-Roman: Standard "(001.005S)" Standard ROM +*Font Symbol: Special "(001.007S)" Special ROM +*Font Times-Bold: Standard "(001.007S)" Standard ROM +*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM +*Font Times-Italic: Standard "(001.007S)" Standard ROM +*Font Times-Roman: Standard "(001.007S)" Standard ROM +*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM +*Font ZapfDingbats: Special "(001.004S)" Standard ROM +*% +*% End of "$Id: zebra.ppd 5130 2006-02-17 20:25:33Z mike $". +*% diff --git a/ppd/zebra.ppd b/ppd/zebra.ppd index 536896cb4..c478eda0f 100644 --- a/ppd/zebra.ppd +++ b/ppd/zebra.ppd @@ -1,6 +1,6 @@ *PPD-Adobe: "4.3" *% -*% "$Id: zebra.ppd 5511 2006-05-11 17:43:12Z mike $" +*% "$Id: zebra.ppd 5510 2006-05-11 17:41:54Z mike $" *% *% Sample Zebra label printer driver PPD file for the Common UNIX Printing *% System (CUPS). @@ -479,5 +479,5 @@ *Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM *Font ZapfDingbats: Special "(001.004S)" Standard ROM *% -*% End of "$Id: zebra.ppd 5511 2006-05-11 17:43:12Z mike $". +*% End of "$Id: zebra.ppd 5510 2006-05-11 17:41:54Z mike $". *% diff --git a/scheduler/Dependencies b/scheduler/Dependencies index e90107a76..46199952f 100644 --- a/scheduler/Dependencies +++ b/scheduler/Dependencies @@ -178,11 +178,11 @@ mime.o: ../cups/array.h ../cups/ipp.h ../cups/file.h type.o: ../cups/string.h ../config.h mime.h ../cups/array.h ../cups/ipp.h type.o: ../cups/file.h ../cups/debug.h cups-deviced.o: util.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -cups-deviced.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h +cups-deviced.o: ../cups/ppd.h ../cups/array.h ../cups/file.h cups-deviced.o: ../cups/language.h ../cups/file.h ../cups/string.h cups-deviced.o: ../config.h ../cups/array.h ../cups/dir.h cups-driverd.o: util.h ../cups/cups.h ../cups/ipp.h ../cups/http.h -cups-driverd.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h +cups-driverd.o: ../cups/ppd.h ../cups/array.h ../cups/file.h cups-driverd.o: ../cups/language.h ../cups/file.h ../cups/string.h cups-driverd.o: ../config.h ../cups/dir.h ../cups/transcode.h cups-lpd.o: ../cups/http-private.h ../config.h ../cups/http.h ../cups/md5.h @@ -193,20 +193,20 @@ cups-polld.o: ../cups/http-private.h ../config.h ../cups/http.h ../cups/md5.h cups-polld.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h cups-polld.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h cups-polld.o: ../cups/language.h ../cups/string.h -testdirsvc.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -testdirsvc.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +testdirsvc.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +testdirsvc.o: ../cups/array.h ../cups/file.h ../cups/language.h testdirsvc.o: ../cups/string.h ../config.h -testlpd.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -testlpd.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h -testlpd.o: ../cups/string.h ../config.h +testlpd.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +testlpd.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/string.h +testlpd.o: ../config.h testmime.o: ../cups/string.h ../config.h mime.h ../cups/array.h ../cups/ipp.h testmime.o: ../cups/file.h ../cups/dir.h -testspeed.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -testspeed.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +testspeed.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +testspeed.o: ../cups/array.h ../cups/file.h ../cups/language.h testspeed.o: ../cups/language.h ../cups/debug.h -testsub.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -testsub.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h -testsub.o: ../cups/debug.h ../cups/string.h ../config.h -util.o: util.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h -util.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h -util.o: ../cups/file.h ../cups/string.h ../config.h +testsub.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +testsub.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +testsub.o: ../cups/string.h ../config.h +util.o: util.h ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/ppd.h +util.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/file.h +util.o: ../cups/string.h ../config.h diff --git a/scheduler/Makefile b/scheduler/Makefile index 2eb297051..c76690e06 100644 --- a/scheduler/Makefile +++ b/scheduler/Makefile @@ -1,9 +1,9 @@ # -# "$Id: Makefile 5940 2006-09-11 18:30:09Z mike $" +# "$Id: Makefile 6291 2007-02-19 21:54:27Z mike $" # # Scheduler Makefile for the Common UNIX Printing System (CUPS). # -# Copyright 1997-2006 by Easy Software Products, all rights reserved. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. # # These coded instructions, statements, and computer programs are the # property of Easy Software Products and are protected by Federal @@ -43,6 +43,7 @@ CUPSDOBJS = \ printers.o \ process.o \ quotas.o \ + select.o \ server.o \ statbuf.o \ subscriptions.o \ @@ -188,14 +189,15 @@ cupsd: $(CUPSDOBJS) libmime.a ../cups/$(LIBCUPS) echo Linking $@... $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) libmime.a \ $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \ - $(LIBPAPER) $(LIBMALLOC) $(CUPSDLIBS) $(LIBS) + $(LIBPAPER) $(LIBMALLOC) $(CUPSDLIBS) $(DNSSDLIBS) $(LIBS) \ + $(LIBGSSAPI) cupsd-static: $(CUPSDOBJS) libmime.a ../cups/libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o cupsd-static $(CUPSDOBJS) libmime.a \ $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \ ../cups/libcups.a $(COMMONLIBS) $(LIBZ) $(LIBPAPER) \ - $(LIBMALLOC) $(CUPSDLIBS) + $(LIBMALLOC) $(CUPSDLIBS) $(DNSSDLIBS) $(LIBGSSAPI) # @@ -261,7 +263,7 @@ testdirsvc: testdirsvc.o testlpd: testlpd.o ../cups/libcups.a cups-lpd echo Linking $@... $(CC) $(LDFLAGS) -o testlpd testlpd.o ../cups/libcups.a \ - $(COMMONLIBS) $(LIBZ) $(SSLLIBS) + $(COMMONLIBS) $(LIBZ) $(SSLLIBS) $(LIBGSSAPI) # @@ -271,7 +273,7 @@ testlpd: testlpd.o ../cups/libcups.a cups-lpd testmime: testmime.o libmime.a ../cups/libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o $@ testmime.o libmime.a ../cups/libcups.a \ - $(COMMONLIBS) $(LIBZ) $(SSLLIBS) + $(COMMONLIBS) $(LIBZ) $(SSLLIBS) $(LIBGSSAPI) # @@ -281,7 +283,7 @@ testmime: testmime.o libmime.a ../cups/libcups.a testspeed: testspeed.o ../cups/libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o testspeed testspeed.o ../cups/libcups.a \ - $(COMMONLIBS) $(LIBZ) $(SSLLIBS) + $(SSLLIBS) $(COMMONLIBS) $(LIBZ) $(LIBGSSAPI) # @@ -291,7 +293,7 @@ testspeed: testspeed.o ../cups/libcups.a testsub: testsub.o ../cups/libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o testsub testsub.o ../cups/libcups.a \ - $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(SSLLIBS) $(COMMONLIBS) $(LIBZ) $(LIBGSSAPI) # @@ -302,5 +304,5 @@ include Dependencies # -# End of "$Id: Makefile 5940 2006-09-11 18:30:09Z mike $". +# End of "$Id: Makefile 6291 2007-02-19 21:54:27Z mike $". # diff --git a/scheduler/auth.c b/scheduler/auth.c index 41fd65f87..8baf94511 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -1,9 +1,12 @@ /* - * "$Id: auth.c 5948 2006-09-12 13:58:39Z mike $" + * "$Id: auth.c 6314 2007-03-01 19:11:54Z mike $" * * Authorization routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * This file contains Kerberos support code, copyright 2006 by + * Jelmer Vernooij. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -49,9 +52,11 @@ * compare_locations() - Compare two locations. * cups_crypt() - Encrypt the password using the DES or MD5 * algorithms, as needed. + * get_gss_creds() - Obtain GSS credentials. * get_md5_password() - Get an MD5 password. * pam_func() - PAM conversation function. * to64() - Base64-encode an integer value... + * check_authref() - Check an authorization services reference. */ /* @@ -79,6 +84,14 @@ #ifdef HAVE_MEMBERSHIP_H # include #endif /* HAVE_MEMBERSHIP_H */ +#ifdef HAVE_AUTHORIZATION_H +# include +# ifdef HAVE_SECBASEPRIV_H +# include +# else +extern const char *cssmErrorString(int error); +# endif /* HAVE_SECBASEPRIV_H */ +#endif /* HAVE_AUTHORIZATION_H */ /* @@ -87,17 +100,23 @@ static cupsd_authmask_t *add_allow(cupsd_location_t *loc); static cupsd_authmask_t *add_deny(cupsd_location_t *loc); +#ifdef HAVE_AUTHORIZATION_H +static int check_authref(cupsd_client_t *con, const char *right); +#endif /* HAVE_AUTHORIZATION_H */ static int compare_locations(cupsd_location_t *a, cupsd_location_t *b); #if !HAVE_LIBPAM && !defined(HAVE_USERSEC_H) static char *cups_crypt(const char *pw, const char *salt); #endif /* !HAVE_LIBPAM && !HAVE_USERSEC_H */ +#ifdef HAVE_GSSAPI +static gss_cred_id_t get_gss_creds(const char *service_name); +#endif /* HAVE_GSSAPI */ static char *get_md5_password(const char *username, const char *group, char passwd[33]); #if HAVE_LIBPAM static int pam_func(int, const struct pam_message **, struct pam_response **, void *); -#else +#elif !defined(HAVE_USERSEC_H) static void to64(char *s, unsigned long v, int n); #endif /* HAVE_LIBPAM */ @@ -309,8 +328,8 @@ void cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ { int type; /* Authentication type */ - char *authorization, /* Pointer into Authorization string */ - *ptr, /* Pointer into string */ + const char *authorization; /* Pointer into Authorization string */ + char *ptr, /* Pointer into string */ username[65], /* Username string */ password[33]; /* Password string */ const char *localuser; /* Certificate username */ @@ -356,7 +375,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ * Decode the Authorization string... */ - authorization = con->http.fields[HTTP_FIELD_AUTHORIZATION]; + authorization = httpGetField(&con->http, HTTP_FIELD_AUTHORIZATION); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAuthorize: Authorization=\"%s\"", authorization); @@ -364,6 +383,14 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ username[0] = '\0'; password[0] = '\0'; +#ifdef HAVE_AUTHORIZATION_H + if (con->authref) + { + AuthorizationFree(con->authref, kAuthorizationFlagDefaults); + con->authref = NULL; + } +#endif /* HAVE_AUTHORIZATION_H */ + if (type == AUTH_NONE) { /* @@ -384,6 +411,59 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ "cupsdAuthorize: No authentication data provided."); return; } +#ifdef HAVE_AUTHORIZATION_H + else if (!strncmp(authorization, "AuthRef", 6) && + !strcasecmp(con->http.hostname, "localhost")) + { + OSStatus status; /* Status */ + int authlen; /* Auth string length */ + AuthorizationItemSet *authinfo; /* Authorization item set */ + + /* + * Get the Authorization Services data... + */ + + authorization += 7; + while (isspace(*authorization & 255)) + authorization ++; + + authlen = sizeof(nonce); + httpDecode64_2(nonce, &authlen, authorization); + + if (authlen != kAuthorizationExternalFormLength) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: External Authorization reference size" + "is incorrect!"); + return; + } + + if ((status = AuthorizationCreateFromExternalForm( + (AuthorizationExternalForm *)nonce, &con->authref)) != 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: AuthorizationCreateFromExternalForm " + "returned %d (%s)", + (int)status, cssmErrorString(status)); + return; + } + + if ((status = AuthorizationCopyInfo(con->authref, + kAuthorizationEnvironmentUsername, + &authinfo)) != 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: AuthorizationCopyInfo returned %d (%s)", + (int)status, cssmErrorString(status)); + return; + } + + if (authinfo->count == 1) + strlcpy(username, authinfo->items[0].value, sizeof(username)); + + AuthorizationFreeItemSet(authinfo); + } +#endif /* HAVE_AUTHORIZATION_H */ else if (!strncmp(authorization, "Local", 5) && !strcasecmp(con->http.hostname, "localhost")) { @@ -754,6 +834,118 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ return; } } +#ifdef HAVE_GSSAPI + else if (!strncmp(authorization, "Negotiate", 9) && type == AUTH_KERBEROS) + { + int len; /* Length of authorization string */ + gss_cred_id_t server_creds; /* Server credentials */ + gss_ctx_id_t context; /* Authorization context */ + OM_uint32 major_status, /* Major status code */ + minor_status; /* Minor status code */ + gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER, + /* Input token from string */ + output_token = GSS_C_EMPTY_BUFFER; + /* Output token for username */ + gss_name_t client_name; /* Client name */ + + + con->gss_output_token.length = 0; + + /* + * Find the start of the Kerberos input token... + */ + + authorization += 9; + while (isspace(*authorization & 255)) + authorization ++; + + if (!*authorization) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAuthorize: No authentication data specified."); + return; + } + + /* + * Get the server credentials... + */ + + if ((server_creds = get_gss_creds(GSSServiceName)) == NULL) + { + con->no_negotiate = 1; + return; + } + + /* + * Decode the authorization string to get the input token... + */ + + len = strlen(authorization); + input_token.value = malloc(len); + input_token.value = httpDecode64_2(input_token.value, &len, + authorization); + input_token.length = len; + + /* + * Accept the input token to get the authorization info... + */ + + context = GSS_C_NO_CONTEXT; + client_name = GSS_C_NO_NAME; + major_status = gss_accept_sec_context(&minor_status, + &context, + server_creds, + &input_token, + GSS_C_NO_CHANNEL_BINDINGS, + &client_name, + NULL, + &con->gss_output_token, + NULL, + NULL, + &con->gss_delegated_cred); + + if (GSS_ERROR(major_status)) + { + cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, + "cupsdAuthorize: Error accepting GSSAPI security " + "context"); + + if (context != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER); + + con->no_negotiate = 1; + return; + } + + /* + * Get the username associated with the credentials... + */ + + if (major_status == GSS_S_COMPLETE) + { + major_status = gss_display_name(&minor_status, client_name, + &output_token, NULL); + + if (GSS_ERROR(major_status)) + { + cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, + "cupsdAuthorize: Error getting username"); + gss_release_name(&minor_status, &client_name); + gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER); + con->no_negotiate = 1; + return; + } + + gss_release_name(&minor_status, &client_name); + strlcpy(username, output_token.value, sizeof(username)); + + gss_release_buffer(&minor_status, &output_token); + gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER); + } + else + gss_release_name(&minor_status, &client_name); + } +#endif /* HAVE_GSSAPI */ else { cupsdLogMessage(CUPSD_LOG_DEBUG, @@ -1493,7 +1685,8 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */ "NONE", "BASIC", "DIGEST", - "BASICDIGEST" + "BASICDIGEST", + "KERBEROS" }; @@ -1623,9 +1816,11 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */ * See if encryption is required... */ - if (best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls && + if ((best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls && strcasecmp(con->http.hostname, "localhost") && - best->satisfy == AUTH_SATISFY_ALL) + best->satisfy == AUTH_SATISFY_ALL) && + !(best->type == AUTH_KERBEROS || + (best->type == AUTH_NONE && DefaultAuthType == AUTH_KERBEROS))) { cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: Need upgrade to TLS..."); @@ -1669,7 +1864,11 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: username=\"%s\"", con->username); +#ifdef HAVE_AUTHORIZATION_H + if (!con->username[0] && !con->authref) +#else if (!con->username[0]) +#endif /* HAVE_AUTHORIZATION_H */ { if (best->satisfy == AUTH_SATISFY_ALL || auth == AUTH_DENY) return (HTTP_UNAUTHORIZED); /* Non-anonymous needs user/pass */ @@ -1692,8 +1891,13 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */ * Get the user info... */ - pw = getpwnam(username); - endpwent(); + if (username[0]) + { + pw = getpwnam(username); + endpwent(); + } + else + pw = NULL; if (best->level == AUTH_USER) { @@ -1713,6 +1917,28 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: Checking user membership..."); +#ifdef HAVE_AUTHORIZATION_H + /* + * If an authorization reference was supplied it must match a right name... + */ + + if (con->authref) + { + for (i = 0; i < best->num_names; i ++) + { + if (!strncasecmp(best->names[i], "@AUTHKEY(", 9) && + check_authref(con, best->names[i] + 9)) + return (HTTP_OK); + else if (!strcasecmp(best->names[i], "@SYSTEM") && + SystemGroupAuthKey && + check_authref(con, SystemGroupAuthKey)) + return (HTTP_OK); + } + + return (HTTP_UNAUTHORIZED); + } +#endif /* HAVE_AUTHORIZATION_H */ + for (i = 0; i < best->num_names; i ++) { if (!strcasecmp(best->names[i], "@OWNER") && owner && @@ -1858,6 +2084,59 @@ add_deny(cupsd_location_t *loc) /* I - Location to add to */ } +#ifdef HAVE_AUTHORIZATION_H +/* + * 'check_authref()' - Check if an authorization services reference has the + * supplied right. + */ + +static int /* O - 1 if right is valid, 0 otherwise */ +check_authref(cupsd_client_t *con, /* I - Connection */ + const char *right) /* I - Right name */ +{ + OSStatus status; /* OS Status */ + AuthorizationItem authright; /* Authorization right */ + AuthorizationRights authrights; /* Authorization rights */ + AuthorizationFlags authflags; /* Authorization flags */ + + + /* + * Check to see if the user is allowed to perform the task... + */ + + if (!con->authref) + return (0); + + authright.name = right; + authright.valueLength = 0; + authright.value = NULL; + authright.flags = 0; + + authrights.count = 1; + authrights.items = &authright; + + authflags = kAuthorizationFlagDefaults | + kAuthorizationFlagExtendRights; + + if ((status = AuthorizationCopyRights(con->authref, &authrights, + kAuthorizationEmptyEnvironment, + authflags, NULL)) != 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "AuthorizationCopyRights(\"%s\") returned %d (%s)", + authright.name, (int)status, cssmErrorString(status)); + return (0); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "AuthorizationCopyRights(\"%s\") succeeded!", + authright.name); + + return (1); +} +#endif /* HAVE_AUTHORIZATION_H */ + + /* * 'compare_locations()' - Compare two locations. */ @@ -1993,6 +2272,79 @@ cups_crypt(const char *pw, /* I - Password string */ #endif /* !HAVE_LIBPAM && !HAVE_USERSEC_H */ +#ifdef HAVE_GSSAPI +/* + * 'get_gss_creds()' - Obtain GSS credentials. + */ + +static gss_cred_id_t /* O - Server credentials */ +get_gss_creds(const char *service_name) /* I - Service name */ +{ + OM_uint32 major_status, /* Major status code */ + minor_status; /* Minor status code */ + gss_name_t server_name; /* Server name */ + gss_cred_id_t server_creds; /* Server credentials */ + gss_buffer_desc token = GSS_C_EMPTY_BUFFER; + /* Service name token */ + char buf[1024], /* Service name buffer */ + fqdn[HTTP_MAX_URI]; /* Hostname of server */ + + + snprintf(buf, sizeof(buf), "%s@%s", service_name, + httpGetHostname(NULL, fqdn, sizeof(fqdn))); + + token.value = buf; + token.length = strlen(buf); + server_name = GSS_C_NO_NAME; + major_status = gss_import_name(&minor_status, &token, + GSS_C_NT_HOSTBASED_SERVICE, + &server_name); + + memset(&token, 0, sizeof(token)); + + if (GSS_ERROR(major_status)) + { + cupsdLogGSSMessage(CUPSD_LOG_WARN, major_status, minor_status, + "gss_import_name() failed"); + return (NULL); + } + + major_status = gss_display_name(&minor_status, server_name, &token, NULL); + + if (GSS_ERROR(major_status)) + { + cupsdLogGSSMessage(CUPSD_LOG_WARN, major_status, minor_status, + "gss_display_name() failed"); + return (NULL); + } + + cupsdLogMessage(CUPSD_LOG_INFO, "Attempting to acquire credentials for %s...", + (char *)token.value); + + server_creds = GSS_C_NO_CREDENTIAL; + major_status = gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE, + GSS_C_NO_OID_SET, GSS_C_ACCEPT, + &server_creds, NULL, NULL); + if (GSS_ERROR(major_status)) + { + cupsdLogGSSMessage(CUPSD_LOG_WARN, major_status, minor_status, + "gss_acquire_cred() failed"); + gss_release_name(&minor_status, &server_name); + gss_release_buffer(&minor_status, &token); + return (NULL); + } + + cupsdLogMessage(CUPSD_LOG_INFO, "Credentials acquired successfully for %s.", + (char *)token.value); + + gss_release_name(&minor_status, &server_name); + gss_release_buffer(&minor_status, &token); + + return (server_creds); +} +#endif /* HAVE_GSSAPI */ + + /* * 'get_md5_password()' - Get an MD5 password. */ @@ -2146,7 +2498,7 @@ pam_func( return (PAM_SUCCESS); } -#else +#elif !defined(HAVE_USERSEC_H) /* @@ -2170,5 +2522,5 @@ to64(char *s, /* O - Output string */ /* - * End of "$Id: auth.c 5948 2006-09-12 13:58:39Z mike $". + * End of "$Id: auth.c 6314 2007-03-01 19:11:54Z mike $". */ diff --git a/scheduler/auth.h b/scheduler/auth.h index 87bd72cd9..61c7ae993 100644 --- a/scheduler/auth.h +++ b/scheduler/auth.h @@ -1,5 +1,5 @@ /* - * "$Id: auth.h 5305 2006-03-18 03:05:12Z mike $" + * "$Id: auth.h 5919 2006-08-31 04:20:45Z mike $" * * Authorization definitions for the Common UNIX Printing System (CUPS) * scheduler. @@ -38,6 +38,7 @@ #define AUTH_BASIC 1 /* Basic authentication */ #define AUTH_DIGEST 2 /* Digest authentication */ #define AUTH_BASICDIGEST 3 /* Basic authentication w/passwd.md5 */ +#define AUTH_KERBEROS 4 /* Kerberos authentication */ #define AUTH_ANON 0 /* Anonymous access */ #define AUTH_USER 1 /* Must have a valid username/password */ @@ -158,5 +159,5 @@ extern http_status_t cupsdIsAuthorized(cupsd_client_t *con, const char *owner); /* - * End of "$Id: auth.h 5305 2006-03-18 03:05:12Z mike $". + * End of "$Id: auth.h 5919 2006-08-31 04:20:45Z mike $". */ diff --git a/scheduler/banners.c b/scheduler/banners.c index f78a1077d..31847ad2f 100644 --- a/scheduler/banners.c +++ b/scheduler/banners.c @@ -1,5 +1,5 @@ /* - * "$Id: banners.c 5948 2006-09-12 13:58:39Z mike $" + * "$Id: banners.c 5947 2006-09-12 13:58:22Z mike $" * * Banner routines for the Common UNIX Printing System (CUPS). * @@ -215,5 +215,5 @@ free_banners(void) /* - * End of "$Id: banners.c 5948 2006-09-12 13:58:39Z mike $". + * End of "$Id: banners.c 5947 2006-09-12 13:58:22Z mike $". */ diff --git a/scheduler/classes.c b/scheduler/classes.c index 749a1bda0..63a818bfd 100644 --- a/scheduler/classes.c +++ b/scheduler/classes.c @@ -1,9 +1,9 @@ /* - * "$Id: classes.c 5151 2006-02-22 22:43:17Z mike $" + * "$Id: classes.c 6318 2007-03-06 04:36:55Z mike $" * * Printer class routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -366,7 +366,21 @@ cupsdLoadAllClasses(void) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Loading class %s...", value); - p = cupsdAddClass(value); + /* + * Since prior classes may have implicitly defined this class, + * see if it already exists... + */ + + if ((p = cupsdFindDest(value)) != NULL) + { + p->type = CUPS_PRINTER_CLASS; + cupsdSetStringf(&p->uri, "ipp://%s:%d/classes/%s", ServerName, + LocalPort, value); + cupsdSetString(&p->error_policy, "retry-job"); + } + else + p = cupsdAddClass(value); + p->accepting = 1; p->state = IPP_PRINTER_IDLE; @@ -400,6 +414,13 @@ cupsdLoadAllClasses(void) "Syntax error on line %d of classes.conf.", linenum); return; } + else if (!strcasecmp(line, "AuthInfoRequired")) + { + if (!cupsdSetAuthInfoRequired(p, value, NULL)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad AuthInfoRequired on line %d of classes.conf.", + linenum); + } else if (!strcasecmp(line, "Info")) { if (value) @@ -703,6 +724,7 @@ cupsdSaveAllClasses(void) time_t curtime; /* Current time */ struct tm *curdate; /* Current date */ cups_option_t *option; /* Current option */ + const char *ptr; /* Pointer into info/location */ /* @@ -776,11 +798,49 @@ cupsdSaveAllClasses(void) else cupsFilePrintf(fp, "\n", pclass->name); + if (pclass->num_auth_info_required > 0) + { + cupsFilePrintf(fp, "AuthInfoRequired %s", pclass->auth_info_required[0]); + for (i = 1; i < pclass->num_auth_info_required; i ++) + cupsFilePrintf(fp, ",%s", pclass->auth_info_required[i]); + cupsFilePutChar(fp, '\n'); + } + if (pclass->info) - cupsFilePrintf(fp, "Info %s\n", pclass->info); + { + if ((ptr = strchr(pclass->info, '#')) != NULL) + { + /* + * Need to quote the first # in the info string... + */ + + cupsFilePuts(fp, "Info "); + cupsFileWrite(fp, pclass->info, ptr - pclass->info); + cupsFilePutChar(fp, '\\'); + cupsFilePuts(fp, ptr); + cupsFilePutChar(fp, '\n'); + } + else + cupsFilePrintf(fp, "Info %s\n", pclass->info); + } if (pclass->location) - cupsFilePrintf(fp, "Location %s\n", pclass->location); + { + if ((ptr = strchr(pclass->info, '#')) != NULL) + { + /* + * Need to quote the first # in the location string... + */ + + cupsFilePuts(fp, "Location "); + cupsFileWrite(fp, pclass->location, ptr - pclass->location); + cupsFilePutChar(fp, '\\'); + cupsFilePuts(fp, ptr); + cupsFilePutChar(fp, '\n'); + } + else + cupsFilePrintf(fp, "Location %s\n", pclass->location); + } if (pclass->state == IPP_PRINTER_STOPPED) { @@ -864,5 +924,5 @@ cupsdUpdateImplicitClasses(void) /* - * End of "$Id: classes.c 5151 2006-02-22 22:43:17Z mike $". + * End of "$Id: classes.c 6318 2007-03-06 04:36:55Z mike $". */ diff --git a/scheduler/client.c b/scheduler/client.c index 44a76f49e..9c0a17dc6 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -1,9 +1,12 @@ /* - * "$Id: client.c 6247 2007-02-07 20:54:37Z mike $" + * "$Id: client.c 6329 2007-03-12 14:48:28Z mike $" * * Client routines for the Common UNIX Printing System (CUPS) scheduler. * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * This file contains Kerberos support code, copyright 2006 by + * Jelmer Vernooij. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -33,6 +36,7 @@ * cupsdSendHeader() - Send an HTTP request. * cupsdUpdateCGI() - Read status messages from CGI scripts and programs. * cupsdWriteClient() - Write data to a client as needed. + * cupsdWritePipe() - Flag that data is available on the CGI pipe. * check_if_modified() - Decode an "If-Modified-Since" line. * encrypt_client() - Enable encryption for the client... * get_cdsa_certificate() - Convert a keychain name into the CFArrayRef @@ -94,7 +98,7 @@ static int encrypt_client(cupsd_client_t *con); #ifdef HAVE_CDSASSL static CFArrayRef get_cdsa_certificate(cupsd_client_t *con); #endif /* HAVE_CDSASSL */ -static char *get_file(cupsd_client_t *con, struct stat *filestats, +static char *get_file(cupsd_client_t *con, struct stat *filestats, char *filename, int len); static http_status_t install_conf_file(cupsd_client_t *con); static int is_cgi(cupsd_client_t *con, const char *filename, @@ -405,7 +409,7 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */ */ val = 1; - setsockopt(con->http.fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); + setsockopt(con->http.fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); /* * Close this file on all execs... @@ -417,10 +421,7 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */ * Add the socket to the select() input mask. */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdAcceptClient: Adding fd %d to InputSet...", - con->http.fd); - FD_SET(con->http.fd, InputSet); + cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, NULL, con); /* * Temporarily suspend accept()'s until we lose a client... @@ -587,13 +588,7 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */ if (con->file >= 0) { - if (FD_ISSET(con->file, InputSet)) - { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdCloseClient: %d Removing fd %d from InputSet...", - con->http.fd, con->file); - FD_CLR(con->file, InputSet); - } + cupsdRemoveSelect(con->file); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCloseClient: %d Closing data file %d.", @@ -615,11 +610,8 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */ * Only do a partial close so that the encrypted client gets everything. */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdCloseClient: Removing fd %d from OutputSet...", - con->http.fd); shutdown(con->http.fd, 0); - FD_CLR(con->http.fd, OutputSet); + cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, NULL, con); } else { @@ -627,12 +619,8 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */ * Shut the socket down fully... */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdCloseClient: Removing fd %d from InputSet and OutputSet...", - con->http.fd); + cupsdRemoveSelect(con->http.fd); close(con->http.fd); - FD_CLR(con->http.fd, InputSet); - FD_CLR(con->http.fd, OutputSet); con->http.fd = -1; } } @@ -671,6 +659,14 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */ con->language = NULL; } +#ifdef HAVE_AUTHORIZATION_H + if (con->authref) + { + AuthorizationFree(con->authref, kAuthorizationFlagDefaults); + con->authref = NULL; + } +#endif /* HAVE_AUTHORIZATION_H */ + /* * Re-enable new client connections if we are going back under the * limit... @@ -711,7 +707,7 @@ cupsdFlushHeader(cupsd_client_t *con) /* I - Client to flush to */ * 'cupsdReadClient()' - Read data from a client. */ -int /* O - 1 on success, 0 on error */ +void cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ { char line[32768], /* Line from client... */ @@ -740,7 +736,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (con->http.error) { cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadClient: http error seen..."); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; } #ifdef HAVE_SSL @@ -764,9 +761,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ buf[0] & 255); if (!encrypt_client(con)) - return (cupsdCloseClient(con)); + cupsdCloseClient(con); - return (1); + return; } } #endif /* HAVE_SSL */ @@ -782,7 +779,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ { cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadClient: httpGets returned EOF..."); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; } /* @@ -846,7 +844,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ "Bad request line \"%s\" from %s!", line, con->http.hostname); cupsdSendError(con, HTTP_BAD_REQUEST); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; case 2 : con->http.version = HTTP_0_9; break; @@ -857,7 +856,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ "Bad request line \"%s\" from %s!", line, con->http.hostname); cupsdSendError(con, HTTP_BAD_REQUEST); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; } if (major < 2) @@ -871,7 +871,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ else { cupsdSendError(con, HTTP_NOT_SUPPORTED); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; } break; } @@ -916,7 +917,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad URI \"%s\" in request!", con->uri); cupsdSendError(con, HTTP_METHOD_NOT_ALLOWED); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; } /* @@ -949,7 +951,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ { cupsdLogMessage(CUPSD_LOG_ERROR, "Bad operation \"%s\"!", operation); cupsdSendError(con, HTTP_BAD_REQUEST); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; } con->start = time(NULL); @@ -972,12 +975,16 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ * Parse incoming parameters until the status changes... */ - status = httpUpdate(HTTP(con)); + while ((status = httpUpdate(HTTP(con))) == HTTP_CONTINUE) + if (con->http.used == 0 || + !memchr(con->http.buffer, '\n', con->http.used)) + break; if (status != HTTP_OK && status != HTTP_CONTINUE) { cupsdSendError(con, HTTP_BAD_REQUEST); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; } break; @@ -1044,7 +1051,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, HTTP_BAD_REQUEST)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } else if (con->operation == HTTP_OPTIONS) { @@ -1055,7 +1065,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (con->best && con->best->type != AUTH_NONE) { if (!cupsdSendHeader(con, HTTP_UNAUTHORIZED, NULL)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } if (!strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Upgrade") && @@ -1067,7 +1080,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } httpPrintf(HTTP(con), "Connection: Upgrade\r\n"); httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n"); @@ -1075,25 +1091,40 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ httpPrintf(HTTP(con), "\r\n"); if (cupsdFlushHeader(con) < 0) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } if (!encrypt_client(con)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } #else if (!cupsdSendError(con, HTTP_NOT_IMPLEMENTED)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } #endif /* HAVE_SSL */ } if (!cupsdSendHeader(con, HTTP_OK, NULL)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } httpPrintf(HTTP(con), "Allow: GET, HEAD, OPTIONS, POST, PUT\r\n"); httpPrintf(HTTP(con), "Content-Length: 0\r\n"); httpPrintf(HTTP(con), "\r\n"); if (cupsdFlushHeader(con) < 0) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } else if (!is_path_absolute(con->uri)) { @@ -1102,7 +1133,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, HTTP_FORBIDDEN)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } else { @@ -1115,7 +1149,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } httpPrintf(HTTP(con), "Connection: Upgrade\r\n"); httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n"); @@ -1123,13 +1160,22 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ httpPrintf(HTTP(con), "\r\n"); if (cupsdFlushHeader(con) < 0) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } if (!encrypt_client(con)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } #else if (!cupsdSendError(con, HTTP_NOT_IMPLEMENTED)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } #endif /* HAVE_SSL */ } @@ -1139,7 +1185,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ "cupsdReadClient: Unauthorized request for %s...\n", con->uri); cupsdSendError(con, status); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; } if (con->http.expect && @@ -1152,7 +1199,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendHeader(con, HTTP_CONTINUE, NULL)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } else { @@ -1161,13 +1211,19 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendHeader(con, HTTP_EXPECTATION_FAILED, NULL)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } httpPrintf(HTTP(con), "Content-Length: 0\r\n"); httpPrintf(HTTP(con), "\r\n"); if (cupsdFlushHeader(con) < 0) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } } @@ -1189,7 +1245,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ else { if (!cupsdSendError(con, HTTP_NOT_FOUND)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1258,7 +1317,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (!cupsdSendCommand(con, con->command, con->options, 0)) { if (!cupsdSendError(con, HTTP_NOT_FOUND)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } else cupsdLogRequest(con, HTTP_OK); @@ -1279,7 +1341,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, HTTP_FORBIDDEN)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1293,7 +1358,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ sizeof(buf))) == NULL) { if (!cupsdSendError(con, HTTP_NOT_FOUND)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1310,7 +1378,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (!cupsdSendCommand(con, con->command, con->options, 0)) { if (!cupsdSendError(con, HTTP_NOT_FOUND)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } else cupsdLogRequest(con, HTTP_OK); @@ -1323,7 +1394,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (!check_if_modified(con, &filestats)) { if (!cupsdSendError(con, HTTP_NOT_MODIFIED)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } else { @@ -1333,7 +1407,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ snprintf(line, sizeof(line), "%s/%s", type->super, type->type); if (!write_file(con, HTTP_OK, filename, line, &filestats)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } } break; @@ -1357,7 +1434,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1368,7 +1448,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, HTTP_BAD_REQUEST)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1460,7 +1543,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ sizeof(buf))) == NULL) { if (!cupsdSendError(con, HTTP_NOT_FOUND)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1474,7 +1560,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, HTTP_UNAUTHORIZED)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } } break; @@ -1494,7 +1583,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, HTTP_FORBIDDEN)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1517,7 +1609,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1528,7 +1623,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, HTTP_BAD_REQUEST)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1548,7 +1646,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (con->file < 0) { if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } fchmod(con->file, 0640); @@ -1559,7 +1660,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ case HTTP_DELETE : case HTTP_TRACE : cupsdSendError(con, HTTP_NOT_IMPLEMENTED); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; case HTTP_HEAD : if (!strncmp(con->uri, "/printers/", 10) && @@ -1577,7 +1679,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ else { if (!cupsdSendError(con, HTTP_NOT_FOUND)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1596,13 +1701,22 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendHeader(con, HTTP_OK, "text/html")) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } if (httpPrintf(HTTP(con), "\r\n") < 0) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } if (cupsdFlushHeader(con) < 0) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } cupsdLogRequest(con, HTTP_OK); } @@ -1619,7 +1733,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, HTTP_FORBIDDEN)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } break; } @@ -1627,14 +1744,20 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ sizeof(buf))) == NULL) { if (!cupsdSendHeader(con, HTTP_NOT_FOUND, "text/html")) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } cupsdLogRequest(con, HTTP_NOT_FOUND); } else if (!check_if_modified(con, &filestats)) { if (!cupsdSendError(con, HTTP_NOT_MODIFIED)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } cupsdLogRequest(con, HTTP_NOT_MODIFIED); } @@ -1651,24 +1774,39 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ snprintf(line, sizeof(line), "%s/%s", type->super, type->type); if (!cupsdSendHeader(con, HTTP_OK, line)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } if (httpPrintf(HTTP(con), "Last-Modified: %s\r\n", httpGetDateString(filestats.st_mtime)) < 0) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } if (httpPrintf(HTTP(con), "Content-Length: %lu\r\n", (unsigned long)filestats.st_size) < 0) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } cupsdLogRequest(con, HTTP_OK); } if (httpPrintf(HTTP(con), "\r\n") < 0) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } if (cupsdFlushHeader(con) < 0) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } con->http.state = HTTP_WAITING; break; @@ -1694,35 +1832,45 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ "CHUNKED" : "LENGTH", CUPS_LLCAST con->http.data_remaining, con->file); - if ((bytes = httpRead2(HTTP(con), line, sizeof(line))) < 0) - return (cupsdCloseClient(con)); - else if (bytes > 0) + do { - con->bytes += bytes; + if ((bytes = httpRead2(HTTP(con), line, sizeof(line))) < 0) + { + cupsdCloseClient(con); + return; + } + else if (bytes > 0) + { + con->bytes += bytes; - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdReadClient: %d writing %d bytes to %d", - con->http.fd, bytes, con->file); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdReadClient: %d writing %d bytes to %d", + con->http.fd, bytes, con->file); - if (write(con->file, line, bytes) < bytes) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "cupsdReadClient: Unable to write %d bytes to %s: %s", - bytes, con->filename, strerror(errno)); + if (write(con->file, line, bytes) < bytes) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdReadClient: Unable to write %d bytes to %s: %s", + bytes, con->filename, strerror(errno)); - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdReadClient: Closing data file %d...", - con->file); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdReadClient: Closing data file %d...", + con->file); - close(con->file); - con->file = -1; - unlink(con->filename); - cupsdClearString(&con->filename); + close(con->file); + con->file = -1; + unlink(con->filename); + cupsdClearString(&con->filename); - if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) - return (cupsdCloseClient(con)); + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) + { + cupsdCloseClient(con); + return; + } + } } - } + } + while (con->http.state == HTTP_PUT_RECV && con->http.used > 0); if (con->http.state == HTTP_WAITING) { @@ -1755,7 +1903,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ cupsdClearString(&con->filename); if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } /* @@ -1769,7 +1920,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ */ if (!cupsdSendError(con, status)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } break; @@ -1782,94 +1936,112 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ "CHUNKED" : "LENGTH", CUPS_LLCAST con->http.data_remaining, con->file); - if (con->request) + do { - /* - * Grab any request data from the connection... - */ - - if ((ipp_state = ippRead(&(con->http), con->request)) == IPP_ERROR) + if (con->request) { - cupsdLogMessage(CUPSD_LOG_ERROR, - "cupsdReadClient: %d IPP Read Error!", - con->http.fd); + /* + * Grab any request data from the connection... + */ - cupsdSendError(con, HTTP_BAD_REQUEST); - return (cupsdCloseClient(con)); - } - else if (ipp_state != IPP_DATA) - { - if (con->http.state == HTTP_POST_SEND) + if ((ipp_state = ippRead(&(con->http), con->request)) == IPP_ERROR) { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdReadClient: %d IPP Read Error!", + con->http.fd); + cupsdSendError(con, HTTP_BAD_REQUEST); - return (cupsdCloseClient(con)); + cupsdCloseClient(con); + return; } + else if (ipp_state != IPP_DATA) + { + if (con->http.state == HTTP_POST_SEND) + { + cupsdSendError(con, HTTP_BAD_REQUEST); + cupsdCloseClient(con); + return; + } - break; - } - else - con->bytes += ippLength(con->request); - } + break; + } + else + con->bytes += ippLength(con->request); + } - if (con->file < 0 && con->http.state != HTTP_POST_SEND) - { - /* - * Create a file as needed for the request data... - */ + if (con->file < 0 && con->http.state != HTTP_POST_SEND) + { + /* + * Create a file as needed for the request data... + */ - cupsdSetStringf(&con->filename, "%s/%08x", RequestRoot, request_id ++); - con->file = open(con->filename, O_WRONLY | O_CREAT | O_TRUNC, 0640); + cupsdSetStringf(&con->filename, "%s/%08x", RequestRoot, request_id ++); + con->file = open(con->filename, O_WRONLY | O_CREAT | O_TRUNC, 0640); - cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadClient: %d REQUEST %s=%d", con->http.fd, - con->filename, con->file); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadClient: %d REQUEST %s=%d", con->http.fd, + con->filename, con->file); - if (con->file < 0) - { - if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) - return (cupsdCloseClient(con)); - } + if (con->file < 0) + { + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) + { + cupsdCloseClient(con); + return; + } + } - fchmod(con->file, 0640); - fchown(con->file, RunUser, Group); - fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC); - } + fchmod(con->file, 0640); + fchown(con->file, RunUser, Group); + fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC); + } - if (con->http.state != HTTP_POST_SEND) - { - if ((bytes = httpRead2(HTTP(con), line, sizeof(line))) < 0) - return (cupsdCloseClient(con)); - else if (bytes > 0) + if (con->http.state != HTTP_POST_SEND) { - con->bytes += bytes; + if ((bytes = httpRead2(HTTP(con), line, sizeof(line))) < 0) + { + cupsdCloseClient(con); + return; + } + else if (bytes > 0) + { + con->bytes += bytes; - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdReadClient: %d writing %d bytes to %d", - con->http.fd, bytes, con->file); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdReadClient: %d writing %d bytes to %d", + con->http.fd, bytes, con->file); - if (write(con->file, line, bytes) < bytes) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "cupsdReadClient: Unable to write %d bytes to %s: %s", - bytes, con->filename, strerror(errno)); + if (write(con->file, line, bytes) < bytes) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdReadClient: Unable to write %d bytes to %s: %s", + bytes, con->filename, strerror(errno)); - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdReadClient: Closing file %d...", - con->file); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdReadClient: Closing file %d...", + con->file); - close(con->file); - con->file = -1; - unlink(con->filename); - cupsdClearString(&con->filename); + close(con->file); + con->file = -1; + unlink(con->filename); + cupsdClearString(&con->filename); - if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) - return (cupsdCloseClient(con)); + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) + { + cupsdCloseClient(con); + return; + } + } + } + else if (con->http.state == HTTP_POST_RECV) + return; + else if (con->http.state != HTTP_POST_SEND) + { + cupsdCloseClient(con); + return; } } - else if (con->http.state == HTTP_POST_RECV) - return (1); /* ??? */ - else if (con->http.state != HTTP_POST_SEND) - return (cupsdCloseClient(con)); - } + } + while (con->http.state == HTTP_POST_RECV && con->http.used > 0); if (con->http.state == HTTP_POST_SEND) { @@ -1910,7 +2082,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } if (con->command) @@ -1918,7 +2093,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ if (!cupsdSendCommand(con, con->command, con->options, 0)) { if (!cupsdSendError(con, HTTP_NOT_FOUND)) - return (cupsdCloseClient(con)); + { + cupsdCloseClient(con); + return; + } } else cupsdLogRequest(con, HTTP_OK); @@ -1926,7 +2104,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } if (con->request) - return (cupsdProcessIPPRequest(con)); + { + cupsdProcessIPPRequest(con); + return; + } } break; @@ -1935,9 +2116,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ } if (!con->http.keep_alive && con->http.state == HTTP_WAITING) - return (cupsdCloseClient(con)); - else - return (1); + cupsdCloseClient(con); } @@ -1989,14 +2168,7 @@ cupsdSendCommand( fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC); - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdSendCommand: Adding fd %d to InputSet...", con->file); - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdSendCommand: Adding fd %d to OutputSet...", - con->http.fd); - - FD_SET(con->file, InputSet); - FD_SET(con->http.fd, OutputSet); + cupsdAddSelect(con->file, (cupsd_selfunc_t)cupsdWritePipe, NULL, con); con->sent_header = 0; con->file_ready = 0; @@ -2044,9 +2216,12 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */ /* * To work around bugs in some proxies, don't use Keep-Alive for some * error messages... + * + * Kerberos authentication doesn't work without Keep-Alive, so + * never disable it in that case. */ - if (code >= HTTP_BAD_REQUEST) + if (code >= HTTP_BAD_REQUEST && con->http.auth_type != AUTH_KERBEROS) con->http.keep_alive = HTTP_KEEPALIVE_OFF; /* @@ -2066,8 +2241,8 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */ return (0); #endif /* HAVE_SSL */ - if ((con->http.version >= HTTP_1_1 && !con->http.keep_alive) || - (code >= HTTP_BAD_REQUEST && code != HTTP_UPGRADE_REQUIRED)) + if (con->http.version >= HTTP_1_1 && + con->http.keep_alive == HTTP_KEEPALIVE_OFF) { if (httpPrintf(HTTP(con), "Connection: close\r\n") < 0) return (0); @@ -2091,7 +2266,8 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */ text = _cupsLangString(con->language, _("Enter your username and password or the " "root username and password to access this " - "page.")); + "page. If you are using Kerberos authentication, " + "make sure you have a valid Kerberos ticket.")); else if (code == HTTP_UPGRADE_REQUIRED) { text = urltext; @@ -2162,6 +2338,9 @@ cupsdSendHeader(cupsd_client_t *con, /* I - Client to send to */ http_status_t code, /* I - HTTP status code */ char *type) /* I - MIME type of document */ { + char auth_str[1024]; /* Authorization string */ + + /* * Send the HTTP status header... */ @@ -2209,22 +2388,77 @@ cupsdSendHeader(cupsd_client_t *con, /* I - Client to send to */ auth_type = DefaultAuthType; else auth_type = con->best->type; - - if (auth_type != AUTH_DIGEST) - { - if (httpPrintf(HTTP(con), - "WWW-Authenticate: Basic realm=\"CUPS\"\r\n") < 0) - return (0); - } - else + + auth_str[0] = '\0'; + + if (auth_type == AUTH_BASIC || auth_type == AUTH_BASICDIGEST) + strlcpy(auth_str, "Basic realm=\"CUPS\"", sizeof(auth_str)); + else if (auth_type == AUTH_DIGEST) + snprintf(auth_str, sizeof(auth_str), "Digest realm=\"CUPS\", nonce=\"%s\"", + con->http.hostname); +#ifdef HAVE_GSSAPI + else if (auth_type == AUTH_KERBEROS && !con->no_negotiate && + con->gss_output_token.length == 0) + strlcpy(auth_str, "Negotiate", sizeof(auth_str)); +#endif /* HAVE_GSSAPI */ + +#ifdef HAVE_AUTHORIZATION_H + if (con->best) { - if (httpPrintf(HTTP(con), - "WWW-Authenticate: Digest realm=\"CUPS\", nonce=\"%s\"\r\n", - con->http.hostname) < 0) - return (0); + int i; /* Looping var */ + char *auth_key; /* Auth key buffer */ + size_t auth_size; /* Size of remaining buffer */ + + + auth_key = auth_str + strlen(auth_str); + auth_size = sizeof(auth_str) - (auth_key - auth_str); + + for (i = 0; i < con->best->num_names; i ++) + { + if (!strncasecmp(con->best->names[i], "@AUTHKEY(", 9)) + { + snprintf(auth_key, auth_size, ", authkey=\"%s\"", + con->best->names[i] + 9); + /* end parenthesis is stripped in conf.c */ + break; + } + else if (!strcasecmp(con->best->names[i], "@SYSTEM") && + SystemGroupAuthKey) + { + snprintf(auth_key, auth_size, ", authkey=\"%s\"", SystemGroupAuthKey); + break; + } + } } +#endif /* HAVE_AUTHORIZATION_H */ + + if (auth_str[0] && + httpPrintf(HTTP(con), "WWW-Authenticate: %s\r\n", auth_str) < 0) + return (0); } +#ifdef HAVE_GSSAPI + /* + * WWW-Authenticate: Negotiate can be included even for + * non-401 replies... + */ + + if (con->gss_output_token.length > 0) + { + char buf[2048]; /* Output token buffer */ + OM_uint32 minor_status; /* Minor status code */ + + + httpEncode64_2(buf, sizeof(buf), + con->gss_output_token.value, + con->gss_output_token.length); + gss_release_buffer(&minor_status, &con->gss_output_token); + + if (httpPrintf(HTTP(con), "WWW-Authenticate: Negotiate %s\r\n", buf) < 0) + return (0); + } +#endif /* HAVE_GSSAPI */ + if (con->language && strcmp(con->language->language, "C")) { if (httpPrintf(HTTP(con), "Content-Language: %s\r\n", @@ -2282,7 +2516,7 @@ cupsdUpdateCGI(void) * 'cupsdWriteClient()' - Write data to a client as needed. */ -int /* O - 1 if success, 0 if fail */ +void cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */ { int bytes; /* Number of bytes written */ @@ -2301,7 +2535,28 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */ if (con->http.state != HTTP_GET_SEND && con->http.state != HTTP_POST_SEND) - return (1); + return; + + if (con->pipe_pid) + { + /* + * Make sure we select on the CGI output... + */ + + cupsdAddSelect(con->file, (cupsd_selfunc_t)cupsdWritePipe, NULL, con); + + if (!con->file_ready) + { + /* + * Try again later when there is CGI output available... + */ + + cupsdRemoveSelect(con->http.fd); + return; + } + + con->file_ready = 0; + } if (con->response) { @@ -2347,7 +2602,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */ con->sent_header = 2; if (httpPrintf(HTTP(con), "Content-Length: 0\r\n") < 0) - return (0); + return; } else if (!strncasecmp(buf, "Status:", 7)) { @@ -2362,7 +2617,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */ if (con->http.version == HTTP_1_1) { if (httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n") < 0) - return (0); + return; } } } @@ -2392,7 +2647,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */ if (cupsdFlushHeader(con) < 0) { cupsdCloseClient(con); - return (0); + return; } if (con->http.version == HTTP_1_1) @@ -2417,7 +2672,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */ httpPrintf(HTTP(con), "%s", buf); con->http.activity = time(NULL); - return (1); + return; } else if (bytes == 0) con->http.activity = time(NULL); @@ -2432,7 +2687,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */ con->http.fd, bytes); cupsdCloseClient(con); - return (0); + return; } con->bytes += bytes; @@ -2456,27 +2711,17 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */ if (httpWrite2(HTTP(con), "", 0) < 0) { cupsdCloseClient(con); - return (0); + return; } } con->http.state = HTTP_WAITING; - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdWriteClient: Removing fd %d from OutputSet...", - con->http.fd); - - FD_CLR(con->http.fd, OutputSet); + cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, NULL, con); if (con->file >= 0) { - if (FD_ISSET(con->file, InputSet)) - { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdWriteClient: Removing fd %d from InputSet...", - con->file); - FD_CLR(con->file, InputSet); - } + cupsdRemoveSelect(con->file); if (con->pipe_pid) cupsdEndProcess(con->pipe_pid, 0); @@ -2518,25 +2763,28 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */ if (!con->http.keep_alive) { cupsdCloseClient(con); - return (0); - } - } - else - { - con->file_ready = 0; - - if (con->pipe_pid && !FD_ISSET(con->file, InputSet)) - { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdWriteClient: Adding fd %d to InputSet...", - con->file); - FD_SET(con->file, InputSet); + return; } } con->http.activity = time(NULL); +} - return (1); + +/* + * 'cupsdWritePipe()' - Flag that data is available on the CGI pipe. + */ + +void +cupsdWritePipe(cupsd_client_t *con) /* I - Client connection */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdWritePipe: CGI output on fd %d...", + con->file); + + con->file_ready = 1; + + cupsdRemoveSelect(con->file); + cupsdAddSelect(con->http.fd, NULL, (cupsd_selfunc_t)cupsdWriteClient, con); } @@ -2667,7 +2915,7 @@ encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */ con->http.tls = conn; return (1); - + # elif defined(HAVE_GNUTLS) http_tls_t *conn; /* TLS session object */ int error; /* Error code */ @@ -2712,7 +2960,7 @@ encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */ } gnutls_certificate_allocate_credentials(credentials); - gnutls_certificate_set_x509_key_file(*credentials, ServerCertificate, + gnutls_certificate_set_x509_key_file(*credentials, ServerCertificate, ServerKey, GNUTLS_X509_FMT_PEM); gnutls_init(&(conn->session), GNUTLS_SERVER); @@ -2979,11 +3227,13 @@ get_file(cupsd_client_t *con, /* I - Client connection */ /* - * Need to add DocumentRoot global... + * Figure out the real filename... */ if (!strncmp(con->uri, "/ppd/", 5)) snprintf(filename, len, "%s%s", ServerRoot, con->uri); + else if (!strncmp(con->uri, "/rss/", 5) && !strchr(con->uri + 5, '/')) + snprintf(filename, len, "%s/rss/%s", CacheDir, con->uri + 5); else if (!strncmp(con->uri, "/admin/conf/", 12)) snprintf(filename, len, "%s%s", ServerRoot, con->uri + 11); else if (!strncmp(con->uri, "/admin/log/", 11)) @@ -3472,7 +3722,7 @@ make_certificate(cupsd_client_t *con) /* I - Client connection */ int pid, /* Process ID of command */ status; /* Status of command */ char command[1024], /* Command */ - *argv[11], /* Command-line arguments */ + *argv[12], /* Command-line arguments */ *envp[MAX_ENV + 1], /* Environment variables */ home[1024], /* HOME environment variable */ infofile[1024], /* Type-in information for cert */ @@ -3548,7 +3798,7 @@ make_certificate(cupsd_client_t *con) /* I - Client connection */ envp[envc++] = home; envp[envc] = NULL; - if (!cupsdStartProcess(command, argv, envp, -1, -1, -1, -1, 1, &pid)) + if (!cupsdStartProcess(command, argv, envp, -1, -1, -1, -1, -1, 1, &pid)) { unlink(seedfile); return (0); @@ -3625,7 +3875,7 @@ make_certificate(cupsd_client_t *con) /* I - Client connection */ infofd = open(infofile, O_RDONLY); - if (!cupsdStartProcess(command, argv, envp, infofd, -1, -1, -1, 1, &pid)) + if (!cupsdStartProcess(command, argv, envp, infofd, -1, -1, -1, -1, 1, &pid)) { close(infofd); unlink(infofile); @@ -3858,7 +4108,7 @@ make_certificate(cupsd_client_t *con) /* I - Client connection */ infofd = open(infofile, O_RDONLY); - if (!cupsdStartProcess(command, argv, envp, infofd, -1, -1, -1, 1, &pid)) + if (!cupsdStartProcess(command, argv, envp, infofd, -1, -1, -1, -1, 1, &pid)) { close(infofd); unlink(infofile); @@ -3928,10 +4178,11 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */ int envc; /* Number of environment variables */ char argbuf[10240], /* Argument buffer */ *argv[100], /* Argument strings */ - *envp[MAX_ENV + 17]; /* Environment variables */ + *envp[MAX_ENV + 18]; /* Environment variables */ char content_length[1024], /* CONTENT_LENGTH environment variable */ content_type[1024], /* CONTENT_TYPE environment variable */ http_cookie[32768], /* HTTP_COOKIE environment variable */ + http_referer[1024], /* HTTP_REFERER environment variable */ http_user_agent[1024], /* HTTP_USER_AGENT environment variable */ lang[1024], /* LANG environment variable */ path_info[1024], /* PATH_INFO environment variable */ @@ -4126,6 +4377,13 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */ envp[envc ++] = http_user_agent; } + if (con->http.fields[HTTP_FIELD_REFERER][0]) + { + snprintf(http_referer, sizeof(http_referer), "HTTP_REFERER=%s", + con->http.fields[HTTP_FIELD_REFERER]); + envp[envc ++] = http_referer; + } + if (con->operation == HTTP_GET) { envp[envc ++] = "REQUEST_METHOD=GET"; @@ -4190,7 +4448,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */ */ if (cupsdStartProcess(command, argv, envp, infile, fds[1], CGIPipes[1], - -1, root, &pid) < 0) + -1, -1, root, &pid) < 0) { /* * Error - can't fork! @@ -4267,15 +4525,13 @@ write_file(cupsd_client_t *con, /* I - Client connection */ else con->http._data_remaining = INT_MAX; - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "write_file: Adding fd %d to OutputSet...", con->http.fd); - - FD_SET(con->http.fd, OutputSet); + cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, + (cupsd_selfunc_t)cupsdWriteClient, con); return (1); } /* - * End of "$Id: client.c 6247 2007-02-07 20:54:37Z mike $". + * End of "$Id: client.c 6329 2007-03-12 14:48:28Z mike $". */ diff --git a/scheduler/client.h b/scheduler/client.h index d11feb836..50f095abf 100644 --- a/scheduler/client.h +++ b/scheduler/client.h @@ -1,5 +1,5 @@ /* - * "$Id: client.h 6205 2007-01-22 22:04:43Z mike $" + * "$Id: client.h 6253 2007-02-10 18:48:40Z mike $" * * Client definitions for the Common UNIX Printing System (CUPS) scheduler. * @@ -22,6 +22,10 @@ * WWW: http://www.cups.org */ +#ifdef HAVE_AUTHORIZATION_H +# include +#endif /* HAVE_AUTHORIZATION_H */ + /* * HTTP client structure... */ @@ -56,6 +60,16 @@ struct cupsd_client_s http_addr_t clientaddr; /* Client address */ char servername[256];/* Server name for connection */ int serverport; /* Server port for connection */ +#ifdef HAVE_GSSAPI + int no_negotiate; /* Don't offer WWW-Authenticate: Negotiate */ + gss_buffer_desc gss_output_token; + /* Output token for Negotiate header */ + gss_cred_id_t gss_delegated_cred; + /* Credentials from client header */ +#endif /* HAVE_GSSAPI */ +#ifdef HAVE_AUTHORIZATION_H + AuthorizationRef authref; /* Authorization ref */ +#endif /* HAVE_AUTHORIZATION_H */ }; #define HTTP(con) &((con)->http) @@ -108,7 +122,7 @@ extern void cupsdDeleteAllListeners(void); extern int cupsdFlushHeader(cupsd_client_t *con); extern void cupsdPauseListening(void); extern int cupsdProcessIPPRequest(cupsd_client_t *con); -extern int cupsdReadClient(cupsd_client_t *con); +extern void cupsdReadClient(cupsd_client_t *con); extern void cupsdResumeListening(void); extern int cupsdSendCommand(cupsd_client_t *con, char *command, char *options, int root); @@ -119,9 +133,10 @@ extern void cupsdShutdownClient(cupsd_client_t *con); extern void cupsdStartListening(void); extern void cupsdStopListening(void); extern void cupsdUpdateCGI(void); -extern int cupsdWriteClient(cupsd_client_t *con); +extern void cupsdWriteClient(cupsd_client_t *con); +extern void cupsdWritePipe(cupsd_client_t *con); /* - * End of "$Id: client.h 6205 2007-01-22 22:04:43Z mike $". + * End of "$Id: client.h 6253 2007-02-10 18:48:40Z mike $". */ diff --git a/scheduler/conf.c b/scheduler/conf.c index c8a3afa43..d033627ad 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -1,5 +1,5 @@ /* - * "$Id: conf.c 6205 2007-01-22 22:04:43Z mike $" + * "$Id: conf.c 6253 2007-02-10 18:48:40Z mike $" * * Configuration routines for the Common UNIX Printing System (CUPS). * @@ -117,13 +117,19 @@ static cupsd_var_t variables[] = { "FilterLimit", &FilterLimit, CUPSD_VARTYPE_INTEGER }, { "FilterNice", &FilterNice, CUPSD_VARTYPE_INTEGER }, { "FontPath", &FontPath, CUPSD_VARTYPE_STRING }, - { "HideImplicitMembers", &HideImplicitMembers, CUPSD_VARTYPE_BOOLEAN }, +#ifdef HAVE_GSSAPI + { "GSSServiceName", &GSSServiceName, CUPSD_VARTYPE_STRING }, +#endif /* HAVE_GSSAPI */ { "ImplicitClasses", &ImplicitClasses, CUPSD_VARTYPE_BOOLEAN }, { "ImplicitAnyClasses", &ImplicitAnyClasses, CUPSD_VARTYPE_BOOLEAN }, { "JobRetryLimit", &JobRetryLimit, CUPSD_VARTYPE_INTEGER }, { "JobRetryInterval", &JobRetryInterval, CUPSD_VARTYPE_INTEGER }, { "KeepAliveTimeout", &KeepAliveTimeout, CUPSD_VARTYPE_INTEGER }, { "KeepAlive", &KeepAlive, CUPSD_VARTYPE_BOOLEAN }, +#ifdef HAVE_LAUNCHD + { "LaunchdTimeout", &LaunchdTimeout, CUPSD_VARTYPE_INTEGER }, + { "LaunchdConf", &LaunchdConf, CUPSD_VARTYPE_STRING }, +#endif /* HAVE_LAUNCHD */ { "LimitRequestBody", &MaxRequestSize, CUPSD_VARTYPE_INTEGER }, { "ListenBackLog", &ListenBackLog, CUPSD_VARTYPE_INTEGER }, { "LogFilePerm", &LogFilePerm, CUPSD_VARTYPE_INTEGER }, @@ -161,13 +167,12 @@ static cupsd_var_t variables[] = { "ServerKey", &ServerKey, CUPSD_VARTYPE_STRING }, # endif /* HAVE_LIBSSL || HAVE_GNUTLS */ #endif /* HAVE_SSL */ -#ifdef HAVE_LAUNCHD - { "LaunchdTimeout", &LaunchdTimeout, CUPSD_VARTYPE_INTEGER }, - { "LaunchdConf", &LaunchdConf, CUPSD_VARTYPE_STRING }, -#endif /* HAVE_LAUNCHD */ { "ServerName", &ServerName, CUPSD_VARTYPE_STRING }, { "ServerRoot", &ServerRoot, CUPSD_VARTYPE_STRING }, { "StateDir", &StateDir, CUPSD_VARTYPE_STRING }, +#ifdef HAVE_AUTHORIZATION_H + { "SystemGroupAuthKey", &SystemGroupAuthKey, CUPSD_VARTYPE_STRING }, +#endif /* HAVE_AUTHORIZATION_H */ { "TempDir", &TempDir, CUPSD_VARTYPE_STRING }, { "Timeout", &Timeout, CUPSD_VARTYPE_INTEGER }, { "UseNetworkDefault", &UseNetworkDefault, CUPSD_VARTYPE_BOOLEAN } @@ -288,6 +293,9 @@ cupsdReadConfiguration(void) cupsdSetString(&RemoteRoot, "remroot"); cupsdSetString(&ServerHeader, "CUPS/1.2"); cupsdSetString(&StateDir, CUPS_STATEDIR); +#ifdef HAVE_GSSAPI + cupsdSetString(&GSSServiceName, CUPS_DEFAULT_GSSSERVICENAME); +#endif /* HAVE_GSSAPI */ if (!strcmp(CUPS_DEFAULT_PRINTCAP, "/etc/printers.conf")) PrintcapFormat = PRINTCAP_SOLARIS; @@ -434,11 +442,15 @@ cupsdReadConfiguration(void) MaxActiveJobs = 0; MaxJobsPerUser = 0; MaxJobsPerPrinter = 0; - MaxCopies = 100; + MaxCopies = CUPS_DEFAULT_MAX_COPIES; cupsdDeleteAllPolicies(); cupsdClearString(&DefaultPolicy); +#ifdef HAVE_AUTHORIZATION_H + cupsdClearString(&SystemGroupAuthKey); +#endif /* HAVE_AUTHORIZATION_H */ + MaxSubscriptions = 100; MaxSubscriptionsPerJob = 0; MaxSubscriptionsPerPrinter = 0; @@ -1705,6 +1717,16 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */ if (loc->level == AUTH_ANON) loc->level = AUTH_USER; } +#ifdef HAVE_GSSAPI + else if (!strcasecmp(value, "kerberos") || + !strcasecmp(value, "gssapi")) + { + loc->type = AUTH_KERBEROS; + + if (loc->level == AUTH_ANON) + loc->level = AUTH_USER; + } +#endif /* HAVE_GSSAPI */ else { cupsdLogMessage(CUPSD_LOG_WARN, @@ -1813,6 +1835,20 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */ while (isspace(*value & 255)) value ++; +#ifdef HAVE_AUTHORIZATION_H + if (!strncmp(value, "@AUTHKEY(", 9)) + { + /* + * Grab "@AUTHKEY(name)" value... + */ + + for (valptr = value + 9; *valptr != ')' && *valptr; valptr ++); + + if (*valptr) + *valptr++ = '\0'; + } + else +#endif /* HAVE_AUTHORIZATION_H */ if (*value == '\"' || *value == '\'') { /* @@ -2700,6 +2736,10 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ DefaultAuthType = AUTH_DIGEST; else if (!strcasecmp(value, "basicdigest")) DefaultAuthType = AUTH_BASICDIGEST; +#ifdef HAVE_GSSAPI + else if (!strcasecmp(value, "kerberos")) + DefaultAuthType = AUTH_KERBEROS; +#endif /* HAVE_GSSAPI */ else { cupsdLogMessage(CUPSD_LOG_WARN, @@ -2730,6 +2770,19 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ } } #endif /* HAVE_SSL */ +#ifdef HAVE_GSSAPI + else if (!strcasecmp(line, "Krb5Keytab")) + { + cupsdSetStringf(&Krb5Keytab, "KRB5_KTNAME=%s", value); + putenv(Krb5Keytab); + +# ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY + gsskrb5_register_acceptor_identity(value); +# else + cupsdSetEnv("KRB5_KTNAME", value); +# endif /* HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY */ + } +#endif /* HAVE_GSSAPI */ else if (!strcasecmp(line, "User")) { /* @@ -3289,5 +3342,5 @@ read_policy(cups_file_t *fp, /* I - Configuration file */ /* - * End of "$Id: conf.c 6205 2007-01-22 22:04:43Z mike $". + * End of "$Id: conf.c 6253 2007-02-10 18:48:40Z mike $". */ diff --git a/scheduler/conf.h b/scheduler/conf.h index 6320f9d19..cfb71fc4e 100644 --- a/scheduler/conf.h +++ b/scheduler/conf.h @@ -1,5 +1,5 @@ /* - * "$Id: conf.h 5696 2006-06-26 18:34:20Z mike $" + * "$Id: conf.h 6291 2007-02-19 21:54:27Z mike $" * * Configuration file definitions for the Common UNIX Printing System (CUPS) * scheduler. @@ -30,19 +30,19 @@ typedef enum { - CUPSD_LOG_ATTR = -3, /* Used internally for attributes */ - CUPSD_LOG_STATE, /* Used internally for state-reasons */ - CUPSD_LOG_PAGE, /* Used internally for page logging */ + CUPSD_LOG_ATTR = -3, /* Used internally for attributes */ + CUPSD_LOG_STATE, /* Used internally for state-reasons */ + CUPSD_LOG_PAGE, /* Used internally for page logging */ CUPSD_LOG_NONE, - CUPSD_LOG_EMERG, /* Emergency issues */ - CUPSD_LOG_ALERT, /* Something bad happened that needs attention */ - CUPSD_LOG_CRIT, /* Critical error but server continues */ - CUPSD_LOG_ERROR, /* Error condition */ - CUPSD_LOG_WARN, /* Warning */ - CUPSD_LOG_NOTICE, /* Normal condition that needs logging */ - CUPSD_LOG_INFO, /* General information */ - CUPSD_LOG_DEBUG, /* General debugging */ - CUPSD_LOG_DEBUG2 /* Detailed debugging */ + CUPSD_LOG_EMERG, /* Emergency issues */ + CUPSD_LOG_ALERT, /* Something bad happened that needs attention */ + CUPSD_LOG_CRIT, /* Critical error but server continues */ + CUPSD_LOG_ERROR, /* Error condition */ + CUPSD_LOG_WARN, /* Warning */ + CUPSD_LOG_NOTICE, /* Normal condition that needs logging */ + CUPSD_LOG_INFO, /* General information */ + CUPSD_LOG_DEBUG, /* General debugging */ + CUPSD_LOG_DEBUG2 /* Detailed debugging */ } cupsd_loglevel_t; @@ -50,8 +50,8 @@ typedef enum * Printcap formats... */ -#define PRINTCAP_BSD 0 /* Berkeley LPD format */ -#define PRINTCAP_SOLARIS 1 /* Solaris lpsched format */ +#define PRINTCAP_BSD 0 /* Berkeley LPD format */ +#define PRINTCAP_SOLARIS 1 /* Solaris lpsched format */ /* @@ -111,6 +111,12 @@ VAR char *AccessLog VALUE(NULL), /* Remote root user */ *Classification VALUE(NULL); /* Classification of system */ +#ifdef HAVE_GSSAPI +VAR char *GSSServiceName VALUE(NULL); + /* GSS service name */ +VAR char *Krb5Keytab VALUE(NULL); + /* Kerberos Keytab */ +#endif /* HAVE_GSSAPI */ VAR uid_t User VALUE(1); /* User ID for server */ VAR gid_t Group VALUE(0); @@ -127,7 +133,7 @@ VAR int ClassifyOverride VALUE(0), /* Maximum number of clients */ MaxClientsPerHost VALUE(0), /* Maximum number of clients per host */ - MaxCopies VALUE(100), + MaxCopies VALUE(CUPS_DEFAULT_MAX_COPIES), /* Maximum number of copies per job */ MaxLogSize VALUE(1024 * 1024), /* Maximum size of log files */ @@ -195,21 +201,32 @@ VAR char *LaunchdConf VALUE(NULL); /* launchd(8) configuration file */ #endif /* HAVE_LAUNCHD */ +#ifdef HAVE_AUTHORIZATION_H +VAR char *SystemGroupAuthKey VALUE(NULL); + /* System group auth key */ +#endif /* HAVE_AUTHORIZATION_H */ + + /* * Prototypes... */ extern char *cupsdGetDateTime(time_t t); extern int cupsdReadConfiguration(void); -extern int cupsdLogRequest(cupsd_client_t *con, http_status_t code); +#ifdef HAVE_GSSAPI +extern int cupsdLogGSSMessage(int level, int major_status, + int minor_status, + const char *message, ...); +#endif /* HAVE_GSSAPI */ extern int cupsdLogMessage(int level, const char *message, ...) #ifdef __GNUC__ __attribute__ ((__format__ (__printf__, 2, 3))) #endif /* __GNUC__ */ ; extern int cupsdLogPage(cupsd_job_t *job, const char *page); +extern int cupsdLogRequest(cupsd_client_t *con, http_status_t code); /* - * End of "$Id: conf.h 5696 2006-06-26 18:34:20Z mike $". + * End of "$Id: conf.h 6291 2007-02-19 21:54:27Z mike $". */ diff --git a/scheduler/cups-driverd.c b/scheduler/cups-driverd.c index a51e4a934..39892bc71 100644 --- a/scheduler/cups-driverd.c +++ b/scheduler/cups-driverd.c @@ -1,5 +1,5 @@ /* - * "$Id: cups-driverd.c 6214 2007-01-23 17:01:48Z mike $" + * "$Id: cups-driverd.c 6211 2007-01-23 15:44:34Z mike $" * * PPD/driver support for the Common UNIX Printing System (CUPS). * @@ -1122,5 +1122,5 @@ load_drivers(void) /* - * End of "$Id: cups-driverd.c 6214 2007-01-23 17:01:48Z mike $". + * End of "$Id: cups-driverd.c 6211 2007-01-23 15:44:34Z mike $". */ diff --git a/scheduler/cups-lpd.c b/scheduler/cups-lpd.c index e771c9eff..a2b0f9003 100644 --- a/scheduler/cups-lpd.c +++ b/scheduler/cups-lpd.c @@ -1,5 +1,5 @@ /* - * "$Id: cups-lpd.c 6022 2006-10-10 19:47:03Z mike $" + * "$Id: cups-lpd.c 6327 2007-03-12 14:32:10Z mike $" * * Line Printer Daemon interface for the Common UNIX Printing System (CUPS). * @@ -96,7 +96,8 @@ static int get_printer(http_t *http, const char *name, char *dest, int destsize, cups_option_t **options, int *accepting, int *shared, ipp_pstate_t *state); static int print_file(http_t *http, int id, const char *filename, - const char *docname, const char *user, int last); + const char *docname, const char *user, + const char *format, int last); static int recv_print_job(const char *name, int num_defaults, cups_option_t *defaults); static int remove_jobs(const char *name, const char *agent, @@ -824,6 +825,7 @@ print_file(http_t *http, /* I - HTTP connection */ const char *filename, /* I - File to print */ const char *docname, /* I - document-name */ const char *user, /* I - requesting-user-name */ + const char *format, /* I - document-format */ int last) /* I - 1 = last file in job */ { ipp_t *request; /* IPP request */ @@ -846,6 +848,10 @@ print_file(http_t *http, /* I - HTTP connection */ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", NULL, docname); + if (format) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, + "document-format", NULL, format); + if (last) ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); @@ -1278,6 +1284,8 @@ recv_print_job( docnumber ++; if (print_file(http, id, temp[i], docname, user, + cupsGetOption("document-format", num_options, + options), docnumber == doccount)) status = 1; else @@ -1717,5 +1725,5 @@ smart_gets(char *s, /* I - Pointer to line buffer */ /* - * End of "$Id: cups-lpd.c 6022 2006-10-10 19:47:03Z mike $". + * End of "$Id: cups-lpd.c 6327 2007-03-12 14:32:10Z mike $". */ diff --git a/scheduler/cups-polld.c b/scheduler/cups-polld.c index be6bbb5e6..2d21f1a0c 100644 --- a/scheduler/cups-polld.c +++ b/scheduler/cups-polld.c @@ -1,5 +1,5 @@ /* - * "$Id: cups-polld.c 5871 2006-08-23 20:55:33Z mike $" + * "$Id: cups-polld.c 5870 2006-08-23 20:30:51Z mike $" * * Polling daemon for the Common UNIX Printing System (CUPS). * @@ -478,5 +478,5 @@ sighup_handler(int sig) /* I - Signal number */ /* - * End of "$Id: cups-polld.c 5871 2006-08-23 20:55:33Z mike $". + * End of "$Id: cups-polld.c 5870 2006-08-23 20:30:51Z mike $". */ diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h index dbdca8bef..81b5b3588 100644 --- a/scheduler/cupsd.h +++ b/scheduler/cupsd.h @@ -1,5 +1,5 @@ /* - * "$Id: cupsd.h 5305 2006-03-18 03:05:12Z mike $" + * "$Id: cupsd.h 6170 2007-01-02 17:26:41Z mike $" * * Main header file for the Common UNIX Printing System (CUPS) scheduler. * @@ -150,14 +150,18 @@ extern const char *cups_hstrerror(int); #define RELOAD_CUPSD 2 /* Reload only cupsd.conf */ +/* + * Select callback function type... + */ + +typedef void (*cupsd_selfunc_t)(void *data); + + /* * Globals... */ -VAR int MaxFDs, /* Maximum number of files */ - SetSize; /* The size of the input/output sets */ -VAR fd_set *InputSet, /* Input files for select() */ - *OutputSet; /* Output files for select() */ +VAR int MaxFDs; /* Maximum number of files */ VAR time_t ReloadTime VALUE(0); /* Time of reload request... */ @@ -200,9 +204,18 @@ extern int cupsdEndProcess(int pid, int force); extern const char *cupsdFinishProcess(int pid, char *name, int namelen); extern int cupsdStartProcess(const char *command, char *argv[], char *envp[], int infd, int outfd, - int errfd, int backfd, int root, int *pid); + int errfd, int backfd, int sidefd, + int root, int *pid); + +extern int cupsdAddSelect(int fd, cupsd_selfunc_t read_cb, + cupsd_selfunc_t write_cb, void *data); +extern int cupsdDoSelect(long timeout); +extern int cupsdIsSelecting(int fd); +extern void cupsdRemoveSelect(int fd); +extern void cupsdStartSelect(void); +extern void cupsdStopSelect(void); /* - * End of "$Id: cupsd.h 5305 2006-03-18 03:05:12Z mike $". + * End of "$Id: cupsd.h 6170 2007-01-02 17:26:41Z mike $". */ diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c index bc5b3a466..73abd7bfc 100644 --- a/scheduler/dirsvc.c +++ b/scheduler/dirsvc.c @@ -1,5 +1,5 @@ /* - * "$Id: dirsvc.c 6205 2007-01-22 22:04:43Z mike $" + * "$Id: dirsvc.c 6309 2007-02-24 03:11:56Z mike $" * * Directory services routines for the Common UNIX Printing System (CUPS). * @@ -23,10 +23,13 @@ * * Contents: * + * cupsdDeregisterPrinter() - Stop sending broadcast information for a + * local printer and remove any pending + * references to remote printers. * cupsdLoadRemoteCache() - Load the remote printer cache. + * cupsdRegisterPrinter() - Start sending broadcast information for a + * printer update the broadcast contents. * cupsdSaveRemoteCache() - Save the remote printer cache. - * cupsdSendBrowseDelete() - Send a "browse delete" message for a - * printer. * cupsdSendBrowseList() - Send new browsing information as necessary. * cupsdStartBrowsing() - Start sending and receiving broadcast * information. @@ -36,9 +39,18 @@ * cupsdStopPolling() - Stop polling servers as needed. * cupsdUpdateCUPSBrowse() - Update the browse lists using the CUPS * protocol. + * cupsdUpdateDNSSDBrowse() - Handle DNS-SD queries. * cupsdUpdateLDAPBrowse() - Scan for new printers via LDAP... * cupsdUpdatePolling() - Read status messages from the poll daemons. * cupsdUpdateSLPBrowse() - Get browsing information via SLP. + * dnssdBuildTxtRecord() - Build a TXT record from printer info. + * dnssdDeregisterPrinter() - Stop sending broadcast information for a + * printer. + * dnssdPackTxtRecord() - Pack an array of key/value pairs into the + * TXT record format. + * dnssdRegisterCallback() - DNSServiceRegister callback. + * dnssdRegisterPrinter() - Start sending broadcast information for a + * printer or update the broadcast contents. * dequote() - Remote quotes from a string. * process_browse_data() - Process new browse data. * process_implicit_classes() - Create/update implicit classes as needed. @@ -60,6 +72,18 @@ #include "cupsd.h" #include +#ifdef HAVE_DNSSD +# include +# include +# include +# ifdef HAVE_COREFOUNDATION +# include +# endif /* HAVE_COREFOUNDATION */ +# ifdef HAVE_SYSTEMCONFIGURATION +# include +# endif /* HAVE_SYSTEMCONFIGURATION */ +#endif /* HAVE_DNSSD */ + /* * Local functions... @@ -135,6 +159,72 @@ static SLPBoolean slp_url_callback(SLPHandle hslp, const char *srvurl, SLPError errcode, void *cookie); #endif /* HAVE_LIBSLP */ +#ifdef HAVE_DNSSD +/* + * For IPP register using a subtype of 'cups' so that shared printer browsing + * only finds other CUPS servers (not all IPP based printers). + */ +static char dnssdIPPRegType[] = "_ipp._tcp,_cups"; +static char dnssdIPPFaxRegType[] = "_fax-ipp._tcp"; + +static char *dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p); +static void dnssdDeregisterPrinter(cupsd_printer_t *p); +static char *dnssdPackTxtRecord(int *txt_len, char *keyvalue[][2], + int count); +static void dnssdRegisterCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + DNSServiceErrorType errorCode, + const char *name, const char *regtype, + const char *domain, void *context); +static void dnssdRegisterPrinter(cupsd_printer_t *p); +#endif /* HAVE_DNSSD */ + + +/* + * 'cupsdDeregisterPrinter()' - Stop sending broadcast information for a + * local printer and remove any pending + * references to remote printers. + */ + +void +cupsdDeregisterPrinter( + cupsd_printer_t *p, /* I - Printer to register */ + int removeit) /* I - Printer being permanently removed */ +{ + /* + * Only deregister if browsing is enabled and it's a local printers... + */ + + if (!Browsing || !p->shared || + (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))) + return; + + /* + * Announce the deletion... + */ + + if ((BrowseLocalProtocols & BROWSE_CUPS)) + { + cups_ptype_t savedtype = p->type; /* Saved printer type */ + + p->type |= CUPS_PRINTER_DELETE; + + send_cups_browse(p); + + p->type = savedtype; + } + +#ifdef HAVE_LIBSLP + if (BrowseLocalProtocols & BROWSE_SLP) + slp_dereg_printer(p); +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_DNSSD + if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD)) + dnssdDeregisterPrinter(p); +#endif /* HAVE_DNSSD */ +} + /* * 'cupsdLoadRemoteCache()' - Load the remote printer cache. @@ -524,6 +614,30 @@ cupsdLoadRemoteCache(void) } +/* + * 'cupsdRegisterPrinter()' - Start sending broadcast information for a + * printer or update the broadcast contents. + */ + +void +cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */ +{ + if (!Browsing || !BrowseLocalProtocols || !BrowseInterval || !NumBrowsers || + (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))) + return; + +#ifdef HAVE_LIBSLP +/* if (BrowseLocalProtocols & BROWSE_SLP) + slpRegisterPrinter(p); */ +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_DNSSD + if (BrowseLocalProtocols & BROWSE_DNSSD) + dnssdRegisterPrinter(p); +#endif /* HAVE_DNSSD */ +} + + /* * 'cupsdRestartPolling()' - Restart polling servers as needed. */ @@ -570,7 +684,7 @@ cupsdSaveRemoteCache(void) return; } else - cupsdLogMessage(CUPSD_LOG_INFO, "Saving remote.cache..."); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Saving remote.cache..."); /* * Restrict access to the file... @@ -670,41 +784,6 @@ cupsdSaveRemoteCache(void) } -/* - * 'cupsdSendBrowseDelete()' - Send a "browse delete" message for a printer. - */ - -void -cupsdSendBrowseDelete( - cupsd_printer_t *p) /* I - Printer to delete */ -{ - /* - * Only announce if browsing is enabled and this is a local queue... - */ - - if (!Browsing || !p->shared || - (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))) - return; - - /* - * First mark the printer for deletion... - */ - - p->type |= CUPS_PRINTER_DELETE; - - /* - * Announce the deletion... - */ - - if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0) - send_cups_browse(p); -#ifdef HAVE_LIBSLP - if ((BrowseLocalProtocols & BROWSE_SLP) && BrowseSLPHandle) - slp_dereg_printer(p); -#endif /* HAVE_LIBSLP */ -} - - /* * 'cupsdSendBrowseList()' - Send new browsing information as necessary. */ @@ -853,6 +932,7 @@ cupsdStartBrowsing(void) { int val; /* Socket option value */ struct sockaddr_in addr; /* Broadcast address */ + cupsd_printer_t *p; /* Current printer */ BrowseNext = NULL; @@ -945,11 +1025,8 @@ cupsdStartBrowsing(void) * We only listen if we want remote printers... */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStartBrowsing: Adding fd %d to InputSet...", - BrowseSocket); - - FD_SET(BrowseSocket, InputSet); + cupsdAddSelect(BrowseSocket, (cupsd_selfunc_t)cupsdUpdateCUPSBrowse, + NULL, NULL); } } else @@ -1048,6 +1125,16 @@ cupsdStartBrowsing(void) BrowseLDAPRefresh = 0; } #endif /* HAVE_OPENLDAP */ + + /* + * Register the individual printers + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))) + cupsdRegisterPrinter(p); } @@ -1129,7 +1216,7 @@ cupsdStartPolling(void) argv[1] = pollp->hostname; - if (cupsdStartProcess(polld, argv, envp, -1, -1, statusfds[1], -1, + if (cupsdStartProcess(polld, argv, envp, -1, -1, statusfds[1], -1, -1, 0, &(pollp->pid)) < 0) { cupsdLogMessage(CUPSD_LOG_ERROR, @@ -1150,10 +1237,7 @@ cupsdStartPolling(void) * Finally, add the pipe to the input selection set... */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStartPolling: Adding fd %d to InputSet...", PollPipe); - - FD_SET(PollPipe, InputSet); + cupsdAddSelect(PollPipe, (cupsd_selfunc_t)cupsdUpdatePolling, NULL, NULL); } @@ -1164,9 +1248,26 @@ cupsdStartPolling(void) void cupsdStopBrowsing(void) { + cupsd_printer_t *p; /* Current printer */ + + if (!Browsing || !(BrowseLocalProtocols | BrowseRemoteProtocols)) return; + /* + * De-register the individual printers + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))) + cupsdDeregisterPrinter(p, 1); + + /* + * Shut down browsing sockets... + */ + if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_CUPS) && BrowseSocket >= 0) { @@ -1180,11 +1281,7 @@ cupsdStopBrowsing(void) close(BrowseSocket); #endif /* WIN32 */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStopBrowsing: Removing fd %d from InputSet...", - BrowseSocket); - - FD_CLR(BrowseSocket, InputSet); + cupsdRemoveSelect(BrowseSocket); BrowseSocket = -1; } @@ -1228,9 +1325,7 @@ cupsdStopPolling(void) cupsdStatBufDelete(PollStatusBuffer); close(PollPipe); - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStopPolling: removing fd %d from InputSet.", PollPipe); - FD_CLR(PollPipe, InputSet); + cupsdRemoveSelect(PollPipe); PollPipe = -1; PollStatusBuffer = NULL; @@ -1515,6 +1610,34 @@ cupsdUpdateCUPSBrowse(void) } +#ifdef HAVE_DNSSD +/* + * 'cupsdUpdateDNSSDBrowse()' - Handle DNS-SD queries. + */ + +void +cupsdUpdateDNSSDBrowse( + cupsd_printer_t *p) /* I - Printer being queried */ +{ + DNSServiceErrorType sdErr; /* Service discovery error */ + + + if ((sdErr = DNSServiceProcessResult(p->dnssd_ipp_ref)) + != kDNSServiceErr_NoError) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "DNS Service Discovery registration error %d for \"%s\"!", + sdErr, p->name); + cupsdRemoveSelect(p->dnssd_ipp_fd); + DNSServiceRefDeallocate(p->dnssd_ipp_ref); + + p->dnssd_ipp_ref = NULL; + p->dnssd_ipp_fd = -1; + } +} +#endif /* HAVE_DNSSD */ + + #ifdef HAVE_OPENLDAP /* * 'cupsdUpdateLDAPBrowse()' - Scan for new printers via LDAP... @@ -2315,6 +2438,465 @@ process_browse_data( } +#ifdef HAVE_DNSSD +/* + * 'dnssdBuildTxtRecord()' - Build a TXT record from printer info. + */ + +static char * /* O - TXT record */ +dnssdBuildTxtRecord( + int *txt_len, /* O - TXT record length */ + cupsd_printer_t *p) /* I - Printer information */ +{ + int i; /* Looping var */ + char type_str[32], /* Type to string buffer */ + state_str[32], /* State to string buffer */ + rp_str[1024], /* Queue name string buffer */ + *keyvalue[32][2]; /* Table of key/value pairs */ + + + /* + * Load up the key value pairs... + */ + + i = 0; + + keyvalue[i ][0] = "txtvers"; + keyvalue[i++][1] = "1"; + + keyvalue[i ][0] = "qtotal"; + keyvalue[i++][1] = "1"; + + keyvalue[i ][0] = "rp"; + keyvalue[i++][1] = rp_str; + snprintf(rp_str, sizeof(rp_str), "%s/%s", + (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers", p->name); + + keyvalue[i ][0] = "ty"; + keyvalue[i++][1] = p->make_model; + + if (p->location && *p->location != '\0') + { + keyvalue[i ][0] = "note"; + keyvalue[i++][1] = p->location; + } + + keyvalue[i ][0] = "product"; + keyvalue[i++][1] = p->product ? p->product : "Unknown"; + + snprintf(type_str, sizeof(type_str), "0x%X", p->type | CUPS_PRINTER_REMOTE); + snprintf(state_str, sizeof(state_str), "%d", p->state); + + keyvalue[i ][0] = "printer-state"; + keyvalue[i++][1] = state_str; + + keyvalue[i ][0] = "printer-type"; + keyvalue[i++][1] = type_str; + + keyvalue[i ][0] = "Transparent"; + keyvalue[i++][1] = "T"; + + keyvalue[i ][0] = "Binary"; + keyvalue[i++][1] = "T"; + + if ((p->type & CUPS_PRINTER_FAX)) + { + keyvalue[i ][0] = "Fax"; + keyvalue[i++][1] = "T"; + } + + if ((p->type & CUPS_PRINTER_COLOR)) + { + keyvalue[i ][0] = "Color"; + keyvalue[i++][1] = "T"; + } + + if ((p->type & CUPS_PRINTER_DUPLEX)) + { + keyvalue[i ][0] = "Duplex"; + keyvalue[i++][1] = "T"; + } + + if ((p->type & CUPS_PRINTER_STAPLE)) + { + keyvalue[i ][0] = "Staple"; + keyvalue[i++][1] = "T"; + } + + if ((p->type & CUPS_PRINTER_COPIES)) + { + keyvalue[i ][0] = "Copies"; + keyvalue[i++][1] = "T"; + } + + if ((p->type & CUPS_PRINTER_COLLATE)) + { + keyvalue[i ][0] = "Collate"; + keyvalue[i++][1] = "T"; + } + + if ((p->type & CUPS_PRINTER_PUNCH)) + { + keyvalue[i ][0] = "Punch"; + keyvalue[i++][1] = "T"; + } + + if ((p->type & CUPS_PRINTER_BIND)) + { + keyvalue[i ][0] = "Bind"; + keyvalue[i++][1] = "T"; + } + + if ((p->type & CUPS_PRINTER_SORT)) + { + keyvalue[i ][0] = "Sort"; + keyvalue[i++][1] = "T"; + } + + keyvalue[i ][0] = "pdl"; + keyvalue[i++][1] = p->pdl ? p->pdl : "application/postscript"; + + /* + * Then pack them into a proper txt record... + */ + + return (dnssdPackTxtRecord(txt_len, keyvalue, i)); +} + + +/* + * 'dnssdDeregisterPrinter()' - Stop sending broadcast information for a + * printer. + */ + +static void +dnssdDeregisterPrinter( + cupsd_printer_t *p) /* I - Printer */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdDeregisterPrinter(%s)", p->name); + + /* + * Closing the socket deregisters the service + */ + + if (p->dnssd_ipp_ref) + { + cupsdRemoveSelect(p->dnssd_ipp_fd); + DNSServiceRefDeallocate(p->dnssd_ipp_ref); + p->dnssd_ipp_ref = NULL; + p->dnssd_ipp_fd = -1; + } + + cupsdClearString(&p->reg_name); + + if (p->txt_record) + { + /* + * p->txt_record is malloc'd, not _cupsStrAlloc'd... + */ + + free(p->txt_record); + p->txt_record = NULL; + } +} + + +/* + * 'dnssdPackTxtRecord()' - Pack an array of key/value pairs into the + * TXT record format. + */ + +static char * /* O - TXT record */ +dnssdPackTxtRecord(int *txt_len, /* O - TXT record length */ + char *keyvalue[][2], /* I - Table of key value pairs */ + int count) /* I - Items in table */ +{ + int i; /* Looping var */ + int length; /* Length of TXT record */ + int length2; /* Length of value */ + char *txtRecord; /* TXT record buffer */ + char *cursor; /* Looping pointer */ + + + /* + * Calculate the buffer size + */ + + for (length = i = 0; i < count; i++) + length += 1 + strlen(keyvalue[i][0]) + + (keyvalue[i][1] ? 1 + strlen(keyvalue[i][1]) : 0); + + /* + * Allocate and fill it + */ + + txtRecord = malloc(length); + if (txtRecord) + { + *txt_len = length; + + for (cursor = txtRecord, i = 0; i < count; i++) + { + /* + * Drop in the p-string style length byte followed by the data + */ + + length = strlen(keyvalue[i][0]); + length2 = keyvalue[i][1] ? 1 + strlen(keyvalue[i][1]) : 0; + + *cursor++ = (unsigned char)(length + length2); + + memcpy(cursor, keyvalue[i][0], length); + cursor += length; + + if (length2) + { + length2 --; + *cursor++ = '='; + memcpy(cursor, keyvalue[i][1], length2); + cursor += length2; + } + } + } + + return (txtRecord); +} + + +/* + * 'dnssdRegisterCallback()' - DNSServiceRegister callback. + */ + +static void +dnssdRegisterCallback( + DNSServiceRef sdRef, /* I - DNS Service reference */ + DNSServiceFlags flags, /* I - Reserved for future use */ + DNSServiceErrorType errorCode, /* I - Error code */ + const char *name, /* I - Service name */ + const char *regtype, /* I - Service type */ + const char *domain, /* I - Domain. ".local" for now */ + void *context) /* I - User-defined context */ +{ + (void)context; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "dnssdRegisterCallback(%s, %s)", name, regtype); + + if (errorCode) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "DNSServiceRegister failed with error %d", (int)errorCode); + return; + } +} + + +/* + * 'dnssdRegisterPrinter()' - Start sending broadcast information for a printer + * or update the broadcast contents. + */ + +static void +dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */ +{ + DNSServiceErrorType se; /* dnssd errors */ + cupsd_listener_t *lis; /* Current listening socket */ + char *txt_record, /* TXT record buffer */ + *name; /* Service name */ + int txt_len, /* TXT record length */ + port; /* IPP port number */ + char str_buffer[1024]; + /* C-string buffer */ + const char *computerName; /* Computer name c-string ptr */ + const char *regtype; /* Registration type */ +#ifdef HAVE_COREFOUNDATION_H + CFStringRef computerNameRef;/* Computer name CFString */ + CFStringEncoding nameEncoding; /* Computer name encoding */ + CFMutableStringRef shortNameRef; /* Mutable name string */ + CFIndex nameLength; /* Name string length */ +#else + int nameLength; /* Name string length */ +#endif /* HAVE_COREFOUNDATION_H */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name, + !p->dnssd_ipp_ref ? "new" : "update"); + + /* + * If per-printer sharing was just disabled make sure we're not + * registered before returning. + */ + + if (!p->shared) + { + dnssdDeregisterPrinter(p); + return; + } + + /* + * Get the computer name as a c-string... + */ + +#ifdef HAVE_COREFOUNDATION_H + computerName = NULL; + if ((computerNameRef = SCDynamicStoreCopyComputerName(NULL, &nameEncoding))) + if ((computerName = CFStringGetCStringPtr(computerNameRef, + kCFStringEncodingUTF8)) == NULL) + if (CFStringGetCString(computerNameRef, str_buffer, sizeof(str_buffer), + kCFStringEncodingUTF8)) + computerName = str_buffer; +#else + computerName = ServerName; +#endif /* HAVE_COREFOUNDATION_H */ + + /* + * The registered name takes the form of " @ "... + */ + + name = NULL; + if (computerName) + cupsdSetStringf(&name, "%s @ %s", + (p->info && strlen(p->info)) ? p->info : p->name, + computerName); + else + cupsdSetString(&name, (p->info && strlen(p->info)) ? p->info : p->name); + +#ifdef HAVE_COREFOUNDATION_H + if (computerNameRef) + CFRelease(computerNameRef); +#endif /* HAVE_COREFOUNDATION_H */ + + /* + * If an existing printer was renamed, unregister it and start over... + */ + + if (p->reg_name && strcmp(p->reg_name, name)) + dnssdDeregisterPrinter(p); + + txt_len = 0; /* anti-compiler-warning-code */ + txt_record = dnssdBuildTxtRecord(&txt_len, p); + + if (!p->dnssd_ipp_ref) + { + /* + * Initial registration... + */ + + cupsdSetString(&p->reg_name, name); + + port = ippPort(); + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + { + if (lis->address.addr.sa_family == AF_INET) + { + port = ntohs(lis->address.ipv4.sin_port); + break; + } + else if (lis->address.addr.sa_family == AF_INET6) + { + port = ntohs(lis->address.ipv6.sin6_port); + break; + } + } + + /* + * Use the _fax subtype for fax queues... + */ + + regtype = (p->type & CUPS_PRINTER_FAX) ? dnssdIPPFaxRegType : + dnssdIPPRegType; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) type is \"%s\"", + p->name, regtype); + + se = DNSServiceRegister(&p->dnssd_ipp_ref, 0, 0, name, regtype, + NULL, NULL, htons(port), txt_len, txt_record, + dnssdRegisterCallback, p); + + /* + * In case the name is too long, try shortening the string one character + * at a time... + */ + + if (se == kDNSServiceErr_BadParam) + { +#ifdef HAVE_COREFOUNDATION_H + if ((shortNameRef = CFStringCreateMutable(NULL, 0)) != NULL) + { + CFStringAppendCString(shortNameRef, name, kCFStringEncodingUTF8); + nameLength = CFStringGetLength(shortNameRef); + + while (se == kDNSServiceErr_BadParam && nameLength > 1) + { + CFStringDelete(shortNameRef, CFRangeMake(--nameLength, 1)); + if (CFStringGetCString(shortNameRef, str_buffer, sizeof(str_buffer), + kCFStringEncodingUTF8)) + { + se = DNSServiceRegister(&p->dnssd_ipp_ref, 0, 0, str_buffer, + regtype, NULL, NULL, htons(port), + txt_len, txt_record, + dnssdRegisterCallback, p); + } + } + + CFRelease(shortNameRef); + } +#else + nameLength = strlen(name); + while (se == kDNSServiceErr_BadParam && nameLength > 1) + { + name[--nameLength] = '\0'; + se = DNSServiceRegister(&p->dnssd_ipp_ref, 0, 0, str_buffer, regtype, + NULL, NULL, htons(port), txt_len, txt_record, + dnssdRegisterCallback, p); + } +#endif /* HAVE_COREFOUNDATION_H */ + } + + if (se == kDNSServiceErr_NoError) + { + p->dnssd_ipp_fd = DNSServiceRefSockFD(p->dnssd_ipp_ref); + p->txt_record = txt_record; + p->txt_len = txt_len; + txt_record = NULL; + + cupsdAddSelect(p->dnssd_ipp_fd, (cupsd_selfunc_t)cupsdUpdateDNSSDBrowse, + NULL, (void *)p); + } + else + cupsdLogMessage(CUPSD_LOG_WARN, + "DNS-SD registration of \"%s\" failed with %d", + p->name, se); + } + else if (txt_len != p->txt_len || memcmp(txt_record, p->txt_record, txt_len)) + { + /* + * Update the existing registration... + */ + + /* A TTL of 0 means use record's original value (Radar 3176248) */ + se = DNSServiceUpdateRecord(p->dnssd_ipp_ref, NULL, 0, + txt_len, txt_record, 0); + + if (p->txt_record) + free(p->txt_record); + + p->txt_record = txt_record; + p->txt_len = txt_len; + txt_record = NULL; + } + + if (txt_record) + free(txt_record); + + cupsdClearString(&name); +} +#endif /* HAVE_DNSSD */ + + /* * 'process_implicit_classes()' - Create/update implicit classes as needed. */ @@ -3192,5 +3774,5 @@ slp_url_callback( /* - * End of "$Id: dirsvc.c 6205 2007-01-22 22:04:43Z mike $". + * End of "$Id: dirsvc.c 6309 2007-02-24 03:11:56Z mike $". */ diff --git a/scheduler/dirsvc.h b/scheduler/dirsvc.h index 2e3a05988..f9d0c025c 100644 --- a/scheduler/dirsvc.h +++ b/scheduler/dirsvc.h @@ -1,10 +1,10 @@ /* - * "$Id: dirsvc.h 5833 2006-08-16 20:05:58Z mike $" + * "$Id: dirsvc.h 6291 2007-02-19 21:54:27Z mike $" * * Directory services definitions for the Common UNIX Printing System * (CUPS) scheduler. * - * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -45,7 +45,7 @@ #define BROWSE_CUPS 1 /* CUPS */ #define BROWSE_SLP 2 /* SLPv2 */ #define BROWSE_LDAP 4 /* LDAP */ -#define BROWSE_DNSSD 8 /* DNS Service Discovery aka Bonjour */ +#define BROWSE_DNSSD 8 /* DNS Service Discovery (aka Bonjour) */ #define BROWSE_ALL 15 /* All protocols */ @@ -163,16 +163,20 @@ VAR char *BrowseLDAPBindDN VALUE(NULL), * Prototypes... */ +extern void cupsdDeregisterPrinter(cupsd_printer_t *p, int removeit); extern void cupsdLoadRemoteCache(void); +extern void cupsdRegisterPrinter(cupsd_printer_t *p); extern void cupsdRestartPolling(void); extern void cupsdSaveRemoteCache(void); -extern void cupsdSendBrowseDelete(cupsd_printer_t *p); extern void cupsdSendBrowseList(void); extern void cupsdStartBrowsing(void); extern void cupsdStartPolling(void); extern void cupsdStopBrowsing(void); extern void cupsdStopPolling(void); extern void cupsdUpdateCUPSBrowse(void); +#ifdef HAVE_DNSSD +extern void cupsdUpdateDNSSDBrowse(cupsd_printer_t *p); +#endif /* HAVE_DNSSD */ #ifdef HAVE_LDAP extern void cupsdUpdateLDAPBrowse(void); #endif /* HAVE_LDAP */ @@ -181,5 +185,5 @@ extern void cupsdUpdateSLPBrowse(void); /* - * End of "$Id: dirsvc.h 5833 2006-08-16 20:05:58Z mike $". + * End of "$Id: dirsvc.h 6291 2007-02-19 21:54:27Z mike $". */ diff --git a/scheduler/filter.c b/scheduler/filter.c index 25d3b651e..e6ca1b518 100644 --- a/scheduler/filter.c +++ b/scheduler/filter.c @@ -1,9 +1,9 @@ /* - * "$Id: filter.c 5606 2006-05-30 19:40:34Z mike $" + * "$Id: filter.c 6252 2007-02-10 15:34:18Z mike $" * * File type conversion routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -23,12 +23,12 @@ * * Contents: * - * mimeAddFilter() - Add a filter to the current MIME database. - * mimeFilter() - Find the fastest way to convert from one type to - * another. - * compare_filters() - Compare two filters... - * find_filters() - Find the filters to convert from one type to another. - * lookup() - Lookup a filter... + * mimeAddFilter() - Add a filter to the current MIME database. + * mimeFilter() - Find the fastest way to convert from one type to + * another. + * mimeFilterLookup() - Lookup a filter... + * compare_filters() - Compare two filters... + * find_filters() - Find the filters to convert from one type to another. */ /* @@ -64,7 +64,6 @@ static int compare_srcs(mime_filter_t *, mime_filter_t *); static cups_array_t *find_filters(mime_t *mime, mime_type_t *src, mime_type_t *dst, int *cost, _mime_typelist_t *visited); -static mime_filter_t *lookup(mime_t *, mime_type_t *, mime_type_t *); /* @@ -93,7 +92,7 @@ mimeAddFilter(mime_t *mime, /* I - MIME database */ * destination... */ - if ((temp = lookup(mime, src, dst)) != NULL) + if ((temp = mimeFilterLookup(mime, src, dst)) != NULL) { /* * Yup, does the existing filter have a higher cost? If so, copy the @@ -193,6 +192,25 @@ mimeFilter(mime_t *mime, /* I - MIME database */ } +/* + * 'mimeFilterLookup()' - Lookup a filter... + */ + +mime_filter_t * /* O - Filter for src->dst */ +mimeFilterLookup(mime_t *mime, /* I - MIME database */ + mime_type_t *src, /* I - Source type */ + mime_type_t *dst) /* I - Destination type */ +{ + mime_filter_t key; /* Key record for filter search */ + + + key.src = src; + key.dst = dst; + + return ((mime_filter_t *)cupsArrayFind(mime->filters, &key)); +} + + /* * 'compare_filters()' - Compare two filters... */ @@ -260,7 +278,7 @@ find_filters(mime_t *mime, /* I - MIME database */ * See if there is a filter that can convert the files directly... */ - if ((current = lookup(mime, src, dst)) != NULL) + if ((current = mimeFilterLookup(mime, src, dst)) != NULL) { /* * Got a direct filter! @@ -392,24 +410,5 @@ find_filters(mime_t *mime, /* I - MIME database */ /* - * 'lookup()' - Lookup a filter... - */ - -static mime_filter_t * /* O - Filter for src->dst */ -lookup(mime_t *mime, /* I - MIME database */ - mime_type_t *src, /* I - Source type */ - mime_type_t *dst) /* I - Destination type */ -{ - mime_filter_t key; /* Key record for filter search */ - - - key.src = src; - key.dst = dst; - - return ((mime_filter_t *)cupsArrayFind(mime->filters, &key)); -} - - -/* - * End of "$Id: filter.c 5606 2006-05-30 19:40:34Z mike $". + * End of "$Id: filter.c 6252 2007-02-10 15:34:18Z mike $". */ diff --git a/scheduler/ipp.c b/scheduler/ipp.c index f96d2bf13..78edc3cc8 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -1,9 +1,12 @@ /* - * "$Id: ipp.c 6145 2006-12-06 20:10:16Z mike $" + * "$Id: ipp.c 6318 2007-03-06 04:36:55Z mike $" * * IPP routines for the Common UNIX Printing System (CUPS) scheduler. * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * This file contains Kerberos support code, copyright 2006 by + * Jelmer Vernooij. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -79,6 +82,7 @@ * release_job() - Release a held print job. * restart_job() - Restart an old print job. * save_auth_info() - Save authentication information for a job. + * save_krb5_creds() - Save Kerberos credentials for a job. * send_document() - Send a file to a printer or class. * send_http_error() - Send a HTTP error back to the IPP client. * send_ipp_status() - Send a status back to the IPP client. @@ -101,6 +105,10 @@ #include "cupsd.h" +#ifdef HAVE_KRB5_H +# include +#endif /* HAVE_KRB5_H */ + #ifdef HAVE_LIBPAPER # include #endif /* HAVE_LIBPAPER */ @@ -114,8 +122,7 @@ static void accept_jobs(cupsd_client_t *con, ipp_attribute_t *uri); static void add_class(cupsd_client_t *con, ipp_attribute_t *uri); static int add_file(cupsd_client_t *con, cupsd_job_t *job, mime_type_t *filetype, int compression); -static cupsd_job_t *add_job(cupsd_client_t *con, ipp_attribute_t *uri, - cupsd_printer_t **dprinter, +static cupsd_job_t *add_job(cupsd_client_t *con, cupsd_printer_t *printer, mime_type_t *filetype); static void add_job_state_reasons(cupsd_client_t *con, cupsd_job_t *job); static void add_job_subscriptions(cupsd_client_t *con, cupsd_job_t *job); @@ -174,7 +181,11 @@ static void reject_jobs(cupsd_client_t *con, ipp_attribute_t *uri); static void release_job(cupsd_client_t *con, ipp_attribute_t *uri); static void renew_subscription(cupsd_client_t *con, int sub_id); static void restart_job(cupsd_client_t *con, ipp_attribute_t *uri); -static void save_auth_info(cupsd_client_t *con, cupsd_job_t *job); +static void save_auth_info(cupsd_client_t *con, cupsd_job_t *job, + ipp_attribute_t *auth_info); +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H) +static void save_krb5_creds(cupsd_client_t *con, cupsd_job_t *job); +#endif /* HAVE_GSSAPI && HAVE_KRB5_H */ static void send_document(cupsd_client_t *con, ipp_attribute_t *uri); static void send_http_error(cupsd_client_t *con, http_status_t status); static void send_ipp_status(cupsd_client_t *con, ipp_status_t status, @@ -233,7 +244,7 @@ cupsdProcessIPPRequest( /* * Then validate the request header and required attributes... */ - + if (con->request->request.any.version[0] != 1) { /* @@ -250,7 +261,7 @@ cupsdProcessIPPRequest( _("Bad request version number %d.%d!"), con->request->request.any.version[0], con->request->request.any.version[1]); - } + } else if (!con->request->attrs) { cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, @@ -384,7 +395,7 @@ cupsdProcessIPPRequest( cupsdLogMessage(CUPSD_LOG_DEBUG, "Request attributes follow..."); for (attr = con->request->attrs; attr; attr = attr->next) - cupsdLogMessage(CUPSD_LOG_DEBUG, + cupsdLogMessage(CUPSD_LOG_DEBUG, "attr \"%s\": group_tag = %x, value_tag = %x", attr->name ? attr->name : "(null)", attr->group_tag, attr->value_tag); @@ -651,11 +662,8 @@ cupsdProcessIPPRequest( con->http.data_remaining = length; } - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdProcessIPPRequest: Adding fd %d to OutputSet...", - con->http.fd); - - FD_SET(con->http.fd, OutputSet); + cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, + (cupsd_selfunc_t)cupsdWriteClient, con); /* * Tell the caller the response header was sent successfully... @@ -694,12 +702,6 @@ accept_jobs(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - const char *name; /* Printer name */ cupsd_printer_t *printer; /* Printer data */ @@ -710,11 +712,7 @@ accept_jobs(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((name = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -745,12 +743,19 @@ accept_jobs(cupsd_client_t *con, /* I - Client connection */ cupsdAddPrinterHistory(printer); if (dtype & CUPS_PRINTER_CLASS) + { cupsdSaveAllClasses(); + + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" now accepting jobs (\"%s\").", + printer->name, get_username(con)); + } else + { cupsdSaveAllPrinters(); - cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" now accepting jobs (\"%s\").", name, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" now accepting jobs (\"%s\").", + printer->name, get_username(con)); + } /* * Everything was ok, so return OK status... @@ -932,7 +937,7 @@ add_class(cupsd_client_t *con, /* I - Client connection */ IPP_TAG_BOOLEAN)) != NULL) { if (pclass->shared && !attr->values[0].boolean) - cupsdSendBrowseDelete(pclass); + cupsdDeregisterPrinter(pclass, 1); cupsdLogMessage(CUPSD_LOG_INFO, "Setting %s printer-is-shared to %d (was %d.)", @@ -996,11 +1001,7 @@ add_class(cupsd_client_t *con, /* I - Client connection */ * Search for the printer or class URI... */ - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if (!cupsdValidateDest(host, resource, &dtype, &member)) + if (!cupsdValidateDest(attr->values[i].string.text, &dtype, &member)) { /* * Bad URI... @@ -1137,54 +1138,25 @@ add_file(cupsd_client_t *con, /* I - Connection to client */ static cupsd_job_t * /* O - Job object */ add_job(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri, /* I - printer-uri */ - cupsd_printer_t **dprinter, /* I - Destination printer */ + cupsd_printer_t *printer, /* I - Destination printer */ mime_type_t *filetype) /* I - First print file type, if any */ { http_status_t status; /* Policy status */ - ipp_attribute_t *attr; /* Current attribute */ - const char *dest; /* Destination */ - cups_ptype_t dtype; /* Destination type (printer or class) */ + ipp_attribute_t *attr, /* Current attribute */ + *auth_info; /* auth-info attribute */ const char *val; /* Default option value */ int priority; /* Job priority */ char *title; /* Job name/title */ cupsd_job_t *job; /* Current job */ - char job_uri[HTTP_MAX_URI], /* Job URI */ - method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - cupsd_printer_t *printer; /* Printer data */ + char job_uri[HTTP_MAX_URI]; /* Job URI */ int kbytes; /* Size of print file */ int i; /* Looping var */ int lowerpagerange; /* Page range bound */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %s)", con, - con->http.fd, uri->values[0].string.text); - - /* - * Is the destination valid? - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) - { - /* - * Bad URI... - */ - - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer or class was not found.")); - return (NULL); - } - - if (dprinter) - *dprinter = printer; + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))", + con, con->http.fd, printer, printer->name, + filetype, filetype->super, filetype->type); /* * Check remote printing to non-shared printer... @@ -1222,13 +1194,13 @@ add_job(cupsd_client_t *con, /* I - Client connection */ { send_ipp_status(con, IPP_NOT_ACCEPTING, _("Destination \"%s\" is not accepting jobs."), - dest); + printer->name); return (NULL); } /* * Validate job template attributes; for now just document-format, - * copies, and page-ranges... + * copies, number-up, and page-ranges... */ if (filetype && printer->filetypes && @@ -1263,12 +1235,30 @@ add_job(cupsd_client_t *con, /* I - Client connection */ } } + if ((attr = ippFindAttribute(con->request, "number-up", + IPP_TAG_INTEGER)) != NULL) + { + if (attr->values[0].integer != 1 && + attr->values[0].integer != 2 && + attr->values[0].integer != 4 && + attr->values[0].integer != 6 && + attr->values[0].integer != 9 && + attr->values[0].integer != 16) + { + send_ipp_status(con, IPP_ATTRIBUTES, _("Bad number-up value %d."), + attr->values[0].integer); + ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER, + "number-up", attr->values[0].integer); + return (NULL); + } + } + if ((attr = ippFindAttribute(con->request, "page-ranges", IPP_TAG_RANGE)) != NULL) { for (i = 0, lowerpagerange = 1; i < attr->num_values; i ++) { - if (attr->values[i].range.lower < lowerpagerange || + if (attr->values[i].range.lower < lowerpagerange || attr->values[i].range.lower > attr->values[i].range.upper) { send_ipp_status(con, IPP_BAD_REQUEST, @@ -1289,7 +1279,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */ if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs) cupsdCleanJobs(); - if (cupsArrayCount(Jobs) >= MaxJobs && MaxJobs) + if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs) { send_ipp_status(con, IPP_NOT_POSSIBLE, _("Too many active jobs.")); @@ -1331,11 +1321,13 @@ add_job(cupsd_client_t *con, /* I - Client connection */ if ((job = cupsdAddJob(priority, printer->name)) == NULL) { send_ipp_status(con, IPP_INTERNAL_ERROR, - _("Unable to add job for destination \"%s\"!"), dest); + _("Unable to add job for destination \"%s\"!"), + printer->name); return (NULL); } - job->dtype = dtype; + job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_REMOTE); job->attrs = con->request; con->request = ippNewRequest(job->attrs->request.op.operation_id); @@ -1350,8 +1342,6 @@ add_job(cupsd_client_t *con, /* I - Client connection */ if (attr) cupsdSetString(&attr->values[0].string.text, con->username); - - save_auth_info(con, job); } else if (attr) { @@ -1374,6 +1364,30 @@ add_job(cupsd_client_t *con, /* I - Client connection */ attr->name = _cupsStrAlloc("job-originating-user-name"); } + auth_info = ippFindAttribute(job->attrs, "auth-info", IPP_TAG_TEXT); + + if (con->username[0] || auth_info) + { + save_auth_info(con, job, auth_info); + + /* + * Remove the auth-info attribute from the attribute data... + */ + + if (auth_info) + { + if (job->attrs->prev) + job->attrs->prev->next = auth_info->next; + else + job->attrs->attrs = auth_info->next; + + if (job->attrs->last == auth_info) + job->attrs->last = job->attrs->prev; + + _ippFreeAttr(auth_info); + } + } + if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name", IPP_TAG_ZERO)) != NULL) { @@ -1440,7 +1454,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */ * the connection... */ - ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-originating-host-name", NULL, con->http.hostname); } @@ -2266,7 +2280,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */ IPP_TAG_BOOLEAN)) != NULL) { if (printer->shared && !attr->values[0].boolean) - cupsdSendBrowseDelete(printer); + cupsdDeregisterPrinter(printer, 1); cupsdLogMessage(CUPSD_LOG_INFO, "Setting %s printer-is-shared to %d (was %d.)", @@ -2566,7 +2580,7 @@ apply_printer_defaults( int i, /* Looping var */ num_options; /* Number of default options */ cups_option_t *options, /* Default options */ - *option; /* Current option */ + *option; /* Current option */ /* @@ -2600,7 +2614,8 @@ static void authenticate_job(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *uri) /* I - Job URI */ { - ipp_attribute_t *attr; /* Job-id attribute */ + ipp_attribute_t *attr, /* job-id attribute */ + *auth_info; /* auth-info attribute */ int jobid; /* Job ID */ cupsd_job_t *job; /* Current job */ char method[HTTP_MAX_URI], @@ -2652,7 +2667,7 @@ authenticate_job(cupsd_client_t *con, /* I - Client connection */ httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, sizeof(method), username, sizeof(username), host, sizeof(host), &port, resource, sizeof(resource)); - + if (strncmp(resource, "/jobs/", 6)) { /* @@ -2702,7 +2717,9 @@ authenticate_job(cupsd_client_t *con, /* I - Client connection */ * See if we have already authenticated... */ - if (!con->username[0]) + auth_info = ippFindAttribute(con->request, "auth-info", IPP_TAG_TEXT); + + if (!con->username[0] && !auth_info) { send_ipp_status(con, IPP_NOT_AUTHORIZED, _("No authentication information provided!")); @@ -2723,7 +2740,7 @@ authenticate_job(cupsd_client_t *con, /* I - Client connection */ * Save the authentication information for this job... */ - save_auth_info(con, job); + save_auth_info(con, job, auth_info); /* * Reset the job-hold-until value to "no-hold"... @@ -2759,11 +2776,10 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *uri) /* I - Job or Printer URI */ { http_status_t status; /* Policy status */ - const char *dest; /* Destination */ cups_ptype_t dtype; /* Destination type */ - char method[HTTP_MAX_URI], /* Method portion of URI */ + char scheme[HTTP_MAX_URI], /* Scheme portion of URI */ userpass[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ + hostname[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ int port; /* Port portion of URI */ ipp_attribute_t *attr; /* Attribute in request */ @@ -2822,16 +2838,17 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ * And if the destination is valid... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), userpass, sizeof(userpass), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI? */ + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, + scheme, sizeof(scheme), userpass, sizeof(userpass), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + if ((!strncmp(resource, "/printers/", 10) && resource[10]) || (!strncmp(resource, "/classes/", 9) && resource[9])) { @@ -2839,13 +2856,6 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ _("The printer or class was not found.")); return; } - else if (strcmp(resource, "/printers/")) - { - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer-uri \"%s\" is not valid."), - uri->values[0].string.text); - return; - } /* * Check policy... @@ -2872,7 +2882,8 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ * Check policy... */ - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) { send_http_error(con, status); return; @@ -2882,10 +2893,11 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ * Cancel all of the jobs on the named printer... */ - cupsdCancelJobs(dest, username, purge); + cupsdCancelJobs(printer->name, username, purge); cupsdLogMessage(CUPSD_LOG_INFO, "All jobs on \"%s\" were %s by \"%s\".", - dest, purge ? "purged" : "canceled", get_username(con)); + printer->name, purge ? "purged" : "canceled", + get_username(con)); } con->response->request.status.status_code = IPP_OK; @@ -2902,13 +2914,12 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */ { ipp_attribute_t *attr; /* Current attribute */ int jobid; /* Job ID */ - char method[HTTP_MAX_URI], /* Method portion of URI */ + char scheme[HTTP_MAX_URI], /* Scheme portion of URI */ username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ int port; /* Port portion of URI */ cupsd_job_t *job; /* Job information */ - const char *dest; /* Destination */ cups_ptype_t dtype; /* Destination type (printer or class) */ cupsd_printer_t *printer; /* Printer data */ @@ -2940,11 +2951,7 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */ * Find the current job on the specified printer... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -2966,12 +2973,12 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */ /* * No, see if there are any pending jobs... */ - + for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); job; job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) if (job->state_value <= IPP_JOB_PROCESSING && - !strcasecmp(job->dest, dest)) + !strcasecmp(job->dest, printer->name)) break; if (job) @@ -2979,7 +2986,7 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */ else { send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s!"), - dest); + printer->name); return; } } @@ -2991,10 +2998,10 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */ * Got a job URI; parse it to get the job ID... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, sizeof(host), &port, resource, sizeof(resource)); - + if (strncmp(resource, "/jobs/", 6)) { /* @@ -3794,7 +3801,7 @@ copy_model(cupsd_client_t *con, /* I - Client connection */ const char *from, /* I - Source file */ const char *to) /* I - Destination file */ { - fd_set *input; /* select() input set */ + fd_set input; /* select() input set */ struct timeval timeout; /* select() timeout */ int maxfd; /* Maximum file descriptor for select() */ char tempfile[1024]; /* Temporary PPD file */ @@ -3847,24 +3854,12 @@ copy_model(cupsd_client_t *con, /* I - Client connection */ cupsdOpenPipe(temppipe); - if ((input = calloc(1, SetSize)) == NULL) - { - close(tempfd); - unlink(tempfile); - - cupsdLogMessage(CUPSD_LOG_ERROR, - "copy_model: Unable to allocate %d bytes for select()...", - SetSize); - return (-1); - } - cupsdLogMessage(CUPSD_LOG_DEBUG, "copy_model: Running \"cups-driverd cat %s\"...", from); if (!cupsdStartProcess(buffer, argv, envp, -1, temppipe[1], CGIPipes[1], - -1, 0, &temppid)) + -1, -1, 0, &temppid)) { - free(input); close(tempfd); unlink(tempfile); return (-1); @@ -3891,13 +3886,14 @@ copy_model(cupsd_client_t *con, /* I - Client connection */ bytes = 0; - FD_SET(temppipe[0], input); - FD_SET(CGIPipes[0], input); + FD_ZERO(&input); + FD_SET(temppipe[0], &input); + FD_SET(CGIPipes[0], &input); timeout.tv_sec = 30; timeout.tv_usec = 0; - if ((i = select(maxfd, input, NULL, NULL, &timeout)) < 0) + if ((i = select(maxfd, &input, NULL, NULL, &timeout)) < 0) { if (errno == EINTR) continue; @@ -3913,7 +3909,7 @@ copy_model(cupsd_client_t *con, /* I - Client connection */ break; } - if (FD_ISSET(temppipe[0], input)) + if (FD_ISSET(temppipe[0], &input)) { /* * Read the PPD file from the pipe, and write it to the PPD file. @@ -3930,15 +3926,13 @@ copy_model(cupsd_client_t *con, /* I - Client connection */ break; } - if (FD_ISSET(CGIPipes[0], input)) + if (FD_ISSET(CGIPipes[0], &input)) cupsdUpdateCGI(); } close(temppipe[0]); close(tempfd); - free(input); - if (!total) { /* @@ -4020,13 +4014,13 @@ copy_model(cupsd_client_t *con, /* I - Client connection */ if ((!strcmp(system_paper, "Letter") && have_letter) || (!strcmp(system_paper, "A4") && have_a4)) { - num_defaults = cupsAddOption("PageSize", system_paper, + num_defaults = cupsAddOption("PageSize", system_paper, num_defaults, &defaults); - num_defaults = cupsAddOption("PageRegion", system_paper, + num_defaults = cupsAddOption("PageRegion", system_paper, num_defaults, &defaults); - num_defaults = cupsAddOption("PaperDimension", system_paper, + num_defaults = cupsAddOption("PaperDimension", system_paper, num_defaults, &defaults); - num_defaults = cupsAddOption("ImageableArea", system_paper, + num_defaults = cupsAddOption("ImageableArea", system_paper, num_defaults, &defaults); } } @@ -4261,7 +4255,7 @@ copy_printer_attrs( if (!ra || cupsArrayFind(ra, "printer-state-change-time")) ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "printer-state-change-time", printer->state_time); - + if (MaxPrinterHistory > 0 && printer->num_history > 0 && cupsArrayFind(ra, "printer-state-history")) { @@ -4446,23 +4440,39 @@ static void create_job(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *uri) /* I - Printer URI */ { - cupsd_job_t *job; /* New job */ + cupsd_printer_t *printer; /* Printer */ + cupsd_job_t *job; /* New job */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", con, con->http.fd, uri->values[0].string.text); + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, NULL, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + /* * Create the job object... */ - if ((job = add_job(con, uri, NULL, NULL)) == NULL) + if ((job = add_job(con, printer, NULL)) == NULL) return; /* * Save and log the job... */ - + cupsdSaveJob(job); cupsdLogMessage(CUPSD_LOG_INFO, "Job %d created on \"%s\" by \"%s\".", @@ -4630,6 +4640,16 @@ create_requested_array(ipp_t *request) /* I - IPP request */ cupsArrayAdd(ra, "uri-authentication-supported"); cupsArrayAdd(ra, "uri-security-supported"); } + else if (!strcmp(value, "printer-defaults")) + { + char *name; /* Option name */ + + + for (name = (char *)cupsArrayFirst(CommonDefaults); + name; + name = (char *)cupsArrayNext(CommonDefaults)) + cupsArrayAdd(ra, name); + } else if (!strcmp(value, "subscription-template")) { cupsArrayAdd(ra, "notify-attributes"); @@ -4683,6 +4703,8 @@ create_subscription( int interval, /* notify-time-interval */ lease; /* notify-lease-duration */ unsigned mask; /* notify-events */ + ipp_attribute_t *notify_events,/* notify-events(-default) */ + *notify_lease; /* notify-lease-duration(-default) */ #ifdef DEBUG @@ -4723,7 +4745,7 @@ create_subscription( dtype = CUPS_PRINTER_CLASS; printer = NULL; } - else if (!cupsdValidateDest(host, resource, &dtype, &printer)) + else if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -4740,7 +4762,8 @@ create_subscription( if (printer) { - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) { send_http_error(con, status); return; @@ -4790,6 +4813,23 @@ create_subscription( jobid = 0; mask = CUPSD_EVENT_NONE; + if (printer) + { + notify_events = ippFindAttribute(printer->attrs, "notify-events-default", + IPP_TAG_KEYWORD); + notify_lease = ippFindAttribute(printer->attrs, + "notify-lease-duration-default", + IPP_TAG_INTEGER); + + if (notify_lease) + lease = notify_lease->values[0].integer; + } + else + { + notify_events = NULL; + notify_lease = NULL; + } + while (attr && attr->group_tag != IPP_TAG_ZERO) { if (!strcmp(attr->name, "notify-recipient") && @@ -4878,10 +4918,7 @@ create_subscription( } else if (!strcmp(attr->name, "notify-events") && attr->value_tag == IPP_TAG_KEYWORD) - { - for (i = 0; i < attr->num_values; i ++) - mask |= cupsdEventValue(attr->values[i].string.text); - } + notify_events = attr; else if (!strcmp(attr->name, "notify-lease-duration") && attr->value_tag == IPP_TAG_INTEGER) lease = attr->values[0].integer; @@ -4895,6 +4932,12 @@ create_subscription( attr = attr->next; } + if (notify_events) + { + for (i = 0; i < notify_events->num_values; i ++) + mask |= cupsdEventValue(notify_events->values[i].string.text); + } + if (recipient) cupsdLogMessage(CUPSD_LOG_DEBUG, "recipient=\"%s\"", recipient); if (pullmethod) @@ -4989,13 +5032,7 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *uri) /* I - URI of printer or class */ { http_status_t status; /* Policy status */ - const char *dest; /* Destination */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ cupsd_printer_t *printer; /* Printer/class */ char filename[1024]; /* Script/PPD filename */ @@ -5007,11 +5044,7 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */ * Do we have a valid URI? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -5036,7 +5069,7 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */ * Remove old jobs... */ - cupsdCancelJobs(dest, NULL, 1); + cupsdCancelJobs(printer->name, NULL, 1); /* * Remove old subscriptions and send a "deleted printer" event... @@ -5045,32 +5078,34 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */ cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, printer, NULL, "%s \"%s\" deleted by \"%s\".", (dtype & CUPS_PRINTER_CLASS) ? "Class" : "Printer", - dest, get_username(con)); + printer->name, get_username(con)); cupsdExpireSubscriptions(printer, NULL); - + /* * Remove any old PPD or script files... */ - snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot, dest); + snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot, + printer->name); unlink(filename); - snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, dest); + snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, + printer->name); unlink(filename); if (dtype & CUPS_PRINTER_CLASS) { - cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" deleted by \"%s\".", dest, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" deleted by \"%s\".", + printer->name, get_username(con)); cupsdDeletePrinter(printer, 0); cupsdSaveAllClasses(); } else { - cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" deleted by \"%s\".", dest, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" deleted by \"%s\".", + printer->name, get_username(con)); cupsdDeletePrinter(printer, 0); cupsdSaveAllPrinters(); @@ -5313,7 +5348,7 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ const char *dest; /* Destination */ cups_ptype_t dtype; /* Destination type (printer or class) */ cups_ptype_t dmask; /* Destination type mask */ - char method[HTTP_MAX_URI], /* Method portion of URI */ + char scheme[HTTP_MAX_URI], /* Scheme portion of URI */ username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ @@ -5335,8 +5370,8 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, sizeof(host), &port, resource, sizeof(resource)); if (!strcmp(resource, "/") || @@ -5361,7 +5396,8 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ dmask = CUPS_PRINTER_CLASS; printer = NULL; } - else if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + else if ((dest = cupsdValidateDest(uri->values[0].string.text, &dtype, + &printer)) == NULL) { /* * Bad URI... @@ -5383,7 +5419,8 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ if (printer) { - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) { send_http_error(con, status); return; @@ -5512,7 +5549,7 @@ get_notifications(cupsd_client_t *con) /* I - Client connection */ int interval; /* Poll interval */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_subscription_attrs(con=%p[%d])", + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_notifications(con=%p[%d])", con, con->http.fd); /* @@ -5720,15 +5757,6 @@ get_printer_attrs(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ cupsd_printer_t *printer; /* Printer/class */ cups_array_t *ra; /* Requested attributes array */ @@ -5740,11 +5768,7 @@ get_printer_attrs(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if (!cupsdValidateDest(host, resource, &dtype, &printer)) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -6007,8 +6031,8 @@ get_subscriptions(cupsd_client_t *con, /* I - Client connection */ cups_array_t *ra; /* Requested attributes array */ ipp_attribute_t *attr; /* Attribute */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ + char scheme[HTTP_MAX_URI], + /* Scheme portion of URI */ username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], @@ -6028,8 +6052,8 @@ get_subscriptions(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, sizeof(host), &port, resource, sizeof(resource)); if (!strcmp(resource, "/") || @@ -6052,7 +6076,7 @@ get_subscriptions(cupsd_client_t *con, /* I - Client connection */ return; } } - else if (!cupsdValidateDest(host, resource, &dtype, &printer)) + else if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -6316,7 +6340,7 @@ move_job(cupsd_client_t *con, /* I - Client connection */ const char *src; /* Source printer/class */ cups_ptype_t stype, /* Source type (printer or class) */ dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], /* Method portion of URI */ + char scheme[HTTP_MAX_URI], /* Scheme portion of URI */ username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ @@ -6343,12 +6367,8 @@ move_job(cupsd_client_t *con, /* I - Client connection */ _("job-printer-uri attribute missing!")); return; } - - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - if (!cupsdValidateDest(host, resource, &dtype, &dprinter)) + if (!cupsdValidateDest(attr->values[0].string.text, &dtype, &dprinter)) { /* * Bad URI... @@ -6363,7 +6383,8 @@ move_job(cupsd_client_t *con, /* I - Client connection */ * Check policy... */ - if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con, NULL)) != HTTP_OK) + if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con, + NULL)) != HTTP_OK) { send_http_error(con, status); return; @@ -6373,8 +6394,8 @@ move_job(cupsd_client_t *con, /* I - Client connection */ * See if we have a job URI or a printer URI... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, sizeof(host), &port, resource, sizeof(resource)); if (!strcmp(uri->name, "printer-uri")) @@ -6390,7 +6411,8 @@ move_job(cupsd_client_t *con, /* I - Client connection */ * Move all jobs... */ - if ((src = cupsdValidateDest(host, resource, &stype, &sprinter)) == NULL) + if ((src = cupsdValidateDest(uri->values[0].string.text, &stype, + &sprinter)) == NULL) { /* * Bad URI... @@ -6638,6 +6660,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */ { ipp_attribute_t *attr; /* Current attribute */ ipp_attribute_t *format; /* Document-format attribute */ + const char *default_format; /* document-format-default value */ cupsd_job_t *job; /* New job */ char filename[1024]; /* Job filename */ mime_type_t *filetype; /* Type of file */ @@ -6694,6 +6717,21 @@ print_job(cupsd_client_t *con, /* I - Client connection */ return; } + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, NULL, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + /* * Is it a format we support? */ @@ -6705,7 +6743,8 @@ print_job(cupsd_client_t *con, /* I - Client connection */ * Grab format from client... */ - if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, type) != 2) + if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, + type) != 2) { send_ipp_status(con, IPP_BAD_REQUEST, _("Could not scan type \"%s\"!"), @@ -6713,10 +6752,26 @@ print_job(cupsd_client_t *con, /* I - Client connection */ return; } } + else if ((default_format = cupsGetOption("document-format", + printer->num_options, + printer->options)) != NULL) + { + /* + * Use default document format... + */ + + if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Could not scan type \"%s\"!"), + default_format); + return; + } + } else { /* - * No document format attribute? Auto-type it! + * Auto-type it! */ strcpy(super, "application"); @@ -6739,32 +6794,35 @@ print_job(cupsd_client_t *con, /* I - Client connection */ doc_name ? doc_name->values[0].string.text : NULL, &compression); - if (filetype) - { - /* - * Replace the document-format attribute value with the auto-typed one. - */ + if (!filetype) + filetype = mimeType(MimeDatabase, super, type); + } + else + filetype = mimeType(MimeDatabase, super, type); - snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, - filetype->type); + if (filetype && + (!format || + (!strcmp(super, "application") && !strcmp(type, "octet-stream")))) + { + /* + * Replace the document-format attribute value with the auto-typed or + * default one. + */ - if (format) - { - _cupsStrFree(format->values[0].string.text); + snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, + filetype->type); - format->values[0].string.text = _cupsStrAlloc(mimetype); - } - else - ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, - "document-format", NULL, mimetype); + if (format) + { + _cupsStrFree(format->values[0].string.text); + + format->values[0].string.text = _cupsStrAlloc(mimetype); } else - filetype = mimeType(MimeDatabase, super, type); + ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, + "document-format", NULL, mimetype); } - else - filetype = mimeType(MimeDatabase, super, type); - - if (!filetype) + else if (!filetype) { send_ipp_status(con, IPP_DOCUMENT_FORMAT, _("Unsupported format \'%s/%s\'!"), super, type); @@ -6793,7 +6851,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */ * Create the job object... */ - if ((job = add_job(con, uri, &printer, filetype)) == NULL) + if ((job = add_job(con, printer, filetype)) == NULL) return; /* @@ -7058,12 +7116,6 @@ reject_jobs(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - const char *name; /* Printer name */ cupsd_printer_t *printer; /* Printer data */ ipp_attribute_t *attr; /* printer-state-message text */ @@ -7075,11 +7127,7 @@ reject_jobs(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((name = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -7120,14 +7168,14 @@ reject_jobs(cupsd_client_t *con, /* I - Client connection */ cupsdSaveAllClasses(); cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" rejecting jobs (\"%s\").", - name, get_username(con)); + printer->name, get_username(con)); } else { cupsdSaveAllPrinters(); cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" rejecting jobs (\"%s\").", - name, get_username(con)); + printer->name, get_username(con)); } /* @@ -7499,22 +7547,24 @@ restart_job(cupsd_client_t *con, /* I - Client connection */ */ static void -save_auth_info(cupsd_client_t *con, /* I - Client connection */ - cupsd_job_t *job) /* I - Job */ +save_auth_info( + cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job, /* I - Job */ + ipp_attribute_t *auth_info) /* I - auth-info attribute, if any */ { int i; /* Looping var */ char filename[1024]; /* Job authentication filename */ cups_file_t *fp; /* Job authentication file */ - char line[1024]; /* Line for file */ + char line[2048]; /* Line for file */ /* * This function saves the in-memory authentication information for * a job so that it can be used to authenticate with a remote host. * The information is stored in a file that is readable only by the - * root user. The username and password are Base-64 encoded, each - * on a separate line, followed by random number (up to 1024) of - * newlines to limit the amount of information that is exposed. + * root user. The fields are Base-64 encoded, each on a separate line, + * followed by random number (up to 1024) of newlines to limit the + * amount of information that is exposed. * * Because of the potential for exposing of authentication information, * this functionality is only enabled when running cupsd as root. @@ -7550,19 +7600,35 @@ save_auth_info(cupsd_client_t *con, /* I - Client connection */ fchown(cupsFileNumber(fp), 0, 0); fchmod(cupsFileNumber(fp), 0400); - /* - * Write the authenticated username... - */ + if (auth_info) + { + /* + * Write 1 to 4 auth values... + */ - httpEncode64_2(line, sizeof(line), con->username, strlen(con->username)); - cupsFilePrintf(fp, "%s\n", line); + for (i = 0; i < auth_info->num_values; i ++) + { + httpEncode64_2(line, sizeof(line), auth_info->values[i].string.text, + strlen(auth_info->values[i].string.text)); + cupsFilePrintf(fp, "%s\n", line); + } + } + else + { + /* + * Write the authenticated username... + */ - /* - * Write the authenticated password... - */ + httpEncode64_2(line, sizeof(line), con->username, strlen(con->username)); + cupsFilePrintf(fp, "%s\n", line); - httpEncode64_2(line, sizeof(line), con->password, strlen(con->password)); - cupsFilePrintf(fp, "%s\n", line); + /* + * Write the authenticated password... + */ + + httpEncode64_2(line, sizeof(line), con->password, strlen(con->password)); + cupsFilePrintf(fp, "%s\n", line); + } /* * Write a random number of newlines to the end of the file... @@ -7576,7 +7642,66 @@ save_auth_info(cupsd_client_t *con, /* I - Client connection */ */ cupsFileClose(fp); + +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H) + save_krb5_creds(con, job); +#endif /* HAVE_GSSAPI && HAVE_KRB5_H */ +} + + +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H) +/* + * 'save_krb5_creds()' - Save Kerberos credentials for the job. + */ + +static void +save_krb5_creds(cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job) /* I - Job */ +{ +# ifndef __APPLE__ + krb5_context krb_context; /* Kerberos context */ + krb5_ccache ccache; /* Credentials cache */ + OM_uint32 major_status, /* Major status code */ + minor_status; /* Minor status code */ + + + /* + * Setup a cached context for the job filters to use... + */ + + if (krb5_init_context(&krb_context)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize Kerberos context"); + return; + } + +# ifdef HAVE_HEIMDAL + if (krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache)) +# else + if (krb5_cc_gen_new(krb_context, &ccache)) +# endif /* HAVE_HEIMDAL */ + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create new credentials"); + return; + } + + major_status = gss_krb5_copy_ccache(&minor_status, con->gss_delegated_cred, + ccache); + + if (GSS_ERROR(major_status)) + { + cupsdLogGSSMessage(CUPSD_LOG_ERROR, major_status, minor_status, + "Unable to import client credentials cache"); + krb5_cc_destroy(krb_context, ccache); + return; + } + + cupsdSetStringf(&(job->ccname), "KRB5CCNAME=FILE:%s", + krb5_cc_get_name(krb_context, ccache)); + krb5_cc_close(krb_context, ccache); +# endif /* !__APPLE__ */ } +#endif /* HAVE_GSSAPI && HAVE_KRB5_H */ /* @@ -7589,6 +7714,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */ { ipp_attribute_t *attr; /* Current attribute */ ipp_attribute_t *format; /* Document-format attribute */ + const char *default_format;/* document-format-default value */ int jobid; /* Job ID number */ cupsd_job_t *job; /* Current job */ char job_uri[HTTP_MAX_URI], @@ -7747,6 +7873,22 @@ send_document(cupsd_client_t *con, /* I - Client connection */ return; } } + else if ((default_format = cupsGetOption("document-format", + printer->num_options, + printer->options)) != NULL) + { + /* + * Use default document format... + */ + + if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Could not scan type \"%s\"!"), + default_format); + return; + } + } else { /* @@ -7773,31 +7915,35 @@ send_document(cupsd_client_t *con, /* I - Client connection */ doc_name ? doc_name->values[0].string.text : NULL, &compression); - if (filetype) - { - /* - * Replace the document-format attribute value with the auto-typed one. - */ - - snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, - filetype->type); - - if (format) - { - _cupsStrFree(format->values[0].string.text); - format->values[0].string.text = _cupsStrAlloc(mimetype); - } - else - ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, - "document-format", NULL, mimetype); - } - else + if (!filetype) filetype = mimeType(MimeDatabase, super, type); } else filetype = mimeType(MimeDatabase, super, type); - if (!filetype) + if (filetype && + (!format || + (!strcmp(super, "application") && !strcmp(type, "octet-stream")))) + { + /* + * Replace the document-format attribute value with the auto-typed or + * default one. + */ + + snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, + filetype->type); + + if (format) + { + _cupsStrFree(format->values[0].string.text); + + format->values[0].string.text = _cupsStrAlloc(mimetype); + } + else + ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, + "document-format", NULL, mimetype); + } + else if (!filetype) { send_ipp_status(con, IPP_DOCUMENT_FORMAT, _("Unsupported format \'%s/%s\'!"), super, type); @@ -8035,16 +8181,6 @@ set_default(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ - const char *name; /* Printer name */ cupsd_printer_t *printer; /* Printer */ @@ -8055,11 +8191,7 @@ set_default(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((name = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -8092,8 +8224,8 @@ set_default(cupsd_client_t *con, /* I - Client connection */ cupsdWritePrintcap(); cupsdLogMessage(CUPSD_LOG_INFO, - "Default destination set to \"%s\" by \"%s\".", name, - get_username(con)); + "Default destination set to \"%s\" by \"%s\".", + printer->name, get_username(con)); /* * Everything was ok, so return OK status... @@ -8613,10 +8745,6 @@ set_printer_defaults( attr->values[0].string.text); cupsdSetString(&printer->error_policy, attr->values[0].string.text); } - else if (!strcmp(attr->name, "document-format-default") || - !strcmp(attr->name, "notify-lease-duration-default") || - !strcmp(attr->name, "notify-events-default")) - continue; /* * Skip any other non-default attributes... @@ -8717,16 +8845,6 @@ start_printer(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ - const char *name; /* Printer name */ cupsd_printer_t *printer; /* Printer data */ @@ -8737,11 +8855,7 @@ start_printer(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((name = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -8771,11 +8885,11 @@ start_printer(cupsd_client_t *con, /* I - Client connection */ cupsdStartPrinter(printer, 1); if (dtype & CUPS_PRINTER_CLASS) - cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" started by \"%s\".", name, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" started by \"%s\".", + printer->name, get_username(con)); else - cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" started by \"%s\".", name, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" started by \"%s\".", + printer->name, get_username(con)); cupsdCheckJobs(); @@ -8797,16 +8911,6 @@ stop_printer(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ - const char *name; /* Printer name */ cupsd_printer_t *printer; /* Printer data */ ipp_attribute_t *attr; /* printer-state-message attribute */ @@ -8818,11 +8922,7 @@ stop_printer(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((name = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -8859,11 +8959,11 @@ stop_printer(cupsd_client_t *con, /* I - Client connection */ cupsdStopPrinter(printer, 1); if (dtype & CUPS_PRINTER_CLASS) - cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" stopped by \"%s\".", name, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" stopped by \"%s\".", + printer->name, get_username(con)); else - cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" stopped by \"%s\".", name, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" stopped by \"%s\".", + printer->name, get_username(con)); /* * Everything was ok, so return OK status... @@ -8989,15 +9089,6 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *attr; /* Current attribute */ ipp_attribute_t *format; /* Document-format attribute */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ char super[MIME_MAX_SUPER], /* Supertype of file */ type[MIME_MAX_TYPE]; @@ -9057,11 +9148,7 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if (cupsdValidateDest(host, resource, &dtype, &printer) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -9105,7 +9192,7 @@ validate_name(const char *name) /* I - Name to check */ */ for (ptr = name; *ptr; ptr ++) - if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || *ptr == '#') + if ((*ptr > 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || *ptr == '#') return (0); /* @@ -9161,5 +9248,5 @@ validate_user(cupsd_job_t *job, /* I - Job */ /* - * End of "$Id: ipp.c 6145 2006-12-06 20:10:16Z mike $". + * End of "$Id: ipp.c 6318 2007-03-06 04:36:55Z mike $". */ diff --git a/scheduler/job.c b/scheduler/job.c index f219c6980..3c876a649 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -1,9 +1,9 @@ /* - * "$Id: job.c 6234 2007-02-05 20:25:50Z mike $" + * "$Id: job.c 6318 2007-03-06 04:36:55Z mike $" * * Job management routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -127,6 +127,8 @@ cupsdAddJob(int priority, /* I - Job priority */ job->back_pipes[1] = -1; job->print_pipes[0] = -1; job->print_pipes[1] = -1; + job->side_pipes[0] = -1; + job->side_pipes[1] = -1; job->status_pipes[0] = -1; job->status_pipes[1] = -1; @@ -461,7 +463,6 @@ cupsdCleanJobs(void) void cupsdFinishJob(cupsd_job_t *job) /* I - Job */ { - int job_history; /* Did cupsdCancelJob() keep the job? */ cupsd_printer_t *printer; /* Current printer */ @@ -478,11 +479,7 @@ cupsdFinishJob(cupsd_job_t *job) /* I - Job */ * Close the pipe and clear the input bit. */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdFinishJob: Removing fd %d from InputSet...", - job->status_buffer->fd); - - FD_CLR(job->status_buffer->fd, InputSet); + cupsdRemoveSelect(job->status_buffer->fd); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFinishJob: Closing status pipes [ %d %d ]...", @@ -711,8 +708,6 @@ cupsdFinishJob(cupsd_job_t *job) /* I - Job */ * Close out this job... */ - job_history = JobHistory && !(job->dtype & CUPS_PRINTER_REMOTE); - cupsdCancelJob(job, 0, IPP_JOB_COMPLETED); cupsdCheckJobs(); } @@ -921,13 +916,6 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ cups_file_t *fp; /* Job file */ int fileid; /* Current file ID */ ipp_attribute_t *attr; /* Job attribute */ - char scheme[32], /* Scheme portion of URI */ - username[64], /* Username portion of URI */ - host[HTTP_MAX_HOST], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ const char *dest; /* Destination */ mime_type_t **filetypes; /* New filetypes array */ int *compressions; /* New compressions array */ @@ -1011,11 +999,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ return; } - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, scheme, - sizeof(scheme), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &(job->dtype), + if ((dest = cupsdValidateDest(attr->values[0].string.text, &(job->dtype), NULL)) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, @@ -1427,7 +1411,7 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */ job->hold_until = curtime + ((17 - curdate->tm_hour) * 60 + 59 - curdate->tm_min) * 60 + 60 - curdate->tm_sec; - } + } else if (!strcmp(when, "second-shift")) { /* @@ -1443,7 +1427,7 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */ job->hold_until = curtime + ((15 - curdate->tm_hour) * 60 + 59 - curdate->tm_min) * 60 + 60 - curdate->tm_sec; - } + } else if (!strcmp(when, "third-shift")) { /* @@ -1459,7 +1443,7 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */ job->hold_until = curtime + ((23 - curdate->tm_hour) * 60 + 59 - curdate->tm_min) * 60 + 60 - curdate->tm_sec; - } + } else if (!strcmp(when, "weekend")) { /* @@ -1622,17 +1606,19 @@ cupsdStopJob(cupsd_job_t *job, /* I - Job */ cupsdClosePipe(job->back_pipes); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdStopJob: Closing side pipes [ %d %d ]...", + job->side_pipes[0], job->side_pipes[1]); + + cupsdClosePipe(job->side_pipes); + if (job->status_buffer) { /* * Close the pipe and clear the input bit. */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStopJob: Removing fd %d from InputSet...", - job->status_buffer->fd); - - FD_CLR(job->status_buffer->fd, InputSet); + cupsdRemoveSelect(job->status_buffer->fd); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStopJob: Closing status pipes [ %d %d ]...", @@ -1710,7 +1696,7 @@ cupsdUpdateJob(cupsd_job_t *job) /* I - Job to check */ } else if (!sscanf(message, "%*d%d", &copies)) copies = 1; - + job->sheets->values[0].integer += copies; if (job->printer->page_limit) @@ -1734,7 +1720,18 @@ cupsdUpdateJob(cupsd_job_t *job) /* I - Job to check */ * Set attribute(s)... */ - /**** TODO ****/ + int num_attrs; /* Number of attributes */ + cups_option_t *attrs; /* Attributes */ + const char *attr; /* Attribute */ + + + num_attrs = cupsParseOptions(message, 0, &attrs); + + if ((attr = cupsGetOption("auth-info-required", num_attrs, + attrs)) != NULL) + cupsdSetAuthInfoRequired(job->printer, attr, NULL); + + cupsFreeOptions(num_attrs, attrs); } #ifdef __APPLE__ else if (!strncmp(message, "recoverable:", 12)) @@ -1853,6 +1850,9 @@ free_job(cupsd_job_t *job) /* I - Job */ { cupsdClearString(&job->username); cupsdClearString(&job->dest); +#ifdef HAVE_GSSAPI + cupsdClearString(&job->ccname); +#endif /* HAVE_GSSAPI */ if (job->num_files > 0) { @@ -1867,7 +1867,7 @@ free_job(cupsd_job_t *job) /* I - Job */ /* - * 'ipp_length()' - Compute the size of the buffer needed to hold + * 'ipp_length()' - Compute the size of the buffer needed to hold * the textual IPP attributes. */ @@ -2082,6 +2082,8 @@ load_job_cache(const char *filename) /* I - job.cache filename */ job->back_pipes[1] = -1; job->print_pipes[0] = -1; job->print_pipes[1] = -1; + job->side_pipes[0] = -1; + job->side_pipes[1] = -1; job->status_pipes[0] = -1; job->status_pipes[1] = -1; @@ -2337,6 +2339,8 @@ load_request_root(void) job->back_pipes[1] = -1; job->print_pipes[0] = -1; job->print_pipes[1] = -1; + job->side_pipes[0] = -1; + job->side_pipes[1] = -1; job->status_pipes[0] = -1; job->status_pipes[1] = -1; @@ -2388,7 +2392,7 @@ set_time(cupsd_job_t *job, /* I - Job to update */ * 'set_hold_until()' - Set the hold time and update job-hold-until attribute... */ -static void +static void set_hold_until(cupsd_job_t *job, /* I - Job to update */ time_t holdtime) /* I - Hold until time */ { @@ -2414,7 +2418,7 @@ set_hold_until(cupsd_job_t *job, /* I - Job to update */ */ holddate = gmtime(&holdtime); - snprintf(holdstr, sizeof(holdstr), "%d:%d:%d", holddate->tm_hour, + snprintf(holdstr, sizeof(holdstr), "%d:%d:%d", holddate->tm_hour, holddate->tm_min, holddate->tm_sec); if ((attr = ippFindAttribute(job->attrs, "job-hold-until", @@ -2445,8 +2449,10 @@ start_job(cupsd_job_t *job, /* I - Job ID */ { int i; /* Looping var */ int slot; /* Pipe slot */ - cups_array_t *filters; /* Filters for job */ + cups_array_t *filters, /* Filters for job */ + *prefilters; /* Filters with prefilters */ mime_filter_t *filter, /* Current filter */ + *prefilter, /* Prefilter */ port_monitor; /* Port monitor filter */ char method[255], /* Method for output */ *optptr, /* Pointer to options */ @@ -2466,7 +2472,7 @@ start_job(cupsd_job_t *job, /* I - Job ID */ title[IPP_MAX_NAME], /* Job title string */ copies[255], /* # copies string */ - *envp[MAX_ENV + 11], + *envp[MAX_ENV + 12], /* Environment variables */ charset[255], /* CHARSET env variable */ class_name[255],/* CLASS env variable */ @@ -2579,6 +2585,33 @@ start_job(cupsd_job_t *job, /* I - Job ID */ cupsArrayDelete(filters); filters = NULL; } + + /* + * If this printer has any pre-filters, insert the required pre-filter + * in the filters array... + */ + + if (printer->prefiltertype && filters) + { + prefilters = cupsArrayNew(NULL, NULL); + + for (filter = (mime_filter_t *)cupsArrayFirst(filters); + filter; + filter = (mime_filter_t *)cupsArrayNext(filters)) + { + if ((prefilter = mimeFilterLookup(MimeDatabase, filter->src, + printer->prefiltertype))) + { + cupsArrayAdd(prefilters, prefilter); + job->cost += prefilter->cost; + } + + cupsArrayAdd(prefilters, filter); + } + + cupsArrayDelete(filters); + filters = prefilters; + } } /* @@ -2707,6 +2740,18 @@ start_job(cupsd_job_t *job, /* I - Job ID */ fcntl(job->back_pipes[1], F_SETFL, fcntl(job->back_pipes[1], F_GETFL) | O_NONBLOCK); + + /* + * Create the side-channel pipes and make them non-blocking... + */ + + socketpair(AF_LOCAL, SOCK_STREAM, 0, job->side_pipes); + + fcntl(job->side_pipes[0], F_SETFL, + fcntl(job->side_pipes[0], F_GETFL) | O_NONBLOCK); + + fcntl(job->side_pipes[1], F_SETFL, + fcntl(job->side_pipes[1], F_GETFL) | O_NONBLOCK); } /* @@ -3083,6 +3128,11 @@ start_job(cupsd_job_t *job, /* I - Job ID */ envp[envc ++] = class_name; } +#ifdef HAVE_GSSAPI + if (job->ccname) + envp[envc ++] = job->ccname; +#endif /* HAVE_GSSAPI */ + envp[envc] = NULL; for (i = 0; i < envc; i ++) @@ -3115,19 +3165,19 @@ start_job(cupsd_job_t *job, /* I - Job ID */ strerror(errno)); snprintf(printer->state_message, sizeof(printer->state_message), "Unable to create status pipes - %s.", strerror(errno)); - + cupsdAddPrinterHistory(printer); - + cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, "Job canceled because the server could not create the job " "status pipes."); - + goto abort_job; } - + cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job: status_pipes = [ %d %d ]", job->status_pipes[0], job->status_pipes[1]); - + job->status_buffer = cupsdStatBufNew(job->status_pipes[0], "[Job %d]", job->id); } @@ -3244,7 +3294,8 @@ start_job(cupsd_job_t *job, /* I - Job ID */ pid = cupsdStartProcess(command, argv, envp, filterfds[!slot][0], filterfds[slot][1], job->status_pipes[1], - job->back_pipes[0], 0, job->filters + i); + job->back_pipes[0], job->side_pipes[0], 0, + job->filters + i); cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job: Closing filter pipes for slot %d " @@ -3314,8 +3365,8 @@ start_job(cupsd_job_t *job, /* I - Job ID */ pid = cupsdStartProcess(command, argv, envp, filterfds[!slot][0], filterfds[slot][1], job->status_pipes[1], - job->back_pipes[1], backroot, - &(job->backend)); + job->back_pipes[1], job->side_pipes[1], + backroot, &(job->backend)); if (pid == 0) { @@ -3353,6 +3404,12 @@ start_job(cupsd_job_t *job, /* I - Job ID */ cupsdClosePipe(job->back_pipes); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "start_job: Closing side pipes [ %d %d ]...", + job->side_pipes[0], job->side_pipes[1]); + + cupsdClosePipe(job->side_pipes); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job: Closing status output pipe %d...", job->status_pipes[1]); @@ -3397,11 +3454,8 @@ start_job(cupsd_job_t *job, /* I - Job ID */ free(argv); - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "start_job: Adding fd %d to InputSet...", - job->status_buffer->fd); - - FD_SET(job->status_buffer->fd, InputSet); + cupsdAddSelect(job->status_buffer->fd, (cupsd_selfunc_t)cupsdUpdateJob, NULL, + job); cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job, "Job #%d started.", job->id); @@ -3467,5 +3521,5 @@ unload_job(cupsd_job_t *job) /* I - Job */ /* - * End of "$Id: job.c 6234 2007-02-05 20:25:50Z mike $". + * End of "$Id: job.c 6318 2007-03-06 04:36:55Z mike $". */ diff --git a/scheduler/job.h b/scheduler/job.h index 5c1b540eb..4b8e399f1 100644 --- a/scheduler/job.h +++ b/scheduler/job.h @@ -1,5 +1,5 @@ /* - * "$Id: job.h 5970 2006-09-19 20:11:08Z mike $" + * "$Id: job.h 6170 2007-01-02 17:26:41Z mike $" * * Print job definitions for the Common UNIX Printing System (CUPS) scheduler. * @@ -46,6 +46,7 @@ typedef struct cupsd_job_s ipp_t *attrs; /* Job attributes */ int print_pipes[2], /* Print data pipes */ back_pipes[2], /* Backchannel pipes */ + side_pipes[2], /* Sidechannel pipes */ status_pipes[2];/* Status pipes */ cupsd_statbuf_t *status_buffer; /* Status buffer for this job */ int cost; /* Filtering cost */ @@ -55,6 +56,9 @@ typedef struct cupsd_job_s int status; /* Status code from filters */ cupsd_printer_t *printer; /* Printer this job is assigned to */ int tries; /* Number of tries for this job */ +#ifdef HAVE_GSSAPI + char *ccname; /* KRB5CCNAME environment variable */ +#endif /* HAVE_GSSAPI */ } cupsd_job_t; @@ -122,5 +126,5 @@ extern void cupsdUpdateJob(cupsd_job_t *job); /* - * End of "$Id: job.h 5970 2006-09-19 20:11:08Z mike $". + * End of "$Id: job.h 6170 2007-01-02 17:26:41Z mike $". */ diff --git a/scheduler/listen.c b/scheduler/listen.c index 2c5ad2bd7..258e292f7 100644 --- a/scheduler/listen.c +++ b/scheduler/listen.c @@ -1,5 +1,5 @@ /* - * "$Id: listen.c 5970 2006-09-19 20:11:08Z mike $" + * "$Id: listen.c 6123 2006-11-21 15:36:04Z mike $" * * Server listening routines for the Common UNIX Printing System (CUPS) * scheduler. @@ -90,14 +90,7 @@ cupsdPauseListening(void) for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); lis; lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) - if (lis->fd >= 0) - { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdPauseListening: Removing fd %d from InputSet...", - lis->fd); - - FD_CLR(lis->fd, InputSet); - } + cupsdRemoveSelect(lis->fd); } @@ -123,13 +116,7 @@ cupsdResumeListening(void) for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); lis; lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) - if (lis->fd >= 0) - { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdResumeListening: Adding fd %d to InputSet...", - lis->fd); - FD_SET(lis->fd, InputSet); - } + cupsdAddSelect(lis->fd, (cupsd_selfunc_t)cupsdAcceptClient, NULL, lis); } @@ -444,5 +431,5 @@ cupsdStopListening(void) /* - * End of "$Id: listen.c 5970 2006-09-19 20:11:08Z mike $". + * End of "$Id: listen.c 6123 2006-11-21 15:36:04Z mike $". */ diff --git a/scheduler/log.c b/scheduler/log.c index 3839dc878..11c3cbcfe 100644 --- a/scheduler/log.c +++ b/scheduler/log.c @@ -1,5 +1,5 @@ /* - * "$Id: log.c 6027 2006-10-11 21:04:58Z mike $" + * "$Id: log.c 6328 2007-03-12 14:45:42Z mike $" * * Log file routines for the Common UNIX Printing System (CUPS). * @@ -23,11 +23,12 @@ * * Contents: * - * cupsdGetDateTime() - Returns a pointer to a date/time string. - * cupsdLogMessage() - Log a message to the error log file. - * cupsdLogPage() - Log a page to the page log file. - * cupsdLogRequest() - Log an HTTP request in Common Log Format. - * check_log_file() - Open/rotate a log file if it needs it. + * cupsdGetDateTime() - Returns a pointer to a date/time string. + * cupsdLogGSSMessage() - Log a GSSAPI error... + * cupsdLogMessage() - Log a message to the error log file. + * cupsdLogPage() - Log a page to the page log file. + * cupsdLogRequest() - Log an HTTP request in Common Log Format. + * check_log_file() - Open/rotate a log file if it needs it. */ /* @@ -107,6 +108,56 @@ cupsdGetDateTime(time_t t) /* I - Time value */ } +#ifdef HAVE_GSSAPI +/* + * 'cupsdLogGSSMessage()' - Log a GSSAPI error... + */ + +int /* O - 1 on success, 0 on error */ +cupsdLogGSSMessage( + int level, /* I - Log level */ + int major_status, /* I - Major GSSAPI status */ + int minor_status, /* I - Minor GSSAPI status */ + const char *message, /* I - printf-style message string */ + ...) /* I - Additional args as needed */ +{ + OM_uint32 err_major_status, /* Major status code for display */ + err_minor_status; /* Minor status code for display */ + OM_uint32 msg_ctx; /* Message context */ + gss_buffer_desc major_status_string = GSS_C_EMPTY_BUFFER, + /* Major status message */ + minor_status_string = GSS_C_EMPTY_BUFFER; + /* Minor status message */ + int ret; /* Return value */ + + + msg_ctx = 0; + err_major_status = gss_display_status(&err_minor_status, + major_status, + GSS_C_GSS_CODE, + GSS_C_NO_OID, + &msg_ctx, + &major_status_string); + + if (!GSS_ERROR(err_major_status)) + err_major_status = gss_display_status(&err_minor_status, + minor_status, + GSS_C_MECH_CODE, + GSS_C_NULL_OID, + &msg_ctx, + &minor_status_string); + + ret = cupsdLogMessage(level, "%s: %s, %s", message, + (char *)major_status_string.value, + (char *)minor_status_string.value); + gss_release_buffer(&err_minor_status, &major_status_string); + gss_release_buffer(&err_minor_status, &minor_status_string); + + return (ret); +} +#endif /* HAVE_GSSAPI */ + + /* * 'cupsdLogMessage()' - Log a message to the error log file. */ @@ -414,9 +465,10 @@ static int /* O - 1 if log file open */ check_log_file(cups_file_t **lf, /* IO - Log file */ const char *logname) /* I - Log filename */ { - char backname[1024], /* Backup log filename */ - filename[1024], /* Formatted log filename */ - *ptr; /* Pointer into filename */ + char backname[1024], /* Backup log filename */ + filename[1024], /* Formatted log filename */ + *ptr; /* Pointer into filename */ + const char *logptr; /* Pointer into log filename */ /* @@ -448,17 +500,17 @@ check_log_file(cups_file_t **lf, /* IO - Log file */ else filename[0] = '\0'; - for (ptr = filename + strlen(filename); - *logname && ptr < (filename + sizeof(filename) - 1); - logname ++) - if (*logname == '%') + for (logptr = logname, ptr = filename + strlen(filename); + *logptr && ptr < (filename + sizeof(filename) - 1); + logptr ++) + if (*logptr == '%') { /* * Format spec... */ - logname ++; - if (*logname == 's') + logptr ++; + if (*logptr == 's') { /* * Insert the server name... @@ -473,11 +525,11 @@ check_log_file(cups_file_t **lf, /* IO - Log file */ * Otherwise just insert the character... */ - *ptr++ = *logname; + *ptr++ = *logptr; } } else - *ptr++ = *logname; + *ptr++ = *logptr; *ptr = '\0'; } @@ -551,5 +603,5 @@ check_log_file(cups_file_t **lf, /* IO - Log file */ /* - * End of "$Id: log.c 6027 2006-10-11 21:04:58Z mike $". + * End of "$Id: log.c 6328 2007-03-12 14:45:42Z mike $". */ diff --git a/scheduler/main.c b/scheduler/main.c index 434cacf89..8591cc0f3 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -1,9 +1,9 @@ /* - * "$Id: main.c 6090 2006-11-14 16:35:27Z mike $" + * "$Id: main.c 6326 2007-03-11 17:50:18Z mike $" * * Scheduler main loop for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -32,10 +32,9 @@ * cupsdSetStringf() - Set a formatted string value. * launchd_checkin() - Check-in with launchd and collect the * listening fds. + * launchd_checkout() - Check-out with launchd. * launchd_create_dict() - Create a dictionary representing the launchd * config file org.cups.cupsd.plist. - * launchd_reload() - Tell launchd to reload the configuration - * file to pick up the new listening directives. * launchd_sync_conf() - Re-write the launchd config file * org.cups.cupsd.plist based on cupsd.conf. * parent_handler() - Catch USR1/CHLD signals... @@ -62,6 +61,17 @@ #ifdef HAVE_LAUNCH_H # include # include +# define CUPS_KEEPALIVE CUPS_STATEDIR "/org.cups.cupsd" + /* Name of the launchd KeepAlive file */ +# ifndef LAUNCH_JOBKEY_KEEPALIVE +# define LAUNCH_JOBKEY_KEEPALIVE "KeepAlive" +# endif /* !LAUNCH_JOBKEY_KEEPALIVE */ +# ifndef LAUNCH_JOBKEY_PATHSTATE +# define LAUNCH_JOBKEY_PATHSTATE "PathState" +# endif /* !LAUNCH_JOBKEY_PATHSTATE */ +# ifndef LAUNCH_JOBKEY_SERVICEIPC +# define LAUNCH_JOBKEY_SERVICEIPC "ServiceIPC" +# endif /* !LAUNCH_JOBKEY_SERVICEIPC */ #endif /* HAVE_LAUNCH_H */ #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO) @@ -78,8 +88,8 @@ #ifdef HAVE_LAUNCHD static void launchd_checkin(void); +static void launchd_checkout(void); static CFDictionaryRef launchd_create_dict(void); -static void launchd_reload(void); static int launchd_sync_conf(void); #endif /* HAVE_LAUNCHD */ static void parent_handler(int sig); @@ -126,8 +136,6 @@ main(int argc, /* I - Number of command-line args */ char *opt; /* Option character */ int fg; /* Run in the foreground */ int fds; /* Number of ready descriptors */ - fd_set *input, /* Input set for select() */ - *output; /* Output set for select() */ cupsd_client_t *con; /* Current client */ cupsd_job_t *job; /* Current job */ cupsd_listener_t *lis; /* Current listener */ @@ -136,14 +144,11 @@ main(int argc, /* I - Number of command-line args */ browse_time, /* Next browse send time */ senddoc_time, /* Send-Document time */ expire_time, /* Subscription expire time */ -#ifndef __APPLE__ - netif_time, /* Network interface poll time */ -#endif /* !__APPLE__ */ mallinfo_time; /* Malloc information time */ size_t string_count, /* String count */ alloc_bytes, /* Allocated string bytes */ total_bytes; /* Total string bytes */ - struct timeval timeout; /* select() timeout */ + long timeout; /* Timeout for cupsdDoSelect() */ struct rlimit limit; /* Runtime limit */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ @@ -372,33 +377,23 @@ main(int argc, /* I - Number of command-line args */ getrlimit(RLIMIT_NOFILE, &limit); +#if !defined(HAVE_POLL) && !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE) if (limit.rlim_max > FD_SETSIZE) MaxFDs = FD_SETSIZE; else +#endif /* !HAVE_POLL && !HAVE_EPOLL && !HAVE_KQUEUE */ +#ifdef RLIM_INFINITY + if (limit.rlim_max == RLIM_INFINITY) + MaxFDs = 16384; + else +#endif /* RLIM_INFINITY */ MaxFDs = limit.rlim_max; limit.rlim_cur = MaxFDs; setrlimit(RLIMIT_NOFILE, &limit); - /* - * Allocate memory for the input and output sets... - */ - - SetSize = (MaxFDs + 31) / 8 + 4; - if (SetSize < sizeof(fd_set)) - SetSize = sizeof(fd_set); - - InputSet = (fd_set *)calloc(1, SetSize); - OutputSet = (fd_set *)calloc(1, SetSize); - input = (fd_set *)calloc(1, SetSize); - output = (fd_set *)calloc(1, SetSize); - - if (InputSet == NULL || OutputSet == NULL || input == NULL || output == NULL) - { - syslog(LOG_LPR, "Unable to allocate memory for select() sets - exiting!"); - return (1); - } + cupsdStartSelect(); /* * Read configuration... @@ -415,22 +410,15 @@ main(int argc, /* I - Number of command-line args */ if (Launchd) { /* - * If we were started by launchd make sure the cupsd plist file contains the - * same listeners as cupsd.conf; If it didn't then reload it before getting - * the list of listening file descriptors... + * If we were started by launchd, make sure the cupsd plist file contains + * the same listeners as cupsd.conf. */ - if (launchd_sync_conf()) - { - launchd_reload(); - - /* - * Until rdar://3854821 is fixed we have to exit after the reload... - */ + launchd_sync_conf(); - cupsdLogMessage(CUPSD_LOG_DEBUG2, "Exiting on launchd_reload"); - exit(0); - } + /* + * Then get the file descriptors from launchd... + */ launchd_checkin(); } @@ -551,9 +539,6 @@ main(int argc, /* I - Number of command-line args */ senddoc_time = time(NULL); expire_time = time(NULL); fds = 1; -#ifndef __APPLE__ - netif_time = 0; -#endif /* !__APPLE__ */ while (!stop_scheduler) { @@ -632,19 +617,7 @@ main(int argc, /* I - Number of command-line args */ #if HAVE_LAUNCHD if (Launchd) { - if (launchd_sync_conf()) - { - launchd_reload(); - - /* - * Until rdar://3854821 is fixed we have to exit after the reload... - */ - - cupsdLogMessage(CUPSD_LOG_DEBUG2, "Exiting on launchd_reload"); - stop_scheduler = 1; - break; - } - + launchd_sync_conf(); launchd_checkin(); } #endif /* HAVE_LAUNCHD */ @@ -658,18 +631,15 @@ main(int argc, /* I - Number of command-line args */ } /* - * Check for available input or ready output. If select() returns - * 0 or -1, something bad happened and we should exit immediately. + * Check for available input or ready output. If cupsdDoSelect() + * returns 0 or -1, something bad happened and we should exit + * immediately. * * Note that we at least have one listening socket open at all * times. */ - memcpy(input, InputSet, SetSize); - memcpy(output, OutputSet, SetSize); - - timeout.tv_sec = select_timeout(fds); - timeout.tv_usec = 0; + timeout = select_timeout(fds); #if HAVE_LAUNCHD /* @@ -678,71 +648,40 @@ main(int argc, /* I - Number of command-line args */ * inactivity... */ - if (timeout.tv_sec == 86400 && Launchd && LaunchdTimeout && !NumPolled && - (!Browsing || !(BrowseLocalProtocols & BROWSE_DNSSD) || - cupsArrayCount(Printers) == 0)) + if (timeout == 86400 && Launchd && LaunchdTimeout && !NumPolled && + (!Browsing || + (!BrowseRemoteProtocols && + (!NumBrowsers || !BrowseLocalProtocols || + cupsArrayCount(Printers) == 0)))) { - timeout.tv_sec = LaunchdTimeout; + timeout = LaunchdTimeout; launchd_idle_exit = 1; } else launchd_idle_exit = 0; #endif /* HAVE_LAUNCHD */ - if (timeout.tv_sec < 86400) /* Only use timeout for < 1 day */ - fds = select(MaxFDs, input, output, NULL, &timeout); - else - fds = select(MaxFDs, input, output, NULL, NULL); - - if (fds < 0) + if ((fds = cupsdDoSelect(timeout)) < 0) { - char s[16384], /* String buffer */ - *sptr; /* Pointer into buffer */ - int slen; /* Length of string buffer */ - - /* * Got an error from select! */ - if (errno == EINTR) /* Just interrupted by a signal */ +#ifdef HAVE_DNSSD + cupsd_printer_t *p; /* Current printer */ +#endif /* HAVE_DNSSD */ + + + if (errno == EINTR) /* Just interrupted by a signal */ continue; /* * Log all sorts of debug info to help track down the problem. */ - cupsdLogMessage(CUPSD_LOG_EMERG, "select() failed - %s!", + cupsdLogMessage(CUPSD_LOG_EMERG, "cupsdDoSelect() failed - %s!", strerror(errno)); - strcpy(s, "InputSet ="); - slen = 10; - sptr = s + 10; - - for (i = 0; i < MaxFDs; i ++) - if (FD_ISSET(i, InputSet)) - { - snprintf(sptr, sizeof(s) - slen, " %d", i); - slen += strlen(sptr); - sptr += strlen(sptr); - } - - cupsdLogMessage(CUPSD_LOG_EMERG, "%s", s); - - strcpy(s, "OutputSet ="); - slen = 11; - sptr = s + 11; - - for (i = 0; i < MaxFDs; i ++) - if (FD_ISSET(i, OutputSet)) - { - snprintf(sptr, sizeof(s) - slen, " %d", i); - slen += strlen(sptr); - sptr += strlen(sptr); - } - - cupsdLogMessage(CUPSD_LOG_EMERG, "%s", s); - for (i = 0, con = (cupsd_client_t *)cupsArrayFirst(Clients); con; i ++, con = (cupsd_client_t *)cupsArrayNext(Clients)) @@ -772,6 +711,15 @@ main(int argc, /* I - Number of command-line args */ job->status_buffer ? job->status_buffer->fd : -1, job->print_pipes[0], job->print_pipes[1], job->back_pipes[0], job->back_pipes[1]); + +#ifdef HAVE_DNSSD + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + cupsdLogMessage(CUPSD_LOG_EMERG, "printer[%s] %d", p->name, + p->dnssd_ipp_fd); +#endif /* HAVE_DNSSD */ + break; } @@ -793,67 +741,6 @@ main(int argc, /* I - Number of command-line args */ } #endif /* HAVE_LAUNCHD */ - /* - * Check for status info from job filters... - */ - - for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); - job; - job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) - if (job->status_buffer && FD_ISSET(job->status_buffer->fd, input)) - { - /* - * Clear the input bit to avoid updating the next job - * using the same status pipe file descriptor... - */ - - FD_CLR(job->status_buffer->fd, input); - - /* - * Read any status messages from the filters... - */ - - cupsdUpdateJob(job); - } - - /* - * Update CGI messages as needed... - */ - - if (CGIPipes[0] >= 0 && FD_ISSET(CGIPipes[0], input)) - cupsdUpdateCGI(); - - /* - * Handle system management events as needed... - */ - -#ifdef __APPLE__ - /* - * Mac OS X provides the SystemConfiguration framework for system - * configuration change events... - */ - - if (SysEventPipes[0] >= 0 && FD_ISSET(SysEventPipes[0], input)) - cupsdUpdateSystemMonitor(); -#else - /* - * All other operating systems need to poll for changes... - */ - - if ((current_time - netif_time) >= 60) - { - NetIFUpdate = 1; - netif_time = current_time; - } -#endif /* __APPLE__ */ - - /* - * Update notifier messages as needed... - */ - - if (NotifierPipes[0] >= 0 && FD_ISSET(NotifierPipes[0], input)) - cupsdUpdateNotifierStatus(); - /* * Expire subscriptions and unload completed jobs as needed... */ @@ -872,14 +759,8 @@ main(int argc, /* I - Number of command-line args */ * Update the browse list as needed... */ - if (Browsing && BrowseRemoteProtocols) + if (Browsing) { - if (BrowseSocket >= 0 && FD_ISSET(BrowseSocket, input)) - cupsdUpdateCUPSBrowse(); - - if (PollPipe >= 0 && FD_ISSET(PollPipe, input)) - cupsdUpdatePolling(); - #ifdef HAVE_LIBSLP if ((BrowseRemoteProtocols & BROWSE_SLP) && BrowseSLPRefresh <= current_time) @@ -900,17 +781,20 @@ main(int argc, /* I - Number of command-line args */ } /* - * Check for new connections on the "listen" sockets... + * Update the root certificate once every 5 minutes if we have client + * connections... */ - for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); - lis; - lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) - if (lis->fd >= 0 && FD_ISSET(lis->fd, input)) - { - FD_CLR(lis->fd, input); - cupsdAcceptClient(lis); - } + if ((current_time - RootCertTime) >= RootCertDuration && RootCertDuration && + !RunUser && cupsArrayCount(Clients)) + { + /* + * Update the root certificate... + */ + + cupsdDeleteCert(0); + cupsdAddCert(0, "root"); + } /* * Check for new data on the client sockets... @@ -921,61 +805,13 @@ main(int argc, /* I - Number of command-line args */ con = (cupsd_client_t *)cupsArrayNext(Clients)) { /* - * Process the input buffer... - */ - - if (FD_ISSET(con->http.fd, input) || con->http.used) - { - int fd = con->file; - - - FD_CLR(con->http.fd, input); - - if (!cupsdReadClient(con)) - { - if (fd >= 0) - FD_CLR(fd, input); - - continue; - } - } - - /* - * Write data as needed... + * Process pending data in the input buffer... */ - if (con->pipe_pid && FD_ISSET(con->file, input)) - { - /* - * Keep track of pending input from the file/pipe separately - * so that we don't needlessly spin on select() when the web - * client is not ready to receive data... - */ - - FD_CLR(con->file, input); - con->file_ready = 1; - -#ifdef DEBUG - cupsdLogMessage(CUPSD_LOG_DEBUG2, "main: Data ready file %d!", - con->file); -#endif /* DEBUG */ - - if (!FD_ISSET(con->http.fd, output)) - { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "main: Removing fd %d from InputSet...", con->file); - FD_CLR(con->file, input); - FD_CLR(con->file, InputSet); - } - } - - if (FD_ISSET(con->http.fd, output)) + if (con->http.used) { - FD_CLR(con->http.fd, output); - - if (!con->pipe_pid || con->file_ready) - if (!cupsdWriteClient(con)) - continue; + cupsdReadClient(con); + continue; } /* @@ -1031,22 +867,6 @@ main(int argc, /* I - Number of command-line args */ mallinfo_time = current_time; } - /* - * Update the root certificate once every 5 minutes if we have client - * connections... - */ - - if ((current_time - RootCertTime) >= RootCertDuration && RootCertDuration && - !RunUser && cupsArrayCount(Clients)) - { - /* - * Update the root certificate... - */ - - cupsdDeleteCert(0); - cupsdAddCert(0, "root"); - } - /* * Handle OS-specific event notification for any events that have * accumulated. Don't send these more than once a second... @@ -1114,13 +934,17 @@ main(int argc, /* I - Number of command-line args */ * Update the launchd config file as needed... */ - launchd_sync_conf(); + if (Launchd) + { + launchd_checkout(); + launchd_sync_conf(); - if (launchd_conf_url) - CFRelease(launchd_conf_url); + if (launchd_conf_url) + CFRelease(launchd_conf_url); - if (launchd_conf_dict) - CFRelease(launchd_conf_dict); + if (launchd_conf_dict) + CFRelease(launchd_conf_dict); + } #endif /* HAVE_LAUNCHD */ #ifdef __sgi @@ -1135,14 +959,7 @@ main(int argc, /* I - Number of command-line args */ unlink("/var/spool/lp/SCHEDLOCK"); #endif /* __sgi */ - /* - * Free memory used by FD sets and return... - */ - - free(InputSet); - free(OutputSet); - free(input); - free(output); + cupsdStopSelect(); return (!stop_scheduler); } @@ -1364,6 +1181,8 @@ launchd_checkin(void) cupsd_listener_t *lis; /* Listeners array */ http_addr_t addr; /* Address variable */ socklen_t addrlen; /* Length of address */ + int fd; /* File descriptor */ + char s[256]; /* String addresss */ cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: pid=%d", (int)getpid()); @@ -1417,56 +1236,77 @@ launchd_checkin(void) if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY) { - /* - * Free the listeners array built from cupsd.conf... - */ - - cupsdDeleteAllListeners(); - - /* - * Create a new array of listeners from the launchd data... - */ - - Listeners = cupsArrayNew(NULL, NULL); - count = launch_data_array_get_count(ld_array); + count = launch_data_array_get_count(ld_array); for (i = 0; i < count; i ++) { /* - * Copy the current address and log it... + * Get the launchd file descriptor and address... */ - if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL) + tmp = launch_data_array_get_index(ld_array, i); + fd = launch_data_get_fd(tmp); + addrlen = sizeof(addr); + + if (getsockname(fd, (struct sockaddr *)&addr, &addrlen)) { cupsdLogMessage(CUPSD_LOG_ERROR, - "launchd_checkin: Unable to allocate listener - %s.", - strerror(errno)); - exit(EXIT_FAILURE); + "launchd_checkin: Unable to get local address - %s", + strerror(errno)); + continue; } - cupsArrayAdd(Listeners, lis); + /* + * Try to match the launchd socket address to one of the listeners... + */ - tmp = launch_data_array_get_index(ld_array, i); - lis->fd = launch_data_get_fd(tmp); - addrlen = sizeof(lis->address); + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + if (httpAddrEqual(&lis->address, &addr)) + break; + + /* + * Add a new listener If there's no match... + */ - if (getsockname(lis->fd, (struct sockaddr *)&(lis->address), &addrlen)) + if (lis) { - cupsdLogMessage(CUPSD_LOG_ERROR, - "launchd_checkin: Unable to get local address - %s", - strerror(errno)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "launchd_checkin: Matched existing listener %s with fd %d...", + httpAddrString(&(lis->address), s, sizeof(s)), fd); + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "launchd_checkin: Adding new listener %s with fd %d...", + httpAddrString(&addr, s, sizeof(s)), fd); + + if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "launchd_checkin: Unable to allocate listener - %s.", + strerror(errno)); + exit(EXIT_FAILURE); + } + + cupsArrayAdd(Listeners, lis); + + memcpy(&lis->address, &addr, sizeof(lis->address)); } + lis->fd = fd; + # ifdef HAVE_SSL portnum = 0; # ifdef AF_INET6 - if (addr.addr.sa_family == AF_INET6) - portnum = ntohs(addr.ipv6.sin6_port); + if (lis->address.addr.sa_family == AF_INET6) + portnum = ntohs(lis->address.ipv6.sin6_port); else # endif /* AF_INET6 */ - if (addr.addr.sa_family == AF_INET) - portnum = ntohs(addr.ipv4.sin_port); + if (lis->address.addr.sa_family == AF_INET) + portnum = ntohs(lis->address.ipv4.sin_port); if (portnum == 443) lis->encryption = HTTP_ENCRYPT_ALWAYS; @@ -1511,6 +1351,43 @@ launchd_checkin(void) } +/* + * 'launchd_checkout()' - Update the launchd KeepAlive file as needed. + */ + +static void +launchd_checkout(void) +{ + int fd; /* File descriptor */ + + + /* + * Create or remove the launchd KeepAlive file based on whether + * there are active jobs, polling, browsing for remote printers or + * shared printers to advertise... + */ + + if ((cupsArrayCount(ActiveJobs) || NumPolled || + (Browsing && + (BrowseRemoteProtocols || + (BrowseLocalProtocols && NumBrowsers && cupsArrayCount(Printers)))))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Creating launchd keepalive file \"" CUPS_KEEPALIVE "\"..."); + + if ((fd = open(CUPS_KEEPALIVE, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR)) >= 0) + close(fd); + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Removing launchd keepalive file \"" CUPS_KEEPALIVE "\"..."); + + unlink(CUPS_KEEPALIVE); + } +} + + /* * 'launchd_create_dict()' - Create a dictionary representing the launchd * config file org.cups.cupsd.plist. @@ -1519,24 +1396,26 @@ launchd_checkin(void) static CFDictionaryRef /* O - CFDictionary */ launchd_create_dict(void) { - int portnum; /* Port number */ - bool runatload; /* Run at load? */ - CFMutableDictionaryRef cupsd_dict, /* org.cups.cupsd.plist dictionary */ - sockets, /* Sockets dictionary */ - listener; /* Listener dictionary */ - CFMutableArrayRef array; /* Array */ - CFNumberRef socket_mode; /* Domain socket mode bits */ - CFStringRef socket_path; /* Domain socket path */ - CFTypeRef value; /* CF values */ - cupsd_listener_t *lis; /* Current listening socket */ - struct servent *service; /* Services data base entry */ - char temp[1024]; /* Temporary buffer for value */ + int portnum; /* Port number */ + bool runatload; /* Run at load? */ + CFMutableDictionaryRef cupsd_dict, /* org.cups.cupsd.plist dictionary */ + keepalive, /* KeepAlive dictionary */ + pathstate, /* PathState dictionary */ + sockets, /* Sockets dictionary */ + listener; /* Listener dictionary */ + CFMutableArrayRef array; /* Array */ + CFNumberRef socket_mode; /* Domain socket mode bits */ + CFStringRef socket_path; /* Domain socket path */ + CFTypeRef value; /* CF values */ + cupsd_listener_t *lis; /* Current listening socket */ + struct servent *service; /* Services data base entry */ + char temp[1024]; /* Temporary buffer for value */ if ((cupsd_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)) == NULL) - return NULL; + return (NULL); CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_LABEL), CFSTR("org.cups.cupsd")); @@ -1544,20 +1423,35 @@ launchd_create_dict(void) kCFBooleanTrue); /* - * Run-at-load if there are active jobs, polling or shared printers - * to advertise... + * Use run-at-load and/or KeepAlive if there are active jobs, polling or + * shared printers to advertise... */ - + + if ((keepalive = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)) != NULL) + { + if ((pathstate = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks)) != NULL) + { + CFDictionaryAddValue(pathstate, CFSTR(CUPS_KEEPALIVE), kCFBooleanTrue); + CFDictionaryAddValue(keepalive, CFSTR(LAUNCH_JOBKEY_PATHSTATE), + pathstate); + } + + CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_KEEPALIVE), + keepalive); + } + runatload = (cupsArrayCount(ActiveJobs) || NumPolled || (Browsing && BrowseLocalProtocols && NumBrowsers && cupsArrayCount(Printers))) ? true : false; CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_RUNATLOAD), runatload ? kCFBooleanTrue : kCFBooleanFalse); -# ifdef LAUNCH_JOBKEY_SERVICEIPC CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_SERVICEIPC), kCFBooleanTrue); -# endif /* LAUNCH_JOBKEY_SERVICEIPC */ if ((array = CFArrayCreateMutable(kCFAllocatorDefault, 2, &kCFTypeArrayCallBacks)) != NULL) @@ -1727,106 +1621,6 @@ launchd_create_dict(void) } -/* - * 'launchd_reload()' - Tell launchd to reload the configuration file to pick - * up the new listening directives. - */ - -static void -launchd_reload(void) -{ - int child_status; /* Exit status of child process */ - pid_t child_pid, /* Child PID */ - waitpid_status; /* Child process exit status */ - char *argv[4]; /* Argument strings */ - - - /* - * The current launchd doesn't support a reload option (rdar://3854821). - * Until this is fixed we need to reload the config file by execing launchctl - * twice (to unload then load). NOTE: This will cause us to exit on SIGTERM - * which will cancel all client & job activity. - * - * After this is fixed we'll be able to tell launchd to reload the file - * and pick up the new listening descriptors without disrupting current - * activity. - */ - - /* - * Unloading the current configuration will cause launchd to send us a SIGTERM; - * block it for now so we can get our work done... - */ - - cupsdHoldSignals(); - - /* - * Set up the unload arguments to launchctl... - */ - - argv[0] = "/bin/launchctl"; - argv[1] = "unload"; - argv[2] = LaunchdConf; - argv[3] = NULL; - - if (cupsdStartProcess(argv[0], argv, NULL, -1, -1, -1, -1, 1, &child_pid) < 0) - cupsdLogMessage(CUPSD_LOG_ERROR, - "launchd_reload: Unable to execute %s - %s", argv[0], - strerror(errno)); - else - { - do - { - waitpid_status = waitpid(child_pid, &child_status, 0); - } - while (waitpid_status == (pid_t)-1 && errno == EINTR); - - if (WIFSIGNALED(child_status)) - cupsdLogMessage(CUPSD_LOG_DEBUG, - "launchd_reload: %s pid %d crashed on signal %d!", - basename(argv[0]), child_pid, WTERMSIG(child_status)); - else - cupsdLogMessage(CUPSD_LOG_DEBUG, - "launchd_reload: %s pid %d stopped with status %d!", - basename(argv[0]), child_pid, WEXITSTATUS(child_status)); - - /* - * Do it again with the load command... - */ - - argv[1] = "load"; - - if (cupsdStartProcess(argv[0], argv, NULL, -1, -1, -1, -1, 1, - &child_pid) < 0) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "launchd_reload: Unable to fork for %s - %s", argv[0], - strerror(errno)); - } - else - { - do - { - waitpid_status = waitpid(child_pid, &child_status, 0); - } while (waitpid_status == (pid_t)-1 && errno == EINTR); - - if (WIFSIGNALED(child_status)) - cupsdLogMessage(CUPSD_LOG_DEBUG, - "launchd_reload: %s pid %d crashed on signal %d!", - basename(argv[0]), child_pid, WTERMSIG(child_status)); - else - cupsdLogMessage(CUPSD_LOG_DEBUG, - "launchd_reload: %s pid %d stopped with status %d", - basename(argv[0]), child_pid, - WEXITSTATUS(child_status)); - } - } - - /* - * Leave signals blocked since exit() will be called momentarily anyways... - */ -} - - /* * 'launchd_sync_conf()' - Rewrite the launchd config file * org.cups.cupsd.plist based on cupsd.conf. @@ -1890,7 +1684,7 @@ launchd_sync_conf(void) if (!CFEqual(cupsd_dict, launchd_conf_dict)) { if ((resourceData = CFPropertyListCreateXMLData(kCFAllocatorDefault, - cupsd_dict))) + cupsd_dict))) { if (CFURLWriteDataAndPropertiesToResource(launchd_conf_url, resourceData, NULL, &errorCode)) @@ -2174,12 +1968,12 @@ select_timeout(int fds) /* I - Number of descriptors returned */ return (0); /* - * If select has been active in the last second (fds != 0) or we have + * If select has been active in the last second (fds > 0) or we have * many resources in use then don't bother trying to optimize the * timeout, just make it 1 second. */ - if (fds || cupsArrayCount(Clients) > 50) + if (fds > 0 || cupsArrayCount(Clients) > 50) return (1); /* @@ -2225,7 +2019,7 @@ select_timeout(int fds) /* I - Number of descriptors returned */ } #endif /* HAVE_LDAP */ - if (BrowseLocalProtocols & BROWSE_CUPS) + if ((BrowseLocalProtocols & BROWSE_CUPS) && NumBrowsers) { for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; @@ -2239,7 +2033,7 @@ select_timeout(int fds) /* I - Number of descriptors returned */ why = "browse timeout a printer"; } } - else if (!(p->type & CUPS_PRINTER_IMPLICIT)) + else if (p->shared && !(p->type & CUPS_PRINTER_IMPLICIT)) { if (BrowseInterval && (p->browse_time + BrowseInterval) < timeout) { @@ -2313,8 +2107,8 @@ select_timeout(int fds) /* I - Number of descriptors returned */ * Log and return the timeout value... */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "select_timeout: %ld seconds to %s", - timeout, why); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "select_timeout(%d): %ld seconds to %s", + fds, timeout, why); return (timeout); } @@ -2340,5 +2134,5 @@ usage(int status) /* O - Exit status */ /* - * End of "$Id: main.c 6090 2006-11-14 16:35:27Z mike $". + * End of "$Id: main.c 6326 2007-03-11 17:50:18Z mike $". */ diff --git a/scheduler/mime.c b/scheduler/mime.c index 2e98d0b3f..052b42922 100644 --- a/scheduler/mime.c +++ b/scheduler/mime.c @@ -1,5 +1,5 @@ /* - * "$Id: mime.c 5606 2006-05-30 19:40:34Z mike $" + * "$Id: mime.c 5605 2006-05-30 19:38:02Z mike $" * * MIME database file routines for the Common UNIX Printing System (CUPS). * @@ -738,5 +738,5 @@ load_types(mime_t *mime, /* I - MIME database */ /* - * End of "$Id: mime.c 5606 2006-05-30 19:40:34Z mike $". + * End of "$Id: mime.c 5605 2006-05-30 19:38:02Z mike $". */ diff --git a/scheduler/mime.h b/scheduler/mime.h index 2b44bf121..16e9a3d7c 100644 --- a/scheduler/mime.h +++ b/scheduler/mime.h @@ -1,9 +1,9 @@ /* - * "$Id: mime.h 5771 2006-07-20 18:06:20Z mike $" + * "$Id: mime.h 6252 2007-02-10 15:34:18Z mike $" * * MIME type/conversion database definitions for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -143,6 +143,8 @@ extern mime_filter_t *mimeAddFilter(mime_t *mime, mime_type_t *src, extern void mimeDeleteFilter(mime_t *mime, mime_filter_t *filter); extern cups_array_t *mimeFilter(mime_t *mime, mime_type_t *src, mime_type_t *dst, int *cost); +extern mime_filter_t *mimeFilterLookup(mime_t *mime, mime_type_t *src, + mime_type_t *dst); extern mime_filter_t *mimeFirstFilter(mime_t *mime); extern mime_filter_t *mimeNextFilter(mime_t *mime); extern int mimeNumFilters(mime_t *mime); @@ -153,5 +155,5 @@ extern int mimeNumFilters(mime_t *mime); #endif /* !_CUPS_MIME_H_ */ /* - * End of "$Id: mime.h 5771 2006-07-20 18:06:20Z mike $". + * End of "$Id: mime.h 6252 2007-02-10 15:34:18Z mike $". */ diff --git a/scheduler/network.c b/scheduler/network.c index e63d4f44e..b7057d7b4 100644 --- a/scheduler/network.c +++ b/scheduler/network.c @@ -1,5 +1,5 @@ /* - * "$Id: network.c 6090 2006-11-14 16:35:27Z mike $" + * "$Id: network.c 6086 2006-11-14 15:43:55Z mike $" * * Network interface functions for the Common UNIX Printing System * (CUPS) scheduler. @@ -314,5 +314,5 @@ compare_netif(cupsd_netif_t *a, /* I - First network interface */ /* - * End of "$Id: network.c 6090 2006-11-14 16:35:27Z mike $". + * End of "$Id: network.c 6086 2006-11-14 15:43:55Z mike $". */ diff --git a/scheduler/network.h b/scheduler/network.h index 5d8c83f8a..c26e8dbb2 100644 --- a/scheduler/network.h +++ b/scheduler/network.h @@ -1,5 +1,5 @@ /* - * "$Id: network.h 6090 2006-11-14 16:35:27Z mike $" + * "$Id: network.h 6086 2006-11-14 15:43:55Z mike $" * * Network interface definitions for the Common UNIX Printing System * (CUPS) scheduler. @@ -57,5 +57,5 @@ extern void cupsdNetIFUpdate(void); /* - * End of "$Id: network.h 6090 2006-11-14 16:35:27Z mike $". + * End of "$Id: network.h 6086 2006-11-14 15:43:55Z mike $". */ diff --git a/scheduler/policy.c b/scheduler/policy.c index 606978e3e..668bbff6f 100644 --- a/scheduler/policy.c +++ b/scheduler/policy.c @@ -1,5 +1,5 @@ /* - * "$Id: policy.c 5838 2006-08-17 14:41:42Z mike $" + * "$Id: policy.c 5837 2006-08-17 14:37:40Z mike $" * * Policy routines for the Common UNIX Printing System (CUPS). * @@ -330,5 +330,5 @@ cupsdFindPolicyOp(cupsd_policy_t *p, /* I - Policy */ /* - * End of "$Id: policy.c 5838 2006-08-17 14:41:42Z mike $". + * End of "$Id: policy.c 5837 2006-08-17 14:37:40Z mike $". */ diff --git a/scheduler/printers.c b/scheduler/printers.c index 936c9d0be..9a33a2221 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -1,9 +1,9 @@ /* - * "$Id: printers.c 5970 2006-09-19 20:11:08Z mike $" + * "$Id: printers.c 6318 2007-03-06 04:36:55Z mike $" * * Printer routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -70,7 +70,8 @@ */ static void add_printer_defaults(cupsd_printer_t *p); -static void add_printer_filter(cupsd_printer_t *p, const char *filter); +static void add_printer_filter(cupsd_printer_t *p, mime_type_t *type, + const char *filter); static void add_printer_formats(cupsd_printer_t *p); static int compare_printers(void *first, void *second, void *data); static void delete_printer_filters(cupsd_printer_t *p); @@ -412,10 +413,6 @@ cupsdCreateCommonData(void) /* copies-supported */ ippAddRange(CommonData, IPP_TAG_PRINTER, "copies-supported", 1, MaxCopies); - /* document-format-default */ - ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE, - "document-format-default", NULL, "application/octet-stream"); - /* generated-natural-language-supported */ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE, "generated-natural-language-supported", NULL, DefaultLanguage); @@ -495,10 +492,6 @@ cupsdCreateCommonData(void) (int)(sizeof(notify_attrs) / sizeof(notify_attrs[0])), NULL, notify_attrs); - /* notify-lease-duration-default */ - ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "notify-lease-duration-default", DefaultLeaseDuration); - /* notify-lease-duration-supported */ ippAddRange(CommonData, IPP_TAG_PRINTER, "notify-lease-duration-supported", 0, @@ -508,10 +501,6 @@ cupsdCreateCommonData(void) ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "notify-max-events-supported", MaxEvents); - /* notify-events-default */ - ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, - "notify-events-default", NULL, "job-completed"); - /* notify-events-supported */ ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "notify-events-supported", @@ -703,13 +692,18 @@ cupsdDeletePrinter( } /* - * Remove this printer from any classes and send a browse delete message... + * Remove this printer from any classes... */ if (!(p->type & CUPS_PRINTER_IMPLICIT)) { cupsdDeletePrinterFromClasses(p); - cupsdSendBrowseDelete(p); + + /* + * Deregister from any browse protocols... + */ + + cupsdDeregisterPrinter(p, 1); } /* @@ -735,6 +729,7 @@ cupsdDeletePrinter( delete_printer_filters(p); mimeDeleteType(MimeDatabase, p->filetype); + mimeDeleteType(MimeDatabase, p->prefiltertype); cupsdFreePrinterUsers(p); cupsdFreeQuotas(p); @@ -752,6 +747,11 @@ cupsdDeletePrinter( cupsdClearString(&p->op_policy); cupsdClearString(&p->error_policy); +#ifdef HAVE_DNSSD + cupsdClearString(&p->product); + cupsdClearString(&p->pdl); +#endif /* HAVE_DNSSD */ + cupsArrayDelete(p->filetypes); if (p->browse_attrs) @@ -954,6 +954,13 @@ cupsdLoadAllPrinters(void) "Syntax error on line %d of printers.conf.", linenum); return; } + else if (!strcasecmp(line, "AuthInfoRequired")) + { + if (!cupsdSetAuthInfoRequired(p, value, NULL)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad AuthInfoRequired on line %d of printers.conf.", + linenum); + } else if (!strcasecmp(line, "Info")) { if (value) @@ -1247,6 +1254,9 @@ cupsdRenamePrinter( mimeDeleteType(MimeDatabase, p->filetype); p->filetype = mimeAddType(MimeDatabase, "printer", name); + mimeDeleteType(MimeDatabase, p->prefiltertype); + p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", name); + /* * Rename the printer... */ @@ -1286,6 +1296,7 @@ cupsdSaveAllPrinters(void) time_t curtime; /* Current time */ struct tm *curdate; /* Current date */ cups_option_t *option; /* Current option */ + const char *ptr; /* Pointer into info/location */ /* @@ -1359,12 +1370,49 @@ cupsdSaveAllPrinters(void) else cupsFilePrintf(fp, "\n", printer->name); + if (printer->num_auth_info_required > 0) + { + cupsFilePrintf(fp, "AuthInfoRequired %s", printer->auth_info_required[0]); + for (i = 1; i < printer->num_auth_info_required; i ++) + cupsFilePrintf(fp, ",%s", printer->auth_info_required[i]); + cupsFilePutChar(fp, '\n'); + } + if (printer->info) - cupsFilePrintf(fp, "Info %s\n", printer->info); + { + if ((ptr = strchr(printer->info, '#')) != NULL) + { + /* + * Need to quote the first # in the info string... + */ + + cupsFilePuts(fp, "Info "); + cupsFileWrite(fp, printer->info, ptr - printer->info); + cupsFilePutChar(fp, '\\'); + cupsFilePuts(fp, ptr); + cupsFilePutChar(fp, '\n'); + } + else + cupsFilePrintf(fp, "Info %s\n", printer->info); + } if (printer->location) - cupsFilePrintf(fp, "Location %s\n", printer->location); + { + if ((ptr = strchr(printer->info, '#')) != NULL) + { + /* + * Need to quote the first # in the location string... + */ + cupsFilePuts(fp, "Location "); + cupsFileWrite(fp, printer->location, ptr - printer->location); + cupsFilePutChar(fp, '\\'); + cupsFilePuts(fp, ptr); + cupsFilePutChar(fp, '\n'); + } + else + cupsFilePrintf(fp, "Location %s\n", printer->location); + } if (printer->device_uri) cupsFilePrintf(fp, "DeviceURI %s\n", printer->device_uri); @@ -1427,6 +1475,119 @@ cupsdSaveAllPrinters(void) } +/* + * 'cupsdSetAuthInfoRequired()' - Set the required authentication info. + */ + +int /* O - 1 if value OK, 0 otherwise */ +cupsdSetAuthInfoRequired( + cupsd_printer_t *p, /* I - Printer */ + const char *values, /* I - Plain text value (or NULL) */ + ipp_attribute_t *attr) /* I - IPP attribute value (or NULL) */ +{ + int i; /* Looping var */ + + + p->num_auth_info_required = 0; + + /* + * Do we have a plain text value? + */ + + if (values) + { + /* + * Yes, grab the keywords... + */ + + const char *end; /* End of current value */ + + + while (*values && p->num_auth_info_required < 4) + { + if ((end = strchr(values, ',')) == NULL) + end = values + strlen(values); + + if (!strncmp(values, "none", end - values)) + { + if (p->num_auth_info_required != 0 || *end) + return (0); + + p->auth_info_required[p->num_auth_info_required] = "none"; + p->num_auth_info_required ++; + + return (1); + } + else if (!strncmp(values, "domain", end - values)) + { + p->auth_info_required[p->num_auth_info_required] = "domain"; + p->num_auth_info_required ++; + } + else if (!strncmp(values, "password", end - values)) + { + p->auth_info_required[p->num_auth_info_required] = "password"; + p->num_auth_info_required ++; + } + else if (!strncmp(values, "username", end - values)) + { + p->auth_info_required[p->num_auth_info_required] = "username"; + p->num_auth_info_required ++; + } + else + return (0); + } + + if (p->num_auth_info_required == 0) + { + p->auth_info_required[0] = "none"; + p->num_auth_info_required = 1; + } + + return (1); + } + + /* + * Grab values from an attribute instead... + */ + + if (!attr || attr->num_values > 4) + return (0); + + for (i = 0; i < attr->num_values; i ++) + { + if (!strcmp(attr->values[i].string.text, "none")) + { + if (p->num_auth_info_required != 0 || attr->num_values != 1) + return (0); + + p->auth_info_required[p->num_auth_info_required] = "none"; + p->num_auth_info_required ++; + + return (1); + } + else if (!strcmp(attr->values[i].string.text, "domain")) + { + p->auth_info_required[p->num_auth_info_required] = "domain"; + p->num_auth_info_required ++; + } + else if (!strcmp(attr->values[i].string.text, "password")) + { + p->auth_info_required[p->num_auth_info_required] = "password"; + p->num_auth_info_required ++; + } + else if (!strcmp(attr->values[i].string.text, "username")) + { + p->auth_info_required[p->num_auth_info_required] = "username"; + p->num_auth_info_required ++; + } + else + return (0); + } + + return (1); +} + + /* * 'cupsdSetPrinterAttrs()' - Set printer attributes based upon the PPD file. */ @@ -1552,6 +1713,13 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ "job-k-limit", p->k_limit); ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "job-page-limit", p->page_limit); + if (p->num_auth_info_required) + ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "auth-info-required", p->num_auth_info_required, + NULL, p->auth_info_required); + else + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "auth-info-required", NULL, "none"); if (cupsArrayCount(Banners) > 0 && !(p->type & CUPS_PRINTER_REMOTE)) { @@ -1880,7 +2048,20 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ * handle "raw" printing by users. */ - add_printer_filter(p, "application/vnd.cups-raw 0 -"); + add_printer_filter(p, p->filetype, "application/vnd.cups-raw 0 -"); + + /* + * Add any pre-filters in the PPD file... + */ + + if ((ppdattr = ppdFindAttr(ppd, "cupsPreFilter", NULL)) != NULL) + { + p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", p->name); + + for (; ppdattr; ppdattr = ppdFindNextAttr(ppd, "cupsPreFilter", NULL)) + if (ppdattr->value) + add_printer_filter(p, p->prefiltertype, ppdattr->value); + } /* * Add any filters in the PPD file... @@ -1890,7 +2071,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ for (i = 0; i < ppd->num_filters; i ++) { DEBUG_printf(("ppd->filters[%d] = \"%s\"\n", i, ppd->filters[i])); - add_printer_filter(p, ppd->filters[i]); + add_printer_filter(p, p->filetype, ppd->filters[i]); } if (ppd->num_filters == 0) @@ -1899,7 +2080,8 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ * If there are no filters, add a PostScript printing filter. */ - add_printer_filter(p, "application/vnd.cups-postscript 0 -"); + add_printer_filter(p, p->filetype, + "application/vnd.cups-postscript 0 -"); } /* @@ -1940,6 +2122,10 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ attr->values[i].string.text = _cupsStrAlloc("bcp"); } +#ifdef HAVE_DNSSD + cupsdSetString(&p->product, ppd->product); +#endif /* HAVE_DNSSD */ + /* * Close the PPD and set the type... */ @@ -1974,13 +2160,14 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ * handle "raw" printing by users. */ - add_printer_filter(p, "application/vnd.cups-raw 0 -"); + add_printer_filter(p, p->filetype, "application/vnd.cups-raw 0 -"); /* * Add a PostScript filter, since this is still possibly PS printer. */ - add_printer_filter(p, "application/vnd.cups-postscript 0 -"); + add_printer_filter(p, p->filetype, + "application/vnd.cups-postscript 0 -"); } else { @@ -1997,11 +2184,12 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ */ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, - "printer-make-and-model", NULL, "Local System V Printer"); + "printer-make-and-model", NULL, + "Local System V Printer"); snprintf(filename, sizeof(filename), "*/* 0 %s/interfaces/%s", ServerRoot, p->name); - add_printer_filter(p, filename); + add_printer_filter(p, p->filetype, filename); } else if (p->device_uri && !strncmp(p->device_uri, "ipp://", 6) && @@ -2098,12 +2286,12 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ length += 13 + strlen(p->job_sheets[0]) + strlen(p->job_sheets[1]); length += 32; if (BrowseLocalOptions) - length += 12 + strlen(BrowseLocalOptions); + length += 12 + strlen(BrowseLocalOptions); /* * Allocate the new string... */ - + if ((p->browse_attrs = calloc(1, length)) == NULL) cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to allocate %d bytes for browse data!", @@ -2173,6 +2361,12 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ write_irix_config(p); write_irix_state(p); #endif /* __sgi */ + + /* + * Let the browse protocols reflect the change + */ + + cupsdRegisterPrinter(p); } @@ -2327,6 +2521,12 @@ cupsdSetPrinterState( cupsdAddPrinterHistory(p); + /* + * Let the browse protocols reflect the change... + */ + + cupsdRegisterPrinter(p); + /* * Save the printer configuration if a printer goes from idle or processing * to stopped (or visa-versa)... @@ -2452,18 +2652,25 @@ cupsdUpdatePrinters(void) const char * /* O - Printer or class name */ cupsdValidateDest( - const char *hostname, /* I - Host name */ - const char *resource, /* I - Resource name */ + const char *uri, /* I - Printer URI */ cups_ptype_t *dtype, /* O - Type (printer or class) */ cupsd_printer_t **printer) /* O - Printer pointer */ { cupsd_printer_t *p; /* Current printer */ char localname[1024],/* Localized hostname */ *lptr, /* Pointer into localized hostname */ - *sptr; /* Pointer into server name */ - - - DEBUG_printf(("cupsdValidateDest(\"%s\", \"%s\", %p, %p)\n", hostname, resource, + *sptr, /* Pointer into server name */ + *rptr, /* Pointer into resource */ + scheme[32], /* Scheme portion of URI */ + username[64], /* Username portion of URI */ + hostname[HTTP_MAX_HOST], + /* Host portion of URI */ + resource[HTTP_MAX_URI]; + /* Resource portion of URI */ + int port; /* Port portion of URI */ + + + DEBUG_printf(("cupsdValidateDest(uri=\"%s\", dtype=%p, printer=%p)\n", uri, dtype, printer)); /* @@ -2473,7 +2680,16 @@ cupsdValidateDest( if (printer) *printer = NULL; - *dtype = (cups_ptype_t)0; + if (dtype) + *dtype = (cups_ptype_t)0; + + /* + * Pull the hostname and resource from the URI... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), + username, sizeof(username), hostname, sizeof(hostname), + &port, resource, sizeof(resource)); /* * See if the resource is a class or printer... @@ -2485,7 +2701,7 @@ cupsdValidateDest( * Class... */ - resource += 9; + rptr = resource + 9; } else if (!strncmp(resource, "/printers/", 10)) { @@ -2493,7 +2709,7 @@ cupsdValidateDest( * Printer... */ - resource += 10; + rptr = resource + 10; } else { @@ -2508,17 +2724,19 @@ cupsdValidateDest( * See if the printer or class name exists... */ - p = cupsdFindDest(resource); + p = cupsdFindDest(rptr); - if (p == NULL && strchr(resource, '@') == NULL) + if (p == NULL && strchr(rptr, '@') == NULL) return (NULL); else if (p != NULL) { if (printer) *printer = p; - *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | - CUPS_PRINTER_REMOTE); + if (dtype) + *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_REMOTE); + return (p->name); } @@ -2527,7 +2745,7 @@ cupsdValidateDest( */ if (!strcasecmp(hostname, "localhost")) - hostname = ServerName; + strlcpy(hostname, ServerName, sizeof(hostname)); strlcpy(localname, hostname, sizeof(localname)); @@ -2569,13 +2787,15 @@ cupsdValidateDest( p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) if (!strcasecmp(p->hostname, localname) && - !strcasecmp(p->name, resource)) + !strcasecmp(p->name, rptr)) { if (printer) *printer = p; - *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | - CUPS_PRINTER_REMOTE); + if (dtype) + *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_REMOTE); + return (p->name); } @@ -2792,6 +3012,27 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */ char name[256]; /* name-default */ + /* + * Maintain a common array of default attribute names... + */ + + if (!CommonDefaults) + { + CommonDefaults = cupsArrayNew((cups_array_func_t)strcmp, NULL); + + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("copies-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("document-format-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("finishings-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-hold-until-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-priority-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-sheets-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("media-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("number-up-default")); + cupsArrayAdd(CommonDefaults, + _cupsStrAlloc("orientation-requested-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("sides-default")); + } + /* * Add all of the default options from the .conf files... */ @@ -2806,6 +3047,9 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */ { snprintf(name, sizeof(name), "%s-default", option->name); num_options = cupsAddOption(name, option->value, num_options, &options); + + if (!cupsArrayFind(CommonDefaults, name)) + cupsArrayAdd(CommonDefaults, _cupsStrAlloc(name)); } } @@ -2824,6 +3068,10 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "copies-default", 1); + if (!cupsGetOption("document-format", p->num_options, p->options)) + ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE, + "document-format-default", NULL, "application/octet-stream"); + if (!cupsGetOption("job-hold-until", p->num_options, p->options)) ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "job-hold-until-default", NULL, "no-hold"); @@ -2839,6 +3087,14 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */ if (!cupsGetOption("orientation-requested", p->num_options, p->options)) ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "orientation-requested-default", IPP_PORTRAIT); + + if (!cupsGetOption("notify-lease-duration", p->num_options, p->options)) + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "notify-lease-duration-default", DefaultLeaseDuration); + + if (!cupsGetOption("notify-events", p->num_options, p->options)) + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "notify-events-default", NULL, "job-completed"); } @@ -2849,6 +3105,7 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */ static void add_printer_filter( cupsd_printer_t *p, /* I - Printer to add to */ + mime_type_t *filtertype, /* I - Filter or prefilter MIME type */ const char *filter) /* I - Filter to add */ { char super[MIME_MAX_SUPER], /* Super-type for filter */ @@ -2919,9 +3176,9 @@ add_printer_filter( cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer_filter: %s: adding filter %s/%s %s/%s %d %s", p->name, temptype->super, temptype->type, - p->filetype->super, p->filetype->type, + filtertype->super, filtertype->type, cost, program); - mimeAddFilter(MimeDatabase, temptype, p->filetype, cost, program); + mimeAddFilter(MimeDatabase, temptype, filtertype, cost, program); } } @@ -3017,6 +3274,54 @@ add_printer_formats(cupsd_printer_t *p) /* I - Printer */ attr->values[i].string.text = _cupsStrAlloc(mimetype); } + +#ifdef HAVE_DNSSD + { + char pdl[1024]; /* Buffer to build pdl list */ + mime_filter_t *filter; /* MIME filter looping var */ + + + pdl[0] = '\0'; + + if (mimeType(MimeDatabase, "application", "pdf")) + strlcat(pdl, "application/pdf,", sizeof(pdl)); + + if (mimeType(MimeDatabase, "application", "postscript")) + strlcat(pdl, "application/postscript,", sizeof(pdl)); + + if (mimeType(MimeDatabase, "application", "vnd.cups-raster")) + strlcat(pdl, "application/vnd.cups-raster,", sizeof(pdl)); + + /* + * Determine if this is a Tioga PrintJobMgr based queue... + */ + + for (filter = (mime_filter_t *)cupsArrayFirst(MimeDatabase->filters); + filter; + filter = (mime_filter_t *)cupsArrayNext(MimeDatabase->filters)) + { + if (filter->dst == p->filetype && filter->filter && + strstr(filter->filter, "PrintJobMgr")) + break; + } + + /* + * We only support raw printing if this is not a Tioga PrintJobMgr based + * queue and if application/octet-stream is a known conversion... + */ + + if (!filter && mimeType(MimeDatabase, "application", "octet-stream")) + strlcat(pdl, "application/octet-stream,", sizeof(pdl)); + + if (mimeType(MimeDatabase, "image", "png")) + strlcat(pdl, "image/png,", sizeof(pdl)); + + if (pdl[0]) + pdl[strlen(pdl) - 1] = '\0'; /* Remove trailing comma */ + + cupsdSetString(&p->pdl, pdl); + } +#endif /* HAVE_DNSSD */ } @@ -3327,5 +3632,5 @@ write_irix_state(cupsd_printer_t *p) /* I - Printer to update */ /* - * End of "$Id: printers.c 5970 2006-09-19 20:11:08Z mike $". + * End of "$Id: printers.c 6318 2007-03-06 04:36:55Z mike $". */ diff --git a/scheduler/printers.h b/scheduler/printers.h index acbc73800..77782359d 100644 --- a/scheduler/printers.h +++ b/scheduler/printers.h @@ -1,9 +1,9 @@ /* - * "$Id: printers.h 5828 2006-08-15 21:21:45Z mike $" + * "$Id: printers.h 6318 2007-03-06 04:36:55Z mike $" * * Printer definitions for the Common UNIX Printing System (CUPS) scheduler. * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -22,6 +22,10 @@ * WWW: http://www.cups.org */ +#ifdef HAVE_DNSSD +# include +#endif /* HAVE_DNSSD */ + /* * Quota data... */ @@ -67,7 +71,8 @@ typedef struct cupsd_printer_s char *port_monitor; /* Port monitor */ int raw; /* Raw queue? */ int remote; /* Remote queue? */ - mime_type_t *filetype; /* Pseudo-filetype for printer */ + mime_type_t *filetype, /* Pseudo-filetype for printer */ + *prefiltertype; /* Pseudo-filetype for pre-filters */ cups_array_t *filetypes; /* Supported file types */ void *job; /* Current job in queue */ ipp_t *attrs; /* Attributes supported by this printer */ @@ -86,9 +91,21 @@ typedef struct cupsd_printer_s int sequence_number; /* Increasing sequence number */ int num_options; /* Number of default options */ cups_option_t *options; /* Default options */ + int num_auth_info_required; /* Number of required auth fields */ + const char *auth_info_required[4]; /* Required authentication fields */ #ifdef __APPLE__ char *recoverable; /* com.apple.print.recoverable-message */ #endif /* __APPLE__ */ + +#ifdef HAVE_DNSSD + char *reg_name, /* Name used for service registration */ + *product, /* PPD Product string */ + *pdl, /* pdl value for TXT record */ + *txt_record; /* TXT record contents */ + int txt_len; /* TXT record length */ + DNSServiceRef dnssd_ipp_ref; /* DNSServiceRegister ref for _ipp */ + int dnssd_ipp_fd; /* File descriptor for DNSServiceRegister reference */ +#endif /* HAVE_DNSSD */ } cupsd_printer_t; @@ -98,6 +115,8 @@ typedef struct cupsd_printer_s VAR ipp_t *CommonData VALUE(NULL); /* Common printer object attrs */ +VAR cups_array_t *CommonDefaults VALUE(NULL); + /* Common -default option names */ VAR cups_array_t *Printers VALUE(NULL), /* Printer list */ *ImplicitPrinters VALUE(NULL); @@ -117,7 +136,8 @@ VAR cupsd_policy_t *DefaultPolicyPtr extern cupsd_printer_t *cupsdAddPrinter(const char *name); extern void cupsdAddPrinterHistory(cupsd_printer_t *p); -extern void cupsdAddPrinterUser(cupsd_printer_t *p, const char *username); +extern void cupsdAddPrinterUser(cupsd_printer_t *p, + const char *username); extern void cupsdCreateCommonData(void); extern void cupsdDeleteAllPrinters(void); extern void cupsdDeletePrinter(cupsd_printer_t *p, int update); @@ -126,26 +146,31 @@ extern cupsd_printer_t *cupsdFindPrinter(const char *name); extern void cupsdFreePrinterUsers(cupsd_printer_t *p); extern void cupsdFreeQuotas(cupsd_printer_t *p); extern void cupsdLoadAllPrinters(void); -extern void cupsdRenamePrinter(cupsd_printer_t *p, const char *name); +extern void cupsdRenamePrinter(cupsd_printer_t *p, + const char *name); +extern char *cupsdSanitizeURI(const char *uri, char *buffer, + int buflen); extern void cupsdSaveAllPrinters(void); +extern int cupsdSetAuthInfoRequired(cupsd_printer_t *p, + const char *values, + ipp_attribute_t *attr); extern void cupsdSetPrinterAttrs(cupsd_printer_t *p); -extern void cupsdSetPrinterReasons(cupsd_printer_t *p, const char *s); -extern void cupsdSetPrinterState(cupsd_printer_t *p, ipp_pstate_t s, int update); +extern void cupsdSetPrinterReasons(cupsd_printer_t *p, + const char *s); +extern void cupsdSetPrinterState(cupsd_printer_t *p, ipp_pstate_t s, + int update); #define cupsdStartPrinter(p,u) cupsdSetPrinterState((p), IPP_PRINTER_IDLE, (u)) extern void cupsdStopPrinter(cupsd_printer_t *p, int update); extern void cupsdUpdatePrinters(void); -extern cupsd_quota_t *cupsdUpdateQuota(cupsd_printer_t *p, const char *username, - int pages, int k); -extern const char *cupsdValidateDest(const char *hostname, - const char *resource, +extern cupsd_quota_t *cupsdUpdateQuota(cupsd_printer_t *p, + const char *username, int pages, + int k); +extern const char *cupsdValidateDest(const char *uri, cups_ptype_t *dtype, cupsd_printer_t **printer); extern void cupsdWritePrintcap(void); -extern char *cupsdSanitizeURI(const char *uri, char *buffer, - int buflen); - /* - * End of "$Id: printers.h 5828 2006-08-15 21:21:45Z mike $". + * End of "$Id: printers.h 6318 2007-03-06 04:36:55Z mike $". */ diff --git a/scheduler/process.c b/scheduler/process.c index 5af7e5eef..7462472a6 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -1,9 +1,9 @@ /* - * "$Id: process.c 5376 2006-04-06 20:32:07Z mike $" + * "$Id: process.c 6326 2007-03-11 17:50:18Z mike $" * * Process management routines for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -121,6 +121,7 @@ cupsdStartProcess( int outfd, /* I - Standard output file descriptor */ int errfd, /* I - Standard error file descriptor */ int backfd, /* I - Backchannel file descriptor */ + int sidefd, /* I - Sidechannel file descriptor */ int root, /* I - Run as root? */ int *pid) /* O - Process ID */ { @@ -161,7 +162,7 @@ cupsdStartProcess( linkpath); else snprintf(processPath, sizeof(processPath), "CFProcessPath=%s/%s", - dirname(command), linkpath); + dirname((char *)command), linkpath); } else snprintf(processPath, sizeof(processPath), "CFProcessPath=%s", command); @@ -217,6 +218,12 @@ cupsdStartProcess( open("/dev/null", O_RDWR); fcntl(3, F_SETFL, O_NDELAY); } + if (sidefd != 4 && sidefd > 0) + { + close(4); + dup(sidefd); + fcntl(4, F_SETFL, O_NDELAY); + } /* * Change the priority of the process based on the FilterNice setting. @@ -344,5 +351,5 @@ compare_procs(cupsd_proc_t *a, /* I - First process */ /* - * End of "$Id: process.c 5376 2006-04-06 20:32:07Z mike $". + * End of "$Id: process.c 6326 2007-03-11 17:50:18Z mike $". */ diff --git a/scheduler/quotas.c b/scheduler/quotas.c index 7d3e4e3eb..a51f7f08d 100644 --- a/scheduler/quotas.c +++ b/scheduler/quotas.c @@ -1,5 +1,5 @@ /* - * "$Id: quotas.c 5970 2006-09-19 20:11:08Z mike $" + * "$Id: quotas.c 5969 2006-09-19 20:09:24Z mike $" * * Quota routines for the Common UNIX Printing System (CUPS). * @@ -230,5 +230,5 @@ find_quota(cupsd_printer_t *p, /* I - Printer */ /* - * End of "$Id: quotas.c 5970 2006-09-19 20:11:08Z mike $". + * End of "$Id: quotas.c 5969 2006-09-19 20:09:24Z mike $". */ diff --git a/scheduler/select.c b/scheduler/select.c new file mode 100644 index 000000000..c72adbdc9 --- /dev/null +++ b/scheduler/select.c @@ -0,0 +1,946 @@ +/* + * "$Id: select.c 6166 2006-12-29 20:35:18Z mike $" + * + * Select abstraction functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9600 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * cupsdAddSelect() - Add a file descriptor to the list. + * cupsdDoSelect() - Do a select-like operation. + * cupsdIsSelecting() - Determine whether we are monitoring a file + * descriptor. + * cupsdRemoveSelect() - Remove a file descriptor from the list. + * cupsdStartSelect() - Initialize the file polling engine. + * cupsdStopSelect() - Shutdown the file polling engine. + * compare_fds() - Compare file descriptors. + * find_fd() - Find an existing file descriptor record. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" + +#ifdef HAVE_EPOLL +# include +#elif defined(HAVE_KQUEUE) +# include +# include +#elif defined(HAVE_POLL) +# include +#elif defined(__hpux) +# include +#else +# include +#endif /* HAVE_EPOLL */ + + +/* + * Design Notes for Poll/Select API in CUPSD + * ----------------------------------------- + * + * SUPPORTED APIS + * + * OS select poll epoll kqueue /dev/poll + * -------------- ------ ------ ------ ------ --------- + * AIX YES YES NO NO NO + * FreeBSD YES YES NO YES NO + * HP-UX YES YES NO NO NO + * IRIX YES YES NO NO NO + * Linux YES YES YES NO NO + * MacOS X YES YES NO YES NO + * NetBSD YES YES NO YES NO + * OpenBSD YES YES NO YES NO + * Solaris YES YES NO NO YES + * Tru64 YES YES NO NO NO + * Windows YES NO NO NO NO + * + * + * HIGH-LEVEL API + * + * typedef void (*cupsd_selfunc_t)(void *data); + * + * void cupsdStartSelect(void); + * void cupsdStopSelect(void); + * void cupsdAddSelect(int fd, cupsd_selfunc_t read_cb, + * cupsd_selfunc_t write_cb, void *data); + * void cupsdRemoveSelect(int fd); + * int cupsdDoSelect(int timeout); + * + * + * IMPLEMENTATION STRATEGY + * + * 0. Common Stuff + * a. CUPS array of file descriptor to callback functions + * and data. + * b. cupsdStartSelect() creates the array + * c. cupsdStopSelect() destroys the array and all elements. + * d. cupsdAddSelect() adds to the array and allocates a + * new callback element. + * e. cupsdRemoveSelect() removes from the array and frees + * the callback element. + * f. _cupsd_fd_t provides a reference-counted structure for + * tracking file descriptors that are monitored. + * + * 1. select() O(n) + * a. Input/Output fd_set variables, copied to working + * copies and then used with select(). + * b. Loop through CUPS array, using FD_ISSET and calling + * the read/write callbacks as needed. + * c. cupsdRemoveSelect() clears fd_set bit from main and + * working sets. + * d. cupsdStopSelect() frees all of the memory used by the + * CUPS array and fd_set's. + * + * 2. poll() - O(n log n) + * a. Regular array of pollfd, sorted the same as the CUPS + * array. + * b. Loop through pollfd array, call the corresponding + * read/write callbacks as needed. + * c. cupsdAddSelect() adds first to CUPS array and flags the + * pollfd array as invalid. + * d. cupsdDoSelect() rebuilds pollfd array as needed, calls + * poll(), then loops through the pollfd array looking up + * as needed. + * e. cupsdRemoveSelect() flags the pollfd array as invalid. + * f. cupsdStopSelect() frees all of the memory used by the + * CUPS array and pollfd array. + * + * 3. epoll() - O(n) + * a. cupsdStartSelect() creates epoll file descriptor using + * epoll_create() with the maximum fd count, and + * allocates an events buffer for the maximum fd count. + * b. cupsdAdd/RemoveSelect() uses epoll_ctl() to add + * (EPOLL_CTL_ADD) or remove (EPOLL_CTL_DEL) a single + * event using the level-triggered semantics. The event + * user data field is a pointer to the new callback array + * element. + * c. cupsdDoSelect() uses epoll_wait() with the global event + * buffer allocated in cupsdStartSelect() and then loops + * through the events, using the user data field to find + * the callback record. + * d. cupsdStopSelect() closes the epoll file descriptor and + * frees all of the memory used by the event buffer. + * + * 4. kqueue() - O(n) + * b. cupsdStartSelect() creates kqueue file descriptor + * using kqyeue() function and allocates a global event + * buffer. + * c. cupsdAdd/RemoveSelect() uses EV_SET and kevent() to + * register the changes. The event user data field is a + * pointer to the new callback array element. + * d. cupsdDoSelect() uses kevent() to poll for events and + * loops through the events, using the user data field to + * find the callback record. + * e. cupsdStopSelect() closes the kqyeye() file descriptor + * and frees all of the memory used by the event buffer. + * + * 5. /dev/poll - O(n log n) - NOT YET IMPLEMENTED + * a. cupsdStartSelect() opens /dev/poll and allocates an + * array of pollfd structs; on failure to open /dev/poll, + * revert to poll() system call. + * b. cupsdAddSelect() writes a single pollfd struct to + * /dev/poll with the new file descriptor and the + * POLLIN/POLLOUT flags. + * c. cupsdRemoveSelect() writes a single pollfd struct to + * /dev/poll with the file descriptor and the POLLREMOVE + * flag. + * d. cupsdDoSelect() uses the DP_POLL ioctl to retrieve + * events from /dev/poll and then loops through the + * returned pollfd array, looking up the file descriptors + * as needed. + * e. cupsdStopSelect() closes /dev/poll and frees the + * pollfd array. + * + * PERFORMANCE + * + * In tests using the "make test" target with option 0 (keep cupsd + * running) and the "testspeed" program with "-c 50 -r 1000", epoll() + * performed 5.5% slower select(), followed by kqueue() at 16% slower + * than select() and poll() at 18% slower than select(). Similar + * results were seen with twice the number of client connections. + * + * The epoll() and kqueue() performance is likely limited by the + * number of system calls used to add/modify/remove file + * descriptors dynamically. Further optimizations may be possible + * in the area of limiting use of cupsdAddSelect() and + * cupsdRemoveSelect(), however extreme care will be needed to avoid + * excess CPU usage and deadlock conditions. + * + * We may be able to improve the poll() implementation simply by + * keeping the pollfd array sync'd with the _cupsd_fd_t array, as that + * will eliminate the rebuilding of the array whenever there is a + * change and eliminate the fd array lookups in the inner loop of + * cupsdDoSelect(). + * + * Since /dev/poll will never be able to use a shadow array, it may + * not make sense to implement support for it. ioctl() overhead will + * impact performance as well, so my guess would be that, for CUPS, + * /dev/poll will yield a net performance loss. + */ + +/* + * Local structures... + */ + +typedef struct _cupsd_fd_s +{ + int fd, /* File descriptor */ + use; /* Use count */ + cupsd_selfunc_t read_cb, /* Read callback */ + write_cb; /* Write callback */ + void *data; /* Data pointer for callbacks */ +} _cupsd_fd_t; + + +/* + * Local globals... + */ + +static cups_array_t *cupsd_fds = NULL; + +#ifdef HAVE_EPOLL +static int cupsd_epoll_fd = -1; +static struct epoll_event *cupsd_epoll_events = NULL; +#elif defined(HAVE_KQUEUE) +static int cupsd_kqueue_fd = -1, + cupsd_kqueue_changes = 0; +static struct kevent *cupsd_kqueue_events = NULL; +#elif defined(HAVE_POLL) +static int cupsd_alloc_pollfds = 0, + cupsd_update_pollfds = 0; +static struct pollfd *cupsd_pollfds = NULL; +#else /* select() */ +static fd_set cupsd_global_input, + cupsd_global_output, + cupsd_current_input, + cupsd_current_output; +#endif /* HAVE_EPOLL */ + + +/* + * Local functions... + */ + +static int compare_fds(_cupsd_fd_t *a, _cupsd_fd_t *b); +static _cupsd_fd_t *find_fd(int fd); +#define release_fd(f) { \ + (f)->use --; \ + if (!(f)->use) free((f));\ + } +#define retain_fd(f) (f)->use++ + + +/* + * 'cupsdAddSelect()' - Add a file descriptor to the list. + */ + +int /* O - 1 on success, 0 on error */ +cupsdAddSelect(int fd, /* I - File descriptor */ + cupsd_selfunc_t read_cb, /* I - Read callback */ + cupsd_selfunc_t write_cb,/* I - Write callback */ + void *data) /* I - Data to pass to callback */ +{ + _cupsd_fd_t *fdptr; /* File descriptor record */ + int added; /* 1 if added, 0 if modified */ + + + /* + * Range check input... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddSelect: fd=%d, read_cb=%p, write_cb=%p, data=%p", + fd, read_cb, write_cb, data); + + if (fd < 0) + return (0); + + /* + * See if this FD has already been added... + */ + + if ((fdptr = find_fd(fd)) == NULL) + { + /* + * No, add a new entry... + */ + + if ((fdptr = calloc(1, sizeof(_cupsd_fd_t))) == NULL) + return (0); + + fdptr->fd = fd; + fdptr->use = 1; + + if (!cupsArrayAdd(cupsd_fds, fdptr)) + { + cupsdLogMessage(CUPSD_LOG_EMERG, "Unable to add fd %d to array!", fd); + free(fdptr); + return (0); + } + + added = 1; + } + else + added = 0; + +#ifdef HAVE_EPOLL + { + struct epoll_event event; /* Event data */ + + + event.events = 0; + + if (read_cb) + event.events |= EPOLLIN; + + if (write_cb) + event.events |= EPOLLOUT; + + event.data.ptr = fdptr; + + epoll_ctl(cupsd_epoll_fd, added ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, + &event); + } + +#elif defined(HAVE_KQUEUE) + { + struct kevent event; /* Event data */ + struct timespec timeout; /* Timeout value */ + + + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + + if (fdptr->read_cb != read_cb) + { + if (read_cb) + EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, fdptr); + else + EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, fdptr); + + if (kevent(cupsd_kqueue_fd, &event, 1, NULL, 0, &timeout)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddSelect: kevent() returned %s", + strerror(errno)); + return (0); + } + } + + if (fdptr->write_cb != write_cb) + { + if (write_cb) + EV_SET(&event, fd, EVFILT_WRITE, EV_ADD, 0, 0, fdptr); + else + EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, fdptr); + + if (kevent(cupsd_kqueue_fd, &event, 1, NULL, 0, &timeout)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddSelect: kevent() returned %s", + strerror(errno)); + return (0); + } + } + } + +#elif defined(HAVE_POLL) + cupsd_update_pollfds = 1; + +#else /* select() */ + /* + * Add or remove the file descriptor in the input and output sets + * for select()... + */ + + if (read_cb) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddSelect: Adding fd %d to input set...", fd); + FD_SET(fd, &cupsd_global_input); + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddSelect: Removing fd %d from input set...", fd); + FD_CLR(fd, &cupsd_global_input); + FD_CLR(fd, &cupsd_current_input); + } + + if (write_cb) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddSelect: Adding fd %d to output set...", fd); + FD_SET(fd, &cupsd_global_output); + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddSelect: Removing fd %d from output set...", fd); + FD_CLR(fd, &cupsd_global_output); + FD_CLR(fd, &cupsd_current_output); + } +#endif /* HAVE_EPOLL */ + + /* + * Save the (new) read and write callbacks... + */ + + fdptr->read_cb = read_cb; + fdptr->write_cb = write_cb; + fdptr->data = data; + + return (1); +} + + +/* + * 'cupsdDoSelect()' - Do a select-like operation. + */ + +int /* O - Number of files or -1 on error */ +cupsdDoSelect(long timeout) /* I - Timeout in seconds */ +{ + int nfds; /* Number of file descriptors */ + _cupsd_fd_t *fdptr; /* Current file descriptor */ +#ifdef HAVE_EPOLL + int i; /* Looping var */ + struct epoll_event *event; /* Current event */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdDoSelect: polling %d fds for %ld seconds...", + cupsArrayCount(cupsd_fds), timeout); + + if (timeout >= 0 && timeout < 86400) + nfds = epoll_wait(cupsd_epoll_fd, cupsd_epoll_events, MaxFDs, + timeout * 1000); + else + nfds = epoll_wait(cupsd_epoll_fd, cupsd_epoll_events, MaxFDs, -1); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: epoll() returned %d...", + nfds); + + for (i = nfds, event = cupsd_epoll_events; i > 0; i --, event ++) + { + fdptr = (_cupsd_fd_t *)event->data.ptr; + + retain_fd(fdptr); + + if (fdptr->read_cb && (event->events & (EPOLLIN | EPOLLERR | EPOLLHUP))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Read on fd %d...", + fdptr->fd); + (*(fdptr->read_cb))(fdptr->data); + } + + if (fdptr->write_cb && (event->events & (EPOLLOUT | EPOLLERR | EPOLLHUP))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Write on fd %d...", + fdptr->fd); + (*(fdptr->write_cb))(fdptr->data); + } + + release_fd(fdptr); + } + +#elif defined(HAVE_KQUEUE) + int i; /* Looping var */ + struct kevent *event; /* Current event */ + struct timespec ktimeout; /* kevent() timeout */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdDoSelect: polling %d fds for %ld seconds...", + cupsArrayCount(cupsd_fds), timeout); + + if (timeout >= 0 && timeout < 86400) + { + ktimeout.tv_sec = timeout; + ktimeout.tv_nsec = 0; + + nfds = kevent(cupsd_kqueue_fd, NULL, 0, cupsd_kqueue_events, MaxFDs, + &ktimeout); + } + else + nfds = kevent(cupsd_kqueue_fd, NULL, 0, cupsd_kqueue_events, MaxFDs, NULL); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdDoSelect: kevent(%d, ..., %d, ...) returned %d...", + cupsd_kqueue_fd, MaxFDs, nfds); + + cupsd_kqueue_changes = 0; + + for (i = nfds, event = cupsd_kqueue_events; i > 0; i --, event ++) + { + fdptr = (_cupsd_fd_t *)event->udata; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "event->filter=%d, event->ident=%d", + event->filter, (int)event->ident); + + retain_fd(fdptr); + + if (fdptr->read_cb && event->filter == EVFILT_READ) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Read on fd %d...", + fdptr->fd); + (*(fdptr->read_cb))(fdptr->data); + } + + if (fdptr->write_cb && event->filter == EVFILT_WRITE) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Write on fd %d...", + fdptr->fd); + (*(fdptr->write_cb))(fdptr->data); + } + + release_fd(fdptr); + } + +#elif defined(HAVE_POLL) + struct pollfd *pfd; /* Current pollfd structure */ + int count; /* Number of file descriptors */ + + + count = cupsArrayCount(cupsd_fds); + + if (cupsd_update_pollfds) + { + /* + * Update the cupsd_pollfds array to match the current FD array... + */ + + cupsd_update_pollfds = 0; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Updating pollfd array..."); + + /* + * (Re)allocate memory as needed... + */ + + if (count > cupsd_alloc_pollfds) + { + int allocfds = count + 16; + + + if (cupsd_pollfds) + pfd = realloc(cupsd_pollfds, allocfds * sizeof(struct pollfd)); + else + pfd = malloc(allocfds * sizeof(struct pollfd)); + + if (!pfd) + { + cupsdLogMessage(CUPSD_LOG_EMERG, + "Unable to allocate %d bytes for polling!", + (int)(allocfds * sizeof(struct pollfd))); + + return (-1); + } + + cupsd_pollfds = pfd; + cupsd_alloc_pollfds = allocfds; + } + + /* + * Rebuild the array... + */ + + for (fdptr = (_cupsd_fd_t *)cupsArrayFirst(cupsd_fds), pfd = cupsd_pollfds; + fdptr; + fdptr = (_cupsd_fd_t *)cupsArrayNext(cupsd_fds), pfd ++) + { + pfd->fd = fdptr->fd; + pfd->events = 0; + + if (fdptr->read_cb) + pfd->events |= POLLIN; + + if (fdptr->write_cb) + pfd->events |= POLLOUT; + } + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdDoSelect: polling %d fds for %ld seconds...", + count, timeout); + + if (timeout >= 0 && timeout < 86400) + nfds = poll(cupsd_pollfds, count, timeout * 1000); + else + nfds = poll(cupsd_pollfds, count, -1); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: poll() returned %d...", + nfds); + + if (nfds > 0) + { + /* + * Do callbacks for each file descriptor... + */ + + for (pfd = cupsd_pollfds; count > 0; pfd ++, count --) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdDoSelect: pollfds[%d]={fd=%d, revents=%x}", + pfd - cupsd_pollfds, pfd->fd, pfd->revents); + + if (!pfd->revents) + continue; + + if ((fdptr = find_fd(pfd->fd)) == NULL) + continue; + + retain_fd(fdptr); + + if (fdptr->read_cb && (pfd->revents & (POLLIN | POLLERR | POLLHUP))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Read on fd %d...", + fdptr->fd); + (*(fdptr->read_cb))(fdptr->data); + } + + if (fdptr->write_cb && (pfd->revents & (POLLOUT | POLLERR | POLLHUP))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Write on fd %d...", + fdptr->fd); + (*(fdptr->write_cb))(fdptr->data); + } + + release_fd(fdptr); + } + } + +#else /* select() */ + struct timeval stimeout; /* Timeout for select() */ + int maxfd; /* Maximum file descriptor */ + + + /* + * Figure out the highest file descriptor number... + */ + + if ((fdptr = (_cupsd_fd_t *)cupsArrayLast(cupsd_fds)) == NULL) + maxfd = 1; + else + maxfd = fdptr->fd + 1; + + /* + * Do the select()... + */ + + cupsd_current_input = cupsd_global_input; + cupsd_current_output = cupsd_global_output; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdDoSelect: selecting %d fds for %ld seconds...", + maxfd, timeout); + + if (timeout >= 0 && timeout < 86400) + { + stimeout.tv_sec = timeout; + stimeout.tv_usec = 0; + + nfds = select(maxfd, &cupsd_current_input, &cupsd_current_output, NULL, + &stimeout); + } + else + nfds = select(maxfd, &cupsd_current_input, &cupsd_current_output, NULL, + NULL); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: select() returned %d...", + nfds); + + if (nfds > 0) + { + /* + * Do callbacks for each file descriptor... + */ + + for (fdptr = (_cupsd_fd_t *)cupsArrayFirst(cupsd_fds); + fdptr; + fdptr = (_cupsd_fd_t *)cupsArrayNext(cupsd_fds)) + { + retain_fd(fdptr); + + if (fdptr->read_cb && FD_ISSET(fdptr->fd, &cupsd_current_input)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Read on fd %d...", + fdptr->fd); + (*(fdptr->read_cb))(fdptr->data); + } + + if (fdptr->write_cb && FD_ISSET(fdptr->fd, &cupsd_current_output)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDoSelect: Write on fd %d...", + fdptr->fd); + (*(fdptr->write_cb))(fdptr->data); + } + + release_fd(fdptr); + } + } + +#endif /* HAVE_EPOLL */ + + /* + * Return the number of file descriptors handled... + */ + + return (nfds); +} + + +/* + * 'cupsdIsSelecting()' - Determine whether we are monitoring a file + * descriptor. + */ + +int /* O - 1 if selecting, 0 otherwise */ +cupsdIsSelecting(int fd) /* I - File descriptor */ +{ + return (find_fd(fd) != NULL); +} + + +/* + * 'cupsdRemoveSelect()' - Remove a file descriptor from the list. + */ + +void +cupsdRemoveSelect(int fd) /* I - File descriptor */ +{ + _cupsd_fd_t *fdptr; /* File descriptor record */ +#ifdef HAVE_EPOLL + struct epoll_event event; /* Event data */ +#elif defined(HAVE_KQUEUE) + struct kevent event; /* Event data */ + struct timespec timeout; /* Timeout value */ +#elif defined(HAVE_POLL) + /* No variables for poll() */ +#endif /* HAVE_EPOLL */ + + + /* + * Range check input... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdRemoveSelect: fd=%d", fd); + + if (fd < 0) + return; + + /* + * Find the file descriptor... + */ + + if ((fdptr = find_fd(fd)) == NULL) + return; + +#ifdef HAVE_EPOLL + epoll_ctl(cupsd_epoll_fd, EPOLL_CTL_DEL, fd, &event); + +#elif defined(HAVE_KQUEUE) + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + + if (fdptr->read_cb) + { + EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, fdptr); + + if (kevent(cupsd_kqueue_fd, &event, 1, NULL, 0, &timeout)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdRemoveSelect: kevent() returned %s", + strerror(errno)); + return; + } + } + + if (fdptr->write_cb) + { + EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, fdptr); + + if (kevent(cupsd_kqueue_fd, &event, 1, NULL, 0, &timeout)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdRemoveSelect: kevent() returned %s", + strerror(errno)); + return; + } + } + + +#elif defined(HAVE_POLL) + /* + * Update the pollfds array... + */ + + cupsd_update_pollfds = 1; + +#else /* select() */ + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdRemoveSelect: Removing fd %d from input and output " + "sets...", fd); + FD_CLR(fd, &cupsd_global_input); + FD_CLR(fd, &cupsd_global_output); + FD_CLR(fd, &cupsd_current_input); + FD_CLR(fd, &cupsd_current_output); +#endif /* HAVE_EPOLL */ + + /* + * Remove the file descriptor for from the FD array... + */ + + cupsArrayRemove(cupsd_fds, fdptr); + release_fd(fdptr); +} + + +/* + * 'cupsdStartSelect()' - Initialize the file polling engine. + */ + +void +cupsdStartSelect(void) +{ + cupsd_fds = cupsArrayNew((cups_array_func_t)compare_fds, NULL); + +#ifdef HAVE_EPOLL + cupsd_epoll_fd = epoll_create(MaxFDs); + cupsd_epoll_events = calloc(MaxFDs, sizeof(struct epoll_event)); + +#elif defined(HAVE_KQUEUE) + cupsd_kqueue_fd = kqueue(); + cupsd_kqueue_changes = 0; + cupsd_kqueue_events = calloc(MaxFDs, sizeof(struct kevent)); + +#elif defined(HAVE_POLL) + cupsd_update_pollfds = 0; + +#else /* select() */ + FD_ZERO(&cupsd_global_input); + FD_ZERO(&cupsd_global_output); +#endif /* HAVE_EPOLL */ +} + + +/* + * 'cupsdStopSelect()' - Shutdown the file polling engine. + */ + +void +cupsdStopSelect(void) +{ + _cupsd_fd_t *fdptr; /* Current file descriptor */ + + + for (fdptr = (_cupsd_fd_t *)cupsArrayFirst(cupsd_fds); + fdptr; + fdptr = (_cupsd_fd_t *)cupsArrayNext(cupsd_fds)) + free(fdptr); + + cupsArrayDelete(cupsd_fds); + cupsd_fds = NULL; + +#ifdef HAVE_EPOLL + if (cupsd_epoll_events) + { + free(cupsd_epoll_events); + cupsd_epoll_events = NULL; + } + + if (cupsd_epoll_fd >= 0) + { + close(cupsd_epoll_fd); + cupsd_epoll_fd = -1; + } + +#elif defined(HAVE_KQUEUE) + if (cupsd_kqueue_events) + { + free(cupsd_kqueue_events); + cupsd_kqueue_events = NULL; + } + + if (cupsd_kqueue_fd >= 0) + { + close(cupsd_kqueue_fd); + cupsd_kqueue_fd = -1; + } + + cupsd_kqueue_changes = 0; + +#elif defined(HAVE_POLL) + if (cupsd_pollfds) + { + free(cupsd_pollfds); + cupsd_pollfds = NULL; + cupsd_alloc_pollfds = 0; + } + + cupsd_update_pollfds = 0; + +#else /* select() */ + FD_ZERO(&cupsd_global_input); + FD_ZERO(&cupsd_global_output); +#endif /* HAVE_EPOLL */ +} + + +/* + * 'compare_fds()' - Compare file descriptors. + */ + +static int /* O - Result of comparison */ +compare_fds(_cupsd_fd_t *a, /* I - First file descriptor */ + _cupsd_fd_t *b) /* I - Second file descriptor */ +{ + return (a->fd - b->fd); +} + + +/* + * 'find_fd()' - Find an existing file descriptor record. + */ + +static _cupsd_fd_t * /* O - FD record pointer or NULL */ +find_fd(int fd) /* I - File descriptor */ +{ + _cupsd_fd_t *fdptr, /* Matching record (if any) */ + key; /* Search key */ + + + cupsArraySave(cupsd_fds); + + key.fd = fd; + fdptr = (_cupsd_fd_t *)cupsArrayFind(cupsd_fds, &key); + + cupsArrayRestore(cupsd_fds); + + return (fdptr); +} + + +/* + * End of "$Id: select.c 6166 2006-12-29 20:35:18Z mike $". + */ diff --git a/scheduler/server.c b/scheduler/server.c index bcc3c71e6..7efbbcd71 100644 --- a/scheduler/server.c +++ b/scheduler/server.c @@ -1,5 +1,5 @@ /* - * "$Id: server.c 5493 2006-05-05 16:33:57Z mike $" + * "$Id: server.c 6123 2006-11-21 15:36:04Z mike $" * * Server start/stop routines for the Common UNIX Printing System (CUPS). * @@ -107,10 +107,7 @@ cupsdStartServer(void) { CGIStatusBuffer = cupsdStatBufNew(CGIPipes[0], "[CGI]"); - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStartServer: Adding fd %d to InputSet...", - CGIPipes[0]); - FD_SET(CGIPipes[0], InputSet); + cupsdAddSelect(CGIPipes[0], (cupsd_selfunc_t)cupsdUpdateCGI, NULL, NULL); } /* @@ -158,11 +155,7 @@ cupsdStopServer(void) if (CGIPipes[0] >= 0) { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStopServer: Removing fd %d from InputSet...", - CGIPipes[0]); - - FD_CLR(CGIPipes[0], InputSet); + cupsdRemoveSelect(CGIPipes[0]); cupsdStatBufDelete(CGIStatusBuffer); close(CGIPipes[1]); @@ -211,5 +204,5 @@ cupsdStopServer(void) /* - * End of "$Id: server.c 5493 2006-05-05 16:33:57Z mike $". + * End of "$Id: server.c 6123 2006-11-21 15:36:04Z mike $". */ diff --git a/scheduler/statbuf.c b/scheduler/statbuf.c index b10f63ebc..0450fa14a 100644 --- a/scheduler/statbuf.c +++ b/scheduler/statbuf.c @@ -1,5 +1,5 @@ /* - * "$Id: statbuf.c 5889 2006-08-24 21:44:35Z mike $" + * "$Id: statbuf.c 5888 2006-08-24 21:42:47Z mike $" * * Status buffer routines for the Common UNIX Printing System (CUPS) * scheduler. @@ -330,5 +330,5 @@ cupsdStatBufUpdate(cupsd_statbuf_t *sb, /* I - Status buffer */ /* - * End of "$Id: statbuf.c 5889 2006-08-24 21:44:35Z mike $". + * End of "$Id: statbuf.c 5888 2006-08-24 21:42:47Z mike $". */ diff --git a/scheduler/subscriptions.c b/scheduler/subscriptions.c index d0e05d9be..c077bcdeb 100644 --- a/scheduler/subscriptions.c +++ b/scheduler/subscriptions.c @@ -1,9 +1,9 @@ /* - * "$Id: subscriptions.c 5991 2006-09-29 02:26:29Z mike $" + * "$Id: subscriptions.c 6176 2007-01-03 15:28:30Z mike $" * * Subscription routines for the Common UNIX Printing System (CUPS) scheduler. * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -52,8 +52,8 @@ # include # ifdef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND # define dbus_message_append_iter_init dbus_message_iter_init_append -# define dbus_message_iter_append_string(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, v) -# define dbus_message_iter_append_uint32(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, v) +# define dbus_message_iter_append_string(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &(v)) +# define dbus_message_iter_append_uint32(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &(v)) # endif /* HAVE_DBUS_MESSAGE_ITER_INIT_APPEND */ #endif /* HAVE_DBUS */ @@ -1226,10 +1226,7 @@ cupsdStopAllNotifiers(void) if (NotifierPipes[0] >= 0) { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStopAllNotifiers: Removing fd %d from InputSet...", - NotifierPipes[0]); - FD_CLR(NotifierPipes[0], InputSet); + cupsdRemoveSelect(NotifierPipes[0]); cupsdStatBufDelete(NotifierStatusBuffer); @@ -1362,11 +1359,11 @@ cupsd_send_dbus(cupsd_eventmask_t event,/* I - Event to send */ dbus_message_append_iter_init(message, &iter); if (dest) - dbus_message_iter_append_string(&iter, &(dest->name)); + dbus_message_iter_append_string(&iter, dest->name); if (job) { - dbus_message_iter_append_uint32(&iter, &(job->id)); - dbus_message_iter_append_string(&iter, &(job->username)); + dbus_message_iter_append_uint32(&iter, job->id); + dbus_message_iter_append_string(&iter, job->username); } dbus_connection_send(con, message, NULL); @@ -1571,11 +1568,8 @@ cupsd_start_notifier( NotifierStatusBuffer = cupsdStatBufNew(NotifierPipes[0], "[Notifier]"); - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "start_notifier: Adding fd %d to InputSet...", - NotifierPipes[0]); - - FD_SET(NotifierPipes[0], InputSet); + cupsdAddSelect(NotifierPipes[0], (cupsd_selfunc_t)cupsdUpdateNotifierStatus, + NULL, NULL); } if (cupsdOpenPipe(fds)) @@ -1597,7 +1591,7 @@ cupsd_start_notifier( */ if (cupsdStartProcess(command, argv, envp, fds[0], -1, NotifierPipes[1], - -1, 0, &pid) < 0) + -1, -1, 0, &pid) < 0) { /* * Error - can't fork! @@ -1627,5 +1621,5 @@ cupsd_start_notifier( /* - * End of "$Id: subscriptions.c 5991 2006-09-29 02:26:29Z mike $". + * End of "$Id: subscriptions.c 6176 2007-01-03 15:28:30Z mike $". */ diff --git a/scheduler/subscriptions.h b/scheduler/subscriptions.h index 9671d937f..6cdd3a063 100644 --- a/scheduler/subscriptions.h +++ b/scheduler/subscriptions.h @@ -1,5 +1,5 @@ /* - * "$Id: subscriptions.h 5673 2006-06-16 21:04:45Z mike $" + * "$Id: subscriptions.h 5672 2006-06-16 21:04:07Z mike $" * * Subscription definitions for the Common UNIX Printing System (CUPS) scheduler. * @@ -168,5 +168,5 @@ extern void cupsdUpdateNotifierStatus(void); /* - * End of "$Id: subscriptions.h 5673 2006-06-16 21:04:45Z mike $". + * End of "$Id: subscriptions.h 5672 2006-06-16 21:04:07Z mike $". */ diff --git a/scheduler/sysman.c b/scheduler/sysman.c index 61f342dcb..6267b665b 100644 --- a/scheduler/sysman.c +++ b/scheduler/sysman.c @@ -1,5 +1,5 @@ /* - * "$Id: sysman.c 6090 2006-11-14 16:35:27Z mike $" + * "$Id: sysman.c 6291 2007-02-19 21:54:27Z mike $" * * System management definitions for the Common UNIX Printing System (CUPS). * @@ -160,10 +160,8 @@ cupsdStartSystemMonitor(void) return; } - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStartSystemMonitor: Adding fd %d to InputSet...", - SysEventPipes[0]); - FD_SET(SysEventPipes[0], InputSet); + cupsdAddSelect(SysEventPipes[0], (cupsd_selfunc_t)cupsdUpdateSystemMonitor, + NULL, NULL); /* * Set non-blocking mode on the descriptor we will be receiving notification @@ -220,12 +218,7 @@ cupsdStopSystemMonitor(void) if (SysEventPipes[0] >= 0) { - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStopSystemMonitor: Removing fd %d from InputSet...", - SysEventPipes[0]); - - FD_CLR(SysEventPipes[0], InputSet); - + cupsdRemoveSelect(SysEventPipes[0]); cupsdClosePipe(SysEventPipes); } } @@ -314,7 +307,7 @@ cupsdUpdateSystemMonitor(void) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Deregistering local printer \"%s\"", p->name); - cupsdSendBrowseDelete(p); + cupsdDeregisterPrinter(p, 0); } } @@ -370,18 +363,19 @@ cupsdUpdateSystemMonitor(void) for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) - cupsdSendBrowseDelete(p); + cupsdDeregisterPrinter(p, 1); /* * Now re-register them... - * - * TODO: This might need updating for MDNS. */ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { p->browse_time = 0; + cupsdRegisterPrinter(p); + } } else cupsdLogMessage(CUPSD_LOG_DEBUG, @@ -757,5 +751,5 @@ sysEventTimerNotifier( /* - * End of "$Id: sysman.c 6090 2006-11-14 16:35:27Z mike $". + * End of "$Id: sysman.c 6291 2007-02-19 21:54:27Z mike $". */ diff --git a/scheduler/testlpd.c b/scheduler/testlpd.c index a49950391..65b827c25 100644 --- a/scheduler/testlpd.c +++ b/scheduler/testlpd.c @@ -1,5 +1,5 @@ /* - * "$Id: testlpd.c 5868 2006-08-23 19:39:39Z mike $" + * "$Id: testlpd.c 6331 2007-03-12 16:07:31Z mike $" * * cups-lpd test program for the Common UNIX Printing System (CUPS). * @@ -184,6 +184,11 @@ main(int argc, /* I - Number of command-line arguments */ status = status_long(cupslpd_stdin[1], cupslpd_stdout[0], dest, opargs); else if (!strcmp(op, "status-short")) status = status_short(cupslpd_stdin[1], cupslpd_stdout[0], dest, opargs); + else + { + printf("Unknown operation \"%s\"!\n", op); + status = 1; + } /* * Kill the test program... @@ -296,8 +301,8 @@ print_job(int outfd, /* I - Command file descriptor */ "Hlocalhost\n" "P%s\n" "J%s\n" - "ldfA%03.3dlocalhost\n" - "UdfA%03.3dlocalhost\n" + "ldfA%03dlocalhost\n" + "UdfA%03dlocalhost\n" "N%s\n", cupsUser(), jobname, sequence, sequence, jobname); @@ -307,7 +312,7 @@ print_job(int outfd, /* I - Command file descriptor */ bytes = strlen(control); - snprintf(command, sizeof(command), "\002%d cfA%03.3dlocalhost\n", + snprintf(command, sizeof(command), "\002%d cfA%03dlocalhost\n", bytes, sequence); if ((status = do_command(outfd, infd, command)) != 0) @@ -344,7 +349,7 @@ print_job(int outfd, /* I - Command file descriptor */ * Send the data file... */ - snprintf(command, sizeof(command), "\003%d dfA%03.3dlocalhost\n", + snprintf(command, sizeof(command), "\003%d dfA%03dlocalhost\n", (int)fileinfo.st_size, sequence); if ((status = do_command(outfd, infd, command)) != 0) @@ -546,5 +551,5 @@ usage(void) /* - * End of "$Id: testlpd.c 5868 2006-08-23 19:39:39Z mike $". + * End of "$Id: testlpd.c 6331 2007-03-12 16:07:31Z mike $". */ diff --git a/scheduler/testmime.c b/scheduler/testmime.c index 460e1d587..6246b64b6 100644 --- a/scheduler/testmime.c +++ b/scheduler/testmime.c @@ -1,5 +1,5 @@ /* - * "$Id: testmime.c 5606 2006-05-30 19:40:34Z mike $" + * "$Id: testmime.c 5605 2006-05-30 19:38:02Z mike $" * * MIME test program for the Common UNIX Printing System (CUPS). * @@ -331,5 +331,5 @@ type_dir(mime_t *mime, /* I - MIME database */ /* - * End of "$Id: testmime.c 5606 2006-05-30 19:40:34Z mike $". + * End of "$Id: testmime.c 5605 2006-05-30 19:38:02Z mike $". */ diff --git a/scheduler/testsub.c b/scheduler/testsub.c index 62156bd17..4c70e7839 100644 --- a/scheduler/testsub.c +++ b/scheduler/testsub.c @@ -1,5 +1,5 @@ /* - * "$Id: testsub.c 5940 2006-09-11 18:30:09Z mike $" + * "$Id: testsub.c 5938 2006-09-11 18:23:46Z mike $" * * Scheduler notification tester for the Common UNIX Printing System (CUPS). * @@ -527,5 +527,5 @@ usage(void) /* - * End of "$Id: testsub.c 5940 2006-09-11 18:30:09Z mike $". + * End of "$Id: testsub.c 5938 2006-09-11 18:23:46Z mike $". */ diff --git a/scripting/java/src/com/easysw/cups/IPPBase64Encoder.java b/scripting/java/src/com/easysw/cups/IPPBase64Encoder.java deleted file mode 100644 index e69de29bb..000000000 diff --git a/scripting/php/Dependencies b/scripting/php/Dependencies index d17772edc..81f5921f1 100644 --- a/scripting/php/Dependencies +++ b/scripting/php/Dependencies @@ -1,6 +1,6 @@ # DO NOT DELETE phpcups.o: ../../cups/string.h ../../config.h phpcups.h ../../cups/cups.h -phpcups.o: ../../cups/ipp.h ../../cups/http.h ../../cups/md5.h -phpcups.o: ../../cups/ppd.h ../../cups/array.h ../../cups/file.h -phpcups.o: ../../cups/language.h ../../cups/language.h ../../cups/debug.h +phpcups.o: ../../cups/ipp.h ../../cups/http.h ../../cups/ppd.h +phpcups.o: ../../cups/array.h ../../cups/file.h ../../cups/language.h +phpcups.o: ../../cups/language.h ../../cups/debug.h diff --git a/standards/papi-1.0.pdf b/standards/papi-1.0.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bea5be817f3b50c3943dc81f6f2fa11ac5981b8d GIT binary patch literal 503784 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⁡)vMeNn} zPWU<-z*FA8!jCLvB8iZ5+(R#kT`4}aEPs1!!1)9iB8YKFV`CEn{G-lIuMI?u;$;Ix z(bCM&$k~?}$zd2{WN2n9-+Fi08%76c_Jog3vW7UKtn|h}#SCP4+#BY@?PsF#I)dIr z$l7*;pqR=(w`1&P3E`!#%>j>hpMHK}*NElto4Lyt%{o6a@P5i64*U)csaMm1GMO#R z->$E>`kBG3N)Q5?djpb^p)>MaDF*Q{t=>mb5jagC z;Dw)#;YKtW7bUK7>+0)I#wU)fefl#(V@a-$?uRlnAHN4I;k&X)?1Hhq$#fs=dq3>_ zP_LGyoV+jB6e?|l^o1Hw5(TQngO*D9O z?HtsVg1uA^X|CWu!DGej+VSKaiE`HIRy&?>=G$HISIV@xjQ7YG8Rfv|a%c_p;+eK4 z%O6YnRYz>A*hDO%Va$u+qNJ*Dg4YtN!6c{8Dj3d~6P8n;WzZTwA_frBC(~K+?=Ovx zGGUU*oS`K79Mb+cg$q{)8rFae0opFXRg8G!D^SSVNz^UPXj}}WJ`0R&06yqHLTz#{ zQ_Lc!+WYVu$c`$V(AtVU7z+SlhS-QI+_Q&jnba7y0zvNC(nEuXaAV8h&pW^6B@B)5 zB%QUar0la{_PYGkEYfE5n?o2(A=Q#)WqDSRjO*R^@s8nZ|7?;ZdApk?W8zgL*K=Gp zfJl0)k!{D3XxRxAo$VT0cv&^GDA6!-4yxQ?S;9I%nK+1P;8N~ai}fWd#0IwxXap-W zieguQ2+@UA4)5l%6v#`Q zO3g#fpSqpp%1WB1t|k=D7(bV2U#!!S7j6RX&86JJEk04_6za=0M43P0Q?wjx>+4e8 zlGDEM6&fog_sDZwkJjVsoT6l(rEJF0iVsQ0I1b}~s9D#x&q};`hnkgBV1}83lZu*6 z0@y^!Y>$$0ER+F_BI?E)fYNe@wZ@U3$C@@ube`qZBr_S(SGiQtocq>zGNn?O#_AQcsIb;7YZz>ztl&Mo*8 z&h&@p$MkgcF0$Av#vKX!nat|fHrx16Q($m|M_UIRv0+<4PaB0tOB@Gxms6qS5#I|7 zqnmxY$4;kq)4t3w0YRT6*#TgEHaR$GWqM#6QXf|#$cv;gB`Q_&hjrJS%VuM=Uk>~P zq&VDs(tXkDGnC2U4RG0iFdUaRj8hDET&LfCv?HZ&M?qpILA17ODSJXXIg%KKOhdXJ zmm@7T0=r)v1##zKgS?u85c@x88ga+(tg!Lb#z_NN$`je$ei5Wc6`=O(q(Na$X#?PT z@<_m|Zwa48peoA3kTgD>W}_FYBe34NO^E8%0}>v)_BHB)O&>sjb^Tm}%#UYc1T++L zZNmr^_#02#e!##WT*_KFHuTdt4RFIe4JOwq4=xZP^f6~U6-ZJk3=<^J2OusS{o*cR zJAdDzHXOeh>N407;&AaYteWL(KFQR95DFj1IErpPJ^`}nU4{CeVmdj&UQbydqq3H|_S z5cF6}#~Hms730lRwZ_Bx0~1^RP+np?N-uypDy_8>tDDOdn?lw>*dw4%K#%JvyzSp! zZf-Nmt)SL41m_NUK3mhN(hcei5Z{V*&8wp8bOy|9{B6;>cEQ<09+z*o5Z?4^ zFRij2;-*%-Z3K6MIszg#V)+fPTlRcC#Cq)h-ITEXCjrmE&iPOAUkP}&|F!V?RP-Sm zd^h{-&90-LipW^JHGz8WSEge;#2=tB6aOI-|E!5lABi;-bIIlvHsEj#TuCW%2J?(bdi+uPrBU7zod#;uVOezrX= zwLE#K6UeE0^?EtO^tRcpM=_-6cJNh-riT4OTzlch$_KY28IY|ORkd3`>Ad+|BtutR@8fbv~+gKIxQ_7&)UeaSyNZXslYm0?17+?z4bfUU0e%8kbh zUaHiQf;l?6y7f)fQpXgfulum2}p~+cJ;sO(GUxEp2Mb69S)MA zAud1i>Wd9dTWNAjQA9<0Ok|4PGxWiluo1g`;8d~>Uy{X|pns+~g~pF6Cu z`8}x7wq%tv7UbjGf}L=kYE)Nm9~u8_niK+_x?V4p1;;10ursx^xmJZoRo;Md98G9< zd0Lu;|BmxoF(wxFMl@VCGtkRZ8N$lFdzXZUHR(ys*?Q=lmx8O@IU&Z6Ex-AI)->8DWE5V*E)4ClDAWTSY&) zp!pa~xc*r1$^XhE)jyI5#jz~(jJ|U{$g4++t7kvE8Cb%N=0tK)2bHAQJ7Fih*PBC? zW^OGl3GfLV(u=GuPsT7dmAVnut#Mx|9lM6y+4{sa;BmL8^K1=xj*e#pN~rE2gi5S z0rgu|k~{li*mIO|r1~j|z`4V$Q3Jjg`83W-4_QnhI*qqvb_*riXLnzvf6l6txya6P z+-}^HinQ(XfAmdc}7FQDtrOi0fxB8Q}uvOLlBCfP14vD;FW zuOFuV`r^FW(#84jnvmo##;hjvrgXtU@o`={#aO3ZOaWl{E< z9-!pe=k@a^ge^BEoPWjen<)Z#D11B{#-Y{xni!QBww`W zd)B}QvVXGAS!;T!pSNe_n7g@UJ!QJCQuZEa?Wcg;0)krz*j6n2Y@U`U>X?!d>t~8K zLi7!58szEbN?YR4)II@cj?(+n&Rc5@p1_i4u0R2A+rVQEu$`d^CpwB2O;jxEL5WGS zYQQAMS+s?1QxTBDtUdDs3?Mak1V?6?tgfeEKTiv$6j zF%?}#^Qlb6Kg=wLTAfCje(6teW41QQzRF$c&1oQz6EBj?Od`o9g=G(8p<)={Yc(4M zrGUxJmz><@?ZDNUlga%I$n^x4Ef{|y8Pv}8Ql+?90^@8KmJQ5`157G-Lk-* z%SCR1VxUv#o8fLtgRnXjJ!-^6hDL2z30|fT7?)$g8Hf3UqvGqyZi5fC@XAxDR;K?v zAzfrSK@d2-fAGbvzL{^*xoRtMwBMs(&)$UM#1^T$9J$HA9C>*=Bo;B@z`9Z6HKa=U z{*v!6QqOHm%{bn6hsVWWnPpBPfx{|BwmXCRJ)Dp9-G0!3*mLMz=!*CKJ?QI*lkI12 zW>O`+)3wqHVh@J@s-qUYVS007ws1&mADHcfWp=Phn!vW=leEo6TatCh+)La-B+!Wy z;ErZ!T9C#pyPldocW+~@=fERDVbzngE%>pI$$ac-TsR8CZy)MQQ;&xqQOTv7$kP$K zaB*Df{R76Pd{Y1GX8!9eP>b>&0I`W!+Fqei@~A5JLDgon-D8@)4vLm}ylawx_F4g3 zQit`5gsjs~kt4IQBCBnq2Imd?W0w z-|!1QtTQjLVUvW#ft|7Ay4Aa3ldsV9?K-b}I<-fb=%NHy?2W0wLwPkc81+0pZ#6WW z#n-{qJg<7wN~@&e`nOqI(AU?BAkK>@mOX%aQG6V5^DIsd!G7LJo+3~uDa!h>Nx~O zc{X_opFa_}-?_>g9Tnjrxq9TG9O+Qx2UsMS@De}DA-P%PW>L`S=m;~%d|CPVXTS$o z%%D!v2e>;Z0YKCnWb^~W7RadTmxkyD$e)pGc^dxffd68~{uAM6X8LD_i0xkyezyM+ z;n&y*$6-hG)?M{IHT_KvC{JDlF%9&1Pl^72E548RT5{dlKrDpb;4q;t)&-(uOQhOfhxZXJ-Z#5GzZNGYc?#ao?JWg1jFS_wC zrmJ4?|1;5XLLPM=fJ^7`ORTfB5fUBUz3T4-V?a(Djcd~*s|Xbe^xE*J5FrciFVQZb z@TagNX&|Wx4QTIKC011En7D0Fg%UA9l``7){u;sW=zc5M4%_{Il>I}HFhG;GjkfKl zZQHhO+qP}nwr$(CZQFML?{`)+CuSD2s>sO9WkqIIU3b;{@KxRp-CM8FN{{aaZ#m!{ z#3V%xz|Gk0OWs+T2H8D0Uq1*bbt#G>Jz_9RXlTTg`9mmrTEq$bQ~-@rM+l9Gwf{Id zBg0@2dG)sXz8pAbItEu0T<1`(nkfx+xjWk=D1Z2TUZe0ygTm>AYlC|j1r%?6PLZro zbGSKVP}@KC_M!auw7xsoN^^aUGb@LJNpy0XUb@Vcyzo)i$VJM|YhdtCZ5_fo+mGFI zv*2pf22fG=4GjQM`D&YF09CnnSKb(0CtCg8pLdCe@+K0DEOU^V!u=E&;J1*2Dokbo!$~ntM@uK;2VHu1DOWYlD&wUSP5G?t zlwk>19z|3QL7sQ9K36oP#}XKn*JyZBcOnQ{$UDA{r0Q${O!jEUvhQmGdSN5SN?Z)NHUg~tZZ871`DJPUoH?%R>^-~5<{GIp?7 z9|`(vG7Y8Pboja(D?srg7lM=ZPS52vVfnCS!E6e9M}2Hmj6-UNpt( ze423fuQd&ac(6u{hr+Snm@Ftrb`3D5jcv*`UJltD51isYZ%BB6@8jW~kARAdCt z4{>~Y?826{o1%8szqqVcz+<+x$MFoa2F(OaiK-RdsaOqfe6Y;Zg{?O#qhh6+Rfkv$i#f%lyx&wL zEb$i?X+ZCr8}HPMjS|UoD}8s1zcr!d4HH`^NkXI1-UpMSq+ z+TvTk8W`v7`W`LccGq_HIsrAJKkn*w?o8S=@K)bUhj~?i%4GSiqKTkey1qBo)&c(5#p!2B%CeK4UksMUpgcZwhpXBAK*--4t; zbr-OY9?Xp7h6zfo$&5%Di>D4nKku7Eu{1mzR)FsX_cdt(!j_CycL0|q{PjNWrO0j< zkv$*&G~bRqY_7&=^-%3|h*syMO&Hg6b=fhj&LkcFq@d3Aje+SdhV(6fG-fKH9!9c`(6*Pb z!Y+p}=oa(Z83VcCn%Gp#l|eAMSdgMr%-Yyl2E}eQ)^bB#1-b4)$`|Y?bEmbBTM<%6x;eA76xo9s^z2qiiI(z zdsih*l)xtV>jIYPu!d;avRHr8N_-BYG}u8_%`Z=hT3LY0>4cD?K)v#JQ88YMt4wh^ zQAwgiR$W$6N~2^cSJ%d_s|<9KLsU*zu9p}(@)@>)J(b=1anF6Q{Vyfuzo5(vEcE{! zWoG>!QD)Zv8_Hawx)r%i595QE?sxw*SejVJKpirn{n>rP&zFCLD%m#gv$0p_oshFd zTrfm05l@37!J7(l=+pN_#m_AmG+0<%_H^*^D&*~h;P=X94wK(z`0e}EvF9Pg)iNRq zMPqXmB9Tc4|CKX$=J3<9$FUe%|4GasF&IlMKo=uik*Li%C=IQjcrJ}Tr=+eNiE!p{ z0E21Vs_x%O3;~5PP@pv|UVyRD4q^a8XhIZvir$|@yrm>w9}c?7+DaXu3rS|3J2nX2 zY%h7Kp52zcl}HcXoG_#fLvczwXdb{ANX{Q+COnIYNQ$Sy3$8*EPh5&y7?ea@J90*n zWgZb<%@55Bo)3jFufmU%wj(M?AMWZLI8PxZ6;^#9b-Xgt_yU5){RFsy2ueak5I1Ic^auyKT2na3q zx%kYhK!GC(D>3`rhp&T8x$6sTNhOwEK4ceE3QT+d&#&b2D}(^(Q*~gA2)iOQ_FJ|7 z)Ji|RbktGJjQ0mm=+t4t4dsaQ!Q;yJAw$lYyr-xYEL4ppUlylg!o@M0F}k4O9Q5giW!hM_8@}-OJEHgy(PFF0 zK6CZx&F;a3^#d$mKgS?7<@mm*`rkxF2=m&KK3_1DKf19eedgvo~>Od{=J>y@%gHc zIhVmNO*vvL?p>Ks%l+QZjKLR$LGyk-6KUgKpuIKPQr-MzsX1>EZF&BqgD@V%Yrpw~ zv;{TX`9z}2`}O@8G7?YL=KZn%pr!sj&`}>k&(8aE|9GB@!y~Ld-5aT~$VqfbH+zdGY9Nm@^{pTX}p#MadR&C<|V zb8V(cq@!(aP`b@^_w-Nc`QnZZd4(QHK~r_Q-V7?@fFCp6_(immM>Q)z5uz^QEa033 z+I{FvmYDtzz^1%7Zflg$J_An?Lk#(#DJ&acrM};kZ-7bY-y-e0gc}!XR+?pa7tuF( zIC@8A%hSAmXt{T$T6552zFX4eQ>gXVDsJ>hZmXC^vW1?}O$1U~oii0zc09M~X0D9& zgiHK7uK3wBm3B!Zs8})zIL)(LeT#)^7ayB@P|dTnt@++)*Er=hF5rxhzNYPP-?rwP zyjB)EXd{iN-p~H6kZ{)Ml%#qnSJnBCX?p|u)^w1(rpTk%GKG8BQkHbGKuIm$~ zquPXEc@8)qImcb{TsL$(50WhDD^Wk-$#EX(YS_z~P)2l1a_U72x7MdSY-Y5P9*E3; zmrp_k4c*(RB8?F`>u@1h8lN+oLGVEt{JtRdf4x6U#9s6Ml52H)L9f0k2;Ls+ z{B(W|g_c1B8%D6y`Qz+UI~w>AWf{+L?f?W2cXk8?yB36uq5RXxzb!&XpgGZB5f8@* z<`^`l(d@C4%q|bzrn^c0g&RpGWdo6n6VR;>>~Ur{un{wFnbH?6X@O^LB#*kRM(kDI z17Zd6(E~Dj&3<2os9U20znfl2jtfzv0~^yXzMpI^(+-%#-49sgt}huw(Rdi*;c6@Z zc1x3p09b20BJ}gsa{z!SLp^9BL*|0W4*aCS)V|-am*_3P4sqG)tD3ZYhaxK>#sYnU zG(-CKj-|y;-8;)wu6ftt$xP1N6Ut^oC_J(@SjO6{2_8SYE2=+R-xZ`6wl8`0X#iC+ zl!*#%VVFGFpckP9Fze5y7}!UXAfEtK5d)PzvjS};2-XXdp^A@sg-?s%e~WZmc_n`o zA;&yAQi4o-rwP68LhE1J%uU7`MtE!Nq;s^F@_Fdt+q~M{Cj1g>Q1vui8->~{b!Z^* zk~pT1BA5@tzTG0+zEhRQZt4PmoGLTOXQFZ2VPR2oO_Z&g_BSAt?CIiW&aaFkE7Ju3 z5QznnSK@Rx#nP4*J61F9lV{XK=?W^02ifxBpfs0P9?Dfw4hE}fRLgVPrtdV`k$O57hG!<1J=rZXlboNx7T{#4_<*1YJ6R&dZK++^p=%hN7!8h{S+jjb6_% zbFXrmd$7r7b5YqsFbFFMoh{0q4-^m68YsvV?_TzVKpqLaxDNr?Yg3^}@*e+7WTaif3I>w5^sBf@@gz_U+%mfH`Vk-->;Yw z0kZT}rw>HFOnrouRcG&p&SM|1{$8#`A6eoerTU=02mDc^Dq3Zo6k&ILD4uAfOlfcl zQy3i}Q*6=fW~zAD>KZg|ej}6GCSE~3HJR+(lrvLhGd{CB_tRr4W#-a!95juFFX`IW zk3hR{AVyG()yPEKDxN{@PQip-GH*`nHM9iTVGkVaOthDGbugPr8I+2v4Q3i3&5{vV zM}l*0WyLj}B~up5Z>oZ%AKMLmYoQdcH%KW*6U{blk?gvnI=`4;UTczOI`+(-*k^SX z#$W1dBmReqzTp{o|BVx>-_OC)liq@=_ATi%%4&#iNx!&<;25g=IM*8wZy|t{R`jjVwWcI3 zz|5wYG-+DWS-abn9r;qCxUKe%RW&y$+5)3*-dJ6sw4HJLbP-|(!hq_EJMEFPJcEL2 zQWFODBA#%63tV&a=&~ruqVo5;LePQ)ZdxdD-zEr{Ek=BA0@Pj7^|Br8FW<>qjAErT z)%;)${^q8)|O4Fu)segVz?8>v) z$@rPynIdf{{M`W_%92*EC}s=aXytpCR~Whpb6cDWG&2?yw3LgtR6g?j+drA>bfClu z)n||YHcNOgrh8v`GCx}m1&-uh-0sjpnZhZ&sQu155j@F!miM9iG2<9*;j0e;IcAJR zUr0&5C~M1+GtGXIMw-rt!|2HCEJ$-hNrF{`D5!ST!$5{{V+}i}2mSIYe0?qv6hwE+ zLwHfD?>5c2$3$A?x(%9*ZPu7f)MFpp3_#3UzbuCq&VBzrG#9WF%*?D-9T`yKPoyWl417KVlTnkVT5WXp~vp@SM_JOT3J*o3vhB zyK%s*NhDxnRMIT6%+bb7T90(Lk_s)2Ja4GIU`U)jQ1V#mPaWKBMmoz8bfiS9CCEt@ zv{z!g4>&oaO*Ub7J5eIXMNB=3K^g13QB^PH5t5es3Vp77 zUmTfdEZq?Hp50_$#Sng|nNcLPT_N}j0=3ehaR_r+-m^I`d#YkB`-T_nSsG9wXBnnl zrDUL26-Nw!HZ6H|^RdTiKwY1isoHki#=E*qcK|d)XCWQdb?vda3Bld=rZsvNZ_mQkVAH&8c0tCuyQE^5o5F+^}sY9Y-ae{u74F zeiiKTiJD5}Z!aG0lHA1YQ@K099o)v_Q#lipL~W3#dE6rF!i7F`jfGQIiG8iH`S@IM z3g$%V>h-Ct5X1r7{-4N>TL@9tVUX8}KtH_r+fSjzvD z*rzAKN{4C@_v#pUxPMK{jTuqMn}{cY(YdGB``s3F>($?w|q^UXz}@#&_2xf$8qDBlj{9t!5PCo2Q*I@o2ihR zJO@jzMBNSZ$3#0MTtZBO!=#Ll?89>Y)SNcRSCHwSR!pK)~ly@-W~P09YHx z8p>c~sK~&IAm8_E_M@@*iCF`GrsD=#qK(bn-Cr$lUe(t&DkLIy!>&n~w@{6*YhlNM z@oq7;Z2(bsCs0oUg0w!GHb2wBKJ(yGV>F>Gt{m(0(_e6!`!b*%A9;R~>1dU$9KIC( zV6bI>P<@C;KX7IdJHU&-{29be9C(QV79tbD!*9zTyt*H3c$lKfCN3Soc0I>3Uuh@x zgbW0VS3ic34{@7mJlkoX^owX4^p=BNTX7JG4E47#-;ETZL1;gxc&u6V8K3w@A}4r4 z%mg2@=pr2=5%*mEvOtsU9urKMadJw$G=|3F&#f(Ax&9-vAA+1x^BWj-S&z{@@u*go zEY)XMvmOuJ5$8^*&q|=LC(VAE(cabH%n1zQL-fFWU!28%zB7o#v~EEeOZ zK0oN$H|{SaIy}b$2-?#Sl}o^n_#Y!uD7BF1TE3z93(X8 zc$T=K59nmI09zqQStyFO4C`|4(qcOr6r!4&m^4~xv_8Yz0NDs2Zx@vE8?84#&+@BPiQef@gJD~bf;SGsLmDSP$9F)XPDLv9(FMbe#f!TI8L!4&_&8}jazVW z9K-WEAzUXfAf5g7w=+bc42L&sWRha>K&x1k4t>*8F;Wm2Wn*TG6fT|atE-4QGJuif zWKoD)aZ0n(fnB5NJSJ8&rNeInBNeY2=aV3EYhE}~{?02hZn*f)ppBSb`bF_fAxk9n zFodvY9VVl_R**QSySOkY9~z{wYifLj1P(C$>ysxe!RT73CLxv>pdMbbxQ8wY^u4n( z88*OMlB1>IybYgSdeoo9E`d|B&AYWJi{USoY3QIJ&v-xKQ8J56U$E%-)A3E+1xwd~p-(~bGaqSft9a^4 zS;ld1XtEF2V$<`N-QqCA9NlEhaKpR{2a<3%wgNP$-)Ol@@sdCJ5M(rz6A*GBs0P3Kp{w2vk3-`jmKRy*cy~yi<@F$|u>NZm*2{ zj(ES<1W2!UbNk8IDFv358AiG6=Cm0Lh6FDfcD zMPh(LN)uTLGsIv$;vY_nwtBjfaq0f?nJ3R}Fb;dgThXf^W4<7I_pWar!>&&0k=|4Q zrn6S~mBSD}ONec-3FX_L@bK39C;BsUWv4T?dnY(GXF<95&N-*eD=_sb$&R1Kn+XgV zZo#>E)hsw8qVhcrTu?KO*zrV!8?>*^rgyRn${I zb{6dfp!TH86p1XFH~m$Lg`Mz0D0~O2f%ANX&kvJbmN5RE#r;&q>w(wF2s^Mlv4ysI z`w0UXO*t0eWXQwtv zfuEKM`cH`zOQ$osC+!0>V~xy@qNHI!R9gRVE<8ALi4@=HO>7Vi!$HC=L^WDQGlNyq zD=JwuSe9AI$aZ7slEBjZGWBT=0&)PsU^nKbsO?R%FCIu8 zHU*Oc?t6#j79fW^fBjnjzt>USt)6rkW<+iMw2|e~&P=Yf?<545r{-6|GFL=G#`3d~ zjHPDQTs4Q^@mJ-YgrDr4}(d8_Uj0BLU}VrmZ6+IBwTbYRg%9@A_Nk z+6MKT9tzO=3^rwcL!%c)Agal75Jy4$TF%KvZ7mN=17EW0m2pj2x74I_DDk_gYU)=V zM&wFsNUQOPt~x4pE9X=HhM=m`5}sM+_Xd*{tTwn`i3cOS zMr7UUT4Jpiw4nyN5)^as#V#EaNgeB~ky5OEm`u8JF8~)YCXN(DpJZ}sjgbhQ7AIu9 z^P^!_1U!Wa+j)!7OTnc-mx#3<$_fsn(i_kQjt3o^cwf<}6o=pUO#@fPatJnzOo*-( zcB$82nH;1e^qAIQ2M=*Qd@f0`41Va#vyElp!Rg!-w}LMl8r@yFTOzf&IvKUO8xbS~ zwCkQlP=H>~*&94`lwr-=%rEpk`?c&^VSA)-U=aXc&#!LfhU=8IS*M`w0rR?z05yM8 zHA=nr*RX#u+>SblQw1G#Q9WS2@P@6J!zECs&F?!(Y|byF@3?ym9jG;}9i+gV_Ul><31;aClcjMh; z$@Vtc)OQ}%7;&mBo}7TqI>q~rA-yD-?GE!72#%*up3FUN!qA6ee|ut7srF(-i~zG$IQBZti33WBj@cZto< zub5R&upQLEfgct&4P9O{1L?YAQEBMo$RX43T(3A%s4?{26{$ z%J!CSC%ifRs6mGqE+>DLE5iH4=(bXm5bHJ{r@B6yzDpKwHTLFb@S@}*7njK-*SRIT zRi*|%iy@@RL`|vA!n$S0>}q*)Zn;y`%b0d0crtIf!D^QTY;?tvWah}4c73@sZy_xw zoreZg!FhIGHk=o{?QC-3X7`BHLlo%Fup=CAZ461TR;3`b$j??gBMr5;c#%%I+h~>+ zQZCDqSn_u|ReYFrfH!NrD#VulpV{g5A9J^cOYuMEzRq^?h8$Zj^xdjXx=SZ&_mviu zSRwQN&h>Te|64Boa3Gib-KwA+|C4iAL;1Ym3>%IX(o(j>g0H(=lPkOC?_L$}^8a&6 zw@S11KtB*VRF_%_bf>`K{wLETs?&CmSzniasBDmXz`Iw45<+*+B$2Xs!{~eL*3TP> z8|r@^h1mX!(1MAP@xOx@Z2zOsg6;n*wAhM0ZH4W{)88Ff17swjm;lEo-~U^_YKDFW z+$`l^KsL91{3J1nN~YO(G;JF&Waw&Y6@Iu+_#}t!)Z5$p-4b}?@z!4>de|Ex_WOH` zyRF-E`Sb7#iUVMO+42nPPEeZri?KOA!}hI!mG^2WX|B%MlD(X|5_F?$pX-Qk^(f54W; ztNnU@yM?FQBXG&{z4XmT)PrDF!0$hZ+bQ$w>ElQMW4s4<@BgIdaR7nOPBnw*et$&w zYOjG$_$g@0gUi;^<<^M9qpF;E_Z=?YoF@=o@qanQ1IGp0HV`#b81C~pH*jV`0P`+9 zA|vAd2!l2FBa}v4#Tq6EyF#p+ADZsl)8F4)W!cCL>xJ$!SfOtmid8Ma+I8pAh`4b! zbgH{Lo#XY>;iI2yyJ}>9#oroO^Z`KoLHE8p6X_L0w{T6W9ycQMtas(%wIH2T#oOEC z)>#Zt5K*(nTifH?lY9(uTbRm&c3MEemE1fqiUUK=0rol?c=uX#@|ZHehJ?X8Bzs+r zQ3|{%-~z+w!~&|CvXfixn#paA-4L+deSSfiU1 zCI@$71V^uJXO$M4SagmZL&%$)bh^N;WgX5O$6mdzYA1#Hr}ikc7On&o<@F%v9Mz@c zEVwQ1i`6T*ZiPIAKa1X+NSrpyz%1wMWYo>BuY9s1>pU7DCOZ9qil`Iy@UhzCu@e8M zl`F<}1QZyx`X%q)0t-Z@xvOzTeUG;0)H^;twM(kDiaE9#2U5}LK7Iv#HH>nn%&3S^ z*}t{bOjq&`?Hm!O(Hw0Rzy2vFz4n9}>;=pXZLg8AJ7s^^&Ru#sHdm;kX}v;D0Sfna zTcb)7!1_(VnJ||cDes>PpKJ)(j|UX(Q)q$xQp)*6?RAfoxY6LTNnR?9FEtZ*33l_S zlxQ`vv7s~{fwsN658}C6<4}uB2|X>)M*vlX!z}rnd>iSJx9Pu+VYX<`n%}f;O%g%R zP|HOp9X2M$44Z8$y6}Y4^Oi`=nRKm&!*rO^AyA6;FvYHCgj+9#YftsC4ecKC zg$g_gM|)YjG`1}L1_x4+daPWE2hyZwF~XRT=z4T!2)0>7dm%)i0pwfIOl2J!8G>y0eAfUzZ?{S z{nqXRYx-ho{k>9Udn*DA*zOQVpdH}4GgjUE&tt9nmwk4N-u^3IR{y>BwWZfY6f7I* z7CIIcMHG$zKik(7e&&8WeC*JJM_>Q=);v3g|BTw@(Sii1b}^YaHQk4g{RuoSoUuMD z7HA1`)BF8rheovdN!a@KaZ|LM%@e`e^c2rDNrh3{=ZZ>*jEzhICIMiG2iZIfF((5q z5$}ebkCMHG3+l;o+z4JofIOuyVj=RBp#tCzMz8(@9?sHUdbTfG+?pC>J@^4r752X5 z&TlKGfwaNP3x2f!yb%~XdIv$^Q4dxlcwFO(JzhlkjTDD?FWS!@V&17)JAC5=N-gcB zG{l1tizE|_E`R%nn*?2D$H;YE1RIZOt41y>bx9n<7NFlXYMF(o=3X`yc9~=tHKm#A z(C=G-A=^CQyHPCXhqsQiX{R6cIUG%BKkc0q#|=Wlvp^x81%`4(Us$1%xJr%mV5;er$=zV< zg(>)|FH^7e+{ue;0m!P5SW3*4NvnKUJItN@{EmHO-`VXea}kr2*FRx2C$!QH6q?wj z)O@FHua_)^v6@^$_X0f??J7~*j-#4JXEz0Ci0XdQpM@q zJm>W_{#CbHoE|3rb{*S!Nw9VRA)#bWAAwcL9yg{e?LW*brLclh!%umnhgG*hc}1Lhcu79mG?iv#VUE2r5Sd>_#X{wNMaRPffl|{x zhn;M!^;!@AsPpF(+Tk(Ypj%zaE?MhALV07oqn)PAFXRO(YB67J61%a_Y8ZCG)Szrj zG^JKDGl|t0fe-I*}2NcSh<>ntE;mJ~NAqCPqo*3~yLa$rgKQTnJUznf4rrNMwQ)?{Huv zHZX$MX5F*O0xJq5 z)95qy-pxoNvklhWjK1Dn;l~@}*=fr%Jt_CmUoTOHhB5h~5nN?Vwi$~zs96t2_1=0g zOO2}(+6C^OCQ=drd;&^uG1jv=imZSGwW}%-o9ALN;}I?)F-aGFt+(Vm)_!i;fxd}n za~kJb*FN4>gEGca9TAkHlB-==vF-D4x?`saRgEP!nr@gFC=Z*<&DLh)~R>`s9r$1ZP8^j@TP~ftQJVkTLx67p3dgh zSzCO@+1hOa4Kp?b@}{OLjIRyY?uFOFL0?y3d&haTU9NB^r679k+D6Aug)h=<|03*V zvczg^B(3%0AUQ0tO4fQx-6~&|@Iy^`6cbDETCqvyf-SYVrr2SYhHbU4KOzSi`!^4& z9pp7(uO37$q_tqbyf!KshZ%2(6;a~IB3Gd2m0bOtonZHz=enk>a95RG+NKwExwyes zj1JK6xSc-$GKk#E|D`SeuaX;f=Kp>}!S+8&ZrJ{BlA96jiCCfz#2z&Hzx*eF)Q%G{ z7#MPuMIV2#Z(v;jJQ#P{U!NrD(Zp!{k;_|5BYKwBWa-2KG(UZw9mf2zo#FYti^JVF59&I(|0#c(ch!Ax3-B= z_*0VPxSAf$_gU?>$J!^qCoUNb=Wd4Hk)itL`DZy#>%Z4u)G+O`_h-z!uh+Jzyu1U$ zos%s-+P=*!A59~)C&WX(-OVr$&LcIeqp~U{*R}!g_LiLVys-&WE-}D|ZGD_x-if*FybXA> zqa09@^atqJbF*n}m~P(9x@PHSVREGIrU5Pem)DH-N?juwkA$VpgULI5yUeB!T;oeBRJjiDrmSpMk^JKKrpE{|fFDTF*uB$5 z$JQJo$u~R(RD~3Tyni%FA1HAfDQ(iu!jRrkKK)bKJ+$}s!}&V~;=_D_CJng5Fz{n+ z+t@V@1#5EnSlGNngsh&IknQ})`_otlt39ZD&BVk%5RBIVjL#a^OVy?3St9;(0BQd5 zY!3tO%1i)ba?N9p?JUH@fXmWL$SK#+n0D9RoEmXtTBRj&2YPDiihPtNNHh;H z=Akc0nGQw^hGQ14>M0bjga3dU!(HE)xyI+bG{=OpXOrJN@CN(Do*sPO+l1cL%o^}a zo1AzN0a!C!7@x^!SpZ2QsV;%pLvL3LWtZVr=^O<8rZzu}(uJws?xQ_h9NC<;42Y^=7Q*jFV z@}XvA+5z=5P$SH$UDy^0qbxs}T*R&W2aVWwczD5BgJXqy;i-Wc5{ipj%qDT~06i6* zQu(t(JX&UP3s0kj&Of(`kJ>SYgQ5tZc1eXhXbcH}JE$XO==d{;&C%2at0o`~cb#XITzjT3w8 zSzcB9=I;a*D?{4XPzg1U&5s?$`*UumL5~z_$!$A`@_mB~%^o=PztQ`nNuJ1Z5Nsz0 z&7ip`1hAZAmft}ixWWh()(i8iB|6QYO0P7U5Tao8g{3bnOz|8@Ep*L^CBU8?_-j@H z4uC6Ba;S1WN}*2Z@`v|rfjJ?H72W*!5YZ1g9h&lEs8JQP6Sk{@qdV|yiE+ClltFvV z42&7mNE4Daq5a>=KESf0t58_JSRa9FdC5`Vz3p-L@5?!<0bc(Fc?r+|eCzg^d?^jy zKfafavR?nNg~Mlrat`T0zbQxBHJqPo)R(;Cl{RT4Rscmd5egEKxXhX3k@a61t5=t1ydHbaXD6~$k%M615gWqR@V%1-+S$}* zb-l^L6}sLHJ1~PIv&D8tt0GEk4Q7^Noz}~H*_QvN3R5QMWOxQ;p_A3`TO4BFtJ6<3 zWlxATzvA$VlRX0F*`(xmP3rfIyR%desBLJgahat09NL~zO&^~nWagt~OCoG=2b5sN z8^0a9%MXX?3_y9T86_{qMF%o3X)iaoW;6;$Voe1pmLkYLGe5{?pxN4*k``3>aZ`ho zTu;kE%}LNlkL~GQMeebRbGx#i;F*G~SU*VwHhbYdYUKTfMv!;?DV!z4q>V&Z?zk7X zOHySC8Wq3Ap7^}}!!+%^R>8*b5YA3bM7aJ)i2(8O&TnbjHeI?|8c!kB*hkPv)y7xG zb$;%2GNzQ)zeT1eFL;^9@P8=-l_Z8UZu+6TNPwXv1Q1B(t{iTYhkK&S8;`+zm$V^VVG0o`5D$*3gMit^u3`~ZJ?nC69Lw+%6ddfFu{B!c1T zd?Js|StB?7MUsBk_aRS9L1$M)^P{hMjz~Qt48x2SW?b|jnf(cFs8j`eIV0C&C-i$>2 zW330T=}V?PqQS6l=8?mo6M&smW$~lwv|p>at#I2@7kzFX|Wm|lvxI1G=xM2 zX1)a>xC2FStw!n@hYnO61s_Ljh=nz6ri;8wQ|(Fsn6!;4)lEmHN0Th%Kq>wy9rrvD z)KlgGD>pNvT!pvZmD!ujfrAKs#^@8B_GXP-3_4-0v{+x%9*3K(U`#^dr=E@O(vP7& zpqart%{p3N(E}Q7<#gc+FS#XdnM^>+_SOYy9MA?Ouwx_6;y8Iyjal)T=1$wh%*`P4 zz2JDL?<(nEzYA|gFMg5=1C0ZrVLV8^X;6a}(S%@i^npUP6pCcVAv~=kmcD5GjGV}U zV@NNldHYhO{%oCcNhFdPDSKq7W{S6RPMGqh;Kwz4HQPvy4$iCPLN(+Gk8ld~o=0~Z z^D;)9&+uj_s~}xd8P=(^$VXd9o4=}BUWHal$}+Po%~qcC$&t<1$gQ$w>?bS!2fSZO z3ZUIDS^)cGedwYx0(5~s(sBb5>yfLRVUjJ=+TXb7;cnRQmH^OSljz~Ds516bmmh5? zkV+Ho7|Tt;mYTg8vB#jJVyHTjUV_jGwD>lng84Q30D0Py&RSf*v+_|j#Fo^>KA_V5 zJwZI$SjgRjm^{QUU&am1(H;R4=U;|goS5Y<&va0QOV86Kv8BN!ChklOcQS#?EwUPr z^66qSv#xO`RvxUim=1MC7bz%!gMw87<)WK%T|7Ge{Lm?F{O8%$Tw&E&hWpf-Y&Cd194-evd6GJr4fjY|b6$hpYuz~Gb8;JTk)kAEQ@w>+XFD(DRBK2O z&{!SQ94PUneuv?*wsKoOkYybrT7{Cb4Ano|2-xiW&P(;&Q)q?-i*wt zph1N9#i@k97#H9@I~urYzKVfo?BG!uoM+h9k4bWAvPni>qxX< zfa_{x!+;K=fJ6u?z_H;z^wLT<4};NG@Enj-ESq?cI!8Y9v|L30((TIi&b9KP0lXzY z*nr^|Xy`y$MoPxSP+H9{!K_CzDBAu6%DVw;Dy2rX;N*-AA5R_%QQDfWUvMtWQ_rQ% zmjfdP%RR=C&*{Dh^z(?!7s{W7gnwPTjjZ`WSw%te>-IgU8vrZDHJc3B*!1nqu+})GX z%HMY_G+`n&qFs`SP%Z=}MirvA5!Y6HwvMg1-|C==00wzF4UAE|;fDItstA5Wld?We zF@xPH!t9hz^8lRLz?otG#dqZdB?B!H=2&QP8ISAZt)@85C9(HyXgz71Uq+B8B8D)G zxL@F&n(Z>}N5P-IGfJs@jouOqr(mN%1Pu9?wTO|wZ2U~_)PTz{!)cfNEttdN&?sY zDRCuB!dwzy)NYt|rd)+4PaZzyNLcIpISf}&n2=-CE8OUB z_yyk~23&p_)K4BF;TfMTM_37njNIekwPzuLbM`#uN7f9gLu%EVPE%YZEMunR!Cfnk zE6+RvcNbeb%*smtRz>k0b_o;Vmm0@L9#i}N4Po6Sq(n4yPY!Te`V04>VTJSI+24F( z0>d$0TSM{cMdGGRiI0C(V&7+4R;82O=4358cY?d@dY1j) zV&6|q=ab#=O3|06YjkOzPLqJ zM;v92Xi;Yot-BMJdi0}{ga^a!vtKtMo#>ZL`l{il#xO<6ZOh&udDMlOX6#6~9<({l z2?;w--`L-y3*ExyO4WDGT2FAD8l6y^?i!vKyWFKrI^!ovW{!!q9{DNZcVDLD15(s747N55(G?3)G_TNI+td$GP#U$}fB2d3FR(Q;0}IRl7XK}5&Gz5H z);*g4@4BO&{!dUIs4*Ouz}LUth6x0*(}(69+IT zc3NInAGaXHy3bq52fUcO{}2>0C&u@t&)eEZ*6A^h+~@4}7Hhf~cPF+q0Hb}X9Zu*b z)#f){kK%66gYVaYtoNsVzb0RFT6-fn?k_Bf>21|XfmQ)^G568dJ2+r7biHd}42!pS zGI;$7LBsLvLrwC5IJ_cAfX_0M2m!Gt4qji3sjp)Eoo?0++VhV@sh*1^tteM z*mrc<<5N|uZlPIO`F4AMKcZ93qw@9}?!pFHITynPLKQ*{2EwKuP$i=6^&q?!Q1+O* z-+1NFYBV7V4V&jp3$4zKyQHfq3Z{k&shLDiSp0;JGJvz4)0KrV)bIC-jpEl(Yob4T z_H)gkBuVfkYVF-&c8PAGg#Jo5lz@pE$R*$Bwy9Dik?NUPrs^zQrAP(1#p}dhW}VDp z3lfYE5j$`Sfzy}s@|kb8b8h|xszOz z;>a_|TXChy;s;W|2x%p970}+!)nfUCUOtvg`F!Pyw%hoTeXoedA|Ky&w|6V~3lAw- zYCreLK}hONf#Vl}v*7Ziu{!>!Kfd)w&UMDR`-_UX zRJLhN0f~HEb;JUVTeY6@q+aJVC>>sn%1tTcccp<{0~9p9V(L^HqNKPSf`3b4csiT_ zaVT#W2pkqi3#$fl2h)nXKn`=1k6uz4F?mSdi*uWtXXkq@u}O25!veEJJc~|p5rvY~ zonD5Ko1@7dwWu@QX_*j&?bI=4HE`J&U1u)ui*3GKz;~=1@zUG70SX5Iptmh8c6=`A ztmAguB$R)I#vK!VE&Fq3D}o4@`HcNK4F6&@>lKNV`)4nJ*T&1Sk!*KF?sD^mUVb=a z>mbpUh=XTpYpU1v^6+Cc{id*yzD5)>5vSQRe3l$%B6G027Qa7+U1^q|YjG>$K7HgV z8GZW5)a50C88^!vvOwhC;p5W*vuCT%7y|NhiC>E22GPy_F93vLu6VaU;4=2*No!F= zvP+o@gLKf6(22z3Rx$$bU`9vnGk#ShF5v#RWX5@zEEYto)xCIK4`PA~@K&sj&TkGE zz&Ub<^G@XA@vx-gVfpW+{Z2IfFJ`oU)*xhpQiUBax_v^n;9;1h-*$RnSbXpyF_`uk zsp3;SXL=x`^f3&Ngr|YfK~IiVqo(>NzwUB+3$TGA);@rcBOKu-(hx}!d@wth8wF*- zROLo-2KcE-VkE^_%Z5$8LucQEkmb+N1pHsmoU)al#aKRrxvMi5AjSKI(tN7Xb49uu z_o(7`^>pbJC5y%K$jyY-#e1~kHiAmc%~W9EKUVZ+P~ywGrp$hB3B zj9nd_4RgcLebb(g9n|vrNJYyV2SoH1a7<`>cD_QP3V528QuKNGFjH%>!@Ys1=gKI` z@Px%>bHp}4X6=)BNIDBq=v#8|$ab$P0?Lr-K7qLzVIg3=QRLzlw0~xBcQQJwP_l?+wVOEmCmdJ&mxe>{k;vh#@8b53 zhTQA>e^ALM4Iye2h*4S+K{%((VVudKMJc}t?Pqcq;5HC{EOHn0qfH&*jBsRlaNyHc zWJd$iq!nBF@#K1r*3|^8o)VDp^uH5`T50Z8BG;jaFxsePnFaLT-GL%mvY$@-myR|) z`&&lDMxn%JNCTCqQ{>l;YJD@(>%i1%z->L#e)vwYqE~aIH8jWZPCI@JPouvfoCp@5 z5M)DtC@CRc=&x<@H6Ocz9AzG}xGR=Qyzke3a9XYtJ2@s(L*hjx>Y0w}Z^@^6!!Ky6 z(sD|qSU%h@8!+PzoWd8a2Fff+!c2c~(zuzd+D6~BJY2*Kb(Y9#p_GomMi!ctOlpyM zix{MSWJr}9#W1}Ioi`;$p=T?7%<~ttT-Sk#JU^{tTclt<2#`o6x?8r+yA&E#U6|62Vw|4Y<*who3cgsf{d07( z>XLlM&I8cb*`LEe7GVghCw9Y9Uet5ch9%i#tL5bd+C&H%CX9+Dzj9CeOo@b=Q@HCR3xE09fymTIOxGi?x@C6iu&9uZuN$QsN;C&V>Rg zNXj<=IZwnEb0*9^vWc+@o6lk3r!e-?^(N3x0)pAact_p&A=(l7d%Ei!?Rwy=FfMWf zn`t{SpF+EEE$!+*&mJOq*t(+)lS7XUmj-FXvzcd~Q=lEeVV#D3^B;zy#W4Ad1$GM@ zO7Gf<@wS?0Tim1mBbs%(f_VhZW{m0x?BqL@a;U|#on>1T{v&Ccd7Atqt!AWZ2>2Gd zyl%~Vx;B0=7s%>V?AtEGF}A77NiQo&O{WNM=e80aWJ<2&b`l<}LQ6e`bNO%|tlIv? zwt_=!^CZ`-$WyrsyY`DW*WCUOPWNBKwOH9$|F`&WtC6t%chyK%w6-g+SmAqj>vs)w z&^tvNjmQHO)%#vTKp#MuXdeq1dNS7PE`|9Ta%f&IdmuuGI3N<&Q%mF)%_d-Ee|-Et z=AdNx1~KIjalg1`&v*HLeBMtH%J_D6_i%tt-KlOc0Zh7haB1S zIlW(=?-O9&dn0y~X=TO!?YyIadvo@<&!YjM zguK1`;IVd?Eeo4m>w~c>jDcFrwE|9!qdL>?i;FTBDrRhbj>1XL{Q~ZcYutuSj!2Yt zU*-s7_Rc7C;oLm?XF27glf_wALL z#<>WFp^N@7v4(Q%D}g_|R1ps1qSS3+au5=~(Z%P$Pr{pv&VDNw>joNZ!OkG}r=dRe|6~FU)VGIvE_x#G` z46w~R&M`hJwAc8bQj?guQFo22g)2Jt2XsGjwyJ(ASfR=nnxP9{r5>27Xmf0-j?C(Z zJt(heZH}Y(BH+IkAh=bCn=FeFfkuLdI#wgvF;=Re_BYDJ(_*TcNu>vJg*-kl!oh$}u@NyeN8~tBQj@(m|1G0UD!*cTwCEu93 zhZ8C*j_vMV{|RNoA#A6HgWlU0^n++4X61~A-{>V1>wwA*=2ZBz zK+tc%sXe(sQ`@0DX$&nhx#P0OIX;Ng=2Lpp+2tb9FmEN7 z?rQ8W4s76$NXCYL18U(6Ng0c7pG(;>E6i1zjNw%1Lv);yO|s_3UPg08Bq(VHHBMQN z{KjlF(aoQ*K>jUxbMNk5$}U$cO30P2>utklea_z#(u3`+2U62kH|gD9h-Jj%PSnZ(zI+XE_f=mSC@Y zJ_0k1s4G?r>twk7gQuH5KQv4AJ$Z3>G=d}sw}VJm9-)KxvOYam%_9=S#H`{dfryRn zR|8d*2cL)%F4Sa_j2k9n&la3I2v(&b;SP;YWE2I7cWbcEm4pO0F*Sq1yX;Qt_^0sp_jKvinl>_O->i`KEoZXg=k}3IEa|@0rTEm0&PYX403@ z{45zXaNS5!oY*Ic%K?vLOH+K6F59>m4AYLbv9bi`o=jSJvM!G+q_Ho2PEvBbfPJAB z%R(im&Lc4G5SqICSXj?>woigVtzp7VRG_9)xq?d6+g#aPIHz5i?k)KqRaV^w=#5F^ zI<>vleW{%*FZWbtqQ0{II9NlCW_T+RQFA516QPxr;cWiPxrdS!8n2i=Gd`EY`e-3Y zqYuP{?m3zVOz;K(V$fry#GYc_N}FXFZ*?tfQ$j-s2BZ2)215ZC02z&?}_TN#+BGjOraU+rWTtr3j`}al$Y8i z>9M3xb~FRGv+z8QCSZ|rif!C986?q#^f2fF&#^Kr? zV}*z`RIPJ6#XRYWMx?I)^M)E6vHfl};FnCzR&|?EC{2jG=vj>q_?sx|O$4nN|5C&w zQ+pNr2gd$+?TIrnni`kolywHQmN}V&ZJQRse$#rx47eK~9aW(1s@r$=?$p+c)Rwn4 z;S@yZxS--7A9%{NQq-1l#98UI%Bk^jO}oT6hLh^R_j5`nkwxIZT#&yCqF!ae?WLG| zm1jLCR~Z4|qO>_HrhYR&;Q6Ko?5I?v0dDgAM1R(JFG*UZepm z!qwwVF-bbLz(XkrE=t|t1P6qF(=#Yjz8<^l=XujDemm)?Ng2*cH!WR)p|3YYs|S(P zIPBM)WBbmU(v_u;u(@zqTAyw8`?v{M(RO1IA@T*nzkF#tCvPUC5Fv+geeZ|%E9>|o2HfT4c|MHyi|ZHZ z)pyYZrCVn)NmLULwJcFEuy|+t@X?~OZ!I>nF!i%?hBQ+lO_d4c!?m=|gkwvyy8d%8s#5{Ute8n4Q`Jf_Iw(Pj#;z+o>;o z+9QJ1gvxQ*ZY_v-%FMlWPr31QGX1W>w6#mBRO(6R(F?ea zMe@4uV*MSr#B3``0tw=#-SbMj*$M$x=Y=MMlfXwM?o)jsf|LDK^>ZM6vr+u>LD}OK zy^hbvb0x}~V$=u}KxAp0Cc<9s25)O;j0$#-AZ|$Tteb?JY#$RfBh+Fs$gW8(` zU1?+`humw9R*WGP7z6X#f>vAK6L2UcI@*|)n>Y&}2_^729+IuJ%hjR+#slUiUe?c| zmDHO_@VI+@HM~AH9{tCuoRUoryAlxgL>m|z-6=klg=Qi2ITHgu=E`X@2i;W5-9_`% zS7Uf$lc)|`Z|3lHM^GK@g9x-J05}6Bsbr52#o$}%H9owiGkv1MI8k Y^wbzRjt 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 z

    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�? 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 + if ((attr = ppdFindAttr(ppd, keyword, option->keyword)) == NULL) { if (verbose >= 0) { @@ -1083,6 +1084,21 @@ main(int argc, /* I - Number of command-line arguments */ errors ++; } + else if (!valid_utf8(attr->text)) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad UTF-8 \"%s\" translation " + "string for option %s!\n"), + langstart, option->keyword); + } + + errors ++; + } for (ptr = option->text; *ptr; ptr ++) if (*ptr & 128) @@ -1116,7 +1132,7 @@ main(int argc, /* I - Number of command-line arguments */ snprintf(ckeyword, sizeof(ckeyword), "%s.Custom%s", langstart, option->keyword); - if (!ppdFindAttr(ppd, ckeyword, "True")) + if ((attr = ppdFindAttr(ppd, ckeyword, "True")) == NULL) { if (verbose >= 0) { @@ -1133,6 +1149,23 @@ main(int argc, /* I - Number of command-line arguments */ errors ++; } + else if (!valid_utf8(attr->text)) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad UTF-8 \"%s\" " + "translation string for option %s, " + "choice %s!\n"), + langstart, ckeyword + 1 + strlen(langstart), + "True"); + } + + errors ++; + } if (strcasecmp(option->keyword, "PageSize")) { @@ -1142,7 +1175,7 @@ main(int argc, /* I - Number of command-line arguments */ { snprintf(ckeyword, sizeof(ckeyword), "%s.ParamCustom%s", langstart, option->keyword); - if (!ppdFindAttr(ppd, ckeyword, cparam->name)) + if ((attr = ppdFindAttr(ppd, ckeyword, cparam->name)) == NULL) { if (verbose >= 0) { @@ -1158,12 +1191,30 @@ main(int argc, /* I - Number of command-line arguments */ cparam->name); } + errors ++; + } + else if (!valid_utf8(attr->text)) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad UTF-8 \"%s\" " + "translation string for option %s, " + "choice %s!\n"), + langstart, + ckeyword + 1 + strlen(langstart), + cparam->name); + } + errors ++; } } } } - else if (!ppdFindAttr(ppd, keyword, option->choices[j].choice)) + else if ((attr = ppdFindAttr(ppd, keyword, option->choices[j].choice)) == NULL) { if (verbose >= 0) { @@ -1180,6 +1231,23 @@ main(int argc, /* I - Number of command-line arguments */ errors ++; } + else if (!valid_utf8(attr->text)) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad UTF-8 \"%s\" " + "translation string for option %s, " + "choice %s!\n"), + langstart, option->keyword, + option->choices[j].choice); + } + + errors ++; + } for (ptr = option->choices[j].text; *ptr; ptr ++) if (*ptr & 128) @@ -1418,8 +1486,7 @@ main(int argc, /* I - Number of command-line arguments */ if (verbose > 0) { if (errors) - _cupsLangPrintf(stdout, _(" %d ERROR%s FOUND\n"), - errors, errors == 1 ? "" : "S"); + _cupsLangPrintf(stdout, _(" %d ERRORS FOUND\n"), errors); else _cupsLangPuts(stdout, _(" NO ERRORS FOUND\n")); } @@ -1790,5 +1857,81 @@ usage(void) /* - * End of "$Id: cupstestppd.c 5926 2006-09-05 20:45:47Z mike $". + * 'valid_utf8()' - Check whether a string contains valid UTF-8 text. + */ + +int /* O - 1 if valid, 0 if not */ +valid_utf8(const char *s) /* I - String to check */ +{ + while (*s) + { + if (*s & 0x80) + { + /* + * Check for valid UTF-8 sequence... + */ + + if ((*s & 0xc0) == 0x80) + return (0); /* Illegal suffix byte */ + else if ((*s & 0xe0) == 0xc0) + { + /* + * 2-byte sequence... + */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + } + else if ((*s & 0xf0) == 0xe0) + { + /* + * 3-byte sequence... + */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + } + else if ((*s & 0xf8) == 0xf0) + { + /* + * 4-byte sequence... + */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + } + else + return (0); /* Bad sequence */ + } + + s ++; + } + + return (1); +} + + +/* + * End of "$Id: cupstestppd.c 6322 2007-03-08 19:25:26Z mike $". */ diff --git a/systemv/lp.c b/systemv/lp.c index f4658ccf9..526930cd7 100644 --- a/systemv/lp.c +++ b/systemv/lp.c @@ -1,5 +1,5 @@ /* - * "$Id: lp.c 5926 2006-09-05 20:45:47Z mike $" + * "$Id: lp.c 5925 2006-09-05 19:43:11Z mike $" * * "lp" command for the Common UNIX Printing System (CUPS). * @@ -840,5 +840,5 @@ sighandler(int s) /* I - Signal number */ /* - * End of "$Id: lp.c 5926 2006-09-05 20:45:47Z mike $". + * End of "$Id: lp.c 5925 2006-09-05 19:43:11Z mike $". */ diff --git a/systemv/lpadmin.c b/systemv/lpadmin.c index 92ecc8667..f48677dd1 100644 --- a/systemv/lpadmin.c +++ b/systemv/lpadmin.c @@ -1,5 +1,5 @@ /* - * "$Id: lpadmin.c 5926 2006-09-05 20:45:47Z mike $" + * "$Id: lpadmin.c 5925 2006-09-05 19:43:11Z mike $" * * "lpadmin" command for the Common UNIX Printing System (CUPS). * @@ -1986,5 +1986,5 @@ validate_name(const char *name) /* I - Name to check */ /* - * End of "$Id: lpadmin.c 5926 2006-09-05 20:45:47Z mike $". + * End of "$Id: lpadmin.c 5925 2006-09-05 19:43:11Z mike $". */ diff --git a/systemv/lpinfo.c b/systemv/lpinfo.c index dbbe3f63c..26f4cf495 100644 --- a/systemv/lpinfo.c +++ b/systemv/lpinfo.c @@ -1,5 +1,5 @@ /* - * "$Id: lpinfo.c 5926 2006-09-05 20:45:47Z mike $" + * "$Id: lpinfo.c 5925 2006-09-05 19:43:11Z mike $" * * "lpinfo" command for the Common UNIX Printing System (CUPS). * @@ -436,5 +436,5 @@ show_models(http_t *http, /* I - HTTP connection to server */ /* - * End of "$Id: lpinfo.c 5926 2006-09-05 20:45:47Z mike $". + * End of "$Id: lpinfo.c 5925 2006-09-05 19:43:11Z mike $". */ diff --git a/systemv/lpmove.c b/systemv/lpmove.c index 5545ddf9a..a46efe0f6 100644 --- a/systemv/lpmove.c +++ b/systemv/lpmove.c @@ -1,5 +1,5 @@ /* - * "$Id: lpmove.c 5926 2006-09-05 20:45:47Z mike $" + * "$Id: lpmove.c 5925 2006-09-05 19:43:11Z mike $" * * "lpmove" command for the Common UNIX Printing System (CUPS). * @@ -235,5 +235,5 @@ move_job(http_t *http, /* I - HTTP connection to server */ /* - * End of "$Id: lpmove.c 5926 2006-09-05 20:45:47Z mike $". + * End of "$Id: lpmove.c 5925 2006-09-05 19:43:11Z mike $". */ diff --git a/systemv/lpoptions.c b/systemv/lpoptions.c index e69bd5a6f..e6778acc9 100644 --- a/systemv/lpoptions.c +++ b/systemv/lpoptions.c @@ -1,5 +1,5 @@ /* - * "$Id: lpoptions.c 6205 2007-01-22 22:04:43Z mike $" + * "$Id: lpoptions.c 6202 2007-01-22 21:37:45Z mike $" * * Printer option program for the Common UNIX Printing System (CUPS). * @@ -484,5 +484,5 @@ usage(void) /* - * End of "$Id: lpoptions.c 6205 2007-01-22 22:04:43Z mike $". + * End of "$Id: lpoptions.c 6202 2007-01-22 21:37:45Z mike $". */ diff --git a/systemv/lppasswd.c b/systemv/lppasswd.c index 8ad801fd8..362fbf208 100644 --- a/systemv/lppasswd.c +++ b/systemv/lppasswd.c @@ -1,5 +1,5 @@ /* - * "$Id: lppasswd.c 5926 2006-09-05 20:45:47Z mike $" + * "$Id: lppasswd.c 5925 2006-09-05 19:43:11Z mike $" * * MD5 password program for the Common UNIX Printing System (CUPS). * @@ -511,5 +511,5 @@ usage(FILE *fp) /* I - File to send usage to */ /* - * End of "$Id: lppasswd.c 5926 2006-09-05 20:45:47Z mike $". + * End of "$Id: lppasswd.c 5925 2006-09-05 19:43:11Z mike $". */ diff --git a/systemv/lpstat.c b/systemv/lpstat.c index 27f0926e8..4830117c1 100644 --- a/systemv/lpstat.c +++ b/systemv/lpstat.c @@ -1,5 +1,5 @@ /* - * "$Id: lpstat.c 6090 2006-11-14 16:35:27Z mike $" + * "$Id: lpstat.c 6084 2006-11-14 14:35:53Z mike $" * * "lpstat" command for the Common UNIX Printing System (CUPS). * @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -2248,5 +2249,5 @@ show_scheduler(http_t *http) /* I - HTTP connection to server */ /* - * End of "$Id: lpstat.c 6090 2006-11-14 16:35:27Z mike $". + * End of "$Id: lpstat.c 6084 2006-11-14 14:35:53Z mike $". */ diff --git a/templates/Makefile b/templates/Makefile index e1b5babc7..908e622b3 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5878 2006-08-24 15:55:42Z mike $" +# "$Id: Makefile 5877 2006-08-24 15:54:12Z mike $" # # Template makefile for the Common UNIX Printing System (CUPS). # @@ -156,5 +156,5 @@ uninstall-languages: # -# End of "$Id: Makefile 5878 2006-08-24 15:55:42Z mike $". +# End of "$Id: Makefile 5877 2006-08-24 15:54:12Z mike $". # diff --git a/templates/add-printer.tmpl b/templates/add-printer.tmpl index cff93eb29..b8c440fe6 100644 --- a/templates/add-printer.tmpl +++ b/templates/add-printer.tmpl @@ -1,22 +1,23 @@

    +{device_uri?:}

    Add New Printer

    - - - diff --git a/templates/add-rss-subscription.tmpl b/templates/add-rss-subscription.tmpl new file mode 100644 index 000000000..4f9235125 --- /dev/null +++ b/templates/add-rss-subscription.tmpl @@ -0,0 +1,43 @@ + + + +

    Add RSS Subscription

    + +
    Name:
    +

    (May contain any printable characters except "/", "#", and space)
    Location:
    +

    (Human-readable location such as "Lab 1")
    Description:
    +

    (Human-readable description such as "HP LaserJet with Duplexer")
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:
    +(May contain any printable characters except space, "/", "?", and "#")
    Queue:
    Events:Job Created
    +Job Completed
    +Job Stopped
    +Job Options Changed
        Queue Stopped
    +Queue Added
    +Queue Modified
    +Queue Deleted
        Server Started
    +Server Stopped
    +Server Restarted
    +Server Security Auditing
    Maximum Events in Feed:
    + + diff --git a/templates/admin.tmpl b/templates/admin.tmpl index 470faaa77..056790dfd 100644 --- a/templates/admin.tmpl +++ b/templates/admin.tmpl @@ -1,5 +1,5 @@ -
    +

    Printers

    @@ -36,7 +36,7 @@ ALT="Manage Classes" CLASS="button"> Jobs" CLASS="button">

    -
          +         

    Server

    @@ -65,6 +65,7 @@ CLASS="button">

    Show printers shared by other systems
    Share published printers connected to this system
    +         Allow printing from the Internet
    Allow remote administration
    Allow users to cancel any job (not just their own)
    Save debugging information for troubleshooting

    @@ -75,3 +76,16 @@ CLASS="button">
    + +

    Subscriptions

    + +

    +Add RSS Subscription +

    + +{notify_subscription_id? + +{[notify_subscription_id] +} + +
    IDNameEventsQueue
    {notify_subscription_id}{notify_recipient_name} Cancel RSS Subscription {notify_events} {notify_printer_name?{notify_printer_name}:All Queues}
    :} diff --git a/templates/classes.tmpl b/templates/classes.tmpl index ef13feca2..bc87f9f58 100644 --- a/templates/classes.tmpl +++ b/templates/classes.tmpl @@ -13,10 +13,11 @@ {printer_is_accepting_jobs=0?rejecting jobs:accepting jobs}, {printer_is_shared=0?not:} published. {?member_uris=?:
    Members: {member_uris}} -

    +

    + + + + +
    -Print Test Page -{printer_state=5? +Print Test Page{printer_state=5? Start Class : @@ -31,8 +32,8 @@ Reject Jobs } -Cancel All Jobs -{printer_is_shared=0? +Cancel All Jobs{printer_is_shared=0? Publish Printer : @@ -46,8 +47,9 @@ Set As Default -Set Allowed Users -

    +Set Allowed Users

    diff --git a/templates/de/add-printer.tmpl b/templates/de/add-printer.tmpl index db60277f9..2313910cc 100644 --- a/templates/de/add-printer.tmpl +++ b/templates/de/add-printer.tmpl @@ -1,22 +1,23 @@
    +{device_uri?:}

    Neuen Drucker hinzufügen

    - - - diff --git a/templates/de/admin.tmpl b/templates/de/admin.tmpl index 9bf668631..170c42c36 100644 --- a/templates/de/admin.tmpl +++ b/templates/de/admin.tmpl @@ -1,5 +1,5 @@
    Name:
    +

    (Darf alle druckbaren Zeichen außer "/", "#", und Leerzeichen enthalten)
    Ort:
    +

    (Für Menschen lesbarer Ort wie "Labor 1")
    Beschreibung:
    +

    (Für Menschen lesbare Beschreibung wie "HP LaserJet mit Duplexeinheit")
    -
    +

    Drucker

    @@ -36,7 +36,7 @@ ALT="Klassen verwalten" CLASS="button"> verwalten" CLASS="button">

    -
          +         

    Server

    @@ -65,6 +65,7 @@ CLASS="button">

    Zeige verteilte Drucker von anderen Systemen
    Verteile publizierte Drucker welche mit diesem System verbunden sind
    +         Allow printing from the Internet
    Erlaube entfernte Verwaltung
    Erlaube Benutzern jeden Auftrag abzubrechen (nicht nur die Eigenen)
    Speichere Fehlerinformationen für Fehlersuche

    diff --git a/templates/de/edit-config.tmpl.in b/templates/de/edit-config.tmpl.in index 4cfcad1a8..dc3f09c32 100644 --- a/templates/de/edit-config.tmpl.in +++ b/templates/de/edit-config.tmpl.in @@ -9,6 +9,7 @@ function reset_config() "\\n" + "# Administrator user group...\\n" + "SystemGroup @CUPS_SYSTEM_GROUPS@\\n" + +"@CUPS_SYSTEM_AUTHKEY@\\n" + "\\n" + "\\n" + "# Only listen for connections from the local machine.\\n" + @@ -19,7 +20,7 @@ function reset_config() "# Show shared printers on the local network.\\n" + "Browsing On\\n" + "BrowseOrder allow,deny\\n" + -"BrowseAllow @LOCAL\\n" + +"BrowseAllow all\\n" + "\\n" + "\\n" + "# Authenticate against system accounts by default...\\n" + diff --git a/templates/edit-config.tmpl.in b/templates/edit-config.tmpl.in index b457fadaf..998514df7 100644 --- a/templates/edit-config.tmpl.in +++ b/templates/edit-config.tmpl.in @@ -9,6 +9,7 @@ function reset_config() "\\n" + "# Administrator user group...\\n" + "SystemGroup @CUPS_SYSTEM_GROUPS@\\n" + +"@CUPS_SYSTEM_AUTHKEY@\\n" + "\\n" + "\\n" + "# Only listen for connections from the local machine.\\n" + @@ -19,7 +20,7 @@ function reset_config() "# Show shared printers on the local network.\\n" + "Browsing On\\n" + "BrowseOrder allow,deny\\n" + -"BrowseAllow @LOCAL\\n" + +"BrowseAllow all\\n" + "\\n" + "\\n" + "# Authenticate against system accounts by default...\\n" + diff --git a/templates/es/add-printer.tmpl b/templates/es/add-printer.tmpl index 66c06e97b..82c004fe4 100644 --- a/templates/es/add-printer.tmpl +++ b/templates/es/add-printer.tmpl @@ -1,22 +1,23 @@ +{device_uri?:}

    Añadir impresora nueva

    - - - diff --git a/templates/es/admin.tmpl b/templates/es/admin.tmpl index b80f46f88..3cd99e0dc 100644 --- a/templates/es/admin.tmpl +++ b/templates/es/admin.tmpl @@ -1,5 +1,5 @@
    Nombre:
    +

    (Puede contener cualquier carácter imprimible excepto "/", "#", y espacio)
    Ubicación:
    +

    (Ubicación fácilmente leíble tal como "Lab 1")
    Descripción:
    +

    (Descripción fácilmente leíble tal como "HP LaserJet de doble cara")
    -
    +

    Impresoras

    @@ -36,7 +36,7 @@ ALT="Administrar clases" CLASS="button"> trabajos" CLASS="button">

    -
          +         

    Servidor

    @@ -65,6 +65,7 @@ CLASS="button">

    Mostrar impresoras compartidas por otros sistemas
    Compartir impresoras públicas conectadas a este sistema
    +         Allow printing from the Internet
    Permitir administración remota
    Permitir a los usuarios cancelar cualquier trabajo (no sólo los suyos propios)
    Guardar información de depuración para búsqueda de problemas

    diff --git a/templates/es/edit-config.tmpl.in b/templates/es/edit-config.tmpl.in index 5ebd84cd7..28a11beaf 100644 --- a/templates/es/edit-config.tmpl.in +++ b/templates/es/edit-config.tmpl.in @@ -9,6 +9,7 @@ function reset_config() "\\n" + "# Administrator user group...\\n" + "SystemGroup @CUPS_SYSTEM_GROUPS@\\n" + +"@CUPS_SYSTEM_AUTHKEY@\\n" + "\\n" + "\\n" + "# Only listen for connections from the local machine.\\n" + @@ -19,7 +20,7 @@ function reset_config() "# Show shared printers on the local network.\\n" + "Browsing On\\n" + "BrowseOrder allow,deny\\n" + -"BrowseAllow @LOCAL\\n" + +"BrowseAllow all\\n" + "\\n" + "\\n" + "# Authenticate against system accounts by default...\\n" + diff --git a/templates/et/add-printer.tmpl b/templates/et/add-printer.tmpl index 21fd997b8..ac59291c5 100644 --- a/templates/et/add-printer.tmpl +++ b/templates/et/add-printer.tmpl @@ -1,22 +1,23 @@ +{device_uri?:}

    Uue printeri lisamine

    - - - diff --git a/templates/et/admin.tmpl b/templates/et/admin.tmpl index e04ec96c9..e7d38428a 100644 --- a/templates/et/admin.tmpl +++ b/templates/et/admin.tmpl @@ -1,5 +1,5 @@
    Nimi:
    +

    (Võib sisaldada kõiki trükitavaid märke, välja arvatud "/", "#" ja tühik)
    Asukoht:
    +

    (Arusaadava sisuga asukoht, näiteks "Laud 1")
    Kirjeldus:
    +

    (Arusaadava sisuga kirjeldus, näiteks "HP LaserJet duplekseriga")
    -
    +

    Printerid

    @@ -36,7 +36,7 @@ ALT="Halda klasse" CLASS="button"> töid" CLASS="button">

    -
          +         

    Server

    @@ -65,6 +65,7 @@ CLASS="button">

    Teiste süsteemide jagatud printerite näitamine
    Aktiivse süsteemiga ühendatud avaldatud printerite jagamine
    +         Allow printing from the Internet
    Võrguhalduse lubamine
    Kasutajatel lubatakse katkestada kõiki töid (mitte ainult enda omi)
    Silumisinfo salvestamine probleemide tuvastamiseks

    diff --git a/templates/et/edit-config.tmpl.in b/templates/et/edit-config.tmpl.in index 1345129bd..965eeb618 100644 --- a/templates/et/edit-config.tmpl.in +++ b/templates/et/edit-config.tmpl.in @@ -9,6 +9,7 @@ function reset_config() "\\n" + "# Administrator user group...\\n" + "SystemGroup @CUPS_SYSTEM_GROUPS@\\n" + +"@CUPS_SYSTEM_AUTHKEY@\\n" + "\\n" + "\\n" + "# Only listen for connections from the local machine.\\n" + @@ -19,7 +20,7 @@ function reset_config() "# Show shared printers on the local network.\\n" + "Browsing On\\n" + "BrowseOrder allow,deny\\n" + -"BrowseAllow @LOCAL\\n" + +"BrowseAllow all\\n" + "\\n" + "\\n" + "# Authenticate against system accounts by default...\\n" + diff --git a/templates/fr/add-class.tmpl b/templates/fr/add-class.tmpl index 0fca49e55..576d53f17 100644 --- a/templates/fr/add-class.tmpl +++ b/templates/fr/add-class.tmpl @@ -31,36 +31,3 @@
    -
    - - -

    Ajouter une classe

    - - - - - - - - - - - - - - - - - - - - - - -
    Nom :
    Lieu :
    Description :
    Membres : - -
    - -
    diff --git a/templates/fr/add-printer.tmpl b/templates/fr/add-printer.tmpl index f039b95fe..f27b415e9 100644 --- a/templates/fr/add-printer.tmpl +++ b/templates/fr/add-printer.tmpl @@ -1,50 +1,23 @@
    +{device_uri?:}

    Ajouter une nouvelle imprimante

    - - - - - - - - -
    Nom :
    +

    ( Peut comporter tout caractère imprimable, "/", "#", et espace exceptés )
    Lieu :
    +

    ( Lieu compréhensible pour un utilisateur, comme "Labo 1" )
    Description :
    -( Description compréhensible pour un utilisateur, comme "HP LaserJet recto/verso" )
    - -
    -
    - - -

    Ajouter une nouvelle imprimante

    - - - - - - - - - - - - - diff --git a/templates/fr/admin.tmpl b/templates/fr/admin.tmpl index a76ce3636..e0486ef67 100644 --- a/templates/fr/admin.tmpl +++ b/templates/fr/admin.tmpl @@ -1,5 +1,5 @@
    Nom :
    -( Peut comporter tout caractère imprimable, "/", "#", et espace exceptés )
    Lieu :
    -( Lieu compréhensible pour un utilisateur, comme "Labo 1" )
    Description :
    +

    ( Description compréhensible pour un utilisateur, comme "HP LaserJet recto/verso" )
    - -
    +

    Imprimantes

    @@ -36,90 +36,7 @@ ALT="Administrer les classes" CLASS="button"> tâches" CLASS="button">

    -
          - -

    Serveur

    - -

    -Éditer le fichier de
-configuration -Liste des accès -Liste des erreurs -Liste des pages -

    - -{SETTINGS_ERROR?

    {SETTINGS_MESSAGE}

    -
    {SETTINGS_ERROR}
    : - - - -

    Paramètres de base du serveur :

    - -

    - Afficher les -imprimantes partagées par d'autres systèmes
    - Partager les -imprimantes publiques connectées à ce système
    - Autoriser -l'administration à distance
    - Autoriser les -utilisateurs à annuler n'importe quelle tâche ( pas seulement les leurs )
    - Enregistrer les -informations de debug pour la résolution de problèmes

    - -

    - -} - -
    - -
    - -

    Imprimantes

    - -

    -Ajouter une imprimante - -{have_samba?Exporter les imprimantes vers SAMBA:} -

    - -{#device_uri=0?:

    Nouvelles imprimantes détectées:

      {[device_uri] -
    • Ajouter cette imprimante -{device_make_and_model} ({device_info})
    • -}
    } - -

    Classes

    - -

    - - -

    - -

    Tâches d'impression

    - -

    -Administrer les
-tâches -

    - -
          +         

    Serveur

    @@ -150,6 +67,7 @@ CLASS="button"> imprimantes partagées par d'autres systèmes
    Partager les imprimantes publiques connectées à ce système
    +         Allow printing from the Internet
    Autoriser l'administration à distance
    Autoriser les diff --git a/templates/fr/choose-device.tmpl b/templates/fr/choose-device.tmpl index 89f774b29..14f19b7b1 100644 --- a/templates/fr/choose-device.tmpl +++ b/templates/fr/choose-device.tmpl @@ -24,29 +24,3 @@
    -
    - - - - - - -

    Matériel pour {printer_name}

    - - - - - - - - - - -
    Matériel : - -
    - -
    diff --git a/templates/fr/choose-make.tmpl b/templates/fr/choose-make.tmpl index c8b216a08..238d5d982 100644 --- a/templates/fr/choose-make.tmpl +++ b/templates/fr/choose-make.tmpl @@ -40,45 +40,3 @@ TYPE="FILE" NAME="PPD_FILE">
    -
    - - - - - - - - - - -

    Marque/Fabricant pour {printer_name}

    - - - - - - - - - - - - - - - - - - - - - - -
    Marque : - -
     
    Ou donnez un fichier PPD :
    - -
    diff --git a/templates/fr/choose-model.tmpl b/templates/fr/choose-model.tmpl index 1ee051ebb..1efeeaefd 100644 --- a/templates/fr/choose-model.tmpl +++ b/templates/fr/choose-model.tmpl @@ -32,37 +32,3 @@ TYPE="FILE" NAME="PPD_FILE">
    -
    - - - - - - - - - - -

    Modèle/Pilote pour {printer_name}

    - - - - - - - - - - - - - - -
    Modèle: - -
    Ou donnez un fichier PPD :
    - -
    diff --git a/templates/fr/choose-serial.tmpl b/templates/fr/choose-serial.tmpl index 14cc4a3f1..5e5173401 100644 --- a/templates/fr/choose-serial.tmpl +++ b/templates/fr/choose-serial.tmpl @@ -45,50 +45,3 @@ -
    - - - - - - -

    Paramètres du port série pour {printer_name}

    - - - - - - - - - - - - - - - - - - - - - - -
    Baud/s :
    Parité :
    Bits données :
    Contrôle de flux :
    - -
    diff --git a/templates/fr/choose-uri.tmpl b/templates/fr/choose-uri.tmpl index f9d2873aa..104017842 100644 --- a/templates/fr/choose-uri.tmpl +++ b/templates/fr/choose-uri.tmpl @@ -40,45 +40,3 @@ Printers" pour construire l'URI à employer avec votre imprimante.

    -
    - - - - - - -

    URI du matériel pour {printer_name}

    - - - - - - - - - - - - - - -
    URI du matériel :
    Exemples : -
    -    http://nom_machine:631/ipp/
    -    http://nom_machine:631/ipp/port1
    -
    -    ipp://nom_machine/ipp/
    -    ipp://nom_machine/ipp/port1
    -
    -    lpd://nom_machine/queue
    -
    -    socket://nom_machine
    -    socket://nom_machine:9100
    -
    - -

    cf. "Network -Printers" pour construire l'URI à employer avec votre imprimante.

    - -
    - -
    diff --git a/templates/fr/class-added.tmpl b/templates/fr/class-added.tmpl index be95a0ade..097e5081f 100644 --- a/templates/fr/class-added.tmpl +++ b/templates/fr/class-added.tmpl @@ -1,2 +1 @@

    La classe {printer_name} a bien été ajoutée. -

    La classe {printer_name} a bien été ajoutée. diff --git a/templates/fr/class-confirm.tmpl b/templates/fr/class-confirm.tmpl index 4b8081edf..95b402021 100644 --- a/templates/fr/class-confirm.tmpl +++ b/templates/fr/class-confirm.tmpl @@ -5,10 +5,3 @@ HREF="/admin?op=delete-class&printer_name={printer_name}&confirm=yes">Supprimer la classe

    -

    Attention : Êtes vous sûr(e) de vouloir supprimer la classe -{printer_name}?

    - -

    Supprimer la classe

    diff --git a/templates/fr/class-deleted.tmpl b/templates/fr/class-deleted.tmpl index 9cd00fd82..e7200e696 100644 --- a/templates/fr/class-deleted.tmpl +++ b/templates/fr/class-deleted.tmpl @@ -1,2 +1 @@

    La classe {printer_name} a bien été supprimée. -

    La classe {printer_name} a bien été supprimée. diff --git a/templates/fr/class-jobs-header.tmpl b/templates/fr/class-jobs-header.tmpl index 481b044c9..8c6dd642f 100644 --- a/templates/fr/class-jobs-header.tmpl +++ b/templates/fr/class-jobs-header.tmpl @@ -1,2 +1 @@

    Tâches d'impression

    -

    Tâches d'impression

    diff --git a/templates/fr/class-modified.tmpl b/templates/fr/class-modified.tmpl index 0915550a0..e2e2c3db7 100644 --- a/templates/fr/class-modified.tmpl +++ b/templates/fr/class-modified.tmpl @@ -1,2 +1 @@

    La classe {printer_name} a bien été modifiée. -

    La classe {printer_name} a bien été modifiée. diff --git a/templates/fr/classes-header.tmpl b/templates/fr/classes-header.tmpl index 0d8009cfa..953cec5b6 100644 --- a/templates/fr/classes-header.tmpl +++ b/templates/fr/classes-header.tmpl @@ -1,2 +1 @@

    {total=0?Aucune classe:Affichage de {#printer_name} classe{#printer_name=1?:s} sur {total}}.

    -

    {total=0?Aucune classe:Affichage de {#printer_name} classe{#printer_name=1?:s} sur {total}}.

    diff --git a/templates/fr/classes.tmpl b/templates/fr/classes.tmpl index 99706b9f2..4cedfc496 100644 --- a/templates/fr/classes.tmpl +++ b/templates/fr/classes.tmpl @@ -52,57 +52,3 @@ }} -{#printer_name=0?: -{[printer_name] -

    {printer_name}{default_name={printer_name}? ( Imprimante par défaut ) :} -{?printer_state_message=?:"{printer_state_message}"}

    - - - - - - -
    -Description : {printer_info}
    -Lieu : {printer_location}
    -État de la classe: {printer_state=3?ne fait rien:{printer_state=4?en cours d'impression:arrêtée}}, -{printer_is_accepting_jobs=0?rejette les tâches:accepte les tâches}, {printer_is_shared=0?cachée:publique}. -{?member_uris=?:
    Membres : {member_uris}} - -

    - -Imprimer une page de test -{printer_state=5? - -Démarrer la classe -: - -Arrêter la classe -} -{printer_is_accepting_jobs=0? - -Accepter les tâches -: - -Rejeter les tâches -} - -Annuler toutes les tâches -{printer_is_shared=0? - -Publier l'imprimante -: - -Cacher l'imprimante -} - -Modifier la classe - -Supprimer la classe - -Choisir par défaut - -Définir les autorisations -

    -
    -}} diff --git a/templates/fr/edit-config.tmpl.in b/templates/fr/edit-config.tmpl.in index 95163c0db..d6829317a 100644 --- a/templates/fr/edit-config.tmpl.in +++ b/templates/fr/edit-config.tmpl.in @@ -9,6 +9,7 @@ function reset_config() "\\n" + "# Groupe des utilisateurs UNIX pour les administrateurs CUPS...\\n" + "SystemGroup @CUPS_SYSTEM_GROUPS@\\n" + +"@CUPS_SYSTEM_AUTHKEY@\\n" + "\\n" + "\\n" + "# N'accepter que les connexions de la machine locale.\\n" + @@ -19,98 +20,7 @@ function reset_config() "# Publier les imprimantes partagées sur le réseau local.\\n" + "Browsing On\\n" + "BrowseOrder allow,deny\\n" + -"BrowseAllow @LOCAL\\n" + -"\\n" + -"\\n" + -"# S'authentifier par défaut via les comptes UNIX...\\n" + -"DefaultAuthType Basic\\n" + -"\\n" + -"# Restreindre l'accès au serveur...\\n" + -"\\n" + -" Order allow,deny\\n" + -" Allow localhost\\n" + -"\\n" + -"\\n" + -"# Restreindre l'accès aux pages d'administration...\\n" + -"\\n" + -"@ENCRYPTION_REQUIRED@\\n" + -" Order allow,deny\\n" + -" Allow localhost\\n" + -"\\n" + -"\\n" + -"# Restreindre l'accès au ficher de configuration...\\n" + -"\\n" + -" AuthType Basic\\n" + -" Require user @SYSTEM\\n" + -" Order allow,deny\\n" + -" Allow localhost\\n" + -"\\n" + -"\\n" + -"# Définir la politique par défaut des tâches d'impression...\\n" + -"\\n" + -" # Les opérations sur les tâches doivent être faites par leur propriétaire ou un adminstrateur...\\n" + -" \\n" + -" Require user @OWNER @SYSTEM\\n" + -" Order deny,allow\\n" + -" \\n" + -"\\n" + -" # Toutes les opérations d'administration nécessite l'authentification d'un adminstrateur...\\n" + -" \\n" + -" AuthType Basic\\n" + -" Require user @SYSTEM\\n" + -" Order deny,allow\\n" + -" \\n" + -"\\n" + -" # Seuls le propriétaire et un administrateur peuvent annuler ou authentifier une tâche...\\n" + -" \\n" + -" Require user @OWNER @SYSTEM\\n" + -" Order deny,allow\\n" + -" \\n" + -"\\n" + -" \\n" + -" Order deny,allow\\n" + -" \\n" + -"\\n"; -} - - -

    Ficher de configuration du serveur

    - -
    - - - - - -

    - -
    - - -
    - - -

    Exporter des imprimantes vers SAMBA

    - -{error?

    Impossible d'exporter les imprimantes vers SAMBA \:

    -
    {error}
    -

    Regardez le fichier error_log pour plus d'informations.

    : -

    Cette page vous permet d'exporter des imprimantes vers SAMBA de sorte que des -clients Windows puissent y accéder via l'icône Voisinage réseau ou -Favoris réseau du bureau. Vous devez au préalable installer les -pilotes Windows d'imprimante PostScript : cf. la page man cupsaddsmb(8).

    } - - - - - - - - - - - - - - - - - - -
    Imprimantes : -
    - Exporter toutes les imprimantes -
    Utilisateur SAMBA : ( indispensable )
    Mot-de-passe SAMBA : ( indispensable )
    - -
    diff --git a/templates/fr/samba-exported.tmpl b/templates/fr/samba-exported.tmpl index cac308431..2eca0390a 100644 --- a/templates/fr/samba-exported.tmpl +++ b/templates/fr/samba-exported.tmpl @@ -1,2 +1 @@

    Les imprimantes ont bien été exportées vers SAMBA.

    -

    Les imprimantes ont bien été exportées vers SAMBA.

    diff --git a/templates/fr/search.tmpl b/templates/fr/search.tmpl index 91f673e80..667eedbad 100644 --- a/templates/fr/search.tmpl +++ b/templates/fr/search.tmpl @@ -11,16 +11,3 @@ HREF="/{SECTION}/{?SEARCH_DEST}{WHICH_JOBS??WHICH_JOBS={WHICH_JOBS}{ORDER?&O SRC="/images/button-clear.gif" ALT="Nettoyer" CLASS="button">

    -
    -{WHICH_JOBS?:} -{ORDER?:} - -

    Rechercher dans -{SEARCH_DEST?{SEARCH_DEST}:{SECTION=classes?les classes:{SECTION=jobs?les tâches:les imprimantes}}} : - -Nettoyer

    - -
    diff --git a/templates/fr/set-printer-options-header.tmpl b/templates/fr/set-printer-options-header.tmpl index 84536d545..864f9f0ce 100644 --- a/templates/fr/set-printer-options-header.tmpl +++ b/templates/fr/set-printer-options-header.tmpl @@ -1,6 +1,3 @@
    - - - diff --git a/templates/fr/set-printer-options-trailer.tmpl b/templates/fr/set-printer-options-trailer.tmpl index 3f6f64a74..a3d1e1ffa 100644 --- a/templates/fr/set-printer-options-trailer.tmpl +++ b/templates/fr/set-printer-options-trailer.tmpl @@ -1,2 +1 @@
    - diff --git a/templates/fr/test-page.tmpl b/templates/fr/test-page.tmpl index bf79bd931..60c16ac1e 100644 --- a/templates/fr/test-page.tmpl +++ b/templates/fr/test-page.tmpl @@ -1,4 +1,2 @@

    La page de test a été envoyée ; l'identifiant de la tâche est {printer_name}-{job_id}.

    -

    La page de test a été envoyée ; l'identifiant de la tâche est -{printer_name}-{job_id}.

    diff --git a/templates/fr/trailer.tmpl b/templates/fr/trailer.tmpl index d9b74c3dd..9d03e7537 100644 --- a/templates/fr/trailer.tmpl +++ b/templates/fr/trailer.tmpl @@ -19,24 +19,3 @@ WIDTH="15" HEIGHT="15" ALT=""> - -  - - - - - -

    Le logiciel CUPS ( Common UNIX Printing System ) et son logo sont -propriété commerciale de Easy Software -Products. CUPS est sous copyright 1997-2006 par Easy Software Products, Tous -Droits Réservés.

    - - - - - - - - diff --git a/templates/fr/users.tmpl b/templates/fr/users.tmpl index b2d29141f..8c5486a01 100644 --- a/templates/fr/users.tmpl +++ b/templates/fr/users.tmpl @@ -24,29 +24,3 @@ -
    - - -{IS_CLASS?:} - -

    Utilisateurs autorisés à utiliser {printer_name}

    - - - - - - - - - - -
    Utilisateurs : - -
    -Autoriser ces utilisateurs à imprimer -Empêcher ces utilisateurs d'imprimer -
    - -
    - -
    diff --git a/templates/it/add-printer.tmpl b/templates/it/add-printer.tmpl index cff93eb29..b8c440fe6 100644 --- a/templates/it/add-printer.tmpl +++ b/templates/it/add-printer.tmpl @@ -1,22 +1,23 @@
    +{device_uri?:}

    Add New Printer

    - - - diff --git a/templates/it/admin.tmpl b/templates/it/admin.tmpl index ee1019025..b7526b3cf 100644 --- a/templates/it/admin.tmpl +++ b/templates/it/admin.tmpl @@ -1,5 +1,5 @@
    Name:
    +

    (May contain any printable characters except "/", "#", and space)
    Location:
    +

    (Human-readable location such as "Lab 1")
    Description:
    +

    (Human-readable description such as "HP LaserJet with Duplexer")
    -
    +

    Stampanti

    @@ -36,7 +36,7 @@ ALT="Gestione classi" CLASS="button"> operazioni" CLASS="button">

    -
          +         

    Server

    @@ -65,6 +65,7 @@ CLASS="button">

    Mostra stampanti condivise da altri sistemi
    Condividi le stampanti pubblicate connesse a questo sistema
    +         Allow printing from the Internet
    Consenti amministrazione remota
    Consenti agli utenti di annullare qualunque operazione (non solo le proprie)
    Salva le informazioni di debug per la risoluzione di problemi

    diff --git a/templates/it/edit-config.tmpl.in b/templates/it/edit-config.tmpl.in index be2ed2ba4..7c3f4301e 100644 --- a/templates/it/edit-config.tmpl.in +++ b/templates/it/edit-config.tmpl.in @@ -9,6 +9,7 @@ function reset_config() "\\n" + "# Administrator user group...\\n" + "SystemGroup @CUPS_SYSTEM_GROUPS@\\n" + +"@CUPS_SYSTEM_AUTHKEY@\\n" + "\\n" + "\\n" + "# Only listen for connections from the local machine.\\n" + @@ -19,7 +20,7 @@ function reset_config() "# Show shared printers on the local network.\\n" + "Browsing On\\n" + "BrowseOrder allow,deny\\n" + -"BrowseAllow @LOCAL\\n" + +"BrowseAllow all\\n" + "\\n" + "\\n" + "# Authenticate against system accounts by default...\\n" + diff --git a/templates/ja/add-printer.tmpl b/templates/ja/add-printer.tmpl index aac93808b..87cda3381 100644 --- a/templates/ja/add-printer.tmpl +++ b/templates/ja/add-printer.tmpl @@ -1,22 +1,23 @@ +{device_uri?:}

    新しいプリンタの追加

    - - - diff --git a/templates/ja/admin.tmpl b/templates/ja/admin.tmpl index 064028af8..ad8a5b7d1 100644 --- a/templates/ja/admin.tmpl +++ b/templates/ja/admin.tmpl @@ -1,5 +1,5 @@
    名前:
    +

    ("/"、"#"、空白を除く適当な表示可能文字を含めることができます)
    場所:
    +

    ("Lab 1" のように人間が読みやすい場所)
    説明:
    +

    ("HP LaserJet with Duplexer" のように人間が読みやすい説明)
    -
    +

    プリンタ

    @@ -35,7 +35,7 @@ ALT="クラスの管理" CLASS="button"> ジョブの管理

    -
          +         

    サーバ

    @@ -63,6 +63,7 @@ CLASS="button">

    ほかのシステムで共有されているプリンタを表示
    このシステムに接続されている公開済みプリンタを共有
    +         Allow printing from the Internet
    リモート管理を許可
    どのジョブであってもキャンセルすることを (たとえ所有者でなくても) ユーザに許可
    トラブルシューティングのためにデバッグ情報を保存

    diff --git a/templates/ja/edit-config.tmpl.in b/templates/ja/edit-config.tmpl.in index b3d4a96d1..baa2f5f2a 100644 --- a/templates/ja/edit-config.tmpl.in +++ b/templates/ja/edit-config.tmpl.in @@ -9,6 +9,7 @@ function reset_config() "\\n" + "# Administrator user group...\\n" + "SystemGroup @CUPS_SYSTEM_GROUPS@\\n" + +"@CUPS_SYSTEM_AUTHKEY@\\n" + "\\n" + "\\n" + "# Only listen for connections from the local machine.\\n" + @@ -19,7 +20,7 @@ function reset_config() "# Show shared printers on the local network.\\n" + "Browsing On\\n" + "BrowseOrder allow,deny\\n" + -"BrowseAllow @LOCAL\\n" + +"BrowseAllow all\\n" + "\\n" + "\\n" + "# Authenticate against system accounts by default...\\n" + diff --git a/templates/pl/add-printer.tmpl b/templates/pl/add-printer.tmpl index a264e05f2..59aa6faa9 100644 --- a/templates/pl/add-printer.tmpl +++ b/templates/pl/add-printer.tmpl @@ -1,22 +1,23 @@ +{device_uri?:}

    Dodaj nową drukarkę

    - - - diff --git a/templates/pl/admin.tmpl b/templates/pl/admin.tmpl index 5dd0ac818..12e40cd1c 100644 --- a/templates/pl/admin.tmpl +++ b/templates/pl/admin.tmpl @@ -1,5 +1,5 @@
    Nazwa:
    +

    (Może zawierać dowolne drukowalne znaki z wyjątkiem "/", "#" i spacji)
    Położenie:
    +

    (Położenie czytelne dla człowieka, takie jak "Laboratorium 1")
    Opis:
    +

    (Opis czytelny dla człowieka, taki jak "HP LaserJet z Dupleksem")
    -
    +

    Drukarki

    @@ -35,7 +35,7 @@ ALT="Zarządzaj klasami" CLASS="button"> Zarządzaj zadaniami

    -
          +         

    Serwer

    @@ -63,6 +63,7 @@ CLASS="button">

    Wyświetl drukarki udostępniane przez inne systemy
    Udostępnij opublikowane drukarki połączone do tego systemu
    +         Allow printing from the Internet
    Pozwól na zdalną administrację
    Pozwól użytkownikom na anulowanie każdego zadania (nie tylko ich)
    Zapisz informacje o debugowaniu do rozwiązywania problemów

    diff --git a/templates/pl/edit-config.tmpl.in b/templates/pl/edit-config.tmpl.in index 939f01153..0fd180079 100644 --- a/templates/pl/edit-config.tmpl.in +++ b/templates/pl/edit-config.tmpl.in @@ -9,6 +9,7 @@ function reset_config() "\\n" + "# Administrator user group...\\n" + "SystemGroup @CUPS_SYSTEM_GROUPS@\\n" + +"@CUPS_SYSTEM_AUTHKEY@\\n" + "\\n" + "\\n" + "# Only listen for connections from the local machine.\\n" + @@ -19,7 +20,7 @@ function reset_config() "# Show shared printers on the local network.\\n" + "Browsing On\\n" + "BrowseOrder allow,deny\\n" + -"BrowseAllow @LOCAL\\n" + +"BrowseAllow all\\n" + "\\n" + "\\n" + "# Authenticate against system accounts by default...\\n" + diff --git a/templates/printers.tmpl b/templates/printers.tmpl index d4f5e569a..24fb466bb 100644 --- a/templates/printers.tmpl +++ b/templates/printers.tmpl @@ -15,14 +15,15 @@ {printer_is_accepting_jobs=0?rejecting jobs:accepting jobs}, {printer_is_shared=0?not:} published. {?device_uri=?:
    Device URI: {device_uri}} -

    +

    + + + + +
    Print Test Page {?cupscommand=1? Clean Print Heads -Print Self Test Page:} -{printer_state=5? +Print Self Test Page:}{printer_state=5? Start Printer : @@ -39,8 +40,8 @@ Move All Jobs -Cancel All Jobs -{printer_is_shared=0? +Cancel All Jobs{printer_is_shared=0? Publish Printer : @@ -56,8 +57,9 @@ Set As Default -Set Allowed Users -

    +Set Allowed Users

    diff --git a/templates/subscription-added.tmpl b/templates/subscription-added.tmpl new file mode 100644 index 000000000..6153d7950 --- /dev/null +++ b/templates/subscription-added.tmpl @@ -0,0 +1 @@ +

    Subscription {subscription_name} has been added successfully.

    diff --git a/templates/subscription-canceled.tmpl b/templates/subscription-canceled.tmpl new file mode 100644 index 000000000..46662ccdb --- /dev/null +++ b/templates/subscription-canceled.tmpl @@ -0,0 +1 @@ +

    Subscription #{notify_subscription_id} has been canceled.

    diff --git a/templates/sv/add-printer.tmpl b/templates/sv/add-printer.tmpl index e80dec9b3..712e843e9 100644 --- a/templates/sv/add-printer.tmpl +++ b/templates/sv/add-printer.tmpl @@ -1,22 +1,23 @@ +{device_uri?:}

    Lägg till ny skrivare

    - - - diff --git a/templates/sv/admin.tmpl b/templates/sv/admin.tmpl index 0a0c0cb1f..ff80be8b8 100644 --- a/templates/sv/admin.tmpl +++ b/templates/sv/admin.tmpl @@ -1,5 +1,5 @@
    Namn:
    +

    (Får innehålla utskrivbara tecken förutom "/", "#", och blanksteg)
    Plats:
    +

    (Läsbar plats såsom "Lab 1")
    Beskrivning:
    +

    (Läsbar beskrivning såsom "HP LaserJet")
    -
    +

    Skrivare

    @@ -36,7 +36,7 @@ ALT="Hantera klasser" CLASS="button"> CLASS="button">

    -
          +         

    Server

    @@ -65,6 +65,7 @@ CLASS="button">

    Visa skrivare utdelade av andra system
    Dela ut publicerade skrivare anslutna till detta system
    +         Allow printing from the Internet
    Tillåt fjärradministration
    Tillåt användare att avbryta alla jobb (inte bara sina egna)
    Spara felsökningsinformation för problemlösning

    diff --git a/templates/sv/edit-config.tmpl.in b/templates/sv/edit-config.tmpl.in index b4d1d8bec..7cd827b75 100644 --- a/templates/sv/edit-config.tmpl.in +++ b/templates/sv/edit-config.tmpl.in @@ -9,6 +9,7 @@ function reset_config() "\\n" + "# Administrator user group...\\n" + "SystemGroup @CUPS_SYSTEM_GROUPS@\\n" + +"@CUPS_SYSTEM_AUTHKEY@\\n" + "\\n" + "\\n" + "# Only listen for connections from the local machine.\\n" + @@ -19,7 +20,7 @@ function reset_config() "# Show shared printers on the local network.\\n" + "Browsing On\\n" + "BrowseOrder allow,deny\\n" + -"BrowseAllow @LOCAL\\n" + +"BrowseAllow all\\n" + "\\n" + "\\n" + "# Authenticate against system accounts by default...\\n" + diff --git a/test/4.2-cups-printer-ops.test b/test/4.2-cups-printer-ops.test index 1be448e3b..585807ed0 100644 --- a/test/4.2-cups-printer-ops.test +++ b/test/4.2-cups-printer-ops.test @@ -1,5 +1,5 @@ # -# "$Id: 4.2-cups-printer-ops.test 5833 2006-08-16 20:05:58Z mike $" +# "$Id: 4.2-cups-printer-ops.test 5831 2006-08-16 19:28:09Z mike $" # # Verify that the CUPS printer operations work. # @@ -258,5 +258,5 @@ } # -# End of "$Id: 4.2-cups-printer-ops.test 5833 2006-08-16 20:05:58Z mike $" +# End of "$Id: 4.2-cups-printer-ops.test 5831 2006-08-16 19:28:09Z mike $" # diff --git a/test/4.4-subscription-ops.test b/test/4.4-subscription-ops.test index 4126c11d7..a724fb4e9 100644 --- a/test/4.4-subscription-ops.test +++ b/test/4.4-subscription-ops.test @@ -1,5 +1,5 @@ # -# "$Id: 4.4-subscription-ops.test 5833 2006-08-16 20:05:58Z mike $" +# "$Id: 4.4-subscription-ops.test 5831 2006-08-16 19:28:09Z mike $" # # Verify that the CUPS subscription operations work. # @@ -118,5 +118,5 @@ } # -# End of "$Id: 4.4-subscription-ops.test 5833 2006-08-16 20:05:58Z mike $" +# End of "$Id: 4.4-subscription-ops.test 5831 2006-08-16 19:28:09Z mike $" # diff --git a/test/Dependencies b/test/Dependencies index 15b3056c8..8f5d16b17 100644 --- a/test/Dependencies +++ b/test/Dependencies @@ -1,5 +1,5 @@ # DO NOT DELETE ipptest.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h -ipptest.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/array.h -ipptest.o: ../cups/file.h ../cups/language.h ../cups/language.h +ipptest.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +ipptest.o: ../cups/language.h ../cups/language.h diff --git a/test/Makefile b/test/Makefile index de2fd5713..93363cdd9 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile 5229 2006-03-05 16:48:12Z mike $" +# "$Id: Makefile 5919 2006-08-31 04:20:45Z mike $" # # IPP test makefile for the Common UNIX Printing System (CUPS). # @@ -69,7 +69,7 @@ uninstall: ipptest: ipptest.o ../cups/libcups.a echo Linking $@... $(CC) $(LDFLAGS) -o ipptest ipptest.o ../cups/libcups.a \ - $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(LIBGSSAPI) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) # @@ -80,5 +80,5 @@ include Dependencies # -# End of "$Id: Makefile 5229 2006-03-05 16:48:12Z mike $". +# End of "$Id: Makefile 5919 2006-08-31 04:20:45Z mike $". # diff --git a/test/get-job-attributes.test b/test/get-job-attributes.test index 35b241b06..ba62bd7f3 100644 --- a/test/get-job-attributes.test +++ b/test/get-job-attributes.test @@ -15,6 +15,7 @@ ATTR charset attributes-charset utf-8 ATTR language attributes-natural-language en ATTR uri job-uri $uri +# ATTR keyword requested-attributes job-media-sheets-completed,job-state # What statuses are OK? #STATUS ok @@ -23,5 +24,4 @@ # What attributes do we expect? EXPECT job-uri EXPECT job-state - EXPECT bogus-attribute } diff --git a/test/get-jobs.test b/test/get-jobs.test new file mode 100644 index 000000000..2d2e5a7dd --- /dev/null +++ b/test/get-jobs.test @@ -0,0 +1,21 @@ +# Get list of jobs +{ + # The name of the test... + NAME "Get-Jobs" + + # The resource to use for the POST + # RESOURCE /admin + + # The operation to use + OPERATION Get-Jobs + + # Attributes, starting in the operation group... + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + ATTR uri printer-uri $uri + ATTR keyword which-jobs completed + + # What statuses are OK? + STATUS successful-ok +} diff --git a/test/ipptest.c b/test/ipptest.c index 252e1dffd..7a127e5df 100644 --- a/test/ipptest.c +++ b/test/ipptest.c @@ -1,5 +1,5 @@ /* - * "$Id: ipptest.c 5878 2006-08-24 15:55:42Z mike $" + * "$Id: ipptest.c 5876 2006-08-24 15:05:04Z mike $" * * IPP test command for the Common UNIX Printing System (CUPS). * @@ -924,5 +924,5 @@ usage(const char *option) /* I - Option string or NULL */ /* - * End of "$Id: ipptest.c 5878 2006-08-24 15:55:42Z mike $". + * End of "$Id: ipptest.c 5876 2006-08-24 15:05:04Z mike $". */ diff --git a/test/run-stp-tests.sh b/test/run-stp-tests.sh index ae38459e9..43a0f9c25 100755 --- a/test/run-stp-tests.sh +++ b/test/run-stp-tests.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# "$Id: run-stp-tests.sh 6113 2006-11-15 20:37:45Z mike $" +# "$Id: run-stp-tests.sh 6297 2007-02-21 02:24:16Z mike $" # # Perform the complete set of IPP compliance tests specified in the # CUPS Software Test Plan. @@ -454,7 +454,7 @@ done # Create the test report source file... # -strfile=cups-str-1.2-`date +%Y-%m-%d`-$user.html +strfile=cups-str-1.3-`date +%Y-%m-%d`-$user.html rm -f $strfile cat str-header.html >$strfile @@ -584,5 +584,5 @@ echo "A HTML report was created in test/$strfile." echo "" # -# End of "$Id: run-stp-tests.sh 6113 2006-11-15 20:37:45Z mike $" +# End of "$Id: run-stp-tests.sh 6297 2007-02-21 02:24:16Z mike $" # diff --git a/tools/makesrcdist b/tools/makesrcdist index a17e8013a..955a8f42d 100755 --- a/tools/makesrcdist +++ b/tools/makesrcdist @@ -1,6 +1,6 @@ #!/bin/sh # -# "$Id: makesrcdist 5500 2006-05-08 20:32:27Z mike $" +# "$Id: makesrcdist 5502 2006-05-08 21:09:15Z mike $" # # makesrcdist - make a source distribution of CUPS. # @@ -18,9 +18,9 @@ if test $# = 0; then echo Updating for snapshot... svn up rev=`svnversion . | sed -e '1,$s/[a-zA-Z]//g'` - version="1.2svn" + version="1.3svn" revision="-r$rev" - fileversion="1.2svn-r$rev" + fileversion="1.3svn-r$rev" fileurl="ftp://ftp.easysw.com/pub/cups/test/cups-$fileversion-source.tar." url="." else @@ -32,7 +32,7 @@ else fileurl="ftp://ftp.easysw.com/pub/cups/$version/cups-$fileversion-source.tar." url="https://svn.easysw.com/public/cups/tags/release-$version" - svn copy https://svn.easysw.com/public/cups/branches/branch-1.2 "$url" \ + svn copy https://svn.easysw.com/public/cups/trunk "$url" \ -m "Tag $version" || exit 1 fi @@ -81,5 +81,5 @@ rm -rf cups-$version echo "Done!" # -# End of "$Id: makesrcdist 5500 2006-05-08 20:32:27Z mike $". +# End of "$Id: makesrcdist 5502 2006-05-08 21:09:15Z mike $". # diff --git a/tools/testosx b/tools/testosx index 5d8ac8477..92cc03063 100755 --- a/tools/testosx +++ b/tools/testosx @@ -12,7 +12,7 @@ fi rev=`svnversion . | awk -F: '{print $NF}' | sed -e '1,$s/[a-zA-Z]*//g'` if test $# = 0; then - version="1.2svn-r$rev" + version="1.3svn-r$rev" else version=$1 fi @@ -72,7 +72,7 @@ for file in packaging/cups-desc.plist packaging/cups-info.plist \ echo Updating $file... sed -e '1,$s/@CUPS_VERSION@/'$version'/g' \ -e '1,$s/@CUPS_REVISION@//g' \ - -e '1,$s/@CUPS_RELEASE@/1.2.'$rev'/g' \ + -e '1,$s/@CUPS_RELEASE@/1.3.'$rev'/g' \ <$file.in >$file done diff --git a/vcnet/config.h b/vcnet/config.h index 6a4613d71..c5f1752d0 100644 --- a/vcnet/config.h +++ b/vcnet/config.h @@ -1,9 +1,9 @@ /* - * "$Id: config.h 6189 2007-01-10 16:30:34Z mike $" + * "$Id: config.h 4828 2005-11-11 12:53:38Z mike $" * * Configuration file for the Common UNIX Printing System (CUPS). * - * Copyright 1997-2007 by Easy Software Products. + * Copyright 1997-2005 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal @@ -37,38 +37,16 @@ * Version of software... */ -#define CUPS_SVERSION "CUPS v1.2.8" -#define CUPS_MINIMAL "CUPS/1.2.8" +#define CUPS_SVERSION "CUPS v1.2svn" +#define CUPS_MINIMAL "CUPS/1.2svn" /* - * Default user and groups... + * Default user and group... */ -#define CUPS_DEFAULT_USER "lp" -#define CUPS_DEFAULT_GROUP "lp" -#define CUPS_DEFAULT_SYSTEM_GROUPS "sys root" - - -/* - * Default file permissions... - */ - -#define CUPS_DEFAULT_CONFIG_FILE_PERM 0640 -#define CUPS_DEFAULT_LOG_FILE_PERM 0644 - - -/* - * Default browsing settings... - */ - -#define CUPS_DEFAULT_BROWSING 1 -#define CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS "CUPS" -#define CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS "CUPS" -#define CUPS_DEFAULT_BROWSE_SHORT_NAMES 1 -#define CUPS_DEFAULT_DEFAULT_SHARED 1 -#define CUPS_DEFAULT_IMPLICIT_CLASSES 1 -#define CUPS_DEFAULT_USE_NETWORK_DEFAULT 1 +#define CUPS_DEFAULT_USER "lp" +#define CUPS_DEFAULT_GROUP "sys" /* @@ -146,13 +124,6 @@ #undef HAVE_CRYPT_H -/* - * Do we have ? - */ - -#undef HAVE_SCSI_SG_H - - /* * Use , , and/or ? */ @@ -245,13 +216,6 @@ #undef HAVE_MALLOC_H -/* - * Do we have the POSIX ACL functions? - */ - -#undef HAVE_ACL_INIT - - /* * Do we have the langinfo.h header file? */ @@ -265,8 +229,8 @@ #undef HAVE_CDSASSL #undef HAVE_GNUTLS -#define HAVE_LIBSSL 1 -#define HAVE_SSL 1 +#undef HAVE_LIBSSL +#undef HAVE_SSL /* @@ -276,14 +240,6 @@ #undef HAVE_LIBSLP -/* - * Do we have an LDAP library? - */ - -#undef HAVE_LDAP -#undef HAVE_OPENLDAP - - /* * Do we have libpaper? */ @@ -375,15 +331,6 @@ #undef HAVE_PTHREAD_H -/* - * Do we have launchd support? - */ - -/* #undef HAVE_LAUNCH_H */ -/* #undef HAVE_LAUNCHD */ -#define CUPS_DEFAULT_LAUNCHD_CONF "" - - /* * Various scripting languages... */ @@ -398,63 +345,8 @@ #define CUPS_PYTHON "/usr/bin/python" -/* - * Do we have Darwin's CoreFoundation and SystemConfiguration frameworks? - */ - -/* #undef HAVE_COREFOUNDATION */ -/* #undef HAVE_SYSTEMCONFIGURATION */ - - -/* - * Do we have CoreFoundation public and private headers? - */ - -/* #undef HAVE_COREFOUNDATION_H */ -/* #undef HAVE_CFPRIV_H */ -/* #undef HAVE_CFBUNDLEPRIV_H */ - - -/* - * Do we have CFLocaleCreateCanonicalLocaleIdentifierFromString()? - */ - -/* #undef HAVE_CF_LOCALE_ID */ - - -/* - * Do we have MacOSX 10.4's mbr_XXX functions()? - */ - -/* #undef HAVE_MEMBERSHIP_H */ -/* #undef HAVE_MBR_UID_TO_UUID */ - - -/* - * Do we have Darwin's notify_post() header and function? - */ - -/* #undef HAVE_NOTIFY_H */ -/* #undef HAVE_NOTIFY_POST */ - - -/* - * Do we have DBUS? - */ - -/* #undef HAVE_DBUS */ -/* #undef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND */ - - -/* - * Do we have the AppleTalk/at_proto.h header? - */ - -/* #undef HAVE_APPLETALK_AT_PROTO_H */ - - #endif /* !_CUPS_CONFIG_H_ */ /* - * End of "$Id: config.h 6189 2007-01-10 16:30:34Z mike $". + * End of "$Id: config.h 4828 2005-11-11 12:53:38Z mike $". */ diff --git a/vcnet/testhttp.vcproj b/vcnet/testhttp.vcproj old mode 100644 new mode 100755 -- 2.39.2