summaryrefslogtreecommitdiff
path: root/scheduler
diff options
context:
space:
mode:
authorŁukasz Stelmach <l.stelmach@samsung.com>2013-10-04 13:55:11 +0200
committerŁukasz Stelmach <l.stelmach@samsung.com>2013-10-04 13:55:11 +0200
commit4daab3758f62250691d3994850ddd3a7faf80d5e (patch)
tree895f25ab9018c6f343a261f0c1e5e3ae0bdd9362 /scheduler
parent4c8dd44ec57d63e728bda99034c043b8941419df (diff)
downloadcups-4daab3758f62250691d3994850ddd3a7faf80d5e.tar.gz
cups-4daab3758f62250691d3994850ddd3a7faf80d5e.tar.bz2
cups-4daab3758f62250691d3994850ddd3a7faf80d5e.zip
Imported Upstream version 1.6.4upstream/1.6.4
Diffstat (limited to 'scheduler')
-rw-r--r--scheduler/Dependencies690
-rw-r--r--scheduler/Makefile58
-rw-r--r--scheduler/auth.c309
-rw-r--r--scheduler/auth.h7
-rw-r--r--scheduler/banners.c4
-rw-r--r--scheduler/banners.h4
-rw-r--r--scheduler/cert.c32
-rw-r--r--scheduler/cert.h13
-rw-r--r--scheduler/classes.c62
-rw-r--r--scheduler/classes.h7
-rw-r--r--scheduler/client.c1497
-rw-r--r--scheduler/client.h15
-rw-r--r--scheduler/colorman.c1542
-rw-r--r--scheduler/colorman.h28
-rw-r--r--scheduler/conf.c1558
-rw-r--r--scheduler/conf.h45
-rw-r--r--scheduler/cups-deviced.c4
-rw-r--r--scheduler/cups-driverd.cxx1531
-rw-r--r--scheduler/cups-exec.c7
-rw-r--r--scheduler/cups-lpd.c9
-rw-r--r--scheduler/cups-polld.c470
-rw-r--r--scheduler/cups.sh.in4
-rw-r--r--scheduler/cups.xml.in2
-rw-r--r--scheduler/cupsd.h30
-rw-r--r--scheduler/cupsfilter.c147
-rw-r--r--scheduler/dirsvc.c5374
-rw-r--r--scheduler/dirsvc.h175
-rw-r--r--scheduler/env.c8
-rw-r--r--scheduler/file.c27
-rw-r--r--scheduler/filter.c4
-rw-r--r--scheduler/ipp.c1797
-rw-r--r--scheduler/job.c865
-rw-r--r--scheduler/job.h33
-rw-r--r--scheduler/listen.c4
-rw-r--r--scheduler/log.c87
-rw-r--r--scheduler/main.c323
-rw-r--r--scheduler/mime-private.h9
-rw-r--r--scheduler/mime.c4
-rw-r--r--scheduler/mime.h4
-rw-r--r--scheduler/network.c4
-rw-r--r--scheduler/network.h4
-rw-r--r--scheduler/policy.c4
-rw-r--r--scheduler/policy.h4
-rw-r--r--scheduler/printers.c547
-rw-r--r--scheduler/printers.h54
-rw-r--r--scheduler/process.c12
-rw-r--r--scheduler/quotas.c4
-rw-r--r--scheduler/select.c8
-rw-r--r--scheduler/server.c32
-rw-r--r--scheduler/statbuf.c4
-rw-r--r--scheduler/statbuf.h4
-rw-r--r--scheduler/subscriptions.c4
-rw-r--r--scheduler/subscriptions.h4
-rw-r--r--scheduler/sysman.c49
-rw-r--r--scheduler/sysman.h14
-rw-r--r--scheduler/testdirsvc.c324
-rw-r--r--scheduler/testlpd.c6
-rw-r--r--scheduler/testmime.c8
-rw-r--r--scheduler/testspeed.c6
-rw-r--r--scheduler/testsub.c13
-rw-r--r--scheduler/tls-darwin.c570
-rw-r--r--scheduler/tls-gnutls.c292
-rw-r--r--scheduler/tls-openssl.c353
-rw-r--r--scheduler/tls.c30
-rw-r--r--scheduler/type.c4
-rw-r--r--scheduler/util.c8
-rw-r--r--scheduler/util.h4
67 files changed, 7728 insertions, 11431 deletions
diff --git a/scheduler/Dependencies b/scheduler/Dependencies
index 5be01ff..2035646 100644
--- a/scheduler/Dependencies
+++ b/scheduler/Dependencies
@@ -1,361 +1,329 @@
-# DO NOT DELETE
-
-auth.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-auth.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-auth.o: ../cups/language.h ../cups/string-private.h ../config.h
-auth.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-auth.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-auth.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-auth.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-auth.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-auth.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h sysman.h
-auth.o: statbuf.h cert.h auth.h client.h policy.h printers.h
-auth.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-auth.o: network.h subscriptions.h
-banners.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-banners.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-banners.o: ../cups/language.h ../cups/string-private.h ../config.h
-banners.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-banners.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-banners.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-banners.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-banners.o: ../cups/transcode.h ../cups/thread-private.h
-banners.o: ../cups/file-private.h ../cups/cups-private.h mime.h
-banners.o: ../cups/array.h ../cups/file.h sysman.h statbuf.h cert.h auth.h
-banners.o: client.h policy.h printers.h ../cups/pwg-private.h classes.h job.h
-banners.o: conf.h banners.h dirsvc.h network.h subscriptions.h ../cups/dir.h
-cert.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-cert.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-cert.o: ../cups/language.h ../cups/string-private.h ../config.h
-cert.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-cert.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-cert.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-cert.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-cert.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-cert.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h sysman.h
-cert.o: statbuf.h cert.h auth.h client.h policy.h printers.h
-cert.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-cert.o: network.h subscriptions.h
-classes.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-classes.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-classes.o: ../cups/language.h ../cups/string-private.h ../config.h
-classes.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-classes.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-classes.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-classes.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-classes.o: ../cups/transcode.h ../cups/thread-private.h
-classes.o: ../cups/file-private.h ../cups/cups-private.h mime.h
-classes.o: ../cups/array.h ../cups/file.h sysman.h statbuf.h cert.h auth.h
-classes.o: client.h policy.h printers.h ../cups/pwg-private.h classes.h job.h
-classes.o: conf.h banners.h dirsvc.h network.h subscriptions.h
-client.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-client.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-client.o: ../cups/language.h ../cups/string-private.h ../config.h
-client.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-client.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-client.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-client.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-client.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-client.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h
-client.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h
-client.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-client.o: network.h subscriptions.h
-conf.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-conf.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-conf.o: ../cups/language.h ../cups/string-private.h ../config.h
-conf.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-conf.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-conf.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-conf.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-conf.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-conf.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h sysman.h
-conf.o: statbuf.h cert.h auth.h client.h policy.h printers.h
-conf.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-conf.o: network.h subscriptions.h
-dirsvc.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-dirsvc.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-dirsvc.o: ../cups/language.h ../cups/string-private.h ../config.h
-dirsvc.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-dirsvc.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-dirsvc.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-dirsvc.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-dirsvc.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-dirsvc.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h
-dirsvc.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h
-dirsvc.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-dirsvc.o: network.h subscriptions.h
-env.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-env.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-env.o: ../cups/language.h ../cups/string-private.h ../config.h
-env.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-env.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-env.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-env.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-env.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-env.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h sysman.h
-env.o: statbuf.h cert.h auth.h client.h policy.h printers.h
-env.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-env.o: network.h subscriptions.h
-file.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-file.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-file.o: ../cups/language.h ../cups/string-private.h ../config.h
-file.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-file.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-file.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-file.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-file.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-file.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h sysman.h
-file.o: statbuf.h cert.h auth.h client.h policy.h printers.h
-file.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-file.o: network.h subscriptions.h ../cups/dir.h
-main.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-main.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-main.o: ../cups/language.h ../cups/string-private.h ../config.h
-main.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-main.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-main.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-main.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-main.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-main.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h sysman.h
-main.o: statbuf.h cert.h auth.h client.h policy.h printers.h
-main.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-main.o: network.h subscriptions.h
-ipp.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-ipp.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-ipp.o: ../cups/language.h ../cups/string-private.h ../config.h
-ipp.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-ipp.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-ipp.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-ipp.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-ipp.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-ipp.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h sysman.h
-ipp.o: statbuf.h cert.h auth.h client.h policy.h printers.h
-ipp.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-ipp.o: network.h subscriptions.h ../cups/ppd-private.h
-listen.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-listen.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-listen.o: ../cups/language.h ../cups/string-private.h ../config.h
-listen.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-listen.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-listen.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-listen.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-listen.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-listen.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h
-listen.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h
-listen.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-listen.o: network.h subscriptions.h
-job.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-job.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-job.o: ../cups/language.h ../cups/string-private.h ../config.h
-job.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-job.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-job.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-job.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-job.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-job.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h sysman.h
-job.o: statbuf.h cert.h auth.h client.h policy.h printers.h
-job.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-job.o: network.h subscriptions.h ../cups/backend.h ../cups/dir.h
-log.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-log.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-log.o: ../cups/language.h ../cups/string-private.h ../config.h
-log.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-log.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-log.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-log.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-log.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-log.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h sysman.h
-log.o: statbuf.h cert.h auth.h client.h policy.h printers.h
-log.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-log.o: network.h subscriptions.h
-network.o: ../cups/http-private.h ../config.h ../cups/http.h
-network.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h cupsd.h
-network.o: ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-network.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-network.o: ../cups/language.h ../cups/string-private.h
-network.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-network.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-network.o: ../cups/http-private.h ../cups/language-private.h
-network.o: ../cups/transcode.h ../cups/thread-private.h
-network.o: ../cups/file-private.h ../cups/cups-private.h mime.h
-network.o: ../cups/array.h ../cups/file.h sysman.h statbuf.h cert.h auth.h
-network.o: client.h policy.h printers.h ../cups/pwg-private.h classes.h job.h
-network.o: conf.h banners.h dirsvc.h network.h subscriptions.h
-policy.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-policy.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-policy.o: ../cups/language.h ../cups/string-private.h ../config.h
-policy.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-policy.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-policy.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-policy.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-policy.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-policy.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h
-policy.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h
-policy.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-policy.o: network.h subscriptions.h
-printers.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-printers.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-printers.o: ../cups/language.h ../cups/string-private.h ../config.h
-printers.o: ../cups/debug-private.h ../cups/versioning.h
-printers.o: ../cups/ppd-private.h ../cups/ppd.h ../cups/cups.h
-printers.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h
-printers.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h
-printers.o: ../cups/language-private.h ../cups/transcode.h
-printers.o: ../cups/thread-private.h ../cups/file-private.h
-printers.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h
-printers.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h
-printers.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-printers.o: network.h subscriptions.h ../cups/dir.h
-process.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-process.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-process.o: ../cups/language.h ../cups/string-private.h ../config.h
-process.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-process.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-process.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-process.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-process.o: ../cups/transcode.h ../cups/thread-private.h
-process.o: ../cups/file-private.h ../cups/cups-private.h mime.h
-process.o: ../cups/array.h ../cups/file.h sysman.h statbuf.h cert.h auth.h
-process.o: client.h policy.h printers.h ../cups/pwg-private.h classes.h job.h
-process.o: conf.h banners.h dirsvc.h network.h subscriptions.h
-quotas.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-quotas.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-quotas.o: ../cups/language.h ../cups/string-private.h ../config.h
-quotas.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-quotas.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-quotas.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-quotas.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-quotas.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-quotas.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h
-quotas.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h
-quotas.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-quotas.o: network.h subscriptions.h
-select.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-select.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-select.o: ../cups/language.h ../cups/string-private.h ../config.h
-select.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-select.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-select.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-select.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-select.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-select.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h
-select.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h
-select.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-select.o: network.h subscriptions.h
-server.o: ../cups/http-private.h ../config.h ../cups/http.h
-server.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h cupsd.h
-server.o: ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-server.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-server.o: ../cups/language.h ../cups/string-private.h ../cups/debug-private.h
-server.o: ../cups/versioning.h ../cups/ppd-private.h ../cups/ppd.h
-server.o: ../cups/cups.h ../cups/pwg-private.h ../cups/http-private.h
-server.o: ../cups/language-private.h ../cups/transcode.h
-server.o: ../cups/thread-private.h ../cups/file-private.h
-server.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h
-server.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h
-server.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-server.o: network.h subscriptions.h
-statbuf.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-statbuf.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-statbuf.o: ../cups/language.h ../cups/string-private.h ../config.h
-statbuf.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-statbuf.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-statbuf.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-statbuf.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-statbuf.o: ../cups/transcode.h ../cups/thread-private.h
-statbuf.o: ../cups/file-private.h ../cups/cups-private.h mime.h
-statbuf.o: ../cups/array.h ../cups/file.h sysman.h statbuf.h cert.h auth.h
-statbuf.o: client.h policy.h printers.h ../cups/pwg-private.h classes.h job.h
-statbuf.o: conf.h banners.h dirsvc.h network.h subscriptions.h
-subscriptions.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-subscriptions.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h
-subscriptions.o: ../cups/array.h ../cups/language.h ../cups/string-private.h
-subscriptions.o: ../config.h ../cups/debug-private.h ../cups/versioning.h
-subscriptions.o: ../cups/ppd-private.h ../cups/ppd.h ../cups/cups.h
-subscriptions.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h
-subscriptions.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h
-subscriptions.o: ../cups/language-private.h ../cups/transcode.h
-subscriptions.o: ../cups/thread-private.h ../cups/file-private.h
-subscriptions.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h
-subscriptions.o: sysman.h statbuf.h cert.h auth.h client.h policy.h
-subscriptions.o: printers.h ../cups/pwg-private.h classes.h job.h conf.h
-subscriptions.o: banners.h dirsvc.h network.h subscriptions.h
-sysman.o: cupsd.h ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-sysman.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-sysman.o: ../cups/language.h ../cups/string-private.h ../config.h
-sysman.o: ../cups/debug-private.h ../cups/versioning.h ../cups/ppd-private.h
-sysman.o: ../cups/ppd.h ../cups/cups.h ../cups/pwg-private.h
-sysman.o: ../cups/http-private.h ../cups/http.h ../cups/md5-private.h
-sysman.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/language-private.h
-sysman.o: ../cups/transcode.h ../cups/thread-private.h ../cups/file-private.h
-sysman.o: ../cups/cups-private.h mime.h ../cups/array.h ../cups/file.h
-sysman.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h
-sysman.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h
-sysman.o: network.h subscriptions.h
-filter.o: ../cups/string-private.h ../config.h ../cups/debug-private.h
-filter.o: ../cups/versioning.h mime.h ../cups/array.h ../cups/ipp.h
-filter.o: ../cups/file.h
-mime.o: ../cups/string-private.h ../config.h ../cups/debug-private.h
-mime.o: ../cups/versioning.h ../cups/dir.h ../cups/versioning.h
-mime.o: mime-private.h mime.h ../cups/array.h ../cups/ipp.h ../cups/file.h
-type.o: ../cups/string-private.h ../config.h ../cups/debug-private.h
-type.o: ../cups/versioning.h mime.h ../cups/array.h ../cups/ipp.h
-type.o: ../cups/file.h
-cupsfilter.o: ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-cupsfilter.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h
-cupsfilter.o: ../cups/array.h ../cups/language.h ../cups/string-private.h
-cupsfilter.o: ../config.h ../cups/debug-private.h ../cups/versioning.h
-cupsfilter.o: ../cups/ppd-private.h ../cups/ppd.h ../cups/cups.h
-cupsfilter.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h
-cupsfilter.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h
-cupsfilter.o: ../cups/language-private.h ../cups/transcode.h
-cupsfilter.o: ../cups/thread-private.h ../cups/file-private.h
-cupsfilter.o: ../cups/cups-private.h ../cups/ppd-private.h mime.h
-cupsfilter.o: ../cups/array.h ../cups/file.h
-cups-deviced.o: util.h ../cups/array-private.h ../cups/array.h
-cups-deviced.o: ../cups/file-private.h ../cups/cups-private.h ../cups/dir.h
-cups-deviced.o: ../cups/versioning.h
-cups-exec.o: ../cups/string-private.h ../config.h
-cups-lpd.o: ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-cups-lpd.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h ../cups/array.h
-cups-lpd.o: ../cups/language.h ../cups/string-private.h ../config.h
-cups-lpd.o: ../cups/debug-private.h ../cups/versioning.h
-cups-lpd.o: ../cups/ppd-private.h ../cups/ppd.h ../cups/cups.h
-cups-lpd.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h
-cups-lpd.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h
-cups-lpd.o: ../cups/language-private.h ../cups/transcode.h
-cups-lpd.o: ../cups/thread-private.h
-cups-polld.o: ../cups/cups-private.h ../cups/cups.h ../cups/file.h
-cups-polld.o: ../cups/versioning.h ../cups/ipp.h ../cups/http.h
-cups-polld.o: ../cups/array.h ../cups/language.h ../cups/string-private.h
-cups-polld.o: ../config.h ../cups/debug-private.h ../cups/versioning.h
-cups-polld.o: ../cups/ppd-private.h ../cups/ppd.h ../cups/cups.h
-cups-polld.o: ../cups/pwg-private.h ../cups/http-private.h ../cups/http.h
-cups-polld.o: ../cups/md5-private.h ../cups/ipp-private.h ../cups/ipp.h
-cups-polld.o: ../cups/language-private.h ../cups/transcode.h
-cups-polld.o: ../cups/thread-private.h
-testdirsvc.o: ../cups/cups.h ../cups/file.h ../cups/versioning.h
-testdirsvc.o: ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h
-testdirsvc.o: ../cups/string-private.h ../config.h
-testlpd.o: ../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h
-testlpd.o: ../cups/http.h ../cups/array.h ../cups/language.h
-testlpd.o: ../cups/string-private.h ../config.h
-testmime.o: ../cups/string-private.h ../config.h ../cups/dir.h
-testmime.o: ../cups/versioning.h ../cups/debug-private.h ../cups/versioning.h
-testmime.o: ../cups/ppd-private.h mime.h ../cups/array.h ../cups/ipp.h
-testmime.o: ../cups/file.h
-testspeed.o: ../cups/string-private.h ../config.h ../cups/cups.h
-testspeed.o: ../cups/file.h ../cups/versioning.h ../cups/ipp.h ../cups/http.h
-testspeed.o: ../cups/array.h ../cups/language.h ../cups/language.h
-testspeed.o: ../cups/debug-private.h ../cups/versioning.h
-testsub.o: ../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h
-testsub.o: ../cups/http.h ../cups/array.h ../cups/language.h
-testsub.o: ../cups/debug-private.h ../cups/versioning.h
-testsub.o: ../cups/string-private.h ../config.h
-util.o: util.h ../cups/array-private.h ../cups/array.h ../cups/file-private.h
-util.o: ../cups/cups-private.h
-cups-driverd.o: util.h ../cups/array-private.h ../cups/array.h
-cups-driverd.o: ../cups/file-private.h ../cups/cups-private.h ../cups/dir.h
-cups-driverd.o: ../cups/versioning.h ../cups/transcode.h ../cups/language.h
-cups-driverd.o: ../cups/array.h ../cups/ppd-private.h ../ppdc/ppdc.h
-cups-driverd.o: ../cups/file.h
+auth.o: auth.c cupsd.h ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+avahi.o: avahi.c ../config.h
+banners.o: banners.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h ../cups/dir.h
+cert.o: cert.c cupsd.h ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+classes.o: classes.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+client.o: client.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+conf.o: conf.c cupsd.h ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+dirsvc.o: dirsvc.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+env.o: env.c cupsd.h ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+file.o: file.c cupsd.h ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h ../cups/dir.h
+main.o: main.c cupsd.h ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+ipp.o: ipp.c cupsd.h ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+listen.o: listen.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+job.o: job.c cupsd.h ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h ../cups/backend.h ../cups/dir.h
+log.o: log.c cupsd.h ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+network.o: network.c ../cups/http-private.h ../config.h ../cups/http.h \
+ ../cups/versioning.h ../cups/array.h ../cups/md5-private.h \
+ ../cups/ipp-private.h ../cups/ipp.h cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../cups/debug-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+policy.o: policy.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+printers.o: printers.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h ../cups/dir.h
+process.o: process.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+quotas.o: quotas.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+select.o: select.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+server.o: server.c ../cups/http-private.h ../config.h ../cups/http.h \
+ ../cups/versioning.h ../cups/array.h ../cups/md5-private.h \
+ ../cups/ipp-private.h ../cups/ipp.h cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../cups/debug-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+statbuf.o: statbuf.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+subscriptions.o: subscriptions.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+sysman.o: sysman.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+timeout.o: timeout.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h
+tls.o: tls.c cupsd.h ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h sysman.h statbuf.h cert.h auth.h \
+ client.h policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h \
+ network.h subscriptions.h tls-darwin.c
+filter.o: filter.c ../cups/string-private.h ../config.h \
+ ../cups/debug-private.h ../cups/versioning.h mime.h ../cups/array.h \
+ ../cups/ipp.h ../cups/http.h ../cups/file.h
+mime.o: mime.c ../cups/string-private.h ../config.h \
+ ../cups/debug-private.h ../cups/versioning.h ../cups/dir.h \
+ mime-private.h mime.h ../cups/array.h ../cups/ipp.h ../cups/http.h \
+ ../cups/file.h
+type.o: type.c ../cups/string-private.h ../config.h \
+ ../cups/debug-private.h ../cups/versioning.h mime.h ../cups/array.h \
+ ../cups/ipp.h ../cups/http.h ../cups/file.h
+cupsfilter.o: cupsfilter.c ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/http-private.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/language.h ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/file-private.h mime.h
+cups-deviced.o: cups-deviced.c util.h ../cups/array-private.h \
+ ../cups/array.h ../cups/versioning.h ../cups/file-private.h \
+ ../cups/cups-private.h ../cups/string-private.h ../config.h \
+ ../cups/debug-private.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/dir.h
+cups-exec.o: cups-exec.c ../cups/string-private.h ../config.h
+cups-lpd.o: cups-lpd.c ../cups/cups-private.h ../cups/string-private.h \
+ ../config.h ../cups/debug-private.h ../cups/versioning.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h ../cups/array.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h
+testlpd.o: testlpd.c ../cups/cups.h ../cups/file.h ../cups/versioning.h \
+ ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h \
+ ../cups/string-private.h ../config.h
+testmime.o: testmime.c ../cups/string-private.h ../config.h ../cups/dir.h \
+ ../cups/versioning.h ../cups/debug-private.h ../cups/ppd-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/ipp.h ../cups/http.h \
+ ../cups/array.h ../cups/language.h ../cups/ppd.h ../cups/pwg-private.h \
+ mime.h
+testspeed.o: testspeed.c ../cups/string-private.h ../config.h \
+ ../cups/cups.h ../cups/file.h ../cups/versioning.h ../cups/ipp.h \
+ ../cups/http.h ../cups/array.h ../cups/language.h \
+ ../cups/debug-private.h
+testsub.o: testsub.c ../cups/cups.h ../cups/file.h ../cups/versioning.h \
+ ../cups/ipp.h ../cups/http.h ../cups/array.h ../cups/language.h \
+ ../cups/debug-private.h ../cups/string-private.h ../config.h \
+ ../cups/ipp-private.h
+util.o: util.c util.h ../cups/array-private.h ../cups/array.h \
+ ../cups/versioning.h ../cups/file-private.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h
+cups-driverd.o: cups-driverd.cxx util.h ../cups/array-private.h \
+ ../cups/array.h ../cups/versioning.h ../cups/file-private.h \
+ ../cups/cups-private.h ../cups/string-private.h ../config.h \
+ ../cups/debug-private.h ../cups/ipp-private.h ../cups/ipp.h \
+ ../cups/http.h ../cups/http-private.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/language.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h \
+ ../cups/ppd-private.h ../cups/ppd.h ../cups/thread-private.h \
+ ../cups/dir.h ../ppdc/ppdc.h
diff --git a/scheduler/Makefile b/scheduler/Makefile
index 18dc80c..2790569 100644
--- a/scheduler/Makefile
+++ b/scheduler/Makefile
@@ -1,9 +1,9 @@
#
-# "$Id: Makefile 9766 2011-05-11 22:17:34Z mike $"
+# "$Id: Makefile 11173 2013-07-23 12:31:34Z msweet $"
#
# Scheduler Makefile for CUPS.
#
-# Copyright 2007-2011 by Apple Inc.
+# Copyright 2007-2012 by Apple Inc.
# Copyright 1997-2007 by Easy Software Products, all rights reserved.
#
# These coded instructions, statements, and computer programs are the
@@ -21,6 +21,7 @@ CUPSDOBJS = \
cert.o \
classes.o \
client.o \
+ colorman.o \
conf.o \
dirsvc.o \
env.o \
@@ -39,7 +40,8 @@ CUPSDOBJS = \
server.o \
statbuf.o \
subscriptions.o \
- sysman.o
+ sysman.o \
+ tls.o
LIBOBJS = \
filter.o \
mime.o \
@@ -51,8 +53,6 @@ COBJS = \
cups-deviced.o \
cups-exec.o \
cups-lpd.o \
- cups-polld.o \
- testdirsvc.o \
testlpd.o \
testmime.o \
testspeed.o \
@@ -68,7 +68,6 @@ LIBTARGETS = \
libcupsmime.a
UNITTARGETS = \
- testdirsvc \
testlpd \
testmime \
testspeed \
@@ -80,8 +79,7 @@ PROGRAMS = \
cups-deviced \
cups-driverd \
cups-exec \
- cups-lpd \
- cups-polld
+ cups-lpd
TARGETS = \
$(LIBTARGETS) \
@@ -124,8 +122,16 @@ clean:
#
depend:
- makedepend -Y -I.. -fDependencies $(COBJS:.o=.c) \
- $(CXXOBJS:.o=.cxx) >/dev/null 2>&1
+ $(CC) -MM $(ALL_CFLAGS) $(COBJS:.o=.c) >Dependencies
+ $(CXX) -MM $(ALL_CXXFLAGS) $(CXXOBJS:.o=.cxx) >>Dependencies
+
+
+#
+# Run oclint to check code coverage...
+#
+
+oclint:
+ oclint -o=oclint.html -html $(CUPSDOBJS:.o=.c) $(LIBOBJS:.o=.c) -- $(ALL_CFLAGS)
#
@@ -213,12 +219,8 @@ install-data:
install-exec:
echo Installing programs in $(SBINDIR)...
$(INSTALL_DIR) -m 755 $(SBINDIR)
- $(INSTALL_BIN) -m 500 cupsd $(SBINDIR)
+ $(INSTALL_BIN) -m $(CUPS_CUPSD_FILE_PERM) cupsd $(SBINDIR)
$(INSTALL_BIN) cupsfilter $(SBINDIR)
- -if test "x`uname`" = xDarwin; then \
- $(INSTALL_DIR) $(BUILDROOT)/System/Library/Printers/Libraries; \
- $(LN) $(sbindir)/cupsfilter $(BUILDROOT)/System/Library/Printers/Libraries/convert; \
- fi
echo Installing programs in $(SERVERBIN)/daemon...
$(INSTALL_DIR) -m 755 $(SERVERBIN)
$(INSTALL_DIR) -m 755 $(SERVERBIN)/daemon
@@ -226,7 +228,6 @@ install-exec:
$(INSTALL_BIN) cups-driverd $(SERVERBIN)/daemon
$(INSTALL_BIN) cups-exec $(SERVERBIN)/daemon
$(INSTALL_BIN) cups-lpd $(SERVERBIN)/daemon
- $(INSTALL_BIN) cups-polld $(SERVERBIN)/daemon
if test "x$(SYMROOT)" != "x"; then \
$(INSTALL_DIR) $(SYMROOT); \
for file in $(PROGRAMS); do \
@@ -284,7 +285,6 @@ uninstall:
$(RM) $(SERVERBIN)/daemon/cups-driverd
$(RM) $(SERVERBIN)/daemon/cups-exec
$(RM) $(SERVERBIN)/daemon/cups-lpd
- $(RM) $(SERVERBIN)/daemon/cups-polld
$(RM) $(BUILDROOT)/System/Library/Printers/Libraries/convert
-$(RMDIR) $(STATEDIR)/certs
-$(RMDIR) $(STATEDIR)
@@ -389,6 +389,8 @@ cupsd-static: $(CUPSDOBJS) libcupsmime.a ../cups/$(LIBCUPSSTATIC)
$(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBGSSAPI) \
$(LIBWRAP)
+tls.o: tls-darwin.c tls-gnutls.c tls-openssl.c
+
#
# Make the cupsfilter utility.
@@ -439,15 +441,6 @@ cups-lpd: cups-lpd.o ../cups/$(LIBCUPS)
#
-# Make the polling daemon, "cups-polld".
-#
-
-cups-polld: cups-polld.o ../cups/$(LIBCUPS)
- echo Linking $@...
- $(CC) $(LDFLAGS) -o cups-polld cups-polld.o $(LIBS)
-
-
-#
# libcupsmime.so.1, libcupsmime.sl.1
#
@@ -507,15 +500,6 @@ libcupsmime.a: $(LIBOBJS)
#
-# Make the test program, "testdirsvc".
-#
-
-testdirsvc: testdirsvc.o
- echo Linking $@...
- $(CC) $(LDFLAGS) -o testdirsvc testdirsvc.o $(COMMONLIBS) $(NETLIBS)
-
-
-#
# Make the test program, "testlpd".
#
@@ -564,7 +548,7 @@ testsub: testsub.o ../cups/$(LIBCUPSSTATIC)
sloc:
echo "cupsd: \c"
- sloccount $(CUPSDOBJS:.o=.c) $(LIBOBJS:.o=.c) cups-driverd.cxx cups-polld.c cups-lpd.c 2>/dev/null | grep "Total Physical" | awk '{print $$9}'
+ sloccount $(CUPSDOBJS:.o=.c) $(LIBOBJS:.o=.c) cups-driverd.cxx cups-lpd.c 2>/dev/null | grep "Total Physical" | awk '{print $$9}'
#
@@ -575,5 +559,5 @@ include Dependencies
#
-# End of "$Id: Makefile 9766 2011-05-11 22:17:34Z mike $".
+# End of "$Id: Makefile 11173 2013-07-23 12:31:34Z msweet $".
#
diff --git a/scheduler/auth.c b/scheduler/auth.c
index d2aeb40..1169adf 100644
--- a/scheduler/auth.c
+++ b/scheduler/auth.c
@@ -1,9 +1,9 @@
/*
- * "$Id: auth.c 9949 2011-08-31 04:58:33Z mike $"
+ * "$Id: auth.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Authorization routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
@@ -89,14 +89,13 @@ extern const char *cssmErrorString(int error);
typedef struct xucred cupsd_ucred_t;
# define CUPSD_UCRED_UID(c) (c).cr_uid
#else
+# ifndef __OpenBSD__
typedef struct ucred cupsd_ucred_t;
+# else
+typedef struct sockpeercred cupsd_ucred_t;
+# endif
# define CUPSD_UCRED_UID(c) (c).uid
#endif /* HAVE_SYS_UCRED_H */
-#ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID
-/* Not in public headers... */
-extern void krb5_ipc_client_set_target_uid(uid_t);
-extern void krb5_ipc_client_clear_target(void);
-#endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */
/*
@@ -130,8 +129,8 @@ static void to64(char *s, unsigned long v, int n);
#if HAVE_LIBPAM
typedef struct cupsd_authdata_s /**** Authentication data ****/
{
- char username[33], /* Username string */
- password[33]; /* Password string */
+ char username[HTTP_MAX_VALUE], /* Username string */
+ password[HTTP_MAX_VALUE]; /* Password string */
} cupsd_authdata_t;
#endif /* HAVE_LIBPAM */
@@ -322,8 +321,10 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
int type; /* Authentication type */
const char *authorization; /* Pointer into Authorization string */
char *ptr, /* Pointer into string */
- username[256], /* Username string */
- password[33]; /* Password string */
+ username[HTTP_MAX_VALUE],
+ /* Username string */
+ password[HTTP_MAX_VALUE];
+ /* Password string */
cupsd_cert_t *localuser; /* Certificate username */
char nonce[HTTP_MAX_VALUE], /* Nonce value from client */
md5[33], /* MD5 password */
@@ -356,18 +357,19 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
con->type = CUPSD_AUTH_NONE;
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdAuthorize: con->uri=\"%s\", con->best=%p(%s)",
- con->uri, con->best, con->best ? con->best->location : "");
+ "[Client %d] con->uri=\"%s\", con->best=%p(%s)",
+ con->http.fd, con->uri, con->best,
+ con->best ? con->best->location : "");
if (con->best && con->best->type != CUPSD_AUTH_NONE)
{
if (con->best->type == CUPSD_AUTH_DEFAULT)
- type = DefaultAuthType;
+ type = cupsdDefaultAuthType();
else
type = con->best->type;
}
else
- type = DefaultAuthType;
+ type = cupsdDefaultAuthType();
/*
* Decode the Authorization string...
@@ -375,8 +377,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
authorization = httpGetField(&con->http, HTTP_FIELD_AUTHORIZATION);
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAuthorize: Authorization=\"%s\"",
- authorization);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "[Client %d] Authorization=\"%s\"",
+ con->http.fd, authorization);
username[0] = '\0';
password[0] = '\0';
@@ -400,7 +402,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
*/
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: No authentication data provided.");
+ "[Client %d] No authentication data provided.",
+ con->http.fd);
return;
}
#ifdef HAVE_AUTHORIZATION_H
@@ -425,7 +428,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (authlen != kAuthorizationExternalFormLength)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "External Authorization reference size is incorrect!");
+ "[Client %d] External Authorization reference size is "
+ "incorrect.", con->http.fd);
return;
}
@@ -433,8 +437,9 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
(AuthorizationExternalForm *)nonce, &con->authref)) != 0)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "AuthorizationCreateFromExternalForm returned %d (%s)",
- (int)status, cssmErrorString(status));
+ "[Client %d] AuthorizationCreateFromExternalForm "
+ "returned %d (%s)", con->http.fd, (int)status,
+ cssmErrorString(status));
return;
}
@@ -449,8 +454,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
strlcpy(username, authinfo->items[0].value, sizeof(username));
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: Authorized as \"%s\" using AuthRef",
- username);
+ "[Client %d] Authorized as \"%s\" using AuthRef",
+ con->http.fd, username);
}
AuthorizationFreeItemSet(authinfo);
@@ -470,15 +475,17 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s",
- strerror(errno));
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Client %d] Unable to get peer credentials - %s",
+ con->http.fd, strerror(errno));
return;
}
if ((pwd = getpwuid(CUPSD_UCRED_UID(peercred))) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to find UID %d for peer credentials.",
+ "[Client %d] Unable to find UID %d for peer "
+ "credentials.", con->http.fd,
(int)CUPSD_UCRED_UID(peercred));
return;
}
@@ -486,8 +493,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
strlcpy(username, pwd->pw_name, sizeof(username));
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: Authorized as \"%s\" using "
- "AuthRef + PeerCred", username);
+ "[Client %d] Authorized as \"%s\" using "
+ "AuthRef + PeerCred", con->http.fd, username);
}
con->type = CUPSD_AUTH_BASIC;
@@ -506,21 +513,43 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
socklen_t peersize; /* Size of peer credentials */
#ifdef HAVE_AUTHORIZATION_H
const char *name; /* Authorizing name */
+ int no_peer = 0; /* Don't allow peer credentials? */
+
+ /*
+ * See if we should allow peer credentials...
+ */
for (name = (char *)cupsArrayFirst(con->best->names);
name;
name = (char *)cupsArrayNext(con->best->names))
- if (!_cups_strncasecmp(name, "@AUTHKEY(", 9) || !_cups_strcasecmp(name, "@SYSTEM"))
+ {
+ if (!_cups_strncasecmp(name, "@AUTHKEY(", 9) ||
+ !_cups_strcasecmp(name, "@SYSTEM"))
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "PeerCred authentication not allowed for resource.");
- return;
+ /* Normally don't want peer credentials if we need an auth key... */
+ no_peer = 1;
}
+ else if (!_cups_strcasecmp(name, "@OWNER"))
+ {
+ /* but if @OWNER is present then we allow it... */
+ no_peer = 0;
+ break;
+ }
+ }
+
+ if (no_peer)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Client %d] PeerCred authentication not allowed for "
+ "resource per AUTHKEY policy.", con->http.fd);
+ return;
+ }
#endif /* HAVE_AUTHORIZATION_H */
if ((pwd = getpwnam(authorization + 9)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "User \"%s\" does not exist.",
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Client %d] User \"%s\" does not exist.", con->http.fd,
authorization + 9);
return;
}
@@ -533,26 +562,27 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred, &peersize))
# endif /* __APPLE__ */
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s",
- strerror(errno));
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Client %d] Unable to get peer credentials - %s",
+ con->http.fd, strerror(errno));
return;
}
if (pwd->pw_uid != CUPSD_UCRED_UID(peercred))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Invalid peer credentials for \"%s\" - got %d, "
- "expected %d!", authorization + 9,
+ "[Client %d] Invalid peer credentials for \"%s\" - got "
+ "%d, expected %d!", con->http.fd, authorization + 9,
CUPSD_UCRED_UID(peercred), pwd->pw_uid);
# ifdef HAVE_SYS_UCRED_H
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_version=%d",
- peercred.cr_version);
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_uid=%d",
- peercred.cr_uid);
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_ngroups=%d",
- peercred.cr_ngroups);
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_groups[0]=%d",
- peercred.cr_groups[0]);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] cr_version=%d",
+ con->http.fd, peercred.cr_version);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] cr_uid=%d",
+ con->http.fd, peercred.cr_uid);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] cr_ngroups=%d",
+ con->http.fd, peercred.cr_ngroups);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] cr_groups[0]=%d",
+ con->http.fd, peercred.cr_groups[0]);
# endif /* HAVE_SYS_UCRED_H */
return;
}
@@ -564,7 +594,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
# endif /* HAVE_GSSAPI */
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: Authorized as %s using PeerCred",
+ "[Client %d] Authorized as %s using PeerCred", con->http.fd,
username);
con->type = CUPSD_AUTH_BASIC;
@@ -581,28 +611,20 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
while (isspace(*authorization & 255))
authorization ++;
- if ((localuser = cupsdFindCert(authorization)) != NULL)
- {
- strlcpy(username, localuser->username, sizeof(username));
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: Authorized as %s using Local",
- username);
- }
- else
+ if ((localuser = cupsdFindCert(authorization)) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Local authentication certificate not "
- "found!");
+ "[Client %d] Local authentication certificate not found.",
+ con->http.fd);
return;
}
-#ifdef HAVE_GSSAPI
- if (localuser->ccache)
- con->type = CUPSD_AUTH_NEGOTIATE;
- else
-#endif /* HAVE_GSSAPI */
- con->type = CUPSD_AUTH_BASIC;
+ strlcpy(username, localuser->username, sizeof(username));
+ con->type = localuser->type;
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "[Client %d] Authorized as %s using Local", con->http.fd,
+ username);
}
else if (!strncmp(authorization, "Basic", 5))
{
@@ -626,8 +648,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if ((ptr = strchr(username, ':')) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Missing Basic password!");
+ cupsdLogMessage(CUPSD_LOG_ERROR, "[Client %d] Missing Basic password.",
+ con->http.fd);
return;
}
@@ -639,8 +661,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* Username must not be empty...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Empty Basic username!");
+ cupsdLogMessage(CUPSD_LOG_ERROR, "[Client %d] Empty Basic username.",
+ con->http.fd);
return;
}
@@ -650,8 +672,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* Password must not be empty...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Empty Basic password!");
+ cupsdLogMessage(CUPSD_LOG_ERROR, "[Client %d] Empty Basic password.",
+ con->http.fd);
return;
}
@@ -703,8 +725,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (pamerr != PAM_SUCCESS)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: pam_start() returned %d (%s)!",
- pamerr, pam_strerror(pamh, pamerr));
+ "[Client %d] pam_start() returned %d (%s)",
+ con->http.fd, pamerr, pam_strerror(pamh, pamerr));
return;
}
@@ -713,8 +735,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
pamerr = pam_set_item(pamh, PAM_RHOST, con->http.hostname);
if (pamerr != PAM_SUCCESS)
cupsdLogMessage(CUPSD_LOG_WARN,
- "cupsdAuthorize: pam_set_item(PAM_RHOST) "
- "returned %d (%s)!", pamerr,
+ "[Client %d] pam_set_item(PAM_RHOST) "
+ "returned %d (%s)", con->http.fd, pamerr,
pam_strerror(pamh, pamerr));
# endif /* PAM_RHOST */
@@ -722,8 +744,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
pamerr = pam_set_item(pamh, PAM_TTY, "cups");
if (pamerr != PAM_SUCCESS)
cupsdLogMessage(CUPSD_LOG_WARN,
- "cupsdAuthorize: pam_set_item(PAM_TTY) "
- "returned %d (%s)!", pamerr,
+ "[Client %d] pam_set_item(PAM_TTY) "
+ "returned %d (%s)!", con->http.fd, pamerr,
pam_strerror(pamh, pamerr));
# endif /* PAM_TTY */
# endif /* HAVE_PAM_SET_ITEM */
@@ -732,9 +754,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (pamerr != PAM_SUCCESS)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: pam_authenticate() returned %d "
- "(%s)!",
- pamerr, pam_strerror(pamh, pamerr));
+ "[Client %d] pam_authenticate() returned %d (%s)",
+ con->http.fd, pamerr, pam_strerror(pamh, pamerr));
pam_end(pamh, 0);
return;
}
@@ -743,8 +764,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
pamerr = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT);
if (pamerr != PAM_SUCCESS)
cupsdLogMessage(CUPSD_LOG_WARN,
- "cupsdAuthorize: pam_setcred() "
- "returned %d (%s)!", pamerr,
+ "[Client %d] pam_setcred() returned %d (%s)",
+ con->http.fd, pamerr,
pam_strerror(pamh, pamerr));
# endif /* HAVE_PAM_SETCRED */
@@ -752,9 +773,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (pamerr != PAM_SUCCESS)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: pam_acct_mgmt() returned %d "
- "(%s)!",
- pamerr, pam_strerror(pamh, pamerr));
+ "[Client %d] pam_acct_mgmt() returned %d (%s)",
+ con->http.fd, pamerr, pam_strerror(pamh, pamerr));
pam_end(pamh, 0);
return;
}
@@ -771,16 +791,16 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: AIX authenticate of username "
- "\"%s\"", username);
+ "[Client %d] AIX authenticate of username \"%s\"",
+ con->http.fd, username);
reenter = 1;
if (authenticate(username, password, &reenter, &authmsg) != 0)
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: Unable to authenticate username "
- "\"%s\": %s",
- username, strerror(errno));
+ "[Client %d] Unable to authenticate username "
+ "\"%s\": %s", con->http.fd, username,
+ strerror(errno));
return;
}
@@ -806,8 +826,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Unknown username \"%s\"!",
- username);
+ "[Client %d] Unknown username \"%s\".",
+ con->http.fd, username);
return;
}
@@ -822,8 +842,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Username \"%s\" has no shadow "
- "password!", username);
+ "[Client %d] Username \"%s\" has no shadow "
+ "password.", con->http.fd, username);
return;
}
@@ -837,8 +857,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Username \"%s\" has no password!",
- username);
+ "[Client %d] Username \"%s\" has no password.",
+ con->http.fd, username);
return;
}
@@ -850,8 +870,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
pass = cups_crypt(password, pw->pw_passwd);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdAuthorize: pw_passwd=\"%s\", crypt=\"%s\"",
- pw->pw_passwd, pass);
+ "[Client %d] pw_passwd=\"%s\", crypt=\"%s\"",
+ con->http.fd, pw->pw_passwd, pass);
if (!pass || strcmp(pw->pw_passwd, pass))
{
@@ -861,15 +881,14 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
pass = cups_crypt(password, spw->sp_pwdp);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdAuthorize: sp_pwdp=\"%s\", crypt=\"%s\"",
- spw->sp_pwdp, pass);
+ "[Client %d] sp_pwdp=\"%s\", crypt=\"%s\"",
+ con->http.fd, spw->sp_pwdp, pass);
if (pass == NULL || strcmp(spw->sp_pwdp, pass))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Authentication failed for "
- "user \"%s\"!",
- username);
+ "[Client %d] Authentication failed for user "
+ "\"%s\".", con->http.fd, username);
return;
}
}
@@ -877,9 +896,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
# endif /* HAVE_SHADOW_H */
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Authentication failed for "
- "user \"%s\"!",
- username);
+ "[Client %d] Authentication failed for user "
+ "\"%s\".", con->http.fd, username);
return;
}
}
@@ -887,8 +905,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
}
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: Authorized as %s using Basic",
- username);
+ "[Client %d] Authorized as %s using Basic",
+ con->http.fd, username);
break;
case CUPSD_AUTH_BASICDIGEST :
@@ -899,8 +917,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (!get_md5_password(username, NULL, md5))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Unknown MD5 username \"%s\"!",
- username);
+ "[Client %d] Unknown MD5 username \"%s\".",
+ con->http.fd, username);
return;
}
@@ -909,14 +927,14 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (strcmp(md5, basicmd5))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Authentication failed for \"%s\"!",
- username);
+ "[Client %d] Authentication failed for \"%s\".",
+ con->http.fd, username);
return;
}
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: Authorized as %s using BasicDigest",
- username);
+ "[Client %d] Authorized as %s using BasicDigest",
+ con->http.fd, username);
break;
}
@@ -936,7 +954,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Empty or missing Digest username!");
+ "[Client %d] Empty or missing Digest username.",
+ con->http.fd);
return;
}
@@ -948,7 +967,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Empty or missing Digest password!");
+ "[Client %d] Empty or missing Digest password.",
+ con->http.fd);
return;
}
@@ -956,16 +976,16 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
nonce))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: No nonce value for Digest "
- "authentication!");
+ "[Client %d] No nonce value for Digest authentication.",
+ con->http.fd);
return;
}
if (strcmp(con->http.hostname, nonce))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Bad nonce value, expected \"%s\", "
- "got \"%s\"!", con->http.hostname, nonce);
+ "[Client %d] Bad nonce value, expected \"%s\", "
+ "got \"%s\".", con->http.fd, con->http.hostname, nonce);
return;
}
@@ -976,8 +996,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (!get_md5_password(username, NULL, md5))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Unknown MD5 username \"%s\"!",
- username);
+ "[Client %d] Unknown MD5 username \"%s\".",
+ con->http.fd, username);
return;
}
@@ -986,13 +1006,13 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (strcmp(md5, password))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdAuthorize: Authentication failed for \"%s\"!",
- username);
+ "[Client %d] Authentication failed for \"%s\".",
+ con->http.fd, username);
return;
}
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: Authorized as %s using Digest",
+ "[Client %d] Authorized as %s using Digest", con->http.fd,
username);
con->type = CUPSD_AUTH_DIGEST;
@@ -1020,8 +1040,9 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (gss_init_sec_context == NULL)
{
cupsdLogMessage(CUPSD_LOG_WARN,
- "GSSAPI/Kerberos authentication failed because the "
- "Kerberos framework is not present.");
+ "[Client %d] GSSAPI/Kerberos authentication failed "
+ "because the Kerberos framework is not present.",
+ con->http.fd);
return;
}
# endif /* __APPLE__ */
@@ -1037,7 +1058,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (!*authorization)
{
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdAuthorize: No authentication data specified.");
+ "[Client %d] No authentication data specified.",
+ con->http.fd);
return;
}
@@ -1059,7 +1081,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
client_name = GSS_C_NO_NAME;
major_status = gss_accept_sec_context(&minor_status,
&context,
- GSS_C_NO_CREDENTIAL,
+ ServerCreds,
&input_token,
GSS_C_NO_CHANNEL_BINDINGS,
&client_name,
@@ -1075,8 +1097,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (GSS_ERROR(major_status))
{
cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
- "cupsdAuthorize: Error accepting GSSAPI security "
- "context");
+ "[Client %d] Error accepting GSSAPI security context",
+ con->http.fd);
if (context != GSS_C_NO_CONTEXT)
gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
@@ -1091,7 +1113,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (major_status == GSS_S_CONTINUE_NEEDED)
cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
- "cupsdAuthorize: Credentials not complete");
+ "[Client %d] Credentials not complete", con->http.fd);
else if (major_status == GSS_S_COMPLETE)
{
major_status = gss_display_name(&minor_status, client_name,
@@ -1100,7 +1122,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (GSS_ERROR(major_status))
{
cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
- "cupsdAuthorize: Error getting username");
+ "[Client %d] Error getting username", con->http.fd);
gss_release_name(&minor_status, &client_name);
gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
return;
@@ -1109,8 +1131,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
strlcpy(username, output_token.value, sizeof(username));
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: Authorized as %s using Negotiate",
- username);
+ "[Client %d] Authorized as %s using Negotiate",
+ con->http.fd, username);
gss_release_name(&minor_status, &client_name);
gss_release_buffer(&minor_status, &output_token);
@@ -1140,14 +1162,15 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
&peersize))
# endif /* __APPLE__ */
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s",
- strerror(errno));
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Client %d] Unable to get peer credentials - %s",
+ con->http.fd, strerror(errno));
}
else
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdAuthorize: Using credentials for UID %d...",
- CUPSD_UCRED_UID(peercred));
+ "[Client %d] Using credentials for UID %d.",
+ con->http.fd, CUPSD_UCRED_UID(peercred));
con->gss_uid = CUPSD_UCRED_UID(peercred);
}
}
@@ -1162,8 +1185,9 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (sscanf(authorization, "%255s", scheme) != 1)
strcpy(scheme, "UNKNOWN");
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad authentication data \"%s ...\"",
- scheme);
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Client %d] Bad authentication data \"%s ...\"",
+ con->http.fd, scheme);
return;
}
@@ -1843,7 +1867,7 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
best = con->best;
if ((type = best->type) == CUPSD_AUTH_DEFAULT)
- type = DefaultAuthType;
+ type = cupsdDefaultAuthType();
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"cupsdIsAuthorized: level=CUPSD_AUTH_%s, type=%s, "
@@ -1907,7 +1931,8 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
_cups_strcasecmp(con->http.hostname, "localhost") &&
best->satisfy == CUPSD_AUTH_SATISFY_ALL) &&
!(type == CUPSD_AUTH_NEGOTIATE ||
- (type == CUPSD_AUTH_NONE && DefaultAuthType == CUPSD_AUTH_NEGOTIATE)))
+ (type == CUPSD_AUTH_NONE &&
+ cupsdDefaultAuthType() == CUPSD_AUTH_NEGOTIATE)))
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
"cupsdIsAuthorized: Need upgrade to TLS...");
@@ -2582,5 +2607,5 @@ to64(char *s, /* O - Output string */
/*
- * End of "$Id: auth.c 9949 2011-08-31 04:58:33Z mike $".
+ * End of "$Id: auth.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/auth.h b/scheduler/auth.h
index f15a6f9..8979023 100644
--- a/scheduler/auth.h
+++ b/scheduler/auth.h
@@ -1,5 +1,5 @@
/*
- * "$Id: auth.h 9652 2011-03-25 21:25:38Z mike $"
+ * "$Id: auth.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Authorization definitions for the CUPS scheduler.
*
@@ -30,6 +30,7 @@
#define CUPSD_AUTH_DIGEST 2 /* Digest authentication */
#define CUPSD_AUTH_BASICDIGEST 3 /* Basic authentication w/passwd.md5 */
#define CUPSD_AUTH_NEGOTIATE 4 /* Kerberos authentication */
+#define CUPSD_AUTH_AUTO 5 /* Kerberos or Basic, depending on configuration of server */
#define CUPSD_AUTH_ANON 0 /* Anonymous access */
#define CUPSD_AUTH_USER 1 /* Must have a valid username/password */
@@ -112,8 +113,6 @@ typedef struct cupsd_client_s cupsd_client_t;
VAR cups_array_t *Locations VALUE(NULL);
/* Authorization locations */
-VAR int DefaultAuthType VALUE(CUPSD_AUTH_BASIC);
- /* Default AuthType, if not specified */
#ifdef HAVE_SSL
VAR http_encryption_t DefaultEncryption VALUE(HTTP_ENCRYPT_REQUIRED);
/* Default encryption for authentication */
@@ -148,5 +147,5 @@ extern cupsd_location_t *cupsdNewLocation(const char *location);
/*
- * End of "$Id: auth.h 9652 2011-03-25 21:25:38Z mike $".
+ * End of "$Id: auth.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/banners.c b/scheduler/banners.c
index 7a4987f..87a1a68 100644
--- a/scheduler/banners.c
+++ b/scheduler/banners.c
@@ -1,5 +1,5 @@
/*
- * "$Id: banners.c 9793 2011-05-20 03:49:49Z mike $"
+ * "$Id: banners.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Banner routines for the CUPS scheduler.
*
@@ -220,5 +220,5 @@ free_banners(void)
/*
- * End of "$Id: banners.c 9793 2011-05-20 03:49:49Z mike $".
+ * End of "$Id: banners.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/banners.h b/scheduler/banners.h
index 2578cdd..4a91e8a 100644
--- a/scheduler/banners.h
+++ b/scheduler/banners.h
@@ -1,5 +1,5 @@
/*
- * "$Id: banners.h 9350 2010-11-04 23:23:25Z mike $"
+ * "$Id: banners.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Banner definitions for the CUPS scheduler.
*
@@ -41,5 +41,5 @@ extern void cupsdLoadBanners(const char *d);
/*
- * End of "$Id: banners.h 9350 2010-11-04 23:23:25Z mike $".
+ * End of "$Id: banners.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/cert.c b/scheduler/cert.c
index 2e83a8b..cd47228 100644
--- a/scheduler/cert.c
+++ b/scheduler/cert.c
@@ -1,9 +1,9 @@
/*
- * "$Id: cert.c 10262 2012-02-12 05:48:09Z mike $"
+ * "$Id: cert.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Authentication certificate routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -42,7 +42,7 @@
void
cupsdAddCert(int pid, /* I - Process ID */
const char *username, /* I - Username */
- void *ccache) /* I - Kerberos credentials or NULL */
+ int type) /* I - AuthType for username */
{
int i; /* Looping var */
cupsd_cert_t *cert; /* Current certificate */
@@ -66,7 +66,8 @@ cupsdAddCert(int pid, /* I - Process ID */
* Fill in the certificate information...
*/
- cert->pid = pid;
+ cert->pid = pid;
+ cert->type = type;
strlcpy(cert->username, username, sizeof(cert->username));
for (i = 0; i < 32; i ++)
@@ -260,16 +261,6 @@ cupsdAddCert(int pid, /* I - Process ID */
close(fd);
/*
- * Add Kerberos credentials as needed...
- */
-
-#ifdef HAVE_GSSAPI
- cert->ccache = (krb5_ccache)ccache;
-#else
- (void)ccache;
-#endif /* HAVE_GSSAPI */
-
- /*
* Insert the certificate at the front of the list...
*/
@@ -308,15 +299,6 @@ cupsdDeleteCert(int pid) /* I - Process ID */
else
prev->next = cert->next;
-#ifdef HAVE_GSSAPI
- /*
- * Release Kerberos credentials as needed...
- */
-
- if (cert->ccache)
- krb5_cc_destroy(KerberosContext, cert->ccache);
-#endif /* HAVE_GSSAPI */
-
free(cert);
/*
@@ -449,10 +431,10 @@ cupsdInitCerts(void)
*/
if (!RunUser)
- cupsdAddCert(0, "root", NULL);
+ cupsdAddCert(0, "root", cupsdDefaultAuthType());
}
/*
- * End of "$Id: cert.c 10262 2012-02-12 05:48:09Z mike $".
+ * End of "$Id: cert.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/cert.h b/scheduler/cert.h
index e456a1a..26eaa9f 100644
--- a/scheduler/cert.h
+++ b/scheduler/cert.h
@@ -1,9 +1,9 @@
/*
- * "$Id: cert.h 9350 2010-11-04 23:23:25Z mike $"
+ * "$Id: cert.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Authentication certificate definitions for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -23,9 +23,7 @@ typedef struct cupsd_cert_s
int pid; /* Process ID (0 for root certificate) */
char certificate[33]; /* 32 hex characters, or 128 bits */
char username[33]; /* Authenticated username */
-#ifdef HAVE_GSSAPI
- krb5_ccache ccache; /* Kerberos credential cache */
-#endif /* HAVE_GSSAPI */
+ int type; /* AuthType for username */
} cupsd_cert_t;
@@ -43,8 +41,7 @@ VAR time_t RootCertTime /* Root certificate update time */
* Prototypes...
*/
-extern void cupsdAddCert(int pid, const char *username,
- void *ccache);
+extern void cupsdAddCert(int pid, const char *username, int type);
extern void cupsdDeleteCert(int pid);
extern void cupsdDeleteAllCerts(void);
extern cupsd_cert_t *cupsdFindCert(const char *certificate);
@@ -52,5 +49,5 @@ extern void cupsdInitCerts(void);
/*
- * End of "$Id: cert.h 9350 2010-11-04 23:23:25Z mike $".
+ * End of "$Id: cert.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/classes.c b/scheduler/classes.c
index c001bc4..1aed92c 100644
--- a/scheduler/classes.c
+++ b/scheduler/classes.c
@@ -1,5 +1,5 @@
/*
- * "$Id: classes.c 9793 2011-05-20 03:49:49Z mike $"
+ * "$Id: classes.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Printer class routines for the CUPS scheduler.
*
@@ -22,8 +22,6 @@
* cupsdFindClass() - Find the named class.
* cupsdLoadAllClasses() - Load classes from the classes.conf file.
* cupsdSaveAllClasses() - Save classes to the classes.conf file.
- * cupsdUpdateImplicitClasses() - Update the accepting state of implicit
- * classes.
*/
/*
@@ -184,24 +182,9 @@ cupsdDeletePrinterFromClasses(
for (c = (cupsd_printer_t *)cupsArrayFirst(Printers);
c;
c = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ if (c->type & CUPS_PRINTER_CLASS)
changed |= cupsdDeletePrinterFromClass(c, p);
- /*
- * Then clean out any empty implicit classes...
- */
-
- for (c = (cupsd_printer_t *)cupsArrayFirst(ImplicitPrinters);
- c;
- c = (cupsd_printer_t *)cupsArrayNext(ImplicitPrinters))
- if (c->num_printers == 0)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Deleting implicit class \"%s\"...",
- c->name);
- cupsdDeletePrinter(c, 0);
- changed = 1;
- }
-
return (changed);
}
@@ -279,8 +262,7 @@ cupsdFindClass(const char *name) /* I - Name of class */
cupsd_printer_t *c; /* Current class/printer */
- if ((c = cupsdFindDest(name)) != NULL &&
- (c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)))
+ if ((c = cupsdFindDest(name)) != NULL && (c->type & CUPS_PRINTER_CLASS))
return (c);
else
return (NULL);
@@ -443,9 +425,8 @@ cupsdLoadAllClasses(void)
{
cupsdSetString(&temp->make_model, "Remote Printer on unknown");
- temp->state = IPP_PRINTER_STOPPED;
- temp->type |= CUPS_PRINTER_REMOTE;
- temp->browse_time = 2147483647;
+ temp->state = IPP_PRINTER_STOPPED;
+ temp->type |= CUPS_PRINTER_REMOTE;
cupsdSetString(&temp->location, "Location Unknown");
cupsdSetString(&temp->info, "No Information Available");
@@ -733,7 +714,6 @@ cupsdSaveAllClasses(void)
*/
if ((pclass->type & CUPS_PRINTER_REMOTE) ||
- (pclass->type & CUPS_PRINTER_IMPLICIT) ||
!(pclass->type & CUPS_PRINTER_CLASS))
continue;
@@ -834,35 +814,5 @@ cupsdSaveAllClasses(void)
/*
- * 'cupsdUpdateImplicitClasses()' - Update the accepting state of implicit
- * classes.
- */
-
-void
-cupsdUpdateImplicitClasses(void)
-{
- int i; /* Looping var */
- cupsd_printer_t *pclass; /* Current class */
- int accepting; /* printer-is-accepting-jobs value */
-
-
- for (pclass = (cupsd_printer_t *)cupsArrayFirst(ImplicitPrinters);
- pclass;
- pclass = (cupsd_printer_t *)cupsArrayNext(ImplicitPrinters))
- {
- /*
- * Loop through the printers to come up with a composite state...
- */
-
- for (i = 0, accepting = 0; i < pclass->num_printers; i ++)
- if ((accepting = pclass->printers[i]->accepting) != 0)
- break;
-
- pclass->accepting = accepting;
- }
-}
-
-
-/*
- * End of "$Id: classes.c 9793 2011-05-20 03:49:49Z mike $".
+ * End of "$Id: classes.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/classes.h b/scheduler/classes.h
index 05c0878..6d94de2 100644
--- a/scheduler/classes.h
+++ b/scheduler/classes.h
@@ -1,9 +1,9 @@
/*
- * "$Id: classes.h 9350 2010-11-04 23:23:25Z mike $"
+ * "$Id: classes.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Printer class definitions for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -28,9 +28,8 @@ extern cupsd_printer_t *cupsdFindAvailablePrinter(const char *name);
extern cupsd_printer_t *cupsdFindClass(const char *name);
extern void cupsdLoadAllClasses(void);
extern void cupsdSaveAllClasses(void);
-extern void cupsdUpdateImplicitClasses(void);
/*
- * End of "$Id: classes.h 9350 2010-11-04 23:23:25Z mike $".
+ * End of "$Id: classes.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/client.c b/scheduler/client.c
index e40ed27..b341e9d 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -1,9 +1,9 @@
/*
- * "$Id: client.c 10338 2012-03-07 06:05:39Z mike $"
+ * "$Id: client.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Client routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
@@ -17,34 +17,30 @@
*
* Contents:
*
- * cupsdAcceptClient() - Accept a new client.
- * cupsdCloseAllClients() - Close all remote clients immediately.
- * cupsdCloseClient() - Close a remote client.
- * cupsdFlushHeader() - Flush the header fields to the client.
- * cupsdReadClient() - Read data from a client.
- * cupsdSendCommand() - Send output from a command via HTTP.
- * cupsdSendError() - Send an error message via HTTP.
- * cupsdSendHeader() - Send an HTTP request.
- * cupsdUpdateCGI() - Read status messages from CGI scripts and
- * programs.
- * cupsdWriteClient() - Write data to a client as needed.
- * check_if_modified() - Decode an "If-Modified-Since" line.
- * compare_clients() - Compare two client connections.
- * copy_cdsa_certificate() - Copy a SSL/TLS certificate from the System
- * keychain.
- * data_ready() - Check whether data is available from a client.
- * encrypt_client() - Enable encryption for the client...
- * get_file() - Get a filename and state info.
- * install_conf_file() - Install a configuration file.
- * is_cgi() - Is the resource a CGI script/program?
- * is_path_absolute() - Is a path absolute and free of relative elements
- * (i.e. "..").
- * make_certificate() - Make a self-signed SSL/TLS certificate.
- * pipe_command() - Pipe the output of a command to the remote
- * client.
- * valid_host() - Is the Host: field valid?
- * write_file() - Send a file via HTTP.
- * write_pipe() - Flag that data is available on the CGI pipe.
+ * cupsdAcceptClient() - Accept a new client.
+ * cupsdCloseAllClients() - Close all remote clients immediately.
+ * cupsdCloseClient() - Close a remote client.
+ * cupsdFlushHeader() - Flush the header fields to the client.
+ * cupsdReadClient() - Read data from a client.
+ * cupsdSendCommand() - Send output from a command via HTTP.
+ * cupsdSendError() - Send an error message via HTTP.
+ * cupsdSendHeader() - Send an HTTP request.
+ * cupsdUpdateCGI() - Read status messages from CGI scripts and
+ * programs.
+ * cupsdWriteClient() - Write data to a client as needed.
+ * check_if_modified() - Decode an "If-Modified-Since" line.
+ * compare_clients() - Compare two client connections.
+ * data_ready() - Check whether data is available from a client.
+ * get_file() - Get a filename and state info.
+ * install_cupsd_conf() - Install a configuration file.
+ * is_cgi() - Is the resource a CGI script/program?
+ * is_path_absolute() - Is a path absolute and free of relative elements
+ * (i.e. "..").
+ * pipe_command() - Pipe the output of a command to the remote
+ * client.
+ * valid_host() - Is the Host: field valid?
+ * write_file() - Send a file via HTTP.
+ * write_pipe() - Flag that data is available on the CGI pipe.
*/
/*
@@ -59,6 +55,36 @@
/*
+ * Local globals...
+ */
+
+static const char * const http_states[] =
+ { /* HTTP state strings */
+ "HTTP_WAITING",
+ "HTTP_OPTIONS",
+ "HTTP_GET",
+ "HTTP_GET_SEND",
+ "HTTP_HEAD",
+ "HTTP_POST",
+ "HTTP_POST_RECV",
+ "HTTP_POST_SEND",
+ "HTTP_PUT",
+ "HTTP_PUT_RECV",
+ "HTTP_DELETE",
+ "HTTP_TRACE",
+ "HTTP_CLOSE",
+ "HTTP_STATUS"
+ };
+static const char * const ipp_states[] =
+ { /* IPP state strings */
+ "IPP_IDLE",
+ "IPP_HEADER",
+ "IPP_ATTRIBUTE",
+ "IPP_DATA"
+ };
+
+
+/*
* Local functions...
*/
@@ -66,22 +92,13 @@ static int check_if_modified(cupsd_client_t *con,
struct stat *filestats);
static int compare_clients(cupsd_client_t *a, cupsd_client_t *b,
void *data);
-#ifdef HAVE_CDSASSL
-static CFArrayRef copy_cdsa_certificate(cupsd_client_t *con);
-#endif /* HAVE_CDSASSL */
static int data_ready(cupsd_client_t *con);
-#ifdef HAVE_SSL
-static int encrypt_client(cupsd_client_t *con);
-#endif /* HAVE_SSL */
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 http_status_t install_cupsd_conf(cupsd_client_t *con);
static int is_cgi(cupsd_client_t *con, const char *filename,
struct stat *filestats, mime_type_t *type);
static int is_path_absolute(const char *path);
-#ifdef HAVE_SSL
-static int make_certificate(cupsd_client_t *con);
-#endif /* HAVE_SSL */
static int pipe_command(cupsd_client_t *con, int infile, int *outfile,
char *command, char *options, int root);
static int valid_host(cupsd_client_t *con);
@@ -157,8 +174,8 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
return;
}
- con->http.activity = time(NULL);
con->file = -1;
+ con->http.activity = time(NULL);
con->http.hostaddr = &(con->clientaddr);
con->http.wait_value = 10000;
@@ -356,11 +373,11 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
#ifdef AF_LOCAL
if (con->http.hostaddr->addr.sa_family == AF_LOCAL)
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s (Domain)",
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Accepted from %s (Domain)",
con->http.fd, con->http.hostname);
else
#endif /* AF_LOCAL */
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s:%d (IPv%d)",
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Accepted from %s:%d (IPv%d)",
con->http.fd, con->http.hostname,
_httpAddrPort(con->http.hostaddr),
_httpAddrFamily(con->http.hostaddr) == AF_INET ? 4 : 6);
@@ -389,7 +406,7 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
{
if (httpAddrLocalhost(&temp))
strlcpy(con->servername, "localhost", sizeof(con->servername));
- else if (HostNameLookups || RemotePort)
+ else if (HostNameLookups)
httpAddrLookup(&temp, con->servername, sizeof(con->servername));
else
httpAddrString(&temp, con->servername, sizeof(con->servername));
@@ -397,6 +414,10 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
con->serverport = _httpAddrPort(&(lis->address));
}
+ /*
+ * Add the connection to the array of active clients...
+ */
+
cupsArrayAdd(Clients, con);
/*
@@ -440,7 +461,7 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
con->http.encryption = HTTP_ENCRYPT_ALWAYS;
- if (!encrypt_client(con))
+ if (!cupsdStartTLS(con))
cupsdCloseClient(con);
}
else
@@ -479,17 +500,13 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */
{
int partial; /* Do partial close for SSL? */
#ifdef HAVE_LIBSSL
- SSL_CTX *context; /* Context for encryption */
- unsigned long error; /* Error code */
#elif defined(HAVE_GNUTLS)
- int error; /* Error code */
- gnutls_certificate_server_credentials *credentials;
- /* TLS credentials */
# elif defined(HAVE_CDSASSL)
#endif /* HAVE_LIBSSL */
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdCloseClient: %d", con->http.fd);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Closing connection.",
+ con->http.fd);
/*
* Flush pending writes before closing...
@@ -508,60 +525,7 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */
{
partial = 1;
-# ifdef HAVE_LIBSSL
- context = SSL_get_SSL_CTX(con->http.tls);
-
- switch (SSL_shutdown(con->http.tls))
- {
- case 1 :
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "SSL shutdown successful!");
- break;
- case -1 :
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Fatal error during SSL shutdown!");
- default :
- while ((error = ERR_get_error()) != 0)
- cupsdLogMessage(CUPSD_LOG_ERROR, "SSL shutdown failed: %s",
- ERR_error_string(error, NULL));
- break;
- }
-
- SSL_CTX_free(context);
- SSL_free(con->http.tls);
-
-# elif defined(HAVE_GNUTLS)
- credentials = (gnutls_certificate_server_credentials *)(con->http.tls_credentials);
-
- error = gnutls_bye(con->http.tls, GNUTLS_SHUT_WR);
- switch (error)
- {
- case GNUTLS_E_SUCCESS:
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "SSL shutdown successful!");
- break;
- default:
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "SSL shutdown failed: %s", gnutls_strerror(error));
- break;
- }
-
- gnutls_deinit(con->http.tls);
- gnutls_certificate_free_credentials(*credentials);
- free(credentials);
-
-# elif defined(HAVE_CDSASSL)
- while (SSLClose(con->http.tls) == errSSLWouldBlock)
- usleep(1000);
-
- SSLDisposeContext(con->http.tls);
-
- if (con->http.tls_credentials)
- CFRelease(con->http.tls_credentials);
-
-# endif /* HAVE_LIBSSL */
-
- con->http.tls = NULL;
+ cupsdEndTLS(con);
}
#endif /* HAVE_SSL */
@@ -719,18 +683,22 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
status = HTTP_CONTINUE;
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdReadClient(con=%p(%d)) "
- "con->http.error=%d "
- "con->http.used=%d, "
- "con->http.state=%d "
- "con->data_encoding=HTTP_ENCODE_%s, "
- "con->data_remaining=" CUPS_LLFMT ", "
- "con->file=%d",
- con, con->http.fd, con->http.error, con->http.used,
- con->http.state,
+ "[Client %d] cupsdReadClient "
+ "error=%d, "
+ "used=%d, "
+ "state=%s, "
+ "data_encoding=HTTP_ENCODE_%s, "
+ "data_remaining=" CUPS_LLFMT ", "
+ "request=%p(%s), "
+ "file=%d",
+ con->http.fd, con->http.error, con->http.used,
+ http_states[con->http.state],
con->http.data_encoding == HTTP_ENCODE_CHUNKED ?
"CHUNKED" : "LENGTH",
- CUPS_LLCAST con->http.data_remaining, con->file);
+ CUPS_LLCAST con->http.data_remaining,
+ con->request,
+ con->request ? ipp_states[con->request->state] : "",
+ con->file);
#ifdef HAVE_SSL
if (con->auto_ssl)
@@ -749,10 +717,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
*/
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdReadClient: Saw first byte %02X, auto-negotiating "
- "SSL/TLS session...", buf[0] & 255);
+ "[Client %d] Saw first byte %02X, auto-negotiating "
+ "SSL/TLS session.", con->http.fd, buf[0] & 255);
- if (!encrypt_client(con))
+ if (!cupsdStartTLS(con))
cupsdCloseClient(con);
return;
@@ -771,12 +739,12 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
{
if (con->http.error && con->http.error != EPIPE)
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d WAITING Closing for error %d "
+ "[Client %d] HTTP_WAITING Closing for error %d "
"(%s)", con->http.fd, con->http.error,
strerror(con->http.error));
else
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d WAITING Closing on EOF",
+ "[Client %d] HTTP_WAITING Closing on EOF",
con->http.fd);
cupsdCloseClient(con);
@@ -848,7 +816,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (line[0])
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Bad request line \"%s\" from %s!",
+ "[Client %d] Bad request line \"%s\" from %s.",
+ con->http.fd,
_httpEncodeURI(buf, line, sizeof(buf)),
con->http.hostname);
cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
@@ -862,7 +831,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (sscanf(version, "HTTP/%d.%d", &major, &minor) != 2)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Bad request line \"%s\" from %s!",
+ "[Client %d] Bad request line \"%s\" from %s.",
+ con->http.fd,
_httpEncodeURI(buf, line, sizeof(buf)),
con->http.hostname);
cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
@@ -881,7 +851,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
else
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unsupported request line \"%s\" from %s!",
+ "[Client %d] Unsupported request line \"%s\" "
+ "from %s.", con->http.fd,
_httpEncodeURI(buf, line, sizeof(buf)),
con->http.hostname);
cupsdSendError(con, HTTP_NOT_SUPPORTED, CUPSD_AUTH_NONE);
@@ -928,8 +899,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Nope, we don't do proxies...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad URI \"%s\" in request!",
- con->uri);
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Client %d] Bad URI \"%s\" in request.",
+ con->http.fd, con->uri);
cupsdSendError(con, HTTP_METHOD_NOT_ALLOWED, CUPSD_AUTH_NONE);
cupsdCloseClient(con);
return;
@@ -963,7 +935,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
con->http.state = HTTP_HEAD;
else
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad operation \"%s\"!", operation);
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Client %d] Bad operation \"%s\".", con->http.fd,
+ operation);
cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
cupsdCloseClient(con);
return;
@@ -972,7 +946,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
gettimeofday(&(con->start), NULL);
con->operation = con->http.state;
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %d %s %s HTTP/%d.%d",
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] %s %s HTTP/%d.%d",
con->http.fd, operation, con->uri,
con->http.version / 100, con->http.version % 100);
@@ -1003,13 +977,14 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
{
if (con->http.error && con->http.error != EPIPE)
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d FIELDS Closing for error %d "
- "(%s)", con->http.fd, con->http.error,
+ "[Client %d] Closing for error %d (%s) while "
+ "reading headers.",
+ con->http.fd, con->http.error,
strerror(con->http.error));
else
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d FIELDS Closing on EOF",
- con->http.fd);
+ "[Client %d] Closing on EOF while reading headers.",
+ con->http.fd);
cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
cupsdCloseClient(con);
@@ -1025,7 +1000,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
*/
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d Closing on EOF", con->http.fd);
+ "[Client %d] Closing on EOF", con->http.fd);
cupsdCloseClient(con);
return;
}
@@ -1078,10 +1053,11 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
cupsdAuthorize(con);
- if (!_cups_strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Keep-Alive",
- 10) && KeepAlive)
+ if (!_cups_strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION],
+ "Keep-Alive", 10) && KeepAlive)
con->http.keep_alive = HTTP_KEEPALIVE_ON;
- else if (!_cups_strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "close", 5))
+ else if (!_cups_strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION],
+ "close", 5))
con->http.keep_alive = HTTP_KEEPALIVE_OFF;
if (!con->http.fields[HTTP_FIELD_HOST][0] &&
@@ -1093,7 +1069,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE))
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Missing Host: field in request!");
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "[Client %d] Missing Host: field in request.",
+ con->http.fd);
cupsdCloseClient(con);
return;
}
@@ -1106,8 +1084,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Request from \"%s\" using invalid Host: field \"%s\"",
- con->http.hostname, con->http.fields[HTTP_FIELD_HOST]);
+ "[Client %d] Request from \"%s\" using invalid Host: "
+ "field \"%s\"", con->http.fd, con->http.hostname,
+ con->http.fields[HTTP_FIELD_HOST]);
if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE))
{
@@ -1155,7 +1134,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
return;
}
- if (!encrypt_client(con))
+ if (!cupsdStartTLS(con))
{
cupsdCloseClient(con);
return;
@@ -1192,7 +1171,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Request for non-absolute resource \"%s\"!", con->uri);
+ "[Client %d] Request for non-absolute resource \"%s\".",
+ con->http.fd, con->uri);
if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE))
{
@@ -1202,15 +1182,16 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
}
else
{
- if (!_cups_strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Upgrade") &&
- con->http.tls == NULL)
+ if (!_cups_strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION],
+ "Upgrade") && con->http.tls == NULL)
{
#ifdef HAVE_SSL
/*
* Do encryption stuff...
*/
- if (!cupsdSendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL, CUPSD_AUTH_NONE))
+ if (!cupsdSendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL,
+ CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1227,7 +1208,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
return;
}
- if (!encrypt_client(con))
+ if (!cupsdStartTLS(con))
{
cupsdCloseClient(con);
return;
@@ -1290,7 +1271,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
switch (con->http.state)
{
case HTTP_GET_SEND :
- if (!strncmp(con->uri, "/printers/", 10) &&
+ if ((!strncmp(con->uri, "/ppd/", 5) ||
+ !strncmp(con->uri, "/printers/", 10)) &&
!strcmp(con->uri + strlen(con->uri) - 4, ".ppd"))
{
/*
@@ -1300,8 +1282,15 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".ppd" */
- if ((p = cupsdFindPrinter(con->uri + 10)) != NULL)
+ if (!strncmp(con->uri, "/ppd/", 5))
+ p = cupsdFindPrinter(con->uri + 5);
+ else
+ p = cupsdFindPrinter(con->uri + 10);
+
+ if (p)
+ {
snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name);
+ }
else
{
if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
@@ -1313,7 +1302,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
break;
}
}
- else if ((!strncmp(con->uri, "/printers/", 10) ||
+ else if ((!strncmp(con->uri, "/icons/", 7) ||
+ !strncmp(con->uri, "/printers/", 10) ||
!strncmp(con->uri, "/classes/", 9)) &&
!strcmp(con->uri + strlen(con->uri) - 4, ".png"))
{
@@ -1324,7 +1314,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".png" */
- if (!strncmp(con->uri, "/printers/", 10))
+ if (!strncmp(con->uri, "/icons/", 7))
+ p = cupsdFindPrinter(con->uri + 7);
+ else if (!strncmp(con->uri, "/printers/", 10))
p = cupsdFindPrinter(con->uri + 10);
else
p = cupsdFindClass(con->uri + 9);
@@ -1685,17 +1677,15 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Validate the resource name...
*/
- if (strncmp(con->uri, "/admin/conf/", 12) ||
- strchr(con->uri + 12, '/') ||
- strlen(con->uri) == 12)
+ if (strcmp(con->uri, "/admin/conf/cupsd.conf"))
{
/*
- * PUT can only be done to configuration files under
- * /admin/conf...
+ * PUT can only be done to the cupsd.conf file...
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Request for subdirectory \"%s\"!", con->uri);
+ "[Client %d] Disallowed PUT request for \"%s\".",
+ con->http.fd, con->uri);
if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE))
{
@@ -1753,8 +1743,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (con->file < 0)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create request file %s: %s",
- con->filename, strerror(errno));
+ "[Client %d] Unable to create request file "
+ "\"%s\": %s", con->http.fd, con->filename,
+ strerror(errno));
if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
{
@@ -1890,7 +1881,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Request for subdirectory \"%s\"!", con->uri);
+ "[Client %d] Request for subdirectory \"%s\".",
+ con->http.fd, con->uri);
if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE))
{
@@ -1991,12 +1983,12 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
{
if (con->http.error && con->http.error != EPIPE)
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d PUT_RECV Closing for error "
+ "[Client %d] HTTP_PUT_RECV Closing for error "
"%d (%s)", con->http.fd, con->http.error,
strerror(con->http.error));
else
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d PUT_RECV Closing on EOF",
+ "[Client %d] HTTP_PUT_RECV Closing on EOF",
con->http.fd);
cupsdCloseClient(con);
@@ -2009,8 +2001,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
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));
+ "[Client %d] Unable to write %d bytes to "
+ "\"%s\": %s", con->http.fd, bytes, con->filename,
+ strerror(errno));
close(con->file);
con->file = -1;
@@ -2059,7 +2052,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Install the configuration file...
*/
- status = install_conf_file(con);
+ status = install_cupsd_conf(con);
/*
* Return the status to the client...
@@ -2085,8 +2078,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if ((ipp_state = ippRead(&(con->http), con->request)) == IPP_ERROR)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdReadClient: %d IPP Read Error!",
- con->http.fd);
+ "[Client %d] IPP read error: %s", con->http.fd,
+ cupsLastErrorString());
cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
cupsdCloseClient(con);
@@ -2105,7 +2098,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
}
else
{
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %d %d.%d %s %d",
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] %d.%d %s %d",
con->http.fd, con->request->request.op.version[0],
con->request->request.op.version[1],
ippOpString(con->request->request.op.operation_id),
@@ -2127,8 +2120,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (con->file < 0)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create request file %s: %s",
- con->filename, strerror(errno));
+ "[Client %d] Unable to create request file "
+ "\"%s\": %s", con->http.fd, con->filename,
+ strerror(errno));
if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
{
@@ -2148,12 +2142,12 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
{
if (con->http.error && con->http.error != EPIPE)
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d POST_SEND Closing for "
+ "[Client %d] HTTP_POST_SEND Closing for "
"error %d (%s)", con->http.fd, con->http.error,
strerror(con->http.error));
else
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d POST_SEND Closing on EOF",
+ "[Client %d] HTTP_POST_SEND Closing on EOF",
con->http.fd);
cupsdCloseClient(con);
@@ -2166,9 +2160,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
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));
+ "[Client %d] Unable to write %d bytes to "
+ "\"%s\": %s", con->http.fd, bytes,
+ con->filename, strerror(errno));
close(con->file);
con->file = -1;
@@ -2188,8 +2182,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
else if (con->http.state != HTTP_POST_SEND)
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d Closing on unknown HTTP "
- "state %d", con->http.fd, con->http.state);
+ "[Client %d] Closing on unexpected state %s.",
+ con->http.fd, http_states[con->http.state]);
cupsdCloseClient(con);
return;
}
@@ -2281,7 +2275,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (!con->http.keep_alive)
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdReadClient: %d Closing because Keep-Alive disabled",
+ "[Client %d] Closing because Keep-Alive disabled",
con->http.fd);
cupsdCloseClient(con);
}
@@ -2315,7 +2309,7 @@ cupsdSendCommand(
if (fd < 0)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdSendCommand: %d Unable to open \"%s\" for reading: %s",
+ "[Client %d] Unable to open \"%s\" for reading: %s",
con->http.fd, con->filename ? con->filename : "/dev/null",
strerror(errno));
return (0);
@@ -2331,11 +2325,11 @@ cupsdSendCommand(
if (fd >= 0)
close(fd);
- cupsdLogMessage(CUPSD_LOG_INFO, "Started \"%s\" (pid=%d)", command,
- con->pipe_pid);
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Started \"%s\" (pid=%d)",
+ con->http.fd, command, con->pipe_pid);
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSendCommand: %d file=%d",
- con->http.fd, con->file);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] file=%d", con->http.fd,
+ con->file);
if (con->pipe_pid == 0)
return (0);
@@ -2363,7 +2357,7 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */
int auth_type)/* I - Authentication type */
{
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdSendError(con=%p(%d), code=%d, auth_type=%d", con,
+ "[Client %d] cupsdSendError code=%d, auth_type=%d",
con->http.fd, code, auth_type);
#ifdef HAVE_SSL
@@ -2519,10 +2513,6 @@ cupsdSendHeader(
int auth_type) /* I - Type of authentication */
{
char auth_str[1024]; /* Authorization string */
-#if 0 /* def HAVE_GSSAPI */
- static char *gss_buf = NULL; /* Kerberos auth data buffer */
- static int gss_bufsize = 0; /* Size of Kerberos auth data buffer */
-#endif /* HAVE_GSSAPI */
/*
@@ -2577,7 +2567,7 @@ cupsdSendHeader(
if (auth_type == CUPSD_AUTH_NONE)
{
if (!con->best || con->best->type <= CUPSD_AUTH_NONE)
- auth_type = DefaultAuthType;
+ auth_type = cupsdDefaultAuthType();
else
auth_type = con->best->type;
}
@@ -2609,7 +2599,7 @@ cupsdSendHeader(
* requests when the request requires system group membership - then the
* client knows the root certificate can/should be used.
*
- * Also, for Mac OS X we also look for @AUTHKEY and add an "authkey"
+ * Also, for OS X we also look for @AUTHKEY and add an "authkey"
* parameter as needed...
*/
@@ -2652,7 +2642,7 @@ cupsdSendHeader(
if (auth_str[0])
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdSendHeader: %d WWW-Authenticate: %s", con->http.fd,
+ "[Client %d] WWW-Authenticate: %s", con->http.fd,
auth_str);
if (httpPrintf(HTTP(con), "WWW-Authenticate: %s\r\n", auth_str) < 0)
@@ -2733,11 +2723,23 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdWriteClient(con=%p(%d)) response=%p(%d), file=%d "
- "pipe_pid=%d state=%d",
- con, con->http.fd, con->response,
- con->response ? con->response->state : -1,
- con->file, con->pipe_pid, con->http.state);
+ "[Client %d] cupsdWriteClient "
+ "error=%d, "
+ "used=%d, "
+ "state=%s, "
+ "data_encoding=HTTP_ENCODE_%s, "
+ "data_remaining=" CUPS_LLFMT ", "
+ "response=%p(%s), "
+ "pipe_pid=%d, "
+ "file=%d",
+ con->http.fd, con->http.error, con->http.used,
+ http_states[con->http.state],
+ con->http.data_encoding == HTTP_ENCODE_CHUNKED ?
+ "CHUNKED" : "LENGTH",
+ CUPS_LLCAST con->http.data_remaining,
+ con->response,
+ con->response ? ipp_states[con->response->state] : "",
+ con->pipe_pid, con->file);
if (con->http.state != HTTP_GET_SEND &&
con->http.state != HTTP_POST_SEND)
@@ -2748,8 +2750,8 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
*/
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdWriteClient: %d Closing on unknown HTTP state %d",
- con->http.fd, con->http.state);
+ "[Client %d] Closing on unexpected HTTP state %s.",
+ con->http.fd, http_states[con->http.state]);
cupsdCloseClient(con);
return;
}
@@ -2902,7 +2904,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
if (httpWrite2(HTTP(con), con->header, con->header_used) < 0)
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdWriteClient: %d Closing for error %d (%s)",
+ "[Client %d] Closing for error %d (%s)",
con->http.fd, con->http.error,
strerror(con->http.error));
cupsdCloseClient(con);
@@ -2939,7 +2941,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
if (httpWrite2(HTTP(con), "", 0) < 0)
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdWriteClient: %d Closing for error %d (%s)",
+ "[Client %d] Closing for error %d (%s)",
con->http.fd, con->http.error,
strerror(con->http.error));
cupsdCloseClient(con);
@@ -2989,7 +2991,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
if (!con->http.keep_alive)
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdWriteClient: %d Closing because Keep-Alive disabled",
+ "[Client %d] Closing because Keep-Alive disabled.",
con->http.fd);
cupsdCloseClient(con);
return;
@@ -3027,9 +3029,9 @@ check_if_modified(
return (1);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "check_if_modified(con=%p(%d), "
+ "[Client %d] check_if_modified "
"filestats=%p(" CUPS_LLFMT ", %d)) If-Modified-Since=\"%s\"",
- con, con->http.fd, filestats, CUPS_LLCAST filestats->st_size,
+ con->http.fd, filestats, CUPS_LLCAST filestats->st_size,
(int)filestats->st_mtime, ptr);
while (*ptr != '\0')
@@ -3081,274 +3083,6 @@ compare_clients(cupsd_client_t *a, /* I - First client */
}
-#ifdef HAVE_CDSASSL
-/*
- * 'copy_cdsa_certificate()' - Copy a SSL/TLS certificate from the System
- * keychain.
- */
-
-static CFArrayRef /* O - Array of certificates */
-copy_cdsa_certificate(
- cupsd_client_t *con) /* I - Client connection */
-{
- OSStatus err; /* Error info */
- SecKeychainRef keychain = NULL;/* Keychain reference */
- SecIdentitySearchRef search = NULL; /* Search reference */
- SecIdentityRef identity = NULL;/* Identity */
- CFArrayRef certificates = NULL;
- /* Certificate array */
-# if HAVE_SECPOLICYCREATESSL
- SecPolicyRef policy = NULL; /* Policy ref */
- CFStringRef servername = NULL;
- /* Server name */
- CFMutableDictionaryRef query = NULL; /* Query qualifiers */
- char localname[1024];/* Local hostname */
-# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
- SecPolicyRef policy = NULL; /* Policy ref */
- SecPolicySearchRef policy_search = NULL;
- /* Policy search ref */
- CSSM_DATA options; /* Policy options */
- CSSM_APPLE_TP_SSL_OPTIONS
- ssl_options; /* SSL Option for hostname */
- char localname[1024];/* Local hostname */
-# endif /* HAVE_SECPOLICYCREATESSL */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "copy_cdsa_certificate: Looking for certs for \"%s\"...",
- con->servername);
-
- if ((err = SecKeychainOpen(ServerCertificate, &keychain)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot open keychain \"%s\" - %s (%d)",
- ServerCertificate, cssmErrorString(err), (int)err);
- goto cleanup;
- }
-
-# if HAVE_SECPOLICYCREATESSL
- servername = CFStringCreateWithCString(kCFAllocatorDefault, con->servername,
- kCFStringEncodingUTF8);
-
- policy = SecPolicyCreateSSL(1, servername);
-
- if (servername)
- CFRelease(servername);
-
- if (!policy)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
- goto cleanup;
- }
-
- if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create query dictionary");
- goto cleanup;
- }
-
- CFDictionaryAddValue(query, kSecClass, kSecClassIdentity);
- CFDictionaryAddValue(query, kSecMatchPolicy, policy);
- CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue);
- CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne);
-
- err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
-
- if (err && DNSSDHostName)
- {
- /*
- * Search for the connection server name failed; try the DNS-SD .local
- * hostname instead...
- */
-
- snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "copy_cdsa_certificate: Looking for certs for \"%s\"...",
- localname);
-
- servername = CFStringCreateWithCString(kCFAllocatorDefault, localname,
- kCFStringEncodingUTF8);
-
- CFRelease(policy);
-
- policy = SecPolicyCreateSSL(1, servername);
-
- if (servername)
- CFRelease(servername);
-
- if (!policy)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
- goto cleanup;
- }
-
- CFDictionarySetValue(query, kSecMatchPolicy, policy);
-
- err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
- }
-
- if (err)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Cannot find signing key in keychain \"%s\": %s (%d)",
- ServerCertificate, cssmErrorString(err), (int)err);
- goto cleanup;
- }
-
-# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
- /*
- * Use a policy to search for valid certificates whose common name matches the
- * servername...
- */
-
- if (SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL,
- NULL, &policy_search))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create a policy search reference");
- goto cleanup;
- }
-
- if (SecPolicySearchCopyNext(policy_search, &policy))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Cannot find a policy to use for searching");
- goto cleanup;
- }
-
- memset(&ssl_options, 0, sizeof(ssl_options));
- ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION;
- ssl_options.ServerName = con->servername;
- ssl_options.ServerNameLen = strlen(con->servername);
-
- options.Data = (uint8 *)&ssl_options;
- options.Length = sizeof(ssl_options);
-
- if (SecPolicySetValue(policy, &options))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Cannot set policy value to use for searching");
- goto cleanup;
- }
-
- if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
- keychain, FALSE, &search)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Cannot create identity search reference: %s (%d)",
- cssmErrorString(err), (int)err);
- goto cleanup;
- }
-
- err = SecIdentitySearchCopyNext(search, &identity);
-
- if (err && DNSSDHostName)
- {
- /*
- * Search for the connection server name failed; try the DNS-SD .local
- * hostname instead...
- */
-
- snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
-
- ssl_options.ServerName = localname;
- ssl_options.ServerNameLen = strlen(localname);
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "copy_cdsa_certificate: Looking for certs for \"%s\"...",
- localname);
-
- if (SecPolicySetValue(policy, &options))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Cannot set policy value to use for searching");
- goto cleanup;
- }
-
- CFRelease(search);
- search = NULL;
- if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
- keychain, FALSE, &search)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Cannot create identity search reference: %s (%d)",
- cssmErrorString(err), (int)err);
- goto cleanup;
- }
-
- err = SecIdentitySearchCopyNext(search, &identity);
-
- }
-
- if (err)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Cannot find signing key in keychain \"%s\": %s (%d)",
- ServerCertificate, cssmErrorString(err), (int)err);
- goto cleanup;
- }
-
-# else
- /*
- * Assume there is exactly one SecIdentity in the keychain...
- */
-
- if ((err = SecIdentitySearchCreate(keychain, CSSM_KEYUSE_SIGN, &search)))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Cannot create identity search reference (%d)", (int)err);
- goto cleanup;
- }
-
- if ((err = SecIdentitySearchCopyNext(search, &identity)))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Cannot find signing key in keychain \"%s\": %s (%d)",
- ServerCertificate, cssmErrorString(err), (int)err);
- goto cleanup;
- }
-# endif /* HAVE_SECPOLICYCREATESSL */
-
- if (CFGetTypeID(identity) != SecIdentityGetTypeID())
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "SecIdentity CFTypeID failure!");
- goto cleanup;
- }
-
- if ((certificates = CFArrayCreate(NULL, (const void **)&identity,
- 1, &kCFTypeArrayCallBacks)) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create certificate array");
- goto cleanup;
- }
-
- cleanup :
-
- if (keychain)
- CFRelease(keychain);
- if (search)
- CFRelease(search);
- if (identity)
- CFRelease(identity);
-
-# if HAVE_SECPOLICYCREATESSL
- if (policy)
- CFRelease(policy);
- if (query)
- CFRelease(query);
-# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
- if (policy)
- CFRelease(policy);
- if (policy_search)
- CFRelease(policy_search);
-# endif /* HAVE_SECPOLICYCREATESSL */
-
- return (certificates);
-}
-#endif /* HAVE_CDSASSL */
-
-
/*
* 'data_ready()' - Check whether data is available from a client.
*/
@@ -3380,245 +3114,6 @@ data_ready(cupsd_client_t *con) /* I - Client */
}
-#ifdef HAVE_SSL
-/*
- * 'encrypt_client()' - Enable encryption for the client...
- */
-
-static int /* O - 1 on success, 0 on error */
-encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */
-{
-# ifdef HAVE_LIBSSL
- SSL_CTX *context; /* Context for encryption */
- BIO *bio; /* BIO data */
- unsigned long error; /* Error code */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con,
- con->http.fd);
-
- /*
- * Verify that we have a certificate...
- */
-
- if (access(ServerKey, 0) || access(ServerCertificate, 0))
- {
- /*
- * Nope, make a self-signed certificate...
- */
-
- if (!make_certificate(con))
- return (0);
- }
-
- /*
- * Create the SSL context and accept the connection...
- */
-
- context = SSL_CTX_new(SSLv23_server_method());
-
- SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
- if (SSLOptions & CUPSD_SSL_NOEMPTY)
- SSL_CTX_set_options(context, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
- SSL_CTX_use_PrivateKey_file(context, ServerKey, SSL_FILETYPE_PEM);
- SSL_CTX_use_certificate_chain_file(context, ServerCertificate);
-
- bio = BIO_new(_httpBIOMethods());
- BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)HTTP(con));
-
- con->http.tls = SSL_new(context);
- SSL_set_bio(con->http.tls, bio, bio);
-
- if (SSL_accept(con->http.tls) != 1)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to encrypt connection from %s.",
- con->http.hostname);
-
- while ((error = ERR_get_error()) != 0)
- cupsdLogMessage(CUPSD_LOG_ERROR, "%s", ERR_error_string(error, NULL));
-
- SSL_CTX_free(context);
- SSL_free(con->http.tls);
- con->http.tls = NULL;
- return (0);
- }
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
- con->http.hostname);
-
- return (1);
-
-# elif defined(HAVE_GNUTLS)
- int status; /* Error code */
- gnutls_certificate_server_credentials *credentials;
- /* TLS credentials */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con,
- con->http.fd);
-
- /*
- * Verify that we have a certificate...
- */
-
- if (access(ServerKey, 0) || access(ServerCertificate, 0))
- {
- /*
- * Nope, make a self-signed certificate...
- */
-
- if (!make_certificate(con))
- return (0);
- }
-
- /*
- * Create the SSL object and perform the SSL handshake...
- */
-
- credentials = (gnutls_certificate_server_credentials *)
- malloc(sizeof(gnutls_certificate_server_credentials));
- if (credentials == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to encrypt connection from %s - %s",
- con->http.hostname, strerror(errno));
-
- return (0);
- }
-
- gnutls_certificate_allocate_credentials(credentials);
- gnutls_certificate_set_x509_key_file(*credentials, ServerCertificate,
- ServerKey, GNUTLS_X509_FMT_PEM);
-
- gnutls_init(&con->http.tls, GNUTLS_SERVER);
- gnutls_set_default_priority(con->http.tls);
-
- gnutls_credentials_set(con->http.tls, GNUTLS_CRD_CERTIFICATE, *credentials);
- gnutls_transport_set_ptr(con->http.tls, (gnutls_transport_ptr)HTTP(con));
- gnutls_transport_set_pull_function(con->http.tls, _httpReadGNUTLS);
- gnutls_transport_set_push_function(con->http.tls, _httpWriteGNUTLS);
-
- while ((status = gnutls_handshake(con->http.tls)) != GNUTLS_E_SUCCESS)
- {
- if (gnutls_error_is_fatal(status))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to encrypt connection from %s - %s",
- con->http.hostname, gnutls_strerror(status));
-
- gnutls_deinit(con->http.tls);
- gnutls_certificate_free_credentials(*credentials);
- con->http.tls = NULL;
- free(credentials);
- return (0);
- }
- }
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
- con->http.hostname);
-
- con->http.tls_credentials = credentials;
- return (1);
-
-# elif defined(HAVE_CDSASSL)
- OSStatus error = 0; /* Error code */
- CFArrayRef peerCerts; /* Peer certificates */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con,
- con->http.fd);
-
- con->http.tls_credentials = copy_cdsa_certificate(con);
-
- if (!con->http.tls_credentials)
- {
- /*
- * No keychain (yet), make a self-signed certificate...
- */
-
- if (make_certificate(con))
- con->http.tls_credentials = copy_cdsa_certificate(con);
- }
-
- if (!con->http.tls_credentials)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Could not find signing key in keychain \"%s\"",
- ServerCertificate);
- error = errSSLBadCert; /* errSSLBadConfiguration is a better choice, but not available on 10.2.x */
- }
-
- if (!error)
- error = SSLNewContext(true, &con->http.tls);
-
- if (!error)
- error = SSLSetIOFuncs(con->http.tls, _httpReadCDSA, _httpWriteCDSA);
-
- if (!error)
- error = SSLSetConnection(con->http.tls, HTTP(con));
-
- if (!error)
- error = SSLSetAllowsExpiredCerts(con->http.tls, true);
-
- if (!error)
- error = SSLSetAllowsAnyRoot(con->http.tls, true);
-
- if (!error)
- error = SSLSetCertificate(con->http.tls, con->http.tls_credentials);
-
- if (!error)
- {
- /*
- * Perform SSL/TLS handshake
- */
-
- while ((error = SSLHandshake(con->http.tls)) == errSSLWouldBlock)
- usleep(1000);
- }
-
- if (error)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to encrypt connection from %s - %s (%d)",
- con->http.hostname, cssmErrorString(error), (int)error);
-
- con->http.error = error;
- con->http.status = HTTP_ERROR;
-
- if (con->http.tls)
- {
- SSLDisposeContext(con->http.tls);
- con->http.tls = NULL;
- }
-
- if (con->http.tls_credentials)
- {
- CFRelease(con->http.tls_credentials);
- con->http.tls_credentials = NULL;
- }
-
- return (0);
- }
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
- con->http.hostname);
-
- if (!SSLCopyPeerCertificates(con->http.tls, &peerCerts) && peerCerts)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates!",
- (int)CFArrayGetCount(peerCerts));
- CFRelease(peerCerts);
- }
- else
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Received NO peer certificates!");
-
- return (1);
-
-# endif /* HAVE_LIBSSL */
-}
-#endif /* HAVE_SSL */
-
-
/*
* 'get_file()' - Get a filename and state info.
*/
@@ -3802,8 +3297,8 @@ get_file(cupsd_client_t *con, /* I - Client connection */
}
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "get_file(con=%p(%d), filestats=%p, filename=%p, len=%d) = "
- "%s", con, con->http.fd, filestats, filename, len,
+ "[Client %d] get_file filestats=%p, filename=%p, len=%d, "
+ "returning \"%s\".", con->http.fd, filestats, filename, len,
status ? "(null)" : filename);
if (status)
@@ -3814,14 +3309,13 @@ get_file(cupsd_client_t *con, /* I - Client connection */
/*
- * 'install_conf_file()' - Install a configuration file.
+ * 'install_cupsd_conf()' - Install a configuration file.
*/
static http_status_t /* O - Status */
-install_conf_file(cupsd_client_t *con) /* I - Connection */
+install_cupsd_conf(cupsd_client_t *con) /* I - Connection */
{
char filename[1024]; /* Configuration filename */
- mode_t mode; /* Permissions */
cups_file_t *in, /* Input file */
*out; /* Output file */
char buffer[16384]; /* Copy buffer */
@@ -3843,19 +3337,14 @@ install_conf_file(cupsd_client_t *con) /* I - Connection */
* Open the new config file...
*/
- snprintf(filename, sizeof(filename), "%s%s", ServerRoot, con->uri + 11);
- if (!strcmp(con->uri, "/admin/conf/printers.conf"))
- mode = ConfigFilePerm & 0600;
- else
- mode = ConfigFilePerm;
-
- if ((out = cupsdCreateConfFile(filename, mode)) == NULL)
+ if ((out = cupsdCreateConfFile(ConfigurationFile, ConfigFilePerm)) == NULL)
{
cupsFileClose(in);
return (HTTP_SERVER_ERROR);
}
- cupsdLogMessage(CUPSD_LOG_INFO, "Installing config file \"%s\"...", filename);
+ cupsdLogMessage(CUPSD_LOG_INFO, "Installing config file \"%s\"...",
+ ConfigurationFile);
/*
* Copy from the request to the new config file...
@@ -3866,12 +3355,12 @@ install_conf_file(cupsd_client_t *con) /* I - Connection */
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Unable to copy to config file \"%s\": %s",
- filename, strerror(errno));
+ ConfigurationFile, strerror(errno));
cupsFileClose(in);
cupsFileClose(out);
- snprintf(filename, sizeof(filename), "%s%s.N", ServerRoot, con->uri + 11);
+ snprintf(filename, sizeof(filename), "%s.N", ConfigurationFile);
cupsdRemoveFile(filename);
return (HTTP_SERVER_ERROR);
@@ -3883,7 +3372,7 @@ install_conf_file(cupsd_client_t *con) /* I - Connection */
cupsFileClose(in);
- if (cupsdCloseCreatedConfFile(out, filename))
+ if (cupsdCloseCreatedConfFile(out, ConfigurationFile))
return (HTTP_SERVER_ERROR);
/*
@@ -3894,14 +3383,10 @@ install_conf_file(cupsd_client_t *con) /* I - Connection */
cupsdClearString(&con->filename);
/*
- * If the cupsd.conf file was updated, set the NeedReload flag...
+ * Set the NeedReload flag...
*/
- if (!strcmp(con->uri, "/admin/conf/cupsd.conf"))
- NeedReload = RELOAD_CUPSD;
- else
- NeedReload = RELOAD_ALL;
-
+ NeedReload = RELOAD_CUPSD;
ReloadTime = time(NULL);
/*
@@ -3942,9 +3427,9 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
if (!type || _cups_strcasecmp(type->super, "application"))
{
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
- "type=%s/%s) = 0", con, con->http.fd, filename, filestats,
- type ? type->super : "unknown",
+ "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+ "type=%s/%s, returning 0", con->http.fd, filename,
+ filestats, type ? type->super : "unknown",
type ? type->type : "unknown");
return (0);
}
@@ -3962,9 +3447,9 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
cupsdSetStringf(&con->options, " %s", options);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
- "type=%s/%s) = 1", con, con->http.fd, filename, filestats,
- type->super, type->type);
+ "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+ "type=%s/%s, returning 1", con->http.fd, filename,
+ filestats, type->super, type->type);
return (1);
}
#ifdef HAVE_JAVA
@@ -3982,9 +3467,9 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
cupsdSetStringf(&con->options, " %s", filename);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
- "type=%s/%s) = 1", con, con->http.fd, filename, filestats,
- type->super, type->type);
+ "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+ "type=%s/%s, returning 1", con->http.fd, filename,
+ filestats, type->super, type->type);
return (1);
}
#endif /* HAVE_JAVA */
@@ -4003,9 +3488,9 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
cupsdSetStringf(&con->options, " %s", filename);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
- "type=%s/%s) = 1", con, con->http.fd, filename, filestats,
- type->super, type->type);
+ "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+ "type=%s/%s, returning 1", con->http.fd, filename,
+ filestats, type->super, type->type);
return (1);
}
#endif /* HAVE_PERL */
@@ -4024,9 +3509,9 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
cupsdSetStringf(&con->options, " %s", filename);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
- "type=%s/%s) = 1", con, con->http.fd, filename, filestats,
- type->super, type->type);
+ "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+ "type=%s/%s, returning 1", con->http.fd, filename,
+ filestats, type->super, type->type);
return (1);
}
#endif /* HAVE_PHP */
@@ -4045,17 +3530,17 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
cupsdSetStringf(&con->options, " %s", filename);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
- "type=%s/%s) = 1", con, con->http.fd, filename, filestats,
- type->super, type->type);
+ "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+ "type=%s/%s, returning 1", con->http.fd, filename,
+ filestats, type->super, type->type);
return (1);
}
#endif /* HAVE_PYTHON */
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, "
- "type=%s/%s) = 0", con, con->http.fd, filename, filestats,
- type->super, type->type);
+ "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
+ "type=%s/%s, returning 0", con->http.fd, filename,
+ filestats, type->super, type->type);
return (0);
}
@@ -4095,475 +3580,6 @@ is_path_absolute(const char *path) /* I - Input path */
}
-#ifdef HAVE_SSL
-/*
- * 'make_certificate()' - Make a self-signed SSL/TLS certificate.
- */
-
-static int /* O - 1 on success, 0 on failure */
-make_certificate(cupsd_client_t *con) /* I - Client connection */
-{
-#if defined(HAVE_LIBSSL) && defined(HAVE_WAITPID)
- int pid, /* Process ID of command */
- status; /* Status of command */
- char command[1024], /* Command */
- *argv[12], /* Command-line arguments */
- *envp[MAX_ENV + 1], /* Environment variables */
- infofile[1024], /* Type-in information for cert */
- seedfile[1024]; /* Random number seed file */
- int envc, /* Number of environment variables */
- bytes; /* Bytes written */
- cups_file_t *fp; /* Seed/info file */
- int infofd; /* Info file descriptor */
-
-
- /*
- * Run the "openssl" command to seed the random number generator and
- * generate a self-signed certificate that is good for 10 years:
- *
- * openssl rand -rand seedfile 1
- *
- * openssl req -new -x509 -keyout ServerKey \
- * -out ServerCertificate -days 3650 -nodes
- *
- * The seeding step is crucial in ensuring that the openssl command
- * does not block on systems without sufficient entropy...
- */
-
- if (!cupsFileFind("openssl", getenv("PATH"), 1, command, sizeof(command)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "No SSL certificate and openssl command not found!");
- return (0);
- }
-
- if (access("/dev/urandom", 0))
- {
- /*
- * If the system doesn't provide /dev/urandom, then any random source
- * will probably be blocking-style, so generate some random data to
- * use as a seed for the certificate. Note that we have already
- * seeded the random number generator in cupsdInitCerts()...
- */
-
- cupsdLogMessage(CUPSD_LOG_INFO,
- "Seeding the random number generator...");
-
- /*
- * Write the seed file...
- */
-
- if ((fp = cupsTempFile2(seedfile, sizeof(seedfile))) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create seed file %s - %s",
- seedfile, strerror(errno));
- return (0);
- }
-
- for (bytes = 0; bytes < 262144; bytes ++)
- cupsFilePutChar(fp, random());
-
- cupsFileClose(fp);
-
- /*
- * Run the openssl command to seed its random number generator...
- */
-
- argv[0] = "openssl";
- argv[1] = "rand";
- argv[2] = "-rand";
- argv[3] = seedfile;
- argv[4] = "1";
- argv[5] = NULL;
-
- envc = cupsdLoadEnv(envp, MAX_ENV);
- envp[envc] = NULL;
-
- if (!cupsdStartProcess(command, argv, envp, -1, -1, -1, -1, -1, 1, NULL,
- NULL, &pid))
- {
- unlink(seedfile);
- return (0);
- }
-
- while (waitpid(pid, &status, 0) < 0)
- if (errno != EINTR)
- {
- status = 1;
- break;
- }
-
- cupsdFinishProcess(pid, command, sizeof(command), NULL);
-
- /*
- * Remove the seed file, as it is no longer needed...
- */
-
- unlink(seedfile);
-
- if (status)
- {
- if (WIFEXITED(status))
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to seed random number generator - "
- "the openssl command stopped with status %d!",
- WEXITSTATUS(status));
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to seed random number generator - "
- "the openssl command crashed on signal %d!",
- WTERMSIG(status));
-
- return (0);
- }
- }
-
- /*
- * Create a file with the certificate information fields...
- *
- * Note: This assumes that the default questions are asked by the openssl
- * command...
- */
-
- if ((fp = cupsTempFile2(infofile, sizeof(infofile))) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create certificate information file %s - %s",
- infofile, strerror(errno));
- return (0);
- }
-
- cupsFilePrintf(fp, ".\n.\n.\n%s\n.\n%s\n%s\n",
- ServerName, ServerName, ServerAdmin);
- cupsFileClose(fp);
-
- cupsdLogMessage(CUPSD_LOG_INFO,
- "Generating SSL server key and certificate...");
-
- argv[0] = "openssl";
- argv[1] = "req";
- argv[2] = "-new";
- argv[3] = "-x509";
- argv[4] = "-keyout";
- argv[5] = ServerKey;
- argv[6] = "-out";
- argv[7] = ServerCertificate;
- argv[8] = "-days";
- argv[9] = "3650";
- argv[10] = "-nodes";
- argv[11] = NULL;
-
- cupsdLoadEnv(envp, MAX_ENV);
-
- infofd = open(infofile, O_RDONLY);
-
- if (!cupsdStartProcess(command, argv, envp, infofd, -1, -1, -1, -1, 1, NULL,
- NULL, &pid))
- {
- close(infofd);
- unlink(infofile);
- return (0);
- }
-
- close(infofd);
- unlink(infofile);
-
- while (waitpid(pid, &status, 0) < 0)
- if (errno != EINTR)
- {
- status = 1;
- break;
- }
-
- cupsdFinishProcess(pid, command, sizeof(command), NULL);
-
- if (status)
- {
- if (WIFEXITED(status))
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create SSL server key and certificate - "
- "the openssl command stopped with status %d!",
- WEXITSTATUS(status));
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create SSL server key and certificate - "
- "the openssl command crashed on signal %d!",
- WTERMSIG(status));
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server key file \"%s\"...",
- ServerKey);
- cupsdLogMessage(CUPSD_LOG_INFO,
- "Created SSL server certificate file \"%s\"...",
- ServerCertificate);
- }
-
- return (!status);
-
-#elif defined(HAVE_GNUTLS)
- gnutls_x509_crt crt; /* Self-signed certificate */
- gnutls_x509_privkey key; /* Encryption key */
- cups_lang_t *language; /* Default language info */
- cups_file_t *fp; /* Key/cert file */
- unsigned char buffer[8192]; /* Buffer for x509 data */
- size_t bytes; /* Number of bytes of data */
- unsigned char serial[4]; /* Serial number buffer */
- time_t curtime; /* Current time */
- int result; /* Result of GNU TLS calls */
-
-
- /*
- * Create the encryption key...
- */
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Generating SSL server key...");
-
- gnutls_x509_privkey_init(&key);
- gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 2048, 0);
-
- /*
- * Save it...
- */
-
- bytes = sizeof(buffer);
-
- if ((result = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM,
- buffer, &bytes)) < 0)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to export SSL server key - %s",
- gnutls_strerror(result));
- gnutls_x509_privkey_deinit(key);
- return (0);
- }
- else if ((fp = cupsFileOpen(ServerKey, "w")) != NULL)
- {
- cupsFileWrite(fp, (char *)buffer, bytes);
- cupsFileClose(fp);
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server key file \"%s\"...",
- ServerKey);
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create SSL server key file \"%s\" - %s",
- ServerKey, strerror(errno));
- gnutls_x509_privkey_deinit(key);
- return (0);
- }
-
- /*
- * Create the self-signed certificate...
- */
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Generating self-signed SSL certificate...");
-
- language = cupsLangDefault();
- curtime = time(NULL);
- serial[0] = curtime >> 24;
- serial[1] = curtime >> 16;
- serial[2] = curtime >> 8;
- serial[3] = curtime;
-
- gnutls_x509_crt_init(&crt);
- if (strlen(language->language) == 5)
- gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0,
- language->language + 3, 2);
- else
- gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0,
- "US", 2);
- gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0,
- ServerName, strlen(ServerName));
- gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
- ServerName, strlen(ServerName));
- gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME,
- 0, "Unknown", 7);
- gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0,
- "Unknown", 7);
- gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_LOCALITY_NAME, 0,
- "Unknown", 7);
- gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_PKCS9_EMAIL, 0,
- ServerAdmin, strlen(ServerAdmin));
- gnutls_x509_crt_set_key(crt, key);
- gnutls_x509_crt_set_serial(crt, serial, sizeof(serial));
- gnutls_x509_crt_set_activation_time(crt, curtime);
- gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400);
- gnutls_x509_crt_set_ca_status(crt, 0);
- gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME,
- ServerName);
- gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0);
- gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT);
- gnutls_x509_crt_set_version(crt, 3);
-
- bytes = sizeof(buffer);
- if (gnutls_x509_crt_get_key_id(crt, 0, buffer, &bytes) >= 0)
- gnutls_x509_crt_set_subject_key_id(crt, buffer, bytes);
-
- gnutls_x509_crt_sign(crt, crt, key);
-
- /*
- * Save it...
- */
-
- bytes = sizeof(buffer);
- if ((result = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM,
- buffer, &bytes)) < 0)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to export SSL server certificate - %s",
- gnutls_strerror(result));
- else if ((fp = cupsFileOpen(ServerCertificate, "w")) != NULL)
- {
- cupsFileWrite(fp, (char *)buffer, bytes);
- cupsFileClose(fp);
-
- cupsdLogMessage(CUPSD_LOG_INFO,
- "Created SSL server certificate file \"%s\"...",
- ServerCertificate);
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create SSL server certificate file \"%s\" - %s",
- ServerCertificate, strerror(errno));
-
- /*
- * Cleanup...
- */
-
- gnutls_x509_crt_deinit(crt);
- gnutls_x509_privkey_deinit(key);
-
- return (1);
-
-#elif defined(HAVE_CDSASSL) && defined(HAVE_WAITPID)
- int pid, /* Process ID of command */
- status; /* Status of command */
- char command[1024], /* Command */
- *argv[4], /* Command-line arguments */
- *envp[MAX_ENV + 1], /* Environment variables */
- keychain[1024], /* Keychain argument */
- infofile[1024], /* Type-in information for cert */
- localname[1024], /* Local hostname */
- *servername; /* Name of server in cert */
- cups_file_t *fp; /* Seed/info file */
- int infofd; /* Info file descriptor */
-
-
- if (con->servername && isdigit(con->servername[0] & 255) && DNSSDHostName)
- {
- snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
- servername = localname;
- }
- else
- servername = con->servername;
-
- /*
- * Run the "certtool" command to generate a self-signed certificate...
- */
-
- if (!cupsFileFind("certtool", getenv("PATH"), 1, command, sizeof(command)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "No SSL certificate and certtool command not found!");
- return (0);
- }
-
- /*
- * Create a file with the certificate information fields...
- *
- * Note: This assumes that the default questions are asked by the certtool
- * command...
- */
-
- if ((fp = cupsTempFile2(infofile, sizeof(infofile))) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create certificate information file %s - %s",
- infofile, strerror(errno));
- return (0);
- }
-
- cupsFilePrintf(fp,
- "%s\n" /* Enter key and certificate label */
- "r\n" /* Generate RSA key pair */
- "2048\n" /* Key size in bits */
- "y\n" /* OK (y = yes) */
- "b\n" /* Usage (b=signing/encryption) */
- "s\n" /* Sign with SHA1 */
- "y\n" /* OK (y = yes) */
- "%s\n" /* Common name */
- "\n" /* Country (default) */
- "\n" /* Organization (default) */
- "\n" /* Organizational unit (default) */
- "\n" /* State/Province (default) */
- "%s\n" /* Email address */
- "y\n", /* OK (y = yes) */
- servername, servername, ServerAdmin);
- cupsFileClose(fp);
-
- cupsdLogMessage(CUPSD_LOG_INFO,
- "Generating SSL server key and certificate...");
-
- snprintf(keychain, sizeof(keychain), "k=%s", ServerCertificate);
-
- argv[0] = "certtool";
- argv[1] = "c";
- argv[2] = keychain;
- argv[3] = NULL;
-
- cupsdLoadEnv(envp, MAX_ENV);
-
- infofd = open(infofile, O_RDONLY);
-
- if (!cupsdStartProcess(command, argv, envp, infofd, -1, -1, -1, -1, 1, NULL,
- NULL, &pid))
- {
- close(infofd);
- unlink(infofile);
- return (0);
- }
-
- close(infofd);
- unlink(infofile);
-
- while (waitpid(pid, &status, 0) < 0)
- if (errno != EINTR)
- {
- status = 1;
- break;
- }
-
- cupsdFinishProcess(pid, command, sizeof(command), NULL);
-
- if (status)
- {
- if (WIFEXITED(status))
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create SSL server key and certificate - "
- "the certtool command stopped with status %d!",
- WEXITSTATUS(status));
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create SSL server key and certificate - "
- "the certtool command crashed on signal %d!",
- WTERMSIG(status));
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_INFO,
- "Created SSL server certificate file \"%s\"...",
- ServerCertificate);
- }
-
- return (!status);
-
-#else
- return (0);
-#endif /* HAVE_LIBSSL && HAVE_WAITPID */
-}
-#endif /* HAVE_SSL */
-
-
/*
* 'pipe_command()' - Pipe the output of a command to the remote client.
*/
@@ -4603,7 +3619,6 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
server_name[1024], /* SERVER_NAME environment variable */
server_port[1024]; /* SERVER_PORT environment variable */
ipp_attribute_t *attr; /* attributes-natural-language attribute */
- void *ccache = NULL; /* Kerberos credentials */
/*
@@ -4625,9 +3640,9 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
*/
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "pipe_command(con=%p(%d), infile=%d, outfile=%p, "
- "command=\"%s\", options=\"%s\", root=%d)",
- con, con->http.fd, infile, outfile, command,
+ "[Client %d] pipe_command infile=%d, outfile=%p, "
+ "command=\"%s\", options=\"%s\", root=%d",
+ con->http.fd, infile, outfile, command,
options ? options : "(null)", root);
argv[0] = command;
@@ -4955,7 +3970,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
*/
if (con->username[0])
- cupsdAddCert(pid, con->username, ccache);
+ cupsdAddCert(pid, con->username, con->type);
cupsdLogMessage(CUPSD_LOG_DEBUG, "[CGI] Started %s (PID %d)", command, pid);
@@ -5003,16 +4018,26 @@ valid_host(cupsd_client_t *con) /* I - Client connection */
!strncmp(host, "[::1]:", 6));
}
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
/*
* Check if the hostname is something.local (Bonjour); if so, allow it.
*/
- if ((end = strrchr(host, '.')) != NULL &&
- (!_cups_strcasecmp(end, ".local") || !_cups_strncasecmp(end, ".local:", 7) ||
- !_cups_strcasecmp(end, ".local.") || !_cups_strncasecmp(end, ".local.:", 8)))
+ if ((end = strrchr(host, '.')) != NULL && end > host &&
+ (!end[1] || end[1] == ':'))
+ {
+ /*
+ * "." on end, work back to second-to-last "."...
+ */
+ for (end --; end > host && *end != '.'; end --);
+ }
+
+ if (end && (!_cups_strcasecmp(end, ".local") ||
+ !_cups_strncasecmp(end, ".local:", 7) ||
+ !_cups_strcasecmp(end, ".local.") ||
+ !_cups_strncasecmp(end, ".local.:", 8)))
return (1);
-#endif /* HAVE_DNSSD */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
/*
* Check if the hostname is an IP address...
@@ -5073,7 +4098,7 @@ valid_host(cupsd_client_t *con) /* I - Client connection */
}
}
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
for (a = (cupsd_alias_t *)cupsArrayFirst(DNSSDAlias);
a;
a = (cupsd_alias_t *)cupsArrayNext(DNSSDAlias))
@@ -5098,7 +4123,7 @@ valid_host(cupsd_client_t *con) /* I - Client connection */
return (1);
}
}
-#endif /* HAVE_DNSSD */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
/*
* Check for interface hostname matches...
@@ -5140,8 +4165,8 @@ write_file(cupsd_client_t *con, /* I - Client connection */
con->file = open(filename, O_RDONLY);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "write_file(con=%p(%d), code=%d, filename=\"%s\" (%d), "
- "type=\"%s\", filestats=%p)", con, con->http.fd,
+ "[Client %d] write_file code=%d, filename=\"%s\" (%d), "
+ "type=\"%s\", filestats=%p", con->http.fd,
code, filename, con->file, type ? type : "(null)", filestats);
if (con->file < 0)
@@ -5189,8 +4214,8 @@ static void
write_pipe(cupsd_client_t *con) /* I - Client connection */
{
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "write_pipe(con=%p(%d)) CGI output on fd %d",
- con, con->http.fd, con->file);
+ "[Client %d] write_pipe CGI output on fd %d",
+ con->http.fd, con->file);
con->file_ready = 1;
@@ -5200,5 +4225,5 @@ write_pipe(cupsd_client_t *con) /* I - Client connection */
/*
- * End of "$Id: client.c 10338 2012-03-07 06:05:39Z mike $".
+ * End of "$Id: client.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/client.h b/scheduler/client.h
index 7beb4aa..106e43e 100644
--- a/scheduler/client.h
+++ b/scheduler/client.h
@@ -1,5 +1,5 @@
/*
- * "$Id: client.h 9652 2011-03-25 21:25:38Z mike $"
+ * "$Id: client.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Client definitions for the CUPS scheduler.
*
@@ -32,8 +32,10 @@ struct cupsd_client_s
http_state_t operation; /* Request operation */
off_t bytes; /* Bytes transferred for this request */
int type; /* AuthType for username */
- char username[256], /* Username from Authorization: line */
- password[33], /* Password from Authorization: line */
+ char username[HTTP_MAX_VALUE],
+ /* Username from Authorization: line */
+ password[HTTP_MAX_VALUE],
+ /* Password from Authorization: line */
uri[HTTP_MAX_URI],
/* Localized URL/URI for GET/PUT */
*filename, /* Filename of output file */
@@ -131,7 +133,12 @@ extern void cupsdStopListening(void);
extern void cupsdUpdateCGI(void);
extern void cupsdWriteClient(cupsd_client_t *con);
+#ifdef HAVE_SSL
+extern int cupsdEndTLS(cupsd_client_t *con);
+extern int cupsdStartTLS(cupsd_client_t *con);
+#endif /* HAVE_SSL */
+
/*
- * End of "$Id: client.h 9652 2011-03-25 21:25:38Z mike $".
+ * End of "$Id: client.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/colorman.c b/scheduler/colorman.c
new file mode 100644
index 0000000..be064b6
--- /dev/null
+++ b/scheduler/colorman.c
@@ -0,0 +1,1542 @@
+/*
+ * "$Id: colorman.c 11173 2013-07-23 12:31:34Z msweet $"
+ *
+ * Color management routines for the CUPS scheduler.
+ *
+ * Copyright 2007-2013 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ *
+ * Original DBUS/colord code is Copyright 2011 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDERS 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:
+ *
+ * cupsdRegisterColor() - Register vendor color profiles in a PPD
+ * file.
+ * cupsdStartColor() - Initialize color management.
+ * cupsdStopColor() - Shutdown color management.
+ * cupsdUnregisterColor() - Unregister vendor color profiles in a PPD
+ * file.
+ * apple_init_profile() - Initialize a color profile.
+ * apple_register_profiles() - Register color profiles for a printer.
+ * apple_unregister_profiles() - Remove color profiles for the specified
+ * printer.
+ * colord_create_device() - Create a device and register profiles.
+ * colord_create_profile() - Create a color profile for a printer.
+ * colord_delete_device() - Delete a device
+ * colord_device_add_profile() - Assign a profile to a device.
+ * colord_dict_add_strings() - Add two strings to a dictionary.
+ * colord_find_device() - Finds a device
+ * colord_get_qualifier_format() - Get the qualifier format.
+ * colord_register_printer() - Register profiles for a printer.
+ * colord_unregister_printer() - Unregister profiles for a printer.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+#include <cups/ppd-private.h>
+
+#ifdef __APPLE__
+# include <ApplicationServices/ApplicationServices.h>
+extern CFUUIDRef ColorSyncCreateUUIDFromUInt32(unsigned id);
+# include <CoreFoundation/CoreFoundation.h>
+#elif defined(HAVE_DBUS)
+# include <dbus/dbus.h>
+
+/*
+ * Defines used by colord. See the reference docs for further details:
+ *
+ * http://colord.hughsie.com/api/ref-dbus.html
+ */
+
+# define COLORD_SCOPE_NORMAL "normal"
+ /* System scope */
+# define COLORD_SCOPE_TEMP "temp" /* Process scope */
+# define COLORD_SCOPE_DISK "disk" /* Lives forever, as stored in DB */
+
+# define COLORD_RELATION_SOFT "soft" /* Mapping is not default */
+# define COLORD_RELATION_HARD "hard" /* Explicitly mapped profile */
+
+# define COLORD_SPACE_RGB "rgb" /* RGB colorspace */
+# define COLORD_SPACE_CMYK "cmyk" /* CMYK colorspace */
+# define COLORD_SPACE_GRAY "gray" /* Gray colorspace */
+# define COLORD_SPACE_UNKNOWN "unknown"
+ /* Unknown colorspace */
+
+# define COLORD_MODE_PHYSICAL "physical"
+ /* Actual device */
+# define COLORD_MODE_VIRTUAL "virtual"
+ /* Virtual device with no hardware */
+
+# define COLORD_KIND_PRINTER "printer"
+ /* printing output device */
+
+# define COLORD_DBUS_SERVICE "org.freedesktop.ColorManager"
+# define COLORD_DBUS_INTERFACE "org.freedesktop.ColorManager"
+# define COLORD_DBUS_INTERFACE_DEVICE "org.freedesktop.ColorManager.Device"
+# define COLORD_DBUS_PATH "/org/freedesktop/ColorManager"
+ /* Path for color management system */
+# define COLORD_DBUS_TIMEOUT 5000 /* Timeout for connecting to colord in ms */
+#endif /* __APPLE__ */
+
+
+/*
+ * Local globals...
+ */
+
+#if !defined(__APPLE__) && defined(HAVE_DBUS)
+static DBusConnection *colord_con = NULL;
+ /* DBUS connection for colord */
+#endif /* !__APPLE__ && HAVE_DBUS */
+
+
+/*
+ * Local functions...
+ */
+
+#ifdef __APPLE__
+static void apple_init_profile(ppd_file_t *ppd, cups_array_t *languages,
+ CFMutableDictionaryRef profile,
+ unsigned id, const char *name,
+ const char *text, const char *iccfile);
+static void apple_register_profiles(cupsd_printer_t *p);
+static void apple_unregister_profiles(cupsd_printer_t *p);
+
+#elif defined(HAVE_DBUS)
+static void colord_create_device(cupsd_printer_t *p, ppd_file_t *ppd,
+ cups_array_t *profiles,
+ const char *colorspace, char **format,
+ const char *relation, const char *scope);
+static void colord_create_profile(cups_array_t *profiles,
+ const char *printer_name,
+ const char *qualifier,
+ const char *colorspace,
+ char **format, const char *iccfile,
+ const char *scope);
+static void colord_delete_device(const char *device_id);
+static void colord_device_add_profile(const char *device_path,
+ const char *profile_path,
+ const char *relation);
+static void colord_dict_add_strings(DBusMessageIter *dict,
+ const char *key, const char *value);
+static char *colord_find_device(const char *device_id);
+static void colord_get_qualifier_format(ppd_file_t *ppd, char *format[3]);
+static void colord_register_printer(cupsd_printer_t *p);
+static void colord_unregister_printer(cupsd_printer_t *p);
+#endif /* __APPLE__ */
+
+
+/*
+ * 'cupsdRegisterColor()' - Register vendor color profiles in a PPD file.
+ */
+
+void
+cupsdRegisterColor(cupsd_printer_t *p) /* I - Printer */
+{
+#ifdef __APPLE__
+ if (!RunUser)
+ {
+ apple_unregister_profiles(p);
+ apple_register_profiles(p);
+ }
+
+#elif defined(HAVE_DBUS)
+ colord_unregister_printer(p);
+ colord_register_printer(p);
+#endif /* __APPLE__ */
+}
+
+
+/*
+ * 'cupsdStartColor()' - Initialize color management.
+ */
+
+void
+cupsdStartColor(void)
+{
+#if !defined(__APPLE__) && defined(HAVE_DBUS)
+ cupsd_printer_t *p; /* Current printer */
+
+
+ colord_con = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
+ p;
+ p = (cupsd_printer_t *)cupsArrayNext(Printers))
+ cupsdRegisterColor(p);
+#endif /* !__APPLE__ && HAVE_DBUS */
+}
+
+
+/*
+ * 'cupsdStopColor()' - Shutdown color management.
+ */
+
+void
+cupsdStopColor(void)
+{
+#if !defined(__APPLE__) && defined(HAVE_DBUS)
+ dbus_connection_unref(colord_con);
+ colord_con = NULL;
+#endif /* !__APPLE__ && HAVE_DBUS */
+}
+
+
+/*
+ * 'cupsdUnregisterColor()' - Unregister vendor color profiles in a PPD file.
+ */
+
+void
+cupsdUnregisterColor(cupsd_printer_t *p)/* I - Printer */
+{
+#ifdef __APPLE__
+ if (!RunUser)
+ apple_unregister_profiles(p);
+
+#elif defined(HAVE_DBUS)
+ colord_unregister_printer(p);
+#endif /* __APPLE__ */
+}
+
+
+#ifdef __APPLE__
+/*
+ * 'apple_init_profile()' - Initialize a color profile.
+ */
+
+static void
+apple_init_profile(
+ ppd_file_t *ppd, /* I - PPD file */
+ cups_array_t *languages, /* I - Languages in the PPD file */
+ CFMutableDictionaryRef profile, /* I - Profile dictionary */
+ unsigned id, /* I - Profile ID */
+ const char *name, /* I - Profile name */
+ const char *text, /* I - Profile UI text */
+ const char *iccfile) /* I - ICC filename */
+{
+ CFURLRef url; /* URL for profile filename */
+ CFMutableDictionaryRef dict; /* Dictionary for name */
+ char *language; /* Current language */
+ ppd_attr_t *attr; /* Profile attribute */
+ CFStringRef cflang, /* Language string */
+ cftext; /* Localized text */
+
+
+ (void)id;
+
+ /*
+ * Build the profile name dictionary...
+ */
+
+ dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (!dict)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize profile \"%s\".",
+ iccfile);
+ return;
+ }
+
+ cftext = CFStringCreateWithCString(kCFAllocatorDefault, text,
+ kCFStringEncodingUTF8);
+
+ if (cftext)
+ {
+ CFDictionarySetValue(dict, CFSTR("en_US"), cftext);
+ CFRelease(cftext);
+ }
+
+ if (languages)
+ {
+ /*
+ * Find localized names for the color profiles...
+ */
+
+ cupsArraySave(ppd->sorted_attrs);
+
+ for (language = (char *)cupsArrayFirst(languages);
+ language;
+ language = (char *)cupsArrayNext(languages))
+ {
+ if (iccfile)
+ {
+ if ((attr = _ppdLocalizedAttr(ppd, "cupsICCProfile", name,
+ language)) == NULL)
+ attr = _ppdLocalizedAttr(ppd, "APTiogaProfile", name, language);
+ }
+ else
+ attr = _ppdLocalizedAttr(ppd, "ColorModel", name, language);
+
+ if (attr && attr->text[0])
+ {
+ cflang = CFStringCreateWithCString(kCFAllocatorDefault, language,
+ kCFStringEncodingUTF8);
+ cftext = CFStringCreateWithCString(kCFAllocatorDefault, attr->text,
+ kCFStringEncodingUTF8);
+
+ if (cflang && cftext)
+ CFDictionarySetValue(dict, cflang, cftext);
+
+ if (cflang)
+ CFRelease(cflang);
+
+ if (cftext)
+ CFRelease(cftext);
+ }
+ }
+
+ cupsArrayRestore(ppd->sorted_attrs);
+ }
+
+ /*
+ * Fill in the profile data...
+ */
+
+ if (iccfile && *iccfile)
+ {
+ url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
+ (const UInt8 *)iccfile,
+ strlen(iccfile), false);
+
+ if (url)
+ {
+ CFDictionarySetValue(profile, kColorSyncDeviceProfileURL, url);
+ CFRelease(url);
+ }
+ }
+
+ CFDictionarySetValue(profile, kColorSyncDeviceModeDescriptions, dict);
+ CFRelease(dict);
+}
+
+
+/*
+ * 'apple_register_profiles()' - Register color profiles for a printer.
+ */
+
+static void
+apple_register_profiles(
+ cupsd_printer_t *p) /* I - Printer */
+{
+ int i; /* Looping var */
+ char ppdfile[1024], /* PPD filename */
+ iccfile[1024], /* ICC filename */
+ selector[PPD_MAX_NAME];
+ /* Profile selection string */
+ ppd_file_t *ppd; /* PPD file */
+ ppd_attr_t *attr, /* Profile attributes */
+ *profileid_attr,/* cupsProfileID attribute */
+ *q1_attr, /* ColorModel (or other) qualifier */
+ *q2_attr, /* MediaType (or other) qualifier */
+ *q3_attr; /* Resolution (or other) qualifier */
+ char q_keyword[PPD_MAX_NAME];
+ /* Qualifier keyword */
+ const char *q1_choice, /* ColorModel (or other) choice */
+ *q2_choice, /* MediaType (or other) choice */
+ *q3_choice; /* Resolution (or other) choice */
+ ppd_option_t *cm_option; /* Color model option */
+ ppd_choice_t *cm_choice; /* Color model choice */
+ int num_profiles; /* Number of profiles */
+ OSStatus error = 0; /* Last error */
+ unsigned device_id, /* Printer device ID */
+ profile_id = 0, /* Profile ID */
+ default_profile_id = 0;
+ /* Default profile ID */
+ CFMutableDictionaryRef device_name; /* Printer device name dictionary */
+ CFStringRef printer_name; /* Printer name string */
+ cups_array_t *languages; /* Languages array */
+ CFMutableDictionaryRef profiles, /* Dictionary of profiles */
+ profile; /* Current profile info dictionary */
+ CFStringRef dict_key; /* Key in factory profile dictionary */
+
+
+ /*
+ * Make sure ColorSync is available...
+ */
+
+ if (ColorSyncRegisterDevice == NULL)
+ return;
+
+ /*
+ * Try opening the PPD file for this printer...
+ */
+
+ snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
+ if ((ppd = _ppdOpenFile(ppdfile, _PPD_LOCALIZATION_ICC_PROFILES)) == NULL)
+ return;
+
+ /*
+ * See if we have any profiles...
+ */
+
+ for (num_profiles = 0, attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
+ attr;
+ attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
+ if (attr->spec[0] && attr->value && attr->value[0])
+ {
+ if (attr->value[0] != '/')
+ snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir,
+ attr->value);
+ else
+ strlcpy(iccfile, attr->value, sizeof(iccfile));
+
+ if (access(iccfile, 0))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "%s: ICC Profile \"%s\" does not exist.", p->name,
+ iccfile);
+ cupsdSetPrinterReasons(p, "+cups-missing-filter-warning");
+ continue;
+ }
+
+ num_profiles ++;
+ }
+
+ /*
+ * Create a dictionary for the factory profiles...
+ */
+
+ profiles = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (!profiles)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to allocate memory for factory profiles.");
+ ppdClose(ppd);
+ return;
+ }
+
+ /*
+ * If we have profiles, add them...
+ */
+
+ if (num_profiles > 0)
+ {
+ /*
+ * For CUPS PPDs, figure out the default profile selector values...
+ */
+
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q1_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else if ((q1_attr = ppdFindAttr(ppd, "DefaultColorModel", NULL)) == NULL)
+ q1_attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL);
+
+ if (q1_attr && q1_attr->value && q1_attr->value[0])
+ q1_choice = q1_attr->value;
+ else
+ q1_choice = "";
+
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q2_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else
+ q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL);
+
+ if (q2_attr && q2_attr->value && q2_attr->value[0])
+ q2_choice = q2_attr->value;
+ else
+ q2_choice = NULL;
+
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL &&
+ attr->value && attr->value[0])
+ {
+ snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
+ q3_attr = ppdFindAttr(ppd, q_keyword, NULL);
+ }
+ else
+ q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL);
+
+ if (q3_attr && q3_attr->value && q3_attr->value[0])
+ q3_choice = q3_attr->value;
+ else
+ q3_choice = NULL;
+
+ /*
+ * Loop through the profiles listed in the PPD...
+ */
+
+ languages = _ppdGetLanguages(ppd);
+
+ for (attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
+ attr;
+ attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
+ if (attr->spec[0] && attr->value && attr->value[0])
+ {
+ /*
+ * Add this profile...
+ */
+
+ if (attr->value[0] != '/')
+ snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir,
+ attr->value);
+ else
+ strlcpy(iccfile, attr->value, sizeof(iccfile));
+
+ if (_cupsFileCheck(iccfile, _CUPS_FILE_CHECK_FILE, !RunUser,
+ cupsdLogFCMessage, p))
+ iccfile[0] = '\0';
+
+ cupsArraySave(ppd->sorted_attrs);
+
+ if ((profileid_attr = ppdFindAttr(ppd, "cupsProfileID",
+ attr->spec)) != NULL &&
+ profileid_attr->value && isdigit(profileid_attr->value[0] & 255))
+ profile_id = (unsigned)strtoul(profileid_attr->value, NULL, 10);
+ else
+ profile_id = _ppdHashName(attr->spec);
+
+ cupsArrayRestore(ppd->sorted_attrs);
+
+ profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (!profile)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to allocate memory for color profile.");
+ CFRelease(profiles);
+ ppdClose(ppd);
+ return;
+ }
+
+ apple_init_profile(ppd, languages, profile, profile_id, attr->spec,
+ attr->text[0] ? attr->text : attr->spec, iccfile);
+
+ dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+ CFSTR("%u"), profile_id);
+ if (dict_key)
+ {
+ CFDictionarySetValue(profiles, dict_key, profile);
+ CFRelease(dict_key);
+ }
+
+ CFRelease(profile);
+
+ /*
+ * See if this is the default profile...
+ */
+
+ if (!default_profile_id && q1_choice && q2_choice && q3_choice)
+ {
+ snprintf(selector, sizeof(selector), "%s.%s.%s", q1_choice, q2_choice,
+ q3_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
+
+ if (!default_profile_id && q1_choice && q2_choice)
+ {
+ snprintf(selector, sizeof(selector), "%s.%s.", q1_choice, q2_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
+
+ if (!default_profile_id && q1_choice && q3_choice)
+ {
+ snprintf(selector, sizeof(selector), "%s..%s", q1_choice, q3_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
+
+ if (!default_profile_id && q1_choice)
+ {
+ snprintf(selector, sizeof(selector), "%s..", q1_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
+
+ if (!default_profile_id && q2_choice && q3_choice)
+ {
+ snprintf(selector, sizeof(selector), ".%s.%s", q2_choice, q3_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
+
+ if (!default_profile_id && q2_choice)
+ {
+ snprintf(selector, sizeof(selector), ".%s.", q2_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
+
+ if (!default_profile_id && q3_choice)
+ {
+ snprintf(selector, sizeof(selector), "..%s", q3_choice);
+ if (!strcmp(selector, attr->spec))
+ default_profile_id = profile_id;
+ }
+ }
+
+ _ppdFreeLanguages(languages);
+ }
+ else if ((cm_option = ppdFindOption(ppd, "ColorModel")) != NULL)
+ {
+ /*
+ * Extract profiles from ColorModel option...
+ */
+
+ const char *profile_name; /* Name of generic profile */
+
+
+ num_profiles = cm_option->num_choices;
+
+ for (i = cm_option->num_choices, cm_choice = cm_option->choices;
+ i > 0;
+ i --, cm_choice ++)
+ {
+ if (!strcmp(cm_choice->choice, "Gray") ||
+ !strcmp(cm_choice->choice, "Black"))
+ profile_name = "Gray";
+ else if (!strcmp(cm_choice->choice, "RGB") ||
+ !strcmp(cm_choice->choice, "CMY"))
+ profile_name = "RGB";
+ else if (!strcmp(cm_choice->choice, "CMYK") ||
+ !strcmp(cm_choice->choice, "KCMY"))
+ profile_name = "CMYK";
+ else
+ profile_name = "DeviceN";
+
+ snprintf(selector, sizeof(selector), "%s..", profile_name);
+ profile_id = _ppdHashName(selector);
+
+ profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ if (!profile)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to allocate memory for color profile.");
+ CFRelease(profiles);
+ ppdClose(ppd);
+ return;
+ }
+
+ apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice,
+ cm_choice->text, NULL);
+
+ dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+ CFSTR("%u"), profile_id);
+ if (dict_key)
+ {
+ CFDictionarySetValue(profiles, dict_key, profile);
+ CFRelease(dict_key);
+ }
+
+ CFRelease(profile);
+
+ if (cm_choice->marked)
+ default_profile_id = profile_id;
+ }
+ }
+ else
+ {
+ /*
+ * Use the default colorspace...
+ */
+
+ attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL);
+
+ num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2;
+
+ /*
+ * Add the grayscale profile first. We always have a grayscale profile.
+ */
+
+ profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ if (!profile)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to allocate memory for color profile.");
+ CFRelease(profiles);
+ ppdClose(ppd);
+ return;
+ }
+
+ profile_id = _ppdHashName("Gray..");
+ apple_init_profile(ppd, NULL, profile, profile_id, "Gray", "Gray", NULL);
+
+ dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"),
+ profile_id);
+ if (dict_key)
+ {
+ CFDictionarySetValue(profiles, dict_key, profile);
+ CFRelease(dict_key);
+ }
+
+ CFRelease(profile);
+
+ /*
+ * Then add the RGB/CMYK/DeviceN color profile...
+ */
+
+ profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ if (!profile)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to allocate memory for color profile.");
+ CFRelease(profiles);
+ ppdClose(ppd);
+ return;
+ }
+
+ switch (ppd->colorspace)
+ {
+ default :
+ case PPD_CS_RGB :
+ case PPD_CS_CMY :
+ profile_id = _ppdHashName("RGB..");
+ apple_init_profile(ppd, NULL, profile, profile_id, "RGB", "RGB",
+ NULL);
+ break;
+
+ case PPD_CS_RGBK :
+ case PPD_CS_CMYK :
+ profile_id = _ppdHashName("CMYK..");
+ apple_init_profile(ppd, NULL, profile, profile_id, "CMYK", "CMYK",
+ NULL);
+ break;
+
+ case PPD_CS_GRAY :
+ if (attr)
+ break;
+
+ case PPD_CS_N :
+ profile_id = _ppdHashName("DeviceN..");
+ apple_init_profile(ppd, NULL, profile, profile_id, "DeviceN",
+ "DeviceN", NULL);
+ break;
+ }
+
+ if (CFDictionaryGetCount(profile) > 0)
+ {
+ dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+ CFSTR("%u"), profile_id);
+ if (dict_key)
+ {
+ CFDictionarySetValue(profiles, dict_key, profile);
+ CFRelease(dict_key);
+ }
+ }
+
+ CFRelease(profile);
+ }
+
+ if (num_profiles > 0)
+ {
+ /*
+ * Make sure we have a default profile ID...
+ */
+
+ if (!default_profile_id)
+ default_profile_id = profile_id; /* Last profile */
+
+ dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"),
+ default_profile_id);
+ if (dict_key)
+ {
+ CFDictionarySetValue(profiles, kColorSyncDeviceDefaultProfileID,
+ dict_key);
+ CFRelease(dict_key);
+ }
+
+ /*
+ * Get the device ID hash and pathelogical name dictionary.
+ */
+
+ cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\"",
+ p->name);
+
+ device_id = _ppdHashName(p->name);
+ device_name = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ printer_name = CFStringCreateWithCString(kCFAllocatorDefault,
+ p->name, kCFStringEncodingUTF8);
+
+ if (device_name && printer_name)
+ {
+ /*
+ * Register the device with ColorSync...
+ */
+
+ CFTypeRef deviceDictKeys[] =
+ { /* Device keys */
+ kColorSyncDeviceDescriptions,
+ kColorSyncFactoryProfiles,
+ kColorSyncDeviceUserScope,
+ kColorSyncDeviceHostScope
+ };
+ CFTypeRef deviceDictVals[] =
+ { /* Device values */
+ device_name,
+ profiles,
+ kCFPreferencesAnyUser,
+ kCFPreferencesCurrentHost
+ };
+ CFDictionaryRef deviceDict; /* Device dictionary */
+ CFUUIDRef deviceUUID; /* Device UUID */
+
+ CFDictionarySetValue(device_name, CFSTR("en_US"), printer_name);
+
+ deviceDict = CFDictionaryCreate(kCFAllocatorDefault,
+ (const void **)deviceDictKeys,
+ (const void **)deviceDictVals,
+ sizeof(deviceDictKeys) /
+ sizeof(deviceDictKeys[0]),
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ deviceUUID = ColorSyncCreateUUIDFromUInt32(device_id);
+
+ if (!deviceDict || !deviceUUID ||
+ !ColorSyncRegisterDevice(kColorSyncPrinterDeviceClass, deviceUUID,
+ deviceDict))
+ error = 1001;
+
+ if (deviceUUID)
+ CFRelease(deviceUUID);
+
+ if (deviceDict)
+ CFRelease(deviceDict);
+ }
+ else
+ error = 1000;
+
+ /*
+ * Clean up...
+ */
+
+ if (error != noErr)
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to register ICC color profiles for \"%s\": %d",
+ p->name, (int)error);
+
+ if (printer_name)
+ CFRelease(printer_name);
+
+ if (device_name)
+ CFRelease(device_name);
+ }
+
+ /*
+ * Free any memory we used...
+ */
+
+ CFRelease(profiles);
+
+ ppdClose(ppd);
+}
+
+
+/*
+ * 'apple_unregister_profiles()' - Remove color profiles for the specified
+ * printer.
+ */
+
+static void
+apple_unregister_profiles(
+ cupsd_printer_t *p) /* I - Printer */
+{
+ /*
+ * Make sure ColorSync is available...
+ */
+
+ if (ColorSyncUnregisterDevice != NULL)
+ {
+ CFUUIDRef deviceUUID; /* Device UUID */
+
+ deviceUUID = ColorSyncCreateUUIDFromUInt32(_ppdHashName(p->name));
+ if (deviceUUID)
+ {
+ ColorSyncUnregisterDevice(kColorSyncPrinterDeviceClass, deviceUUID);
+ CFRelease(deviceUUID);
+ }
+ }
+}
+
+
+#elif defined(HAVE_DBUS)
+/*
+ * 'colord_create_device()' - Create a device and register profiles.
+ */
+
+static void
+colord_create_device(
+ cupsd_printer_t *p, /* I - Printer */
+ ppd_file_t *ppd, /* I - PPD file */
+ cups_array_t *profiles, /* I - Profiles array */
+ const char *colorspace, /* I - Device colorspace, e.g. 'rgb' */
+ char **format, /* I - Device qualifier format */
+ const char *relation, /* I - Profile relation, either 'soft'
+ or 'hard' */
+ const char *scope) /* I - The scope of the device, e.g.
+ 'normal', 'temp' or 'disk' */
+{
+ DBusMessage *message = NULL; /* D-Bus request */
+ DBusMessage *reply = NULL; /* D-Bus reply */
+ DBusMessageIter args; /* D-Bus method arguments */
+ DBusMessageIter dict; /* D-Bus method arguments */
+ DBusError error; /* D-Bus error */
+ const char *device_path; /* Device object path */
+ const char *profile_path; /* Profile path */
+ char *default_profile_path = NULL;
+ /* Default profile path */
+ char device_id[1024]; /* Device ID as understood by colord */
+ char format_str[1024]; /* Qualifier format as a string */
+
+
+ /*
+ * Create the device...
+ */
+
+ snprintf(device_id, sizeof(device_id), "cups-%s", p->name);
+ device_path = device_id;
+
+ message = dbus_message_new_method_call(COLORD_DBUS_SERVICE,
+ COLORD_DBUS_PATH,
+ COLORD_DBUS_INTERFACE,
+ "CreateDevice");
+
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_path);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &scope);
+
+ snprintf(format_str, sizeof(format_str), "%s.%s.%s", format[0], format[1],
+ format[2]);
+
+ dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "{ss}", &dict);
+ colord_dict_add_strings(&dict, "Colorspace", colorspace);
+ colord_dict_add_strings(&dict, "Mode", COLORD_MODE_PHYSICAL);
+ if (ppd->manufacturer)
+ colord_dict_add_strings(&dict, "Vendor", ppd->manufacturer);
+ if (ppd->modelname)
+ colord_dict_add_strings(&dict, "Model", ppd->modelname);
+ if (p->sanitized_device_uri)
+ colord_dict_add_strings(&dict, "Serial", p->sanitized_device_uri);
+ colord_dict_add_strings(&dict, "Format", format_str);
+ colord_dict_add_strings(&dict, "Kind", COLORD_KIND_PRINTER);
+ dbus_message_iter_close_container(&args, &dict);
+
+ /*
+ * Send the CreateDevice request synchronously...
+ */
+
+ dbus_error_init(&error);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling CreateDevice(%s,%s)", device_id,
+ scope);
+ reply = dbus_connection_send_with_reply_and_block(colord_con, message,
+ COLORD_DBUS_TIMEOUT,
+ &error);
+ if (!reply)
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN, "CreateDevice failed: %s:%s", error.name,
+ error.message);
+ dbus_error_free(&error);
+ goto out;
+ }
+
+ /*
+ * Get reply data...
+ */
+
+ dbus_message_iter_init(reply, &args);
+ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "CreateDevice failed: Incorrect reply type.");
+ goto out;
+ }
+
+ dbus_message_iter_get_basic(&args, &device_path);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Created device \"%s\".", device_path);
+
+ /*
+ * Add profiles...
+ */
+
+ for (profile_path = cupsArrayFirst(profiles);
+ profile_path;
+ profile_path = cupsArrayNext(profiles))
+ {
+ colord_device_add_profile(device_path, profile_path, relation);
+ }
+
+out:
+
+ if (default_profile_path)
+ free(default_profile_path);
+
+ if (message)
+ dbus_message_unref(message);
+
+ if (reply)
+ dbus_message_unref(reply);
+}
+
+
+/*
+ * 'colord_create_profile()' - Create a color profile for a printer.
+ */
+
+static void
+colord_create_profile(
+ cups_array_t *profiles, /* I - Profiles array */
+ const char *printer_name, /* I - Printer name */
+ const char *qualifier, /* I - Profile qualifier */
+ const char *colorspace, /* I - Profile colorspace */
+ char **format, /* I - Profile qualifier format */
+ const char *iccfile, /* I - ICC filename */
+ const char *scope) /* I - The scope of the profile, e.g.
+ 'normal', 'temp' or 'disk' */
+{
+ DBusMessage *message = NULL; /* D-Bus request */
+ DBusMessage *reply = NULL; /* D-Bus reply */
+ DBusMessageIter args; /* D-Bus method arguments */
+ DBusMessageIter dict; /* D-Bus method arguments */
+ DBusError error; /* D-Bus error */
+ char *idstr; /* Profile ID string */
+ size_t idstrlen; /* Profile ID allocated length */
+ const char *profile_path; /* Device object path */
+ char format_str[1024]; /* Qualifier format as a string */
+
+
+ /*
+ * Create the profile...
+ */
+
+ message = dbus_message_new_method_call(COLORD_DBUS_SERVICE,
+ COLORD_DBUS_PATH,
+ COLORD_DBUS_INTERFACE,
+ "CreateProfile");
+
+ idstrlen = strlen(printer_name) + 1 + strlen(qualifier) + 1;
+ if ((idstr = malloc(idstrlen)) == NULL)
+ goto out;
+ snprintf(idstr, idstrlen, "%s-%s", printer_name, qualifier);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Using profile ID \"%s\".", idstr);
+
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &idstr);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &scope);
+
+ snprintf(format_str, sizeof(format_str), "%s.%s.%s", format[0], format[1],
+ format[2]);
+
+ dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "{ss}", &dict);
+ colord_dict_add_strings(&dict, "Qualifier", qualifier);
+ colord_dict_add_strings(&dict, "Format", format_str);
+ colord_dict_add_strings(&dict, "Colorspace", colorspace);
+ if (iccfile)
+ colord_dict_add_strings(&dict, "Filename", iccfile);
+ dbus_message_iter_close_container(&args, &dict);
+
+ /*
+ * Send the CreateProfile request synchronously...
+ */
+
+ dbus_error_init(&error);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling CreateProfile(%s,%s)", idstr,
+ scope);
+ reply = dbus_connection_send_with_reply_and_block(colord_con, message,
+ COLORD_DBUS_TIMEOUT,
+ &error);
+ if (!reply)
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN, "CreateProfile failed: %s:%s", error.name,
+ error.message);
+ dbus_error_free(&error);
+ goto out;
+ }
+
+ /*
+ * Get reply data...
+ */
+
+ dbus_message_iter_init(reply, &args);
+ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "CreateProfile failed: Incorrect reply type.");
+ goto out;
+ }
+
+ dbus_message_iter_get_basic(&args, &profile_path);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Created profile \"%s\".", profile_path);
+ cupsArrayAdd(profiles, strdup(profile_path));
+
+out:
+
+ if (message)
+ dbus_message_unref(message);
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ if (idstr)
+ free(idstr);
+}
+
+
+/*
+ * 'colord_delete_device()' - Delete a device
+ */
+
+static void
+colord_delete_device(
+ const char *device_id) /* I - Device ID string */
+{
+ DBusMessage *message = NULL; /* D-Bus request */
+ DBusMessage *reply = NULL; /* D-Bus reply */
+ DBusMessageIter args; /* D-Bus method arguments */
+ DBusError error; /* D-Bus error */
+ char *device_path; /* Device object path */
+
+
+ /*
+ * Find the device...
+ */
+
+ if ((device_path = colord_find_device(device_id)) == NULL)
+ goto out;
+
+ /*
+ * Delete the device...
+ */
+
+ message = dbus_message_new_method_call(COLORD_DBUS_SERVICE,
+ COLORD_DBUS_PATH,
+ COLORD_DBUS_INTERFACE,
+ "DeleteDevice");
+
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_OBJECT_PATH, &device_path);
+
+ /*
+ * Send the DeleteDevice request synchronously...
+ */
+
+ dbus_error_init(&error);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling DeleteDevice(%s)", device_path);
+ reply = dbus_connection_send_with_reply_and_block(colord_con, message,
+ COLORD_DBUS_TIMEOUT,
+ &error);
+ if (!reply)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "DeleteDevice failed: %s:%s", error.name,
+ error.message);
+ dbus_error_free(&error);
+ goto out;
+ }
+
+out:
+
+ if (device_path)
+ free(device_path);
+
+ if (message)
+ dbus_message_unref(message);
+
+ if (reply)
+ dbus_message_unref(reply);
+}
+
+
+/*
+ * 'colord_device_add_profile()' - Assign a profile to a device.
+ */
+
+static void
+colord_device_add_profile(
+ const char *device_path, /* I - Device object path */
+ const char *profile_path, /* I - Profile object path */
+ const char *relation) /* I - Device relation, either
+ 'soft' or 'hard' */
+{
+ DBusMessage *message = NULL; /* D-Bus request */
+ DBusMessage *reply = NULL; /* D-Bus reply */
+ DBusMessageIter args; /* D-Bus method arguments */
+ DBusError error; /* D-Bus error */
+
+
+ message = dbus_message_new_method_call(COLORD_DBUS_SERVICE,
+ device_path,
+ COLORD_DBUS_INTERFACE_DEVICE,
+ "AddProfile");
+
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &relation);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_OBJECT_PATH, &profile_path);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling %s:AddProfile(%s) [%s]",
+ device_path, profile_path, relation);
+
+ /*
+ * Send the AddProfile request synchronously...
+ */
+
+ dbus_error_init(&error);
+ reply = dbus_connection_send_with_reply_and_block(colord_con, message,
+ COLORD_DBUS_TIMEOUT,
+ &error);
+ if (!reply)
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN, "AddProfile failed: %s:%s", error.name,
+ error.message);
+ dbus_error_free(&error);
+ goto out;
+ }
+
+out:
+
+ if (message)
+ dbus_message_unref(message);
+
+ if (reply)
+ dbus_message_unref(reply);
+}
+
+
+/*
+ * 'colord_dict_add_strings()' - Add two strings to a dictionary.
+ */
+
+static void
+colord_dict_add_strings(
+ DBusMessageIter *dict, /* I - Dictionary */
+ const char *key, /* I - Key string */
+ const char *value) /* I - Value string */
+{
+ DBusMessageIter entry; /* Entry to add */
+
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &value);
+ dbus_message_iter_close_container(dict, &entry);
+}
+
+
+/*
+ * 'colord_find_device()' - Finds a device
+ */
+
+static char * /* O - Device path or NULL */
+colord_find_device(
+ const char *device_id) /* I - Device ID string */
+{
+ DBusMessage *message = NULL; /* D-Bus request */
+ DBusMessage *reply = NULL; /* D-Bus reply */
+ DBusMessageIter args; /* D-Bus method arguments */
+ DBusError error; /* D-Bus error */
+ const char *device_path_tmp; /* Device object path */
+ char *device_path = NULL; /* Device object path */
+
+
+ message = dbus_message_new_method_call(COLORD_DBUS_SERVICE,
+ COLORD_DBUS_PATH,
+ COLORD_DBUS_INTERFACE,
+ "FindDeviceById");
+
+ dbus_message_iter_init_append(message, &args);
+ dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_id);
+
+ /*
+ * Send the FindDeviceById request synchronously...
+ */
+
+ dbus_error_init(&error);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling FindDeviceById(%s)", device_id);
+ reply = dbus_connection_send_with_reply_and_block(colord_con, message,
+ COLORD_DBUS_TIMEOUT,
+ &error);
+ if (!reply)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "FindDeviceById failed: %s:%s",
+ error.name, error.message);
+ dbus_error_free(&error);
+ goto out;
+ }
+
+ /*
+ * Get reply data...
+ */
+
+ dbus_message_iter_init(reply, &args);
+ if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "FindDeviceById failed: Incorrect reply type.");
+ goto out;
+ }
+
+ dbus_message_iter_get_basic(&args, &device_path_tmp);
+ if (device_path_tmp)
+ device_path = strdup(device_path_tmp);
+
+out:
+
+ if (message)
+ dbus_message_unref(message);
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ return (device_path);
+}
+
+
+/*
+ * 'colord_get_qualifier_format()' - Get the qualifier format.
+ *
+ * Note: Returns a value of "ColorSpace.MediaType.Resolution" by default.
+ */
+
+static void
+colord_get_qualifier_format(
+ ppd_file_t *ppd, /* I - PPD file data */
+ char *format[3]) /* I - Format tuple */
+{
+ const char *tmp; /* Temporary string */
+ ppd_attr_t *attr; /* Profile attributes */
+
+
+ /*
+ * Get 1st section...
+ */
+
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL)
+ tmp = attr->value;
+ else if (ppdFindAttr(ppd, "DefaultColorModel", NULL))
+ tmp = "ColorModel";
+ else if (ppdFindAttr(ppd, "DefaultColorSpace", NULL))
+ tmp = "ColorSpace";
+ else
+ tmp = "";
+
+ format[0] = strdup(tmp);
+
+ /*
+ * Get 2nd section...
+ */
+
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL)
+ tmp = attr->value;
+ else
+ tmp = "MediaType";
+
+ format[1] = strdup(tmp);
+
+ /*
+ * Get 3rd section...
+ */
+
+ if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL)
+ tmp = attr->value;
+ else
+ tmp = "Resolution";
+
+ format[2] = strdup(tmp);
+}
+
+
+/*
+ * 'colord_register_printer()' - Register profiles for a printer.
+ */
+
+static void
+colord_register_printer(
+ cupsd_printer_t *p) /* I - printer */
+{
+ char ppdfile[1024], /* PPD filename */
+ iccfile[1024]; /* ICC filename */
+ ppd_file_t *ppd; /* PPD file */
+ cups_array_t *profiles; /* Profile paths array */
+ ppd_attr_t *attr; /* Profile attributes */
+ const char *device_colorspace; /* Device colorspace */
+ char *format[3]; /* Qualifier format tuple */
+
+
+ /*
+ * Ensure we have a D-Bus connection...
+ */
+
+ if (!colord_con)
+ return;
+
+ /*
+ * Try opening the PPD file for this printer...
+ */
+
+ snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
+ if ((ppd = _ppdOpenFile(ppdfile, _PPD_LOCALIZATION_ICC_PROFILES)) == NULL)
+ return;
+
+ /*
+ * Find out the qualifier format
+ */
+
+ colord_get_qualifier_format(ppd, format);
+
+ /*
+ * See if we have any embedded profiles...
+ */
+
+ profiles = cupsArrayNew3(NULL, NULL, NULL, 0, (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free);
+ for (attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
+ attr;
+ attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL))
+ if (attr->spec[0] && attr->value && attr->value[0])
+ {
+ if (attr->value[0] != '/')
+ snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir,
+ attr->value);
+ else
+ strlcpy(iccfile, attr->value, sizeof(iccfile));
+
+ if (_cupsFileCheck(iccfile, _CUPS_FILE_CHECK_FILE, !RunUser,
+ cupsdLogFCMessage, p))
+ continue;
+
+ colord_create_profile(profiles, p->name, attr->spec, COLORD_SPACE_UNKNOWN,
+ format, iccfile, COLORD_SCOPE_TEMP);
+ }
+
+ /*
+ * Add the grayscale profile first. We always have a grayscale profile.
+ */
+
+ colord_create_profile(profiles, p->name, "Gray..", COLORD_SPACE_GRAY,
+ format, NULL, COLORD_SCOPE_TEMP);
+
+ /*
+ * Then add the RGB/CMYK/DeviceN color profile...
+ */
+
+ device_colorspace = "unknown";
+ switch (ppd->colorspace)
+ {
+ case PPD_CS_RGB :
+ case PPD_CS_CMY :
+ device_colorspace = COLORD_SPACE_RGB;
+ colord_create_profile(profiles, p->name, "RGB..", COLORD_SPACE_RGB,
+ format, NULL, COLORD_SCOPE_TEMP);
+ break;
+
+ case PPD_CS_RGBK :
+ case PPD_CS_CMYK :
+ device_colorspace = COLORD_SPACE_CMYK;
+ colord_create_profile(profiles, p->name, "CMYK..", COLORD_SPACE_CMYK,
+ format, NULL, COLORD_SCOPE_TEMP);
+ break;
+
+ case PPD_CS_GRAY :
+ device_colorspace = COLORD_SPACE_GRAY;
+ break;
+
+ case PPD_CS_N :
+ colord_create_profile(profiles, p->name, "DeviceN..",
+ COLORD_SPACE_UNKNOWN, format, NULL,
+ COLORD_SCOPE_TEMP);
+ break;
+ }
+
+ /*
+ * Register the device with colord.
+ */
+
+ cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\".",
+ p->name);
+ colord_create_device(p, ppd, profiles, device_colorspace, format,
+ COLORD_RELATION_SOFT, COLORD_SCOPE_TEMP);
+
+ /*
+ * Free any memory we used...
+ */
+
+ cupsArrayDelete(profiles);
+
+ free(format[0]);
+ free(format[1]);
+ free(format[2]);
+
+ ppdClose(ppd);
+}
+
+
+/*
+ * 'colord_unregister_printer()' - Unregister profiles for a printer.
+ */
+
+static void
+colord_unregister_printer(
+ cupsd_printer_t *p) /* I - printer */
+{
+ char device_id[1024]; /* Device ID as understood by colord */
+
+
+ /*
+ * Ensure we have a D-Bus connection...
+ */
+
+ if (!colord_con)
+ return;
+
+ /*
+ * Just delete the device itself, and leave the profiles registered
+ */
+
+ snprintf(device_id, sizeof(device_id), "cups-%s", p->name);
+ colord_delete_device(device_id);
+}
+#endif /* __APPLE__ */
+
+
+/*
+ * End of "$Id: colorman.c 11173 2013-07-23 12:31:34Z msweet $".
+ */
diff --git a/scheduler/colorman.h b/scheduler/colorman.h
new file mode 100644
index 0000000..a95adcf
--- /dev/null
+++ b/scheduler/colorman.h
@@ -0,0 +1,28 @@
+/*
+ * "$Id: colorman.h 11173 2013-07-23 12:31:34Z msweet $"
+ *
+ * Color management definitions for the CUPS scheduler.
+ *
+ * Copyright 2007-2012 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ */
+
+/*
+ * Prototypes...
+ */
+
+extern void cupsdRegisterColor(cupsd_printer_t *p);
+extern void cupsdStartColor(void);
+extern void cupsdStopColor(void);
+extern void cupsdUnregisterColor(cupsd_printer_t *p);
+
+
+/*
+ * End of "$Id: colorman.h 11173 2013-07-23 12:31:34Z msweet $".
+ */
diff --git a/scheduler/conf.c b/scheduler/conf.c
index 3ddcdcd..7ae8fed 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -1,9 +1,9 @@
/*
- * "$Id: conf.c 10121 2011-11-16 15:28:11Z mike $"
+ * "$Id: conf.c 11221 2013-08-06 16:16:01Z msweet $"
*
* Configuration routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2013 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -14,22 +14,25 @@
*
* Contents:
*
- * cupsdAddAlias() - Add a host alias.
+ * cupsdAddAlias() - Add a host alias.
* cupsdCheckPermissions() - Fix the mode and ownership of a file or
- * directory.
+ * directory.
+ * cupsdDefaultAuthType() - Get the default AuthType.
* cupsdFreeAliases() - Free all of the alias entries.
* cupsdReadConfiguration() - Read the cupsd.conf file.
- * get_address() - Get an address + port number from a line.
+ * get_address() - Get an address + port number from a line.
* get_addr_and_mask() - Get an IP address and netmask.
- * mime_error_cb() - Log a MIME error.
- * parse_aaa() - Parse authentication, authorization, and access
- * control lines.
+ * mime_error_cb() - Log a MIME error.
+ * parse_aaa() - Parse authentication, authorization, and access
+ * control lines.
* parse_fatal_errors() - Parse FatalErrors values in a string.
- * parse_groups() - Parse system group names in a string.
- * parse_protocols() - Parse browse protocols in a string.
- * read_configuration() - Read a configuration file.
- * read_location() - Read a <Location path> definition.
- * read_policy() - Read a <Policy name> definition.
+ * parse_groups() - Parse system group names in a string.
+ * parse_protocols() - Parse browse protocols in a string.
+ * parse_variable() - Parse a variable line.
+ * read_cupsd_conf() - Read the cupsd.conf configuration file.
+ * read_cups_files_conf() - Read the cups-files.conf configuration file.
+ * read_location() - Read a <Location path> definition.
+ * read_policy() - Read a <Policy name> definition.
* set_policy_defaults() - Set default policy values as needed.
*/
@@ -64,6 +67,7 @@
typedef enum
{
CUPSD_VARTYPE_INTEGER, /* Integer option */
+ CUPSD_VARTYPE_TIME, /* Time interval option */
CUPSD_VARTYPE_STRING, /* String option */
CUPSD_VARTYPE_BOOLEAN, /* Boolean option */
CUPSD_VARTYPE_PATHNAME /* File/directory name option */
@@ -71,7 +75,7 @@ typedef enum
typedef struct
{
- char *name; /* Name of variable */
+ const char *name; /* Name of variable */
void *ptr; /* Pointer to variable */
cupsd_vartype_t type; /* Type (int, string, address) */
} cupsd_var_t;
@@ -81,92 +85,85 @@ typedef struct
* Local globals...
*/
-static const cupsd_var_t variables[] =
+static const cupsd_var_t cupsd_vars[] =
{
- { "AccessLog", &AccessLog, CUPSD_VARTYPE_STRING },
{ "AutoPurgeJobs", &JobAutoPurge, CUPSD_VARTYPE_BOOLEAN },
-#ifdef HAVE_DNSSD
- { "BrowseDNSSDRegType", &DNSSDRegType, CUPSD_VARTYPE_STRING },
-#endif /* HAVE_DNSSD */
- { "BrowseInterval", &BrowseInterval, CUPSD_VARTYPE_INTEGER },
-#ifdef HAVE_LDAP
- { "BrowseLDAPBindDN", &BrowseLDAPBindDN, CUPSD_VARTYPE_STRING },
-# ifdef HAVE_LDAP_SSL
- { "BrowseLDAPCACertFile", &BrowseLDAPCACertFile, CUPSD_VARTYPE_PATHNAME },
-# endif /* HAVE_LDAP_SSL */
- { "BrowseLDAPDN", &BrowseLDAPDN, CUPSD_VARTYPE_STRING },
- { "BrowseLDAPPassword", &BrowseLDAPPassword, CUPSD_VARTYPE_STRING },
- { "BrowseLDAPServer", &BrowseLDAPServer, CUPSD_VARTYPE_STRING },
-#endif /* HAVE_LDAP */
- { "BrowseLocalOptions", &BrowseLocalOptions, CUPSD_VARTYPE_STRING },
- { "BrowsePort", &BrowsePort, CUPSD_VARTYPE_INTEGER },
- { "BrowseRemoteOptions", &BrowseRemoteOptions, CUPSD_VARTYPE_STRING },
- { "BrowseShortNames", &BrowseShortNames, CUPSD_VARTYPE_BOOLEAN },
- { "BrowseTimeout", &BrowseTimeout, CUPSD_VARTYPE_INTEGER },
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ { "BrowseDNSSDSubTypes", &DNSSDSubTypes, CUPSD_VARTYPE_STRING },
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
{ "BrowseWebIF", &BrowseWebIF, CUPSD_VARTYPE_BOOLEAN },
{ "Browsing", &Browsing, CUPSD_VARTYPE_BOOLEAN },
- { "CacheDir", &CacheDir, CUPSD_VARTYPE_STRING },
{ "Classification", &Classification, CUPSD_VARTYPE_STRING },
{ "ClassifyOverride", &ClassifyOverride, CUPSD_VARTYPE_BOOLEAN },
- { "ConfigFilePerm", &ConfigFilePerm, CUPSD_VARTYPE_INTEGER },
- { "DataDir", &DataDir, CUPSD_VARTYPE_STRING },
{ "DefaultLanguage", &DefaultLanguage, CUPSD_VARTYPE_STRING },
- { "DefaultLeaseDuration", &DefaultLeaseDuration, CUPSD_VARTYPE_INTEGER },
+ { "DefaultLeaseDuration", &DefaultLeaseDuration, CUPSD_VARTYPE_TIME },
{ "DefaultPaperSize", &DefaultPaperSize, CUPSD_VARTYPE_STRING },
{ "DefaultPolicy", &DefaultPolicy, CUPSD_VARTYPE_STRING },
{ "DefaultShared", &DefaultShared, CUPSD_VARTYPE_BOOLEAN },
- { "DirtyCleanInterval", &DirtyCleanInterval, CUPSD_VARTYPE_INTEGER },
- { "DocumentRoot", &DocumentRoot, CUPSD_VARTYPE_STRING },
- { "ErrorLog", &ErrorLog, CUPSD_VARTYPE_STRING },
+ { "DirtyCleanInterval", &DirtyCleanInterval, CUPSD_VARTYPE_TIME },
{ "ErrorPolicy", &ErrorPolicy, CUPSD_VARTYPE_STRING },
- { "FileDevice", &FileDevice, CUPSD_VARTYPE_BOOLEAN },
{ "FilterLimit", &FilterLimit, CUPSD_VARTYPE_INTEGER },
{ "FilterNice", &FilterNice, CUPSD_VARTYPE_INTEGER },
- { "FontPath", &FontPath, CUPSD_VARTYPE_STRING },
- { "HideImplicitMembers", &HideImplicitMembers, CUPSD_VARTYPE_BOOLEAN },
- { "ImplicitClasses", &ImplicitClasses, CUPSD_VARTYPE_BOOLEAN },
- { "ImplicitAnyClasses", &ImplicitAnyClasses, CUPSD_VARTYPE_BOOLEAN },
- { "JobKillDelay", &JobKillDelay, CUPSD_VARTYPE_INTEGER },
+#ifdef HAVE_GSSAPI
+ { "GSSServiceName", &GSSServiceName, CUPSD_VARTYPE_STRING },
+#endif /* HAVE_GSSAPI */
+ { "JobKillDelay", &JobKillDelay, CUPSD_VARTYPE_TIME },
{ "JobRetryLimit", &JobRetryLimit, CUPSD_VARTYPE_INTEGER },
- { "JobRetryInterval", &JobRetryInterval, CUPSD_VARTYPE_INTEGER },
- { "KeepAliveTimeout", &KeepAliveTimeout, CUPSD_VARTYPE_INTEGER },
+ { "JobRetryInterval", &JobRetryInterval, CUPSD_VARTYPE_TIME },
+ { "KeepAliveTimeout", &KeepAliveTimeout, CUPSD_VARTYPE_TIME },
{ "KeepAlive", &KeepAlive, CUPSD_VARTYPE_BOOLEAN },
#ifdef HAVE_LAUNCHD
- { "LaunchdTimeout", &LaunchdTimeout, CUPSD_VARTYPE_INTEGER },
+ { "LaunchdTimeout", &LaunchdTimeout, CUPSD_VARTYPE_TIME },
#endif /* HAVE_LAUNCHD */
{ "LimitRequestBody", &MaxRequestSize, CUPSD_VARTYPE_INTEGER },
{ "ListenBackLog", &ListenBackLog, CUPSD_VARTYPE_INTEGER },
{ "LogDebugHistory", &LogDebugHistory, CUPSD_VARTYPE_INTEGER },
- { "LogFilePerm", &LogFilePerm, CUPSD_VARTYPE_INTEGER },
- { "LPDConfigFile", &LPDConfigFile, CUPSD_VARTYPE_STRING },
{ "MaxActiveJobs", &MaxActiveJobs, CUPSD_VARTYPE_INTEGER },
{ "MaxClients", &MaxClients, CUPSD_VARTYPE_INTEGER },
{ "MaxClientsPerHost", &MaxClientsPerHost, CUPSD_VARTYPE_INTEGER },
{ "MaxCopies", &MaxCopies, CUPSD_VARTYPE_INTEGER },
{ "MaxEvents", &MaxEvents, CUPSD_VARTYPE_INTEGER },
+ { "MaxHoldTime", &MaxHoldTime, CUPSD_VARTYPE_TIME },
{ "MaxJobs", &MaxJobs, CUPSD_VARTYPE_INTEGER },
{ "MaxJobsPerPrinter", &MaxJobsPerPrinter, CUPSD_VARTYPE_INTEGER },
{ "MaxJobsPerUser", &MaxJobsPerUser, CUPSD_VARTYPE_INTEGER },
- { "MaxLeaseDuration", &MaxLeaseDuration, CUPSD_VARTYPE_INTEGER },
+ { "MaxJobTime", &MaxJobTime, CUPSD_VARTYPE_INTEGER },
+ { "MaxLeaseDuration", &MaxLeaseDuration, CUPSD_VARTYPE_TIME },
{ "MaxLogSize", &MaxLogSize, CUPSD_VARTYPE_INTEGER },
{ "MaxRequestSize", &MaxRequestSize, CUPSD_VARTYPE_INTEGER },
{ "MaxSubscriptions", &MaxSubscriptions, CUPSD_VARTYPE_INTEGER },
{ "MaxSubscriptionsPerJob", &MaxSubscriptionsPerJob, CUPSD_VARTYPE_INTEGER },
{ "MaxSubscriptionsPerPrinter",&MaxSubscriptionsPerPrinter, CUPSD_VARTYPE_INTEGER },
{ "MaxSubscriptionsPerUser", &MaxSubscriptionsPerUser, CUPSD_VARTYPE_INTEGER },
- { "MultipleOperationTimeout", &MultipleOperationTimeout, CUPSD_VARTYPE_INTEGER },
- { "PageLog", &PageLog, CUPSD_VARTYPE_STRING },
+ { "MultipleOperationTimeout", &MultipleOperationTimeout, CUPSD_VARTYPE_TIME },
{ "PageLogFormat", &PageLogFormat, CUPSD_VARTYPE_STRING },
- { "PreserveJobFiles", &JobFiles, CUPSD_VARTYPE_BOOLEAN },
- { "PreserveJobHistory", &JobHistory, CUPSD_VARTYPE_BOOLEAN },
+ { "PreserveJobFiles", &JobFiles, CUPSD_VARTYPE_TIME },
+ { "PreserveJobHistory", &JobHistory, CUPSD_VARTYPE_TIME },
+ { "ReloadTimeout", &ReloadTimeout, CUPSD_VARTYPE_TIME },
+ { "RIPCache", &RIPCache, CUPSD_VARTYPE_STRING },
+ { "RootCertDuration", &RootCertDuration, CUPSD_VARTYPE_TIME },
+ { "ServerAdmin", &ServerAdmin, CUPSD_VARTYPE_STRING },
+ { "ServerName", &ServerName, CUPSD_VARTYPE_STRING },
+ { "StrictConformance", &StrictConformance, CUPSD_VARTYPE_BOOLEAN },
+ { "Timeout", &Timeout, CUPSD_VARTYPE_TIME },
+ { "WebInterface", &WebInterface, CUPSD_VARTYPE_BOOLEAN }
+};
+static const cupsd_var_t cupsfiles_vars[] =
+{
+ { "AccessLog", &AccessLog, CUPSD_VARTYPE_STRING },
+ { "CacheDir", &CacheDir, CUPSD_VARTYPE_STRING },
+ { "ConfigFilePerm", &ConfigFilePerm, CUPSD_VARTYPE_INTEGER },
+ { "DataDir", &DataDir, CUPSD_VARTYPE_STRING },
+ { "DocumentRoot", &DocumentRoot, CUPSD_VARTYPE_STRING },
+ { "ErrorLog", &ErrorLog, CUPSD_VARTYPE_STRING },
+ { "FileDevice", &FileDevice, CUPSD_VARTYPE_BOOLEAN },
+ { "FontPath", &FontPath, CUPSD_VARTYPE_STRING },
+ { "LogFilePerm", &LogFilePerm, CUPSD_VARTYPE_INTEGER },
+ { "LPDConfigFile", &LPDConfigFile, CUPSD_VARTYPE_STRING },
+ { "PageLog", &PageLog, CUPSD_VARTYPE_STRING },
{ "Printcap", &Printcap, CUPSD_VARTYPE_STRING },
- { "PrintcapGUI", &PrintcapGUI, CUPSD_VARTYPE_STRING },
- { "ReloadTimeout", &ReloadTimeout, CUPSD_VARTYPE_INTEGER },
{ "RemoteRoot", &RemoteRoot, CUPSD_VARTYPE_STRING },
{ "RequestRoot", &RequestRoot, CUPSD_VARTYPE_STRING },
- { "RIPCache", &RIPCache, CUPSD_VARTYPE_STRING },
- { "RootCertDuration", &RootCertDuration, CUPSD_VARTYPE_INTEGER },
- { "ServerAdmin", &ServerAdmin, CUPSD_VARTYPE_STRING },
{ "ServerBin", &ServerBin, CUPSD_VARTYPE_PATHNAME },
#ifdef HAVE_SSL
{ "ServerCertificate", &ServerCertificate, CUPSD_VARTYPE_PATHNAME },
@@ -174,20 +171,18 @@ static const cupsd_var_t variables[] =
{ "ServerKey", &ServerKey, CUPSD_VARTYPE_PATHNAME },
# endif /* HAVE_LIBSSL || HAVE_GNUTLS */
#endif /* HAVE_SSL */
- { "ServerName", &ServerName, CUPSD_VARTYPE_STRING },
{ "ServerRoot", &ServerRoot, CUPSD_VARTYPE_PATHNAME },
{ "SMBConfigFile", &SMBConfigFile, CUPSD_VARTYPE_STRING },
{ "StateDir", &StateDir, CUPSD_VARTYPE_STRING },
+ { "SyncOnClose", &SyncOnClose, CUPSD_VARTYPE_BOOLEAN },
#ifdef HAVE_AUTHORIZATION_H
{ "SystemGroupAuthKey", &SystemGroupAuthKey, CUPSD_VARTYPE_STRING },
#endif /* HAVE_AUTHORIZATION_H */
- { "TempDir", &TempDir, CUPSD_VARTYPE_PATHNAME },
- { "Timeout", &Timeout, CUPSD_VARTYPE_INTEGER },
- { "UseNetworkDefault", &UseNetworkDefault, CUPSD_VARTYPE_BOOLEAN },
- { "WebInterface", &WebInterface, CUPSD_VARTYPE_BOOLEAN }
+ { "TempDir", &TempDir, CUPSD_VARTYPE_PATHNAME }
};
-#define NUM_VARS (sizeof(variables) / sizeof(variables[0]))
+static int default_auth_type = CUPSD_AUTH_AUTO;
+ /* Default AuthType, if not specified */
static const unsigned ones[4] =
{
@@ -212,7 +207,12 @@ static int parse_aaa(cupsd_location_t *loc, char *line,
static int parse_fatal_errors(const char *s);
static int parse_groups(const char *s);
static int parse_protocols(const char *s);
-static int read_configuration(cups_file_t *fp);
+static int parse_variable(const char *filename, int linenum,
+ const char *line, const char *value,
+ size_t num_vars,
+ const cupsd_var_t *vars);
+static int read_cupsd_conf(cups_file_t *fp);
+static int read_cups_files_conf(cups_file_t *fp);
static int read_location(cups_file_t *fp, char *name, int linenum);
static int read_policy(cups_file_t *fp, char *name, int linenum);
static void set_policy_defaults(cupsd_policy_t *pol);
@@ -394,6 +394,118 @@ cupsdCheckPermissions(
/*
+ * 'cupsdDefaultAuthType()' - Get the default AuthType.
+ *
+ * When the default_auth_type is "auto", this function tries to get the GSS
+ * credentials for the server. If that succeeds we use Kerberos authentication,
+ * otherwise we do a fallback to Basic authentication against the local user
+ * accounts.
+ */
+
+int /* O - Default AuthType value */
+cupsdDefaultAuthType(void)
+{
+#ifdef HAVE_GSSAPI
+ OM_uint32 major_status, /* Major status code */
+ minor_status; /* Minor status code */
+ gss_name_t server_name; /* Server name */
+ gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
+ /* Service name token */
+ char buf[1024]; /* Service name buffer */
+#endif /* HAVE_GSSAPI */
+
+
+ /*
+ * If we have already determined the correct default AuthType, use it...
+ */
+
+ if (default_auth_type != CUPSD_AUTH_AUTO)
+ return (default_auth_type);
+
+#ifdef HAVE_GSSAPI
+# ifdef __APPLE__
+ /*
+ * If the weak-linked GSSAPI/Kerberos library is not present, don't try
+ * to use it...
+ */
+
+ if (gss_init_sec_context == NULL)
+ return (default_auth_type = CUPSD_AUTH_BASIC);
+# endif /* __APPLE__ */
+
+ /*
+ * Try to obtain the server's GSS credentials (GSSServiceName@servername). If
+ * that fails we must use Basic...
+ */
+
+ snprintf(buf, sizeof(buf), "%s@%s", GSSServiceName, ServerName);
+
+ 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_DEBUG, major_status, minor_status,
+ "cupsdDefaultAuthType: gss_import_name(%s) failed", buf);
+ return (default_auth_type = CUPSD_AUTH_BASIC);
+ }
+
+ major_status = gss_display_name(&minor_status, server_name, &token, NULL);
+
+ if (GSS_ERROR(major_status))
+ {
+ cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
+ "cupsdDefaultAuthType: gss_display_name(%s) failed",
+ buf);
+ return (default_auth_type = CUPSD_AUTH_BASIC);
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "cupsdDefaultAuthType: Attempting to acquire Kerberos "
+ "credentials for %s...", (char *)token.value);
+
+ ServerCreds = GSS_C_NO_CREDENTIAL;
+ major_status = gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET, GSS_C_ACCEPT,
+ &ServerCreds, NULL, NULL);
+ if (GSS_ERROR(major_status))
+ {
+ cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
+ "cupsdDefaultAuthType: gss_acquire_cred(%s) failed",
+ (char *)token.value);
+ gss_release_name(&minor_status, &server_name);
+ gss_release_buffer(&minor_status, &token);
+ return (default_auth_type = CUPSD_AUTH_BASIC);
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "cupsdDefaultAuthType: Kerberos credentials acquired "
+ "successfully for %s.", (char *)token.value);
+
+ gss_release_name(&minor_status, &server_name);
+ gss_release_buffer(&minor_status, &token);
+
+ HaveServerCreds = 1;
+
+ return (default_auth_type = CUPSD_AUTH_NEGOTIATE);
+
+#else
+ /*
+ * No Kerberos support compiled in so just use Basic all the time...
+ */
+
+ return (default_auth_type = CUPSD_AUTH_BASIC);
+#endif /* HAVE_GSSAPI */
+}
+
+
+/*
* 'cupsdFreeAliases()' - Free all of the alias entries.
*/
@@ -451,31 +563,6 @@ cupsdReadConfiguration(void)
cupsdDeleteAllLocations();
- if (NumBrowsers > 0)
- {
- free(Browsers);
- Browsers = NULL;
-
- NumBrowsers = 0;
- }
-
- if (NumPolled > 0)
- {
- free(Polled);
-
- NumPolled = 0;
- }
-
- if (NumRelays > 0)
- {
- for (i = 0; i < NumRelays; i ++)
- cupsArrayDelete(Relays[i].from);
-
- free(Relays);
-
- NumRelays = 0;
- }
-
cupsdDeleteAllListeners();
old_remote_port = RemotePort;
@@ -505,7 +592,7 @@ cupsdReadConfiguration(void)
cupsdSetString(&PrintcapGUI, "/usr/bin/glpoptions");
cupsdSetString(&FontPath, CUPS_FONTPATH);
cupsdSetString(&RemoteRoot, "remroot");
- cupsdSetStringf(&ServerHeader, "CUPS/%d.%d", CUPS_VERSION_MAJOR,
+ cupsdSetStringf(&ServerHeader, "CUPS/%d.%d IPP/2.1", CUPS_VERSION_MAJOR,
CUPS_VERSION_MINOR);
cupsdSetString(&StateDir, CUPS_STATEDIR);
@@ -548,6 +635,21 @@ cupsdReadConfiguration(void)
cupsdSetString(&TempDir, NULL);
+#ifdef HAVE_GSSAPI
+ cupsdSetString(&GSSServiceName, CUPS_DEFAULT_GSSSERVICENAME);
+
+ if (HaveServerCreds)
+ {
+ OM_uint32 minor_status; /* Minor status code */
+
+ gss_release_cred(&minor_status, &ServerCreds);
+
+ HaveServerCreds = 0;
+ }
+
+ ServerCreds = GSS_C_NO_CREDENTIAL;
+#endif /* HAVE_GSSAPI */
+
/*
* Find the default user...
*/
@@ -604,7 +706,7 @@ cupsdReadConfiguration(void)
AccessLogLevel = CUPSD_ACCESSLOG_ACTIONS;
ConfigFilePerm = CUPS_DEFAULT_CONFIG_FILE_PERM;
FatalErrors = parse_fatal_errors(CUPS_DEFAULT_FATAL_ERRORS);
- DefaultAuthType = CUPSD_AUTH_BASIC;
+ default_auth_type = CUPSD_AUTH_BASIC;
#ifdef HAVE_SSL
DefaultEncryption = HTTP_ENCRYPT_REQUIRED;
SSLOptions = CUPSD_SSL_NONE;
@@ -618,9 +720,6 @@ cupsdReadConfiguration(void)
FilterLimit = 0;
FilterNice = 0;
HostNameLookups = FALSE;
- ImplicitClasses = CUPS_DEFAULT_IMPLICIT_CLASSES;
- ImplicitAnyClasses = FALSE;
- HideImplicitMembers = TRUE;
KeepAlive = TRUE;
KeepAliveTimeout = DEFAULT_KEEPALIVE;
ListenBackLog = SOMAXCONN;
@@ -633,58 +732,44 @@ cupsdReadConfiguration(void)
MaxLogSize = 1024 * 1024;
MaxRequestSize = 0;
MultipleOperationTimeout = DEFAULT_TIMEOUT;
+ NumSystemGroups = 0;
ReloadTimeout = DEFAULT_KEEPALIVE;
RootCertDuration = 300;
+ StrictConformance = FALSE;
+ SyncOnClose = FALSE;
Timeout = DEFAULT_TIMEOUT;
- NumSystemGroups = 0;
WebInterface = CUPS_DEFAULT_WEBIF;
- BrowseInterval = DEFAULT_INTERVAL;
- BrowsePort = ippPort();
BrowseLocalProtocols = parse_protocols(CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS);
- BrowseRemoteProtocols = parse_protocols(CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS);
- BrowseShortNames = CUPS_DEFAULT_BROWSE_SHORT_NAMES;
- BrowseTimeout = DEFAULT_TIMEOUT;
BrowseWebIF = FALSE;
Browsing = CUPS_DEFAULT_BROWSING;
DefaultShared = CUPS_DEFAULT_DEFAULT_SHARED;
-#ifdef HAVE_DNSSD
- cupsdSetString(&DNSSDRegType, "_ipp._tcp,_cups");
-#endif /* HAVE_DNSSD */
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ cupsdSetString(&DNSSDSubTypes, "_cups,_print");
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
cupsdSetString(&LPDConfigFile, CUPS_DEFAULT_LPD_CONFIG_FILE);
cupsdSetString(&SMBConfigFile, CUPS_DEFAULT_SMB_CONFIG_FILE);
- cupsdClearString(&BrowseLocalOptions);
- cupsdClearString(&BrowseRemoteOptions);
-
cupsdSetString(&ErrorPolicy, "stop-printer");
-#ifdef HAVE_LDAP
- cupsdClearString(&BrowseLDAPBindDN);
- cupsdClearString(&BrowseLDAPDN);
- cupsdClearString(&BrowseLDAPPassword);
- cupsdClearString(&BrowseLDAPServer);
-# ifdef HAVE_LDAP_SSL
- cupsdClearString(&BrowseLDAPCACertFile);
-# endif /* HAVE_LDAP_SSL */
-#endif /* HAVE_LDAP */
-
JobHistory = DEFAULT_HISTORY;
JobFiles = DEFAULT_FILES;
JobAutoPurge = 0;
+ MaxHoldTime = 0;
MaxJobs = 500;
MaxActiveJobs = 0;
MaxJobsPerUser = 0;
MaxJobsPerPrinter = 0;
+ MaxJobTime = 3 * 60 * 60; /* 3 hours */
MaxCopies = CUPS_DEFAULT_MAX_COPIES;
cupsdDeleteAllPolicies();
cupsdClearString(&DefaultPolicy);
#ifdef HAVE_AUTHORIZATION_H
- cupsdClearString(&SystemGroupAuthKey);
+ cupsdSetString(&SystemGroupAuthKey, CUPS_DEFAULT_SYSTEM_AUTHKEY);
#endif /* HAVE_AUTHORIZATION_H */
MaxSubscriptions = 100;
@@ -695,7 +780,7 @@ cupsdReadConfiguration(void)
MaxLeaseDuration = 0;
#ifdef HAVE_LAUNCHD
- LaunchdTimeout = DEFAULT_TIMEOUT + 10;
+ LaunchdTimeout = 10;
#endif /* HAVE_LAUNCHD */
/*
@@ -705,21 +790,63 @@ cupsdReadConfiguration(void)
cupsdInitEnv();
/*
- * Read the configuration file...
+ * Read the cups-files.conf file...
+ */
+
+ if ((fp = cupsFileOpen(CupsFilesFile, "r")) != NULL)
+ {
+ status = read_cups_files_conf(fp);
+
+ cupsFileClose(fp);
+
+ if (!status)
+ {
+ if (TestConfigFile)
+ printf("\"%s\" contains errors.\n", CupsFilesFile);
+ else
+ syslog(LOG_LPR, "Unable to read \"%s\" due to errors.",
+ CupsFilesFile);
+
+ return (0);
+ }
+ }
+ else if (errno == ENOENT)
+ cupsdLogMessage(CUPSD_LOG_INFO, "No %s, using defaults.", CupsFilesFile);
+ else
+ {
+ syslog(LOG_LPR, "Unable to open \"%s\": %s", CupsFilesFile,
+ strerror(errno));
+ return (0);
+ }
+
+ if (!ErrorLog)
+ cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log");
+
+ /*
+ * Read the cupsd.conf file...
*/
if ((fp = cupsFileOpen(ConfigurationFile, "r")) == NULL)
+ {
+ syslog(LOG_LPR, "Unable to open \"%s\": %s", ConfigurationFile,
+ strerror(errno));
return (0);
+ }
- status = read_configuration(fp);
+ status = read_cupsd_conf(fp);
cupsFileClose(fp);
if (!status)
- return (0);
+ {
+ if (TestConfigFile)
+ printf("\"%s\" contains errors.\n", ConfigurationFile);
+ else
+ syslog(LOG_LPR, "Unable to read \"%s\" due to errors.",
+ ConfigurationFile);
- if (!ErrorLog)
- cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log");
+ return (0);
+ }
RunUser = getuid();
@@ -833,10 +960,11 @@ cupsdReadConfiguration(void)
}
/*
- * Get the access control list for browsing...
+ * Make sure ConfigFilePerm and LogFilePerm have sane values...
*/
- BrowseACL = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL");
+ ConfigFilePerm &= 0664;
+ LogFilePerm &= 0664;
/*
* Open the system log for cupsd if necessary...
@@ -999,7 +1127,9 @@ cupsdReadConfiguration(void)
Group, 1, 1) < 0 ||
cupsdCheckPermissions(ServerRoot, "ssl", 0700, RunUser,
Group, 1, 0) < 0 ||
- cupsdCheckPermissions(ServerRoot, "cupsd.conf", ConfigFilePerm, RunUser,
+ cupsdCheckPermissions(ConfigurationFile, NULL, ConfigFilePerm, RunUser,
+ Group, 0, 0) < 0 ||
+ cupsdCheckPermissions(CupsFilesFile, NULL, ConfigFilePerm, RunUser,
Group, 0, 0) < 0 ||
cupsdCheckPermissions(ServerRoot, "classes.conf", 0600, RunUser,
Group, 0, 0) < 0 ||
@@ -1014,11 +1144,20 @@ cupsdReadConfiguration(void)
* Update TempDir to the default if it hasn't been set already...
*/
+#ifdef __APPLE__
+ if (TempDir && !RunUser &&
+ (!strncmp(TempDir, "/private/tmp", 12) || !strncmp(TempDir, "/tmp", 4)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot use %s for TempDir.", TempDir);
+ cupsdClearString(&TempDir);
+ }
+#endif /* __APPLE__ */
+
if (!TempDir)
{
#ifdef __APPLE__
if ((tmpdir = getenv("TMPDIR")) != NULL &&
- strncmp(tmpdir, "/private/tmp", 12))
+ strncmp(tmpdir, "/private/tmp", 12) && strncmp(tmpdir, "/tmp", 4))
#else
if ((tmpdir = getenv("TMPDIR")) != NULL)
#endif /* __APPLE__ */
@@ -1041,13 +1180,13 @@ cupsdReadConfiguration(void)
else
cupsdSetString(&TempDir, tmpdir);
}
+ }
- if (!TempDir)
- {
- cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...",
- RequestRoot);
- cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot);
- }
+ if (!TempDir)
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...",
+ RequestRoot);
+ cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot);
}
/*
@@ -1156,24 +1295,6 @@ cupsdReadConfiguration(void)
MaxClientsPerHost);
/*
- * Make sure that BrowseTimeout is at least twice the interval...
- */
-
- if (BrowseTimeout < (2 * BrowseInterval) || BrowseTimeout <= 0)
- {
- cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid BrowseTimeout value %d.",
- BrowseTimeout);
-
- if (BrowseInterval)
- BrowseTimeout = BrowseInterval * 2;
- else
- BrowseTimeout = DEFAULT_TIMEOUT;
-
- cupsdLogMessage(CUPSD_LOG_ALERT, "Reset BrowseTimeout to %d.",
- BrowseTimeout);
- }
-
- /*
* Update the default policy, as needed...
*/
@@ -1477,7 +1598,6 @@ cupsdReadConfiguration(void)
cupsdLoadAllPrinters();
cupsdLoadAllClasses();
- cupsdLoadRemoteCache();
cupsdCreateCommonData();
@@ -1511,6 +1631,12 @@ cupsdReadConfiguration(void)
cupsdCreateCommonData();
/*
+ * Update all jobs as needed...
+ */
+
+ cupsdUpdateJobs();
+
+ /*
* Update all printers as needed...
*/
@@ -2474,20 +2600,10 @@ parse_protocols(const char *s) /* I - Space-delimited protocols */
* Add the protocol to the bitmask...
*/
- if (!_cups_strcasecmp(valstart, "cups"))
- protocols |= BROWSE_CUPS;
- else if (!_cups_strcasecmp(valstart, "slp"))
- protocols |= BROWSE_SLP;
- else if (!_cups_strcasecmp(valstart, "ldap"))
- protocols |= BROWSE_LDAP;
- else if (!_cups_strcasecmp(valstart, "dnssd") ||
- !_cups_strcasecmp(valstart, "dns-sd") ||
- !_cups_strcasecmp(valstart, "bonjour"))
+ if (!_cups_strcasecmp(valstart, "dnssd") ||
+ !_cups_strcasecmp(valstart, "dns-sd") ||
+ !_cups_strcasecmp(valstart, "bonjour"))
protocols |= BROWSE_DNSSD;
- else if (!_cups_strcasecmp(valstart, "lpd"))
- protocols |= BROWSE_LPD;
- else if (!_cups_strcasecmp(valstart, "smb"))
- protocols |= BROWSE_SMB;
else if (!_cups_strcasecmp(valstart, "all"))
protocols |= BROWSE_ALL;
else if (_cups_strcasecmp(valstart, "none"))
@@ -2504,33 +2620,256 @@ parse_protocols(const char *s) /* I - Space-delimited protocols */
/*
- * 'read_configuration()' - Read a configuration file.
+ * 'parse_variable()' - Parse a variable line.
*/
static int /* O - 1 on success, 0 on failure */
-read_configuration(cups_file_t *fp) /* I - File to read from */
+parse_variable(
+ const char *filename, /* I - Name of configuration file */
+ int linenum, /* I - Line in configuration file */
+ const char *line, /* I - Line from configuration file */
+ const char *value, /* I - Value from configuration file */
+ size_t num_vars, /* I - Number of variables */
+ const cupsd_var_t *vars) /* I - Variables */
+{
+ size_t i; /* Looping var */
+ const cupsd_var_t *var; /* Variables */
+ char temp[1024]; /* Temporary string */
+
+
+ for (i = num_vars, var = vars; i > 0; i --, var ++)
+ if (!_cups_strcasecmp(line, var->name))
+ break;
+
+ if (i == 0)
+ {
+ /*
+ * Unknown directive! Output an error message and continue...
+ */
+
+ if (!value)
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d of %s.",
+ line, linenum, filename);
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d of %s.",
+ line, linenum, filename);
+
+ return (0);
+ }
+
+ switch (var->type)
+ {
+ case CUPSD_VARTYPE_INTEGER :
+ if (!value)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Missing integer value for %s on line %d of %s.",
+ line, linenum, filename);
+ return (0);
+ }
+ else if (!isdigit(*value & 255))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Bad integer value for %s on line %d of %s.",
+ line, linenum, filename);
+ return (0);
+ }
+ else
+ {
+ int n; /* Number */
+ char *units; /* Units */
+
+ n = strtol(value, &units, 0);
+
+ if (units && *units)
+ {
+ if (tolower(units[0] & 255) == 'g')
+ n *= 1024 * 1024 * 1024;
+ else if (tolower(units[0] & 255) == 'm')
+ n *= 1024 * 1024;
+ else if (tolower(units[0] & 255) == 'k')
+ n *= 1024;
+ else if (tolower(units[0] & 255) == 't')
+ n *= 262144;
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unknown integer value for %s on line %d of %s.",
+ line, linenum, filename);
+ return (0);
+ }
+ }
+
+ if (n < 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Bad negative integer value for %s on line %d of "
+ "%s.", line, linenum, filename);
+ return (0);
+ }
+ else
+ {
+ *((int *)var->ptr) = n;
+ }
+ }
+ break;
+
+ case CUPSD_VARTYPE_TIME :
+ if (!value)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Missing time interval value for %s on line %d of "
+ "%s.", line, linenum, filename);
+ return (0);
+ }
+ else if (!_cups_strncasecmp(line, "PreserveJob", 11) &&
+ (!_cups_strcasecmp(value, "true") ||
+ !_cups_strcasecmp(value, "on") ||
+ !_cups_strcasecmp(value, "enabled") ||
+ !_cups_strcasecmp(value, "yes")))
+ {
+ *((int *)var->ptr) = INT_MAX;
+ }
+ else if (!_cups_strcasecmp(value, "false") ||
+ !_cups_strcasecmp(value, "off") ||
+ !_cups_strcasecmp(value, "disabled") ||
+ !_cups_strcasecmp(value, "no"))
+ {
+ *((int *)var->ptr) = 0;
+ }
+ else if (!isdigit(*value & 255))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unknown time interval value for %s on line %d of "
+ "%s.", line, linenum, filename);
+ return (0);
+ }
+ else
+ {
+ double n; /* Number */
+ char *units; /* Units */
+
+ n = strtod(value, &units);
+
+ if (units && *units)
+ {
+ if (tolower(units[0] & 255) == 'w')
+ n *= 7 * 24 * 60 * 60;
+ else if (tolower(units[0] & 255) == 'd')
+ n *= 24 * 60 * 60;
+ else if (tolower(units[0] & 255) == 'h')
+ n *= 60 * 60;
+ else if (tolower(units[0] & 255) == 'm')
+ n *= 60;
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unknown time interval value for %s on line "
+ "%d of %s.", line, linenum, filename);
+ return (0);
+ }
+ }
+
+ if (n < 0.0 || n > INT_MAX)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Bad time value for %s on line %d of %s.",
+ line, linenum, filename);
+ return (0);
+ }
+ else
+ {
+ *((int *)var->ptr) = (int)n;
+ }
+ }
+ break;
+
+ case CUPSD_VARTYPE_BOOLEAN :
+ if (!value)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Missing boolean value for %s on line %d of %s.",
+ line, linenum, filename);
+ return (0);
+ }
+ else if (!_cups_strcasecmp(value, "true") ||
+ !_cups_strcasecmp(value, "on") ||
+ !_cups_strcasecmp(value, "enabled") ||
+ !_cups_strcasecmp(value, "yes") ||
+ atoi(value) != 0)
+ {
+ *((int *)var->ptr) = TRUE;
+ }
+ else if (!_cups_strcasecmp(value, "false") ||
+ !_cups_strcasecmp(value, "off") ||
+ !_cups_strcasecmp(value, "disabled") ||
+ !_cups_strcasecmp(value, "no") ||
+ !_cups_strcasecmp(value, "0"))
+ {
+ *((int *)var->ptr) = FALSE;
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unknown boolean value %s on line %d of %s.",
+ value, linenum, filename);
+ return (0);
+ }
+ break;
+
+ case CUPSD_VARTYPE_PATHNAME :
+ if (!value)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Missing pathname value for %s on line %d of %s.",
+ line, linenum, filename);
+ return (0);
+ }
+
+ if (value[0] == '/')
+ strlcpy(temp, value, sizeof(temp));
+ else
+ snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);
+
+ if (access(temp, 0))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "File or directory for \"%s %s\" on line %d of %s "
+ "does not exist.", line, value, linenum, filename);
+ return (0);
+ }
+
+ cupsdSetString((char **)var->ptr, temp);
+ break;
+
+ case CUPSD_VARTYPE_STRING :
+ cupsdSetString((char **)var->ptr, value);
+ break;
+ }
+
+ return (1);
+}
+
+
+/*
+ * 'read_cupsd_conf()' - Read the cupsd.conf configuration file.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
{
- int i; /* Looping var */
int linenum; /* Current line number */
char line[HTTP_MAX_BUFFER],
/* Line from file */
temp[HTTP_MAX_BUFFER],
/* Temporary buffer for value */
- *ptr, /* Pointer into line/temp */
*value, /* Pointer to value */
*valueptr; /* Pointer into value */
int valuelen; /* Length of value */
- cupsd_var_t const *var; /* Current variable */
http_addrlist_t *addrlist, /* Address list */
*addr; /* Current address */
- unsigned ip[4], /* Address value */
- mask[4]; /* Netmask value */
- cupsd_dirsvc_relay_t *relay; /* Relay data */
- cupsd_dirsvc_poll_t *pollp; /* Polling data */
- cupsd_location_t *location; /* Browse location */
cups_file_t *incfile; /* Include file */
char incname[1024]; /* Include filename */
- struct group *group; /* Group */
/*
@@ -2562,7 +2901,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
incname, strerror(errno));
else
{
- read_configuration(incfile);
+ read_cupsd_conf(incfile);
cupsFileClose(incfile);
}
}
@@ -2586,8 +2925,6 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
if (linenum == 0)
return (0);
}
- else if (!_cups_strcasecmp(line, "FatalErrors"))
- FatalErrors = parse_fatal_errors(value);
else if (!_cups_strcasecmp(line, "FaxRetryInterval") && value)
{
JobRetryInterval = atoi(value);
@@ -2711,117 +3048,12 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
httpAddrFreeList(addrlist);
}
- else if (!_cups_strcasecmp(line, "BrowseAddress") && value)
- {
- /*
- * Add a browse address to the list...
- */
-
- cupsd_dirsvc_addr_t *dira; /* New browse address array */
-
-
- if (NumBrowsers == 0)
- dira = malloc(sizeof(cupsd_dirsvc_addr_t));
- else
- dira = realloc(Browsers, (NumBrowsers + 1) * sizeof(cupsd_dirsvc_addr_t));
-
- if (!dira)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate BrowseAddress at line %d - %s.",
- linenum, strerror(errno));
- continue;
- }
-
- Browsers = dira;
- dira += NumBrowsers;
-
- memset(dira, 0, sizeof(cupsd_dirsvc_addr_t));
-
- if (!_cups_strcasecmp(value, "@LOCAL"))
- {
- /*
- * Send browse data to all local interfaces...
- */
-
- strcpy(dira->iface, "*");
- NumBrowsers ++;
- }
- else if (!_cups_strncasecmp(value, "@IF(", 4))
- {
- /*
- * Send browse data to the named interface...
- */
-
- strlcpy(dira->iface, value + 4, sizeof(Browsers[0].iface));
-
- ptr = dira->iface + strlen(dira->iface) - 1;
- if (*ptr == ')')
- *ptr = '\0';
-
- NumBrowsers ++;
- }
- else if ((addrlist = get_address(value, BrowsePort)) != NULL)
- {
- /*
- * Only IPv4 addresses are supported...
- */
-
- for (addr = addrlist; addr; addr = addr->next)
- if (_httpAddrFamily(&(addr->addr)) == AF_INET)
- break;
-
- if (addr)
- {
- memcpy(&(dira->to), &(addrlist->addr), sizeof(dira->to));
- httpAddrString(&(dira->to), temp, sizeof(temp));
-
- cupsdLogMessage(CUPSD_LOG_INFO,
- "Sending browsing info to %s:%d (IPv4)",
- temp, _httpAddrPort(&(dira->to)));
-
- NumBrowsers ++;
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad BrowseAddress %s at line %d.",
- value, linenum);
-
- httpAddrFreeList(addrlist);
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad BrowseAddress %s at line %d.",
- value, linenum);
- }
- else if (!_cups_strcasecmp(line, "BrowseOrder") && value)
- {
- /*
- * "BrowseOrder Deny,Allow" or "BrowseOrder Allow,Deny"...
- */
-
- if ((location = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL")) == NULL)
- if ((location = cupsdNewLocation("CUPS_INTERNAL_BROWSE_ACL")) != NULL)
- cupsdAddLocation(location);
-
- if (location == NULL)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to initialize browse access control list.");
- else if (!_cups_strncasecmp(value, "deny", 4))
- location->order_type = CUPSD_AUTH_ALLOW;
- else if (!_cups_strncasecmp(value, "allow", 5))
- location->order_type = CUPSD_AUTH_DENY;
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown BrowseOrder value %s on line %d.",
- value, linenum);
- }
else if (!_cups_strcasecmp(line, "BrowseProtocols") ||
- !_cups_strcasecmp(line, "BrowseLocalProtocols") ||
- !_cups_strcasecmp(line, "BrowseRemoteProtocols"))
+ !_cups_strcasecmp(line, "BrowseLocalProtocols"))
{
/*
* "BrowseProtocols name [... name]"
* "BrowseLocalProtocols name [... name]"
- * "BrowseRemoteProtocols name [... name]"
*/
int protocols = parse_protocols(value);
@@ -2834,367 +3066,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
break;
}
- if (_cups_strcasecmp(line, "BrowseLocalProtocols"))
- BrowseRemoteProtocols = protocols;
- if (_cups_strcasecmp(line, "BrowseRemoteProtocols"))
- BrowseLocalProtocols = protocols;
- }
- else if ((!_cups_strcasecmp(line, "BrowseAllow") ||
- !_cups_strcasecmp(line, "BrowseDeny")) && value)
- {
- /*
- * BrowseAllow [From] host/ip...
- * BrowseDeny [From] host/ip...
- */
-
- if ((location = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL")) == NULL)
- if ((location = cupsdNewLocation("CUPS_INTERNAL_BROWSE_ACL")) != NULL)
- cupsdAddLocation(location);
-
-
- if (location == NULL)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to initialize browse access control list.");
- else
- {
- if (!_cups_strncasecmp(value, "from", 4))
- {
- /*
- * Skip leading "from"...
- */
-
- value += 4;
- }
-
- while (*value)
- {
- /*
- * Skip leading whitespace...
- */
-
- while (_cups_isspace(*value))
- value ++;
-
- if (!*value)
- break;
-
- /*
- * Find the end of the value...
- */
-
- for (valueptr = value;
- *valueptr && !_cups_isspace(*valueptr);
- valueptr ++);
-
- while (_cups_isspace(*valueptr))
- *valueptr++ = '\0';
-
- /*
- * Figure out what form the allow/deny address takes:
- *
- * All
- * None
- * *.domain.com
- * .domain.com
- * host.domain.com
- * nnn.*
- * nnn.nnn.*
- * nnn.nnn.nnn.*
- * nnn.nnn.nnn.nnn
- * nnn.nnn.nnn.nnn/mm
- * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
- */
-
- if (!_cups_strcasecmp(value, "all"))
- {
- /*
- * All hosts...
- */
-
- if (!_cups_strcasecmp(line, "BrowseAllow"))
- cupsdAddIPMask(&(location->allow), zeros, zeros);
- else
- cupsdAddIPMask(&(location->deny), zeros, zeros);
- }
- else if (!_cups_strcasecmp(value, "none"))
- {
- /*
- * No hosts...
- */
-
- if (!_cups_strcasecmp(line, "BrowseAllow"))
- cupsdAddIPMask(&(location->allow), ones, zeros);
- else
- cupsdAddIPMask(&(location->deny), ones, zeros);
- }
-#ifdef AF_INET6
- else if (value[0] == '*' || value[0] == '.' ||
- (!isdigit(value[0] & 255) && value[0] != '['))
-#else
- else if (value[0] == '*' || value[0] == '.' ||
- !isdigit(value[0] & 255))
-#endif /* AF_INET6 */
- {
- /*
- * Host or domain name...
- */
-
- if (!_cups_strcasecmp(line, "BrowseAllow"))
- cupsdAddNameMask(&(location->allow), value);
- else
- cupsdAddNameMask(&(location->deny), value);
- }
- else
- {
- /*
- * One of many IP address forms...
- */
-
- if (!get_addr_and_mask(value, ip, mask))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
- value, linenum);
- break;
- }
-
- if (!_cups_strcasecmp(line, "BrowseAllow"))
- cupsdAddIPMask(&(location->allow), ip, mask);
- else
- cupsdAddIPMask(&(location->deny), ip, mask);
- }
-
- /*
- * Advance to next value...
- */
-
- value = valueptr;
- }
- }
- }
- else if (!_cups_strcasecmp(line, "BrowseRelay") && value)
- {
- /*
- * BrowseRelay [from] source [to] destination
- */
-
- if (NumRelays == 0)
- relay = malloc(sizeof(cupsd_dirsvc_relay_t));
- else
- relay = realloc(Relays, (NumRelays + 1) * sizeof(cupsd_dirsvc_relay_t));
-
- if (!relay)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate BrowseRelay at line %d - %s.",
- linenum, strerror(errno));
- continue;
- }
-
- Relays = relay;
- relay += NumRelays;
-
- memset(relay, 0, sizeof(cupsd_dirsvc_relay_t));
-
- if (!_cups_strncasecmp(value, "from ", 5))
- {
- /*
- * Skip leading "from"...
- */
-
- value += 5;
-
- /*
- * Skip leading whitespace...
- */
-
- while (_cups_isspace(*value))
- value ++;
- }
-
- /*
- * Find the end of the from value...
- */
-
- for (valueptr = value;
- *valueptr && !_cups_isspace(*valueptr);
- valueptr ++);
-
- while (_cups_isspace(*valueptr))
- *valueptr++ = '\0';
-
- /*
- * Figure out what form the from address takes:
- *
- * *.domain.com
- * .domain.com
- * host.domain.com
- * nnn.*
- * nnn.nnn.*
- * nnn.nnn.nnn.*
- * nnn.nnn.nnn.nnn
- * nnn.nnn.nnn.nnn/mm
- * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
- */
-
-#ifdef AF_INET6
- if (value[0] == '*' || value[0] == '.' ||
- (!isdigit(value[0] & 255) && value[0] != '['))
-#else
- if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255))
-#endif /* AF_INET6 */
- {
- /*
- * Host or domain name...
- */
-
- if (!cupsdAddNameMask(&(relay->from), value))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate BrowseRelay name at line %d - %s.",
- linenum, strerror(errno));
- continue;
- }
- }
- else
- {
- /*
- * One of many IP address forms...
- */
-
- if (!get_addr_and_mask(value, ip, mask))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
- value, linenum);
- break;
- }
-
- if (!cupsdAddIPMask(&(relay->from), ip, mask))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate BrowseRelay IP at line %d - %s.",
- linenum, strerror(errno));
- continue;
- }
- }
-
- /*
- * Get "to" address and port...
- */
-
- if (!_cups_strncasecmp(valueptr, "to ", 3))
- {
- /*
- * Strip leading "to"...
- */
-
- valueptr += 3;
-
- while (_cups_isspace(*valueptr))
- valueptr ++;
- }
-
- if ((addrlist = get_address(valueptr, BrowsePort)) != NULL)
- {
- /*
- * Only IPv4 addresses are supported...
- */
-
- for (addr = addrlist; addr; addr = addr->next)
- if (addr->addr.addr.sa_family == AF_INET)
- break;
-
- if (addr)
- {
- memcpy(&(relay->to), &(addrlist->addr), sizeof(relay->to));
-
- httpAddrString(&(relay->to), temp, sizeof(temp));
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Relaying from %s to %s:%d (IPv4)",
- value, temp, _httpAddrPort(&(relay->to)));
-
- NumRelays ++;
- }
- else
- {
- cupsArrayDelete(relay->from);
- relay->from = NULL;
-
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad relay address %s at line %d.",
- valueptr, linenum);
- }
-
- httpAddrFreeList(addrlist);
- }
- else
- {
- cupsArrayDelete(relay->from);
- relay->from = NULL;
-
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad relay address %s at line %d.",
- valueptr, linenum);
- }
- }
- else if (!_cups_strcasecmp(line, "BrowsePoll") && value)
- {
- /*
- * BrowsePoll address[:port]
- */
-
- char *portname; /* Port name */
- int portnum; /* Port number */
- struct servent *service; /* Service */
-
-
- /*
- * Extract the port name from the address...
- */
-
- if ((portname = strrchr(value, ':')) != NULL && !strchr(portname, ']'))
- {
- *portname++ = '\0';
-
- if (isdigit(*portname & 255))
- portnum = atoi(portname);
- else if ((service = getservbyname(portname, NULL)) != NULL)
- portnum = ntohs(service->s_port);
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Lookup of service \"%s\" failed.",
- portname);
- continue;
- }
- }
- else
- portnum = ippPort();
-
- /*
- * Add the poll entry...
- */
-
- if (NumPolled == 0)
- pollp = malloc(sizeof(cupsd_dirsvc_poll_t));
- else
- pollp = realloc(Polled, (NumPolled + 1) * sizeof(cupsd_dirsvc_poll_t));
-
- if (!pollp)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate BrowsePoll at line %d - %s.",
- linenum, strerror(errno));
- continue;
- }
-
- Polled = pollp;
- pollp += NumPolled;
-
- NumPolled ++;
- memset(pollp, 0, sizeof(cupsd_dirsvc_poll_t));
-
- strlcpy(pollp->hostname, value, sizeof(pollp->hostname));
- pollp->port = portnum;
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Polling %s:%d", pollp->hostname,
- pollp->port);
+ BrowseLocalProtocols = protocols;
}
else if (!_cups_strcasecmp(line, "DefaultAuthType") && value)
{
@@ -3203,17 +3075,19 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
*/
if (!_cups_strcasecmp(value, "none"))
- DefaultAuthType = CUPSD_AUTH_NONE;
+ default_auth_type = CUPSD_AUTH_NONE;
else if (!_cups_strcasecmp(value, "basic"))
- DefaultAuthType = CUPSD_AUTH_BASIC;
+ default_auth_type = CUPSD_AUTH_BASIC;
else if (!_cups_strcasecmp(value, "digest"))
- DefaultAuthType = CUPSD_AUTH_DIGEST;
+ default_auth_type = CUPSD_AUTH_DIGEST;
else if (!_cups_strcasecmp(value, "basicdigest"))
- DefaultAuthType = CUPSD_AUTH_BASICDIGEST;
+ default_auth_type = CUPSD_AUTH_BASICDIGEST;
#ifdef HAVE_GSSAPI
else if (!_cups_strcasecmp(value, "negotiate"))
- DefaultAuthType = CUPSD_AUTH_NEGOTIATE;
+ default_auth_type = CUPSD_AUTH_NEGOTIATE;
#endif /* HAVE_GSSAPI */
+ else if (!_cups_strcasecmp(value, "auto"))
+ default_auth_type = CUPSD_AUTH_AUTO;
else
{
cupsdLogMessage(CUPSD_LOG_WARN,
@@ -3246,81 +3120,6 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
}
}
#endif /* HAVE_SSL */
- else if (!_cups_strcasecmp(line, "User") && value)
- {
- /*
- * User ID to run as...
- */
-
- if (isdigit(value[0] & 255))
- {
- int uid = atoi(value);
-
- if (!uid)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Will not use User 0 as specified on line %d "
- "for security reasons. You must use a non-"
- "privileged account instead.",
- linenum);
- else
- User = atoi(value);
- }
- else
- {
- struct passwd *p; /* Password information */
-
- endpwent();
- p = getpwnam(value);
-
- if (p)
- {
- if (!p->pw_uid)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Will not use User %s (UID=0) as specified on line "
- "%d for security reasons. You must use a non-"
- "privileged account instead.",
- value, linenum);
- else
- User = p->pw_uid;
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown User \"%s\" on line %d, ignoring.",
- value, linenum);
- }
- }
- else if (!_cups_strcasecmp(line, "Group") && value)
- {
- /*
- * Group ID to run as...
- */
-
- if (isdigit(value[0]))
- Group = atoi(value);
- else
- {
- endgrent();
- group = getgrnam(value);
-
- if (group != NULL)
- Group = group->gr_gid;
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown Group \"%s\" on line %d, ignoring.",
- value, linenum);
- }
- }
- else if (!_cups_strcasecmp(line, "SystemGroup") && value)
- {
- /*
- * SystemGroup (admin) group(s)...
- */
-
- if (!parse_groups(value))
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown SystemGroup \"%s\" on line %d, ignoring.",
- value, linenum);
- }
else if (!_cups_strcasecmp(line, "HostNameLookups") && value)
{
/*
@@ -3399,22 +3198,6 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogTimeFormat %s on line %d.",
value, linenum);
}
- else if (!_cups_strcasecmp(line, "PrintcapFormat") && value)
- {
- /*
- * Format of printcap file?
- */
-
- if (!_cups_strcasecmp(value, "bsd"))
- PrintcapFormat = PRINTCAP_BSD;
- else if (!_cups_strcasecmp(value, "plist"))
- PrintcapFormat = PRINTCAP_PLIST;
- else if (!_cups_strcasecmp(value, "solaris"))
- PrintcapFormat = PRINTCAP_SOLARIS;
- else
- cupsdLogMessage(CUPSD_LOG_WARN, "Unknown PrintcapFormat %s on line %d.",
- value, linenum);
- }
else if (!_cups_strcasecmp(line, "ServerTokens") && value)
{
/*
@@ -3427,19 +3210,20 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
uname(&plat);
if (!_cups_strcasecmp(value, "ProductOnly"))
- cupsdSetString(&ServerHeader, "CUPS");
+ cupsdSetString(&ServerHeader, "CUPS IPP");
else if (!_cups_strcasecmp(value, "Major"))
- cupsdSetStringf(&ServerHeader, "CUPS/%d", CUPS_VERSION_MAJOR);
+ cupsdSetStringf(&ServerHeader, "CUPS/%d IPP/2", CUPS_VERSION_MAJOR);
else if (!_cups_strcasecmp(value, "Minor"))
- cupsdSetStringf(&ServerHeader, "CUPS/%d.%d", CUPS_VERSION_MAJOR,
+ cupsdSetStringf(&ServerHeader, "CUPS/%d.%d IPP/2.1", CUPS_VERSION_MAJOR,
CUPS_VERSION_MINOR);
else if (!_cups_strcasecmp(value, "Minimal"))
- cupsdSetString(&ServerHeader, CUPS_MINIMAL);
+ cupsdSetString(&ServerHeader, CUPS_MINIMAL " IPP/2.1");
else if (!_cups_strcasecmp(value, "OS"))
- cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s)", plat.sysname);
+ cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s %s) IPP/2.1",
+ plat.sysname, plat.release);
else if (!_cups_strcasecmp(value, "Full"))
- cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s) IPP/2.1",
- plat.sysname);
+ cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s %s; %s) IPP/2.1",
+ plat.sysname, plat.release, plat.machine);
else if (!_cups_strcasecmp(value, "None"))
cupsdClearString(&ServerHeader);
else
@@ -3540,117 +3324,193 @@ read_configuration(cups_file_t *fp) /* I - File to read from */
"line %d.", value, linenum);
}
#endif /* HAVE_SSL */
+ else if (!_cups_strcasecmp(line, "AccessLog") ||
+ !_cups_strcasecmp(line, "CacheDir") ||
+ !_cups_strcasecmp(line, "ConfigFilePerm") ||
+ !_cups_strcasecmp(line, "DataDir") ||
+ !_cups_strcasecmp(line, "DocumentRoot") ||
+ !_cups_strcasecmp(line, "ErrorLog") ||
+ !_cups_strcasecmp(line, "FatalErrors") ||
+ !_cups_strcasecmp(line, "FileDevice") ||
+ !_cups_strcasecmp(line, "FontPath") ||
+ !_cups_strcasecmp(line, "Group") ||
+ !_cups_strcasecmp(line, "LogFilePerm") ||
+ !_cups_strcasecmp(line, "LPDConfigFile") ||
+ !_cups_strcasecmp(line, "PageLog") ||
+ !_cups_strcasecmp(line, "Printcap") ||
+ !_cups_strcasecmp(line, "PrintcapFormat") ||
+ !_cups_strcasecmp(line, "RemoteRoot") ||
+ !_cups_strcasecmp(line, "RequestRoot") ||
+ !_cups_strcasecmp(line, "ServerBin") ||
+ !_cups_strcasecmp(line, "ServerCertificate") ||
+ !_cups_strcasecmp(line, "ServerKey") ||
+ !_cups_strcasecmp(line, "ServerRoot") ||
+ !_cups_strcasecmp(line, "SMBConfigFile") ||
+ !_cups_strcasecmp(line, "StateDir") ||
+ !_cups_strcasecmp(line, "SystemGroup") ||
+ !_cups_strcasecmp(line, "SystemGroupAuthKey") ||
+ !_cups_strcasecmp(line, "TempDir") ||
+ !_cups_strcasecmp(line, "User"))
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO,
+ "Please move \"%s%s%s\" on line %d of %s to the %s file; "
+ "this will become an error in a future release.",
+ line, value ? " " : "", value ? value : "", linenum,
+ ConfigurationFile, CupsFilesFile);
+ }
else
+ parse_variable(ConfigurationFile, linenum, line, value,
+ sizeof(cupsd_vars) / sizeof(cupsd_vars[0]), cupsd_vars);
+ }
+
+ return (1);
+}
+
+
+/*
+ * 'read_cups_files_conf()' - Read the cups-files.conf configuration file.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+read_cups_files_conf(cups_file_t *fp) /* I - File to read from */
+{
+ int linenum; /* Current line number */
+ char line[HTTP_MAX_BUFFER], /* Line from file */
+ *value; /* Value from line */
+ struct group *group; /* Group */
+
+
+ /*
+ * Loop through each line in the file...
+ */
+
+ linenum = 0;
+
+ while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
+ {
+ if (!_cups_strcasecmp(line, "FatalErrors"))
+ FatalErrors = parse_fatal_errors(value);
+ else if (!_cups_strcasecmp(line, "Group") && value)
{
/*
- * Find a simple variable in the list...
+ * Group ID to run as...
*/
- for (i = NUM_VARS, var = variables; i > 0; i --, var ++)
- if (!_cups_strcasecmp(line, var->name))
- break;
-
- if (i == 0)
+ if (isdigit(value[0]))
+ Group = atoi(value);
+ else
{
- /*
- * Unknown directive! Output an error message and continue...
- */
+ endgrent();
+ group = getgrnam(value);
- if (!value)
- cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d.",
- line, linenum);
+ if (group != NULL)
+ Group = group->gr_gid;
else
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d.",
- line, linenum);
- continue;
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unknown Group \"%s\" on line %d of %s.", value,
+ linenum, CupsFilesFile);
+ if (FatalErrors & CUPSD_FATAL_CONFIG)
+ return (0);
+ }
}
+ }
+ else if (!_cups_strcasecmp(line, "PrintcapFormat") && value)
+ {
+ /*
+ * Format of printcap file?
+ */
- switch (var->type)
+ if (!_cups_strcasecmp(value, "bsd"))
+ PrintcapFormat = PRINTCAP_BSD;
+ else if (!_cups_strcasecmp(value, "plist"))
+ PrintcapFormat = PRINTCAP_PLIST;
+ else if (!_cups_strcasecmp(value, "solaris"))
+ PrintcapFormat = PRINTCAP_SOLARIS;
+ else
{
- case CUPSD_VARTYPE_INTEGER :
- if (!value)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Missing integer value for %s on line %d.",
- line, linenum);
- else
- {
- int n; /* Number */
- char *units; /* Units */
-
-
- n = strtol(value, &units, 0);
-
- if (units && *units)
- {
- if (tolower(units[0] & 255) == 'g')
- n *= 1024 * 1024 * 1024;
- else if (tolower(units[0] & 255) == 'm')
- n *= 1024 * 1024;
- else if (tolower(units[0] & 255) == 'k')
- n *= 1024;
- else if (tolower(units[0] & 255) == 't')
- n *= 262144;
- }
-
- if (n < 0)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Bad negative integer value for %s on line %d.",
- line, linenum);
- else
- *((int *)var->ptr) = n;
- }
- break;
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unknown PrintcapFormat \"%s\" on line %d of %s.",
+ value, linenum, CupsFilesFile);
+ if (FatalErrors & CUPSD_FATAL_CONFIG)
+ return (0);
+ }
+ }
+ else if (!_cups_strcasecmp(line, "SystemGroup") && value)
+ {
+ /*
+ * SystemGroup (admin) group(s)...
+ */
- case CUPSD_VARTYPE_BOOLEAN :
- if (!value)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Missing boolean value for %s on line %d.",
- line, linenum);
- else if (!_cups_strcasecmp(value, "true") ||
- !_cups_strcasecmp(value, "on") ||
- !_cups_strcasecmp(value, "enabled") ||
- !_cups_strcasecmp(value, "yes") ||
- atoi(value) != 0)
- *((int *)var->ptr) = TRUE;
- else if (!_cups_strcasecmp(value, "false") ||
- !_cups_strcasecmp(value, "off") ||
- !_cups_strcasecmp(value, "disabled") ||
- !_cups_strcasecmp(value, "no") ||
- !_cups_strcasecmp(value, "0"))
- *((int *)var->ptr) = FALSE;
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown boolean value %s on line %d.",
- value, linenum);
- break;
+ if (!parse_groups(value))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unknown SystemGroup \"%s\" on line %d of %s.", value,
+ linenum, CupsFilesFile);
+ if (FatalErrors & CUPSD_FATAL_CONFIG)
+ return (0);
+ }
+ }
+ else if (!_cups_strcasecmp(line, "User") && value)
+ {
+ /*
+ * User ID to run as...
+ */
- case CUPSD_VARTYPE_PATHNAME :
- if (!value)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Missing pathname value for %s on line %d.",
- line, linenum);
- break;
- }
+ if (isdigit(value[0] & 255))
+ {
+ int uid = atoi(value);
- if (value[0] == '/')
- strlcpy(temp, value, sizeof(temp));
- else
- snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);
+ if (!uid)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Will not use User 0 as specified on line %d of %s "
+ "for security reasons. You must use a non-"
+ "privileged account instead.",
+ linenum, CupsFilesFile);
+ if (FatalErrors & CUPSD_FATAL_CONFIG)
+ return (0);
+ }
+ else
+ User = atoi(value);
+ }
+ else
+ {
+ struct passwd *p; /* Password information */
- if (access(temp, 0))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "File or directory for \"%s %s\" on line %d "
- "does not exist.", line, value, linenum);
- break;
- }
+ endpwent();
+ p = getpwnam(value);
- case CUPSD_VARTYPE_STRING :
- cupsdSetString((char **)var->ptr, value);
- break;
+ if (p)
+ {
+ if (!p->pw_uid)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Will not use User %s (UID=0) as specified on line "
+ "%d of %s for security reasons. You must use a "
+ "non-privileged account instead.",
+ value, linenum, CupsFilesFile);
+ if (FatalErrors & CUPSD_FATAL_CONFIG)
+ return (0);
+ }
+ else
+ User = p->pw_uid;
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unknown User \"%s\" on line %d of %s.",
+ value, linenum, CupsFilesFile);
+ if (FatalErrors & CUPSD_FATAL_CONFIG)
+ return (0);
+ }
}
}
+ else if (!parse_variable(CupsFilesFile, linenum, line, value,
+ sizeof(cupsfiles_vars) / sizeof(cupsfiles_vars[0]),
+ cupsfiles_vars) &&
+ (FatalErrors & CUPSD_FATAL_CONFIG))
+ return (0);
}
return (1);
@@ -3970,6 +3830,7 @@ read_policy(cups_file_t *fp, /* I - Configuration file */
cupsdAddString(&(pol->job_attrs), "job-name");
cupsdAddString(&(pol->job_attrs), "job-originating-host-name");
cupsdAddString(&(pol->job_attrs), "job-originating-user-name");
+ cupsdAddString(&(pol->job_attrs), "phone");
}
else
cupsdAddString(&(pol->job_attrs), value);
@@ -4194,6 +4055,7 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */
cupsdAddString(&(pol->job_attrs), "job-name");
cupsdAddString(&(pol->job_attrs), "job-originating-host-name");
cupsdAddString(&(pol->job_attrs), "job-originating-user-name");
+ cupsdAddString(&(pol->job_attrs), "phone");
}
if (!pol->sub_access)
@@ -4220,5 +4082,5 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */
/*
- * End of "$Id: conf.c 10121 2011-11-16 15:28:11Z mike $".
+ * End of "$Id: conf.c 11221 2013-08-06 16:16:01Z msweet $".
*/
diff --git a/scheduler/conf.h b/scheduler/conf.h
index 0c05ced..8bf0749 100644
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -1,9 +1,9 @@
/*
- * "$Id: conf.h 9710 2011-04-22 17:47:03Z mike $"
+ * "$Id: conf.h 11221 2013-08-06 16:16:01Z msweet $"
*
* Configuration file definitions for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2013 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -69,7 +69,7 @@ typedef enum
#define PRINTCAP_BSD 0 /* Berkeley LPD format */
#define PRINTCAP_SOLARIS 1 /* Solaris lpsched format */
-#define PRINTCAP_PLIST 2 /* Mac OS X plist format */
+#define PRINTCAP_PLIST 2 /* OS X plist format */
/*
@@ -96,7 +96,9 @@ typedef struct
*/
VAR char *ConfigurationFile VALUE(NULL),
- /* Configuration file to use */
+ /* cupsd.conf file to use */
+ *CupsFilesFile VALUE(NULL),
+ /* cups-files.conf file to use */
*ServerName VALUE(NULL),
/* FQDN for server */
*ServerAdmin VALUE(NULL),
@@ -169,6 +171,10 @@ VAR int ClassifyOverride VALUE(0),
/* Amount of automatic debug history */
FatalErrors VALUE(CUPSD_FATAL_CONFIG),
/* Which errors are fatal? */
+ StrictConformance VALUE(FALSE),
+ /* Require strict IPP conformance? */
+ SyncOnClose VALUE(FALSE),
+ /* Call fsync() when closing files? */
LogFilePerm VALUE(0644);
/* Permissions for log files */
VAR cupsd_loglevel_t LogLevel VALUE(CUPSD_LOG_WARN);
@@ -193,12 +199,6 @@ VAR int MaxClients VALUE(100),
/* Support the Keep-Alive option? */
KeepAliveTimeout VALUE(DEFAULT_KEEPALIVE),
/* Timeout between requests */
- ImplicitClasses VALUE(TRUE),
- /* Are classes implicitly created? */
- ImplicitAnyClasses VALUE(FALSE),
- /* Create AnyPrinter classes? */
- HideImplicitMembers VALUE(TRUE),
- /* Hide implicit class members? */
FileDevice VALUE(FALSE),
/* Allow file: devices? */
FilterLimit VALUE(0),
@@ -248,7 +248,7 @@ VAR int SSLOptions VALUE(CUPSD_SSL_NONE);
#endif /* HAVE_SSL */
#ifdef HAVE_LAUNCHD
-VAR int LaunchdTimeout VALUE(DEFAULT_KEEPALIVE);
+VAR int LaunchdTimeout VALUE(10);
/* Time after which an idle cupsd will exit */
#endif /* HAVE_LAUNCHD */
@@ -257,6 +257,14 @@ VAR char *SystemGroupAuthKey VALUE(NULL);
/* System group auth key */
#endif /* HAVE_AUTHORIZATION_H */
+#ifdef HAVE_GSSAPI
+VAR char *GSSServiceName VALUE(NULL);
+ /* GSS service name */
+int HaveServerCreds VALUE(0);
+ /* Do we have server credentials? */
+gss_cred_id_t ServerCreds; /* Server's GSS credentials */
+#endif /* HAVE_GSSAPI */
+
/*
* Prototypes...
@@ -269,6 +277,7 @@ extern int cupsdCheckPermissions(const char *filename,
int user, int group, int is_dir,
int create_dir);
extern int cupsdCheckProgram(const char *filename, cupsd_printer_t *p);
+extern int cupsdDefaultAuthType(void);
extern void cupsdFreeAliases(cups_array_t *aliases);
extern char *cupsdGetDateTime(struct timeval *t, cupsd_time_t format);
extern void cupsdLogFCMessage(void *context, _cups_fc_result_t result,
@@ -278,16 +287,10 @@ extern int cupsdLogGSSMessage(int level, int major_status,
int minor_status,
const char *message, ...);
#endif /* HAVE_GSSAPI */
-extern int cupsdLogJob(cupsd_job_t *job, int level, const char *message, ...)
-#ifdef __GNUC__
-__attribute__ ((__format__ (__printf__, 3, 4)))
-#endif /* __GNUC__ */
-;
+extern int cupsdLogJob(cupsd_job_t *job, int level, const char *message,
+ ...) __attribute__((__format__(__printf__, 3, 4)));
extern int cupsdLogMessage(int level, const char *message, ...)
-#ifdef __GNUC__
-__attribute__ ((__format__ (__printf__, 2, 3)))
-#endif /* __GNUC__ */
-;
+ __attribute__ ((__format__ (__printf__, 2, 3)));
extern int cupsdLogPage(cupsd_job_t *job, const char *page);
extern int cupsdLogRequest(cupsd_client_t *con, http_status_t code);
extern int cupsdReadConfiguration(void);
@@ -295,5 +298,5 @@ extern int cupsdWriteErrorLog(int level, const char *message);
/*
- * End of "$Id: conf.h 9710 2011-04-22 17:47:03Z mike $".
+ * End of "$Id: conf.h 11221 2013-08-06 16:16:01Z msweet $".
*/
diff --git a/scheduler/cups-deviced.c b/scheduler/cups-deviced.c
index aa06ed3..7a5929f 100644
--- a/scheduler/cups-deviced.c
+++ b/scheduler/cups-deviced.c
@@ -1,5 +1,5 @@
/*
- * "$Id: cups-deviced.c 9793 2011-05-20 03:49:49Z mike $"
+ * "$Id: cups-deviced.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Device scanning mini-daemon for CUPS.
*
@@ -806,5 +806,5 @@ start_backend(const char *name, /* I - Backend to run */
/*
- * End of "$Id: cups-deviced.c 9793 2011-05-20 03:49:49Z mike $".
+ * End of "$Id: cups-deviced.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx
index 8500031..4a3d34f 100644
--- a/scheduler/cups-driverd.cxx
+++ b/scheduler/cups-driverd.cxx
@@ -1,5 +1,5 @@
/*
- * "$Id: cups-driverd.cxx 10276 2012-02-13 22:48:22Z mike $"
+ * "$Id: cups-driverd.cxx 11173 2013-07-23 12:31:34Z msweet $"
*
* PPD/driver support for CUPS.
*
@@ -18,26 +18,31 @@
*
* Contents:
*
- * main() - Scan for drivers and return an IPP response.
- * add_ppd() - Add a PPD file.
- * cat_drv() - Generate a PPD from a driver info file.
- * cat_ppd() - Copy a PPD file to stdout.
+ * main() - Scan for drivers and return an IPP response.
+ * add_ppd() - Add a PPD file.
+ * cat_drv() - Generate a PPD from a driver info file.
+ * cat_ppd() - Copy a PPD file to stdout.
* copy_static() - Copy a static PPD file to stdout.
+ * cat_tar() - Copy an archived PPD file to stdout.
* compare_inodes() - Compare two inodes.
* compare_matches() - Compare PPD match scores for sorting.
* compare_names() - Compare PPD filenames for sorting.
* compare_ppds() - Compare PPD file make and model names for sorting.
* dump_ppds_dat() - Dump the contents of the ppds.dat file.
* free_array() - Free an array of strings.
+ * get_file() - Get the filename associated with a request.
* list_ppds() - List PPD files.
* load_drv() - Load the PPDs from a driver information file.
* load_drivers() - Load driver-generated PPD files.
+ * load_ppd() - Load a PPD file.
* load_ppds() - Load PPD files recursively.
* load_ppds_dat() - Load the ppds.dat file.
+ * load_tar() - Load archived PPD files.
+ * read_tar() - Read a file header from an archive.
* regex_device_id() - Compile a regular expression based on the 1284 device
- * ID.
+ * ID.
* regex_string() - Construct a regular expression to compare a simple
- * string.
+ * string.
*/
/*
@@ -67,16 +72,23 @@
#define PPD_TYPE_FAX 3 /* Facsimile/MFD PPD */
#define PPD_TYPE_UNKNOWN 4 /* Other/hybrid PPD */
#define PPD_TYPE_DRV 5 /* Driver info file */
+#define PPD_TYPE_ARCHIVE 6 /* Archive file */
-static const char * const ppd_types[] = /* ppd-type values */
-{
- "postscript",
- "pdf",
- "raster",
- "fax",
- "unknown",
- "drv"
-};
+#define TAR_BLOCK 512 /* Number of bytes in a block */
+#define TAR_BLOCKS 10 /* Blocking factor */
+
+#define TAR_MAGIC "ustar" /* 5 chars and a null */
+#define TAR_VERSION "00" /* POSIX tar version */
+
+#define TAR_OLDNORMAL '\0' /* Normal disk file, Unix compat */
+#define TAR_NORMAL '0' /* Normal disk file */
+#define TAR_LINK '1' /* Link to previously dumped file */
+#define TAR_SYMLINK '2' /* Symbolic link */
+#define TAR_CHR '3' /* Character special file */
+#define TAR_BLK '4' /* Block special file */
+#define TAR_DIR '5' /* Directory */
+#define TAR_FIFO '6' /* FIFO special file */
+#define TAR_CONTIG '7' /* Contiguous file */
/*
@@ -110,15 +122,51 @@ typedef struct /**** In-memory record ****/
ppd_rec_t record; /* PPDs.dat record */
} ppd_info_t;
+typedef union /**** TAR record format ****/
+{
+ unsigned char all[TAR_BLOCK]; /* Raw data block */
+ struct
+ {
+ char pathname[100], /* Destination path */
+ mode[8], /* Octal file permissions */
+ uid[8], /* Octal user ID */
+ gid[8], /* Octal group ID */
+ size[12], /* Octal size in bytes */
+ mtime[12], /* Octal modification time */
+ chksum[8], /* Octal checksum value */
+ linkflag, /* File type */
+ linkname[100], /* Source path for link */
+ magic[6], /* Magic string */
+ version[2], /* Format version */
+ uname[32], /* User name */
+ gname[32], /* Group name */
+ devmajor[8], /* Octal device major number */
+ devminor[8], /* Octal device minor number */
+ prefix[155]; /* Prefix for long filenames */
+ } header;
+} tar_rec_t;
+
/*
* Globals...
*/
-cups_array_t *Inodes = NULL, /* Inodes of directories we've visited */
- *PPDsByName = NULL, /* PPD files sorted by filename and name */
- *PPDsByMakeModel = NULL;/* PPD files sorted by make and model */
-int ChangedPPD; /* Did we change the PPD database? */
+static cups_array_t *Inodes = NULL, /* Inodes of directories we've visited */
+ *PPDsByName = NULL,
+ /* PPD files sorted by filename and name */
+ *PPDsByMakeModel = NULL;
+ /* PPD files sorted by make and model */
+static int ChangedPPD; /* Did we change the PPD database? */
+static const char * const PPDTypes[] = /* ppd-type values */
+ {
+ "postscript",
+ "pdf",
+ "raster",
+ "fax",
+ "unknown",
+ "drv",
+ "archive"
+ };
/*
@@ -135,6 +183,7 @@ static ppd_info_t *add_ppd(const char *filename, const char *name,
static int cat_drv(const char *name, int request_id);
static int cat_ppd(const char *name, int request_id);
static int cat_static(const char *name, int request_id);
+static int cat_tar(const char *name, int request_id);
static int compare_inodes(struct stat *a, struct stat *b);
static int compare_matches(const ppd_info_t *p0,
const ppd_info_t *p1);
@@ -142,16 +191,26 @@ static int compare_names(const ppd_info_t *p0,
const ppd_info_t *p1);
static int compare_ppds(const ppd_info_t *p0,
const ppd_info_t *p1);
-static int dump_ppds_dat(void);
+static int dump_ppds_dat(const char *filename);
static void free_array(cups_array_t *a);
+static cups_file_t *get_file(const char *name, int request_id,
+ const char *subdir, char *buffer,
+ size_t bufsize, char **subfile);
static int list_ppds(int request_id, int limit, const char *opt);
static int load_drivers(cups_array_t *include,
cups_array_t *exclude);
static int load_drv(const char *filename, const char *name,
cups_file_t *fp, time_t mtime, off_t size);
+static void load_ppd(const char *filename, const char *name,
+ const char *scheme, struct stat *fileinfo,
+ ppd_info_t *ppd, cups_file_t *fp, off_t end);
static int load_ppds(const char *d, const char *p, int descend);
static void load_ppds_dat(char *filename, size_t filesize,
int verbose);
+static int load_tar(const char *filename, const char *name,
+ cups_file_t *fp, time_t mtime, off_t size);
+static int read_tar(cups_file_t *fp, char *name, size_t namesize,
+ struct stat *info);
static regex_t *regex_device_id(const char *device_id);
static regex_t *regex_string(const char *s);
@@ -174,8 +233,8 @@ main(int argc, /* I - Number of command-line args */
if (argc == 3 && !strcmp(argv[1], "cat"))
return (cat_ppd(argv[2], 0));
- else if (argc == 2 && !strcmp(argv[1], "dump"))
- return (dump_ppds_dat());
+ else if ((argc == 2 || argc == 3) && !strcmp(argv[1], "dump"))
+ return (dump_ppds_dat(argv[2]));
else if (argc == 4 && !strcmp(argv[1], "get"))
return (cat_ppd(argv[3], atoi(argv[2])));
else if (argc == 5 && !strcmp(argv[1], "list"))
@@ -281,7 +340,7 @@ static int /* O - Exit code */
cat_drv(const char *name, /* I - PPD name */
int request_id) /* I - Request ID for response? */
{
- const char *datadir; // CUPS_DATADIR env var
+ cups_file_t *fp; // File pointer
ppdcSource *src; // PPD source file data
ppdcDriver *d; // Current driver
cups_file_t *out; // Stdout via CUPS file API
@@ -295,23 +354,16 @@ cat_drv(const char *name, /* I - PPD name */
int port; // Port number (unused)
- // Determine where CUPS has installed the data files...
- if ((datadir = getenv("CUPS_DATADIR")) == NULL)
- datadir = CUPS_DATADIR;
-
// Pull out the path to the .drv file...
if (httpSeparateURI(HTTP_URI_CODING_ALL, name, scheme, sizeof(scheme),
userpass, sizeof(userpass), host, sizeof(host), &port,
- resource, sizeof(resource)) < HTTP_URI_OK ||
- strstr(resource, "../") ||
- (pc_file_name = strrchr(resource, '/')) == NULL ||
- pc_file_name == resource)
+ resource, sizeof(resource)) < HTTP_URI_OK)
{
- fprintf(stderr, "ERROR: Bad PPD name \"%s\"!\n", name);
+ fprintf(stderr, "ERROR: Bad PPD name \"%s\".\n", name);
if (request_id)
{
- snprintf(message, sizeof(message), "Bad PPD name \"%s\"!", name);
+ snprintf(message, sizeof(message), "Bad PPD name \"%s\".", name);
cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
cupsdSendIPPGroup(IPP_TAG_OPERATION);
@@ -325,21 +377,11 @@ cat_drv(const char *name, /* I - PPD name */
return (1);
}
- *pc_file_name++ = '\0';
-
-#ifdef __APPLE__
- if (!strncmp(resource, "/Library/Printers/PPDs/Contents/Resources/", 42) ||
- !strncmp(resource, "/System/Library/Printers/PPDs/Contents/Resources/", 49))
- strlcpy(filename, resource, sizeof(filename));
- else
-#endif // __APPLE__
- {
- snprintf(filename, sizeof(filename), "%s/drv%s", datadir, resource);
- if (access(filename, 0))
- snprintf(filename, sizeof(filename), "%s/model%s", datadir, resource);
- }
+ if ((fp = get_file(resource, request_id, "drv", filename, sizeof(filename),
+ &pc_file_name)) == NULL)
+ return (1);
- src = new ppdcSource(filename);
+ src = new ppdcSource(filename, fp);
for (d = (ppdcDriver *)src->drivers->first();
d;
@@ -387,11 +429,11 @@ cat_drv(const char *name, /* I - PPD name */
}
else
{
- fprintf(stderr, "ERROR: PPD \"%s\" not found!\n", name);
+ fprintf(stderr, "ERROR: PPD \"%s\" not found.\n", name);
if (request_id)
{
- snprintf(message, sizeof(message), "PPD \"%s\" not found!", name);
+ snprintf(message, sizeof(message), "PPD \"%s\" not found.", name);
cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
cupsdSendIPPGroup(IPP_TAG_OPERATION);
@@ -404,6 +446,7 @@ cat_drv(const char *name, /* I - PPD name */
}
src->release();
+ cupsFileClose(fp);
return (!d);
}
@@ -439,7 +482,12 @@ cat_ppd(const char *name, /* I - PPD name */
*/
name += 5;
- scheme[0] = '\0';
+
+ while (*name == '/')
+ name ++;
+
+ if (!strstr(name, ".tar/") && !strstr(name, ".tar.gz/"))
+ scheme[0] = '\0';
}
}
else
@@ -452,6 +500,8 @@ cat_ppd(const char *name, /* I - PPD name */
return (cat_static(name, request_id));
else if (!strcmp(scheme, "drv"))
return (cat_drv(name, request_id));
+ else if (!strcmp(scheme, "file"))
+ return (cat_tar(name, request_id));
else
{
/*
@@ -540,144 +590,132 @@ cat_static(const char *name, /* I - PPD name */
int request_id) /* I - Request ID for response? */
{
cups_file_t *fp; /* PPD file */
- const char *datadir; /* CUPS_DATADIR env var */
- char line[1024], /* Line/filename */
- message[2048]; /* status-message */
-#ifdef __APPLE__
- const char *printerDriver, /* Pointer to .printerDriver extension */
- *slash; /* Pointer to next slash */
-#endif /* __APPLE__ */
-
-
- if (name[0] == '/' || strstr(name, "../") || strstr(name, "/.."))
- {
- /*
- * Bad name...
- */
-
- fprintf(stderr, "ERROR: [cups-driverd] Bad PPD name \"%s\"!\n", name);
-
- if (request_id)
- {
- snprintf(message, sizeof(message), "Bad PPD name \"%s\"!", name);
+ char filename[1024], /* PPD filename */
+ line[1024]; /* Line buffer */
- cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
- cupsdSendIPPGroup(IPP_TAG_OPERATION);
- cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
- cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
- "en-US");
- cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message);
- cupsdSendIPPTrailer();
- }
+ if ((fp = get_file(name, request_id, "model", filename, sizeof(filename),
+ NULL)) == NULL)
return (1);
+
+ if (request_id)
+ {
+ cupsdSendIPPHeader(IPP_OK, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPTrailer();
}
/*
- * Try opening the file...
+ * Now copy the file to stdout...
*/
-#ifdef __APPLE__
- if (!strncmp(name, "System/Library/Printers/PPDs/Contents/Resources/", 48) ||
- !strncmp(name, "Library/Printers/PPDs/Contents/Resources/", 41) ||
- (!strncmp(name, "System/Library/Printers/", 24) &&
- (printerDriver =
- strstr(name + 24,
- ".printerDriver/Contents/Resources/PPDs")) != NULL &&
- (slash = strchr(name + 24, '/')) != NULL &&
- slash > printerDriver) ||
- (!strncmp(name, "Library/Printers/", 17) &&
- (printerDriver =
- strstr(name + 17,
- ".printerDriver/Contents/Resources/PPDs")) != NULL &&
- (slash = strchr(name + 17, '/')) != NULL &&
- slash > printerDriver))
- {
- /*
- * Map ppd-name to Mac OS X standard locations...
- */
+ while (cupsFileGets(fp, line, sizeof(line)))
+ puts(line);
- snprintf(line, sizeof(line), "/%s", name);
- }
- else
+ cupsFileClose(fp);
-#elif defined(__linux)
- if (!strncmp(name, "lsb/usr/", 8))
- {
- /*
- * Map ppd-name to LSB standard /usr/share/ppd location...
- */
+ return (0);
+}
- snprintf(line, sizeof(line), "/usr/share/ppd/%s", name + 8);
- }
- else if (!strncmp(name, "lsb/opt/", 8))
- {
- /*
- * Map ppd-name to LSB standard /opt/share/ppd location...
- */
- snprintf(line, sizeof(line), "/opt/share/ppd/%s", name + 8);
- }
- else if (!strncmp(name, "lsb/local/", 10))
- {
- /*
- * Map ppd-name to LSB standard /usr/local/share/ppd location...
- */
+/*
+ * 'cat_tar()' - Copy an archived PPD file to stdout.
+ */
- snprintf(line, sizeof(line), "/usr/local/share/ppd/%s", name + 10);
- }
- else
+static int /* O - Exit code */
+cat_tar(const char *name, /* I - PPD name */
+ int request_id) /* I - Request ID */
+{
+ cups_file_t *fp; /* Archive file pointer */
+ char filename[1024], /* Archive filename */
+ *ppdname, /* PPD filename in archive */
+ curname[256], /* Current name in archive */
+ buffer[8192]; /* Copy buffer */
+ struct stat curinfo; /* Current file info in archive */
+ off_t total, /* Total bytes copied */
+ next; /* Offset for next record in archive */
+ ssize_t bytes; /* Bytes read */
-#endif /* __APPLE__ */
- {
- if ((datadir = getenv("CUPS_DATADIR")) == NULL)
- datadir = CUPS_DATADIR;
- snprintf(line, sizeof(line), "%s/model/%s", datadir, name);
- }
+ /*
+ * Open the archive file...
+ */
- if ((fp = cupsFileOpen(line, "r")) == NULL)
+ if ((fp = get_file(name, request_id, "model", filename, sizeof(filename),
+ &ppdname)) == NULL)
+ return (1);
+
+ /*
+ * Scan the archive for the PPD...
+ */
+
+ while (read_tar(fp, curname, sizeof(curname), &curinfo))
{
- fprintf(stderr, "ERROR: [cups-driverd] Unable to open \"%s\" - %s\n",
- line, strerror(errno));
+ next = cupsFileTell(fp) + ((curinfo.st_size + TAR_BLOCK - 1) &
+ ~(TAR_BLOCK - 1));
- if (request_id)
+ if (!strcmp(ppdname, curname))
{
- snprintf(message, sizeof(message), "Unable to open \"%s\" - %s",
- line, strerror(errno));
+ if (request_id)
+ {
+ cupsdSendIPPHeader(IPP_OK, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPTrailer();
+ }
- cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
- cupsdSendIPPGroup(IPP_TAG_OPERATION);
- cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
- cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
- "en-US");
- cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message);
- cupsdSendIPPTrailer();
+ for (total = 0; total < curinfo.st_size; total += bytes)
+ {
+ if ((size_t)(bytes = (curinfo.st_size - total)) > sizeof(buffer))
+ bytes = sizeof(buffer);
+
+ if ((bytes = cupsFileRead(fp, buffer, bytes)) < 0)
+ {
+ if (errno == EINTR || errno == EAGAIN)
+ {
+ bytes = 0;
+ }
+ else
+ {
+ perror("ERROR: [cups-driverd] Read error");
+ break;
+ }
+ }
+ else if (bytes > 0 && fwrite(buffer, bytes, 1, stdout) != 1)
+ break;
+ }
+
+ cupsFileClose(fp);
+ return (0);
}
- return (1);
+ if (cupsFileTell(fp) != next)
+ cupsFileSeek(fp, next);
}
+ cupsFileClose(fp);
+
+ fprintf(stderr, "ERROR: PPD \"%s\" not found.\n", name);
+
if (request_id)
{
- cupsdSendIPPHeader(IPP_OK, request_id);
+ snprintf(buffer, sizeof(buffer), "PPD \"%s\" not found.", name);
+
+ cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
cupsdSendIPPGroup(IPP_TAG_OPERATION);
cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
"en-US");
+ cupsdSendIPPString(IPP_TAG_TEXT, "status-message", buffer);
cupsdSendIPPTrailer();
}
- /*
- * Now copy the file to stdout...
- */
-
- while (cupsFileGets(fp, line, sizeof(line)))
- puts(line);
-
- cupsFileClose(fp);
-
- return (0);
+ return (1);
}
@@ -763,9 +801,9 @@ compare_ppds(const ppd_info_t *p0, /* I - First PPD file */
*/
static int /* O - Exit status */
-dump_ppds_dat(void)
+dump_ppds_dat(const char *filename) /* I - Filename */
{
- char filename[1024]; /* ppds.dat filename */
+ char temp[1024]; /* ppds.dat filename */
ppd_info_t *ppd; /* Current PPD */
@@ -773,7 +811,12 @@ dump_ppds_dat(void)
* See if we a PPD database file...
*/
- load_ppds_dat(filename, sizeof(filename), 0);
+ if (filename)
+ strlcpy(temp, filename, sizeof(temp));
+ else
+ temp[0] = '\0';
+
+ load_ppds_dat(temp, sizeof(temp), 0);
puts("mtime,size,model_number,type,filename,name,languages0,products0,"
"psversions0,make,make_and_model,device_id,scheme");
@@ -813,6 +856,173 @@ free_array(cups_array_t *a) /* I - Array to free */
/*
+ * 'get_file()' - Get the filename associated with a request.
+ */
+
+static cups_file_t * /* O - File pointer or NULL */
+get_file(const char *name, /* I - Name */
+ int request_id, /* I - Request ID */
+ const char *subdir, /* I - Subdirectory for file */
+ char *buffer, /* I - Filename buffer */
+ size_t bufsize, /* I - Size of filename buffer */
+ char **subfile) /* O - Sub-filename */
+{
+ cups_file_t *fp; /* File pointer */
+ const char *datadir; /* CUPS_DATADIR env var */
+ char *bufptr, /* Pointer into filename buffer */
+ message[2048]; /* status-message */
+#ifdef __APPLE__
+ const char *printerDriver, /* Pointer to .printerDriver extension */
+ *slash; /* Pointer to next slash */
+#endif /* __APPLE__ */
+
+
+ if (subfile)
+ *subfile = NULL;
+
+ while (*name == '/')
+ name ++;
+
+ if (strstr(name, "../") || strstr(name, "/.."))
+ {
+ /*
+ * Bad name...
+ */
+
+ fprintf(stderr, "ERROR: [cups-driverd] Bad PPD name \"%s\".\n", name);
+
+ if (request_id)
+ {
+ snprintf(message, sizeof(message), "Bad PPD name \"%s\".", name);
+
+ cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message);
+ cupsdSendIPPTrailer();
+ }
+
+ return (NULL);
+ }
+
+ /*
+ * Try opening the file...
+ */
+
+#ifdef __APPLE__
+ if (!strncmp(name, "System/Library/Printers/PPDs/Contents/Resources/", 48) ||
+ !strncmp(name, "Library/Printers/PPDs/Contents/Resources/", 41) ||
+ (!strncmp(name, "System/Library/Printers/", 24) &&
+ (printerDriver =
+ strstr(name + 24,
+ ".printerDriver/Contents/Resources/PPDs")) != NULL &&
+ (slash = strchr(name + 24, '/')) != NULL &&
+ slash > printerDriver) ||
+ (!strncmp(name, "Library/Printers/", 17) &&
+ (printerDriver =
+ strstr(name + 17,
+ ".printerDriver/Contents/Resources/PPDs")) != NULL &&
+ (slash = strchr(name + 17, '/')) != NULL &&
+ slash > printerDriver))
+ {
+ /*
+ * Map ppd-name to OS X standard locations...
+ */
+
+ snprintf(buffer, bufsize, "/%s", name);
+ }
+ else
+
+#elif defined(__linux)
+ if (!strncmp(name, "lsb/usr/", 8))
+ {
+ /*
+ * Map ppd-name to LSB standard /usr/share/ppd location...
+ */
+
+ snprintf(buffer, bufsize, "/usr/share/ppd/%s", name + 8);
+ }
+ else if (!strncmp(name, "lsb/opt/", 8))
+ {
+ /*
+ * Map ppd-name to LSB standard /opt/share/ppd location...
+ */
+
+ snprintf(buffer, bufsize, "/opt/share/ppd/%s", name + 8);
+ }
+ else if (!strncmp(name, "lsb/local/", 10))
+ {
+ /*
+ * Map ppd-name to LSB standard /usr/local/share/ppd location...
+ */
+
+ snprintf(buffer, bufsize, "/usr/local/share/ppd/%s", name + 10);
+ }
+ else
+
+#endif /* __APPLE__ */
+ {
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
+
+ snprintf(buffer, bufsize, "%s/%s/%s", datadir, subdir, name);
+ }
+
+ /*
+ * Strip anything after ".drv/", ".drv.gz/", ".tar/", or ".tar.gz/"...
+ */
+
+ if (subfile)
+ {
+ if ((bufptr = strstr(buffer, ".drv/")) != NULL)
+ bufptr += 4;
+ else if ((bufptr = strstr(buffer, ".drv.gz/")) != NULL)
+ bufptr += 7;
+ else if ((bufptr = strstr(buffer, ".tar/")) != NULL)
+ bufptr += 4;
+ else if ((bufptr = strstr(buffer, ".tar.gz/")) != NULL)
+ bufptr += 7;
+
+ if (bufptr)
+ {
+ *bufptr++ = '\0';
+ *subfile = bufptr;
+ }
+ }
+
+ /*
+ * Try opening the file...
+ */
+
+ if ((fp = cupsFileOpen(buffer, "r")) == NULL)
+ {
+ fprintf(stderr, "ERROR: [cups-driverd] Unable to open \"%s\" - %s\n",
+ buffer, strerror(errno));
+
+ if (request_id)
+ {
+ snprintf(message, sizeof(message), "Unable to open \"%s\" - %s",
+ buffer, strerror(errno));
+
+ cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message);
+ cupsdSendIPPTrailer();
+ }
+
+ return (NULL);
+ }
+
+ return (fp);
+}
+
+
+/*
* 'list_ppds()' - List PPD files.
*/
@@ -869,6 +1079,7 @@ list_ppds(int request_id, /* I - Request ID */
* See if we a PPD database file...
*/
+ filename[0] = '\0';
load_ppds_dat(filename, sizeof(filename), 1);
/*
@@ -888,7 +1099,7 @@ list_ppds(int request_id, /* I - Request ID */
#ifdef __APPLE__
/*
- * Load PPDs from standard Mac OS X locations...
+ * Load PPDs from standard OS X locations...
*/
load_ppds("/Library/Printers",
@@ -1029,12 +1240,12 @@ list_ppds(int request_id, /* I - Request ID */
if (type_str)
{
for (type = 0;
- type < (int)(sizeof(ppd_types) / sizeof(ppd_types[0]));
+ type < (int)(sizeof(PPDTypes) / sizeof(PPDTypes[0]));
type ++)
- if (!strcmp(type_str, ppd_types[type]))
+ if (!strcmp(type_str, PPDTypes[type]))
break;
- if (type >= (int)(sizeof(ppd_types) / sizeof(ppd_types[0])))
+ if (type >= (int)(sizeof(PPDTypes) / sizeof(PPDTypes[0])))
{
fprintf(stderr, "ERROR: [cups-driverd] Bad ppd-type=\"%s\" ignored!\n",
type_str);
@@ -1273,11 +1484,14 @@ list_ppds(int request_id, /* I - Request ID */
{
sent_header = 1;
- cupsdSendIPPHeader(IPP_OK, request_id);
- cupsdSendIPPGroup(IPP_TAG_OPERATION);
- cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
- cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
- "en-US");
+ if (request_id)
+ {
+ cupsdSendIPPHeader(IPP_OK, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ }
}
fprintf(stderr, "DEBUG2: [cups-driverd] Sending %s (%s)...\n",
@@ -1285,56 +1499,61 @@ list_ppds(int request_id, /* I - Request ID */
count --;
- cupsdSendIPPGroup(IPP_TAG_PRINTER);
+ if (request_id)
+ {
+ cupsdSendIPPGroup(IPP_TAG_PRINTER);
- if (send_name)
- cupsdSendIPPString(IPP_TAG_NAME, "ppd-name", ppd->record.name);
+ if (send_name)
+ cupsdSendIPPString(IPP_TAG_NAME, "ppd-name", ppd->record.name);
- if (send_natural_language)
- {
- cupsdSendIPPString(IPP_TAG_LANGUAGE, "ppd-natural-language",
- ppd->record.languages[0]);
+ if (send_natural_language)
+ {
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "ppd-natural-language",
+ ppd->record.languages[0]);
- for (i = 1; i < PPD_MAX_LANG && ppd->record.languages[i][0]; i ++)
- cupsdSendIPPString(IPP_TAG_LANGUAGE, "", ppd->record.languages[i]);
- }
+ for (i = 1; i < PPD_MAX_LANG && ppd->record.languages[i][0]; i ++)
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "", ppd->record.languages[i]);
+ }
- if (send_make)
- cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make", ppd->record.make);
+ if (send_make)
+ cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make", ppd->record.make);
- if (send_make_and_model)
- cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make-and-model",
- ppd->record.make_and_model);
+ if (send_make_and_model)
+ cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make-and-model",
+ ppd->record.make_and_model);
- if (send_device_id)
- cupsdSendIPPString(IPP_TAG_TEXT, "ppd-device-id",
- ppd->record.device_id);
+ if (send_device_id)
+ cupsdSendIPPString(IPP_TAG_TEXT, "ppd-device-id",
+ ppd->record.device_id);
- if (send_product)
- {
- cupsdSendIPPString(IPP_TAG_TEXT, "ppd-product",
- ppd->record.products[0]);
+ if (send_product)
+ {
+ cupsdSendIPPString(IPP_TAG_TEXT, "ppd-product",
+ ppd->record.products[0]);
- for (i = 1; i < PPD_MAX_PROD && ppd->record.products[i][0]; i ++)
- cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.products[i]);
- }
+ for (i = 1; i < PPD_MAX_PROD && ppd->record.products[i][0]; i ++)
+ cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.products[i]);
+ }
- if (send_psversion)
- {
- cupsdSendIPPString(IPP_TAG_TEXT, "ppd-psversion",
- ppd->record.psversions[0]);
+ if (send_psversion)
+ {
+ cupsdSendIPPString(IPP_TAG_TEXT, "ppd-psversion",
+ ppd->record.psversions[0]);
- for (i = 1; i < PPD_MAX_VERS && ppd->record.psversions[i][0]; i ++)
- cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.psversions[i]);
- }
+ for (i = 1; i < PPD_MAX_VERS && ppd->record.psversions[i][0]; i ++)
+ cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.psversions[i]);
+ }
- if (send_type)
- cupsdSendIPPString(IPP_TAG_KEYWORD, "ppd-type",
- ppd_types[ppd->record.type]);
+ if (send_type)
+ cupsdSendIPPString(IPP_TAG_KEYWORD, "ppd-type",
+ PPDTypes[ppd->record.type]);
- if (send_model_number)
- cupsdSendIPPInteger(IPP_TAG_INTEGER, "ppd-model-number",
- ppd->record.model_number);
+ if (send_model_number)
+ cupsdSendIPPInteger(IPP_TAG_INTEGER, "ppd-model-number",
+ ppd->record.model_number);
+ }
+ else
+ printf("%s (%s)\n", ppd->record.name, ppd->record.make_and_model);
/*
* If we have only requested the ppd-make attribute, then skip
@@ -1358,7 +1577,7 @@ list_ppds(int request_id, /* I - Request ID */
}
}
- if (!sent_header)
+ if (!sent_header && request_id)
{
cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
cupsdSendIPPGroup(IPP_TAG_OPERATION);
@@ -1366,7 +1585,8 @@ list_ppds(int request_id, /* I - Request ID */
cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US");
}
- cupsdSendIPPTrailer();
+ if (request_id)
+ cupsdSendIPPTrailer();
return (0);
}
@@ -1687,12 +1907,12 @@ load_drivers(cups_array_t *include, /* I - Drivers to include */
*start++ = '\0';
for (type = 0;
- type < (int)(sizeof(ppd_types) / sizeof(ppd_types[0]));
+ type < (int)(sizeof(PPDTypes) / sizeof(PPDTypes[0]));
type ++)
- if (!strcmp(type_str, ppd_types[type]))
+ if (!strcmp(type_str, PPDTypes[type]))
break;
- if (type >= (int)(sizeof(ppd_types) / sizeof(ppd_types[0])))
+ if (type >= (int)(sizeof(PPDTypes) / sizeof(PPDTypes[0])))
{
fprintf(stderr,
"ERROR: [cups-driverd] Bad ppd-type \"%s\" ignored!\n",
@@ -1745,24 +1965,21 @@ load_drivers(cups_array_t *include, /* I - Drivers to include */
/*
- * 'load_ppds()' - Load PPD files recursively.
+ * 'load_ppd()' - Load a PPD file.
*/
-static int /* O - 1 on success, 0 on failure */
-load_ppds(const char *d, /* I - Actual directory */
- const char *p, /* I - Virtual path in name */
- int descend) /* I - Descend into directories? */
+static void
+load_ppd(const char *filename, /* I - Real filename */
+ const char *name, /* I - Virtual filename */
+ const char *scheme, /* I - PPD scheme */
+ struct stat *fileinfo, /* I - File information */
+ ppd_info_t *ppd, /* I - Existing PPD file or NULL */
+ cups_file_t *fp, /* I - File to read from */
+ off_t end) /* I - End of file position or 0 */
{
- struct stat dinfo, /* Directory information */
- *dinfoptr; /* Pointer to match */
int i; /* Looping var */
- cups_file_t *fp; /* Pointer to file */
- cups_dir_t *dir; /* Directory pointer */
- cups_dentry_t *dent; /* Directory entry */
- char filename[1024], /* Name of PPD or directory */
- line[256], /* Line from backend */
- *ptr, /* Pointer into name */
- name[128], /* Name of PPD file */
+ char line[256], /* Line from file */
+ *ptr, /* Pointer into line */
lang_version[64], /* PPD LanguageVersion */
lang_encoding[64], /* PPD LanguageEncoding */
country[64], /* Country code */
@@ -1780,8 +1997,6 @@ load_ppds(const char *d, /* I - Actual directory */
cups_array_t *products, /* Product array */
*psversions, /* PSVersion array */
*cups_languages; /* cupsLanguages array */
- ppd_info_t *ppd, /* New PPD file */
- key; /* Search key */
int new_ppd; /* Is this a new PPD? */
struct /* LanguageVersion translation table */
{
@@ -1816,6 +2031,379 @@ load_ppds(const char *d, /* I - Actual directory */
/*
+ * Now read until we get the required fields...
+ */
+
+ cups_languages = cupsArrayNew(NULL, NULL);
+ products = cupsArrayNew(NULL, NULL);
+ psversions = cupsArrayNew(NULL, NULL);
+
+ model_name[0] = '\0';
+ nick_name[0] = '\0';
+ manufacturer[0] = '\0';
+ device_id[0] = '\0';
+ lang_encoding[0] = '\0';
+ strcpy(lang_version, "en");
+ model_number = 0;
+ install_group = 0;
+ type = PPD_TYPE_POSTSCRIPT;
+
+ while ((end == 0 || cupsFileTell(fp) < end) &&
+ cupsFileGets(fp, line, sizeof(line)))
+ {
+ if (!strncmp(line, "*Manufacturer:", 14))
+ sscanf(line, "%*[^\"]\"%255[^\"]", manufacturer);
+ else if (!strncmp(line, "*ModelName:", 11))
+ sscanf(line, "%*[^\"]\"%127[^\"]", model_name);
+ else if (!strncmp(line, "*LanguageEncoding:", 18))
+ sscanf(line, "%*[^:]:%63s", lang_encoding);
+ else if (!strncmp(line, "*LanguageVersion:", 17))
+ sscanf(line, "%*[^:]:%63s", lang_version);
+ else if (!strncmp(line, "*NickName:", 10))
+ sscanf(line, "%*[^\"]\"%255[^\"]", nick_name);
+ else if (!_cups_strncasecmp(line, "*1284DeviceID:", 14))
+ {
+ sscanf(line, "%*[^\"]\"%255[^\"]", device_id);
+
+ // Make sure device ID ends with a semicolon...
+ if (device_id[0] && device_id[strlen(device_id) - 1] != ';')
+ strlcat(device_id, ";", sizeof(device_id));
+ }
+ else if (!strncmp(line, "*Product:", 9))
+ {
+ if (sscanf(line, "%*[^\"]\"(%255[^\"]", product) == 1)
+ {
+ /*
+ * Make sure the value ends with a right parenthesis - can't stop at
+ * the first right paren since the product name may contain escaped
+ * parenthesis...
+ */
+
+ ptr = product + strlen(product) - 1;
+ if (ptr > product && *ptr == ')')
+ {
+ /*
+ * Yes, ends with a parenthesis, so remove it from the end and
+ * add the product to the list...
+ */
+
+ *ptr = '\0';
+ cupsArrayAdd(products, strdup(product));
+ }
+ }
+ }
+ else if (!strncmp(line, "*PSVersion:", 11))
+ {
+ sscanf(line, "%*[^\"]\"%255[^\"]", psversion);
+ cupsArrayAdd(psversions, strdup(psversion));
+ }
+ else if (!strncmp(line, "*cupsLanguages:", 15))
+ {
+ char *start; /* Start of language */
+
+
+ for (start = line + 15; *start && isspace(*start & 255); start ++);
+
+ if (*start++ == '\"')
+ {
+ while (*start)
+ {
+ for (ptr = start + 1;
+ *ptr && *ptr != '\"' && !isspace(*ptr & 255);
+ ptr ++);
+
+ if (*ptr)
+ {
+ *ptr++ = '\0';
+
+ while (isspace(*ptr & 255))
+ *ptr++ = '\0';
+ }
+
+ cupsArrayAdd(cups_languages, strdup(start));
+ start = ptr;
+ }
+ }
+ }
+ else if (!strncmp(line, "*cupsFax:", 9))
+ {
+ for (ptr = line + 9; isspace(*ptr & 255); ptr ++);
+
+ if (!_cups_strncasecmp(ptr, "true", 4))
+ type = PPD_TYPE_FAX;
+ }
+ else if (!strncmp(line, "*cupsFilter:", 12) && type == PPD_TYPE_POSTSCRIPT)
+ {
+ if (strstr(line + 12, "application/vnd.cups-raster"))
+ type = PPD_TYPE_RASTER;
+ else if (strstr(line + 12, "application/vnd.cups-pdf"))
+ type = PPD_TYPE_PDF;
+ }
+ else if (!strncmp(line, "*cupsModelNumber:", 17))
+ sscanf(line, "*cupsModelNumber:%d", &model_number);
+ else if (!strncmp(line, "*OpenGroup: Installable", 23))
+ install_group = 1;
+ else if (!strncmp(line, "*CloseGroup:", 12))
+ install_group = 0;
+ else if (!strncmp(line, "*OpenUI", 7))
+ {
+ /*
+ * Stop early if we have a NickName or ModelName attributes
+ * before the first non-installable OpenUI...
+ */
+
+ if (!install_group && (model_name[0] || nick_name[0]) &&
+ cupsArrayCount(products) > 0 && cupsArrayCount(psversions) > 0)
+ break;
+ }
+ }
+
+ /*
+ * See if we got all of the required info...
+ */
+
+ if (nick_name[0])
+ cupsCharsetToUTF8((cups_utf8_t *)make_model, nick_name,
+ sizeof(make_model), _ppdGetEncoding(lang_encoding));
+ else
+ strcpy(make_model, model_name);
+
+ while (isspace(make_model[0] & 255))
+ _cups_strcpy(make_model, make_model + 1);
+
+ if (!make_model[0] || cupsArrayCount(products) == 0 ||
+ cupsArrayCount(psversions) == 0)
+ {
+ /*
+ * We don't have all the info needed, so skip this file...
+ */
+
+ if (!make_model[0])
+ fprintf(stderr, "WARNING: Missing NickName and ModelName in %s!\n",
+ filename);
+
+ if (cupsArrayCount(products) == 0)
+ fprintf(stderr, "WARNING: Missing Product in %s!\n", filename);
+
+ if (cupsArrayCount(psversions) == 0)
+ fprintf(stderr, "WARNING: Missing PSVersion in %s!\n", filename);
+
+ free_array(products);
+ free_array(psversions);
+ free_array(cups_languages);
+
+ return;
+ }
+
+ if (model_name[0])
+ cupsArrayAdd(products, strdup(model_name));
+
+ /*
+ * Normalize the make and model string...
+ */
+
+ while (isspace(manufacturer[0] & 255))
+ _cups_strcpy(manufacturer, manufacturer + 1);
+
+ if (!_cups_strncasecmp(make_model, manufacturer, strlen(manufacturer)))
+ strlcpy(temp, make_model, sizeof(temp));
+ else
+ snprintf(temp, sizeof(temp), "%s %s", manufacturer, make_model);
+
+ _ppdNormalizeMakeAndModel(temp, make_model, sizeof(make_model));
+
+ /*
+ * See if we got a manufacturer...
+ */
+
+ if (!manufacturer[0] || !strcmp(manufacturer, "ESP"))
+ {
+ /*
+ * Nope, copy the first part of the make and model then...
+ */
+
+ strlcpy(manufacturer, make_model, sizeof(manufacturer));
+
+ /*
+ * Truncate at the first space, dash, or slash, or make the
+ * manufacturer "Other"...
+ */
+
+ for (ptr = manufacturer; *ptr; ptr ++)
+ if (*ptr == ' ' || *ptr == '-' || *ptr == '/')
+ break;
+
+ if (*ptr && ptr > manufacturer)
+ *ptr = '\0';
+ else
+ strcpy(manufacturer, "Other");
+ }
+ else if (!_cups_strncasecmp(manufacturer, "LHAG", 4) ||
+ !_cups_strncasecmp(manufacturer, "linotype", 8))
+ strcpy(manufacturer, "LHAG");
+ else if (!_cups_strncasecmp(manufacturer, "Hewlett", 7))
+ strcpy(manufacturer, "HP");
+
+ /*
+ * Fix the lang_version as needed...
+ */
+
+ if ((ptr = strchr(lang_version, '-')) != NULL)
+ *ptr++ = '\0';
+ else if ((ptr = strchr(lang_version, '_')) != NULL)
+ *ptr++ = '\0';
+
+ if (ptr)
+ {
+ /*
+ * Setup the country suffix...
+ */
+
+ country[0] = '_';
+ _cups_strcpy(country + 1, ptr);
+ }
+ else
+ {
+ /*
+ * No country suffix...
+ */
+
+ country[0] = '\0';
+ }
+
+ for (i = 0; i < (int)(sizeof(languages) / sizeof(languages[0])); i ++)
+ if (!_cups_strcasecmp(languages[i].version, lang_version))
+ break;
+
+ if (i < (int)(sizeof(languages) / sizeof(languages[0])))
+ {
+ /*
+ * Found a known language...
+ */
+
+ snprintf(lang_version, sizeof(lang_version), "%s%s",
+ languages[i].language, country);
+ }
+ else
+ {
+ /*
+ * Unknown language; use "xx"...
+ */
+
+ strcpy(lang_version, "xx");
+ }
+
+ /*
+ * Record the PPD file...
+ */
+
+ new_ppd = !ppd;
+
+ if (new_ppd)
+ {
+ /*
+ * Add new PPD file...
+ */
+
+ fprintf(stderr, "DEBUG2: [cups-driverd] Adding ppd \"%s\"...\n", name);
+
+ ppd = add_ppd(name, name, lang_version, manufacturer, make_model,
+ device_id, (char *)cupsArrayFirst(products),
+ (char *)cupsArrayFirst(psversions),
+ fileinfo->st_mtime, fileinfo->st_size,
+ model_number, type, scheme);
+
+ if (!ppd)
+ return;
+ }
+ else
+ {
+ /*
+ * Update existing record...
+ */
+
+ fprintf(stderr, "DEBUG2: [cups-driverd] Updating ppd \"%s\"...\n", name);
+
+ memset(ppd, 0, sizeof(ppd_info_t));
+
+ ppd->found = 1;
+ ppd->record.mtime = fileinfo->st_mtime;
+ ppd->record.size = fileinfo->st_size;
+ ppd->record.model_number = model_number;
+ ppd->record.type = type;
+
+ strlcpy(ppd->record.filename, name, sizeof(ppd->record.filename));
+ strlcpy(ppd->record.name, name, sizeof(ppd->record.name));
+ strlcpy(ppd->record.languages[0], lang_version,
+ sizeof(ppd->record.languages[0]));
+ strlcpy(ppd->record.products[0], (char *)cupsArrayFirst(products),
+ sizeof(ppd->record.products[0]));
+ strlcpy(ppd->record.psversions[0], (char *)cupsArrayFirst(psversions),
+ sizeof(ppd->record.psversions[0]));
+ strlcpy(ppd->record.make, manufacturer, sizeof(ppd->record.make));
+ strlcpy(ppd->record.make_and_model, make_model,
+ sizeof(ppd->record.make_and_model));
+ strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id));
+ strlcpy(ppd->record.scheme, scheme, sizeof(ppd->record.scheme));
+ }
+
+ /*
+ * Add remaining products, versions, and languages...
+ */
+
+ for (i = 1;
+ i < PPD_MAX_PROD && (ptr = (char *)cupsArrayNext(products)) != NULL;
+ i ++)
+ strlcpy(ppd->record.products[i], ptr,
+ sizeof(ppd->record.products[0]));
+
+ for (i = 1;
+ i < PPD_MAX_VERS && (ptr = (char *)cupsArrayNext(psversions)) != NULL;
+ i ++)
+ strlcpy(ppd->record.psversions[i], ptr,
+ sizeof(ppd->record.psversions[0]));
+
+ for (i = 1, ptr = (char *)cupsArrayFirst(cups_languages);
+ i < PPD_MAX_LANG && ptr;
+ i ++, ptr = (char *)cupsArrayNext(cups_languages))
+ strlcpy(ppd->record.languages[i], ptr,
+ sizeof(ppd->record.languages[0]));
+
+ /*
+ * Free products, versions, and languages...
+ */
+
+ free_array(cups_languages);
+ free_array(products);
+ free_array(psversions);
+
+ ChangedPPD = 1;
+}
+
+
+/*
+ * 'load_ppds()' - Load PPD files recursively.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+load_ppds(const char *d, /* I - Actual directory */
+ const char *p, /* I - Virtual path in name */
+ int descend) /* I - Descend into directories? */
+{
+ struct stat dinfo, /* Directory information */
+ *dinfoptr; /* Pointer to match */
+ cups_file_t *fp; /* Pointer to file */
+ cups_dir_t *dir; /* Directory pointer */
+ cups_dentry_t *dent; /* Directory entry */
+ char filename[1024], /* Name of PPD or directory */
+ line[256], /* Line from file */
+ *ptr, /* Pointer into name */
+ name[128]; /* Name of PPD file */
+ ppd_info_t *ppd, /* New PPD file */
+ key; /* Search key */
+
+
+ /*
* See if we've loaded this directory before...
*/
@@ -1915,8 +2503,7 @@ load_ppds(const char *d, /* I - Actual directory */
continue;
}
- else if ((ptr = filename + strlen(filename) - 6) > filename &&
- !strcmp(ptr, ".plist"))
+ else if (strstr(filename, ".plist"))
{
/*
* Skip plist files in the PPDs directory...
@@ -1973,373 +2560,36 @@ load_ppds(const char *d, /* I - Actual directory */
line[0] = '\0';
cupsFileGets(fp, line, sizeof(line));
- if (strncmp(line, "*PPD-Adobe:", 11))
- {
- /*
- * Nope, treat it as a driver information file...
- */
-
- load_drv(filename, name, fp, dent->fileinfo.st_mtime,
- dent->fileinfo.st_size);
- continue;
- }
-
- /*
- * Now read until we get the NickName field...
- */
-
- cups_languages = cupsArrayNew(NULL, NULL);
- products = cupsArrayNew(NULL, NULL);
- psversions = cupsArrayNew(NULL, NULL);
-
- model_name[0] = '\0';
- nick_name[0] = '\0';
- manufacturer[0] = '\0';
- device_id[0] = '\0';
- lang_encoding[0] = '\0';
- strcpy(lang_version, "en");
- model_number = 0;
- install_group = 0;
- type = PPD_TYPE_POSTSCRIPT;
-
- while (cupsFileGets(fp, line, sizeof(line)) != NULL)
- {
- if (!strncmp(line, "*Manufacturer:", 14))
- sscanf(line, "%*[^\"]\"%255[^\"]", manufacturer);
- else if (!strncmp(line, "*ModelName:", 11))
- sscanf(line, "%*[^\"]\"%127[^\"]", model_name);
- else if (!strncmp(line, "*LanguageEncoding:", 18))
- sscanf(line, "%*[^:]:%63s", lang_encoding);
- else if (!strncmp(line, "*LanguageVersion:", 17))
- sscanf(line, "%*[^:]:%63s", lang_version);
- else if (!strncmp(line, "*NickName:", 10))
- sscanf(line, "%*[^\"]\"%255[^\"]", nick_name);
- else if (!_cups_strncasecmp(line, "*1284DeviceID:", 14))
- {
- sscanf(line, "%*[^\"]\"%255[^\"]", device_id);
-
- // Make sure device ID ends with a semicolon...
- if (device_id[0] && device_id[strlen(device_id) - 1] != ';')
- strlcat(device_id, ";", sizeof(device_id));
- }
- else if (!strncmp(line, "*Product:", 9))
- {
- if (sscanf(line, "%*[^\"]\"(%255[^\"]", product) == 1)
- {
- /*
- * Make sure the value ends with a right parenthesis - can't stop at
- * the first right paren since the product name may contain escaped
- * parenthesis...
- */
-
- ptr = product + strlen(product) - 1;
- if (ptr > product && *ptr == ')')
- {
- /*
- * Yes, ends with a parenthesis, so remove it from the end and
- * add the product to the list...
- */
-
- *ptr = '\0';
- cupsArrayAdd(products, strdup(product));
- }
- }
- }
- else if (!strncmp(line, "*PSVersion:", 11))
- {
- sscanf(line, "%*[^\"]\"%255[^\"]", psversion);
- cupsArrayAdd(psversions, strdup(psversion));
- }
- else if (!strncmp(line, "*cupsLanguages:", 15))
- {
- char *start; /* Start of language */
-
-
- for (start = line + 15; *start && isspace(*start & 255); start ++);
-
- if (*start++ == '\"')
- {
- while (*start)
- {
- for (ptr = start + 1;
- *ptr && *ptr != '\"' && !isspace(*ptr & 255);
- ptr ++);
-
- if (*ptr)
- {
- *ptr++ = '\0';
-
- while (isspace(*ptr & 255))
- *ptr++ = '\0';
- }
-
- cupsArrayAdd(cups_languages, strdup(start));
- start = ptr;
- }
- }
- }
- else if (!strncmp(line, "*cupsFax:", 9))
- {
- for (ptr = line + 9; isspace(*ptr & 255); ptr ++);
-
- if (!_cups_strncasecmp(ptr, "true", 4))
- type = PPD_TYPE_FAX;
- }
- else if (!strncmp(line, "*cupsFilter:", 12) && type == PPD_TYPE_POSTSCRIPT)
- {
- if (strstr(line + 12, "application/vnd.cups-raster"))
- type = PPD_TYPE_RASTER;
- else if (strstr(line + 12, "application/vnd.cups-pdf"))
- type = PPD_TYPE_PDF;
- }
- else if (!strncmp(line, "*cupsModelNumber:", 17))
- sscanf(line, "*cupsModelNumber:%d", &model_number);
- else if (!strncmp(line, "*OpenGroup: Installable", 23))
- install_group = 1;
- else if (!strncmp(line, "*CloseGroup:", 12))
- install_group = 0;
- else if (!strncmp(line, "*OpenUI", 7))
- {
- /*
- * Stop early if we have a NickName or ModelName attributes
- * before the first non-installable OpenUI...
- */
-
- if (!install_group && (model_name[0] || nick_name[0]) &&
- cupsArrayCount(products) > 0 && cupsArrayCount(psversions) > 0)
- break;
- }
- }
-
- /*
- * Close the file...
- */
-
- cupsFileClose(fp);
-
- /*
- * See if we got all of the required info...
- */
-
- if (nick_name[0])
- cupsCharsetToUTF8((cups_utf8_t *)make_model, nick_name,
- sizeof(make_model), _ppdGetEncoding(lang_encoding));
- else
- strcpy(make_model, model_name);
-
- while (isspace(make_model[0] & 255))
- _cups_strcpy(make_model, make_model + 1);
-
- if (!make_model[0] || cupsArrayCount(products) == 0 ||
- cupsArrayCount(psversions) == 0)
+ if (!strncmp(line, "*PPD-Adobe:", 11))
{
/*
- * We don't have all the info needed, so skip this file...
+ * Yes, load it...
*/
- if (!make_model[0])
- fprintf(stderr, "WARNING: Missing NickName and ModelName in %s!\n",
- filename);
-
- if (cupsArrayCount(products) == 0)
- fprintf(stderr, "WARNING: Missing Product in %s!\n", filename);
-
- if (cupsArrayCount(psversions) == 0)
- fprintf(stderr, "WARNING: Missing PSVersion in %s!\n", filename);
-
- free_array(products);
- free_array(psversions);
- free_array(cups_languages);
-
- continue;
+ load_ppd(filename, name, "file", &dent->fileinfo, ppd, fp, 0);
}
-
- if (model_name[0])
- cupsArrayAdd(products, strdup(model_name));
-
- /*
- * Normalize the make and model string...
- */
-
- while (isspace(manufacturer[0] & 255))
- _cups_strcpy(manufacturer, manufacturer + 1);
-
- if (!_cups_strncasecmp(make_model, manufacturer, strlen(manufacturer)))
- strlcpy(temp, make_model, sizeof(temp));
else
- snprintf(temp, sizeof(temp), "%s %s", manufacturer, make_model);
-
- _ppdNormalizeMakeAndModel(temp, make_model, sizeof(make_model));
-
- /*
- * See if we got a manufacturer...
- */
-
- if (!manufacturer[0] || !strcmp(manufacturer, "ESP"))
{
/*
- * Nope, copy the first part of the make and model then...
- */
-
- strlcpy(manufacturer, make_model, sizeof(manufacturer));
-
- /*
- * Truncate at the first space, dash, or slash, or make the
- * manufacturer "Other"...
+ * Nope, treat it as a driver information file or archive...
*/
- for (ptr = manufacturer; *ptr; ptr ++)
- if (*ptr == ' ' || *ptr == '-' || *ptr == '/')
- break;
+ cupsFileRewind(fp);
- if (*ptr && ptr > manufacturer)
- *ptr = '\0';
+ if ((ptr = strstr(filename, ".tar")) != NULL &&
+ (!strcmp(ptr, ".tar") || !strcmp(ptr, ".tar.gz")))
+ load_tar(filename, name, fp, dent->fileinfo.st_mtime,
+ dent->fileinfo.st_size);
else
- strcpy(manufacturer, "Other");
- }
- else if (!_cups_strncasecmp(manufacturer, "LHAG", 4) ||
- !_cups_strncasecmp(manufacturer, "linotype", 8))
- strcpy(manufacturer, "LHAG");
- else if (!_cups_strncasecmp(manufacturer, "Hewlett", 7))
- strcpy(manufacturer, "HP");
-
- /*
- * Fix the lang_version as needed...
- */
-
- if ((ptr = strchr(lang_version, '-')) != NULL)
- *ptr++ = '\0';
- else if ((ptr = strchr(lang_version, '_')) != NULL)
- *ptr++ = '\0';
-
- if (ptr)
- {
- /*
- * Setup the country suffix...
- */
-
- country[0] = '_';
- _cups_strcpy(country + 1, ptr);
- }
- else
- {
- /*
- * No country suffix...
- */
-
- country[0] = '\0';
- }
-
- for (i = 0; i < (int)(sizeof(languages) / sizeof(languages[0])); i ++)
- if (!_cups_strcasecmp(languages[i].version, lang_version))
- break;
-
- if (i < (int)(sizeof(languages) / sizeof(languages[0])))
- {
- /*
- * Found a known language...
- */
-
- snprintf(lang_version, sizeof(lang_version), "%s%s",
- languages[i].language, country);
- }
- else
- {
- /*
- * Unknown language; use "xx"...
- */
-
- strcpy(lang_version, "xx");
- }
-
- /*
- * Record the PPD file...
- */
-
- new_ppd = !ppd;
-
- if (new_ppd)
- {
- /*
- * Add new PPD file...
- */
-
- fprintf(stderr, "DEBUG2: [cups-driverd] Adding ppd \"%s\"...\n", name);
-
- ppd = add_ppd(name, name, lang_version, manufacturer, make_model,
- device_id, (char *)cupsArrayFirst(products),
- (char *)cupsArrayFirst(psversions),
- dent->fileinfo.st_mtime, dent->fileinfo.st_size,
- model_number, type, "file");
-
- if (!ppd)
- {
- cupsDirClose(dir);
- return (0);
- }
- }
- else
- {
- /*
- * Update existing record...
- */
-
- fprintf(stderr, "DEBUG2: [cups-driverd] Updating ppd \"%s\"...\n", name);
-
- memset(ppd, 0, sizeof(ppd_info_t));
-
- ppd->found = 1;
- ppd->record.mtime = dent->fileinfo.st_mtime;
- ppd->record.size = dent->fileinfo.st_size;
- ppd->record.model_number = model_number;
- ppd->record.type = type;
-
- strlcpy(ppd->record.filename, name, sizeof(ppd->record.filename));
- strlcpy(ppd->record.name, name, sizeof(ppd->record.name));
- strlcpy(ppd->record.languages[0], lang_version,
- sizeof(ppd->record.languages[0]));
- strlcpy(ppd->record.products[0], (char *)cupsArrayFirst(products),
- sizeof(ppd->record.products[0]));
- strlcpy(ppd->record.psversions[0], (char *)cupsArrayFirst(psversions),
- sizeof(ppd->record.psversions[0]));
- strlcpy(ppd->record.make, manufacturer, sizeof(ppd->record.make));
- strlcpy(ppd->record.make_and_model, make_model,
- sizeof(ppd->record.make_and_model));
- strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id));
- strlcpy(ppd->record.scheme, "file", sizeof(ppd->record.scheme));
+ load_drv(filename, name, fp, dent->fileinfo.st_mtime,
+ dent->fileinfo.st_size);
}
/*
- * Add remaining products, versions, and languages...
- */
-
- for (i = 1;
- i < PPD_MAX_PROD && (ptr = (char *)cupsArrayNext(products)) != NULL;
- i ++)
- strlcpy(ppd->record.products[i], ptr,
- sizeof(ppd->record.products[0]));
-
- for (i = 1;
- i < PPD_MAX_VERS && (ptr = (char *)cupsArrayNext(psversions)) != NULL;
- i ++)
- strlcpy(ppd->record.psversions[i], ptr,
- sizeof(ppd->record.psversions[0]));
-
- for (i = 1, ptr = (char *)cupsArrayFirst(cups_languages);
- i < PPD_MAX_LANG && ptr;
- i ++, ptr = (char *)cupsArrayNext(cups_languages))
- strlcpy(ppd->record.languages[i], ptr,
- sizeof(ppd->record.languages[0]));
-
- /*
- * Free products, versions, and languages...
+ * Close the file...
*/
- free_array(cups_languages);
- free_array(products);
- free_array(psversions);
-
- ChangedPPD = 1;
+ cupsFileClose(fp);
}
cupsDirClose(dir);
@@ -2367,10 +2617,14 @@ load_ppds_dat(char *filename, /* I - Filename buffer */
PPDsByMakeModel = cupsArrayNew((cups_array_func_t)compare_ppds, NULL);
ChangedPPD = 0;
- if ((cups_cachedir = getenv("CUPS_CACHEDIR")) == NULL)
- cups_cachedir = CUPS_CACHEDIR;
+ if (!filename[0])
+ {
+ if ((cups_cachedir = getenv("CUPS_CACHEDIR")) == NULL)
+ cups_cachedir = CUPS_CACHEDIR;
+
+ snprintf(filename, filesize, "%s/ppds.dat", cups_cachedir);
+ }
- snprintf(filename, filesize, "%s/ppds.dat", cups_cachedir);
if ((fp = cupsFileOpen(filename, "r")) != NULL)
{
/*
@@ -2425,6 +2679,117 @@ load_ppds_dat(char *filename, /* I - Filename buffer */
/*
+ * 'load_tar()' - Load archived PPD files.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+load_tar(const char *filename, /* I - Actual filename */
+ const char *name, /* I - Name to the rest of the world */
+ cups_file_t *fp, /* I - File to read from */
+ time_t mtime, /* I - Mod time of driver info file */
+ off_t size) /* I - Size of driver info file */
+{
+ char curname[256], /* Current archive file name */
+ uri[1024]; /* Virtual file URI */
+ const char *curext; /* Extension on file */
+ struct stat curinfo; /* Current archive file information */
+ off_t next; /* Position for next header */
+
+
+ /*
+ * Add a dummy entry for the file...
+ */
+
+ (void)filename;
+
+ add_ppd(name, name, "", "", "", "", "", "", mtime, size, 0,
+ PPD_TYPE_ARCHIVE, "file");
+ ChangedPPD = 1;
+
+ /*
+ * Scan for PPDs in the archive...
+ */
+
+ while (read_tar(fp, curname, sizeof(curname), &curinfo))
+ {
+ next = cupsFileTell(fp) + ((curinfo.st_size + TAR_BLOCK - 1) &
+ ~(TAR_BLOCK - 1));
+
+ if ((curext = strrchr(curname, '.')) != NULL &&
+ !_cups_strcasecmp(curext, ".ppd"))
+ {
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "file", "", "",
+ 0, "/%s/%s", name, curname);
+ load_ppd(name, uri, "file", &curinfo, NULL, fp, next);
+ }
+
+ if (cupsFileTell(fp) != next)
+ cupsFileSeek(fp, next);
+ }
+
+ return (1);
+}
+
+
+/*
+ * 'read_tar()' - Read a file header from an archive.
+ *
+ * This function skips all directories and special files.
+ */
+
+static int /* O - 1 if found, 0 on EOF */
+read_tar(cups_file_t *fp, /* I - Archive to read */
+ char *name, /* I - Filename buffer */
+ size_t namesize, /* I - Size of filename buffer */
+ struct stat *info) /* O - File information */
+{
+ tar_rec_t record; /* Record from file */
+
+
+ while (cupsFileRead(fp, (char *)&record, sizeof(record)) == sizeof(record))
+ {
+ /*
+ * Check for a valid tar header...
+ */
+
+ if (memcmp(record.header.magic, TAR_MAGIC, 6) ||
+ memcmp(record.header.version, TAR_VERSION, 2))
+ {
+ if (record.header.magic[0] ||
+ memcmp(record.header.magic, record.header.magic + 1, 5))
+ fputs("ERROR: [cups-driverd] Bad tar magic/version.\n", stderr);
+ break;
+ }
+
+ /*
+ * Ignore non-files...
+ */
+
+ if (record.header.linkflag != TAR_OLDNORMAL &&
+ record.header.linkflag != TAR_NORMAL)
+ continue;
+
+ /*
+ * Grab size and name from tar header and return...
+ */
+
+ if (record.header.prefix[0])
+ snprintf(name, namesize, "%s/%s", record.header.prefix,
+ record.header.pathname);
+ else
+ strlcpy(name, record.header.pathname, namesize);
+
+ info->st_mtime = strtol(record.header.mtime, NULL, 8);
+ info->st_size = strtoll(record.header.size, NULL, 8);
+
+ return (1);
+ }
+
+ return (0);
+}
+
+
+/*
* 'regex_device_id()' - Compile a regular expression based on the 1284 device
* ID.
*/
@@ -2582,5 +2947,5 @@ regex_string(const char *s) /* I - String to compare */
/*
- * End of "$Id: cups-driverd.cxx 10276 2012-02-13 22:48:22Z mike $".
+ * End of "$Id: cups-driverd.cxx 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/cups-exec.c b/scheduler/cups-exec.c
index 6918c7f..6d0d3d8 100644
--- a/scheduler/cups-exec.c
+++ b/scheduler/cups-exec.c
@@ -1,9 +1,9 @@
/*
- * "$Id: cups-exec.c 9931 2011-08-29 20:12:39Z mike $"
+ * "$Id: cups-exec.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Sandbox helper for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -31,6 +31,7 @@
# ifndef SANDBOX_NAMED_EXTERNAL
# define SANDBOX_NAMED_EXTERNAL 0x0003
# endif /* !SANDBOX_NAMED_EXTERNAL */
+# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif /* HAVE_SANDBOX_H */
@@ -104,5 +105,5 @@ main(int argc, /* I - Number of command-line args */
/*
- * End of "$Id: cups-exec.c 9931 2011-08-29 20:12:39Z mike $".
+ * End of "$Id: cups-exec.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/cups-lpd.c b/scheduler/cups-lpd.c
index 7846ecf..bd6757b 100644
--- a/scheduler/cups-lpd.c
+++ b/scheduler/cups-lpd.c
@@ -1,9 +1,9 @@
/*
- * "$Id: cups-lpd.c 10379 2012-03-23 22:16:22Z mike $"
+ * "$Id: cups-lpd.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Line Printer Daemon interface for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -744,8 +744,7 @@ print_file(http_t *http, /* I - HTTP connection */
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
"document-format", NULL, format);
- if (last)
- ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);
+ ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last);
/*
* Do the request...
@@ -1623,5 +1622,5 @@ smart_gets(char *s, /* I - Pointer to line buffer */
/*
- * End of "$Id: cups-lpd.c 10379 2012-03-23 22:16:22Z mike $".
+ * End of "$Id: cups-lpd.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/cups-polld.c b/scheduler/cups-polld.c
deleted file mode 100644
index 65b2e68..0000000
--- a/scheduler/cups-polld.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * "$Id: cups-polld.c 10321 2012-03-02 18:26:30Z mike $"
- *
- * Polling daemon for CUPS.
- *
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
- *
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * main() - Open sockets and poll until we are killed...
- * dequote() - Remote quotes from a string.
- * poll_server() - Poll the server for the given set of printers or
- * classes.
- * sighup_handler() - Handle 'hangup' signals to restart polling.
- */
-
-/*
- * Include necessary headers...
- */
-
-#include <cups/cups-private.h>
-#include <signal.h>
-
-
-/*
- * Local globals...
- */
-
-static int restart_polling = 1;
-
-
-/*
- * Local functions...
- */
-
-static char *dequote(char *d, const char *s, int dlen);
-static int poll_server(http_t *http, int sock, int port, int interval,
- const char *prefix);
-static void sighup_handler(int sig);
-
-
-/*
- * 'main()' - Open sockets and poll until we are killed...
- */
-
-int /* O - Exit status */
-main(int argc, /* I - Number of command-line args */
- char *argv[]) /* I - Command-line arguments */
-{
- http_t *http; /* HTTP connection */
- int interval; /* Polling interval */
- int sock; /* Browser sock */
- int port; /* Browser port */
- int val; /* Socket option value */
- int seconds, /* Seconds left from poll */
- remain; /* Total remaining time to sleep */
- char prefix[1024]; /* Prefix for log messages */
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
- struct sigaction action; /* Actions for POSIX signals */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
-
-
- /*
- * Catch hangup signals for when the network changes...
- */
-
-#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
- sigset(SIGHUP, sighup_handler);
-#elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
-
- sigemptyset(&action.sa_mask);
- sigaddset(&action.sa_mask, SIGHUP);
- action.sa_handler = sighup_handler;
- sigaction(SIGHUP, &action, NULL);
-#else
- signal(SIGHUP, sighup_handler);
-#endif /* HAVE_SIGSET */
-
- /*
- * Don't buffer log messages...
- */
-
- setbuf(stderr, NULL);
-
- /*
- * The command-line must contain the following:
- *
- * cups-polld server server-port interval port
- */
-
- if (argc != 5)
- {
- fputs("Usage: cups-polld server server-port interval port\n", stderr);
- return (1);
- }
-
- interval = atoi(argv[3]);
- port = atoi(argv[4]);
-
- if (interval < 2)
- interval = 2;
-
- snprintf(prefix, sizeof(prefix), "[cups-polld %s:%d]", argv[1], atoi(argv[2]));
-
- /*
- * Open a broadcast socket...
- */
-
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- fprintf(stderr, "ERROR: %s Unable to open broadcast socket: %s\n", prefix,
- strerror(errno));
- return (1);
- }
-
- /*
- * Set the "broadcast" flag...
- */
-
- val = 1;
- if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
- {
- fprintf(stderr, "ERROR: %s Unable to put socket in broadcast mode: %s\n",
- prefix, strerror(errno));
-
- close(sock);
- return (1);
- }
-
- /*
- * Loop forever, asking for available printers and classes...
- */
-
- for (http = NULL; !ferror(stderr);)
- {
- /*
- * Open a connection to the server...
- */
-
- if (restart_polling || !http)
- {
- restart_polling = 0;
- httpClose(http);
-
- if ((http = httpConnectEncrypt(argv[1], atoi(argv[2]),
- cupsEncryption())) == NULL)
- {
- fprintf(stderr, "ERROR: %s Unable to connect to %s on port %s.\n",
- prefix, argv[1], argv[2]);
- }
- }
-
- /*
- * Get the printers and classes...
- */
-
- remain = interval;
-
- if (http && (seconds = poll_server(http, sock, port, interval, prefix)) > 0)
- remain -= seconds;
-
- /*
- * Sleep for any remaining time...
- */
-
- if (remain > 0 && !restart_polling)
- sleep(remain);
- }
-
- return (1);
-}
-
-
-/*
- * 'dequote()' - Remote quotes from a string.
- */
-
-static char * /* O - Dequoted string */
-dequote(char *d, /* I - Destination string */
- const char *s, /* I - Source string */
- int dlen) /* I - Destination length */
-{
- char *dptr; /* Pointer into destination */
-
-
- if (s)
- {
- for (dptr = d, dlen --; *s && dlen > 0; s ++)
- if (*s != '\"')
- {
- *dptr++ = *s;
- dlen --;
- }
-
- *dptr = '\0';
- }
- else
- *d = '\0';
-
- return (d);
-}
-
-
-/*
- * 'poll_server()' - Poll the server for the given set of printers or classes.
- */
-
-static int /* O - Number of seconds or -1 on error */
-poll_server(http_t *http, /* I - HTTP connection */
- int sock, /* I - Broadcast sock */
- int port, /* I - Broadcast port */
- int interval, /* I - Polling interval */
- const char *prefix) /* I - Prefix for log messages */
-{
- int seconds; /* Number of seconds */
- int count, /* Current number of printers/classes */
- max_count; /* Maximum printers/classes per second */
- ipp_t *request, /* Request data */
- *response; /* Response data */
- ipp_attribute_t *attr; /* Current attribute */
- const char *uri; /* printer-uri */
- char info[1024], /* printer-info */
- job_sheets[1024],/* job-sheets-default */
- location[1024], /* printer-location */
- make_model[1024];
- /* printer-make-and-model */
- cups_ptype_t type; /* printer-type */
- ipp_pstate_t state; /* printer-state */
- int accepting; /* printer-is-accepting-jobs */
- struct sockaddr_in addr; /* Broadcast address */
- char packet[1540]; /* Data packet */
- static const char * const attrs[] = /* Requested attributes */
- {
- "job-sheets-default",
- "printer-info",
- "printer-is-accepting-jobs",
- "printer-location",
- "printer-make-and-model",
- "printer-name",
- "printer-state",
- "printer-type",
- "printer-uri-supported"
- };
-
-
- /*
- * Broadcast to 127.0.0.1 (localhost)
- */
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_addr.s_addr = htonl(0x7f000001);
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
-
- /*
- * Build a CUPS_GET_PRINTERS request and pass along a list of the
- * attributes we are interested in along with the types of printers
- * (and classes) we want.
- */
-
- request = ippNewRequest(CUPS_GET_PRINTERS);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes", sizeof(attrs) / sizeof(attrs[0]),
- NULL, attrs);
-
- ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
- "printer-type", 0);
- ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
- "printer-type-mask",
- CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_NOT_SHARED);
-
- /*
- * Do the request and get back a response...
- */
-
- seconds = time(NULL);
- response = cupsDoRequest(http, request, "/");
-
- if (cupsLastError() > IPP_OK_CONFLICT)
- {
- fprintf(stderr, "ERROR: %s CUPS-Get-Printers failed: %s\n", prefix,
- cupsLastErrorString());
- ippDelete(response);
- restart_polling = 1;
- return (-1);
- }
-
- if (response)
- {
- /*
- * Figure out how many printers/classes we have...
- */
-
- for (attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME),
- max_count = 0;
- attr != NULL;
- attr = ippFindNextAttribute(response, "printer-name", IPP_TAG_NAME),
- max_count ++);
-
- fprintf(stderr, "DEBUG: %s Found %d printers.\n", prefix, max_count);
-
- count = 0;
- max_count = 2 * max_count / interval + 1;
-
- /*
- * Loop through the printers or classes returned in the list...
- */
-
- for (attr = response->attrs; attr; attr = attr->next)
- {
- /*
- * Skip leading attributes until we hit a printer...
- */
-
- while (attr && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (!attr)
- break;
-
- /*
- * Pull the needed attributes from this printer...
- */
-
- uri = NULL;
- info[0] = '\0';
- job_sheets[0] = '\0';
- location[0] = '\0';
- make_model[0] = '\0';
- type = CUPS_PRINTER_REMOTE;
- accepting = 1;
- state = IPP_PRINTER_IDLE;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
- {
- if (!strcmp(attr->name, "job-sheets-default") &&
- (attr->value_tag == IPP_TAG_NAME ||
- attr->value_tag == IPP_TAG_KEYWORD))
- {
- if (attr->num_values == 1)
- snprintf(job_sheets, sizeof(job_sheets), " job-sheets=%s",
- attr->values[0].string.text);
- else
- snprintf(job_sheets, sizeof(job_sheets), " job-sheets=%s,%s",
- attr->values[0].string.text,
- attr->values[1].string.text);
- }
- else if (!strcmp(attr->name, "printer-uri-supported") &&
- attr->value_tag == IPP_TAG_URI)
- uri = attr->values[0].string.text;
- else if (!strcmp(attr->name, "printer-info") &&
- attr->value_tag == IPP_TAG_TEXT)
- dequote(info, attr->values[0].string.text, sizeof(info));
- else if (!strcmp(attr->name, "printer-is-accepting-jobs") &&
- attr->value_tag == IPP_TAG_BOOLEAN)
- accepting = attr->values[0].boolean;
- else if (!strcmp(attr->name, "printer-location") &&
- attr->value_tag == IPP_TAG_TEXT)
- dequote(location, attr->values[0].string.text, sizeof(location));
- else if (!strcmp(attr->name, "printer-make-and-model") &&
- attr->value_tag == IPP_TAG_TEXT)
- dequote(make_model, attr->values[0].string.text, sizeof(location));
- else if (!strcmp(attr->name, "printer-state") &&
- attr->value_tag == IPP_TAG_ENUM)
- state = (ipp_pstate_t)attr->values[0].integer;
- else if (!strcmp(attr->name, "printer-type") &&
- attr->value_tag == IPP_TAG_ENUM)
- type = (cups_ptype_t)attr->values[0].integer;
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (uri == NULL)
- {
- if (attr == NULL)
- break;
- else
- continue;
- }
-
- /*
- * Send the printer information...
- */
-
- type |= CUPS_PRINTER_REMOTE;
-
- if (!accepting)
- type |= CUPS_PRINTER_REJECTING;
-
- snprintf(packet, sizeof(packet),
- "%x %x %s \"%s\" \"%s\" \"%s\" lease-duration=%d%s\n",
- type, state, uri, location, info, make_model, interval * 2,
- job_sheets);
-
- fprintf(stderr, "DEBUG2: %s Sending %s", prefix, packet);
-
- if (sendto(sock, packet, strlen(packet), 0,
- (struct sockaddr *)&addr, sizeof(addr)) <= 0)
- {
- ippDelete(response);
- perror("cups-polld");
- return (-1);
- }
-
- /*
- * Throttle the local broadcasts as needed so that we don't
- * overwhelm the local server...
- */
-
- count ++;
- if (count >= max_count)
- {
- /*
- * Sleep for a second...
- */
-
- count = 0;
-
- sleep(1);
- }
-
- if (!attr || restart_polling)
- break;
- }
-
- ippDelete(response);
- }
-
- /*
- * Return the number of seconds we used...
- */
-
- return (time(NULL) - seconds);
-}
-
-
-/*
- * 'sighup_handler()' - Handle 'hangup' signals to restart polling.
- */
-
-static void
-sighup_handler(int sig) /* I - Signal number */
-{
- (void)sig;
-
- restart_polling = 1;
-
-#if !defined(HAVE_SIGSET) && !defined(HAVE_SIGACTION)
- signal(SIGHUP, sighup_handler);
-#endif /* !HAVE_SIGSET && !HAVE_SIGACTION */
-}
-
-
-/*
- * End of "$Id: cups-polld.c 10321 2012-03-02 18:26:30Z mike $".
- */
diff --git a/scheduler/cups.sh.in b/scheduler/cups.sh.in
index 133bca6..ff72c1c 100644
--- a/scheduler/cups.sh.in
+++ b/scheduler/cups.sh.in
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# "$Id: cups.sh.in 9949 2011-08-31 04:58:33Z mike $"
+# "$Id: cups.sh.in 11173 2013-07-23 12:31:34Z msweet $"
#
# Startup/shutdown script for CUPS.
#
@@ -233,5 +233,5 @@ exit 0
#
-# End of "$Id: cups.sh.in 9949 2011-08-31 04:58:33Z mike $".
+# End of "$Id: cups.sh.in 11173 2013-07-23 12:31:34Z msweet $".
#
diff --git a/scheduler/cups.xml.in b/scheduler/cups.xml.in
index ba614ce..b76ad02 100644
--- a/scheduler/cups.xml.in
+++ b/scheduler/cups.xml.in
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<!--
- $Id: cups.xml.in 9197 2010-07-08 17:23:08Z mike $
+ $Id: cups.xml.in 11173 2013-07-23 12:31:34Z msweet $
Service manifest for CUPS.
diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h
index 55d5ccb..48ea1d7 100644
--- a/scheduler/cupsd.h
+++ b/scheduler/cupsd.h
@@ -1,9 +1,9 @@
/*
- * "$Id: cupsd.h 9766 2011-05-11 22:17:34Z mike $"
+ * "$Id: cupsd.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Main header file for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -82,12 +82,10 @@ extern const char *cups_hstrerror(int);
* Defaults...
*/
-#define DEFAULT_HISTORY 1 /* Preserve job history? */
-#define DEFAULT_FILES 0 /* Preserve job files? */
+#define DEFAULT_HISTORY INT_MAX /* Preserve job history? */
+#define DEFAULT_FILES 86400 /* Preserve job files? */
#define DEFAULT_TIMEOUT 300 /* Timeout during requests/updates */
#define DEFAULT_KEEPALIVE 30 /* Timeout between requests */
-#define DEFAULT_INTERVAL 30 /* Interval between browse updates */
-#define DEFAULT_CHARSET "utf-8" /* Default charset */
/*
@@ -118,6 +116,7 @@ extern const char *cups_hstrerror(int);
#include "printers.h"
#include "classes.h"
#include "job.h"
+#include "colorman.h"
#include "conf.h"
#include "banners.h"
#include "dirsvc.h"
@@ -161,13 +160,6 @@ VAR int NeedReload VALUE(RELOAD_ALL),
VAR void *DefaultProfile VALUE(0);
/* Default security profile */
-#ifdef HAVE_GSSAPI
-VAR int KerberosInitialized VALUE(0);
- /* Has Kerberos been initialized? */
-VAR krb5_context KerberosContext VALUE(NULL);
- /* Kerberos context for credentials */
-#endif /* HAVE_GSSAPI */
-
#ifdef HAVE_LAUNCH_H
VAR int Launchd VALUE(0);
/* Running from launchd */
@@ -183,10 +175,7 @@ extern void cupsdInitEnv(void);
extern int cupsdLoadEnv(char *envp[], int envmax);
extern void cupsdSetEnv(const char *name, const char *value);
extern void cupsdSetEnvf(const char *name, const char *value, ...)
-#ifdef __GNUC__
-__attribute__ ((__format__ (__printf__, 2, 3)))
-#endif /* __GNUC__ */
-;
+ __attribute__ ((__format__ (__printf__, 2, 3)));
extern void cupsdUpdateEnv(void);
/* file.c */
@@ -210,10 +199,7 @@ extern char *cupsdMakeUUID(const char *name, int number,
extern void cupsdReleaseSignals(void);
extern void cupsdSetString(char **s, const char *v);
extern void cupsdSetStringf(char **s, const char *f, ...)
-#ifdef __GNUC__
-__attribute__ ((__format__ (__printf__, 2, 3)))
-#endif /* __GNUC__ */
-;
+ __attribute__ ((__format__ (__printf__, 2, 3)));
/* process.c */
extern void *cupsdCreateProfile(int job_id);
@@ -244,5 +230,5 @@ extern void cupsdStopServer(void);
/*
- * End of "$Id: cupsd.h 9766 2011-05-11 22:17:34Z mike $".
+ * End of "$Id: cupsd.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/cupsfilter.c b/scheduler/cupsfilter.c
index 9f21a52..4b471d5 100644
--- a/scheduler/cupsfilter.c
+++ b/scheduler/cupsfilter.c
@@ -1,9 +1,9 @@
/*
- * "$Id: cupsfilter.c 9862 2011-08-03 02:44:09Z mike $"
+ * "$Id: cupsfilter.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Filtering program for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2013 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -102,7 +102,7 @@ static int open_pipe(int *fds);
static int read_cupsd_conf(const char *filename);
static void set_string(char **s, const char *val);
static void sighandler(int sig);
-static void usage(const char *command, const char *opt);
+static void usage(const char *opt) __attribute__((noreturn));
/*
@@ -192,7 +192,7 @@ main(int argc, /* I - Number of command-line args */
if (i < argc && !infile)
infile = argv[i];
else
- usage(command, opt);
+ usage(opt);
break;
case 'a' : /* Specify option... */
@@ -200,7 +200,7 @@ main(int argc, /* I - Number of command-line args */
if (i < argc)
num_options = cupsParseOptions(argv[i], num_options, &options);
else
- usage(command, opt);
+ usage(opt);
break;
case 'c' : /* Specify cupsd.conf file location... */
@@ -214,7 +214,7 @@ main(int argc, /* I - Number of command-line args */
strlcpy(cupsdconf, argv[i], sizeof(cupsdconf));
}
else
- usage(command, opt);
+ usage(opt);
break;
case 'd' : /* Specify the real printer name */
@@ -222,7 +222,7 @@ main(int argc, /* I - Number of command-line args */
if (i < argc)
printer = argv[i];
else
- usage(command, opt);
+ usage(opt);
break;
case 'D' : /* Delete input file after conversion */
@@ -238,7 +238,7 @@ main(int argc, /* I - Number of command-line args */
if (i < argc && !infile)
infile = argv[i];
else
- usage(command, opt);
+ usage(opt);
break;
case 'i' : /* Specify source MIME type... */
@@ -246,12 +246,12 @@ main(int argc, /* I - Number of command-line args */
if (i < argc)
{
if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2)
- usage(command, opt);
+ usage(opt);
srctype = argv[i];
}
else
- usage(command, opt);
+ usage(opt);
break;
case 'j' : /* Get job file or specify destination MIME type... */
@@ -264,7 +264,7 @@ main(int argc, /* I - Number of command-line args */
infile = TempFile;
}
else
- usage(command, opt);
+ usage(opt);
break;
}
@@ -274,12 +274,12 @@ main(int argc, /* I - Number of command-line args */
if (i < argc)
{
if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2)
- usage(command, opt);
+ usage(opt);
dsttype = argv[i];
}
else
- usage(command, opt);
+ usage(opt);
break;
case 'n' : /* Specify number of copies... */
@@ -288,7 +288,7 @@ main(int argc, /* I - Number of command-line args */
num_options = cupsAddOption("copies", argv[i], num_options,
&options);
else
- usage(command, opt);
+ usage(opt);
break;
case 'o' : /* Specify option(s) or output filename */
@@ -298,7 +298,7 @@ main(int argc, /* I - Number of command-line args */
if (!strcmp(command, "convert"))
{
if (outfile)
- usage(command, NULL);
+ usage(NULL);
else
outfile = argv[i];
}
@@ -307,7 +307,7 @@ main(int argc, /* I - Number of command-line args */
&options);
}
else
- usage(command, opt);
+ usage(opt);
break;
case 'p' : /* Specify PPD file... */
@@ -316,7 +316,7 @@ main(int argc, /* I - Number of command-line args */
if (i < argc)
ppdfile = argv[i];
else
- usage(command, opt);
+ usage(opt);
break;
case 't' : /* Specify title... */
@@ -325,7 +325,7 @@ main(int argc, /* I - Number of command-line args */
if (i < argc)
title = argv[i];
else
- usage(command, opt);
+ usage(opt);
break;
case 'u' : /* Delete PPD file after conversion */
@@ -337,11 +337,11 @@ main(int argc, /* I - Number of command-line args */
if (i < argc)
user = argv[i];
else
- usage(command, opt);
+ usage(opt);
break;
default : /* Something we don't understand... */
- usage(command, opt);
+ usage(opt);
break;
}
}
@@ -350,22 +350,17 @@ main(int argc, /* I - Number of command-line args */
if (strcmp(command, "convert"))
infile = argv[i];
else
- {
- _cupsLangPuts(stderr,
- _("convert: Use the -f option to specify a file to "
- "convert."));
- usage(command, NULL);
- }
+ usage(NULL);
}
else
{
_cupsLangPuts(stderr,
_("cupsfilter: Only one filename can be specified."));
- usage(command, NULL);
+ usage(NULL);
}
if (!infile && !srctype)
- usage(command, NULL);
+ usage(NULL);
if (!title)
{
@@ -414,6 +409,7 @@ main(int argc, /* I - Number of command-line args */
if (srctype)
{
+ /* sscanf return value already checked above */
sscanf(srctype, "%15[^/]/%255s", super, type);
if ((src = mimeType(mime, super, type)) == NULL)
{
@@ -431,6 +427,7 @@ main(int argc, /* I - Number of command-line args */
return (1);
}
+ /* sscanf return value already checked above */
sscanf(dsttype, "%15[^/]/%255s", super, type);
if (!_cups_strcasecmp(super, "printer"))
dst = printer_type;
@@ -658,7 +655,7 @@ add_printer_filters(
mime_type_t *printer_type; /* Printer filter type */
- if ((ppd = ppdOpenFile(ppdfile)) == NULL)
+ if ((ppd = _ppdOpenFile(ppdfile, _PPD_LOCALIZATION_NONE)) == NULL)
{
ppd_status_t status; /* PPD load status */
int linenum; /* Line number */
@@ -920,7 +917,7 @@ exec_filters(mime_type_t *srctype, /* I - Source type */
{
int i; /* Looping var */
const char *argv[8], /* Command-line arguments */
- *envp[15], /* Environment variables */
+ *envp[16], /* Environment variables */
*temp; /* Temporary string */
char *optstr, /* Filter options */
content_type[1024], /* CONTENT_TYPE */
@@ -1043,7 +1040,8 @@ exec_filters(mime_type_t *srctype, /* I - Source type */
envp[11] = printer_name;
envp[12] = rip_max_cache;
envp[13] = userenv;
- envp[14] = NULL;
+ envp[14] = "CHARSET=utf-8";
+ envp[15] = NULL;
for (i = 0; argv[i]; i ++)
fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);
@@ -1425,70 +1423,41 @@ sighandler(int s) /* I - Signal number */
*/
static void
-usage(const char *command, /* I - Command name */
- const char *opt) /* I - Incorrect option, if any */
+usage(const char *opt) /* I - Incorrect option, if any */
{
if (opt)
- _cupsLangPrintf(stderr, _("%s: Unknown option \"%c\"."), command, *opt);
-
- if (!strcmp(command, "cupsfilter"))
- {
- _cupsLangPuts(stdout, _("Usage: cupsfilter [ options ] filename"));
- _cupsLangPuts(stdout, _("Options:"));
- _cupsLangPuts(stdout, _(" -D Remove the input file "
- "when finished."));
- _cupsLangPuts(stdout, _(" -P filename.ppd Set PPD file."));
- _cupsLangPuts(stdout, _(" -U username Set username for job."));
- _cupsLangPuts(stdout, _(" -c cupsd.conf Set cupsd.conf file to "
- "use."));
- _cupsLangPuts(stdout, _(" -d printer Use the named "
- "printer."));
- _cupsLangPuts(stdout, _(" -e Use every filter from "
- "the PPD file."));
- _cupsLangPuts(stdout, _(" -i mime/type Set input MIME type "
- "(otherwise auto-typed)."));
- _cupsLangPuts(stdout, _(" -j job-id[,N] Filter file N from the "
- "specified job (default is file 1)."));
- _cupsLangPuts(stdout, _(" -m mime/type Set output MIME type "
- "(otherwise application/pdf)."));
- _cupsLangPuts(stdout, _(" -n copies Set number of copies."));
- _cupsLangPuts(stdout, _(" -o name=value Set option(s)."));
- _cupsLangPuts(stdout, _(" -p filename.ppd Set PPD file."));
- _cupsLangPuts(stdout, _(" -t title Set title."));
- _cupsLangPuts(stdout, _(" -u Remove the PPD file "
- "when finished."));
- }
- else
- {
- _cupsLangPuts(stdout, _("Usage: convert [ options ]"));
- _cupsLangPuts(stdout, _("Options:"));
- _cupsLangPuts(stdout, _(" -D Remove the input file "
- "when finished."));
- _cupsLangPuts(stdout, _(" -J title Set title."));
- _cupsLangPuts(stdout, _(" -P filename.ppd Set PPD file."));
- _cupsLangPuts(stdout, _(" -U username Set username for job."));
- _cupsLangPuts(stdout, _(" -a 'name=value ...' Set option(s)."));
- _cupsLangPuts(stdout, _(" -c copies Set number of copies."));
- _cupsLangPuts(stdout, _(" -d printer Use the named "
- "printer."));
- _cupsLangPuts(stdout, _(" -e Use every filter from "
- "the PPD file."));
- _cupsLangPuts(stdout, _(" -f filename Set file to be "
- "converted (otherwise stdin)."));
- _cupsLangPuts(stdout, _(" -i mime/type Set input MIME type "
- "(otherwise auto-typed)."));
- _cupsLangPuts(stdout, _(" -j mime/type Set output MIME type "
- "(otherwise application/pdf)."));
- _cupsLangPuts(stdout, _(" -o filename Set file to be "
- "generated (otherwise stdout)."));
- _cupsLangPuts(stdout, _(" -u Remove the PPD file "
- "when finished."));
- }
+ _cupsLangPrintf(stderr, _("%s: Unknown option \"%c\"."), "cupsfilter",
+ *opt);
+
+ _cupsLangPuts(stdout, _("Usage: cupsfilter [ options ] filename"));
+ _cupsLangPuts(stdout, _("Options:"));
+ _cupsLangPuts(stdout, _(" -D Remove the input file "
+ "when finished."));
+ _cupsLangPuts(stdout, _(" -P filename.ppd Set PPD file."));
+ _cupsLangPuts(stdout, _(" -U username Specify username."));
+ _cupsLangPuts(stdout, _(" -c cupsd.conf Set cupsd.conf file to "
+ "use."));
+ _cupsLangPuts(stdout, _(" -d printer Use the named "
+ "printer."));
+ _cupsLangPuts(stdout, _(" -e Use every filter from "
+ "the PPD file."));
+ _cupsLangPuts(stdout, _(" -i mime/type Set input MIME type "
+ "(otherwise auto-typed)."));
+ _cupsLangPuts(stdout, _(" -j job-id[,N] Filter file N from the "
+ "specified job (default is file 1)."));
+ _cupsLangPuts(stdout, _(" -m mime/type Set output MIME type "
+ "(otherwise application/pdf)."));
+ _cupsLangPuts(stdout, _(" -n copies Set number of copies."));
+ _cupsLangPuts(stdout, _(" -o name=value Set option(s)."));
+ _cupsLangPuts(stdout, _(" -p filename.ppd Set PPD file."));
+ _cupsLangPuts(stdout, _(" -t title Set title."));
+ _cupsLangPuts(stdout, _(" -u Remove the PPD file "
+ "when finished."));
exit(1);
}
/*
- * End of "$Id: cupsfilter.c 9862 2011-08-03 02:44:09Z mike $".
+ * End of "$Id: cupsfilter.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c
index 00e8807..bce0d64 100644
--- a/scheduler/dirsvc.c
+++ b/scheduler/dirsvc.c
@@ -1,9 +1,9 @@
/*
- * "$Id: dirsvc.c 10243 2012-02-11 02:05:21Z mike $"
+ * "$Id: dirsvc.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Directory services routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -14,68 +14,33 @@
*
* 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 or update the broadcast contents.
- * cupsdRestartPolling() - Restart polling servers as needed.
- * cupsdSaveRemoteCache() - Save the remote printer cache.
- * cupsdSendBrowseList() - Send new browsing information as necessary.
- * ldap_rebind_proc() - Callback function for LDAP rebind
- * ldap_connect() - Start new LDAP connection
- * ldap_reconnect() - Reconnect to LDAP Server
- * ldap_disconnect() - Disconnect from LDAP Server
- * cupsdStartBrowsing() - Start sending and receiving broadcast
- * information.
- * cupsdStartPolling() - Start polling servers as needed.
- * cupsdStopBrowsing() - Stop sending and receiving broadcast
- * information.
- * cupsdStopPolling() - Stop polling servers as needed.
- * cupsdUpdateDNSSDName() - Update the computer name we use for
- * browsing...
- * cupsdUpdateLDAPBrowse() - Scan for new printers via LDAP...
- * cupsdUpdateSLPBrowse() - Get browsing information via SLP.
- * dequote() - Remote quotes from a string.
- * dnssdAddAlias() - Add a DNS-SD alias name.
- * dnssdBuildTxtRecord() - Build a TXT record from printer info.
- * dnssdComparePrinters() - Compare the registered names of two printers.
- * 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.
- * dnssdStop() - Stop all DNS-SD registrations.
- * dnssdUpdate() - Handle DNS-SD queries.
- * get_auth_info_required() - Get the auth-info-required value to advertise.
- * get_hostconfig() - Get an /etc/hostconfig service setting.
- * is_local_queue() - Determine whether the URI points at a local
- * queue.
- * process_browse_data() - Process new browse data.
- * process_implicit_classes() - Create/update implicit classes as needed.
- * send_cups_browse() - Send new browsing information using the CUPS
- * protocol.
- * ldap_search_rec() - LDAP Search with reconnect
- * ldap_freeres() - Free LDAPMessage
- * ldap_getval_char() - Get first LDAP value and convert to string
- * send_ldap_ou() - Send LDAP ou registrations.
- * send_ldap_browse() - Send LDAP printer registrations.
- * ldap_dereg_printer() - Delete printer from directory
- * ldap_dereg_ou() - Remove the organizational unit.
- * send_slp_browse() - Register the specified printer with SLP.
- * slp_attr_callback() - SLP attribute callback
- * slp_dereg_printer() - SLPDereg() the specified printer
- * slp_get_attr() - Get an attribute from an SLP registration.
- * slp_reg_callback() - Empty SLPRegReport.
- * slp_url_callback() - SLP service url callback
- * update_cups_browse() - Update the browse lists using the CUPS
- * protocol.
- * update_lpd() - Update the LPD configuration as needed.
- * update_polling() - Read status messages from the poll daemons.
- * update_smb() - Update the SMB configuration as needed.
+ * cupsdDeregisterPrinter() - Stop sending broadcast information for a local
+ * printer and remove any pending references to
+ * remote printers.
+ * cupsdRegisterPrinter() - Start sending broadcast information for a
+ * printer or update the broadcast contents.
+ * cupsdStartBrowsing() - Start sending and receiving broadcast
+ * information.
+ * cupsdStopBrowsing() - Stop sending and receiving broadcast
+ * information.
+ * cupsdUpdateDNSSDName() - Update the computer name we use for
+ * browsing...
+ * dnssdAddAlias() - Add a DNS-SD alias name.
+ * dnssdBuildTxtRecord() - Build a TXT record from printer info.
+ * dnssdDeregisterInstance() - Deregister a DNS-SD service instance.
+ * dnssdDeregisterPrinter() - Deregister all services for a printer.
+ * dnssdErrorString() - Return an error string for an error code.
+ * dnssdRegisterCallback() - Free a TXT record.
+ * dnssdRegisterCallback() - DNSServiceRegister callback.
+ * dnssdRegisterInstance() - Register an instance of a printer service.
+ * dnssdRegisterPrinter() - Start sending broadcast information for a
+ * printer or update the broadcast contents.
+ * dnssdStop() - Stop all DNS-SD registrations.
+ * dnssdUpdate() - Handle DNS-SD queries.
+ * get_auth_info_required() - Get the auth-info-required value to advertise.
+ * get_hostconfig() - Get an /etc/hostconfig service setting.
+ * update_lpd() - Update the LPD configuration as needed.
+ * update_smb() - Update the SMB configuration as needed.
*/
/*
@@ -85,153 +50,63 @@
#include "cupsd.h"
#include <grp.h>
-#ifdef HAVE_DNSSD
-# include <dns_sd.h>
-# ifdef __APPLE__
-# include <nameser.h>
-# ifdef HAVE_COREFOUNDATION
-# include <CoreFoundation/CoreFoundation.h>
-# endif /* HAVE_COREFOUNDATION */
-# ifdef HAVE_SYSTEMCONFIGURATION
-# include <SystemConfiguration/SystemConfiguration.h>
-# endif /* HAVE_SYSTEMCONFIGURATION */
-# endif /* __APPLE__ */
-#endif /* HAVE_DNSSD */
+#if defined(HAVE_DNSSD) && defined(__APPLE__)
+# include <nameser.h>
+# include <CoreFoundation/CoreFoundation.h>
+# include <SystemConfiguration/SystemConfiguration.h>
+#endif /* HAVE_DNSSD && __APPLE__ */
/*
* Local functions...
*/
-static char *dequote(char *d, const char *s, int dlen);
-static char *get_auth_info_required(cupsd_printer_t *p, char *buffer,
- size_t bufsize);
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+static char *get_auth_info_required(cupsd_printer_t *p,
+ char *buffer, size_t bufsize);
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
#ifdef __APPLE__
-static int get_hostconfig(const char *name);
+static int get_hostconfig(const char *name);
#endif /* __APPLE__ */
-static int is_local_queue(const char *uri, char *host, int hostlen,
- char *resource, int resourcelen);
-static void process_browse_data(const char *uri, const char *host,
- const char *resource, cups_ptype_t type,
- ipp_pstate_t state, const char *location,
- const char *info, const char *make_model,
- int num_attrs, cups_option_t *attrs);
-static void process_implicit_classes(void);
-static void send_cups_browse(cupsd_printer_t *p);
-#ifdef HAVE_LDAP
-static LDAP *ldap_connect(void);
-static LDAP *ldap_reconnect(void);
-static void ldap_disconnect(LDAP *ld);
-static int ldap_search_rec(LDAP *ld, char *base, int scope,
- char *filter, char *attrs[],
- int attrsonly, LDAPMessage **res);
-static int ldap_getval_firststring(LDAP *ld, LDAPMessage *entry,
- char *attr, char *retval,
- unsigned long maxsize);
-static void ldap_freeres(LDAPMessage *entry);
-static void send_ldap_ou(char *ou, char *basedn, char *descstring);
-static void send_ldap_browse(cupsd_printer_t *p);
-static void ldap_dereg_printer(cupsd_printer_t *p);
-static void ldap_dereg_ou(char *ou, char *basedn);
-# ifdef HAVE_LDAP_REBIND_PROC
-# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
- LDAP_CONST char *refsp,
- ber_tag_t request,
- ber_int_t msgid,
- void *params);
-# else
-static int ldap_rebind_proc(LDAP *RebindLDAPHandle,
- char **dnp,
- char **passwdp,
- int *authmethodp,
- int freeit,
- void *arg);
-# endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
-# endif /* HAVE_LDAP_REBIND_PROC */
-#endif /* HAVE_LDAP */
-#ifdef HAVE_LIBSLP
-static void send_slp_browse(cupsd_printer_t *p);
-#endif /* HAVE_LIBSLP */
-static void update_cups_browse(void);
-static void update_lpd(int onoff);
-static void update_polling(void);
-static void update_smb(int onoff);
-
-
-#ifdef HAVE_DNSSD
-# ifdef HAVE_COREFOUNDATION
-static void dnssdAddAlias(const void *key, const void *value,
- void *context);
-# endif /* HAVE_COREFOUNDATION */
-static char *dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
- int for_lpd);
-static int dnssdComparePrinters(cupsd_printer_t *a, cupsd_printer_t *b);
-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);
-static void dnssdStop(void);
-static void dnssdUpdate(void);
-#endif /* HAVE_DNSSD */
-
-#ifdef HAVE_LDAP
-static const char * const ldap_attrs[] =/* CUPS LDAP attributes */
- {
- "printerDescription",
- "printerLocation",
- "printerMakeAndModel",
- "printerType",
- "printerURI",
- NULL
- };
-#endif /* HAVE_LDAP */
-
-#ifdef HAVE_LIBSLP
-/*
- * SLP definitions...
- */
-
-/*
- * SLP service name for CUPS...
- */
-
-# define SLP_CUPS_SRVTYPE "service:printer"
-# define SLP_CUPS_SRVLEN 15
-
+static void update_lpd(int onoff);
+static void update_smb(int onoff);
-/*
- * Printer service URL structure
- */
-
-typedef struct _slpsrvurl_s /**** SLP URL list ****/
-{
- struct _slpsrvurl_s *next; /* Next URL in list */
- char url[HTTP_MAX_URI];
- /* URL */
-} slpsrvurl_t;
-
-
-/*
- * Local functions...
- */
-static SLPBoolean slp_attr_callback(SLPHandle hslp, const char *attrlist,
- SLPError errcode, void *cookie);
-static void slp_dereg_printer(cupsd_printer_t *p);
-static int slp_get_attr(const char *attrlist, const char *tag,
- char **valbuf);
-static void slp_reg_callback(SLPHandle hslp, SLPError errcode,
- void *cookie);
-static SLPBoolean slp_url_callback(SLPHandle hslp, const char *srvurl,
- unsigned short lifetime,
- SLPError errcode, void *cookie);
-#endif /* HAVE_LIBSLP */
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+# ifdef __APPLE__
+static void dnssdAddAlias(const void *key, const void *value,
+ void *context);
+# endif /* __APPLE__ */
+static cupsd_txt_t dnssdBuildTxtRecord(cupsd_printer_t *p, int for_lpd);
+static void dnssdDeregisterInstance(cupsd_srv_t *srv);
+static void dnssdDeregisterPrinter(cupsd_printer_t *p,
+ int clear_name);
+static const char *dnssdErrorString(int error);
+static void dnssdFreeTxtRecord(cupsd_txt_t *txt);
+# ifdef HAVE_DNSSD
+static void dnssdRegisterCallback(DNSServiceRef sdRef,
+ DNSServiceFlags flags,
+ DNSServiceErrorType errorCode,
+ const char *name,
+ const char *regtype,
+ const char *domain,
+ void *context);
+# else
+static void dnssdRegisterCallback(AvahiEntryGroup *p,
+ AvahiEntryGroupState state,
+ void *context);
+# endif /* HAVE_DNSSD */
+static int dnssdRegisterInstance(cupsd_srv_t *srv,
+ cupsd_printer_t *p,
+ char *name, const char *type,
+ const char *subtypes, int port,
+ cupsd_txt_t *txt, int commit);
+static void dnssdRegisterPrinter(cupsd_printer_t *p);
+static void dnssdStop(void);
+# ifdef HAVE_DNSSD
+static void dnssdUpdate(void);
+# endif /* HAVE_DNSSD */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
/*
@@ -254,430 +129,17 @@ cupsdDeregisterPrinter(
removeit);
if (!Browsing || !p->shared ||
- (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_SCANNER)))
+ (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
return;
/*
* Announce the deletion...
*/
- if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0)
- {
- 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_LDAP
- if (BrowseLocalProtocols & BROWSE_LDAP)
- ldap_dereg_printer(p);
-#endif /* HAVE_LDAP */
-
-#ifdef HAVE_DNSSD
- if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
- dnssdDeregisterPrinter(p);
-#endif /* HAVE_DNSSD */
-}
-
-
-/*
- * 'cupsdLoadRemoteCache()' - Load the remote printer cache.
- */
-
-void
-cupsdLoadRemoteCache(void)
-{
- int i; /* Looping var */
- cups_file_t *fp; /* remote.cache file */
- int linenum; /* Current line number */
- char line[4096], /* Line from file */
- *value, /* Pointer to value */
- *valueptr, /* Pointer into value */
- scheme[32], /* Scheme portion of URI */
- username[64], /* Username portion of URI */
- host[HTTP_MAX_HOST],
- /* Hostname portion of URI */
- resource[HTTP_MAX_URI];
- /* Resource portion of URI */
- int port; /* Port number */
- cupsd_printer_t *p; /* Current printer */
- time_t now; /* Current time */
-
-
- /*
- * Don't load the cache if the remote protocols are disabled...
- */
-
- if (!Browsing)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdLoadRemoteCache: Not loading remote cache.");
- return;
- }
-
- /*
- * Open the remote.cache file...
- */
-
- snprintf(line, sizeof(line), "%s/remote.cache", CacheDir);
- if ((fp = cupsdOpenConfFile(line)) == NULL)
- return;
-
- /*
- * Read printer configurations until we hit EOF...
- */
-
- linenum = 0;
- p = NULL;
- now = time(NULL);
-
- while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
- {
- /*
- * Decode the directive...
- */
-
- if (!_cups_strcasecmp(line, "<Printer") ||
- !_cups_strcasecmp(line, "<DefaultPrinter"))
- {
- /*
- * <Printer name> or <DefaultPrinter name>
- */
-
- if (p == NULL && value)
- {
- /*
- * Add the printer and a base file type...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdLoadRemoteCache: Loading printer %s...", value);
-
- if ((p = cupsdFindDest(value)) != NULL)
- {
- if (p->type & CUPS_PRINTER_CLASS)
- {
- cupsdLogMessage(CUPSD_LOG_WARN,
- "Cached remote printer \"%s\" conflicts with "
- "existing class!",
- value);
- p = NULL;
- continue;
- }
- }
- else
- p = cupsdAddPrinter(value);
-
- p->accepting = 1;
- p->state = IPP_PRINTER_IDLE;
- p->type |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED;
- p->browse_time = now;
- p->browse_expire = now + BrowseTimeout;
-
- /*
- * Set the default printer as needed...
- */
-
- if (!_cups_strcasecmp(line, "<DefaultPrinter"))
- DefaultPrinter = p;
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- break;
- }
- }
- else if (!_cups_strcasecmp(line, "<Class") ||
- !_cups_strcasecmp(line, "<DefaultClass"))
- {
- /*
- * <Class name> or <DefaultClass name>
- */
-
- if (p == NULL && value)
- {
- /*
- * Add the printer and a base file type...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdLoadRemoteCache: Loading class %s...", value);
-
- if ((p = cupsdFindDest(value)) != NULL)
- p->type = CUPS_PRINTER_CLASS;
- else
- p = cupsdAddClass(value);
-
- p->accepting = 1;
- p->state = IPP_PRINTER_IDLE;
- p->type |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED;
- p->browse_time = now;
- p->browse_expire = now + BrowseTimeout;
-
- /*
- * Set the default printer as needed...
- */
-
- if (!_cups_strcasecmp(line, "<DefaultClass"))
- DefaultPrinter = p;
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- break;
- }
- }
- else if (!_cups_strcasecmp(line, "</Printer>") ||
- !_cups_strcasecmp(line, "</Class>"))
- {
- if (p != NULL)
- {
- /*
- * Close out the current printer...
- */
-
- cupsdSetPrinterAttrs(p);
-
- p = NULL;
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else if (!p)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else if (!_cups_strcasecmp(line, "UUID"))
- {
- if (value && !strncmp(value, "urn:uuid:", 9))
- cupsdSetString(&(p->uuid), value);
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Bad UUID on line %d of remote.cache.", linenum);
- }
- else if (!_cups_strcasecmp(line, "Info"))
- {
- if (value)
- cupsdSetString(&p->info, value);
- }
- else if (!_cups_strcasecmp(line, "MakeModel"))
- {
- if (value)
- cupsdSetString(&p->make_model, value);
- }
- else if (!_cups_strcasecmp(line, "Location"))
- {
- if (value)
- cupsdSetString(&p->location, value);
- }
- else if (!_cups_strcasecmp(line, "DeviceURI"))
- {
- if (value)
- {
- httpSeparateURI(HTTP_URI_CODING_ALL, value, scheme, sizeof(scheme),
- username, sizeof(username), host, sizeof(host), &port,
- resource, sizeof(resource));
-
- cupsdSetString(&p->hostname, host);
- cupsdSetString(&p->uri, value);
- cupsdSetDeviceURI(p, value);
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else if (!_cups_strcasecmp(line, "Option") && value)
- {
- /*
- * Option name value
- */
-
- for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
-
- if (!*valueptr)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- else
- {
- for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0');
-
- p->num_options = cupsAddOption(value, valueptr, p->num_options,
- &(p->options));
- }
- }
- else if (!_cups_strcasecmp(line, "Reason"))
- {
- if (value)
- {
- for (i = 0 ; i < p->num_reasons; i ++)
- if (!strcmp(value, p->reasons[i]))
- break;
-
- if (i >= p->num_reasons &&
- p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
- {
- p->reasons[p->num_reasons] = _cupsStrAlloc(value);
- p->num_reasons ++;
- }
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else if (!_cups_strcasecmp(line, "State"))
- {
- /*
- * Set the initial queue state...
- */
-
- if (value && !_cups_strcasecmp(value, "idle"))
- p->state = IPP_PRINTER_IDLE;
- else if (value && !_cups_strcasecmp(value, "stopped"))
- {
- p->state = IPP_PRINTER_STOPPED;
- cupsdSetPrinterReasons(p, "+paused");
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else if (!_cups_strcasecmp(line, "StateMessage"))
- {
- /*
- * Set the initial queue state message...
- */
-
- if (value)
- strlcpy(p->state_message, value, sizeof(p->state_message));
- }
- else if (!_cups_strcasecmp(line, "Accepting"))
- {
- /*
- * Set the initial accepting state...
- */
-
- if (value &&
- (!_cups_strcasecmp(value, "yes") ||
- !_cups_strcasecmp(value, "on") ||
- !_cups_strcasecmp(value, "true")))
- p->accepting = 1;
- else if (value &&
- (!_cups_strcasecmp(value, "no") ||
- !_cups_strcasecmp(value, "off") ||
- !_cups_strcasecmp(value, "false")))
- p->accepting = 0;
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else if (!_cups_strcasecmp(line, "Type"))
- {
- if (value)
- p->type = atoi(value);
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else if (!_cups_strcasecmp(line, "BrowseTime"))
- {
- if (value)
- {
- time_t t = atoi(value);
-
- if (t > p->browse_expire)
- p->browse_expire = t;
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else if (!_cups_strcasecmp(line, "JobSheets"))
- {
- /*
- * Set the initial job sheets...
- */
-
- if (value)
- {
- for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
-
- if (*valueptr)
- *valueptr++ = '\0';
-
- cupsdSetString(&p->job_sheets[0], value);
-
- while (isspace(*valueptr & 255))
- valueptr ++;
-
- if (*valueptr)
- {
- for (value = valueptr; *valueptr && !isspace(*valueptr & 255); valueptr ++);
-
- if (*valueptr)
- *valueptr = '\0';
-
- cupsdSetString(&p->job_sheets[1], value);
- }
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else if (!_cups_strcasecmp(line, "AllowUser"))
- {
- if (value)
- {
- p->deny_users = 0;
- cupsdAddString(&(p->users), value);
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else if (!_cups_strcasecmp(line, "DenyUser"))
- {
- if (value)
- {
- p->deny_users = 1;
- cupsdAddString(&(p->users), value);
- }
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of remote.cache.", linenum);
- }
- else
- {
- /*
- * Something else we don't understand...
- */
-
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown configuration directive %s on line %d of remote.cache.",
- line, linenum);
- }
- }
-
- cupsFileClose(fp);
-
- /*
- * Do auto-classing if needed...
- */
-
- process_implicit_classes();
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
+ dnssdDeregisterPrinter(p, 1);
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
}
@@ -693,730 +155,14 @@ cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
p->name);
if (!Browsing || !BrowseLocalProtocols ||
- (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_SCANNER)))
+ (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
return;
-#ifdef HAVE_LIBSLP
-/* if (BrowseLocalProtocols & BROWSE_SLP)
- slpRegisterPrinter(p); */
-#endif /* HAVE_LIBSLP */
-
-#ifdef HAVE_DNSSD
- if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
dnssdRegisterPrinter(p);
-#endif /* HAVE_DNSSD */
-}
-
-
-/*
- * 'cupsdRestartPolling()' - Restart polling servers as needed.
- */
-
-void
-cupsdRestartPolling(void)
-{
- int i; /* Looping var */
- cupsd_dirsvc_poll_t *pollp; /* Current polling server */
-
-
- for (i = 0, pollp = Polled; i < NumPolled; i ++, pollp ++)
- if (pollp->pid)
- kill(pollp->pid, SIGHUP);
-}
-
-
-/*
- * 'cupsdSaveRemoteCache()' - Save the remote printer cache.
- */
-
-void
-cupsdSaveRemoteCache(void)
-{
- int i; /* Looping var */
- cups_file_t *fp; /* remote.cache file */
- char filename[1024], /* remote.cache filename */
- temp[1024], /* Temporary string */
- value[2048], /* Value string */
- *name; /* Current user name */
- cupsd_printer_t *printer; /* Current printer class */
- time_t curtime; /* Current time */
- struct tm *curdate; /* Current date */
- cups_option_t *option; /* Current option */
-
-
- /*
- * Create the remote.cache file...
- */
-
- snprintf(filename, sizeof(filename), "%s/remote.cache", CacheDir);
-
- if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm)) == NULL)
- return;
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Saving remote.cache...");
-
- /*
- * Write a small header to the file...
- */
-
- curtime = time(NULL);
- curdate = localtime(&curtime);
- strftime(temp, sizeof(temp) - 1, "%Y-%m-%d %H:%M", curdate);
-
- cupsFilePuts(fp, "# Remote cache file for " CUPS_SVERSION "\n");
- cupsFilePrintf(fp, "# Written by cupsd on %s\n", temp);
-
- /*
- * Write each local printer known to the system...
- */
-
- for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
- printer;
- printer = (cupsd_printer_t *)cupsArrayNext(Printers))
- {
- /*
- * Skip local destinations...
- */
-
- if (!(printer->type & CUPS_PRINTER_DISCOVERED))
- continue;
-
- /*
- * Write printers as needed...
- */
-
- if (printer == DefaultPrinter)
- cupsFilePuts(fp, "<Default");
- else
- cupsFilePutChar(fp, '<');
-
- if (printer->type & CUPS_PRINTER_CLASS)
- cupsFilePrintf(fp, "Class %s>\n", printer->name);
- else
- cupsFilePrintf(fp, "Printer %s>\n", printer->name);
-
- cupsFilePrintf(fp, "BrowseTime %d\n", (int)printer->browse_expire);
-
- cupsFilePrintf(fp, "UUID %s\n", printer->uuid);
-
- if (printer->info)
- cupsFilePutConf(fp, "Info", printer->info);
-
- if (printer->location)
- cupsFilePutConf(fp, "Location", printer->location);
-
- if (printer->make_model)
- cupsFilePutConf(fp, "MakeModel", printer->make_model);
-
- cupsFilePutConf(fp, "DeviceURI", printer->device_uri);
-
- if (printer->state == IPP_PRINTER_STOPPED)
- cupsFilePuts(fp, "State Stopped\n");
- else
- cupsFilePuts(fp, "State Idle\n");
-
- for (i = 0; i < printer->num_reasons; i ++)
- cupsFilePutConf(fp, "Reason", printer->reasons[i]);
-
- cupsFilePrintf(fp, "Type %d\n", printer->type);
-
- if (printer->accepting)
- cupsFilePuts(fp, "Accepting Yes\n");
- else
- cupsFilePuts(fp, "Accepting No\n");
-
- snprintf(value, sizeof(value), "%s %s", printer->job_sheets[0],
- printer->job_sheets[1]);
- cupsFilePutConf(fp, "JobSheets", value);
-
- for (name = (char *)cupsArrayFirst(printer->users);
- name;
- name = (char *)cupsArrayNext(printer->users))
- cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser", name);
-
- for (i = printer->num_options, option = printer->options;
- i > 0;
- i --, option ++)
- {
- snprintf(value, sizeof(value), "%s %s", option->name, option->value);
- cupsFilePutConf(fp, "Option", value);
- }
-
- if (printer->type & CUPS_PRINTER_CLASS)
- cupsFilePuts(fp, "</Class>\n");
- else
- cupsFilePuts(fp, "</Printer>\n");
- }
-
- cupsdCloseCreatedConfFile(fp, filename);
-}
-
-
-/*
- * 'cupsdSendBrowseList()' - Send new browsing information as necessary.
- */
-
-void
-cupsdSendBrowseList(void)
-{
- int count; /* Number of dests to update */
- cupsd_printer_t *p; /* Current printer */
- time_t ut, /* Minimum update time */
- to; /* Timeout time */
-
-
- if (!Browsing || !Printers)
- return;
-
- /*
- * Compute the update and timeout times...
- */
-
- to = time(NULL);
- ut = to - BrowseInterval;
-
- /*
- * Figure out how many printers need an update...
- */
-
- if (BrowseInterval > 0 && BrowseLocalProtocols)
- {
- int max_count; /* Maximum number to update */
-
-
- /*
- * Throttle the number of printers we'll be updating this time
- * around based on the number of queues that need updating and
- * the maximum number of queues to update each second...
- */
-
- max_count = 2 * cupsArrayCount(Printers) / BrowseInterval + 1;
-
- for (count = 0, p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- count < max_count && p != NULL;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_SCANNER)) &&
- p->shared && p->browse_time < ut)
- count ++;
-
- /*
- * Loop through all of the printers and send local updates as needed...
- */
-
- if (BrowseNext)
- p = (cupsd_printer_t *)cupsArrayFind(Printers, BrowseNext);
- else
- p = (cupsd_printer_t *)cupsArrayFirst(Printers);
-
- for (;
- count > 0;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- {
- /*
- * Check for wraparound...
- */
-
- if (!p)
- p = (cupsd_printer_t *)cupsArrayFirst(Printers);
-
- if (!p)
- break;
- else if ((p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_SCANNER)) ||
- !p->shared)
- continue;
- else if (p->browse_time < ut)
- {
- /*
- * Need to send an update...
- */
-
- count --;
-
- p->browse_time = time(NULL);
-
- if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0)
- send_cups_browse(p);
-
-#ifdef HAVE_LIBSLP
- if (BrowseLocalProtocols & BROWSE_SLP)
- send_slp_browse(p);
-#endif /* HAVE_LIBSLP */
-
-#ifdef HAVE_LDAP
- if (BrowseLocalProtocols & BROWSE_LDAP)
- send_ldap_browse(p);
-#endif /* HAVE_LDAP */
- }
- }
-
- /*
- * Save where we left off so that all printers get updated...
- */
-
- BrowseNext = p;
- }
-
- /*
- * Loop through all of the printers and timeout old printers as needed...
- */
-
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- {
- /*
- * If this is a remote queue, see if it needs to be timed out...
- */
-
- if ((p->type & CUPS_PRINTER_DISCOVERED) &&
- !(p->type & CUPS_PRINTER_IMPLICIT) &&
- p->browse_expire < to)
- {
- cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, p, NULL,
- "%s \'%s\' deleted by directory services (timeout).",
- (p->type & CUPS_PRINTER_CLASS) ? "Class" : "Printer",
- p->name);
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Remote destination \"%s\" has timed out; "
- "deleting it...",
- p->name);
-
- cupsArraySave(Printers);
- cupsdDeletePrinter(p, 1);
- cupsArrayRestore(Printers);
- cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP | CUPSD_DIRTY_REMOTE);
- }
- }
-}
-
-
-#ifdef HAVE_LDAP_REBIND_PROC
-# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-/*
- * 'ldap_rebind_proc()' - Callback function for LDAP rebind
- */
-
-static int /* O - Result code */
-ldap_rebind_proc(
- LDAP *RebindLDAPHandle, /* I - LDAP handle */
- LDAP_CONST char *refsp, /* I - ??? */
- ber_tag_t request, /* I - ??? */
- ber_int_t msgid, /* I - ??? */
- void *params) /* I - ??? */
-{
- int rc; /* Result code */
-# if LDAP_API_VERSION > 3000
- struct berval bval; /* Bind value */
-# endif /* LDAP_API_VERSION > 3000 */
-
-
- (void)request;
- (void)msgid;
- (void)params;
-
- /*
- * Bind to new LDAP server...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_rebind_proc: Rebind to %s", refsp);
-
-# if LDAP_API_VERSION > 3000
- bval.bv_val = BrowseLDAPPassword;
- bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword);
-
- rc = ldap_sasl_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE,
- &bval, NULL, NULL, NULL);
-# else
- rc = ldap_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, BrowseLDAPPassword,
- LDAP_AUTH_SIMPLE);
-# endif /* LDAP_API_VERSION > 3000 */
-
- return (rc);
-}
-
-
-# else /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
-/*
- * 'ldap_rebind_proc()' - Callback function for LDAP rebind
- */
-
-static int /* O - Result code */
-ldap_rebind_proc(
- LDAP *RebindLDAPHandle, /* I - LDAP handle */
- char **dnp, /* I - ??? */
- char **passwdp, /* I - ??? */
- int *authmethodp, /* I - ??? */
- int freeit, /* I - ??? */
- void *arg) /* I - ??? */
-{
- switch (freeit)
- {
- case 1:
- /*
- * Free current values...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_rebind_proc: Free values...");
-
- if (dnp && *dnp)
- free(*dnp);
-
- if (passwdp && *passwdp)
- free(*passwdp);
- break;
-
- case 0:
- /*
- * Return credentials for LDAP referal...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "ldap_rebind_proc: Return necessary values...");
-
- *dnp = strdup(BrowseLDAPBindDN);
- *passwdp = strdup(BrowseLDAPPassword);
- *authmethodp = LDAP_AUTH_SIMPLE;
- break;
-
- default:
- /*
- * Should never happen...
- */
-
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "LDAP rebind has been called with wrong freeit value!");
- break;
- }
-
- return (LDAP_SUCCESS);
-}
-# endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
-#endif /* HAVE_LDAP_REBIND_PROC */
-
-
-#ifdef HAVE_LDAP
-/*
- * 'ldap_connect()' - Start new LDAP connection
- */
-
-static LDAP * /* O - LDAP handle */
-ldap_connect(void)
-{
- int rc; /* LDAP API status */
- int version = 3; /* LDAP version */
- struct berval bv = {0, ""}; /* SASL bind value */
- LDAP *TempBrowseLDAPHandle=NULL;
- /* Temporary LDAP Handle */
-# if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
- int ldap_ssl = 0; /* LDAP SSL indicator */
- int ssl_err = 0; /* LDAP SSL error value */
-# endif /* defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) */
-
-
-# ifdef HAVE_OPENLDAP
-# ifdef HAVE_LDAP_SSL
- /*
- * Set the certificate file to use for encrypted LDAP sessions...
- */
-
- if (BrowseLDAPCACertFile)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "ldap_connect: Setting CA certificate file \"%s\"",
- BrowseLDAPCACertFile);
-
- if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
- (void *)BrowseLDAPCACertFile)) != LDAP_SUCCESS)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to set CA certificate file for LDAP "
- "connections: %d - %s", rc, ldap_err2string(rc));
- }
-# endif /* HAVE_LDAP_SSL */
-
- /*
- * Initialize OPENLDAP connection...
- * LDAP stuff currently only supports ldapi EXTERNAL SASL binds...
- */
-
- if (!BrowseLDAPServer || !_cups_strcasecmp(BrowseLDAPServer, "localhost"))
- rc = ldap_initialize(&TempBrowseLDAPHandle, "ldapi:///");
- else
- rc = ldap_initialize(&TempBrowseLDAPHandle, BrowseLDAPServer);
-
-# else /* HAVE_OPENLDAP */
-
- int ldap_port = 0; /* LDAP port */
- char ldap_protocol[11], /* LDAP protocol */
- ldap_host[255]; /* LDAP host */
-
- /*
- * Split LDAP URI into its components...
- */
-
- if (!BrowseLDAPServer)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "BrowseLDAPServer not configured!");
- cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!");
- BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
- return (NULL);
- }
-
- sscanf(BrowseLDAPServer, "%10[^:]://%254[^:/]:%d", ldap_protocol, ldap_host,
- &ldap_port);
-
- if (!strcmp(ldap_protocol, "ldap"))
- ldap_ssl = 0;
- else if (!strcmp(ldap_protocol, "ldaps"))
- ldap_ssl = 1;
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unrecognized LDAP protocol (%s)!",
- ldap_protocol);
- cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!");
- BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
- return (NULL);
- }
-
- if (ldap_port == 0)
- {
- if (ldap_ssl)
- ldap_port = LDAPS_PORT;
- else
- ldap_port = LDAP_PORT;
- }
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "ldap_connect: PROT:%s HOST:%s PORT:%d",
- ldap_protocol, ldap_host, ldap_port);
-
- /*
- * Initialize LDAP connection...
- */
-
- if (!ldap_ssl)
- {
- if ((TempBrowseLDAPHandle = ldap_init(ldap_host, ldap_port)) == NULL)
- rc = LDAP_OPERATIONS_ERROR;
- else
- rc = LDAP_SUCCESS;
-
-# ifdef HAVE_LDAP_SSL
- }
- else
- {
- /*
- * Initialize SSL LDAP connection...
- */
-
- if (BrowseLDAPCACertFile)
- {
- rc = ldapssl_client_init(BrowseLDAPCACertFile, (void *)NULL);
- if (rc != LDAP_SUCCESS)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Failed to initialize LDAP SSL client!");
- rc = LDAP_OPERATIONS_ERROR;
- }
- else
- {
- if ((TempBrowseLDAPHandle = ldapssl_init(ldap_host, ldap_port,
- 1)) == NULL)
- rc = LDAP_OPERATIONS_ERROR;
- else
- rc = LDAP_SUCCESS;
- }
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "LDAP SSL certificate file/database not configured!");
- rc = LDAP_OPERATIONS_ERROR;
- }
-
-# else /* HAVE_LDAP_SSL */
-
- /*
- * Return error, because client libraries doesn't support SSL
- */
-
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "LDAP client libraries do not support SSL");
- rc = LDAP_OPERATIONS_ERROR;
-
-# endif /* HAVE_LDAP_SSL */
- }
-# endif /* HAVE_OPENLDAP */
-
- /*
- * Check return code from LDAP initialize...
- */
-
- if (rc != LDAP_SUCCESS)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize LDAP!");
-
- if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
- cupsdLogMessage(CUPSD_LOG_ERROR, "Temporarily disabling LDAP browsing...");
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!");
-
- BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
- }
-
- ldap_disconnect(TempBrowseLDAPHandle);
-
- return (NULL);
- }
-
- /*
- * Upgrade LDAP version...
- */
-
- if (ldap_set_option(TempBrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION,
- (const void *)&version) != LDAP_SUCCESS)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to set LDAP protocol version %d!",
- version);
- cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!");
-
- BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
- ldap_disconnect(TempBrowseLDAPHandle);
-
- return (NULL);
- }
-
- /*
- * Register LDAP rebind procedure...
- */
-
-# ifdef HAVE_LDAP_REBIND_PROC
-# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-
- rc = ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc,
- (void *)NULL);
- if (rc != LDAP_SUCCESS)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Setting LDAP rebind function failed with status %d: %s",
- rc, ldap_err2string(rc));
-
-# else
-
- ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc, (void *)NULL);
-
-# endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */
-# endif /* HAVE_LDAP_REBIND_PROC */
-
- /*
- * Start LDAP bind...
- */
-
-# if LDAP_API_VERSION > 3000
- struct berval bval;
- bval.bv_val = BrowseLDAPPassword;
- bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword);
-
- if (!BrowseLDAPServer || !_cups_strcasecmp(BrowseLDAPServer, "localhost"))
- rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL,
- NULL, NULL);
- else
- rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE, &bval, NULL, NULL, NULL);
-
-# else
- rc = ldap_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN,
- BrowseLDAPPassword, LDAP_AUTH_SIMPLE);
-# endif /* LDAP_API_VERSION > 3000 */
-
- if (rc != LDAP_SUCCESS)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "LDAP bind failed with error %d: %s",
- rc, ldap_err2string(rc));
-
-# if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP)
- if (ldap_ssl && (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR))
- {
- ssl_err = PORT_GetError();
- if (ssl_err != 0)
- cupsdLogMessage(CUPSD_LOG_ERROR, "LDAP SSL error %d: %s", ssl_err,
- ldapssl_err2string(ssl_err));
- }
-# endif /* defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) */
-
- ldap_disconnect(TempBrowseLDAPHandle);
-
- return (NULL);
- }
-
- cupsdLogMessage(CUPSD_LOG_INFO, "LDAP connection established");
-
- return (TempBrowseLDAPHandle);
-}
-
-
-/*
- * 'ldap_reconnect()' - Reconnect to LDAP Server
- */
-
-static LDAP * /* O - New LDAP handle */
-ldap_reconnect(void)
-{
- LDAP *TempBrowseLDAPHandle = NULL; /* Temp Handle to LDAP server */
-
-
- /*
- * Get a new LDAP Handle and replace the global Handle
- * if the new connection was successful.
- */
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Try LDAP reconnect...");
-
- TempBrowseLDAPHandle = ldap_connect();
-
- if (TempBrowseLDAPHandle != NULL)
- {
- if (BrowseLDAPHandle != NULL)
- ldap_disconnect(BrowseLDAPHandle);
-
- BrowseLDAPHandle = TempBrowseLDAPHandle;
- }
-
- return (BrowseLDAPHandle);
-}
-
-
-/*
- * 'ldap_disconnect()' - Disconnect from LDAP Server
- */
-
-static void
-ldap_disconnect(LDAP *ld) /* I - LDAP handle */
-{
- int rc; /* Return code */
-
-
- /*
- * Close LDAP handle...
- */
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- rc = ldap_unbind_ext_s(ld, NULL, NULL);
-# else
- rc = ldap_unbind_s(ld);
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
-
- if (rc != LDAP_SUCCESS)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unbind from LDAP server failed with status %d: %s",
- rc, ldap_err2string(rc));
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
}
-#endif /* HAVE_LDAP */
/*
@@ -1426,134 +172,24 @@ ldap_disconnect(LDAP *ld) /* I - LDAP handle */
void
cupsdStartBrowsing(void)
{
- int val; /* Socket option value */
- struct sockaddr_in addr; /* Broadcast address */
cupsd_printer_t *p; /* Current printer */
- BrowseNext = NULL;
-
- if (!Browsing || !(BrowseLocalProtocols | BrowseRemoteProtocols))
+ if (!Browsing || !BrowseLocalProtocols)
return;
- if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_CUPS)
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ if (BrowseLocalProtocols & BROWSE_DNSSD)
{
- if (BrowseSocket < 0)
- {
- /*
- * Create the broadcast socket...
- */
-
- if ((BrowseSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create broadcast socket - %s.",
- strerror(errno));
- BrowseLocalProtocols &= ~BROWSE_CUPS;
- BrowseRemoteProtocols &= ~BROWSE_CUPS;
-
- if (FatalErrors & CUPSD_FATAL_BROWSE)
- cupsdEndProcess(getpid(), 0);
- }
- }
-
- if (BrowseSocket >= 0)
- {
- /*
- * Bind the socket to browse port...
- */
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- addr.sin_family = AF_INET;
- addr.sin_port = htons(BrowsePort);
-
- if (bind(BrowseSocket, (struct sockaddr *)&addr, sizeof(addr)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to bind broadcast socket - %s.",
- strerror(errno));
-
-#ifdef WIN32
- closesocket(BrowseSocket);
-#else
- close(BrowseSocket);
-#endif /* WIN32 */
-
- BrowseSocket = -1;
- BrowseLocalProtocols &= ~BROWSE_CUPS;
- BrowseRemoteProtocols &= ~BROWSE_CUPS;
-
- if (FatalErrors & CUPSD_FATAL_BROWSE)
- cupsdEndProcess(getpid(), 0);
- }
- }
-
- if (BrowseSocket >= 0)
- {
- /*
- * Set the "broadcast" flag...
- */
-
- val = 1;
- if (setsockopt(BrowseSocket, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to set broadcast mode - %s.",
- strerror(errno));
-
-#ifdef WIN32
- closesocket(BrowseSocket);
-#else
- close(BrowseSocket);
-#endif /* WIN32 */
-
- BrowseSocket = -1;
- BrowseLocalProtocols &= ~BROWSE_CUPS;
- BrowseRemoteProtocols &= ~BROWSE_CUPS;
-
- if (FatalErrors & CUPSD_FATAL_BROWSE)
- cupsdEndProcess(getpid(), 0);
- }
- }
-
- if (BrowseSocket >= 0)
- {
- /*
- * Close the socket on exec...
- */
-
- fcntl(BrowseSocket, F_SETFD, fcntl(BrowseSocket, F_GETFD) | FD_CLOEXEC);
-
- /*
- * Finally, add the socket to the input selection set as needed...
- */
-
- if (BrowseRemoteProtocols & BROWSE_CUPS)
- {
- /*
- * We only listen if we want remote printers...
- */
-
- cupsdAddSelect(BrowseSocket, (cupsd_selfunc_t)update_cups_browse,
- NULL, NULL);
- }
- }
- }
- else
- BrowseSocket = -1;
-
-#ifdef HAVE_DNSSD
- if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_DNSSD)
- {
- DNSServiceErrorType error; /* Error from service creation */
cupsd_listener_t *lis; /* Current listening socket */
-
+# ifdef HAVE_DNSSD
+ DNSServiceErrorType error; /* Error from service creation */
/*
* First create a "master" connection for all registrations...
*/
- if ((error = DNSServiceCreateConnection(&DNSSDRef))
+ if ((error = DNSServiceCreateConnection(&DNSSDMaster))
!= kDNSServiceErr_NoError)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
@@ -1568,100 +204,71 @@ cupsdStartBrowsing(void)
* Add the master connection to the select list...
*/
- int fd = DNSServiceRefSockFD(DNSSDRef);
+ int fd = DNSServiceRefSockFD(DNSSDMaster);
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
+ }
- /*
- * Then get the port we use for registrations. If we are not listening
- * on any non-local ports, there is no sense sharing local printers via
- * Bonjour...
- */
-
- DNSSDPort = 0;
-
- for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
- lis;
- lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
- {
- if (httpAddrLocalhost(&(lis->address)))
- continue;
+# else /* HAVE_AVAHI */
+ if ((DNSSDMaster = avahi_threaded_poll_new()) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create DNS-SD thread.");
- DNSSDPort = _httpAddrPort(&(lis->address));
- break;
- }
+ if (FatalErrors & CUPSD_FATAL_BROWSE)
+ cupsdEndProcess(getpid(), 0);
+ }
+ else
+ {
+ int error; /* Error code, if any */
- /*
- * Create an array to track the printers we share...
- */
+ DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), 0,
+ NULL, NULL, &error);
- if (BrowseRemoteProtocols & BROWSE_DNSSD)
- DNSSDPrinters = cupsArrayNew((cups_array_func_t)dnssdComparePrinters,
- NULL);
+ if (DNSSDClient == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to communicate with avahi-daemon: %s",
+ dnssdErrorString(error));
- /*
- * Set the computer name and register the web interface...
- */
+ if (FatalErrors & CUPSD_FATAL_BROWSE)
+ cupsdEndProcess(getpid(), 0);
- cupsdUpdateDNSSDName();
+ avahi_threaded_poll_free(DNSSDMaster);
+ DNSSDMaster = NULL;
+ }
+ else
+ avahi_threaded_poll_start(DNSSDMaster);
}
- }
-#endif /* HAVE_DNSSD */
+# endif /* HAVE_DNSSD */
-#ifdef HAVE_LIBSLP
- if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP)
- {
/*
- * Open SLP handle...
+ * Then get the port we use for registrations. If we are not listening
+ * on any non-local ports, there is no sense sharing local printers via
+ * Bonjour...
*/
- if (SLPOpen("en", SLP_FALSE, &BrowseSLPHandle) != SLP_OK)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to open an SLP handle; disabling SLP browsing!");
- BrowseLocalProtocols &= ~BROWSE_SLP;
- BrowseRemoteProtocols &= ~BROWSE_SLP;
- BrowseSLPHandle = NULL;
+ DNSSDPort = 0;
- if (FatalErrors & CUPSD_FATAL_BROWSE)
- cupsdEndProcess(getpid(), 0);
- }
-
- BrowseSLPRefresh = 0;
- }
- else
- BrowseSLPHandle = NULL;
-#endif /* HAVE_LIBSLP */
-
-#ifdef HAVE_LDAP
- if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP)
- {
- if (!BrowseLDAPDN)
+ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
+ lis;
+ lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Need to set BrowseLDAPDN to use LDAP browsing!");
- BrowseLocalProtocols &= ~BROWSE_LDAP;
- BrowseRemoteProtocols &= ~BROWSE_LDAP;
+ if (httpAddrLocalhost(&(lis->address)))
+ continue;
- if (FatalErrors & CUPSD_FATAL_BROWSE)
- cupsdEndProcess(getpid(), 0);
+ DNSSDPort = _httpAddrPort(&(lis->address));
+ break;
}
- else
- {
- /*
- * Open LDAP handle...
- */
- if ((BrowseLDAPHandle = ldap_connect()) == NULL &&
- (FatalErrors & CUPSD_FATAL_BROWSE))
- cupsdEndProcess(getpid(), 0);
- }
+ /*
+ * Set the computer name and register the web interface...
+ */
- BrowseLDAPRefresh = 0;
+ cupsdUpdateDNSSDName();
}
-#endif /* HAVE_LDAP */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
/*
* Enable LPD and SMB printer sharing as needed through external programs...
@@ -1680,116 +287,12 @@ cupsdStartBrowsing(void)
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_SCANNER)))
+ if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
cupsdRegisterPrinter(p);
}
/*
- * 'cupsdStartPolling()' - Start polling servers as needed.
- */
-
-void
-cupsdStartPolling(void)
-{
- int i; /* Looping var */
- cupsd_dirsvc_poll_t *pollp; /* Current polling server */
- char polld[1024]; /* Poll daemon path */
- char sport[255]; /* Server port */
- char bport[255]; /* Browser port */
- char interval[255]; /* Poll interval */
- int statusfds[2]; /* Status pipe */
- char *argv[6]; /* Arguments */
- char *envp[100]; /* Environment */
-
-
- /*
- * Don't do anything if we aren't polling...
- */
-
- if (NumPolled == 0 || BrowseSocket < 0)
- {
- PollPipe = -1;
- PollStatusBuffer = NULL;
- return;
- }
-
- /*
- * Setup string arguments for polld, port and interval options.
- */
-
- snprintf(polld, sizeof(polld), "%s/daemon/cups-polld", ServerBin);
-
- sprintf(bport, "%d", BrowsePort);
-
- if (BrowseInterval)
- sprintf(interval, "%d", BrowseInterval);
- else
- strcpy(interval, "30");
-
- argv[0] = "cups-polld";
- argv[2] = sport;
- argv[3] = interval;
- argv[4] = bport;
- argv[5] = NULL;
-
- cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
-
- /*
- * Create a pipe that receives the status messages from each
- * polling daemon...
- */
-
- if (cupsdOpenPipe(statusfds))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create polling status pipes - %s.",
- strerror(errno));
- PollPipe = -1;
- PollStatusBuffer = NULL;
- return;
- }
-
- PollPipe = statusfds[0];
- PollStatusBuffer = cupsdStatBufNew(PollPipe, "[Poll]");
-
- /*
- * Run each polling daemon, redirecting stderr to the polling pipe...
- */
-
- for (i = 0, pollp = Polled; i < NumPolled; i ++, pollp ++)
- {
- sprintf(sport, "%d", pollp->port);
-
- argv[1] = pollp->hostname;
-
- if (cupsdStartProcess(polld, argv, envp, -1, -1, statusfds[1], -1, -1,
- 0, DefaultProfile, NULL, &(pollp->pid)) < 0)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdStartPolling: Unable to fork polling daemon - %s",
- strerror(errno));
- pollp->pid = 0;
- break;
- }
- else
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdStartPolling: Started polling daemon for %s:%d, pid = %d",
- pollp->hostname, pollp->port, pollp->pid);
- }
-
- close(statusfds[1]);
-
- /*
- * Finally, add the pipe to the input selection set...
- */
-
- cupsdAddSelect(PollPipe, (cupsd_selfunc_t)update_polling, NULL, NULL);
-}
-
-
-/*
* 'cupsdStopBrowsing()' - Stop sending and receiving broadcast information.
*/
@@ -1799,7 +302,7 @@ cupsdStopBrowsing(void)
cupsd_printer_t *p; /* Current printer */
- if (!Browsing || !(BrowseLocalProtocols | BrowseRemoteProtocols))
+ if (!Browsing || !BrowseLocalProtocols)
return;
/*
@@ -1809,58 +312,17 @@ cupsdStopBrowsing(void)
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_SCANNER)))
+ if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
cupsdDeregisterPrinter(p, 1);
/*
* Shut down browsing sockets...
*/
- if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_CUPS) &&
- BrowseSocket >= 0)
- {
- /*
- * Close the socket and remove it from the input selection set.
- */
-
-#ifdef WIN32
- closesocket(BrowseSocket);
-#else
- close(BrowseSocket);
-#endif /* WIN32 */
-
- cupsdRemoveSelect(BrowseSocket);
- BrowseSocket = -1;
- }
-
-#ifdef HAVE_DNSSD
- if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
dnssdStop();
-#endif /* HAVE_DNSSD */
-
-#ifdef HAVE_LIBSLP
- if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) &&
- BrowseSLPHandle)
- {
- /*
- * Close SLP handle...
- */
-
- SLPClose(BrowseSLPHandle);
- BrowseSLPHandle = NULL;
- }
-#endif /* HAVE_LIBSLP */
-
-#ifdef HAVE_LDAP
- if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) &&
- BrowseLDAPHandle)
- {
- ldap_dereg_ou(ServerName, BrowseLDAPDN);
- ldap_disconnect(BrowseLDAPHandle);
- BrowseLDAPHandle = NULL;
- }
-#endif /* HAVE_OPENLDAP */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
/*
* Disable LPD and SMB printer sharing as needed through external programs...
@@ -1874,35 +336,7 @@ cupsdStopBrowsing(void)
}
-/*
- * 'cupsdStopPolling()' - Stop polling servers as needed.
- */
-
-void
-cupsdStopPolling(void)
-{
- int i; /* Looping var */
- cupsd_dirsvc_poll_t *pollp; /* Current polling server */
-
-
- if (PollPipe >= 0)
- {
- cupsdStatBufDelete(PollStatusBuffer);
- close(PollPipe);
-
- cupsdRemoveSelect(PollPipe);
-
- PollPipe = -1;
- PollStatusBuffer = NULL;
- }
-
- for (i = 0, pollp = Polled; i < NumPolled; i ++, pollp ++)
- if (pollp->pid)
- cupsdEndProcess(pollp->pid, 0);
-}
-
-
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
/*
* 'cupsdUpdateDNSSDName()' - Update the computer name we use for browsing...
*/
@@ -1910,15 +344,14 @@ cupsdStopPolling(void)
void
cupsdUpdateDNSSDName(void)
{
- DNSServiceErrorType error; /* Error from service creation */
char webif[1024]; /* Web interface share name */
-# ifdef HAVE_SYSTEMCONFIGURATION
+# ifdef __APPLE__
SCDynamicStoreRef sc; /* Context for dynamic store */
CFDictionaryRef btmm; /* Back-to-My-Mac domains */
CFStringEncoding nameEncoding; /* Encoding of computer name */
CFStringRef nameRef; /* Host name CFString */
char nameBuffer[1024]; /* C-string buffer */
-# endif /* HAVE_SYSTEMCONFIGURATION */
+# endif /* __APPLE__ */
/*
@@ -1926,7 +359,6 @@ cupsdUpdateDNSSDName(void)
* enabled...
*/
-
if (!DNSSDPort)
return;
@@ -1934,7 +366,7 @@ cupsdUpdateDNSSDName(void)
* Get the computer name as a c-string...
*/
-# ifdef HAVE_SYSTEMCONFIGURATION
+# ifdef __APPLE__
sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL);
if (sc)
@@ -2025,282 +457,52 @@ cupsdUpdateDNSSDName(void)
CFRelease(sc);
}
else
-# endif /* HAVE_SYSTEMCONFIGURATION */
+# endif /* __APPLE__ */
+# ifdef HAVE_AVAHI
+ if (DNSSDClient)
{
- cupsdSetString(&DNSSDComputerName, ServerName);
- cupsdSetString(&DNSSDHostName, ServerName);
- }
+ const char *host_name = avahi_client_get_host_name(DNSSDClient);
+ const char *host_fqdn = avahi_client_get_host_name_fqdn(DNSSDClient);
- /*
- * Then (re)register the web interface if enabled...
- */
+ cupsdSetString(&DNSSDComputerName, host_name ? host_name : ServerName);
- if (BrowseWebIF)
- {
- if (DNSSDComputerName)
- snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDComputerName);
+ if (host_fqdn)
+ cupsdSetString(&DNSSDHostName, host_fqdn);
+ else if (strchr(ServerName, '.'))
+ cupsdSetString(&DNSSDHostName, ServerName);
else
- strlcpy(webif, "CUPS Web Interface", sizeof(webif));
-
- if (WebIFRef)
- DNSServiceRefDeallocate(WebIFRef);
-
- WebIFRef = DNSSDRef;
- if ((error = DNSServiceRegister(&WebIFRef,
- kDNSServiceFlagsShareConnection,
- 0, webif, "_http._tcp", NULL,
- NULL, htons(DNSSDPort), 7,
- "\006path=/", dnssdRegisterCallback,
- NULL)) != kDNSServiceErr_NoError)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "DNS-SD web interface registration failed: %d", error);
- }
-}
-#endif /* HAVE_DNSSD */
-
-
-#ifdef HAVE_LDAP
-/*
- * 'cupsdUpdateLDAPBrowse()' - Scan for new printers via LDAP...
- */
-
-void
-cupsdUpdateLDAPBrowse(void)
-{
- char uri[HTTP_MAX_URI], /* Printer URI */
- host[HTTP_MAX_URI], /* Hostname */
- resource[HTTP_MAX_URI], /* Resource path */
- location[1024], /* Printer location */
- info[1024], /* Printer information */
- make_model[1024], /* Printer make and model */
- type_num[30]; /* Printer type number */
- int type; /* Printer type */
- int rc; /* LDAP status */
- int limit; /* Size limit */
- LDAPMessage *res, /* LDAP search results */
- *e; /* Current entry from search */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "UpdateLDAPBrowse: %s", ServerName);
-
- BrowseLDAPRefresh = time(NULL) + BrowseInterval;
-
- /*
- * Reconnect if LDAP Handle is invalid...
- */
-
- if (! BrowseLDAPHandle)
- {
- ldap_reconnect();
- return;
+ cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
}
-
- /*
- * Search for cups printers in LDAP directory...
- */
-
- rc = ldap_search_rec(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE,
- "(objectclass=cupsPrinter)", (char **)ldap_attrs, 0, &res);
-
- /*
- * If ldap search was successfull then exit function
- * and temporary disable LDAP updates...
- */
-
- if (rc != LDAP_SUCCESS)
- {
- if (BrowseLDAPUpdate && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR)))
- {
- BrowseLDAPUpdate = FALSE;
- cupsdLogMessage(CUPSD_LOG_INFO,
- "LDAP update temporary disabled");
- }
- return;
- }
-
- /*
- * If LDAP updates were disabled, we will reenable them...
- */
-
- if (! BrowseLDAPUpdate)
- {
- BrowseLDAPUpdate = TRUE;
- cupsdLogMessage(CUPSD_LOG_INFO,
- "LDAP update enabled");
- }
-
- /*
- * Count LDAP entries and return if no entry exist...
- */
-
- limit = ldap_count_entries(BrowseLDAPHandle, res);
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "LDAP search returned %d entries", limit);
- if (limit < 1)
- {
- ldap_freeres(res);
- return;
- }
-
- /*
- * Loop through the available printers...
- */
-
- for (e = ldap_first_entry(BrowseLDAPHandle, res);
- e;
- e = ldap_next_entry(BrowseLDAPHandle, e))
+ else
+# endif /* HAVE_AVAHI */
{
- /*
- * Get the required values from this entry...
- */
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerDescription", info, sizeof(info)) == -1)
- continue;
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerLocation", location, sizeof(location)) == -1)
- continue;
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerMakeAndModel", make_model, sizeof(make_model)) == -1)
- continue;
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerType", type_num, sizeof(type_num)) == -1)
- continue;
-
- type = atoi(type_num);
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e,
- "printerURI", uri, sizeof(uri)) == -1)
- continue;
-
- /*
- * Process the entry as browse data...
- */
-
- if (!is_local_queue(uri, host, sizeof(host), resource, sizeof(resource)))
- process_browse_data(uri, host, resource, type, IPP_PRINTER_IDLE,
- location, info, make_model, 0, NULL);
+ cupsdSetString(&DNSSDComputerName, ServerName);
+ if (strchr(ServerName, '.'))
+ cupsdSetString(&DNSSDHostName, ServerName);
+ else
+ cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
}
- ldap_freeres(res);
-}
-#endif /* HAVE_LDAP */
-
-
-#ifdef HAVE_LIBSLP
-/*
- * 'cupsdUpdateSLPBrowse()' - Get browsing information via SLP.
- */
-
-void
-cupsdUpdateSLPBrowse(void)
-{
- slpsrvurl_t *s, /* Temporary list of service URLs */
- *next; /* Next service in list */
- cupsd_printer_t p; /* Printer information */
- const char *uri; /* Pointer to printer URI */
- char host[HTTP_MAX_URI], /* Host portion of URI */
- resource[HTTP_MAX_URI]; /* Resource portion of URI */
-
-
- /*
- * Reset the refresh time...
- */
-
- BrowseSLPRefresh = time(NULL) + BrowseInterval;
-
/*
- * Poll for remote printers using SLP...
- */
-
- s = NULL;
-
- SLPFindSrvs(BrowseSLPHandle, SLP_CUPS_SRVTYPE, "", "",
- slp_url_callback, &s);
-
- /*
- * Loop through the list of available printers...
+ * Then (re)register the web interface if enabled...
*/
- for (; s; s = next)
- {
- /*
- * Save the "next" pointer...
- */
-
- next = s->next;
-
- /*
- * Load a cupsd_printer_t structure with the SLP service attributes...
- */
-
- SLPFindAttrs(BrowseSLPHandle, s->url, "", "", slp_attr_callback, &p);
-
- /*
- * Process this printer entry...
- */
-
- uri = s->url + SLP_CUPS_SRVLEN + 1;
-
- if (!strncmp(uri, "http://", 7) || !strncmp(uri, "ipp://", 6))
- {
- /*
- * Pull the URI apart to see if this is a local or remote printer...
- */
-
- if (!is_local_queue(uri, host, sizeof(host), resource, sizeof(resource)))
- process_browse_data(uri, host, resource, p.type, IPP_PRINTER_IDLE,
- p.location, p.info, p.make_model, 0, NULL);
- }
-
- /*
- * Free this listing...
- */
-
- cupsdClearString(&p.info);
- cupsdClearString(&p.location);
- cupsdClearString(&p.make_model);
-
- free(s);
- }
-}
-#endif /* HAVE_LIBSLP */
-
-
-/*
- * 'dequote()' - Remote quotes from a string.
- */
-
-static char * /* O - Dequoted string */
-dequote(char *d, /* I - Destination string */
- const char *s, /* I - Source string */
- int dlen) /* I - Destination length */
-{
- char *dptr; /* Pointer into destination */
-
-
- if (s)
+ if (BrowseWebIF)
{
- for (dptr = d, dlen --; *s && dlen > 0; s ++)
- if (*s != '\"')
- {
- *dptr++ = *s;
- dlen --;
- }
+ if (DNSSDComputerName)
+ snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDComputerName);
+ else
+ strlcpy(webif, "CUPS", sizeof(webif));
- *dptr = '\0';
+ dnssdDeregisterInstance(&WebIFSrv);
+ dnssdRegisterInstance(&WebIFSrv, NULL, webif, "_http._tcp", "_printer",
+ DNSSDPort, NULL, 1);
}
- else
- *d = '\0';
-
- return (d);
}
-#ifdef HAVE_DNSSD
-# ifdef HAVE_COREFOUNDATION
+# ifdef __APPLE__
/*
* 'dnssdAddAlias()' - Add a DNS-SD alias name.
*/
@@ -2338,20 +540,20 @@ dnssdAddAlias(const void *key, /* I - Key */
cupsdLogMessage(CUPSD_LOG_ERROR,
"Bad Back to My Mac domain in dynamic store!");
}
-# endif /* HAVE_COREFOUNDATION */
+# endif /* __APPLE__ */
/*
* 'dnssdBuildTxtRecord()' - Build a TXT record from printer info.
*/
-static char * /* O - TXT record */
+static cupsd_txt_t /* O - TXT record */
dnssdBuildTxtRecord(
- int *txt_len, /* O - TXT record length */
cupsd_printer_t *p, /* I - Printer information */
int for_lpd) /* I - 1 = LPD, 0 = IPP */
{
- int i; /* Looping var */
+ int i, /* Looping var */
+ count; /* Count of key/value pairs */
char admin_hostname[256], /* .local hostname for admin page */
adminurl_str[256], /* URL for the admin page */
type_str[32], /* Type to string buffer */
@@ -2359,249 +561,370 @@ dnssdBuildTxtRecord(
rp_str[1024], /* Queue name string buffer */
air_str[1024], /* auth-info-required string buffer */
*keyvalue[32][2]; /* Table of key/value pairs */
+ cupsd_txt_t txt; /* TXT record */
/*
* Load up the key value pairs...
*/
- i = 0;
-
- keyvalue[i ][0] = "txtvers";
- keyvalue[i++][1] = "1";
+ count = 0;
- keyvalue[i ][0] = "qtotal";
- keyvalue[i++][1] = "1";
-
- keyvalue[i ][0] = "rp";
- keyvalue[i++][1] = rp_str;
- if (for_lpd)
- strlcpy(rp_str, p->name, sizeof(rp_str));
- else
- snprintf(rp_str, sizeof(rp_str), "%s/%s",
- (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers", p->name);
+ if (!for_lpd || (BrowseLocalProtocols & BROWSE_LPD))
+ {
+ keyvalue[count ][0] = "txtvers";
+ keyvalue[count++][1] = "1";
- keyvalue[i ][0] = "ty";
- keyvalue[i++][1] = p->make_model ? p->make_model : "Unknown";
+ keyvalue[count ][0] = "qtotal";
+ keyvalue[count++][1] = "1";
- snprintf(admin_hostname, sizeof(admin_hostname), "%s.local.", DNSSDHostName);
- httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str),
- "http", NULL, admin_hostname, DNSSDPort, "/%s/%s",
- (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
- p->name);
- keyvalue[i ][0] = "adminurl";
- keyvalue[i++][1] = adminurl_str;
+ keyvalue[count ][0] = "rp";
+ keyvalue[count++][1] = rp_str;
+ if (for_lpd)
+ strlcpy(rp_str, p->name, sizeof(rp_str));
+ else
+ snprintf(rp_str, sizeof(rp_str), "%s/%s",
+ (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
+ p->name);
- keyvalue[i ][0] = "note";
- keyvalue[i++][1] = p->location ? p->location : "";
+ keyvalue[count ][0] = "ty";
+ keyvalue[count++][1] = p->make_model ? p->make_model : "Unknown";
- keyvalue[i ][0] = "priority";
- keyvalue[i++][1] = for_lpd ? "100" : "0";
+ if (strstr(DNSSDHostName, ".local"))
+ strlcpy(admin_hostname, DNSSDHostName, sizeof(admin_hostname));
+ else
+ snprintf(admin_hostname, sizeof(admin_hostname), "%s.local.",
+ DNSSDHostName);
+ httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str),
+# ifdef HAVE_SSL
+ "https",
+# else
+ "http",
+# endif /* HAVE_SSL */
+ NULL, admin_hostname, DNSSDPort, "/%s/%s",
+ (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
+ p->name);
+ keyvalue[count ][0] = "adminurl";
+ keyvalue[count++][1] = adminurl_str;
- keyvalue[i ][0] = "product";
- keyvalue[i++][1] = p->pc && p->pc->product ? p->pc->product : "Unknown";
+ if (p->location)
+ {
+ keyvalue[count ][0] = "note";
+ keyvalue[count++][1] = p->location;
+ }
- keyvalue[i ][0] = "pdl";
- keyvalue[i++][1] = p->pdl ? p->pdl : "application/postscript";
+ keyvalue[count ][0] = "priority";
+ keyvalue[count++][1] = for_lpd ? "100" : "0";
- if (get_auth_info_required(p, air_str, sizeof(air_str)))
- {
- keyvalue[i ][0] = "air";
- keyvalue[i++][1] = air_str;
- }
+ keyvalue[count ][0] = "product";
+ keyvalue[count++][1] = p->pc && p->pc->product ? p->pc->product : "Unknown";
- keyvalue[i ][0] = "UUID";
- keyvalue[i++][1] = p->uuid + 9;
+ keyvalue[count ][0] = "pdl";
+ keyvalue[count++][1] = p->pdl ? p->pdl : "application/postscript";
-#ifdef HAVE_SSL
- keyvalue[i ][0] = "TLS";
- keyvalue[i++][1] = "1.2";
-#endif /* HAVE_SSL */
+ if (get_auth_info_required(p, air_str, sizeof(air_str)))
+ {
+ keyvalue[count ][0] = "air";
+ keyvalue[count++][1] = air_str;
+ }
- keyvalue[i ][0] = "Transparent";
- keyvalue[i++][1] = "F";
+ keyvalue[count ][0] = "UUID";
+ keyvalue[count++][1] = p->uuid + 9;
- keyvalue[i ][0] = "Binary";
- keyvalue[i++][1] = "F";
+ #ifdef HAVE_SSL
+ keyvalue[count ][0] = "TLS";
+ keyvalue[count++][1] = "1.2";
+ #endif /* HAVE_SSL */
- keyvalue[i ][0] = "Fax";
- keyvalue[i++][1] = (p->type & CUPS_PRINTER_FAX) ? "T" : "F";
+ if (p->type & CUPS_PRINTER_FAX)
+ {
+ keyvalue[count ][0] = "Fax";
+ keyvalue[count++][1] = (p->type & CUPS_PRINTER_FAX) ? "T" : "F";
+ }
- keyvalue[i ][0] = "Color";
- keyvalue[i++][1] = (p->type & CUPS_PRINTER_COLOR) ? "T" : "F";
+ if (p->type & CUPS_PRINTER_COLOR)
+ {
+ keyvalue[count ][0] = "Color";
+ keyvalue[count++][1] = (p->type & CUPS_PRINTER_COLOR) ? "T" : "F";
+ }
- keyvalue[i ][0] = "Duplex";
- keyvalue[i++][1] = (p->type & CUPS_PRINTER_DUPLEX) ? "T" : "F";
+ if (p->type & CUPS_PRINTER_DUPLEX)
+ {
+ keyvalue[count ][0] = "Duplex";
+ keyvalue[count++][1] = (p->type & CUPS_PRINTER_DUPLEX) ? "T" : "F";
+ }
- keyvalue[i ][0] = "Staple";
- keyvalue[i++][1] = (p->type & CUPS_PRINTER_STAPLE) ? "T" : "F";
+ if (p->type & CUPS_PRINTER_STAPLE)
+ {
+ keyvalue[count ][0] = "Staple";
+ keyvalue[count++][1] = (p->type & CUPS_PRINTER_STAPLE) ? "T" : "F";
+ }
- keyvalue[i ][0] = "Copies";
- keyvalue[i++][1] = (p->type & CUPS_PRINTER_COPIES) ? "T" : "F";
+ if (p->type & CUPS_PRINTER_COPIES)
+ {
+ keyvalue[count ][0] = "Copies";
+ keyvalue[count++][1] = (p->type & CUPS_PRINTER_COPIES) ? "T" : "F";
+ }
- keyvalue[i ][0] = "Collate";
- keyvalue[i++][1] = (p->type & CUPS_PRINTER_COLLATE) ? "T" : "F";
+ if (p->type & CUPS_PRINTER_COLLATE)
+ {
+ keyvalue[count ][0] = "Collate";
+ keyvalue[count++][1] = (p->type & CUPS_PRINTER_COLLATE) ? "T" : "F";
+ }
- keyvalue[i ][0] = "Punch";
- keyvalue[i++][1] = (p->type & CUPS_PRINTER_PUNCH) ? "T" : "F";
+ if (p->type & CUPS_PRINTER_PUNCH)
+ {
+ keyvalue[count ][0] = "Punch";
+ keyvalue[count++][1] = (p->type & CUPS_PRINTER_PUNCH) ? "T" : "F";
+ }
- keyvalue[i ][0] = "Bind";
- keyvalue[i++][1] = (p->type & CUPS_PRINTER_BIND) ? "T" : "F";
+ if (p->type & CUPS_PRINTER_BIND)
+ {
+ keyvalue[count ][0] = "Bind";
+ keyvalue[count++][1] = (p->type & CUPS_PRINTER_BIND) ? "T" : "F";
+ }
- keyvalue[i ][0] = "Sort";
- keyvalue[i++][1] = (p->type & CUPS_PRINTER_SORT) ? "T" : "F";
+ if (p->type & CUPS_PRINTER_SORT)
+ {
+ keyvalue[count ][0] = "Sort";
+ keyvalue[count++][1] = (p->type & CUPS_PRINTER_SORT) ? "T" : "F";
+ }
- keyvalue[i ][0] = "Scan";
- keyvalue[i++][1] = (p->type & CUPS_PRINTER_MFP) ? "T" : "F";
+ if (p->type & CUPS_PRINTER_MFP)
+ {
+ keyvalue[count ][0] = "Scan";
+ keyvalue[count++][1] = (p->type & CUPS_PRINTER_MFP) ? "T" : "F";
+ }
- snprintf(type_str, sizeof(type_str), "0x%X", p->type | CUPS_PRINTER_REMOTE);
- snprintf(state_str, sizeof(state_str), "%d", p->state);
+ 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[count ][0] = "printer-state";
+ keyvalue[count++][1] = state_str;
- keyvalue[i ][0] = "printer-type";
- keyvalue[i++][1] = type_str;
+ keyvalue[count ][0] = "printer-type";
+ keyvalue[count++][1] = type_str;
+ }
/*
* Then pack them into a proper txt record...
*/
- return (dnssdPackTxtRecord(txt_len, keyvalue, i));
-}
+# ifdef HAVE_DNSSD
+ TXTRecordCreate(&txt, 0, NULL);
+ for (i = 0; i < count; i ++)
+ {
+ size_t len = strlen(keyvalue[i][1]);
-/*
- * 'dnssdComparePrinters()' - Compare the registered names of two printers.
- */
+ if (len < 256)
+ TXTRecordSetValue(&txt, keyvalue[i][0], (uint8_t)len, keyvalue[i][1]);
+ }
-static int /* O - Result of comparison */
-dnssdComparePrinters(cupsd_printer_t *a,/* I - First printer */
- cupsd_printer_t *b)/* I - Second printer */
-{
- return (_cups_strcasecmp(a->reg_name, b->reg_name));
+# else
+ for (i = 0, txt = NULL; i < count; i ++)
+ txt = avahi_string_list_add_printf(txt, "%s=%s", keyvalue[i][0],
+ keyvalue[i][1]);
+# endif /* HAVE_DNSSD */
+
+ return (txt);
}
/*
- * 'dnssdDeregisterPrinter()' - Stop sending broadcast information for a
- * printer.
+ * 'dnssdDeregisterInstance()' - Deregister a DNS-SD service instance.
*/
static void
-dnssdDeregisterPrinter(
- cupsd_printer_t *p) /* I - Printer */
+dnssdDeregisterInstance(
+ cupsd_srv_t *srv) /* I - Service */
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdDeregisterPrinter(%s)", p->name);
+ if (!srv || !*srv)
+ return;
- /*
- * Closing the socket deregisters the service
- */
+# ifdef HAVE_DNSSD
+ DNSServiceRefDeallocate(*srv);
- if (p->ipp_ref)
- {
- DNSServiceRefDeallocate(p->ipp_ref);
- p->ipp_ref = NULL;
- }
+# else /* HAVE_AVAHI */
+ avahi_threaded_poll_lock(DNSSDMaster);
+ avahi_entry_group_free(*srv);
+ avahi_threaded_poll_unlock(DNSSDMaster);
+# endif /* HAVE_DNSSD */
- if (p->ipp_txt)
- {
- /*
- * p->ipp_txt is malloc'd, not _cupsStrAlloc'd...
- */
+ *srv = NULL;
+}
- free(p->ipp_txt);
- p->ipp_txt = NULL;
- }
- if (p->printer_ref)
- {
- DNSServiceRefDeallocate(p->printer_ref);
- p->printer_ref = NULL;
- }
+/*
+ * 'dnssdDeregisterPrinter()' - Deregister all services for a printer.
+ */
- if (p->printer_txt)
+static void
+dnssdDeregisterPrinter(
+ cupsd_printer_t *p, /* I - Printer */
+ int clear_name) /* I - Clear the name? */
+
+{
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "dnssdDeregisterPrinter(p=%p(%s), clear_name=%d)", p, p->name,
+ clear_name);
+
+ if (p->ipp_srv)
{
- /*
- * p->printer_txt is malloc'd, not _cupsStrAlloc'd...
- */
+ dnssdDeregisterInstance(&p->ipp_srv);
- free(p->printer_txt);
- p->printer_txt = NULL;
+# ifdef HAVE_DNSSD
+# ifdef HAVE_SSL
+ dnssdDeregisterInstance(&p->ipps_srv);
+# endif /* HAVE_SSL */
+ dnssdDeregisterInstance(&p->printer_srv);
+# endif /* HAVE_DNSSD */
}
/*
- * Remove the printer from the array of DNS-SD printers, then clear the
+ * Remove the printer from the array of DNS-SD printers but keep the
* registered name...
*/
cupsArrayRemove(DNSSDPrinters, p);
- cupsdClearString(&p->reg_name);
+
+ /*
+ * Optionally clear the service name...
+ */
+
+ if (clear_name)
+ cupsdClearString(&p->reg_name);
}
/*
- * 'dnssdPackTxtRecord()' - Pack an array of key/value pairs into the
- * TXT record format.
+ * 'dnssdErrorString()' - Return an error string for an error code.
*/
-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 */
+static const char * /* O - Error message */
+dnssdErrorString(int error) /* I - Error number */
{
- int i; /* Looping var */
- int length; /* Length of TXT record */
- int length2; /* Length of value */
- char *txtRecord; /* TXT record buffer */
- char *cursor; /* Looping pointer */
+# ifdef HAVE_DNSSD
+ switch (error)
+ {
+ case kDNSServiceErr_NoError :
+ return ("OK.");
+ default :
+ case kDNSServiceErr_Unknown :
+ return ("Unknown error.");
- /*
- * Calculate the buffer size
- */
+ case kDNSServiceErr_NoSuchName :
+ return ("Service not found.");
- if (count <= 0)
- return (NULL);
+ case kDNSServiceErr_NoMemory :
+ return ("Out of memory.");
- for (length = i = 0; i < count; i++)
- length += 1 + strlen(keyvalue[i][0]) +
- (keyvalue[i][1] ? 1 + strlen(keyvalue[i][1]) : 0);
+ case kDNSServiceErr_BadParam :
+ return ("Bad parameter.");
- /*
- * Allocate and fill it
- */
+ case kDNSServiceErr_BadReference :
+ return ("Bad service reference.");
- txtRecord = malloc(length);
- if (txtRecord)
- {
- *txt_len = length;
+ case kDNSServiceErr_BadState :
+ return ("Bad state.");
- for (cursor = txtRecord, i = 0; i < count; i++)
- {
- /*
- * Drop in the p-string style length byte followed by the data
- */
+ case kDNSServiceErr_BadFlags :
+ return ("Bad flags.");
- length = strlen(keyvalue[i][0]);
- length2 = keyvalue[i][1] ? 1 + strlen(keyvalue[i][1]) : 0;
+ case kDNSServiceErr_Unsupported :
+ return ("Unsupported.");
- *cursor++ = (unsigned char)(length + length2);
+ case kDNSServiceErr_NotInitialized :
+ return ("Not initialized.");
- memcpy(cursor, keyvalue[i][0], length);
- cursor += length;
+ case kDNSServiceErr_AlreadyRegistered :
+ return ("Already registered.");
- if (length2)
- {
- length2 --;
- *cursor++ = '=';
- memcpy(cursor, keyvalue[i][1], length2);
- cursor += length2;
- }
- }
+ case kDNSServiceErr_NameConflict :
+ return ("Name conflict.");
+
+ case kDNSServiceErr_Invalid :
+ return ("Invalid name.");
+
+ case kDNSServiceErr_Firewall :
+ return ("Firewall prevents registration.");
+
+ case kDNSServiceErr_Incompatible :
+ return ("Client library incompatible.");
+
+ case kDNSServiceErr_BadInterfaceIndex :
+ return ("Bad interface index.");
+
+ case kDNSServiceErr_Refused :
+ return ("Server prevents registration.");
+
+ case kDNSServiceErr_NoSuchRecord :
+ return ("Record not found.");
+
+ case kDNSServiceErr_NoAuth :
+ return ("Authentication required.");
+
+ case kDNSServiceErr_NoSuchKey :
+ return ("Encryption key not found.");
+
+ case kDNSServiceErr_NATTraversal :
+ return ("Unable to traverse NAT boundary.");
+
+ case kDNSServiceErr_DoubleNAT :
+ return ("Unable to traverse double-NAT boundary.");
+
+ case kDNSServiceErr_BadTime :
+ return ("Bad system time.");
+
+ case kDNSServiceErr_BadSig :
+ return ("Bad signature.");
+
+ case kDNSServiceErr_BadKey :
+ return ("Bad encryption key.");
+
+ case kDNSServiceErr_Transient :
+ return ("Transient error occurred - please try again.");
+
+ case kDNSServiceErr_ServiceNotRunning :
+ return ("Server not running.");
+
+ case kDNSServiceErr_NATPortMappingUnsupported :
+ return ("NAT doesn't support NAT-PMP or UPnP.");
+
+ case kDNSServiceErr_NATPortMappingDisabled :
+ return ("NAT supports NAT-PNP or UPnP but it is disabled.");
+
+ case kDNSServiceErr_NoRouter :
+ return ("No Internet/default router configured.");
+
+ case kDNSServiceErr_PollingMode :
+ return ("Service polling mode error.");
+
+ case kDNSServiceErr_Timeout :
+ return ("Service timeout.");
}
- return (txtRecord);
+# else /* HAVE_AVAHI */
+ return (avahi_strerror(error));
+# endif /* HAVE_DNSSD */
+}
+
+
+/*
+ * 'dnssdRegisterCallback()' - Free a TXT record.
+ */
+
+static void
+dnssdFreeTxtRecord(cupsd_txt_t *txt) /* I - TXT record */
+{
+# ifdef HAVE_DNSSD
+ TXTRecordDeallocate(txt);
+
+# else /* HAVE_AVAHI */
+ avahi_string_list_free(*txt);
+ *txt = NULL;
+# endif /* HAVE_DNSSD */
}
@@ -2609,6 +932,7 @@ dnssdPackTxtRecord(int *txt_len, /* O - TXT record length */
* 'dnssdRegisterCallback()' - DNSServiceRegister callback.
*/
+# ifdef HAVE_DNSSD
static void
dnssdRegisterCallback(
DNSServiceRef sdRef, /* I - DNS Service reference */
@@ -2617,7 +941,7 @@ dnssdRegisterCallback(
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) /* I - Printer */
{
cupsd_printer_t *p = (cupsd_printer_t *)context;
/* Current printer */
@@ -2650,245 +974,330 @@ dnssdRegisterCallback(
}
}
+# else /* HAVE_AVAHI */
+static void
+dnssdRegisterCallback(
+ AvahiEntryGroup *srv, /* I - Service */
+ AvahiEntryGroupState state, /* I - Registration state */
+ void *context) /* I - Printer */
+{
+ cupsd_printer_t *p = (cupsd_printer_t *)context;
+ /* Current printer */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "dnssdRegisterCallback(srv=%p, state=%d, context=%p) "
+ "for %s (%s)", srv, state, context,
+ p ? p->name : "Web Interface",
+ p ? (p->reg_name ? p->reg_name : "(null)") : "NA");
+
+ /* TODO: Handle collisions with avahi_alternate_service_name(p->reg_name)? */
+}
+# endif /* HAVE_DNSSD */
+
/*
- * 'dnssdRegisterPrinter()' - Start sending broadcast information for a printer
- * or update the broadcast contents.
+ * 'dnssdRegisterInstance()' - Register an instance of a printer service.
*/
-static void
-dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
+static int /* O - 1 on success, 0 on failure */
+dnssdRegisterInstance(
+ cupsd_srv_t *srv, /* O - Service */
+ cupsd_printer_t *p, /* I - Printer */
+ char *name, /* I - DNS-SD service name */
+ const char *type, /* I - DNS-SD service type */
+ const char *subtypes, /* I - Subtypes to register or NULL */
+ int port, /* I - Port number or 0 */
+ cupsd_txt_t *txt, /* I - TXT record */
+ int commit) /* I - Commit registration? */
{
- DNSServiceErrorType se; /* dnssd errors */
- char *ipp_txt, /* IPP TXT record buffer */
- *printer_txt, /* LPD TXT record buffer */
- name[1024], /* Service name */
- *nameptr; /* Pointer into name */
- int ipp_len, /* IPP TXT record length */
- printer_len, /* LPD TXT record length */
- printer_port; /* LPD port number */
- const char *regtype; /* Registration type */
+ char temp[256], /* Temporary string */
+ *ptr; /* Pointer into string */
+ int error; /* Any error */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
- !p->ipp_ref ? "new" : "update");
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Registering \"%s\" with DNS-SD type \"%s\".", name, type);
- /*
- * If per-printer sharing was just disabled make sure we're not
- * registered before returning.
- */
+ if (p && !srv)
+ {
+ /*
+ * Assign the correct pointer for "srv"...
+ */
- if (!p->shared)
+# ifdef HAVE_DNSSD
+ if (!strcmp(type, "_printer._tcp"))
+ srv = &p->printer_srv; /* Target LPD service */
+# ifdef HAVE_SSL
+ else if (!strcmp(type, "_ipps._tcp"))
+ srv = &p->ipps_srv; /* Target IPPS service */
+# endif /* HAVE_SSL */
+ else
+ srv = &p->ipp_srv; /* Target IPP service */
+
+# else /* HAVE_AVAHI */
+ srv = &p->ipp_srv; /* Target service group */
+# endif /* HAVE_DNSSD */
+ }
+
+# ifdef HAVE_DNSSD
+ (void)commit;
+
+# else /* HAVE_AVAHI */
+ avahi_threaded_poll_lock(DNSSDMaster);
+
+ if (!*srv)
+ *srv = avahi_entry_group_new(DNSSDClient, dnssdRegisterCallback, NULL);
+ if (!*srv)
{
- dnssdDeregisterPrinter(p);
- return;
+ avahi_threaded_poll_unlock(DNSSDMaster);
+
+ cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
+ name, dnssdErrorString(avahi_client_errno(DNSSDClient)));
+ return (0);
}
+# endif /* HAVE_DNSSD */
/*
- * The registered name takes the form of "<printer-info> @ <computer name>"...
+ * Make sure the name is <= 63 octets, and when we truncate be sure to
+ * properly truncate any UTF-8 characters...
*/
- if (p->info && strlen(p->info) > 0)
+ ptr = name + strlen(name);
+ while ((ptr - name) > 63)
{
- if (DNSSDComputerName)
- snprintf(name, sizeof(name), "%s @ %s", p->info, DNSSDComputerName);
- else
- strlcpy(name, p->info, sizeof(name));
+ do
+ {
+ ptr --;
+ }
+ while (ptr > name && (*ptr & 0xc0) == 0x80);
+
+ if (ptr > name)
+ *ptr = '\0';
}
- else if (DNSSDComputerName)
- snprintf(name, sizeof(name), "%s @ %s", p->name, DNSSDComputerName);
- else
- strlcpy(name, p->name, sizeof(name));
/*
- * If an existing printer was renamed, unregister it and start over...
+ * Register the service...
*/
- if (p->reg_name && strcmp(p->reg_name, name))
- dnssdDeregisterPrinter(p);
+# ifdef HAVE_DNSSD
+ if (subtypes)
+ snprintf(temp, sizeof(temp), "%s,%s", type, subtypes);
+ else
+ strlcpy(temp, type, sizeof(temp));
- if (!p->reg_name)
+ *srv = DNSSDMaster;
+ error = DNSServiceRegister(srv, kDNSServiceFlagsShareConnection,
+ 0, name, temp, NULL, NULL, htons(port),
+ txt ? TXTRecordGetLength(txt) : 0,
+ txt ? TXTRecordGetBytesPtr(txt) : NULL,
+ dnssdRegisterCallback, p);
+
+# else /* HAVE_AVAHI */
+ if (txt)
{
- cupsdSetString(&p->reg_name, name);
- cupsArrayAdd(DNSSDPrinters, p);
+ AvahiStringList *temptxt;
+ for (temptxt = *txt; temptxt; temptxt = temptxt->next)
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS_SD \"%s\" %s", name, temptxt->text);
}
- /*
- * Register IPP and (optionally) LPD...
- */
-
- ipp_len = 0; /* anti-compiler-warning-code */
- ipp_txt = dnssdBuildTxtRecord(&ipp_len, p, 0);
+ error = avahi_entry_group_add_service_strlst(*srv, AVAHI_IF_UNSPEC,
+ AVAHI_PROTO_UNSPEC, 0, name,
+ type, NULL, NULL, port,
+ txt ? *txt : NULL);
+ if (error)
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD service add for \"%s\" failed.",
+ name);
- if (p->ipp_ref &&
- (ipp_len != p->ipp_len || memcmp(ipp_txt, p->ipp_txt, ipp_len)))
+ if (!error && subtypes)
{
/*
- * Update the existing registration...
+ * Register all of the subtypes...
*/
- /* A TTL of 0 means use record's original value (Radar 3176248) */
- if ((se = DNSServiceUpdateRecord(p->ipp_ref, NULL, 0, ipp_len, ipp_txt,
- 0)) == kDNSServiceErr_NoError)
- {
- if (p->ipp_txt)
- free(p->ipp_txt);
+ char *start, /* Start of subtype */
+ subtype[256]; /* Subtype string */
- p->ipp_txt = ipp_txt;
- p->ipp_len = ipp_len;
- ipp_txt = NULL;
- }
- else
+ strlcpy(temp, subtypes, sizeof(temp));
+
+ for (start = temp; *start; start = ptr)
{
/*
- * Failed to update record, lets close this reference and move on...
+ * Skip leading whitespace...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to update IPP DNS-SD record for %s - %d", p->name,
- se);
+ while (*start && isspace(*start & 255))
+ start ++;
- DNSServiceRefDeallocate(p->ipp_ref);
- p->ipp_ref = NULL;
+ /*
+ * Grab everything up to the next comma or the end of the string...
+ */
+
+ for (ptr = start; *ptr && *ptr != ','; ptr ++);
+
+ if (*ptr)
+ *ptr++ = '\0';
+
+ if (!*start)
+ break;
+
+ /*
+ * Register the subtype...
+ */
+
+ snprintf(subtype, sizeof(subtype), "%s._sub.%s", start, type);
+
+ error = avahi_entry_group_add_service_subtype(*srv, AVAHI_IF_UNSPEC,
+ AVAHI_PROTO_UNSPEC, 0,
+ name, type, NULL, subtype);
+ if (error)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "DNS-SD subtype %s registration for \"%s\" failed." ,
+ subtype, name);
+ break;
+ }
}
}
- if (!p->ipp_ref)
+ if (!error && commit)
{
- /*
- * Initial registration. Use the _fax-ipp regtype for fax queues...
- */
+ if ((error = avahi_entry_group_commit(*srv)) != 0)
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD commit of \"%s\" failed.",
+ name);
+ }
- regtype = (p->type & CUPS_PRINTER_FAX) ? "_fax-ipp._tcp" : DNSSDRegType;
+ avahi_threaded_poll_unlock(DNSSDMaster);
+# endif /* HAVE_DNSSD */
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Registering DNS-SD printer %s with name \"%s\" and "
- "type \"%s\"", p->name, name, regtype);
+ if (error)
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
+ name, dnssdErrorString(error));
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD type: %s", type);
+ if (subtypes)
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD sub-types: %s", subtypes);
+ }
- /*
- * Register the queue, dropping characters as needed until we succeed...
- */
+ return (!error);
+}
- nameptr = name + strlen(name);
- do
- {
- p->ipp_ref = DNSSDRef;
- if ((se = DNSServiceRegister(&p->ipp_ref, kDNSServiceFlagsShareConnection,
- 0, name, regtype, NULL, NULL,
- htons(DNSSDPort), ipp_len, ipp_txt,
- dnssdRegisterCallback,
- p)) == kDNSServiceErr_BadParam)
- {
- /*
- * Name is too long, drop trailing characters, taking into account
- * UTF-8 encoding...
- */
+/*
+ * 'dnssdRegisterPrinter()' - Start sending broadcast information for a printer
+ * or update the broadcast contents.
+ */
- nameptr --;
+static void
+dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
+{
+ char name[256]; /* Service name */
+ int printer_port; /* LPD port number */
+ int status; /* Registration status */
+ cupsd_txt_t ipp_txt, /* IPP(S) TXT record */
+ printer_txt; /* LPD TXT record */
- while (nameptr > name && (*nameptr & 0xc0) == 0x80)
- nameptr --;
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
+ !p->ipp_srv ? "new" : "update");
- if (nameptr > name)
- *nameptr = '\0';
- }
- }
- while (se == kDNSServiceErr_BadParam && nameptr > name);
+ /*
+ * Remove the current registrations if we have them and then return if
+ * per-printer sharing was just disabled...
+ */
+
+ dnssdDeregisterPrinter(p, 0);
+
+ if (!p->shared)
+ return;
- if (se == kDNSServiceErr_NoError)
+ /*
+ * Set the registered name as needed; the registered name takes the form of
+ * "<printer-info> @ <computer name>"...
+ */
+
+ if (!p->reg_name)
+ {
+ if (p->info && strlen(p->info) > 0)
{
- p->ipp_txt = ipp_txt;
- p->ipp_len = ipp_len;
- ipp_txt = NULL;
+ if (DNSSDComputerName)
+ snprintf(name, sizeof(name), "%s @ %s", p->info, DNSSDComputerName);
+ else
+ strlcpy(name, p->info, sizeof(name));
}
+ else if (DNSSDComputerName)
+ snprintf(name, sizeof(name), "%s @ %s", p->name, DNSSDComputerName);
else
- cupsdLogMessage(CUPSD_LOG_WARN,
- "DNS-SD IPP registration of \"%s\" failed: %d",
- p->name, se);
+ strlcpy(name, p->name, sizeof(name));
}
+ else
+ strlcpy(name, p->reg_name, sizeof(name));
+
+ /*
+ * Register IPP and LPD...
+ *
+ * We always must register the "_printer" service type in order to reserve
+ * our name, but use port number 0 if we haven't actually configured cups-lpd
+ * to share via LPD...
+ */
- if (ipp_txt)
- free(ipp_txt);
+ ipp_txt = dnssdBuildTxtRecord(p, 0);
+ printer_txt = dnssdBuildTxtRecord(p, 1);
if (BrowseLocalProtocols & BROWSE_LPD)
- {
- printer_len = 0; /* anti-compiler-warning-code */
printer_port = 515;
- printer_txt = dnssdBuildTxtRecord(&printer_len, p, 1);
- }
else
- {
- printer_len = 0;
printer_port = 0;
- printer_txt = NULL;
- }
- if (p->printer_ref &&
- (printer_len != p->printer_len ||
- memcmp(printer_txt, p->printer_txt, printer_len)))
+ status = dnssdRegisterInstance(NULL, p, name, "_printer._tcp", NULL,
+ printer_port, &printer_txt, 0);
+
+# ifdef HAVE_SSL
+ if (status)
+ dnssdRegisterInstance(NULL, p, name, "_ipps._tcp", DNSSDSubTypes,
+ DNSSDPort, &ipp_txt, 0);
+# endif /* HAVE_SSL */
+
+ if (status)
{
/*
- * Update the existing registration...
+ * Use the "_fax-ipp" service type for fax queues, otherwise use "_ipp"...
*/
- /* A TTL of 0 means use record's original value (Radar 3176248) */
- if ((se = DNSServiceUpdateRecord(p->printer_ref, NULL, 0, printer_len,
- printer_txt,
- 0)) == kDNSServiceErr_NoError)
- {
- if (p->printer_txt)
- free(p->printer_txt);
-
- p->printer_txt = printer_txt;
- p->printer_len = printer_len;
- printer_txt = NULL;
- }
+ if (p->type & CUPS_PRINTER_FAX)
+ status = dnssdRegisterInstance(NULL, p, name, "_fax-ipp._tcp",
+ DNSSDSubTypes, DNSSDPort, &ipp_txt, 1);
else
- {
- /*
- * Failed to update record, lets close this reference and move on...
- */
-
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to update LPD DNS-SD record for %s - %d",
- p->name, se);
-
- DNSServiceRefDeallocate(p->printer_ref);
- p->printer_ref = NULL;
- }
+ status = dnssdRegisterInstance(NULL, p, name, "_ipp._tcp", DNSSDSubTypes,
+ DNSSDPort, &ipp_txt, 1);
}
- if (!p->printer_ref)
+ dnssdFreeTxtRecord(&ipp_txt);
+ dnssdFreeTxtRecord(&printer_txt);
+
+ if (status)
{
/*
- * Initial registration...
+ * Save the registered name and add the printer to the array of DNS-SD
+ * printers...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Registering DNS-SD printer %s with name \"%s\" and "
- "type \"_printer._tcp\"", p->name, name);
-
- p->printer_ref = DNSSDRef;
- if ((se = DNSServiceRegister(&p->printer_ref,
- kDNSServiceFlagsShareConnection,
- 0, name, "_printer._tcp", NULL, NULL,
- htons(printer_port), printer_len, printer_txt,
- dnssdRegisterCallback,
- p)) == kDNSServiceErr_NoError)
- {
- p->printer_txt = printer_txt;
- p->printer_len = printer_len;
- printer_txt = NULL;
- }
- else
- cupsdLogMessage(CUPSD_LOG_WARN,
- "DNS-SD LPD registration of \"%s\" failed: %d",
- p->name, se);
+ cupsdSetString(&p->reg_name, name);
+ cupsArrayAdd(DNSSDPrinters, p);
}
+ else
+ {
+ /*
+ * Registration failed for this printer...
+ */
- if (printer_txt)
- free(printer_txt);
+ dnssdDeregisterInstance(&p->ipp_srv);
+
+# ifdef HAVE_DNSSD
+# ifdef HAVE_SSL
+ dnssdDeregisterInstance(&p->ipps_srv);
+# endif /* HAVE_SSL */
+ dnssdDeregisterInstance(&p->printer_srv);
+# endif /* HAVE_DNSSD */
+ }
}
@@ -2909,28 +1318,27 @@ dnssdStop(void)
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
- dnssdDeregisterPrinter(p);
+ dnssdDeregisterPrinter(p, 1);
/*
* Shutdown the rest of the service refs...
*/
- if (WebIFRef)
- {
- DNSServiceRefDeallocate(WebIFRef);
- WebIFRef = NULL;
- }
+ dnssdDeregisterInstance(&WebIFSrv);
- if (RemoteRef)
- {
- DNSServiceRefDeallocate(RemoteRef);
- RemoteRef = NULL;
- }
+# ifdef HAVE_DNSSD
+ cupsdRemoveSelect(DNSServiceRefSockFD(DNSSDMaster));
- cupsdRemoveSelect(DNSServiceRefSockFD(DNSSDRef));
+ DNSServiceRefDeallocate(DNSSDMaster);
+ DNSSDMaster = NULL;
- DNSServiceRefDeallocate(DNSSDRef);
- DNSSDRef = NULL;
+# else /* HAVE_AVAHI */
+ avahi_client_free(DNSSDClient);
+ DNSSDClient = NULL;
+
+ avahi_threaded_poll_free(DNSSDMaster);
+ DNSSDMaster = NULL;
+# endif /* HAVE_DNSSD */
cupsArrayDelete(DNSSDPrinters);
DNSSDPrinters = NULL;
@@ -2939,6 +1347,7 @@ dnssdStop(void)
}
+# ifdef HAVE_DNSSD
/*
* 'dnssdUpdate()' - Handle DNS-SD queries.
*/
@@ -2949,7 +1358,7 @@ dnssdUpdate(void)
DNSServiceErrorType sdErr; /* Service discovery error */
- if ((sdErr = DNSServiceProcessResult(DNSSDRef)) != kDNSServiceErr_NoError)
+ if ((sdErr = DNSServiceProcessResult(DNSSDMaster)) != kDNSServiceErr_NoError)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"DNS Service Discovery registration error %d!",
@@ -2957,7 +1366,7 @@ dnssdUpdate(void)
dnssdStop();
}
}
-#endif /* HAVE_DNSSD */
+# endif /* HAVE_DNSSD */
/*
@@ -3016,7 +1425,7 @@ get_auth_info_required(
int auth_type; /* Authentication type */
if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT)
- auth_type = DefaultAuthType;
+ auth_type = cupsdDefaultAuthType();
switch (auth_type)
{
@@ -3037,6 +1446,7 @@ get_auth_info_required(
return ("none");
}
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
#ifdef __APPLE__
@@ -3092,2295 +1502,6 @@ get_hostconfig(const char *name) /* I - Name of service */
/*
- * 'is_local_queue()' - Determine whether the URI points at a local queue.
- */
-
-static int /* O - 1 = local, 0 = remote, -1 = bad URI */
-is_local_queue(const char *uri, /* I - Printer URI */
- char *host, /* O - Host string */
- int hostlen, /* I - Length of host buffer */
- char *resource, /* O - Resource string */
- int resourcelen) /* I - Length of resource buffer */
-{
- char scheme[32], /* Scheme portion of URI */
- username[HTTP_MAX_URI]; /* Username portion of URI */
- int port; /* Port portion of URI */
- cupsd_netif_t *iface; /* Network interface */
-
-
- /*
- * Pull the URI apart to see if this is a local or remote printer...
- */
-
- if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme),
- username, sizeof(username), host, hostlen, &port,
- resource, resourcelen) < HTTP_URI_OK)
- return (-1);
-
- DEBUG_printf(("host=\"%s\", ServerName=\"%s\"\n", host, ServerName));
-
- /*
- * Check for local server addresses...
- */
-
- if (!_cups_strcasecmp(host, ServerName) && port == LocalPort)
- return (1);
-
- cupsdNetIFUpdate();
-
- for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList);
- iface;
- iface = (cupsd_netif_t *)cupsArrayNext(NetIFList))
- if (!_cups_strcasecmp(host, iface->hostname) && port == iface->port)
- return (1);
-
- /*
- * If we get here, the printer is remote...
- */
-
- return (0);
-}
-
-
-/*
- * 'process_browse_data()' - Process new browse data.
- */
-
-static void
-process_browse_data(
- const char *uri, /* I - URI of printer/class */
- const char *host, /* I - Hostname */
- const char *resource, /* I - Resource path */
- cups_ptype_t type, /* I - Printer type */
- ipp_pstate_t state, /* I - Printer state */
- const char *location, /* I - Printer location */
- const char *info, /* I - Printer information */
- const char *make_model, /* I - Printer make and model */
- int num_attrs, /* I - Number of attributes */
- cups_option_t *attrs) /* I - Attributes */
-{
- int i; /* Looping var */
- int update; /* Update printer attributes? */
- char finaluri[HTTP_MAX_URI], /* Final URI for printer */
- name[IPP_MAX_NAME], /* Name of printer */
- newname[IPP_MAX_NAME], /* New name of printer */
- *hptr, /* Pointer into hostname */
- *sptr; /* Pointer into ServerName */
- const char *shortname; /* Short queue name (queue) */
- char local_make_model[IPP_MAX_NAME];
- /* Local make and model */
- cupsd_printer_t *p; /* Printer information */
- const char *ipp_options, /* ipp-options value */
- *lease_duration, /* lease-duration value */
- *uuid; /* uuid value */
- int is_class; /* Is this queue a class? */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "process_browse_data(uri=\"%s\", host=\"%s\", "
- "resource=\"%s\", type=%x, state=%d, location=\"%s\", "
- "info=\"%s\", make_model=\"%s\", num_attrs=%d, attrs=%p)",
- uri, host, resource, type, state,
- location ? location : "(nil)", info ? info : "(nil)",
- make_model ? make_model : "(nil)", num_attrs, attrs);
-
- /*
- * Determine if the URI contains any illegal characters in it...
- */
-
- if (strncmp(uri, "ipp://", 6) || !host[0] ||
- (strncmp(resource, "/printers/", 10) &&
- strncmp(resource, "/classes/", 9)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad printer URI in browse data: %s", uri);
- return;
- }
-
- if (strchr(resource, '?') ||
- (!strncmp(resource, "/printers/", 10) && strchr(resource + 10, '/')) ||
- (!strncmp(resource, "/classes/", 9) && strchr(resource + 9, '/')))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad resource in browse data: %s",
- resource);
- return;
- }
-
- /*
- * OK, this isn't a local printer; add any remote options...
- */
-
- ipp_options = cupsGetOption("ipp-options", num_attrs, attrs);
-
- if (BrowseRemoteOptions)
- {
- if (BrowseRemoteOptions[0] == '?')
- {
- /*
- * Override server-supplied options...
- */
-
- snprintf(finaluri, sizeof(finaluri), "%s%s", uri, BrowseRemoteOptions);
- }
- else if (ipp_options)
- {
- /*
- * Combine the server and local options...
- */
-
- snprintf(finaluri, sizeof(finaluri), "%s?%s+%s", uri, ipp_options,
- BrowseRemoteOptions);
- }
- else
- {
- /*
- * Just use the local options...
- */
-
- snprintf(finaluri, sizeof(finaluri), "%s?%s", uri, BrowseRemoteOptions);
- }
-
- uri = finaluri;
- }
- else if (ipp_options)
- {
- /*
- * Just use the server-supplied options...
- */
-
- snprintf(finaluri, sizeof(finaluri), "%s?%s", uri, ipp_options);
- uri = finaluri;
- }
-
- /*
- * See if we already have it listed in the Printers list, and add it if not...
- */
-
- type |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED;
- type &= ~CUPS_PRINTER_IMPLICIT;
- update = 0;
- hptr = strchr(host, '.');
- sptr = strchr(ServerName, '.');
- is_class = type & CUPS_PRINTER_CLASS;
- uuid = cupsGetOption("uuid", num_attrs, attrs);
-
- if (!ServerNameIsIP && sptr != NULL && hptr != NULL)
- {
- /*
- * Strip the common domain name components...
- */
-
- while (hptr != NULL)
- {
- if (!_cups_strcasecmp(hptr, sptr))
- {
- *hptr = '\0';
- break;
- }
- else
- hptr = strchr(hptr + 1, '.');
- }
- }
-
- if (is_class)
- {
- /*
- * Remote destination is a class...
- */
-
- if (!strncmp(resource, "/classes/", 9))
- snprintf(name, sizeof(name), "%s@%s", resource + 9, host);
- else
- return;
-
- shortname = resource + 9;
- }
- else
- {
- /*
- * Remote destination is a printer...
- */
-
- if (!strncmp(resource, "/printers/", 10))
- snprintf(name, sizeof(name), "%s@%s", resource + 10, host);
- else
- return;
-
- shortname = resource + 10;
- }
-
- if (hptr && !*hptr)
- *hptr = '.'; /* Resource FQDN */
-
- if ((p = cupsdFindDest(name)) == NULL && BrowseShortNames)
- {
- /*
- * Long name doesn't exist, try short name...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "process_browse_data: %s not found...",
- name);
-
- if ((p = cupsdFindDest(shortname)) == NULL)
- {
- /*
- * Short name doesn't exist, use it for this shared queue.
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "process_browse_data: %s not found...",
- shortname);
- strlcpy(name, shortname, sizeof(name));
- }
- else
- {
- /*
- * Short name exists...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "process_browse_data: %s found, type=%x, hostname=%s...",
- shortname, p->type, p->hostname ? p->hostname : "(nil)");
-
- if (p->type & CUPS_PRINTER_IMPLICIT)
- p = NULL; /* Don't replace implicit classes */
- else if (p->hostname && _cups_strcasecmp(p->hostname, host))
- {
- /*
- * Short name exists but is for a different host. If this is a remote
- * queue, rename it and use the long name...
- */
-
- if (p->type & CUPS_PRINTER_REMOTE)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Renamed remote %s \"%s\" to \"%s@%s\"...",
- is_class ? "class" : "printer", p->name, p->name,
- p->hostname);
- cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, p, NULL,
- "%s \'%s\' deleted by directory services.",
- is_class ? "Class" : "Printer", p->name);
-
- snprintf(newname, sizeof(newname), "%s@%s", p->name, p->hostname);
- cupsdRenamePrinter(p, newname);
-
- cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL,
- "%s \'%s\' added by directory services.",
- is_class ? "Class" : "Printer", p->name);
- }
-
- /*
- * Force creation with long name...
- */
-
- p = NULL;
- }
- }
- }
- else if (p)
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "process_browse_data: %s found, type=%x, hostname=%s...",
- name, p->type, p->hostname ? p->hostname : "(nil)");
-
- if (!p)
- {
- /*
- * Queue doesn't exist; add it...
- */
-
- if (is_class)
- p = cupsdAddClass(name);
- else
- p = cupsdAddPrinter(name);
-
- if (!p)
- return;
-
- cupsdClearString(&(p->hostname));
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Added remote %s \"%s\"...",
- is_class ? "class" : "printer", name);
-
- cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL,
- "%s \'%s\' added by directory services.",
- is_class ? "Class" : "Printer", name);
-
- /*
- * Force the URI to point to the real server...
- */
-
- p->type = type & ~CUPS_PRINTER_REJECTING;
- p->accepting = 1;
-
- cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
- }
-
- if (!p->hostname)
- {
- /*
- * Hostname not set, so this must be a cached remote printer
- * that was created for a pending print job...
- */
-
- cupsdSetString(&p->hostname, host);
- cupsdSetString(&p->uri, uri);
- cupsdSetString(&p->device_uri, uri);
- update = 1;
-
- cupsdMarkDirty(CUPSD_DIRTY_REMOTE);
- }
-
- /*
- * Update the state...
- */
-
- p->state = state;
- p->browse_time = time(NULL);
-
- if ((lease_duration = cupsGetOption("lease-duration", num_attrs,
- attrs)) != NULL)
- {
- /*
- * Grab the lease-duration for the browse data; anything less then 1
- * second or more than 1 week gets the default BrowseTimeout...
- */
-
- i = atoi(lease_duration);
- if (i < 1 || i > 604800)
- i = BrowseTimeout;
-
- p->browse_expire = p->browse_time + i;
- }
- else
- p->browse_expire = p->browse_time + BrowseTimeout;
-
- if (type & CUPS_PRINTER_REJECTING)
- {
- type &= ~CUPS_PRINTER_REJECTING;
-
- if (p->accepting)
- {
- update = 1;
- p->accepting = 0;
- }
- }
- else if (!p->accepting)
- {
- update = 1;
- p->accepting = 1;
- }
-
- if (p->type != type)
- {
- p->type = type;
- update = 1;
- }
-
- if (uuid && strcmp(p->uuid, uuid))
- {
- cupsdSetString(&p->uuid, uuid);
- update = 1;
- }
-
- if (location && (!p->location || strcmp(p->location, location)))
- {
- cupsdSetString(&p->location, location);
- update = 1;
- }
-
- if (info && (!p->info || strcmp(p->info, info)))
- {
- cupsdSetString(&p->info, info);
- update = 1;
-
- cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP | CUPSD_DIRTY_REMOTE);
- }
-
- if (!make_model || !make_model[0])
- {
- if (is_class)
- snprintf(local_make_model, sizeof(local_make_model),
- "Remote Class on %s", host);
- else
- snprintf(local_make_model, sizeof(local_make_model),
- "Remote Printer on %s", host);
- }
- else
- snprintf(local_make_model, sizeof(local_make_model),
- "%s on %s", make_model, host);
-
- if (!p->make_model || strcmp(p->make_model, local_make_model))
- {
- cupsdSetString(&p->make_model, local_make_model);
- update = 1;
- }
-
- if (p->num_options)
- {
- if (!update && !(type & CUPS_PRINTER_DELETE))
- {
- /*
- * See if we need to update the attributes...
- */
-
- if (p->num_options != num_attrs)
- update = 1;
- else
- {
- for (i = 0; i < num_attrs; i ++)
- if (strcmp(attrs[i].name, p->options[i].name) ||
- (!attrs[i].value != !p->options[i].value) ||
- (attrs[i].value && strcmp(attrs[i].value, p->options[i].value)))
- {
- update = 1;
- break;
- }
- }
- }
-
- /*
- * Free the old options...
- */
-
- cupsFreeOptions(p->num_options, p->options);
- }
-
- p->num_options = num_attrs;
- p->options = attrs;
-
- if (type & CUPS_PRINTER_DELETE)
- {
- cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, p, NULL,
- "%s \'%s\' deleted by directory services.",
- is_class ? "Class" : "Printer", p->name);
-
- cupsdExpireSubscriptions(p, NULL);
-
- cupsdDeletePrinter(p, 1);
- cupsdUpdateImplicitClasses();
- cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP | CUPSD_DIRTY_REMOTE);
- }
- else if (update)
- {
- cupsdSetPrinterAttrs(p);
- cupsdUpdateImplicitClasses();
- }
-
- /*
- * See if we have a default printer... If not, make the first network
- * default printer the default.
- */
-
- if (DefaultPrinter == NULL && Printers != NULL && UseNetworkDefault)
- {
- /*
- * Find the first network default printer and use it...
- */
-
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (p->type & CUPS_PRINTER_DEFAULT)
- {
- DefaultPrinter = p;
- cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP | CUPSD_DIRTY_REMOTE);
- break;
- }
- }
-
- /*
- * Do auto-classing if needed...
- */
-
- process_implicit_classes();
-}
-
-
-/*
- * 'process_implicit_classes()' - Create/update implicit classes as needed.
- */
-
-static void
-process_implicit_classes(void)
-{
- int i; /* Looping var */
- int update; /* Update printer attributes? */
- char name[IPP_MAX_NAME], /* Name of printer */
- *hptr; /* Pointer into hostname */
- cupsd_printer_t *p, /* Printer information */
- *pclass, /* Printer class */
- *first; /* First printer in class */
- int offset, /* Offset of name */
- len; /* Length of name */
-
-
- if (!ImplicitClasses || !Printers)
- return;
-
- /*
- * Loop through all available printers and create classes as needed...
- */
-
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers), len = 0, offset = 0,
- update = 0, pclass = NULL, first = NULL;
- p != NULL;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- {
- /*
- * Skip implicit classes...
- */
-
- if (p->type & CUPS_PRINTER_IMPLICIT)
- {
- len = 0;
- continue;
- }
-
- /*
- * If len == 0, get the length of this printer name up to the "@"
- * sign (if any).
- */
-
- cupsArraySave(Printers);
-
- if (len > 0 &&
- !_cups_strncasecmp(p->name, name + offset, len) &&
- (p->name[len] == '\0' || p->name[len] == '@'))
- {
- /*
- * We have more than one printer with the same name; see if
- * we have a class, and if this printer is a member...
- */
-
- if (pclass && _cups_strcasecmp(pclass->name, name))
- {
- if (update)
- cupsdSetPrinterAttrs(pclass);
-
- update = 0;
- pclass = NULL;
- }
-
- if (!pclass && (pclass = cupsdFindDest(name)) == NULL)
- {
- /*
- * Need to add the class...
- */
-
- pclass = cupsdAddPrinter(name);
- cupsArrayAdd(ImplicitPrinters, pclass);
-
- pclass->type |= CUPS_PRINTER_IMPLICIT;
- pclass->accepting = 1;
- pclass->state = IPP_PRINTER_IDLE;
-
- cupsdSetString(&pclass->location, p->location);
- cupsdSetString(&pclass->info, p->info);
-
- cupsdSetString(&pclass->job_sheets[0], p->job_sheets[0]);
- cupsdSetString(&pclass->job_sheets[1], p->job_sheets[1]);
-
- update = 1;
-
- cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP | CUPSD_DIRTY_REMOTE);
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Added implicit class \"%s\"...",
- name);
- cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL,
- "Implicit class \'%s\' added by directory services.",
- name);
- }
-
- if (first != NULL)
- {
- for (i = 0; i < pclass->num_printers; i ++)
- if (pclass->printers[i] == first)
- break;
-
- if (i >= pclass->num_printers)
- {
- first->in_implicit_class = 1;
- cupsdAddPrinterToClass(pclass, first);
- }
-
- first = NULL;
- }
-
- for (i = 0; i < pclass->num_printers; i ++)
- if (pclass->printers[i] == p)
- break;
-
- if (i >= pclass->num_printers)
- {
- p->in_implicit_class = 1;
- cupsdAddPrinterToClass(pclass, p);
- update = 1;
- }
- }
- else
- {
- /*
- * First time around; just get name length and mark it as first
- * in the list...
- */
-
- if ((hptr = strchr(p->name, '@')) != NULL)
- len = hptr - p->name;
- else
- len = strlen(p->name);
-
- if (len >= sizeof(name))
- {
- /*
- * If the printer name length somehow is greater than we normally allow,
- * skip this printer...
- */
-
- len = 0;
- cupsArrayRestore(Printers);
- continue;
- }
-
- strncpy(name, p->name, len);
- name[len] = '\0';
- offset = 0;
-
- if ((first = (hptr ? cupsdFindDest(name) : p)) != NULL &&
- !(first->type & CUPS_PRINTER_IMPLICIT))
- {
- /*
- * Can't use same name as a local printer; add "Any" to the
- * front of the name, unless we have explicitly disabled
- * the "ImplicitAnyClasses"...
- */
-
- if (ImplicitAnyClasses && len < (sizeof(name) - 4))
- {
- /*
- * Add "Any" to the class name...
- */
-
- strcpy(name, "Any");
- strncpy(name + 3, p->name, len);
- name[len + 3] = '\0';
- offset = 3;
- }
- else
- {
- /*
- * Don't create an implicit class if we have a local printer
- * with the same name...
- */
-
- len = 0;
- cupsArrayRestore(Printers);
- continue;
- }
- }
-
- first = p;
- }
-
- cupsArrayRestore(Printers);
- }
-
- /*
- * Update the last printer class as needed...
- */
-
- if (pclass && update)
- cupsdSetPrinterAttrs(pclass);
-}
-
-
-/*
- * 'send_cups_browse()' - Send new browsing information using the CUPS
- * protocol.
- */
-
-static void
-send_cups_browse(cupsd_printer_t *p) /* I - Printer to send */
-{
- int i; /* Looping var */
- cups_ptype_t type; /* Printer type */
- cupsd_dirsvc_addr_t *b; /* Browse address */
- int bytes; /* Length of packet */
- char packet[1453], /* Browse data packet */
- uri[1024], /* Printer URI */
- location[1024], /* printer-location */
- info[1024], /* printer-info */
- make_model[1024],
- /* printer-make-and-model */
- air[1024]; /* auth-info-required */
- cupsd_netif_t *iface; /* Network interface */
-
-
- /*
- * Figure out the printer type value...
- */
-
- type = p->type | CUPS_PRINTER_REMOTE;
-
- if (!p->accepting)
- type |= CUPS_PRINTER_REJECTING;
-
- if (p == DefaultPrinter)
- type |= CUPS_PRINTER_DEFAULT;
-
- /*
- * Remove quotes from printer-info, printer-location, and
- * printer-make-and-model attributes...
- */
-
- dequote(location, p->location, sizeof(location));
- dequote(info, p->info, sizeof(info));
-
- if (p->make_model)
- dequote(make_model, p->make_model, sizeof(make_model));
- else if (p->type & CUPS_PRINTER_CLASS)
- {
- if (p->num_printers > 0 && p->printers[0]->make_model)
- strlcpy(make_model, p->printers[0]->make_model, sizeof(make_model));
- else
- strlcpy(make_model, "Local Printer Class", sizeof(make_model));
- }
- else if (p->raw)
- strlcpy(make_model, "Local Raw Printer", sizeof(make_model));
- else
- strlcpy(make_model, "Local System V Printer", sizeof(make_model));
-
- if (get_auth_info_required(p, packet, sizeof(packet)))
- snprintf(air, sizeof(air), " auth-info-required=%s", packet);
- else
- air[0] = '\0';
-
- /*
- * Send a packet to each browse address...
- */
-
- for (i = NumBrowsers, b = Browsers; i > 0; i --, b ++)
- if (b->iface[0])
- {
- /*
- * Send the browse packet to one or more interfaces...
- */
-
- if (!strcmp(b->iface, "*"))
- {
- /*
- * Send to all local interfaces...
- */
-
- cupsdNetIFUpdate();
-
- for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList);
- iface;
- iface = (cupsd_netif_t *)cupsArrayNext(NetIFList))
- {
- /*
- * Only send to local, IPv4 interfaces...
- */
-
- if (!iface->is_local || !iface->port ||
- iface->address.addr.sa_family != AF_INET)
- continue;
-
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- iface->hostname, iface->port,
- (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s" :
- "/printers/%s",
- p->name);
- snprintf(packet, sizeof(packet),
- "%x %x %s \"%s\" \"%s\" \"%s\" %s%s uuid=%s\n",
- type, p->state, uri, location, info, make_model,
- p->browse_attrs ? p->browse_attrs : "", air, p->uuid);
-
- bytes = strlen(packet);
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdSendBrowseList: (%d bytes to \"%s\") %s", bytes,
- iface->name, packet);
-
- iface->broadcast.ipv4.sin_port = htons(BrowsePort);
-
- sendto(BrowseSocket, packet, bytes, 0,
- (struct sockaddr *)&(iface->broadcast),
- httpAddrLength(&(iface->broadcast)));
- }
- }
- else if ((iface = cupsdNetIFFind(b->iface)) != NULL)
- {
- /*
- * Send to the named interface using the IPv4 address...
- */
-
- while (iface)
- if (strcmp(b->iface, iface->name))
- {
- iface = NULL;
- break;
- }
- else if (iface->address.addr.sa_family == AF_INET && iface->port)
- break;
- else
- iface = (cupsd_netif_t *)cupsArrayNext(NetIFList);
-
- if (iface)
- {
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- iface->hostname, iface->port,
- (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s" :
- "/printers/%s",
- p->name);
- snprintf(packet, sizeof(packet),
- "%x %x %s \"%s\" \"%s\" \"%s\" %s%s uuid=%s\n",
- type, p->state, uri, location, info, make_model,
- p->browse_attrs ? p->browse_attrs : "", air, p->uuid);
-
- bytes = strlen(packet);
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdSendBrowseList: (%d bytes to \"%s\") %s", bytes,
- iface->name, packet);
-
- iface->broadcast.ipv4.sin_port = htons(BrowsePort);
-
- sendto(BrowseSocket, packet, bytes, 0,
- (struct sockaddr *)&(iface->broadcast),
- httpAddrLength(&(iface->broadcast)));
- }
- }
- }
- else
- {
- /*
- * Send the browse packet to the indicated address using
- * the default server name...
- */
-
- snprintf(packet, sizeof(packet),
- "%x %x %s \"%s\" \"%s\" \"%s\" %s%s uuid=%s\n",
- type, p->state, p->uri, location, info, make_model,
- p->browse_attrs ? p->browse_attrs : "", air, p->uuid);
-
- bytes = strlen(packet);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdSendBrowseList: (%d bytes) %s", bytes, packet);
-
- if (sendto(BrowseSocket, packet, bytes, 0,
- (struct sockaddr *)&(b->to),
- httpAddrLength(&(b->to))) <= 0)
- {
- /*
- * Unable to send browse packet, so remove this address from the
- * list...
- */
-
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdSendBrowseList: sendto failed for browser "
- "%d - %s.",
- (int)(b - Browsers + 1), strerror(errno));
-
- if (i > 1)
- memmove(b, b + 1, (i - 1) * sizeof(cupsd_dirsvc_addr_t));
-
- b --;
- NumBrowsers --;
- }
- }
-}
-
-
-#ifdef HAVE_LDAP
-/*
- * 'ldap_search_rec()' - LDAP Search with reconnect
- */
-
-static int /* O - Return code */
-ldap_search_rec(LDAP *ld, /* I - LDAP handler */
- char *base, /* I - Base dn */
- int scope, /* I - LDAP search scope */
- char *filter, /* I - Filter string */
- char *attrs[], /* I - Requested attributes */
- int attrsonly, /* I - Return only attributes? */
- LDAPMessage **res) /* I - LDAP handler */
-{
- int rc; /* Return code */
- LDAP *ldr; /* LDAP handler after reconnect */
-
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- rc = ldap_search_ext_s(ld, base, scope, filter, attrs, attrsonly, NULL, NULL,
- NULL, LDAP_NO_LIMIT, res);
-# else
- rc = ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res);
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
-
- /*
- * If we have a connection problem try again...
- */
-
- if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "LDAP search failed with status %d: %s",
- rc, ldap_err2string(rc));
- cupsdLogMessage(CUPSD_LOG_INFO,
- "We try the LDAP search once again after reconnecting to "
- "the server");
- ldap_freeres(*res);
- ldr = ldap_reconnect();
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- rc = ldap_search_ext_s(ldr, base, scope, filter, attrs, attrsonly, NULL,
- NULL, NULL, LDAP_NO_LIMIT, res);
-# else
- rc = ldap_search_s(ldr, base, scope, filter, attrs, attrsonly, res);
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
- }
-
- if (rc == LDAP_NO_SUCH_OBJECT)
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "ldap_search_rec: LDAP entry/object not found");
- else if (rc != LDAP_SUCCESS)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "ldap_search_rec: LDAP search failed with status %d: %s",
- rc, ldap_err2string(rc));
-
- if (rc != LDAP_SUCCESS)
- ldap_freeres(*res);
-
- return (rc);
-}
-
-
-/*
- * 'ldap_freeres()' - Free LDAPMessage
- */
-
-static void
-ldap_freeres(LDAPMessage *entry) /* I - LDAP handler */
-{
- int rc; /* Return value */
-
-
- rc = ldap_msgfree(entry);
- if (rc == -1)
- cupsdLogMessage(CUPSD_LOG_WARN, "Can't free LDAPMessage!");
- else if (rc == 0)
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "Freeing LDAPMessage was unnecessary");
-}
-
-
-/*
- * 'ldap_getval_char()' - Get first LDAP value and convert to string
- */
-
-static int /* O - Return code */
-ldap_getval_firststring(
- LDAP *ld, /* I - LDAP handler */
- LDAPMessage *entry, /* I - LDAP message or search result */
- char *attr, /* I - the wanted attribute */
- char *retval, /* O - String to return */
- unsigned long maxsize) /* I - Max string size */
-{
- char *dn; /* LDAP DN */
- int rc = 0; /* Return code */
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- struct berval **bval; /* LDAP value array */
- unsigned long size; /* String size */
-
-
- /*
- * Get value from LDAPMessage...
- */
-
- if ((bval = ldap_get_values_len(ld, entry, attr)) == NULL)
- {
- rc = -1;
- dn = ldap_get_dn(ld, entry);
- cupsdLogMessage(CUPSD_LOG_WARN,
- "Failed to get LDAP value %s for %s!",
- attr, dn);
- ldap_memfree(dn);
- }
- else
- {
- /*
- * Check size and copy value into our string...
- */
-
- size = maxsize;
- if (size < (bval[0]->bv_len + 1))
- {
- rc = -1;
- dn = ldap_get_dn(ld, entry);
- cupsdLogMessage(CUPSD_LOG_WARN,
- "Attribute %s is too big! (dn: %s)",
- attr, dn);
- ldap_memfree(dn);
- }
- else
- size = bval[0]->bv_len + 1;
-
- strlcpy(retval, bval[0]->bv_val, size);
- ldap_value_free_len(bval);
- }
-# else
- char **value; /* LDAP value */
-
- /*
- * Get value from LDAPMessage...
- */
-
- if ((value = (char **)ldap_get_values(ld, entry, attr)) == NULL)
- {
- rc = -1;
- dn = ldap_get_dn(ld, entry);
- cupsdLogMessage(CUPSD_LOG_WARN, "Failed to get LDAP value %s for %s!",
- attr, dn);
- ldap_memfree(dn);
- }
- else
- {
- strlcpy(retval, *value, maxsize);
- ldap_value_free(value);
- }
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
-
- return (rc);
-}
-
-
-/*
- * 'send_ldap_ou()' - Send LDAP ou registrations.
- */
-
-static void
-send_ldap_ou(char *ou, /* I - Servername/ou to register */
- char *basedn, /* I - Our base dn */
- char *descstring) /* I - Description for ou */
-{
- int i; /* Looping var... */
- LDAPMod mods[3]; /* The 3 attributes we will be adding */
- LDAPMod *pmods[4]; /* Pointers to the 3 attributes + NULL */
- LDAPMessage *res, /* Search result token */
- *e; /* Current entry from search */
- int rc; /* LDAP status */
- int rcmod; /* LDAP status for modifications */
- char dn[1024], /* DN of the organizational unit we are adding */
- *desc[2], /* Change records */
- *ou_value[2];
- char old_desc[1024]; /* Old description */
- static const char * const objectClass_values[] =
- { /* The 2 objectClass's we use in */
- "top", /* our LDAP entries */
- "organizationalUnit",
- NULL
- };
- static const char * const ou_attrs[] =/* CUPS LDAP attributes */
- {
- "description",
- NULL
- };
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_ou: %s", ou);
-
- /*
- * Reconnect if LDAP Handle is invalid...
- */
-
- if (!BrowseLDAPHandle)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "send_ldap_ou: LDAP Handle is invalid. Try reconnecting...");
- ldap_reconnect();
- return;
- }
-
- /*
- * Prepare ldap search...
- */
-
- snprintf(dn, sizeof(dn), "ou=%s, %s", ou, basedn);
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_ou: dn=\"%s\"", dn);
-
- ou_value[0] = ou;
- ou_value[1] = NULL;
- desc[0] = descstring;
- desc[1] = NULL;
-
- mods[0].mod_type = "ou";
- mods[0].mod_values = ou_value;
- mods[1].mod_type = "description";
- mods[1].mod_values = desc;
- mods[2].mod_type = "objectClass";
- mods[2].mod_values = (char **)objectClass_values;
-
- rc = ldap_search_rec(BrowseLDAPHandle, dn, LDAP_SCOPE_BASE, NULL,
- (char **)ou_attrs, 0, &res);
-
- /*
- * If ldap search was not successfull then exit function...
- */
-
- if (rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT)
- return;
-
- /*
- * Check if we need to insert or update the LDAP entry...
- */
-
- if (ldap_count_entries(BrowseLDAPHandle, res) > 0 &&
- rc != LDAP_NO_SUCH_OBJECT)
- {
- /*
- * Printserver has already been registered, check if
- * modification is required...
- */
-
- e = ldap_first_entry(BrowseLDAPHandle, res);
-
- /*
- * Get the required values from this entry...
- */
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e, "description", old_desc,
- sizeof(old_desc)) == -1)
- old_desc[0] = '\0';
-
- /*
- * Check if modification is required...
- */
-
- if ( strcmp(desc[0], old_desc) == 0 )
- {
- /*
- * LDAP entry for the printer exists.
- * Printer has already been registered,
- * no modifications required...
- */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "send_ldap_ou: No updates required for %s", ou);
- }
- else
- {
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "send_ldap_ou: Replace entry for %s", ou);
-
- for (i = 0; i < 3; i ++)
- {
- pmods[i] = mods + i;
- pmods[i]->mod_op = LDAP_MOD_REPLACE;
- }
- pmods[i] = NULL;
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- if ((rcmod = ldap_modify_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
- NULL)) != LDAP_SUCCESS)
-# else
- if ((rcmod = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "LDAP modify for %s failed with status %d: %s",
- ou, rcmod, ldap_err2string(rcmod));
- if (rcmod == LDAP_SERVER_DOWN)
- ldap_reconnect();
- }
- }
- }
- else
- {
- /*
- * Printserver has never been registered,
- * add registration...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "send_ldap_ou: Add entry for %s", ou);
-
- for (i = 0; i < 3; i ++)
- {
- pmods[i] = mods + i;
- pmods[i]->mod_op = LDAP_MOD_ADD;
- }
- pmods[i] = NULL;
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- if ((rcmod = ldap_add_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
- NULL)) != LDAP_SUCCESS)
-# else
- if ((rcmod = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "LDAP add for %s failed with status %d: %s",
- ou, rcmod, ldap_err2string(rcmod));
- if (rcmod == LDAP_SERVER_DOWN)
- ldap_reconnect();
- }
- }
-
- if (rc == LDAP_SUCCESS)
- ldap_freeres(res);
-}
-
-
-/*
- * 'send_ldap_browse()' - Send LDAP printer registrations.
- */
-
-static void
-send_ldap_browse(cupsd_printer_t *p) /* I - Printer to register */
-{
- int i; /* Looping var... */
- LDAPMod mods[7]; /* The 7 attributes we will be adding */
- LDAPMod *pmods[8]; /* Pointers to the 7 attributes + NULL */
- LDAPMessage *res, /* Search result token */
- *e; /* Current entry from search */
- char *cn_value[2], /* Change records */
- *uri[2],
- *info[2],
- *location[2],
- *make_model[2],
- *type[2],
- typestring[255], /* String to hold printer-type */
- dn[1024]; /* DN of the printer we are adding */
- int rc; /* LDAP status */
- int rcmod; /* LDAP status for modifications */
- char old_uri[HTTP_MAX_URI], /* Printer URI */
- old_location[1024], /* Printer location */
- old_info[1024], /* Printer information */
- old_make_model[1024], /* Printer make and model */
- old_type_string[30]; /* Temporary type number */
- int old_type; /* Printer type */
- static const char * const objectClass_values[] =
- { /* The 3 objectClass's we use in */
- "top", /* our LDAP entries */
- "device",
- "cupsPrinter",
- NULL
- };
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_browse: %s", p->name);
-
- /*
- * Exit function if LDAP updates has been disabled...
- */
-
- if (!BrowseLDAPUpdate)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "send_ldap_browse: Updates temporary disabled; "
- "skipping...");
- return;
- }
-
- /*
- * Reconnect if LDAP Handle is invalid...
- */
-
- if (!BrowseLDAPHandle)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "send_ldap_browse: LDAP Handle is invalid. Try "
- "reconnecting...");
- ldap_reconnect();
- return;
- }
-
- /*
- * Everything in ldap is ** so we fudge around it...
- */
-
- sprintf(typestring, "%u", p->type);
-
- cn_value[0] = p->name;
- cn_value[1] = NULL;
- info[0] = p->info ? p->info : "Unknown";
- info[1] = NULL;
- location[0] = p->location ? p->location : "Unknown";
- location[1] = NULL;
- make_model[0] = p->make_model ? p->make_model : "Unknown";
- make_model[1] = NULL;
- type[0] = typestring;
- type[1] = NULL;
- uri[0] = p->uri;
- uri[1] = NULL;
-
- /*
- * Get ldap entry for printer ...
- */
-
- snprintf(dn, sizeof(dn), "cn=%s, ou=%s, %s", p->name, ServerName,
- BrowseLDAPDN);
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_browse: dn=\"%s\"", dn);
-
- rc = ldap_search_rec(BrowseLDAPHandle, dn, LDAP_SCOPE_BASE, NULL,
- (char **)ldap_attrs, 0, &res);
-
- /*
- * If ldap search was not successfull then exit function
- * and temporary disable LDAP updates...
- */
-
- if (rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT)
- {
- if (BrowseLDAPUpdate &&
- (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR))
- {
- BrowseLDAPUpdate = FALSE;
- cupsdLogMessage(CUPSD_LOG_INFO,
- "LDAP update temporary disabled");
- }
-
- return;
- }
-
- /*
- * Fill modification array...
- */
-
- mods[0].mod_type = "cn";
- mods[0].mod_values = cn_value;
- mods[1].mod_type = "printerDescription";
- mods[1].mod_values = info;
- mods[2].mod_type = "printerURI";
- mods[2].mod_values = uri;
- mods[3].mod_type = "printerLocation";
- mods[3].mod_values = location;
- mods[4].mod_type = "printerMakeAndModel";
- mods[4].mod_values = make_model;
- mods[5].mod_type = "printerType";
- mods[5].mod_values = type;
- mods[6].mod_type = "objectClass";
- mods[6].mod_values = (char **)objectClass_values;
-
- /*
- * Check if we need to insert or update the LDAP entry...
- */
-
- if (ldap_count_entries(BrowseLDAPHandle, res) > 0 &&
- rc != LDAP_NO_SUCH_OBJECT)
- {
- /*
- * Printer has already been registered, check if
- * modification is required...
- */
-
- e = ldap_first_entry(BrowseLDAPHandle, res);
-
- /*
- * Get the required values from this entry...
- */
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e, "printerDescription",
- old_info, sizeof(old_info)) == -1)
- old_info[0] = '\0';
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e, "printerLocation",
- old_location, sizeof(old_location)) == -1)
- old_info[0] = '\0';
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e, "printerMakeAndModel",
- old_make_model, sizeof(old_make_model)) == -1)
- old_info[0] = '\0';
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e, "printerType",
- old_type_string, sizeof(old_type_string)) == -1)
- old_info[0] = '\0';
-
- old_type = atoi(old_type_string);
-
- if (ldap_getval_firststring(BrowseLDAPHandle, e, "printerURI", old_uri,
- sizeof(old_uri)) == -1)
- old_info[0] = '\0';
-
- /*
- * Check if modification is required...
- */
-
- if (!strcmp(info[0], old_info) && !strcmp(uri[0], old_uri) &&
- !strcmp(location[0], old_location) &&
- !strcmp(make_model[0], old_make_model) && p->type == old_type)
- {
- /*
- * LDAP entry for the printer exists. Printer has already been registered,
- * no modifications required...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "send_ldap_browse: No updates required for %s", p->name);
- }
- else
- {
- /*
- * LDAP entry for the printer exists. Printer has already been registered,
- * modify the current registration...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "send_ldap_browse: Replace entry for %s", p->name);
-
- for (i = 0; i < 7; i ++)
- {
- pmods[i] = mods + i;
- pmods[i]->mod_op = LDAP_MOD_REPLACE;
- }
- pmods[i] = NULL;
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- if ((rcmod = ldap_modify_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
- NULL)) != LDAP_SUCCESS)
-# else
- if ((rcmod = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "LDAP modify for %s failed with status %d: %s",
- p->name, rcmod, ldap_err2string(rcmod));
- if (rcmod == LDAP_SERVER_DOWN)
- ldap_reconnect();
- }
- }
- }
- else
- {
- /*
- * No LDAP entry exists for the printer. Printer has never been registered,
- * add the current registration...
- */
-
- send_ldap_ou(ServerName, BrowseLDAPDN, "CUPS Server");
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "send_ldap_browse: Add entry for %s", p->name);
-
- for (i = 0; i < 7; i ++)
- {
- pmods[i] = mods + i;
- pmods[i]->mod_op = LDAP_MOD_ADD;
- }
- pmods[i] = NULL;
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- if ((rcmod = ldap_add_ext_s(BrowseLDAPHandle, dn, pmods, NULL,
- NULL)) != LDAP_SUCCESS)
-# else
- if ((rcmod = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS)
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "LDAP add for %s failed with status %d: %s",
- p->name, rcmod, ldap_err2string(rcmod));
- if (rcmod == LDAP_SERVER_DOWN)
- ldap_reconnect();
- }
- }
-
- if (rc == LDAP_SUCCESS)
- ldap_freeres(res);
-}
-
-
-/*
- * 'ldap_dereg_printer()' - Delete printer from directory
- */
-
-static void
-ldap_dereg_printer(cupsd_printer_t *p) /* I - Printer to deregister */
-{
- char dn[1024]; /* DN of the printer */
- int rc; /* LDAP status */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_dereg_printer: Remove entry for %s",
- p->name);
-
- /*
- * Reconnect if LDAP Handle is invalid...
- */
-
- if (!BrowseLDAPHandle)
- {
- ldap_reconnect();
- return;
- }
-
- /*
- * Get dn for printer and delete LDAP entry...
- */
-
- snprintf(dn, sizeof(dn), "cn=%s, ou=%s, %s", p->name, ServerName,
- BrowseLDAPDN);
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_dereg_printer: dn=\"%s\"", dn);
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- if ((rc = ldap_delete_ext_s(BrowseLDAPHandle, dn, NULL,
- NULL)) != LDAP_SUCCESS)
-# else
- if ((rc = ldap_delete_s(BrowseLDAPHandle, dn)) != LDAP_SUCCESS)
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
- {
- cupsdLogMessage(CUPSD_LOG_WARN,
- "LDAP delete for %s failed with status %d: %s",
- p->name, rc, ldap_err2string(rc));
-
- /*
- * If we had a connection problem (connection timed out, etc.)
- * we should reconnect and try again to delete the entry...
- */
-
- if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
- {
- cupsdLogMessage(CUPSD_LOG_INFO,
- "Retry deleting LDAP entry for %s after a reconnect...", p->name);
- ldap_reconnect();
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- if ((rc = ldap_delete_ext_s(BrowseLDAPHandle, dn, NULL,
- NULL)) != LDAP_SUCCESS)
-# else
- if ((rc = ldap_delete_s(BrowseLDAPHandle, dn)) != LDAP_SUCCESS)
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
- cupsdLogMessage(CUPSD_LOG_WARN,
- "LDAP delete for %s failed with status %d: %s",
- p->name, rc, ldap_err2string(rc));
- }
- }
-}
-
-
-/*
- * 'ldap_dereg_ou()' - Remove the organizational unit.
- */
-
-static void
-ldap_dereg_ou(char *ou, /* I - Organizational unit (servername) */
- char *basedn) /* I - Dase dn */
-{
- char dn[1024]; /* DN of the printer */
- int rc; /* LDAP status */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_dereg_ou: Remove entry for %s", ou);
-
- /*
- * Reconnect if LDAP Handle is invalid...
- */
-
- if (!BrowseLDAPHandle)
- {
- ldap_reconnect();
- return;
- }
-
- /*
- * Get dn for printer and delete LDAP entry...
- */
-
- snprintf(dn, sizeof(dn), "ou=%s, %s", ou, basedn);
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_dereg_ou: dn=\"%s\"", dn);
-
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- if ((rc = ldap_delete_ext_s(BrowseLDAPHandle, dn, NULL,
- NULL)) != LDAP_SUCCESS)
-# else
- if ((rc = ldap_delete_s(BrowseLDAPHandle, dn)) != LDAP_SUCCESS)
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
- {
- cupsdLogMessage(CUPSD_LOG_WARN,
- "LDAP delete for %s failed with status %d: %s",
- ou, rc, ldap_err2string(rc));
-
- /*
- * If we had a connection problem (connection timed out, etc.)
- * we should reconnect and try again to delete the entry...
- */
-
- if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)
- {
- cupsdLogMessage(CUPSD_LOG_INFO,
- "Retry deleting LDAP entry for %s after a reconnect...", ou);
- ldap_reconnect();
-# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000
- if ((rc = ldap_delete_ext_s(BrowseLDAPHandle, dn, NULL,
- NULL)) != LDAP_SUCCESS)
-# else
- if ((rc = ldap_delete_s(BrowseLDAPHandle, dn)) != LDAP_SUCCESS)
-# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */
- cupsdLogMessage(CUPSD_LOG_WARN,
- "LDAP delete for %s failed with status %d: %s",
- ou, rc, ldap_err2string(rc));
- }
- }
-}
-#endif /* HAVE_LDAP */
-
-
-#ifdef HAVE_LIBSLP
-/*
- * 'send_slp_browse()' - Register the specified printer with SLP.
- */
-
-static void
-send_slp_browse(cupsd_printer_t *p) /* I - Printer to register */
-{
- char srvurl[HTTP_MAX_URI], /* Printer service URI */
- attrs[8192], /* Printer attributes */
- finishings[1024], /* Finishings to support */
- make_model[IPP_MAX_NAME * 2],
- /* Make and model, quoted */
- location[IPP_MAX_NAME * 2],
- /* Location, quoted */
- info[IPP_MAX_NAME * 2], /* Info, quoted */
- *src, /* Pointer to original string */
- *dst; /* Pointer to destination string */
- ipp_attribute_t *authentication; /* uri-authentication-supported value */
- SLPError error; /* SLP error, if any */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "send_slp_browse(%p = \"%s\")", p,
- p->name);
-
- /*
- * Make the SLP service URL that conforms to the IANA
- * 'printer:' template.
- */
-
- snprintf(srvurl, sizeof(srvurl), SLP_CUPS_SRVTYPE ":%s", p->uri);
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "Service URL = \"%s\"", srvurl);
-
- /*
- * Figure out the finishings string...
- */
-
- if (p->type & CUPS_PRINTER_STAPLE)
- strcpy(finishings, "staple");
- else
- finishings[0] = '\0';
-
- if (p->type & CUPS_PRINTER_BIND)
- {
- if (finishings[0])
- strlcat(finishings, ",bind", sizeof(finishings));
- else
- strcpy(finishings, "bind");
- }
-
- if (p->type & CUPS_PRINTER_PUNCH)
- {
- if (finishings[0])
- strlcat(finishings, ",punch", sizeof(finishings));
- else
- strcpy(finishings, "punch");
- }
-
- if (p->type & CUPS_PRINTER_COVER)
- {
- if (finishings[0])
- strlcat(finishings, ",cover", sizeof(finishings));
- else
- strcpy(finishings, "cover");
- }
-
- if (p->type & CUPS_PRINTER_SORT)
- {
- if (finishings[0])
- strlcat(finishings, ",sort", sizeof(finishings));
- else
- strcpy(finishings, "sort");
- }
-
- if (!finishings[0])
- strcpy(finishings, "none");
-
- /*
- * Quote any commas in the make and model, location, and info strings...
- */
-
- for (src = p->make_model, dst = make_model;
- src && *src && dst < (make_model + sizeof(make_model) - 2);)
- {
- if (*src == ',' || *src == '\\' || *src == ')')
- *dst++ = '\\';
-
- *dst++ = *src++;
- }
-
- *dst = '\0';
-
- if (!make_model[0])
- strcpy(make_model, "Unknown");
-
- for (src = p->location, dst = location;
- src && *src && dst < (location + sizeof(location) - 2);)
- {
- if (*src == ',' || *src == '\\' || *src == ')')
- *dst++ = '\\';
-
- *dst++ = *src++;
- }
-
- *dst = '\0';
-
- if (!location[0])
- strcpy(location, "Unknown");
-
- for (src = p->info, dst = info;
- src && *src && dst < (info + sizeof(info) - 2);)
- {
- if (*src == ',' || *src == '\\' || *src == ')')
- *dst++ = '\\';
-
- *dst++ = *src++;
- }
-
- *dst = '\0';
-
- if (!info[0])
- strcpy(info, "Unknown");
-
- /*
- * Get the authentication value...
- */
-
- authentication = ippFindAttribute(p->attrs, "uri-authentication-supported",
- IPP_TAG_KEYWORD);
-
- /*
- * Make the SLP attribute string list that conforms to
- * the IANA 'printer:' template.
- */
-
- snprintf(attrs, sizeof(attrs),
- "(printer-uri-supported=%s),"
- "(uri-authentication-supported=%s>),"
-#ifdef HAVE_SSL
- "(uri-security-supported=tls>),"
-#else
- "(uri-security-supported=none>),"
-#endif /* HAVE_SSL */
- "(printer-name=%s),"
- "(printer-location=%s),"
- "(printer-info=%s),"
- "(printer-more-info=%s),"
- "(printer-make-and-model=%s),"
- "(printer-type=%d),"
- "(charset-supported=utf-8),"
- "(natural-language-configured=%s),"
- "(natural-language-supported=de,en,es,fr,it),"
- "(color-supported=%s),"
- "(finishings-supported=%s),"
- "(sides-supported=one-sided%s),"
- "(multiple-document-jobs-supported=true)"
- "(ipp-versions-supported=1.0,1.1)",
- p->uri, authentication->values[0].string.text, p->name, location,
- info, p->uri, make_model, p->type, DefaultLanguage,
- p->type & CUPS_PRINTER_COLOR ? "true" : "false",
- finishings,
- p->type & CUPS_PRINTER_DUPLEX ?
- ",two-sided-long-edge,two-sided-short-edge" : "");
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "Attributes = \"%s\"", attrs);
-
- /*
- * Register the printer with the SLP server...
- */
-
- error = SLPReg(BrowseSLPHandle, srvurl, BrowseTimeout,
- SLP_CUPS_SRVTYPE, attrs, SLP_TRUE, slp_reg_callback, 0);
-
- if (error != SLP_OK)
- cupsdLogMessage(CUPSD_LOG_ERROR, "SLPReg of \"%s\" failed with status %d!", p->name,
- error);
-}
-
-
-/*
- * 'slp_attr_callback()' - SLP attribute callback
- */
-
-static SLPBoolean /* O - SLP_TRUE for success */
-slp_attr_callback(
- SLPHandle hslp, /* I - SLP handle */
- const char *attrlist, /* I - Attribute list */
- SLPError errcode, /* I - Parsing status for this attr */
- void *cookie) /* I - Current printer */
-{
- char *tmp = 0; /* Temporary string */
- cupsd_printer_t *p = (cupsd_printer_t*)cookie;
- /* Current printer */
-
-
- (void)hslp; /* anti-compiler-warning-code */
-
- /*
- * Bail if there was an error
- */
-
- if (errcode != SLP_OK)
- return (SLP_TRUE);
-
- /*
- * Parse the attrlist to obtain things needed to build CUPS browse packet
- */
-
- memset(p, 0, sizeof(cupsd_printer_t));
-
- if (slp_get_attr(attrlist, "(printer-location=", &(p->location)))
- return (SLP_FALSE);
- if (slp_get_attr(attrlist, "(printer-info=", &(p->info)))
- return (SLP_FALSE);
- if (slp_get_attr(attrlist, "(printer-make-and-model=", &(p->make_model)))
- return (SLP_FALSE);
- if (!slp_get_attr(attrlist, "(printer-type=", &tmp))
- p->type = atoi(tmp);
- else
- p->type = CUPS_PRINTER_REMOTE;
-
- cupsdClearString(&tmp);
-
- return (SLP_TRUE);
-}
-
-
-/*
- * 'slp_dereg_printer()' - SLPDereg() the specified printer
- */
-
-static void
-slp_dereg_printer(cupsd_printer_t *p) /* I - Printer */
-{
- char srvurl[HTTP_MAX_URI]; /* Printer service URI */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "slp_dereg_printer: printer=\"%s\"", p->name);
-
- if (!(p->type & CUPS_PRINTER_REMOTE))
- {
- /*
- * Make the SLP service URL that conforms to the IANA
- * 'printer:' template.
- */
-
- snprintf(srvurl, sizeof(srvurl), SLP_CUPS_SRVTYPE ":%s", p->uri);
-
- /*
- * Deregister the printer...
- */
-
- SLPDereg(BrowseSLPHandle, srvurl, slp_reg_callback, 0);
- }
-}
-
-
-/*
- * 'slp_get_attr()' - Get an attribute from an SLP registration.
- */
-
-static int /* O - 0 on success */
-slp_get_attr(const char *attrlist, /* I - Attribute list string */
- const char *tag, /* I - Name of attribute */
- char **valbuf) /* O - Value */
-{
- char *ptr1, /* Pointer into string */
- *ptr2; /* ... */
-
-
- cupsdClearString(valbuf);
-
- if ((ptr1 = strstr(attrlist, tag)) != NULL)
- {
- ptr1 += strlen(tag);
-
- if ((ptr2 = strchr(ptr1,')')) != NULL)
- {
- /*
- * Copy the value...
- */
-
- *valbuf = calloc(ptr2 - ptr1 + 1, 1);
- strncpy(*valbuf, ptr1, ptr2 - ptr1);
-
- /*
- * Dequote the value...
- */
-
- for (ptr1 = *valbuf; *ptr1; ptr1 ++)
- if (*ptr1 == '\\' && ptr1[1])
- _cups_strcpy(ptr1, ptr1 + 1);
-
- return (0);
- }
- }
-
- return (-1);
-}
-
-
-/*
- * 'slp_reg_callback()' - Empty SLPRegReport.
- */
-
-static void
-slp_reg_callback(SLPHandle hslp, /* I - SLP handle */
- SLPError errcode, /* I - Error code, if any */
- void *cookie) /* I - App data */
-{
- (void)hslp;
- (void)errcode;
- (void)cookie;
-
- return;
-}
-
-
-/*
- * 'slp_url_callback()' - SLP service url callback
- */
-
-static SLPBoolean /* O - TRUE = OK, FALSE = error */
-slp_url_callback(
- SLPHandle hslp, /* I - SLP handle */
- const char *srvurl, /* I - URL of service */
- unsigned short lifetime, /* I - Life of service */
- SLPError errcode, /* I - Existing error code */
- void *cookie) /* I - Pointer to service list */
-{
- slpsrvurl_t *s, /* New service entry */
- **head; /* Pointer to head of entry */
-
-
- /*
- * Let the compiler know we won't be using these vars...
- */
-
- (void)hslp;
- (void)lifetime;
-
- /*
- * Bail if there was an error
- */
-
- if (errcode != SLP_OK)
- return (SLP_TRUE);
-
- /*
- * Grab the head of the list...
- */
-
- head = (slpsrvurl_t**)cookie;
-
- /*
- * Allocate a *temporary* slpsrvurl_t to hold this entry.
- */
-
- if ((s = (slpsrvurl_t *)calloc(1, sizeof(slpsrvurl_t))) == NULL)
- return (SLP_FALSE);
-
- /*
- * Copy the SLP service URL...
- */
-
- strlcpy(s->url, srvurl, sizeof(s->url));
-
- /*
- * Link the SLP service URL into the head of the list
- */
-
- if (*head)
- s->next = *head;
-
- *head = s;
-
- return (SLP_TRUE);
-}
-#endif /* HAVE_LIBSLP */
-
-
-/*
- * 'update_cups_browse()' - Update the browse lists using the CUPS protocol.
- */
-
-static void
-update_cups_browse(void)
-{
- int i; /* Looping var */
- int auth; /* Authorization status */
- int len; /* Length of name string */
- int bytes; /* Number of bytes left */
- char packet[1541], /* Broadcast packet */
- *pptr; /* Pointer into packet */
- socklen_t srclen; /* Length of source address */
- http_addr_t srcaddr; /* Source address */
- char srcname[1024]; /* Source hostname */
- unsigned address[4]; /* Source address */
- unsigned type; /* Printer type */
- unsigned state; /* Printer state */
- char uri[HTTP_MAX_URI], /* Printer URI */
- host[HTTP_MAX_URI], /* Host portion of URI */
- resource[HTTP_MAX_URI], /* Resource portion of URI */
- info[IPP_MAX_NAME], /* Information string */
- location[IPP_MAX_NAME], /* Location string */
- make_model[IPP_MAX_NAME];/* Make and model string */
- int num_attrs; /* Number of attributes */
- cups_option_t *attrs; /* Attributes */
-
-
- /*
- * Read a packet from the browse socket...
- */
-
- srclen = sizeof(srcaddr);
- if ((bytes = recvfrom(BrowseSocket, packet, sizeof(packet) - 1, 0,
- (struct sockaddr *)&srcaddr, &srclen)) < 0)
- {
- /*
- * "Connection refused" is returned under Linux if the destination port
- * or address is unreachable from a previous sendto(); check for the
- * error here and ignore it for now...
- */
-
- if (errno != ECONNREFUSED && errno != EAGAIN)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Browse recv failed - %s.",
- strerror(errno));
- cupsdLogMessage(CUPSD_LOG_ERROR, "CUPS browsing turned off.");
-
-#ifdef WIN32
- closesocket(BrowseSocket);
-#else
- close(BrowseSocket);
-#endif /* WIN32 */
-
- cupsdRemoveSelect(BrowseSocket);
- BrowseSocket = -1;
-
- BrowseLocalProtocols &= ~BROWSE_CUPS;
- BrowseRemoteProtocols &= ~BROWSE_CUPS;
- }
-
- return;
- }
-
- packet[bytes] = '\0';
-
- /*
- * If we're about to sleep, ignore incoming browse packets.
- */
-
- if (Sleeping)
- return;
-
- /*
- * Figure out where it came from...
- */
-
-#ifdef AF_INET6
- if (srcaddr.addr.sa_family == AF_INET6)
- {
- address[0] = ntohl(srcaddr.ipv6.sin6_addr.s6_addr32[0]);
- address[1] = ntohl(srcaddr.ipv6.sin6_addr.s6_addr32[1]);
- address[2] = ntohl(srcaddr.ipv6.sin6_addr.s6_addr32[2]);
- address[3] = ntohl(srcaddr.ipv6.sin6_addr.s6_addr32[3]);
- }
- else
-#endif /* AF_INET6 */
- {
- address[0] = 0;
- address[1] = 0;
- address[2] = 0;
- address[3] = ntohl(srcaddr.ipv4.sin_addr.s_addr);
- }
-
- if (HostNameLookups)
- httpAddrLookup(&srcaddr, srcname, sizeof(srcname));
- else
- httpAddrString(&srcaddr, srcname, sizeof(srcname));
-
- len = strlen(srcname);
-
- /*
- * Do ACL stuff...
- */
-
- if (BrowseACL)
- {
- if (httpAddrLocalhost(&srcaddr) || !_cups_strcasecmp(srcname, "localhost"))
- {
- /*
- * Access from localhost (127.0.0.1) is always allowed...
- */
-
- auth = CUPSD_AUTH_ALLOW;
- }
- else
- {
- /*
- * Do authorization checks on the domain/address...
- */
-
- switch (BrowseACL->order_type)
- {
- default :
- auth = CUPSD_AUTH_DENY; /* anti-compiler-warning-code */
- break;
-
- case CUPSD_AUTH_ALLOW : /* Order Deny,Allow */
- auth = CUPSD_AUTH_ALLOW;
-
- if (cupsdCheckAuth(address, srcname, len, BrowseACL->deny))
- auth = CUPSD_AUTH_DENY;
-
- if (cupsdCheckAuth(address, srcname, len, BrowseACL->allow))
- auth = CUPSD_AUTH_ALLOW;
- break;
-
- case CUPSD_AUTH_DENY : /* Order Allow,Deny */
- auth = CUPSD_AUTH_DENY;
-
- if (cupsdCheckAuth(address, srcname, len, BrowseACL->allow))
- auth = CUPSD_AUTH_ALLOW;
-
- if (cupsdCheckAuth(address, srcname, len, BrowseACL->deny))
- auth = CUPSD_AUTH_DENY;
- break;
- }
- }
- }
- else
- auth = CUPSD_AUTH_ALLOW;
-
- if (auth == CUPSD_AUTH_DENY)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "update_cups_browse: Refused %d bytes from %s", bytes,
- srcname);
- return;
- }
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "update_cups_browse: (%d bytes from %s) %s", bytes,
- srcname, packet);
-
- /*
- * Parse packet...
- */
-
- if (sscanf(packet, "%x%x%1023s", &type, &state, uri) < 3)
- {
- cupsdLogMessage(CUPSD_LOG_WARN,
- "update_cups_browse: Garbled browse packet - %s", packet);
- return;
- }
-
- strcpy(location, "Location Unknown");
- strcpy(info, "No Information Available");
- make_model[0] = '\0';
- num_attrs = 0;
- attrs = NULL;
-
- if ((pptr = strchr(packet, '\"')) != NULL)
- {
- /*
- * Have extended information; can't use sscanf for it because not all
- * sscanf's allow empty strings with %[^\"]...
- */
-
- for (i = 0, pptr ++;
- i < (sizeof(location) - 1) && *pptr && *pptr != '\"';
- i ++, pptr ++)
- location[i] = *pptr;
-
- if (i)
- location[i] = '\0';
-
- if (*pptr == '\"')
- pptr ++;
-
- while (*pptr && isspace(*pptr & 255))
- pptr ++;
-
- if (*pptr == '\"')
- {
- for (i = 0, pptr ++;
- i < (sizeof(info) - 1) && *pptr && *pptr != '\"';
- i ++, pptr ++)
- info[i] = *pptr;
-
- info[i] = '\0';
-
- if (*pptr == '\"')
- pptr ++;
-
- while (*pptr && isspace(*pptr & 255))
- pptr ++;
-
- if (*pptr == '\"')
- {
- for (i = 0, pptr ++;
- i < (sizeof(make_model) - 1) && *pptr && *pptr != '\"';
- i ++, pptr ++)
- make_model[i] = *pptr;
-
- if (*pptr == '\"')
- pptr ++;
-
- make_model[i] = '\0';
-
- if (*pptr)
- num_attrs = cupsParseOptions(pptr, num_attrs, &attrs);
- }
- }
- }
-
- DEBUG_puts(packet);
- DEBUG_printf(("type=%x, state=%x, uri=\"%s\"\n"
- "location=\"%s\", info=\"%s\", make_model=\"%s\"\n",
- type, state, uri, location, info, make_model));
-
- /*
- * Pull the URI apart to see if this is a local or remote printer...
- */
-
- if (is_local_queue(uri, host, sizeof(host), resource, sizeof(resource)))
- {
- cupsFreeOptions(num_attrs, attrs);
- return;
- }
-
- /*
- * Do relaying...
- */
-
- for (i = 0; i < NumRelays; i ++)
- if (cupsdCheckAuth(address, srcname, len, Relays[i].from))
- if (sendto(BrowseSocket, packet, bytes, 0,
- (struct sockaddr *)&(Relays[i].to),
- httpAddrLength(&(Relays[i].to))) <= 0)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "update_cups_browse: sendto failed for relay %d - %s.",
- i + 1, strerror(errno));
- cupsFreeOptions(num_attrs, attrs);
- return;
- }
-
- /*
- * Process the browse data...
- */
-
- process_browse_data(uri, host, resource, (cups_ptype_t)type,
- (ipp_pstate_t)state, location, info, make_model,
- num_attrs, attrs);
-}
-
-
-/*
* 'update_lpd()' - Update the LPD configuration as needed.
*/
@@ -5478,41 +1599,6 @@ update_lpd(int onoff) /* - 1 = turn on, 0 = turn off */
/*
- * 'update_polling()' - Read status messages from the poll daemons.
- */
-
-static void
-update_polling(void)
-{
- char *ptr, /* Pointer to end of line in buffer */
- message[1024]; /* Pointer to message text */
- int loglevel; /* Log level for message */
-
-
- while ((ptr = cupsdStatBufUpdate(PollStatusBuffer, &loglevel,
- message, sizeof(message))) != NULL)
- {
- if (loglevel == CUPSD_LOG_INFO)
- cupsdLogMessage(CUPSD_LOG_INFO, "%s", message);
-
- if (!strchr(PollStatusBuffer->buffer, '\n'))
- break;
- }
-
- if (ptr == NULL && !PollStatusBuffer->bufused)
- {
- /*
- * All polling processes have died; stop polling...
- */
-
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "update_polling: all polling processes have exited!");
- cupsdStopPolling();
- }
-}
-
-
-/*
* 'update_smb()' - Update the SMB configuration as needed.
*/
@@ -5580,5 +1666,5 @@ update_smb(int onoff) /* I - 1 = turn on, 0 = turn off */
/*
- * End of "$Id: dirsvc.c 10243 2012-02-11 02:05:21Z mike $".
+ * End of "$Id: dirsvc.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/dirsvc.h b/scheduler/dirsvc.h
index be8774b..edc5ad3 100644
--- a/scheduler/dirsvc.h
+++ b/scheduler/dirsvc.h
@@ -1,9 +1,9 @@
/*
- * "$Id: dirsvc.h 9632 2011-03-21 02:12:14Z mike $"
+ * "$Id: dirsvc.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Directory services definitions for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -14,68 +14,13 @@
*/
/*
- * Include necessary headers...
- */
-
-#ifdef HAVE_LIBSLP
-# include <slp.h>
-#endif /* HAVE_LIBSLP */
-
-#ifdef HAVE_LDAP
-# ifdef __sun
-# include <lber.h>
-# endif /* __sun */
-# include <ldap.h>
-# ifdef HAVE_LDAP_SSL_H
-# include <ldap_ssl.h>
-# endif /* HAVE_LDAP_SSL_H */
-#endif /* HAVE_LDAP */
-
-/*
* Browse protocols...
*/
-#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_SMB 16 /* SMB/Samba */
-#define BROWSE_LPD 32 /* LPD via xinetd or launchd */
-#define BROWSE_ALL 63 /* All protocols */
-
-
-/*
- * Browse address...
- */
-
-typedef struct
-{
- char iface[32]; /* Destination interface */
- http_addr_t to; /* Destination address */
-} cupsd_dirsvc_addr_t;
-
-
-/*
- * Relay structure...
- */
-
-typedef struct
-{
- cups_array_t *from; /* Source address/name mask(s) */
- http_addr_t to; /* Destination address */
-} cupsd_dirsvc_relay_t;
-
-
-/*
- * Polling structure...
- */
-
-typedef struct
-{
- char hostname[64]; /* Hostname (actually, IP address) */
- int port; /* Port number */
- int pid; /* Current poll server PID */
-} cupsd_dirsvc_poll_t;
+#define BROWSE_DNSSD 1 /* DNS Service Discovery (aka Bonjour) */
+#define BROWSE_SMB 2 /* SMB/Samba */
+#define BROWSE_LPD 4 /* LPD via xinetd or launchd */
+#define BROWSE_ALL 7 /* All protocols */
/*
@@ -87,98 +32,34 @@ VAR int Browsing VALUE(TRUE),
BrowseWebIF VALUE(FALSE),
/* Whether the web interface is advertised */
BrowseLocalProtocols
- VALUE(BROWSE_ALL),
+ VALUE(BROWSE_ALL);
/* Protocols to support for local printers */
- BrowseRemoteProtocols
- VALUE(BROWSE_ALL),
- /* Protocols to support for remote printers */
- BrowseShortNames VALUE(TRUE),
- /* Short names for remote printers? */
- BrowseSocket VALUE(-1),
- /* Socket for browsing */
- BrowsePort VALUE(IPP_PORT),
- /* Port number for broadcasts */
- BrowseInterval VALUE(DEFAULT_INTERVAL),
- /* Broadcast interval in seconds */
- BrowseTimeout VALUE(DEFAULT_TIMEOUT),
- /* Time out for printers in seconds */
- UseNetworkDefault VALUE(CUPS_DEFAULT_USE_NETWORK_DEFAULT),
- /* Use the network default printer? */
- NumBrowsers VALUE(0);
- /* Number of broadcast addresses */
-VAR char *BrowseLocalOptions
- VALUE(NULL),
- /* Options to add to local printer URIs */
- *BrowseRemoteOptions
- VALUE(NULL);
- /* Options to add to remote printer URIs */
-VAR cupsd_dirsvc_addr_t *Browsers VALUE(NULL);
- /* Broadcast addresses */
-VAR cupsd_location_t *BrowseACL VALUE(NULL);
- /* Browser access control list */
-VAR cupsd_printer_t *BrowseNext VALUE(NULL);
- /* Next class/printer to broadcast */
-VAR int NumRelays VALUE(0);
- /* Number of broadcast relays */
-VAR cupsd_dirsvc_relay_t *Relays VALUE(NULL);
- /* Broadcast relays */
-VAR int NumPolled VALUE(0);
- /* Number of polled servers */
-VAR cupsd_dirsvc_poll_t *Polled VALUE(NULL);
- /* Polled servers */
-VAR int PollPipe VALUE(0);
- /* Status pipe for pollers */
-VAR cupsd_statbuf_t *PollStatusBuffer VALUE(NULL);
- /* Status buffer for pollers */
-
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
VAR char *DNSSDComputerName VALUE(NULL),
/* Computer/server name */
*DNSSDHostName VALUE(NULL),
/* Hostname */
- *DNSSDRegType VALUE(NULL);
- /* Bonjour registration type */
+ *DNSSDSubTypes VALUE(NULL);
+ /* Bonjour registration subtypes */
VAR cups_array_t *DNSSDAlias VALUE(NULL);
/* List of dynamic ServerAlias's */
VAR int DNSSDPort VALUE(0);
/* Port number to register */
VAR cups_array_t *DNSSDPrinters VALUE(NULL);
/* Printers we have registered */
-VAR DNSServiceRef DNSSDRef VALUE(NULL),
+# ifdef HAVE_DNSSD
+VAR DNSServiceRef DNSSDMaster VALUE(NULL);
/* Master DNS-SD service reference */
- WebIFRef VALUE(NULL),
+# else /* HAVE_AVAHI */
+VAR AvahiThreadedPoll *DNSSDMaster VALUE(NULL);
+ /* Master polling interface for Avahi */
+VAR AvahiClient *DNSSDClient VALUE(NULL);
+ /* Client information */
+# endif /* HAVE_DNSSD */
+VAR cupsd_srv_t WebIFSrv VALUE(NULL);
/* Service reference for the web interface */
- RemoteRef VALUE(NULL);
- /* Remote printer browse reference */
-#endif /* HAVE_DNSSD */
-
-#ifdef HAVE_LIBSLP
-VAR SLPHandle BrowseSLPHandle VALUE(NULL);
- /* SLP API handle */
-VAR time_t BrowseSLPRefresh VALUE(0);
- /* Next SLP refresh time */
-#endif /* HAVE_LIBSLP */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
-#ifdef HAVE_LDAP
-VAR LDAP *BrowseLDAPHandle VALUE(NULL);
- /* Handle to LDAP server */
-VAR time_t BrowseLDAPRefresh VALUE(0);
- /* Next LDAP refresh time */
-VAR char *BrowseLDAPBindDN VALUE(NULL),
- /* LDAP login DN */
- *BrowseLDAPDN VALUE(NULL),
- /* LDAP search DN */
- *BrowseLDAPPassword VALUE(NULL),
- /* LDAP login password */
- *BrowseLDAPServer VALUE(NULL);
- /* LDAP server to use */
-VAR int BrowseLDAPUpdate VALUE(TRUE);
- /* enables LDAP updates */
-# ifdef HAVE_LDAP_SSL
-VAR char *BrowseLDAPCACertFile VALUE(NULL);
- /* LDAP CA CERT file to use */
-# endif /* HAVE_LDAP_SSL */
-#endif /* HAVE_LDAP */
VAR char *LPDConfigFile VALUE(NULL),
/* LPD configuration file */
*SMBConfigFile VALUE(NULL);
@@ -190,24 +71,14 @@ VAR char *LPDConfigFile VALUE(NULL),
*/
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 cupsdSendBrowseList(void);
extern void cupsdStartBrowsing(void);
-extern void cupsdStartPolling(void);
extern void cupsdStopBrowsing(void);
-extern void cupsdStopPolling(void);
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
extern void cupsdUpdateDNSSDName(void);
-#endif /* HAVE_DNSSD */
-#ifdef HAVE_LDAP
-extern void cupsdUpdateLDAPBrowse(void);
-#endif /* HAVE_LDAP */
-extern void cupsdUpdateSLPBrowse(void);
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
/*
- * End of "$Id: dirsvc.h 9632 2011-03-21 02:12:14Z mike $".
+ * End of "$Id: dirsvc.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/env.c b/scheduler/env.c
index ec12d15..ba11aad 100644
--- a/scheduler/env.c
+++ b/scheduler/env.c
@@ -1,5 +1,5 @@
/*
- * "$Id: env.c 9459 2011-01-11 03:48:42Z mike $"
+ * "$Id: env.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Environment management routines for the CUPS scheduler.
*
@@ -62,7 +62,7 @@ cupsdInitEnv(void)
#if defined(__APPLE__)
/*
- * Add special voodoo magic for MacOS X - this allows MacOS X
+ * Add special voodoo magic for MacOS X - this allows MacOS X
* programs to access their bundle resources properly...
*
* This string is replaced in cupsdStartProcess()...
@@ -227,6 +227,8 @@ cupsdUpdateEnv(void)
set_if_undefined("TZ", NULL);
set_if_undefined("USER", "root");
set_if_undefined("VG_ARGS", NULL);
+
+ cupsdSetEnvf("CUPS_MAX_MESSAGE", "%d", CUPSD_SB_BUFFER_SIZE - 1);
}
@@ -267,5 +269,5 @@ find_env(const char *name) /* I - Variable name */
/*
- * End of "$Id: env.c 9459 2011-01-11 03:48:42Z mike $".
+ * End of "$Id: env.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/file.c b/scheduler/file.c
index 4dcf54d..84ceef1 100644
--- a/scheduler/file.c
+++ b/scheduler/file.c
@@ -1,5 +1,5 @@
/*
- * "$Id: file.c 9766 2011-05-11 22:17:34Z mike $"
+ * "$Id: file.c 11221 2013-08-06 16:16:01Z msweet $"
*
* File functions for the CUPS scheduler.
*
@@ -109,6 +109,29 @@ cupsdCloseCreatedConfFile(
/*
+ * Synchronize changes to disk if SyncOnClose is enabled.
+ */
+
+ if (SyncOnClose)
+ {
+ if (cupsFileFlush(fp))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to write changes to \"%s\": %s",
+ filename, strerror(errno));
+ cupsFileClose(fp);
+ return (-1);
+ }
+
+ if (fsync(cupsFileNumber(fp)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to sync changes to \"%s\": %s",
+ filename, strerror(errno));
+ cupsFileClose(fp);
+ return (-1);
+ }
+ }
+
+ /*
* First close the file...
*/
@@ -446,5 +469,5 @@ overwrite_data(int fd, /* I - File descriptor */
/*
- * End of "$Id: file.c 9766 2011-05-11 22:17:34Z mike $".
+ * End of "$Id: file.c 11221 2013-08-06 16:16:01Z msweet $".
*/
diff --git a/scheduler/filter.c b/scheduler/filter.c
index 5cde777..6979b5c 100644
--- a/scheduler/filter.c
+++ b/scheduler/filter.c
@@ -1,5 +1,5 @@
/*
- * "$Id: filter.c 9705 2011-04-22 04:38:28Z mike $"
+ * "$Id: filter.c 11173 2013-07-23 12:31:34Z msweet $"
*
* File type conversion routines for CUPS.
*
@@ -500,5 +500,5 @@ mime_find_filters(
/*
- * End of "$Id: filter.c 9705 2011-04-22 04:38:28Z mike $".
+ * End of "$Id: filter.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index fa3d96e..6968cd5 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -1,9 +1,9 @@
/*
- * "$Id: ipp.c 10274 2012-02-13 20:42:51Z mike $"
+ * "$Id: ipp.c 11173 2013-07-23 12:31:34Z msweet $"
*
* IPP routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2013 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
@@ -23,8 +23,6 @@
* add_class() - Add a class to the system.
* add_file() - Add a file to a job.
* add_job() - Add a job to a print queue.
- * add_job_state_reasons() - Add the "job-state-reasons" attribute based
- * upon the job and printer state...
* add_job_subscriptions() - Add any subscriptions for a job.
* add_job_uuid() - Add job-uuid attribute to a job.
* add_printer() - Add a printer to the system.
@@ -32,10 +30,6 @@
* based upon the printer state...
* add_queued_job_count() - Add the "queued-job-count" attribute for the
* specified printer or class.
- * apple_init_profile() - Initialize a color profile.
- * apple_register_profiles() - Register color profiles for a printer.
- * apple_unregister_profiles() - Remove color profiles for the specified
- * printer.
* apply_printer_defaults() - Apply printer default options to a job.
* authenticate_job() - Set job authentication info.
* cancel_all_jobs() - Cancel all or selected print jobs.
@@ -45,7 +39,6 @@
* feed URI.
* check_quotas() - Check quotas for a printer and user.
* close_job() - Close a multi-file job.
- * copy_attribute() - Copy a single attribute.
* copy_attrs() - Copy attributes from one request to another.
* copy_banner() - Copy a banner file to the requests directory
* for the specified job.
@@ -114,11 +107,9 @@
#include <cups/ppd-private.h>
#ifdef __APPLE__
-# include <ApplicationServices/ApplicationServices.h>
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
+/*# include <ApplicationServices/ApplicationServices.h>
extern CFUUIDRef ColorSyncCreateUUIDFromUInt32(unsigned id);
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-# include <CoreFoundation/CoreFoundation.h>
+# include <CoreFoundation/CoreFoundation.h>*/
# ifdef HAVE_MEMBERSHIP_H
# include <membership.h>
# endif /* HAVE_MEMBERSHIP_H */
@@ -142,25 +133,12 @@ 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, 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);
static void add_job_uuid(cupsd_job_t *job);
static void add_printer(cupsd_client_t *con, ipp_attribute_t *uri);
static void add_printer_state_reasons(cupsd_client_t *con,
cupsd_printer_t *p);
static void add_queued_job_count(cupsd_client_t *con, cupsd_printer_t *p);
-#ifdef __APPLE__
-static void apple_init_profile(ppd_file_t *ppd, cups_array_t *languages,
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- CFMutableDictionaryRef profile,
-# else
- CMDeviceProfileInfo *profile,
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
- unsigned id, const char *name,
- const char *text, const char *iccfile);
-static void apple_register_profiles(cupsd_printer_t *p);
-static void apple_unregister_profiles(cupsd_printer_t *p);
-#endif /* __APPLE__ */
static void apply_printer_defaults(cupsd_printer_t *printer,
cupsd_job_t *job);
static void authenticate_job(cupsd_client_t *con, ipp_attribute_t *uri);
@@ -169,8 +147,6 @@ static void cancel_job(cupsd_client_t *con, ipp_attribute_t *uri);
static void cancel_subscription(cupsd_client_t *con, int id);
static int check_rss_recipient(const char *recipient);
static int check_quotas(cupsd_client_t *con, cupsd_printer_t *p);
-static ipp_attribute_t *copy_attribute(ipp_t *to, ipp_attribute_t *attr,
- int quickcopy);
static void close_job(cupsd_client_t *con, ipp_attribute_t *uri);
static void copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra,
ipp_tag_t group, int quickcopy,
@@ -228,10 +204,7 @@ static void send_http_error(cupsd_client_t *con, http_status_t status,
cupsd_printer_t *printer);
static void send_ipp_status(cupsd_client_t *con, ipp_status_t status,
const char *message, ...)
-# ifdef __GNUC__
-__attribute__ ((__format__ (__printf__, 3, 4)))
-# endif /* __GNUC__ */
-;
+ __attribute__((__format__(__printf__, 3, 4)));
static void set_default(cupsd_client_t *con, ipp_attribute_t *uri);
static void set_job_attrs(cupsd_client_t *con, ipp_attribute_t *uri);
static void set_printer_attrs(cupsd_client_t *con, ipp_attribute_t *uri);
@@ -853,8 +826,7 @@ cupsdTimeoutJob(cupsd_job_t *job) /* I - Job to timeout */
printer = cupsdFindDest(job->dest);
attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
- if (printer &&
- !(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) &&
+ if (printer && !(printer->type & CUPS_PRINTER_REMOTE) &&
attr && attr->num_values > 1)
{
/*
@@ -969,7 +941,6 @@ add_class(cupsd_client_t *con, /* I - Client connection */
cups_ptype_t dtype; /* Destination type */
ipp_attribute_t *attr; /* Printer attribute */
int modify; /* Non-zero if we just modified */
- char newname[IPP_MAX_NAME]; /* New class name */
int need_restart_job; /* Need to restart job? */
@@ -1023,8 +994,7 @@ add_class(cupsd_client_t *con, /* I - Client connection */
* Class doesn't exist; see if we have a printer of the same name...
*/
- if ((pclass = cupsdFindPrinter(resource + 9)) != NULL &&
- !(pclass->type & CUPS_PRINTER_DISCOVERED))
+ if ((pclass = cupsdFindPrinter(resource + 9)) != NULL)
{
/*
* Yes, return an error...
@@ -1049,56 +1019,6 @@ add_class(cupsd_client_t *con, /* I - Client connection */
pclass = cupsdAddClass(resource + 9);
modify = 0;
}
- else if (pclass->type & CUPS_PRINTER_IMPLICIT)
- {
- /*
- * Check the default policy, then rename the implicit class to "AnyClass"
- * or remove it...
- */
-
- if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
- {
- send_http_error(con, status, NULL);
- return;
- }
-
- if (ImplicitAnyClasses)
- {
- snprintf(newname, sizeof(newname), "Any%s", resource + 9);
- cupsdRenamePrinter(pclass, newname);
- }
- else
- cupsdDeletePrinter(pclass, 1);
-
- /*
- * Add the class as a new local class...
- */
-
- pclass = cupsdAddClass(resource + 9);
- modify = 0;
- }
- else if (pclass->type & CUPS_PRINTER_DISCOVERED)
- {
- /*
- * Check the default policy, then rename the remote class to "Class"...
- */
-
- if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
- {
- send_http_error(con, status, NULL);
- return;
- }
-
- snprintf(newname, sizeof(newname), "%s@%s", resource + 9, pclass->hostname);
- cupsdRenamePrinter(pclass, newname);
-
- /*
- * Add the class as a new local class...
- */
-
- pclass = cupsdAddClass(resource + 9);
- modify = 0;
- }
else if ((status = cupsdCheckPolicy(pclass->op_policy_ptr, con,
NULL)) != HTTP_OK)
{
@@ -1365,6 +1285,21 @@ add_job(cupsd_client_t *con, /* I - Client connection */
ipp_attribute_t *media_col, /* media-col attribute */
*media_margin; /* media-*-margin attribute */
ipp_t *unsup_col; /* media-col in unsupported response */
+ static const char * const readonly[] =/* List of read-only attributes */
+ {
+ "job-id",
+ "job-k-octets",
+ /*"job-impressions",*/ /* For now we allow this since cupsd can't count */
+ "job-impressions-completed",
+ "job-media-sheets",
+ "job-media-sheets-completed",
+ "job-state",
+ "job-state-message",
+ "job-state-reasons",
+ "time-at-completed",
+ "time-at-creation",
+ "time-at-processing"
+ };
cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
@@ -1433,6 +1368,27 @@ add_job(cupsd_client_t *con, /* I - Client connection */
* copies, number-up, and page-ranges...
*/
+ for (i = 0; i < (int)(sizeof(readonly) / sizeof(readonly[0])); i ++)
+ {
+ if ((attr = ippFindAttribute(con->request, readonly[i],
+ IPP_TAG_ZERO)) != NULL)
+ {
+ ippDeleteAttribute(con->request, attr);
+
+ if (StrictConformance)
+ {
+ send_ipp_status(con, IPP_BAD_REQUEST,
+ _("The '%s' Job Description attribute cannot be "
+ "supplied in a job creation request."), readonly[i]);
+ return (NULL);
+ }
+
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "Unexpected '%s' Job Description attribute in a job "
+ "creation request.", readonly[i]);
+ }
+ }
+
if (filetype && printer->filetypes &&
!cupsArrayFind(printer->filetypes, filetype))
{
@@ -1618,9 +1574,71 @@ add_job(cupsd_client_t *con, /* I - Client connection */
priority);
}
- if (!ippFindAttribute(con->request, "job-name", IPP_TAG_NAME))
+ if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_ZERO)) == NULL)
ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
"Untitled");
+ else if ((attr->value_tag != IPP_TAG_NAME &&
+ attr->value_tag != IPP_TAG_NAMELANG) ||
+ attr->num_values != 1)
+ {
+ send_ipp_status(con, IPP_ATTRIBUTES,
+ _("Bad job-name value: Wrong type or count."));
+ if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL)
+ attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
+ return (NULL);
+ }
+ else
+ {
+ const char *ptr; /* Pointer into string */
+
+ for (ptr = attr->values[0].string.text; *ptr; ptr ++)
+ {
+ if ((*ptr & 0xe0) == 0xc0)
+ {
+ ptr ++;
+ if ((*ptr & 0xc0) != 0x80)
+ break;
+ }
+ else if ((*ptr & 0xf0) == 0xe0)
+ {
+ ptr ++;
+ if ((*ptr & 0xc0) != 0x80)
+ break;
+ ptr ++;
+ if ((*ptr & 0xc0) != 0x80)
+ break;
+ }
+ else if ((*ptr & 0xf8) == 0xf0)
+ {
+ ptr ++;
+ if ((*ptr & 0xc0) != 0x80)
+ break;
+ ptr ++;
+ if ((*ptr & 0xc0) != 0x80)
+ break;
+ ptr ++;
+ if ((*ptr & 0xc0) != 0x80)
+ break;
+ }
+ else if (*ptr & 0x80)
+ break;
+ }
+
+ if (*ptr || (ptr - attr->values[0].string.text) > (IPP_MAX_NAME - 1))
+ {
+ if (*ptr)
+ send_ipp_status(con, IPP_ATTRIBUTES,
+ _("Bad job-name value: Bad UTF-8 sequence."));
+ else
+ send_ipp_status(con, IPP_ATTRIBUTES,
+ _("Bad job-name value: Name too long."));
+
+ if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL)
+ attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
+
+ return (NULL);
+ }
+ }
if ((job = cupsdAddJob(priority, printer->name)) == NULL)
{
@@ -1630,8 +1648,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
return (NULL);
}
- job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_REMOTE);
+ job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
job->attrs = con->request;
job->dirty = 1;
con->request = ippNewRequest(job->attrs->request.op.operation_id);
@@ -1720,10 +1737,10 @@ add_job(cupsd_client_t *con, /* I - Client connection */
{
_cupsStrFree(attr->values[i].string.text);
attr->values[i].string.text = NULL;
- if (attr->values[i].string.charset)
+ if (attr->values[i].string.language)
{
- _cupsStrFree(attr->values[i].string.charset);
- attr->values[i].string.charset = NULL;
+ _cupsStrFree(attr->values[i].string.language);
+ attr->values[i].string.language = NULL;
}
}
@@ -1770,6 +1787,8 @@ add_job(cupsd_client_t *con, /* I - Client connection */
job->state = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_ENUM,
"job-state", IPP_JOB_STOPPED);
job->state_value = (ipp_jstate_t)job->state->values[0].integer;
+ job->reasons = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, "job-incoming");
job->sheets = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
"job-media-sheets-completed", 0);
ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL,
@@ -1803,6 +1822,8 @@ add_job(cupsd_client_t *con, /* I - Client connection */
job->state->values[0].integer = IPP_JOB_HELD;
job->state_value = IPP_JOB_HELD;
+
+ ippSetString(job->attrs, &job->reasons, 0, "job-hold-until-specified");
}
else if (job->attrs->request.op.operation_id == IPP_CREATE_JOB)
{
@@ -1814,10 +1835,11 @@ add_job(cupsd_client_t *con, /* I - Client connection */
{
job->state->values[0].integer = IPP_JOB_PENDING;
job->state_value = IPP_JOB_PENDING;
+
+ ippSetString(job->attrs, &job->reasons, 0, "none");
}
- if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) ||
- Classification)
+ if (!(printer->type & CUPS_PRINTER_REMOTE) || Classification)
{
/*
* Add job sheets options...
@@ -1950,7 +1972,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
* See if we need to add the starting sheet...
*/
- if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)))
+ if (!(printer->type & CUPS_PRINTER_REMOTE))
{
cupsdLogJob(job, CUPSD_LOG_INFO, "Adding start banner page \"%s\".",
attr->values[0].string.text);
@@ -1983,7 +2005,8 @@ add_job(cupsd_client_t *con, /* I - Client connection */
ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
job->state_value);
- add_job_state_reasons(con, job);
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons",
+ NULL, job->reasons->values[0].string.text);
con->response->request.status.status_code = IPP_OK;
@@ -2015,76 +2038,6 @@ add_job(cupsd_client_t *con, /* I - Client connection */
/*
- * 'add_job_state_reasons()' - Add the "job-state-reasons" attribute based
- * upon the job and printer state...
- */
-
-static void
-add_job_state_reasons(
- cupsd_client_t *con, /* I - Client connection */
- cupsd_job_t *job) /* I - Job info */
-{
- cupsd_printer_t *dest; /* Destination printer */
- ipp_attribute_t *attr; /* job-hold attribute */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job_state_reasons(%p[%d], %d)",
- con, con->http.fd, job ? job->id : 0);
-
- switch (job ? job->state_value : IPP_JOB_CANCELED)
- {
- case IPP_JOB_PENDING :
- dest = cupsdFindDest(job->dest);
-
- if (dest && dest->state == IPP_PRINTER_STOPPED)
- ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "printer-stopped");
- else
- ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "none");
- break;
-
- case IPP_JOB_HELD :
- if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
- IPP_TAG_KEYWORD)) == NULL)
- attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
-
- if (!attr || strcmp(attr->values[0].string.text, "no-hold"))
- ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-hold-until-specified");
- else
- ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-incoming");
- break;
-
- case IPP_JOB_PROCESSING :
- ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-printing");
- break;
-
- case IPP_JOB_STOPPED :
- ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-stopped");
- break;
-
- case IPP_JOB_CANCELED :
- ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-canceled-by-user");
- break;
-
- case IPP_JOB_ABORTED :
- ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "aborted-by-system");
- break;
-
- case IPP_JOB_COMPLETED :
- ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD,
- "job-state-reasons", NULL, "job-completed-successfully");
- break;
- }
-}
-
-
-/*
* 'add_job_subscriptions()' - Add any subscriptions for a job.
*/
@@ -2302,7 +2255,7 @@ add_job_subscriptions(
* Free and remove this attribute...
*/
- _ippFreeAttr(attr);
+ ippDeleteAttribute(NULL, attr);
if (prev)
prev->next = next;
@@ -2363,7 +2316,6 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
char srcfile[1024], /* Source Script/PPD file */
dstfile[1024]; /* Destination Script/PPD file */
int modify; /* Non-zero if we are modifying */
- char newname[IPP_MAX_NAME]; /* New printer name */
int changed_driver, /* Changed the PPD/interface script? */
need_restart_job, /* Need to restart job? */
set_device_uri, /* Did we set the device URI? */
@@ -2419,8 +2371,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
* Printer doesn't exist; see if we have a class of the same name...
*/
- if ((printer = cupsdFindClass(resource + 10)) != NULL &&
- !(printer->type & CUPS_PRINTER_DISCOVERED))
+ if ((printer = cupsdFindClass(resource + 10)) != NULL)
{
/*
* Yes, return an error...
@@ -2445,58 +2396,6 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
printer = cupsdAddPrinter(resource + 10);
modify = 0;
}
- else if (printer->type & CUPS_PRINTER_IMPLICIT)
- {
- /*
- * Check the default policy, then rename the implicit printer to
- * "AnyPrinter" or delete it...
- */
-
- if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
- {
- send_http_error(con, status, NULL);
- return;
- }
-
- if (ImplicitAnyClasses)
- {
- snprintf(newname, sizeof(newname), "Any%s", resource + 10);
- cupsdRenamePrinter(printer, newname);
- }
- else
- cupsdDeletePrinter(printer, 1);
-
- /*
- * Add the printer as a new local printer...
- */
-
- printer = cupsdAddPrinter(resource + 10);
- modify = 0;
- }
- else if (printer->type & CUPS_PRINTER_DISCOVERED)
- {
- /*
- * Check the default policy, then rename the remote printer to
- * "Printer@server"...
- */
-
- if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
- {
- send_http_error(con, status, NULL);
- return;
- }
-
- snprintf(newname, sizeof(newname), "%s@%s", resource + 10,
- printer->hostname);
- cupsdRenamePrinter(printer, newname);
-
- /*
- * Add the printer as a new local printer...
- */
-
- printer = cupsdAddPrinter(resource + 10);
- modify = 0;
- }
else if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con,
NULL)) != HTTP_OK)
{
@@ -2533,6 +2432,21 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
http_uri_status_t uri_status; /* URI separation status */
char old_device_uri[1024];
/* Old device URI */
+ static const char * const uri_status_strings[] =
+ {
+ "URI too large.",
+ "Bad arguments to function.",
+ "Bad resource path.",
+ "Bad port number.",
+ "Bad hostname/address.",
+ "Bad username/password.",
+ "Bad URI scheme.",
+ "Bad URI.",
+ "OK",
+ "Missing URI scheme.",
+ "Unknown URI scheme",
+ "Missing resource path."
+ };
need_restart_job = 1;
@@ -2544,12 +2458,14 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
host, sizeof(host), &port,
resource, sizeof(resource));
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "%s device-uri: %s", printer->name,
+ uri_status_strings[uri_status - HTTP_URI_OVERFLOW]);
+
if (uri_status < HTTP_URI_OK)
{
send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\"."),
attr->values[0].string.text);
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "add_printer: httpSeparateURI returned %d", uri_status);
return;
}
@@ -2568,7 +2484,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
send_ipp_status(con, IPP_NOT_POSSIBLE,
_("File device URIs have been disabled. "
"To enable, see the FileDevice directive in "
- "\"%s/cupsd.conf\"."),
+ "\"%s/cups-files.conf\"."),
ServerRoot);
return;
}
@@ -2925,17 +2841,11 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
cupsdSetPrinterReasons(printer, "none");
-#ifdef __APPLE__
/*
* (Re)register color profiles...
*/
- if (!RunUser)
- {
- apple_unregister_profiles(printer);
- apple_register_profiles(printer);
- }
-#endif /* __APPLE__ */
+ cupsdRegisterColor(printer);
}
/*
@@ -2955,7 +2865,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
snprintf(srcfile, sizeof(srcfile), "%s/ppd/%s.ppd", ServerRoot,
printer->name);
- if ((ppd = ppdOpenFile(srcfile)) != NULL)
+ if ((ppd = _ppdOpenFile(srcfile, _PPD_LOCALIZATION_NONE)) != NULL)
{
for (ppdattr = ppdFindAttr(ppd, "cupsPortMonitor", NULL);
ppdattr;
@@ -3069,888 +2979,6 @@ add_queued_job_count(
}
-#ifdef __APPLE__
-/*
- * 'apple_init_profile()' - Initialize a color profile.
- */
-
-static void
-apple_init_profile(
- ppd_file_t *ppd, /* I - PPD file */
- cups_array_t *languages, /* I - Languages in the PPD file */
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- CFMutableDictionaryRef profile, /* I - Profile dictionary */
-# else
- CMDeviceProfileInfo *profile, /* I - Profile record */
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
- unsigned id, /* I - Profile ID */
- const char *name, /* I - Profile name */
- const char *text, /* I - Profile UI text */
- const char *iccfile) /* I - ICC filename */
-{
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- CFURLRef url; /* URL for profile filename */
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
- CFMutableDictionaryRef dict; /* Dictionary for name */
- char *language; /* Current language */
- ppd_attr_t *attr; /* Profile attribute */
- CFStringRef cflang, /* Language string */
- cftext; /* Localized text */
-
-
- (void)id;
-
- /*
- * Build the profile name dictionary...
- */
-
- dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- if (!dict)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize profile \"%s\".",
- iccfile);
- return;
- }
-
- cftext = CFStringCreateWithCString(kCFAllocatorDefault, text,
- kCFStringEncodingUTF8);
-
- if (cftext)
- {
- CFDictionarySetValue(dict, CFSTR("en_US"), cftext);
- CFRelease(cftext);
- }
-
- if (languages)
- {
- /*
- * Find localized names for the color profiles...
- */
-
- cupsArraySave(ppd->sorted_attrs);
-
- for (language = (char *)cupsArrayFirst(languages);
- language;
- language = (char *)cupsArrayNext(languages))
- {
- if (iccfile)
- {
- if ((attr = _ppdLocalizedAttr(ppd, "cupsICCProfile", name,
- language)) == NULL)
- attr = _ppdLocalizedAttr(ppd, "APTiogaProfile", name, language);
- }
- else
- attr = _ppdLocalizedAttr(ppd, "ColorModel", name, language);
-
- if (attr && attr->text[0])
- {
- cflang = CFStringCreateWithCString(kCFAllocatorDefault, language,
- kCFStringEncodingUTF8);
- cftext = CFStringCreateWithCString(kCFAllocatorDefault, attr->text,
- kCFStringEncodingUTF8);
-
- if (cflang && cftext)
- CFDictionarySetValue(dict, cflang, cftext);
-
- if (cflang)
- CFRelease(cflang);
-
- if (cftext)
- CFRelease(cftext);
- }
- }
-
- cupsArrayRestore(ppd->sorted_attrs);
- }
-
- /*
- * Fill in the profile data...
- */
-
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- if (iccfile)
- {
- url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
- (const UInt8 *)iccfile,
- strlen(iccfile), false);
-
- if (url)
- {
- CFDictionarySetValue(profile, kColorSyncDeviceProfileURL, url);
- CFRelease(url);
- }
- }
-
- CFDictionarySetValue(profile, kColorSyncDeviceModeDescriptions, dict);
- CFRelease(dict);
-
-# else
- profile->dataVersion = cmDeviceProfileInfoVersion1;
- profile->profileID = id;
- profile->profileLoc.locType = iccfile ? cmPathBasedProfile : cmNoProfileBase;
- profile->profileName = dict;
-
- if (iccfile)
- strlcpy(profile->profileLoc.u.pathLoc.path, iccfile,
- sizeof(profile->profileLoc.u.pathLoc.path));
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-}
-
-
-/*
- * 'apple_register_profiles()' - Register color profiles for a printer.
- */
-
-static void
-apple_register_profiles(
- cupsd_printer_t *p) /* I - Printer */
-{
- int i; /* Looping var */
- char ppdfile[1024], /* PPD filename */
- iccfile[1024], /* ICC filename */
- selector[PPD_MAX_NAME];
- /* Profile selection string */
- ppd_file_t *ppd; /* PPD file */
- ppd_attr_t *attr, /* Profile attributes */
- *profileid_attr,/* cupsProfileID attribute */
- *q1_attr, /* ColorModel (or other) qualifier */
- *q2_attr, /* MediaType (or other) qualifier */
- *q3_attr; /* Resolution (or other) qualifier */
- char q_keyword[PPD_MAX_NAME];
- /* Qualifier keyword */
- const char *q1_choice, /* ColorModel (or other) choice */
- *q2_choice, /* MediaType (or other) choice */
- *q3_choice; /* Resolution (or other) choice */
- const char *profile_key; /* Profile keyword */
- ppd_option_t *cm_option; /* Color model option */
- ppd_choice_t *cm_choice; /* Color model choice */
- int num_profiles; /* Number of profiles */
- OSStatus error = 0; /* Last error */
- unsigned device_id, /* Printer device ID */
- profile_id = 0, /* Profile ID */
- default_profile_id = 0;
- /* Default profile ID */
- CFMutableDictionaryRef device_name; /* Printer device name dictionary */
- CFStringRef printer_name; /* Printer name string */
- cups_array_t *languages; /* Languages array */
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- CFMutableDictionaryRef profiles, /* Dictionary of profiles */
- profile; /* Current profile info dictionary */
- CFStringRef dict_key; /* Key in factory profile dictionary */
-# else
- CMDeviceScope scope = /* Scope of the registration */
- {
- kCFPreferencesAnyUser,
- kCFPreferencesCurrentHost
- };
- CMDeviceProfileArrayPtr profiles; /* Profiles */
- CMDeviceProfileInfo *profile; /* Current profile */
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
-
- /*
- * Make sure ColorSync is available...
- */
-
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- if (ColorSyncRegisterDevice == NULL)
- return;
-
-# else
- if (CMRegisterColorDevice == NULL)
- return;
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
- /*
- * Try opening the PPD file for this printer...
- */
-
- snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
- if ((ppd = ppdOpenFile(ppdfile)) == NULL)
- return;
-
- /*
- * See if we have any profiles...
- */
-
- if ((attr = ppdFindAttr(ppd, "APTiogaProfile", NULL)) != NULL)
- profile_key = "APTiogaProfile";
- else
- {
- attr = ppdFindAttr(ppd, "cupsICCProfile", NULL);
- profile_key = "cupsICCProfile";
- }
-
- for (num_profiles = 0; attr; attr = ppdFindNextAttr(ppd, profile_key, NULL))
- if (attr->spec[0] && attr->value && attr->value[0])
- {
- if (attr->value[0] != '/')
- snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir,
- attr->value);
- else
- strlcpy(iccfile, attr->value, sizeof(iccfile));
-
- if (access(iccfile, 0))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "%s: ICC Profile \"%s\" does not exist.", p->name,
- iccfile);
- continue;
- }
-
- num_profiles ++;
- }
-
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- /*
- * Create a dictionary for the factory profiles...
- */
-
- profiles = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- if (!profiles)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for factory profiles.");
- ppdClose(ppd);
- return;
- }
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
- /*
- * If we have profiles, add them...
- */
-
- if (num_profiles > 0)
- {
- if (profile_key[0] == 'A')
- {
- /*
- * For Tioga PPDs, get the default profile using the DefaultAPTiogaProfile
- * attribute...
- */
-
- if ((attr = ppdFindAttr(ppd, "DefaultAPTiogaProfile", NULL)) != NULL &&
- attr->value)
- default_profile_id = atoi(attr->value);
-
- q1_choice = q2_choice = q3_choice = NULL;
- }
- else
- {
- /*
- * For CUPS PPDs, figure out the default profile selector values...
- */
-
- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL &&
- attr->value && attr->value[0])
- {
- snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
- q1_attr = ppdFindAttr(ppd, q_keyword, NULL);
- }
- else if ((q1_attr = ppdFindAttr(ppd, "DefaultColorModel", NULL)) == NULL)
- q1_attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL);
-
- if (q1_attr && q1_attr->value && q1_attr->value[0])
- q1_choice = q1_attr->value;
- else
- q1_choice = "";
-
- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL &&
- attr->value && attr->value[0])
- {
- snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
- q2_attr = ppdFindAttr(ppd, q_keyword, NULL);
- }
- else
- q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL);
-
- if (q2_attr && q2_attr->value && q2_attr->value[0])
- q2_choice = q2_attr->value;
- else
- q2_choice = NULL;
-
- if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL &&
- attr->value && attr->value[0])
- {
- snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value);
- q3_attr = ppdFindAttr(ppd, q_keyword, NULL);
- }
- else
- q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL);
-
- if (q3_attr && q3_attr->value && q3_attr->value[0])
- q3_choice = q3_attr->value;
- else
- q3_choice = NULL;
- }
-
-# ifndef HAVE_COLORSYNCREGISTERDEVICE
- /*
- * Build the array of profiles...
- *
- * Note: This calloc actually requests slightly more memory than needed.
- */
-
- if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for factory profiles.");
- ppdClose(ppd);
- return;
- }
-
- profiles->profileCount = num_profiles;
- profile = profiles->profiles;
-# endif /* !HAVE_COLORSYNCREGISTERDEVICE */
-
- /*
- * Loop through the profiles listed in the PPD...
- */
-
- languages = _ppdGetLanguages(ppd);
-
- for (attr = ppdFindAttr(ppd, profile_key, NULL);
- attr;
- attr = ppdFindNextAttr(ppd, profile_key, NULL))
- if (attr->spec[0] && attr->value && attr->value[0])
- {
- /*
- * Add this profile...
- */
-
- if (attr->value[0] != '/')
- snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir,
- attr->value);
- else
- strlcpy(iccfile, attr->value, sizeof(iccfile));
-
- if (_cupsFileCheck(iccfile, _CUPS_FILE_CHECK_FILE, !RunUser,
- cupsdLogFCMessage, p))
- continue;
-
- if (profile_key[0] == 'c')
- {
- cupsArraySave(ppd->sorted_attrs);
-
- if ((profileid_attr = ppdFindAttr(ppd, "cupsProfileID",
- attr->spec)) != NULL &&
- profileid_attr->value && isdigit(profileid_attr->value[0] & 255))
- profile_id = (unsigned)strtoul(profileid_attr->value, NULL, 10);
- else
- profile_id = _ppdHashName(attr->spec);
-
- cupsArrayRestore(ppd->sorted_attrs);
- }
- else
- profile_id = atoi(attr->spec);
-
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- if (!profile)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for color profile.");
- CFRelease(profiles);
- ppdClose(ppd);
- return;
- }
-
- apple_init_profile(ppd, languages, profile, profile_id, attr->spec,
- attr->text[0] ? attr->text : attr->spec, iccfile);
-
- dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
- CFSTR("%u"), profile_id);
- if (dict_key)
- {
- CFDictionarySetValue(profiles, dict_key, profile);
- CFRelease(dict_key);
- }
-
- CFRelease(profile);
-
-# else
- apple_init_profile(ppd, languages, profile, profile_id, attr->spec,
- attr->text[0] ? attr->text : attr->spec, iccfile);
-
- profile ++;
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
- /*
- * See if this is the default profile...
- */
-
- if (!default_profile_id && q1_choice && q2_choice && q3_choice)
- {
- snprintf(selector, sizeof(selector), "%s.%s.%s", q1_choice, q2_choice,
- q3_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
-
- if (!default_profile_id && q1_choice && q2_choice)
- {
- snprintf(selector, sizeof(selector), "%s.%s.", q1_choice, q2_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
-
- if (!default_profile_id && q1_choice && q3_choice)
- {
- snprintf(selector, sizeof(selector), "%s..%s", q1_choice, q3_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
-
- if (!default_profile_id && q1_choice)
- {
- snprintf(selector, sizeof(selector), "%s..", q1_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
-
- if (!default_profile_id && q2_choice && q3_choice)
- {
- snprintf(selector, sizeof(selector), ".%s.%s", q2_choice, q3_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
-
- if (!default_profile_id && q2_choice)
- {
- snprintf(selector, sizeof(selector), ".%s.", q2_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
-
- if (!default_profile_id && q3_choice)
- {
- snprintf(selector, sizeof(selector), "..%s", q3_choice);
- if (!strcmp(selector, attr->spec))
- default_profile_id = profile_id;
- }
- }
-
- _ppdFreeLanguages(languages);
- }
- else if ((cm_option = ppdFindOption(ppd, "ColorModel")) != NULL)
- {
- /*
- * Extract profiles from ColorModel option...
- */
-
- const char *profile_name; /* Name of generic profile */
-
-
- num_profiles = cm_option->num_choices;
-
-# ifndef HAVE_COLORSYNCREGISTERDEVICE
- /*
- * Create an array for the factory profiles...
- */
-
- if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for factory profiles.");
- ppdClose(ppd);
- return;
- }
-
- profiles->profileCount = num_profiles;
- profile = profiles->profiles;
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
- for (i = cm_option->num_choices, cm_choice = cm_option->choices;
- i > 0;
- i --, cm_choice ++)
- {
- if (!strcmp(cm_choice->choice, "Gray") ||
- !strcmp(cm_choice->choice, "Black"))
- profile_name = "Gray";
- else if (!strcmp(cm_choice->choice, "RGB") ||
- !strcmp(cm_choice->choice, "CMY"))
- profile_name = "RGB";
- else if (!strcmp(cm_choice->choice, "CMYK") ||
- !strcmp(cm_choice->choice, "KCMY"))
- profile_name = "CMYK";
- else
- profile_name = "DeviceN";
-
- snprintf(selector, sizeof(selector), "%s..", profile_name);
- profile_id = _ppdHashName(selector);
-
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- if (!profile)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for color profile.");
- CFRelease(profiles);
- ppdClose(ppd);
- return;
- }
-
- apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice,
- cm_choice->text, NULL);
-
- dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
- CFSTR("%u"), profile_id);
- if (dict_key)
- {
- CFDictionarySetValue(profiles, dict_key, profile);
- CFRelease(dict_key);
- }
-
- CFRelease(profile);
-
-# else
- apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice,
- cm_choice->text, NULL);
- profile ++;
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
- if (cm_choice->marked)
- default_profile_id = profile_id;
- }
- }
- else
- {
- /*
- * Use the default colorspace...
- */
-
- attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL);
-
- num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2;
-
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- /*
- * Add the grayscale profile first. We always have a grayscale profile.
- */
-
- profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- if (!profile)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for color profile.");
- CFRelease(profiles);
- ppdClose(ppd);
- return;
- }
-
- profile_id = _ppdHashName("Gray..");
- apple_init_profile(ppd, NULL, profile, profile_id, "Gray", "Gray", NULL);
-
- dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"),
- profile_id);
- if (dict_key)
- {
- CFDictionarySetValue(profiles, dict_key, profile);
- CFRelease(dict_key);
- }
-
- CFRelease(profile);
-
- /*
- * Then add the RGB/CMYK/DeviceN color profile...
- */
-
- profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- if (!profile)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for color profile.");
- CFRelease(profiles);
- ppdClose(ppd);
- return;
- }
-
- switch (ppd->colorspace)
- {
- default :
- case PPD_CS_RGB :
- case PPD_CS_CMY :
- profile_id = _ppdHashName("RGB..");
- apple_init_profile(ppd, NULL, profile, profile_id, "RGB", "RGB",
- NULL);
- break;
-
- case PPD_CS_RGBK :
- case PPD_CS_CMYK :
- profile_id = _ppdHashName("CMYK..");
- apple_init_profile(ppd, NULL, profile, profile_id, "CMYK", "CMYK",
- NULL);
- break;
-
- case PPD_CS_GRAY :
- if (attr)
- break;
-
- case PPD_CS_N :
- profile_id = _ppdHashName("DeviceN..");
- apple_init_profile(ppd, NULL, profile, profile_id, "DeviceN",
- "DeviceN", NULL);
- break;
- }
-
- if (CFDictionaryGetCount(profile) > 0)
- {
- dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
- CFSTR("%u"), profile_id);
- if (dict_key)
- {
- CFDictionarySetValue(profiles, dict_key, profile);
- CFRelease(dict_key);
- }
- }
-
- CFRelease(profile);
-
-# else
- /*
- * Create an array for the factory profiles...
- */
-
- if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for factory profiles.");
- ppdClose(ppd);
- return;
- }
-
- profiles->profileCount = num_profiles;
-
- /*
- * Add the grayscale profile first. We always have a grayscale profile.
- */
-
- profile_id = _ppdHashName("Gray..");
- apple_init_profile(ppd, NULL, profiles->profiles, profile_id, "Gray",
- "Gray", NULL);
-
- /*
- * Then add the RGB/CMYK/DeviceN color profile...
- */
-
- switch (ppd->colorspace)
- {
- default :
- case PPD_CS_RGB :
- case PPD_CS_CMY :
- profile_id = _ppdHashName("RGB..");
- apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id,
- "RGB", "RGB", NULL);
- break;
- case PPD_CS_RGBK :
- case PPD_CS_CMYK :
- profile_id = _ppdHashName("CMYK..");
- apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id,
- "CMYK", "CMYK", NULL);
- break;
-
- case PPD_CS_GRAY :
- if (attr)
- break;
-
- case PPD_CS_N :
- profile_id = _ppdHashName("DeviceN..");
- apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id,
- "DeviceN", "DeviceN", NULL);
- break;
- }
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
- }
-
- if (num_profiles > 0)
- {
- /*
- * Make sure we have a default profile ID...
- */
-
- if (!default_profile_id)
- default_profile_id = profile_id; /* Last profile */
-
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"),
- default_profile_id);
- if (dict_key)
- {
- CFDictionarySetValue(profiles, kColorSyncDeviceDefaultProfileID,
- dict_key);
- CFRelease(dict_key);
- }
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
- /*
- * Get the device ID hash and pathelogical name dictionary.
- */
-
- cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\"",
- p->name);
-
- device_id = _ppdHashName(p->name);
- device_name = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- printer_name = CFStringCreateWithCString(kCFAllocatorDefault,
- p->name, kCFStringEncodingUTF8);
-
- if (device_name && printer_name)
- {
- CFDictionarySetValue(device_name, CFSTR("en_US"), printer_name);
-
- /*
- * Register the device with ColorSync...
- */
-
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- CFTypeRef deviceDictKeys[] =
- { /* Device keys */
- kColorSyncDeviceDescriptions,
- kColorSyncFactoryProfiles,
- kColorSyncDeviceUserScope,
- kColorSyncDeviceHostScope
- };
- CFTypeRef deviceDictVals[] =
- { /* Device values */
- device_name,
- profiles,
- kCFPreferencesAnyUser,
- kCFPreferencesCurrentHost
- };
- CFDictionaryRef deviceDict; /* Device dictionary */
- CFUUIDRef deviceUUID; /* Device UUID */
-
- deviceDict = CFDictionaryCreate(kCFAllocatorDefault,
- (const void **)deviceDictKeys,
- (const void **)deviceDictVals,
- sizeof(deviceDictKeys) /
- sizeof(deviceDictKeys[0]),
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- deviceUUID = ColorSyncCreateUUIDFromUInt32(device_id);
-
- if (!deviceDict || !deviceUUID ||
- !ColorSyncRegisterDevice(kColorSyncPrinterDeviceClass, deviceUUID,
- deviceDict))
- error = 1001;
-
- if (deviceUUID)
- CFRelease(deviceUUID);
-
- if (deviceDict)
- CFRelease(deviceDict);
-
-# else
- error = CMRegisterColorDevice(cmPrinterDeviceClass, device_id,
- device_name, &scope);
-
- /*
- * Register the profiles...
- */
-
- if (error == noErr)
- error = CMSetDeviceFactoryProfiles(cmPrinterDeviceClass, device_id,
- default_profile_id, profiles);
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
- }
- else
- error = 1000;
-
- /*
- * Clean up...
- */
-
- if (error != noErr)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to register ICC color profiles for \"%s\": %d",
- p->name, (int)error);
-
- if (printer_name)
- CFRelease(printer_name);
-
- if (device_name)
- CFRelease(device_name);
- }
-
- /*
- * Free any memory we used...
- */
-
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- CFRelease(profiles);
-
-# else
- if (num_profiles > 0)
- {
- for (profile = profiles->profiles;
- num_profiles > 0;
- profile ++, num_profiles --)
- CFRelease(profile->profileName);
-
- free(profiles);
- }
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
- ppdClose(ppd);
-}
-
-
-/*
- * 'apple_unregister_profiles()' - Remove color profiles for the specified
- * printer.
- */
-
-static void
-apple_unregister_profiles(
- cupsd_printer_t *p) /* I - Printer */
-{
- /*
- * Make sure ColorSync is available...
- */
-
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
- if (ColorSyncUnregisterDevice != NULL)
- {
- /*
- * Because we may have registered the printer profiles using a prior device
- * ID-based UUID, remove both the old style UUID and current UUID for the
- * printer.
- */
-
- CFUUIDRef deviceUUID; /* Device UUID */
-
- deviceUUID = ColorSyncCreateUUIDFromUInt32(_ppdHashName(p->name));
- if (deviceUUID)
- {
- ColorSyncUnregisterDevice(kColorSyncPrinterDeviceClass, deviceUUID);
- CFRelease(deviceUUID);
- }
- }
-
-# else
- if (CMUnregisterColorDevice != NULL)
- CMUnregisterColorDevice(cmPrinterDeviceClass, _ppdHashName(p->name));
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-}
-#endif /* __APPLE__ */
-
-
/*
* 'apply_printer_defaults()' - Apply printer default options to a job.
*/
@@ -5042,8 +4070,6 @@ close_job(cupsd_client_t *con, /* I - Client connection */
ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
job->state_value);
- add_job_state_reasons(con, job);
-
con->response->request.status.status_code = IPP_OK;
/*
@@ -5055,192 +4081,6 @@ close_job(cupsd_client_t *con, /* I - Client connection */
/*
- * 'copy_attribute()' - Copy a single attribute.
- */
-
-static ipp_attribute_t * /* O - New attribute */
-copy_attribute(
- ipp_t *to, /* O - Destination request/response */
- ipp_attribute_t *attr, /* I - Attribute to copy */
- int quickcopy) /* I - Do a quick copy? */
-{
- int i; /* Looping var */
- ipp_attribute_t *toattr; /* Destination attribute */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "copy_attribute(%p, %p[%s,%x,%x])", to, attr,
- attr->name ? attr->name : "(null)", attr->group_tag,
- attr->value_tag);
-
- switch (attr->value_tag & ~IPP_TAG_COPY)
- {
- case IPP_TAG_ZERO :
- toattr = ippAddSeparator(to);
- break;
-
- case IPP_TAG_INTEGER :
- case IPP_TAG_ENUM :
- toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag,
- attr->name, attr->num_values, NULL);
-
- for (i = 0; i < attr->num_values; i ++)
- toattr->values[i].integer = attr->values[i].integer;
- break;
-
- case IPP_TAG_BOOLEAN :
- toattr = ippAddBooleans(to, attr->group_tag, attr->name,
- attr->num_values, NULL);
-
- for (i = 0; i < attr->num_values; i ++)
- toattr->values[i].boolean = attr->values[i].boolean;
- break;
-
- case IPP_TAG_STRING :
- case IPP_TAG_TEXT :
- case IPP_TAG_NAME :
- case IPP_TAG_KEYWORD :
- case IPP_TAG_URI :
- case IPP_TAG_URISCHEME :
- case IPP_TAG_CHARSET :
- case IPP_TAG_LANGUAGE :
- case IPP_TAG_MIMETYPE :
- toattr = ippAddStrings(to, attr->group_tag,
- (ipp_tag_t)(attr->value_tag | quickcopy),
- attr->name, attr->num_values, NULL, NULL);
-
- if (quickcopy)
- {
- for (i = 0; i < attr->num_values; i ++)
- toattr->values[i].string.text = attr->values[i].string.text;
- }
- else if (attr->value_tag & IPP_TAG_COPY)
- {
- for (i = 0; i < attr->num_values; i ++)
- toattr->values[i].string.text =
- _cupsStrAlloc(attr->values[i].string.text);
- }
- else
- {
- for (i = 0; i < attr->num_values; i ++)
- toattr->values[i].string.text =
- _cupsStrRetain(attr->values[i].string.text);
- }
- break;
-
- case IPP_TAG_DATE :
- toattr = ippAddDate(to, attr->group_tag, attr->name,
- attr->values[0].date);
- break;
-
- case IPP_TAG_RESOLUTION :
- toattr = ippAddResolutions(to, attr->group_tag, attr->name,
- attr->num_values, IPP_RES_PER_INCH,
- NULL, NULL);
-
- for (i = 0; i < attr->num_values; i ++)
- {
- toattr->values[i].resolution.xres = attr->values[i].resolution.xres;
- toattr->values[i].resolution.yres = attr->values[i].resolution.yres;
- toattr->values[i].resolution.units = attr->values[i].resolution.units;
- }
- break;
-
- case IPP_TAG_RANGE :
- toattr = ippAddRanges(to, attr->group_tag, attr->name,
- attr->num_values, NULL, NULL);
-
- for (i = 0; i < attr->num_values; i ++)
- {
- toattr->values[i].range.lower = attr->values[i].range.lower;
- toattr->values[i].range.upper = attr->values[i].range.upper;
- }
- break;
-
- case IPP_TAG_TEXTLANG :
- case IPP_TAG_NAMELANG :
- toattr = ippAddStrings(to, attr->group_tag,
- (ipp_tag_t)(attr->value_tag | quickcopy),
- attr->name, attr->num_values, NULL, NULL);
-
- if (quickcopy)
- {
- for (i = 0; i < attr->num_values; i ++)
- {
- toattr->values[i].string.charset = attr->values[i].string.charset;
- toattr->values[i].string.text = attr->values[i].string.text;
- }
- }
- else if (attr->value_tag & IPP_TAG_COPY)
- {
- for (i = 0; i < attr->num_values; i ++)
- {
- if (!i)
- toattr->values[i].string.charset =
- _cupsStrAlloc(attr->values[i].string.charset);
- else
- toattr->values[i].string.charset =
- toattr->values[0].string.charset;
-
- toattr->values[i].string.text =
- _cupsStrAlloc(attr->values[i].string.text);
- }
- }
- else
- {
- for (i = 0; i < attr->num_values; i ++)
- {
- if (!i)
- toattr->values[i].string.charset =
- _cupsStrRetain(attr->values[i].string.charset);
- else
- toattr->values[i].string.charset =
- toattr->values[0].string.charset;
-
- toattr->values[i].string.text =
- _cupsStrRetain(attr->values[i].string.text);
- }
- }
- break;
-
- case IPP_TAG_BEGIN_COLLECTION :
- toattr = ippAddCollections(to, attr->group_tag, attr->name,
- attr->num_values, NULL);
-
- for (i = 0; i < attr->num_values; i ++)
- {
- toattr->values[i].collection = attr->values[i].collection;
- attr->values[i].collection->use ++;
- }
- break;
-
- default :
- toattr = ippAddIntegers(to, attr->group_tag, attr->value_tag,
- attr->name, attr->num_values, NULL);
-
- for (i = 0; i < attr->num_values; i ++)
- {
- toattr->values[i].unknown.length = attr->values[i].unknown.length;
-
- if (toattr->values[i].unknown.length > 0)
- {
- if ((toattr->values[i].unknown.data =
- malloc(toattr->values[i].unknown.length)) == NULL)
- toattr->values[i].unknown.length = 0;
- else
- memcpy(toattr->values[i].unknown.data,
- attr->values[i].unknown.data,
- toattr->values[i].unknown.length);
- }
- }
- break; /* anti-compiler-warning-code */
- }
-
- return (toattr);
-}
-
-
-/*
* 'copy_attrs()' - Copy attributes from one request to another.
*/
@@ -5307,7 +4147,7 @@ copy_attrs(ipp_t *to, /* I - Destination request */
!strcmp(fromattr->name, "media-col-database")))
continue;
- copy_attribute(to, fromattr, quickcopy);
+ ippCopyAttribute(to, fromattr, quickcopy);
}
}
}
@@ -5528,7 +4368,7 @@ copy_banner(cupsd_client_t *con, /* I - Client connection */
cupsFilePrintf(out, "%dx%d%s", attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
break;
case IPP_TAG_URI :
@@ -5791,11 +4631,22 @@ copy_model(cupsd_client_t *con, /* I - Client connection */
}
/*
+ * Open the source file for a copy...
+ */
+
+ if ((src = cupsFileOpen(tempfile, "rb")) == NULL)
+ {
+ unlink(tempfile);
+ return (-1);
+ }
+
+ /*
* Read the source file and see what page sizes are supported...
*/
- if ((ppd = ppdOpenFile(tempfile)) == NULL)
+ if ((ppd = _ppdOpen(src, _PPD_LOCALIZATION_NONE)) == NULL)
{
+ cupsFileClose(src);
unlink(tempfile);
return (-1);
}
@@ -5863,17 +4714,6 @@ copy_model(cupsd_client_t *con, /* I - Client connection */
ppdClose(ppd);
/*
- * Open the source file for a copy...
- */
-
- if ((src = cupsFileOpen(tempfile, "rb")) == NULL)
- {
- cupsFreeOptions(num_defaults, defaults);
- unlink(tempfile);
- return (-1);
- }
-
- /*
* Open the destination file for a copy...
*/
@@ -5889,6 +4729,8 @@ copy_model(cupsd_client_t *con, /* I - Client connection */
* Copy the source file to the destination...
*/
+ cupsFileRewind(src);
+
while (cupsFileGets(src, buffer, sizeof(buffer)))
{
if (!strncmp(buffer, "*Default", 8))
@@ -5953,10 +4795,10 @@ copy_job_attrs(cupsd_client_t *con, /* I - Client connection */
if (!cupsArrayFind(exclude, "all"))
{
- if ((!exclude || !cupsArrayFind(exclude, "document-count")) &&
- (!ra || cupsArrayFind(ra, "document-count")))
+ if ((!exclude || !cupsArrayFind(exclude, "number-of-documents")) &&
+ (!ra || cupsArrayFind(ra, "number-of-documents")))
ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER,
- "document-count", job->num_files);
+ "number-of-documents", job->num_files);
if ((!exclude || !cupsArrayFind(exclude, "job-media-progress")) &&
(!ra || cupsArrayFind(ra, "job-media-progress")))
@@ -5989,16 +4831,13 @@ copy_job_attrs(cupsd_client_t *con, /* I - Client connection */
{
httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
con->servername, con->serverport,
- job->dtype & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS) ?
- "/classes/%s" : "/printers/%s",
+ (job->dtype & CUPS_PRINTER_CLASS) ? "/classes/%s" :
+ "/printers/%s",
job->dest);
ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
"job-printer-uri", NULL, job_uri);
}
- if (!ra || cupsArrayFind(ra, "job-state-reasons"))
- add_job_state_reasons(con, job);
-
if (!ra || cupsArrayFind(ra, "job-uri"))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
@@ -6089,7 +4928,7 @@ copy_printer_attrs(
ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
ippTimeToDate(curtime));
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
if (!ra || cupsArrayFind(ra, "printer-dns-sd-name"))
{
if (printer->reg_name)
@@ -6099,7 +4938,7 @@ copy_printer_attrs(
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE,
"printer-dns-sd-name", 0);
}
-#endif /* HAVE_DNSSD */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
if (!ra || cupsArrayFind(ra, "printer-error-policy"))
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
@@ -6115,7 +4954,7 @@ copy_printer_attrs(
"stop-printer"
};
- if (printer->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS))
+ if (printer->type & CUPS_PRINTER_CLASS)
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY,
"printer-error-policy-supported", NULL, "retry-current-job");
else
@@ -6142,8 +4981,7 @@ copy_printer_attrs(
ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared",
printer->shared);
- if ((!ra || cupsArrayFind(ra, "printer-more-info")) &&
- !(printer->type & CUPS_PRINTER_DISCOVERED))
+ if (!ra || cupsArrayFind(ra, "printer-more-info"))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
"http", NULL, con->servername, con->serverport,
@@ -6199,8 +5037,7 @@ copy_printer_attrs(
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"printer-up-time", curtime);
- if ((!ra || cupsArrayFind(ra, "printer-uri-supported")) &&
- !(printer->type & CUPS_PRINTER_DISCOVERED))
+ if (!ra || cupsArrayFind(ra, "printer-uri-supported"))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
"ipp", NULL, con->servername, con->serverport,
@@ -6350,8 +5187,16 @@ static void
create_job(cupsd_client_t *con, /* I - Client connection */
ipp_attribute_t *uri) /* I - Printer URI */
{
+ int i; /* Looping var */
cupsd_printer_t *printer; /* Printer */
cupsd_job_t *job; /* New job */
+ static const char * const forbidden_attrs[] =
+ { /* List of forbidden attributes */
+ "compression",
+ "document-format",
+ "document-name",
+ "document-natural-language"
+ };
cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", con,
@@ -6373,6 +5218,29 @@ create_job(cupsd_client_t *con, /* I - Client connection */
}
/*
+ * Check for invalid Create-Job attributes and log a warning or error depending
+ * on whether cupsd is running in "strict conformance" mode...
+ */
+
+ for (i = 0;
+ i < (int)(sizeof(forbidden_attrs) / sizeof(forbidden_attrs[0]));
+ i ++)
+ if (ippFindAttribute(con->request, forbidden_attrs[i], IPP_TAG_ZERO))
+ {
+ if (StrictConformance)
+ {
+ send_ipp_status(con, IPP_BAD_REQUEST,
+ _("The '%s' operation attribute cannot be supplied in a "
+ "Create-Job request."), forbidden_attrs[i]);
+ return;
+ }
+
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "Unexpected '%s' operation attribute in a Create-Job "
+ "request.", forbidden_attrs[i]);
+ }
+
+ /*
* Create the job object...
*/
@@ -6432,6 +5300,7 @@ create_requested_array(ipp_t *request) /* I - IPP request */
if (!strcmp(value, "job-template"))
{
+ /* Only includes the set of Job Template attributes supported by CUPS */
cupsArrayAdd(ra, "copies");
cupsArrayAdd(ra, "copies-default");
cupsArrayAdd(ra, "copies-supported");
@@ -6448,6 +5317,8 @@ create_requested_array(ipp_t *request) /* I - IPP request */
cupsArrayAdd(ra, "job-sheets-default");
cupsArrayAdd(ra, "job-sheets-supported");
cupsArrayAdd(ra, "media");
+ cupsArrayAdd(ra, "media-col");
+ cupsArrayAdd(ra, "media-col-default");
cupsArrayAdd(ra, "media-default");
cupsArrayAdd(ra, "media-supported");
cupsArrayAdd(ra, "multiple-document-handling");
@@ -6455,24 +5326,49 @@ create_requested_array(ipp_t *request) /* I - IPP request */
cupsArrayAdd(ra, "multiple-document-handling-supported");
cupsArrayAdd(ra, "number-up");
cupsArrayAdd(ra, "number-up-default");
+ cupsArrayAdd(ra, "number-up-layout");
+ cupsArrayAdd(ra, "number-up-layout-default");
+ cupsArrayAdd(ra, "number-up-layout-supported");
cupsArrayAdd(ra, "number-up-supported");
cupsArrayAdd(ra, "orientation-requested");
cupsArrayAdd(ra, "orientation-requested-default");
cupsArrayAdd(ra, "orientation-requested-supported");
+ cupsArrayAdd(ra, "output-bin");
+ cupsArrayAdd(ra, "output-bin-default");
+ cupsArrayAdd(ra, "output-bin-supported");
+ cupsArrayAdd(ra, "page-delivery");
+ cupsArrayAdd(ra, "page-delivery-default");
+ cupsArrayAdd(ra, "page-delivery-supported");
+ cupsArrayAdd(ra, "page-order-received");
+ cupsArrayAdd(ra, "page-order-received-default");
+ cupsArrayAdd(ra, "page-order-received-supported");
cupsArrayAdd(ra, "page-ranges");
cupsArrayAdd(ra, "page-ranges-supported");
- cupsArrayAdd(ra, "printer-resolution");
- cupsArrayAdd(ra, "printer-resolution-default");
- cupsArrayAdd(ra, "printer-resolution-supported");
+ cupsArrayAdd(ra, "presentation-direction-number-up");
+ cupsArrayAdd(ra, "presentation-direction-number-up-default");
+ cupsArrayAdd(ra, "presentation-direction-number-up-supported");
+ cupsArrayAdd(ra, "print-color-mode");
+ cupsArrayAdd(ra, "print-color-mode-default");
+ cupsArrayAdd(ra, "print-color-mode-supported");
+ cupsArrayAdd(ra, "print-content-optimize");
+ cupsArrayAdd(ra, "print-content-optimize-default");
+ cupsArrayAdd(ra, "print-content-optimize-supported");
cupsArrayAdd(ra, "print-quality");
cupsArrayAdd(ra, "print-quality-default");
cupsArrayAdd(ra, "print-quality-supported");
+ cupsArrayAdd(ra, "printer-resolution");
+ cupsArrayAdd(ra, "printer-resolution-default");
+ cupsArrayAdd(ra, "printer-resolution-supported");
+ cupsArrayAdd(ra, "sheet-collate");
+ cupsArrayAdd(ra, "sheet-collate-default");
+ cupsArrayAdd(ra, "sheet-collate-supported");
cupsArrayAdd(ra, "sides");
cupsArrayAdd(ra, "sides-default");
cupsArrayAdd(ra, "sides-supported");
}
else if (!strcmp(value, "job-description"))
{
+ /* Only includes the set of Job Description attributes supported by CUPS */
cupsArrayAdd(ra, "date-time-at-completed");
cupsArrayAdd(ra, "date-time-at-creation");
cupsArrayAdd(ra, "date-time-at-processing");
@@ -6483,6 +5379,7 @@ create_requested_array(ipp_t *request) /* I - IPP request */
cupsArrayAdd(ra, "job-impressions-completed");
cupsArrayAdd(ra, "job-k-octets");
cupsArrayAdd(ra, "job-k-octets-processed");
+ cupsArrayAdd(ra, "job-mandatory-attributes");
cupsArrayAdd(ra, "job-media-progress");
cupsArrayAdd(ra, "job-media-sheets");
cupsArrayAdd(ra, "job-media-sheets-completed");
@@ -6505,6 +5402,7 @@ create_requested_array(ipp_t *request) /* I - IPP request */
}
else if (!strcmp(value, "printer-description"))
{
+ /* Only includes the set of Printer Description attributes supported by CUPS */
cupsArrayAdd(ra, "charset-configured");
cupsArrayAdd(ra, "charset-supported");
cupsArrayAdd(ra, "color-supported");
@@ -6513,43 +5411,54 @@ create_requested_array(ipp_t *request) /* I - IPP request */
cupsArrayAdd(ra, "document-format-supported");
cupsArrayAdd(ra, "generated-natural-language-supported");
cupsArrayAdd(ra, "ipp-versions-supported");
+ cupsArrayAdd(ra, "job-creation-attributes-supported");
+ cupsArrayAdd(ra, "job-ids-supported");
cupsArrayAdd(ra, "job-impressions-supported");
cupsArrayAdd(ra, "job-k-octets-supported");
cupsArrayAdd(ra, "job-media-sheets-supported");
cupsArrayAdd(ra, "job-settable-attributes-supported");
+ cupsArrayAdd(ra, "jpeg-k-octets-supported");
+ cupsArrayAdd(ra, "jpeg-x-dimension-supported");
+ cupsArrayAdd(ra, "jpeg-y-dimension-supported");
+ cupsArrayAdd(ra, "media-bottom-margin-supported");
+ cupsArrayAdd(ra, "media-col-supported");
+ cupsArrayAdd(ra, "media-key-supported");
+ cupsArrayAdd(ra, "media-left-margin-supported");
+ cupsArrayAdd(ra, "media-right-margin-supported");
+ cupsArrayAdd(ra, "media-size-supported");
+ cupsArrayAdd(ra, "media-source-supported");
+ cupsArrayAdd(ra, "media-top-margin-supported");
+ cupsArrayAdd(ra, "media-type-supported");
cupsArrayAdd(ra, "multiple-document-jobs-supported");
cupsArrayAdd(ra, "multiple-operation-time-out");
cupsArrayAdd(ra, "natural-language-configured");
- cupsArrayAdd(ra, "notify-attributes-supported");
- cupsArrayAdd(ra, "notify-lease-duration-default");
- cupsArrayAdd(ra, "notify-lease-duration-supported");
cupsArrayAdd(ra, "notify-max-events-supported");
- cupsArrayAdd(ra, "notify-events-default");
- cupsArrayAdd(ra, "notify-events-supported");
- cupsArrayAdd(ra, "notify-pull-method-supported");
cupsArrayAdd(ra, "notify-schemes-supported");
cupsArrayAdd(ra, "operations-supported");
cupsArrayAdd(ra, "pages-per-minute");
cupsArrayAdd(ra, "pages-per-minute-color");
+ cupsArrayAdd(ra, "pdf-k-octets-supported");
cupsArrayAdd(ra, "pdl-override-supported");
cupsArrayAdd(ra, "printer-alert");
cupsArrayAdd(ra, "printer-alert-description");
cupsArrayAdd(ra, "printer-commands");
cupsArrayAdd(ra, "printer-current-time");
- cupsArrayAdd(ra, "printer-driver-installer");
cupsArrayAdd(ra, "printer-dns-sd-name");
cupsArrayAdd(ra, "printer-info");
cupsArrayAdd(ra, "printer-is-accepting-jobs");
+ cupsArrayAdd(ra, "printer-is-shared");
cupsArrayAdd(ra, "printer-location");
cupsArrayAdd(ra, "printer-make-and-model");
cupsArrayAdd(ra, "printer-message-from-operator");
cupsArrayAdd(ra, "printer-more-info");
cupsArrayAdd(ra, "printer-more-info-manufacturer");
cupsArrayAdd(ra, "printer-name");
+ cupsArrayAdd(ra, "printer-settable-attributes-supported");
cupsArrayAdd(ra, "printer-state");
+ cupsArrayAdd(ra, "printer-state-change-date-time");
+ cupsArrayAdd(ra, "printer-state-change-time");
cupsArrayAdd(ra, "printer-state-message");
cupsArrayAdd(ra, "printer-state-reasons");
- cupsArrayAdd(ra, "printer-settable-attributes-supported");
cupsArrayAdd(ra, "printer-type");
cupsArrayAdd(ra, "printer-up-time");
cupsArrayAdd(ra, "printer-uri-supported");
@@ -6557,6 +5466,7 @@ create_requested_array(ipp_t *request) /* I - IPP request */
cupsArrayAdd(ra, "reference-uri-schemes-supported");
cupsArrayAdd(ra, "uri-authentication-supported");
cupsArrayAdd(ra, "uri-security-supported");
+ cupsArrayAdd(ra, "which-jobs-supported");
}
else if (!strcmp(value, "printer-defaults"))
{
@@ -6568,14 +5478,32 @@ create_requested_array(ipp_t *request) /* I - IPP request */
name = (char *)cupsArrayNext(CommonDefaults))
cupsArrayAdd(ra, name);
}
+ else if (!strcmp(value, "subscription-description"))
+ {
+ /* Only includes the set of Subscription Description attributes supported by CUPS */
+ cupsArrayAdd(ra, "notify-job-id");
+ cupsArrayAdd(ra, "notify-lease-expiration-time");
+ cupsArrayAdd(ra, "notify-printer-up-time");
+ cupsArrayAdd(ra, "notify-printer-uri");
+ cupsArrayAdd(ra, "notify-sequence-number");
+ cupsArrayAdd(ra, "notify-subscriber-user-name");
+ cupsArrayAdd(ra, "notify-subscription-id");
+ }
else if (!strcmp(value, "subscription-template"))
{
+ /* Only includes the set of Subscription Template attributes supported by CUPS */
cupsArrayAdd(ra, "notify-attributes");
+ cupsArrayAdd(ra, "notify-attributes-supported");
cupsArrayAdd(ra, "notify-charset");
cupsArrayAdd(ra, "notify-events");
+ cupsArrayAdd(ra, "notify-events-default");
+ cupsArrayAdd(ra, "notify-events-supported");
cupsArrayAdd(ra, "notify-lease-duration");
+ cupsArrayAdd(ra, "notify-lease-duration-default");
+ cupsArrayAdd(ra, "notify-lease-duration-supported");
cupsArrayAdd(ra, "notify-natural-language");
cupsArrayAdd(ra, "notify-pull-method");
+ cupsArrayAdd(ra, "notify-pull-method-supported");
cupsArrayAdd(ra, "notify-recipient-uri");
cupsArrayAdd(ra, "notify-time-interval");
cupsArrayAdd(ra, "notify-user-data");
@@ -7034,13 +5962,11 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */
snprintf(filename, sizeof(filename), "%s/%s.data", CacheDir, printer->name);
unlink(filename);
-#ifdef __APPLE__
/*
* Unregister color profiles...
*/
- apple_unregister_profiles(printer);
-#endif /* __APPLE__ */
+ cupsdUnregisterColor(printer);
if (dtype & CUPS_PRINTER_CLASS)
{
@@ -8062,11 +6988,10 @@ get_ppd(cupsd_client_t *con, /* I - Client connection */
"printer-uri", NULL, dest->uri);
return;
}
- else if (dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ else if (dtype & CUPS_PRINTER_CLASS)
{
for (i = 0; i < dest->num_printers; i ++)
- if (!(dest->printers[i]->type &
- (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)))
+ if (!(dest->printers[i]->type & CUPS_PRINTER_CLASS))
{
snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
dest->printers[i]->name);
@@ -8514,15 +7439,6 @@ get_printers(cupsd_client_t *con, /* I - Client connection */
(printer->location && !_cups_strcasecmp(printer->location, location))))
{
/*
- * If HideImplicitMembers is enabled, see if this printer or class
- * is a member of an implicit class...
- */
-
- if (ImplicitClasses && HideImplicitMembers &&
- printer->in_implicit_class)
- continue;
-
- /*
* If a username is specified, see if it is allowed or denied
* access...
*/
@@ -9416,7 +8332,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */
* Grab format from client...
*/
- if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super,
+ if (sscanf(format->values[0].string.text, "%15[^/]/%255[^;]", super,
type) != 2)
{
send_ipp_status(con, IPP_BAD_REQUEST,
@@ -9433,7 +8349,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */
* Use default document format...
*/
- if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2)
+ if (sscanf(default_format, "%15[^/]/%255[^;]", super, type) != 2)
{
send_ipp_status(con, IPP_BAD_REQUEST,
_("Bad document-format \"%s\"."),
@@ -9747,14 +8663,14 @@ read_job_ticket(cupsd_client_t *con) /* I - Client connection */
if (con->request->last == attr2)
con->request->last = prev2;
- _ippFreeAttr(attr2);
+ ippDeleteAttribute(NULL, attr2);
}
/*
* Add new option by copying it...
*/
- copy_attribute(con->request, attr, 0);
+ ippCopyAttribute(con->request, attr, 0);
}
/*
@@ -10035,6 +8951,7 @@ release_job(cupsd_client_t *con, /* I - Client connection */
cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
"Job job-hold-until value changed by user.");
+ ippSetString(job->attrs, &job->reasons, 0, "none");
}
/*
@@ -10362,7 +9279,7 @@ save_auth_info(
fchown(cupsFileNumber(fp), 0, 0);
fchmod(cupsFileNumber(fp), 0400);
- cupsFilePuts(fp, "CUPSD-AUTH-V2\n");
+ cupsFilePuts(fp, "CUPSD-AUTH-V3\n");
for (i = 0;
i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
@@ -10380,9 +9297,15 @@ save_auth_info(
i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
i ++)
{
- httpEncode64_2(line, sizeof(line), auth_info->values[i].string.text,
- strlen(auth_info->values[i].string.text));
- cupsFilePutConf(fp, dest->auth_info_required[i], line);
+ if (strcmp(dest->auth_info_required[i], "negotiate"))
+ {
+ httpEncode64_2(line, sizeof(line), auth_info->values[i].string.text,
+ strlen(auth_info->values[i].string.text));
+ cupsFilePutConf(fp, dest->auth_info_required[i], line);
+ }
+ else
+ cupsFilePutConf(fp, dest->auth_info_required[i],
+ auth_info->values[i].string.text);
if (!strcmp(dest->auth_info_required[i], "username"))
cupsdSetStringf(job->auth_env + i, "AUTH_USERNAME=%s",
@@ -10646,7 +9569,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */
* Grab format from client...
*/
- if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]",
+ if (sscanf(format->values[0].string.text, "%15[^/]/%255[^;]",
super, type) != 2)
{
send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"."),
@@ -10662,7 +9585,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */
* Use default document format...
*/
- if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2)
+ if (sscanf(default_format, "%15[^/]/%255[^;]", super, type) != 2)
{
send_ipp_status(con, IPP_BAD_REQUEST,
_("Bad document-format-default \"%s\"."), default_format);
@@ -10804,6 +9727,8 @@ send_document(cupsd_client_t *con, /* I - Client connection */
{
job->state->values[0].integer = IPP_JOB_PENDING;
job->state_value = IPP_JOB_PENDING;
+
+ ippSetString(job->attrs, &job->reasons, 0, "none");
}
else if (job->state_value == IPP_JOB_HELD)
{
@@ -10815,7 +9740,11 @@ send_document(cupsd_client_t *con, /* I - Client connection */
{
job->state->values[0].integer = IPP_JOB_PENDING;
job->state_value = IPP_JOB_PENDING;
+
+ ippSetString(job->attrs, &job->reasons, 0, "none");
}
+ else
+ ippSetString(job->attrs, &job->reasons, 0, "job-hold-until-specified");
}
job->dirty = 1;
@@ -10834,8 +9763,10 @@ send_document(cupsd_client_t *con, /* I - Client connection */
job->state->values[0].integer = IPP_JOB_HELD;
job->state_value = IPP_JOB_HELD;
job->hold_until = time(NULL) + MultipleOperationTimeout;
- job->dirty = 1;
+ ippSetString(job->attrs, &job->reasons, 0, "job-incoming");
+
+ job->dirty = 1;
cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
@@ -10855,7 +9786,8 @@ send_document(cupsd_client_t *con, /* I - Client connection */
ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
job->state_value);
- add_job_state_reasons(con, job);
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons",
+ NULL, job->reasons->values[0].string.text);
con->response->request.status.status_code = IPP_OK;
@@ -10940,7 +9872,7 @@ send_http_error(
if (auth)
{
if (auth->type == CUPSD_AUTH_DEFAULT)
- auth_type = DefaultAuthType;
+ auth_type = cupsdDefaultAuthType();
else
auth_type = auth->type;
}
@@ -11055,7 +9987,7 @@ set_default(cupsd_client_t *con, /* I - Client connection */
"%s is now the default printer.", printer->name);
cupsdMarkDirty(CUPSD_DIRTY_PRINTERS | CUPSD_DIRTY_CLASSES |
- CUPSD_DIRTY_REMOTE | CUPSD_DIRTY_PRINTCAP);
+ CUPSD_DIRTY_PRINTCAP);
cupsdLogMessage(CUPSD_LOG_INFO,
"Default destination set to \"%s\" by \"%s\".",
@@ -11233,9 +10165,8 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */
send_ipp_status(con, IPP_ATTRIBUTES_NOT_SETTABLE,
_("%s cannot be changed."), attr->name);
- if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL)
- attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
-
+ attr2 = ippCopyAttribute(con->response, attr, 0);
+ ippSetGroupTag(con->response, &attr2, IPP_TAG_UNSUPPORTED_GROUP);
continue;
}
@@ -11249,8 +10180,8 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */
{
send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-priority value."));
- if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL)
- attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
+ attr2 = ippCopyAttribute(con->response, attr, 0);
+ ippSetGroupTag(con->response, &attr2, IPP_TAG_UNSUPPORTED_GROUP);
}
else if (job->state_value >= IPP_JOB_PROCESSING)
{
@@ -11279,8 +10210,8 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */
{
send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-state value."));
- if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL)
- attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
+ attr2 = ippCopyAttribute(con->response, attr, 0);
+ ippSetGroupTag(con->response, &attr2, IPP_TAG_UNSUPPORTED_GROUP);
}
else
{
@@ -11354,13 +10285,13 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */
if (job->attrs->last == attr2)
job->attrs->last = job->attrs->prev;
- _ippFreeAttr(attr2);
+ ippDeleteAttribute(NULL, attr2);
/*
* Then copy the attribute...
*/
- copy_attribute(job->attrs, attr, 0);
+ ippCopyAttribute(job->attrs, attr, 0);
/*
* See if the job-name or job-hold-until is being changed.
@@ -11401,7 +10332,7 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */
if (attr2 == job->attrs->last)
job->attrs->last = job->attrs->prev;
- _ippFreeAttr(attr2);
+ ippDeleteAttribute(NULL, attr2);
event |= CUPSD_EVENT_JOB_CONFIG_CHANGED;
}
@@ -11412,7 +10343,7 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */
* Add new option by copying it...
*/
- copy_attribute(job->attrs, attr, 0);
+ ippCopyAttribute(job->attrs, attr, 0);
event |= CUPSD_EVENT_JOB_CONFIG_CHANGED;
}
@@ -11677,7 +10608,7 @@ set_printer_defaults(
continue;
if (strcmp(attr->values[0].string.text, "retry-current-job") &&
- ((printer->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS)) ||
+ ((printer->type & CUPS_PRINTER_CLASS) ||
(strcmp(attr->values[0].string.text, "abort-job") &&
strcmp(attr->values[0].string.text, "retry-job") &&
strcmp(attr->values[0].string.text, "stop-printer"))))
@@ -11767,7 +10698,7 @@ set_printer_defaults(
sprintf(value, "%dx%d%s", attr->values[0].resolution.xres,
attr->values[0].resolution.yres,
attr->values[0].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
printer->num_options = cupsAddOption(name, value,
printer->num_options,
&(printer->options));
@@ -12110,7 +11041,8 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
http_status_t status; /* Policy status */
ipp_attribute_t *attr, /* Current attribute */
*auth_info; /* auth-info attribute */
- ipp_attribute_t *format; /* Document-format attribute */
+ ipp_attribute_t *format, /* Document-format attribute */
+ *name; /* Job-name attribute */
cups_ptype_t dtype; /* Destination type (printer/class) */
char super[MIME_MAX_SUPER],
/* Supertype of file */
@@ -12137,7 +11069,7 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
)
{
send_ipp_status(con, IPP_ATTRIBUTES,
- _("Unsupported compression \"%s\"."),
+ _("Unsupported 'compression' value \"%s\"."),
attr->values[0].string.text);
ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
"compression", NULL, attr->values[0].string.text);
@@ -12152,10 +11084,11 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
if ((format = ippFindAttribute(con->request, "document-format",
IPP_TAG_MIMETYPE)) != NULL)
{
- if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]",
+ if (sscanf(format->values[0].string.text, "%15[^/]/%255[^;]",
super, type) != 2)
{
- send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"."),
+ send_ipp_status(con, IPP_BAD_REQUEST,
+ _("Bad 'document-format' value \"%s\"."),
format->values[0].string.text);
return;
}
@@ -12166,7 +11099,7 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_INFO,
"Hint: Do you have the raw file printing rules enabled?");
send_ipp_status(con, IPP_DOCUMENT_FORMAT,
- _("Unsupported document-format \"%s\"."),
+ _("Unsupported 'document-format' value \"%s\"."),
format->values[0].string.text);
ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
"document-format", NULL, format->values[0].string.text);
@@ -12175,6 +11108,86 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
}
/*
+ * Is the job-name valid?
+ */
+
+ if ((name = ippFindAttribute(con->request, "job-name", IPP_TAG_ZERO)) != NULL)
+ {
+ int bad_name = 0; /* Is the job-name value bad? */
+
+ if ((name->value_tag != IPP_TAG_NAME && name->value_tag != IPP_TAG_NAMELANG) ||
+ name->num_values != 1)
+ {
+ bad_name = 1;
+ }
+ else
+ {
+ /*
+ * Validate that job-name conforms to RFC 5198 (Network Unicode) and
+ * IPP Everywhere requirements for "name" values...
+ */
+
+ const unsigned char *nameptr; /* Pointer into "job-name" attribute */
+
+ for (nameptr = (unsigned char *)name->values[0].string.text;
+ *nameptr;
+ nameptr ++)
+ {
+ if (*nameptr < ' ' && *nameptr != '\t')
+ break;
+ else if (*nameptr == 0x7f)
+ break;
+ else if ((*nameptr & 0xe0) == 0xc0)
+ {
+ if ((nameptr[1] & 0xc0) != 0x80)
+ break;
+
+ nameptr ++;
+ }
+ else if ((*nameptr & 0xf0) == 0xe0)
+ {
+ if ((nameptr[1] & 0xc0) != 0x80 ||
+ (nameptr[2] & 0xc0) != 0x80)
+ break;
+
+ nameptr += 2;
+ }
+ else if ((*nameptr & 0xf8) == 0xf0)
+ {
+ if ((nameptr[1] & 0xc0) != 0x80 ||
+ (nameptr[2] & 0xc0) != 0x80 ||
+ (nameptr[3] & 0xc0) != 0x80)
+ break;
+
+ nameptr += 3;
+ }
+ else if (*nameptr & 0x80)
+ break;
+ }
+
+ if (*nameptr)
+ bad_name = 1;
+ }
+
+ if (bad_name)
+ {
+ if (StrictConformance)
+ {
+ send_ipp_status(con, IPP_ATTRIBUTES,
+ _("Unsupported 'job-name' value."));
+ ippCopyAttribute(con->response, name, 0);
+ return;
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "Unsupported 'job-name' value, deleting from request.");
+ ippDeleteAttribute(con->request, name);
+ }
+ }
+ }
+
+ /*
* Is the destination valid?
*/
@@ -12299,5 +11312,5 @@ validate_user(cupsd_job_t *job, /* I - Job */
/*
- * End of "$Id: ipp.c 10274 2012-02-13 20:42:51Z mike $".
+ * End of "$Id: ipp.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/job.c b/scheduler/job.c
index 92e1955..d8f56b5 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -1,5 +1,5 @@
/*
- * "$Id: job.c 10420 2012-04-20 03:01:06Z mike $"
+ * "$Id: job.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Job management routines for the CUPS scheduler.
*
@@ -14,54 +14,58 @@
*
* Contents:
*
- * cupsdAddJob() - Add a new job to the job queue.
- * cupsdCancelJobs() - Cancel all jobs for the given
- * destination/user.
- * cupsdCheckJobs() - Check the pending jobs and start any if the
- * destination is available.
- * cupsdCleanJobs() - Clean out old jobs.
- * cupsdContinueJob() - Continue printing with the next file in a job.
- * cupsdDeleteJob() - Free all memory used by a job.
- * cupsdFreeAllJobs() - Free all jobs from memory.
- * cupsdFindJob() - Find the specified job.
- * cupsdGetPrinterJobCount() - Get the number of pending, processing, or held
- * jobs in a printer or class.
- * cupsdGetUserJobCount() - Get the number of pending, processing, or held
- * jobs for a user.
- * cupsdLoadAllJobs() - Load all jobs from disk.
- * cupsdLoadJob() - Load a single job.
- * cupsdMoveJob() - Move the specified job to a different
- * destination.
- * cupsdReleaseJob() - Release the specified job.
- * cupsdRestartJob() - Restart the specified job.
- * cupsdSaveAllJobs() - Save a summary of all jobs to disk.
- * cupsdSaveJob() - Save a job to disk.
- * cupsdSetJobHoldUntil() - Set the hold time for a job.
- * cupsdSetJobPriority() - Set the priority of a job, moving it up/down
- * in the list as needed.
- * cupsdSetJobState() - Set the state of the specified print job.
- * cupsdStopAllJobs() - Stop all print jobs.
+ * cupsdAddJob() - Add a new job to the job queue.
+ * cupsdCancelJobs() - Cancel all jobs for the given
+ * destination/user.
+ * cupsdCheckJobs() - Check the pending jobs and start any if the
+ * destination is available.
+ * cupsdCleanJobs() - Clean out old jobs.
+ * cupsdContinueJob() - Continue printing with the next file in a
+ * job.
+ * cupsdDeleteJob() - Free all memory used by a job.
+ * cupsdFreeAllJobs() - Free all jobs from memory.
+ * cupsdFindJob() - Find the specified job.
+ * cupsdGetPrinterJobCount() - Get the number of pending, processing, or
+ * held jobs in a printer or class.
+ * cupsdGetUserJobCount() - Get the number of pending, processing, or
+ * held jobs for a user.
+ * cupsdLoadAllJobs() - Load all jobs from disk.
+ * cupsdLoadJob() - Load a single job.
+ * cupsdMoveJob() - Move the specified job to a different
+ * destination.
+ * cupsdReleaseJob() - Release the specified job.
+ * cupsdRestartJob() - Restart the specified job.
+ * cupsdSaveAllJobs() - Save a summary of all jobs to disk.
+ * cupsdSaveJob() - Save a job to disk.
+ * cupsdSetJobHoldUntil() - Set the hold time for a job.
+ * cupsdSetJobPriority() - Set the priority of a job, moving it up/down
+ * in the list as needed.
+ * cupsdSetJobState() - Set the state of the specified print job.
+ * cupsdStopAllJobs() - Stop all print jobs.
* cupsdUnloadCompletedJobs() - Flush completed job history from memory.
- * compare_active_jobs() - Compare the job IDs and priorities of two
- * jobs.
- * compare_jobs() - Compare the job IDs of two jobs.
- * dump_job_history() - Dump any debug messages for a job.
- * free_job_history() - Free any log history.
- * finalize_job() - Cleanup after job filter processes and support
- * data.
- * get_options() - Get a string containing the job options.
- * ipp_length() - Compute the size of the buffer needed to hold
- * the textual IPP attributes.
- * load_job_cache() - Load jobs from the job.cache file.
- * load_next_job_id() - Load the NextJobId value from the job.cache
- * file.
- * load_request_root() - Load jobs from the RequestRoot directory.
- * set_time() - Set one of the "time-at-xyz" attributes.
- * start_job() - Start a print job.
- * stop_job() - Stop a print job.
- * unload_job() - Unload a job from memory.
- * update_job() - Read a status update from a job's filters.
- * update_job_attrs() - Update the job-printer-* attributes.
+ * cupsdUpdateJobs() - Update the history/file files for all jobs.
+ * compare_active_jobs() - Compare the job IDs and priorities of two
+ * jobs.
+ * compare_jobs() - Compare the job IDs of two jobs.
+ * dump_job_history() - Dump any debug messages for a job.
+ * free_job_history() - Free any log history.
+ * finalize_job() - Cleanup after job filter processes and
+ * support data.
+ * get_options() - Get a string containing the job options.
+ * ipp_length() - Compute the size of the buffer needed to hold
+ * the textual IPP attributes.
+ * load_job_cache() - Load jobs from the job.cache file.
+ * load_next_job_id() - Load the NextJobId value from the job.cache
+ * file.
+ * load_request_root() - Load jobs from the RequestRoot directory.
+ * remove_job_files() - Remove the document files for a job.
+ * remove_job_history() - Remove the control file for a job.
+ * set_time() - Set one of the "time-at-xyz" attributes.
+ * start_job() - Start a print job.
+ * stop_job() - Stop a print job.
+ * unload_job() - Unload a job from memory.
+ * update_job() - Read a status update from a job's filters.
+ * update_job_attrs() - Update the job-printer-* attributes.
*/
/*
@@ -181,6 +185,8 @@ static size_t ipp_length(ipp_t *ipp);
static void load_job_cache(const char *filename);
static void load_next_job_id(const char *filename);
static void load_request_root(void);
+static void remove_job_files(cupsd_job_t *job);
+static void remove_job_history(cupsd_job_t *job);
static void set_time(cupsd_job_t *job, const char *name);
static void start_job(cupsd_job_t *job, cupsd_printer_t *printer);
static void stop_job(cupsd_job_t *job, cupsd_jobaction_t action);
@@ -281,23 +287,32 @@ cupsdCheckJobs(void)
time_t curtime; /* Current time */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdCheckJobs: %d active jobs, sleeping=%d, reload=%d",
- cupsArrayCount(ActiveJobs), Sleeping, NeedReload);
-
curtime = time(NULL);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "cupsdCheckJobs: %d active jobs, sleeping=%d, reload=%d, "
+ "curtime=%ld", cupsArrayCount(ActiveJobs), Sleeping,
+ NeedReload, (long)curtime);
+
for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
job;
job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
{
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "cupsdCheckJobs: Job %d - dest=\"%s\", printer=%p, "
+ "state=%d, cancel_time=%ld, hold_until=%ld, kill_time=%ld, "
+ "pending_cost=%d, pending_timeout=%ld", job->id, job->dest,
+ job->printer, job->state_value, (long)job->cancel_time,
+ (long)job->hold_until, (long)job->kill_time,
+ job->pending_cost, (long)job->pending_timeout);
+
/*
* Kill jobs if they are unresponsive...
*/
if (job->kill_time && job->kill_time <= curtime)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Stopping unresponsive job!",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Stopping unresponsive job.",
job->id);
stop_job(job, CUPSD_JOB_FORCE);
@@ -305,6 +320,17 @@ cupsdCheckJobs(void)
}
/*
+ * Cancel stuck jobs...
+ */
+
+ if (job->cancel_time && job->cancel_time <= curtime)
+ {
+ cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_DEFAULT,
+ "Canceling stuck job after %d seconds.", MaxJobTime);
+ continue;
+ }
+
+ /*
* Start held jobs if they are ready...
*/
@@ -322,7 +348,6 @@ cupsdCheckJobs(void)
cupsd_client_t *con; /* Current client connection */
-
for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
con;
con = (cupsd_client_t *)cupsArrayNext(Clients))
@@ -362,8 +387,7 @@ cupsdCheckJobs(void)
printer = cupsdFindDest(job->dest);
pclass = NULL;
- while (printer &&
- (printer->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS)))
+ while (printer && (printer->type & CUPS_PRINTER_CLASS))
{
/*
* If the class is remote, just pass it to the remote server...
@@ -415,10 +439,7 @@ cupsdCheckJobs(void)
cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
- if ((!(printer->type & CUPS_PRINTER_DISCOVERED) && /* Printer is local */
- printer->state == IPP_PRINTER_IDLE) || /* and idle, OR */
- ((printer->type & CUPS_PRINTER_DISCOVERED) && /* Printer is remote */
- !printer->job)) /* and not printing */
+ if (!printer->job && printer->state == IPP_PRINTER_IDLE)
{
/*
* Start the job...
@@ -440,16 +461,56 @@ void
cupsdCleanJobs(void)
{
cupsd_job_t *job; /* Current job */
+ time_t curtime; /* Current time */
- if (MaxJobs <= 0 && JobHistory)
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "cupsdCleanJobs: MaxJobs=%d, JobHistory=%d, JobFiles=%d",
+ MaxJobs, JobHistory, JobFiles);
+
+ if (MaxJobs <= 0 && JobHistory == INT_MAX && JobFiles == INT_MAX)
return;
+ curtime = time(NULL);
+ JobHistoryUpdate = 0;
+
for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
- job && (cupsArrayCount(Jobs) >= MaxJobs || !JobHistory);
+ job;
job = (cupsd_job_t *)cupsArrayNext(Jobs))
+ {
if (job->state_value >= IPP_JOB_CANCELED && !job->printer)
- cupsdDeleteJob(job, CUPSD_JOB_PURGE);
+ {
+ /*
+ * Expire old jobs (or job files)...
+ */
+
+ if ((MaxJobs > 0 && cupsArrayCount(Jobs) >= MaxJobs) ||
+ (job->history_time && job->history_time <= curtime))
+ {
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing from history.");
+ cupsdDeleteJob(job, CUPSD_JOB_PURGE);
+ }
+ else if (job->file_time && job->file_time <= curtime)
+ {
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing document files.");
+ remove_job_files(job);
+
+ if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
+ JobHistoryUpdate = job->history_time;
+ }
+ else
+ {
+ if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
+ JobHistoryUpdate = job->history_time;
+
+ if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate)
+ JobHistoryUpdate = job->file_time;
+ }
+ }
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCleanJobs: JobHistoryUpdate=%ld",
+ (long)JobHistoryUpdate);
}
@@ -499,7 +560,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
/* CONTENT_TYPE env variable */
device_uri[1024],
/* DEVICE_URI env variable */
- final_content_type[1024],
+ final_content_type[1024] = "",
/* FINAL_CONTENT_TYPE env variable */
lang[255], /* LANG env variable */
#ifdef __APPLE__
@@ -565,16 +626,55 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
if (!filters)
{
cupsdLogJob(job, CUPSD_LOG_ERROR,
- "Unable to convert file %d to printable format!",
+ "Unable to convert file %d to printable format.",
job->current_file);
abort_message = "Aborting job because it cannot be printed.";
abort_state = IPP_JOB_ABORTED;
+ ippSetString(job->attrs, &job->reasons, 0, "document-unprintable-error");
goto abort_job;
}
/*
+ * Figure out the final content type...
+ */
+
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "%d filters for job:",
+ cupsArrayCount(filters));
+ for (filter = (mime_filter_t *)cupsArrayFirst(filters);
+ filter;
+ filter = (mime_filter_t *)cupsArrayNext(filters))
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "%s (%s/%s to %s/%s, cost %d)",
+ filter->filter,
+ filter->src ? filter->src->super : "???",
+ filter->src ? filter->src->type : "???",
+ filter->dst ? filter->dst->super : "???",
+ filter->dst ? filter->dst->type : "???",
+ filter->cost);
+
+ if (!job->printer->remote)
+ {
+ for (filter = (mime_filter_t *)cupsArrayLast(filters);
+ filter && filter->dst;
+ filter = (mime_filter_t *)cupsArrayPrev(filters))
+ if (strcmp(filter->dst->super, "printer") ||
+ strcmp(filter->dst->type, job->printer->name))
+ break;
+
+ if (filter && filter->dst)
+ {
+ if ((ptr = strchr(filter->dst->type, '/')) != NULL)
+ snprintf(final_content_type, sizeof(final_content_type),
+ "FINAL_CONTENT_TYPE=%s", ptr + 1);
+ else
+ snprintf(final_content_type, sizeof(final_content_type),
+ "FINAL_CONTENT_TYPE=%s/%s", filter->dst->super,
+ filter->dst->type);
+ }
+ }
+
+ /*
* Remove NULL ("-") filters...
*/
@@ -719,12 +819,14 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
if (cupsArrayCount(filters) > MAX_FILTERS)
{
cupsdLogJob(job, CUPSD_LOG_DEBUG,
- "Too many filters (%d > %d), unable to print!",
+ "Too many filters (%d > %d), unable to print.",
cupsArrayCount(filters), MAX_FILTERS);
abort_message = "Aborting job because it needs too many filters to print.";
abort_state = IPP_JOB_ABORTED;
+ ippSetString(job->attrs, &job->reasons, 0, "document-unprintable-error");
+
goto abort_job;
}
@@ -738,7 +840,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
if ((job->job_sheets =
ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL)
cupsdLogJob(job, CUPSD_LOG_DEBUG,
- "... but someone added one without setting job_sheets!");
+ "... but someone added one without setting job_sheets.");
}
else if (job->job_sheets->num_values == 1)
cupsdLogJob(job, CUPSD_LOG_DEBUG, "job-sheets=%s",
@@ -748,7 +850,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
job->job_sheets->values[0].string.text,
job->job_sheets->values[1].string.text);
- if (job->printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))
+ if (job->printer->type & CUPS_PRINTER_REMOTE)
banner_page = 0;
else if (job->job_sheets == NULL)
banner_page = 0;
@@ -969,25 +1071,8 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
envp[envc ++] = banner_page ? "CUPS_FILETYPE=job-sheet" :
"CUPS_FILETYPE=document";
- if (!job->printer->remote && !job->printer->raw)
- {
- filter = (mime_filter_t *)cupsArrayLast(filters);
-
- if (job->printer->port_monitor)
- filter = (mime_filter_t *)cupsArrayPrev(filters);
-
- if (filter && filter->dst)
- {
- if ((ptr = strchr(filter->dst->type, '/')) != NULL)
- snprintf(final_content_type, sizeof(final_content_type),
- "FINAL_CONTENT_TYPE=%s", ptr + 1);
- else
- snprintf(final_content_type, sizeof(final_content_type),
- "FINAL_CONTENT_TYPE=%s/%s", filter->dst->super,
- filter->dst->type);
- envp[envc ++] = final_content_type;
- }
- }
+ if (final_content_type[0])
+ envp[envc ++] = final_content_type;
if (Classification && !banner_page)
{
@@ -1006,7 +1091,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
envp[envc ++] = classification;
}
- if (job->dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ if (job->dtype & CUPS_PRINTER_CLASS)
{
snprintf(class_name, sizeof(class_name), "CLASS=%s", job->dest);
envp[envc ++] = class_name;
@@ -1317,25 +1402,13 @@ cupsdDeleteJob(cupsd_job_t *job, /* I - Job */
cupsd_jobaction_t action)/* I - Action */
{
int i; /* Looping var */
- char filename[1024]; /* Job filename */
if (job->printer)
finalize_job(job, 1);
if (action == CUPSD_JOB_PURGE)
- {
- /*
- * Remove the job info file...
- */
-
- snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot,
- job->id);
- if (Classification)
- cupsdRemoveFile(filename);
- else
- unlink(filename);
- }
+ remove_job_history(job);
cupsdClearString(&job->username);
cupsdClearString(&job->dest);
@@ -1345,27 +1418,14 @@ cupsdDeleteJob(cupsd_job_t *job, /* I - Job */
cupsdClearString(job->auth_env + i);
cupsdClearString(&job->auth_uid);
- if (job->num_files > 0)
+ if (action == CUPSD_JOB_PURGE)
+ remove_job_files(job);
+ else if (job->num_files > 0)
{
free(job->compressions);
free(job->filetypes);
- if (action == CUPSD_JOB_PURGE)
- {
- while (job->num_files > 0)
- {
- snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
- job->id, job->num_files);
- if (Classification)
- cupsdRemoveFile(filename);
- else
- unlink(filename);
-
- job->num_files --;
- }
- }
- else
- job->num_files = 0;
+ job->num_files = 0;
}
if (job->history)
@@ -1572,7 +1632,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
if ((job->attrs = ippNew()) == NULL)
{
- cupsdLogJob(job, CUPSD_LOG_ERROR, "Ran out of memory for job attributes!");
+ cupsdLogJob(job, CUPSD_LOG_ERROR, "Ran out of memory for job attributes.");
return (0);
}
@@ -1583,22 +1643,8 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Loading attributes...", job->id);
snprintf(jobfile, sizeof(jobfile), "%s/c%05d", RequestRoot, job->id);
- if ((fp = cupsFileOpen(jobfile, "r")) == NULL)
- {
- char newfile[1024]; /* New job filename */
-
- snprintf(newfile, sizeof(newfile), "%s/c%05d.N", RequestRoot, job->id);
- if ((fp = cupsFileOpen(newfile, "r")) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to open job control file \"%s\": %s",
- job->id, jobfile, strerror(errno));
- goto error;
- }
-
- unlink(jobfile);
- rename(newfile, jobfile);
- }
+ if ((fp = cupsdOpenConfFile(jobfile)) == NULL)
+ goto error;
if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, job->attrs) != IPP_DATA)
{
@@ -1619,7 +1665,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Missing or bad time-at-creation attribute in "
- "control file!", job->id);
+ "control file.", job->id);
goto error;
}
@@ -1628,11 +1674,40 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Missing or bad job-state attribute in control "
- "file!", job->id);
+ "file.", job->id);
goto error;
}
- job->state_value = (ipp_jstate_t)job->state->values[0].integer;
+ job->state_value = (ipp_jstate_t)job->state->values[0].integer;
+ job->file_time = 0;
+ job->history_time = 0;
+
+ if (job->state_value >= IPP_JOB_CANCELED &&
+ (attr = ippFindAttribute(job->attrs, "time-at-completed",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ if (JobHistory < INT_MAX)
+ job->history_time = attr->values[0].integer + JobHistory;
+ else
+ job->history_time = INT_MAX;
+
+ if (job->history_time < time(NULL))
+ goto error; /* Expired, remove from history */
+
+ if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
+ JobHistoryUpdate = job->history_time;
+
+ if (JobFiles < INT_MAX)
+ job->file_time = attr->values[0].integer + JobFiles;
+ else
+ job->file_time = INT_MAX;
+
+ if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate)
+ JobHistoryUpdate = job->file_time;
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdLoadJob: JobHistoryUpdate=%ld",
+ (long)JobHistoryUpdate);
+ }
if (!job->dest)
{
@@ -1640,7 +1715,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
IPP_TAG_URI)) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] No job-printer-uri attribute in control file!",
+ "[Job %d] No job-printer-uri attribute in control file.",
job->id);
goto error;
}
@@ -1649,7 +1724,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
&destptr)) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to queue job for destination \"%s\"!",
+ "[Job %d] Unable to queue job for destination \"%s\".",
job->id, attr->values[0].string.text);
goto error;
}
@@ -1659,11 +1734,74 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
else if ((destptr = cupsdFindDest(job->dest)) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to queue job for destination \"%s\"!",
+ "[Job %d] Unable to queue job for destination \"%s\".",
job->id, job->dest);
goto error;
}
+ if ((job->reasons = ippFindAttribute(job->attrs, "job-state-reasons",
+ IPP_TAG_KEYWORD)) == NULL)
+ {
+ const char *reason; /* job-state-reason keyword */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "[Job %d] Adding missing job-state-reasons attribute to "
+ " control file.", job->id);
+
+ switch (job->state_value)
+ {
+ default :
+ case IPP_JOB_PENDING :
+ if (destptr->state == IPP_PRINTER_STOPPED)
+ reason = "printer-stopped";
+ else
+ reason = "none";
+ break;
+
+ case IPP_JOB_HELD :
+ if ((attr = ippFindAttribute(job->attrs, "job-hold-until",
+ IPP_TAG_ZERO)) != NULL &&
+ (attr->value_tag == IPP_TAG_NAME ||
+ attr->value_tag == IPP_TAG_NAMELANG ||
+ attr->value_tag == IPP_TAG_KEYWORD) &&
+ strcmp(attr->values[0].string.text, "no-hold"))
+ reason = "job-hold-until-specified";
+ else
+ reason = "job-incoming";
+ break;
+
+ case IPP_JOB_PROCESSING :
+ reason = "job-printing";
+ break;
+
+ case IPP_JOB_STOPPED :
+ reason = "job-stopped";
+ break;
+
+ case IPP_JOB_CANCELED :
+ reason = "job-canceled-by-user";
+ break;
+
+ case IPP_JOB_ABORTED :
+ reason = "aborted-by-system";
+ break;
+
+ case IPP_JOB_COMPLETED :
+ reason = "job-completed-successfully";
+ break;
+ }
+
+ job->reasons = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
+ "job-state-reasons", NULL, reason);
+ }
+ else if (job->state_value == IPP_JOB_PENDING)
+ {
+ if (destptr->state == IPP_PRINTER_STOPPED)
+ ippSetString(job->attrs, &job->reasons, 0, "printer-stopped");
+ else
+ ippSetString(job->attrs, &job->reasons, 0, "none");
+ }
+
job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed",
IPP_TAG_INTEGER);
job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
@@ -1675,7 +1813,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Missing or bad job-priority attribute in "
- "control file!", job->id);
+ "control file.", job->id);
goto error;
}
@@ -1689,7 +1827,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Missing or bad job-originating-user-name "
- "attribute in control file!", job->id);
+ "attribute in control file.", job->id);
goto error;
}
@@ -1757,7 +1895,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
if (!compressions || !filetypes)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Ran out of memory for job file types!",
+ "[Job %d] Ran out of memory for job file types.",
job->id);
ippDelete(job->attrs);
@@ -1823,7 +1961,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
if (cupsFileGets(fp, line, sizeof(line)) &&
- !strcmp(line, "CUPSD-AUTH-V2"))
+ !strcmp(line, "CUPSD-AUTH-V3"))
{
i = 0;
while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
@@ -1832,8 +1970,11 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
* Decode value...
*/
- bytes = sizeof(data);
- httpDecode64_2(data, &bytes, value);
+ if (strcmp(line, "negotiate") && strcmp(line, "uid"))
+ {
+ bytes = sizeof(data);
+ httpDecode64_2(data, &bytes, value);
+ }
/*
* Assign environment variables...
@@ -1846,7 +1987,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
}
else if (i >= (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0])))
break;
-
+
if (!strcmp(line, "username"))
cupsdSetStringf(job->auth_env + i, "AUTH_USERNAME=%s", data);
else if (!strcmp(line, "domain"))
@@ -1854,7 +1995,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
else if (!strcmp(line, "password"))
cupsdSetStringf(job->auth_env + i, "AUTH_PASSWORD=%s", data);
else if (!strcmp(line, "negotiate"))
- cupsdSetStringf(job->auth_env + i, "AUTH_NEGOTIATE=%s", data);
+ cupsdSetStringf(job->auth_env + i, "AUTH_NEGOTIATE=%s", value);
else
continue;
@@ -1878,24 +2019,8 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
ippDelete(job->attrs);
job->attrs = NULL;
- if (job->compressions)
- {
- free(job->compressions);
- job->compressions = NULL;
- }
-
- if (job->filetypes)
- {
- free(job->filetypes);
- job->filetypes = NULL;
- }
-
- job->num_files = 0;
-
- if (Classification)
- cupsdRemoveFile(jobfile);
- else
- unlink(jobfile);
+ remove_job_history(job);
+ remove_job_files(job);
return (0);
}
@@ -1945,8 +2070,7 @@ cupsdMoveJob(cupsd_job_t *job, /* I - Job */
p->name);
cupsdSetString(&job->dest, p->name);
- job->dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE |
- CUPS_PRINTER_IMPLICIT);
+ job->dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
if ((attr = ippFindAttribute(job->attrs, "job-printer-uri",
IPP_TAG_URI)) != NULL)
@@ -2069,8 +2193,7 @@ cupsdSaveAllJobs(void)
void
cupsdSaveJob(cupsd_job_t *job) /* I - Job */
{
- char filename[1024], /* Job control filename */
- newfile[1024]; /* New job control filename */
+ char filename[1024]; /* Job control filename */
cups_file_t *fp; /* Job file */
@@ -2078,17 +2201,10 @@ cupsdSaveJob(cupsd_job_t *job) /* I - Job */
job, job->id, job->attrs);
snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id);
- snprintf(newfile, sizeof(newfile), "%s/c%05d.N", RequestRoot, job->id);
- if ((fp = cupsFileOpen(newfile, "w")) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to create job control file \"%s\": %s",
- job->id, newfile, strerror(errno));
+ if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm & 0600)) == NULL)
return;
- }
- fchmod(cupsFileNumber(fp), 0600);
fchown(cupsFileNumber(fp), RunUser, Group);
job->attrs->state = IPP_IDLE;
@@ -2099,23 +2215,19 @@ cupsdSaveJob(cupsd_job_t *job) /* I - Job */
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Unable to write job control file.", job->id);
cupsFileClose(fp);
- unlink(newfile);
return;
}
- if (cupsFileClose(fp))
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to close job control file: %s",
- job->id, strerror(errno));
- else
+ if (!cupsdCloseCreatedConfFile(fp, filename))
{
+ /*
+ * Remove backup file and mark this job as clean...
+ */
+
+ strlcat(filename, ".O", sizeof(filename));
unlink(filename);
- if (rename(newfile, filename))
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to finalize job control file: %s",
- job->id, strerror(errno));
- else
- job->dirty = 0;
+
+ job->dirty = 0;
}
}
@@ -2168,12 +2280,16 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */
job->dirty = 1;
cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
+
+ ippSetString(job->attrs, &job->reasons, 0, "job-hold-until-specified");
}
/*
* Update the hold time...
*/
+ job->cancel_time = 0;
+
if (!strcmp(when, "indefinite") || !strcmp(when, "auth-info-required"))
{
/*
@@ -2181,6 +2297,9 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */
*/
job->hold_until = 0;
+
+ if (MaxHoldTime > 0)
+ job->cancel_time = time(NULL) + MaxHoldTime;
}
else if (!strcmp(when, "day-time"))
{
@@ -2382,8 +2501,10 @@ cupsdSetJobState(
* Set the new job state...
*/
- job->state->values[0].integer = newstate;
- job->state_value = newstate;
+ job->state_value = newstate;
+
+ if (job->state)
+ job->state->values[0].integer = newstate;
switch (newstate)
{
@@ -2409,6 +2530,7 @@ cupsdSetJobState(
case IPP_JOB_CANCELED :
case IPP_JOB_COMPLETED :
set_time(job, "time-at-completed");
+ ippSetString(job->attrs, &job->reasons, 0, "processing-to-stop-point");
break;
}
@@ -2537,27 +2659,7 @@ cupsdSetJobState(
*/
if (!JobHistory || !JobFiles || action == CUPSD_JOB_PURGE)
- {
- for (i = 1; i <= job->num_files; i ++)
- {
- snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
- job->id, i);
- if (Classification)
- cupsdRemoveFile(filename);
- else
- unlink(filename);
- }
-
- if (job->num_files > 0)
- {
- free(job->filetypes);
- free(job->compressions);
-
- job->num_files = 0;
- job->filetypes = NULL;
- job->compressions = NULL;
- }
- }
+ remove_job_files(job);
if (JobHistory && action != CUPSD_JOB_PURGE)
{
@@ -2649,6 +2751,62 @@ cupsdUnloadCompletedJobs(void)
/*
+ * 'cupsdUpdateJobs()' - Update the history/file files for all jobs.
+ */
+
+void
+cupsdUpdateJobs(void)
+{
+ cupsd_job_t *job; /* Current job */
+ time_t curtime; /* Current time */
+ ipp_attribute_t *attr; /* time-at-completed attribute */
+
+
+ curtime = time(NULL);
+ JobHistoryUpdate = 0;
+
+ for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
+ job;
+ job = (cupsd_job_t *)cupsArrayNext(Jobs))
+ {
+ if (job->state_value >= IPP_JOB_CANCELED &&
+ (attr = ippFindAttribute(job->attrs, "time-at-completed",
+ IPP_TAG_INTEGER)) != NULL)
+ {
+ /*
+ * Update history/file expiration times...
+ */
+
+ if (JobHistory < INT_MAX)
+ job->history_time = attr->values[0].integer + JobHistory;
+ else
+ job->history_time = INT_MAX;
+
+ if (job->history_time < curtime)
+ {
+ cupsdDeleteJob(job, CUPSD_JOB_PURGE);
+ continue;
+ }
+
+ if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
+ JobHistoryUpdate = job->history_time;
+
+ if (JobFiles < INT_MAX)
+ job->file_time = attr->values[0].integer + JobFiles;
+ else
+ job->file_time = INT_MAX;
+
+ if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate)
+ JobHistoryUpdate = job->file_time;
+ }
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdUpdateAllJobs: JobHistoryUpdate=%ld",
+ (long)JobHistoryUpdate);
+}
+
+
+/*
* 'compare_active_jobs()' - Compare the job IDs and priorities of two jobs.
*/
@@ -2854,7 +3012,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */
* rarely have current information for network devices...
*/
- if (strncmp(job->printer->device_uri, "usb:", 4))
+ if (strncmp(job->printer->device_uri, "usb:", 4) &&
+ strncmp(job->printer->device_uri, "ippusb:", 7))
cupsdSetPrinterReasons(job->printer, "-offline-report");
/*
@@ -2865,10 +3024,11 @@ finalize_job(cupsd_job_t *job, /* I - Job */
job->profile = NULL;
/*
- * Clear the unresponsive job watchdog timer...
+ * Clear the unresponsive job watchdog timers...
*/
- job->kill_time = 0;
+ job->cancel_time = 0;
+ job->kill_time = 0;
/*
* Close pipes and status buffer...
@@ -2907,14 +3067,21 @@ finalize_job(cupsd_job_t *job, /* I - Job */
case IPP_JOB_COMPLETED :
job_state = IPP_JOB_COMPLETED;
message = "Job completed.";
+
+ ippSetString(job->attrs, &job->reasons, 0,
+ "job-completed-successfully");
break;
case IPP_JOB_STOPPED :
message = "Job stopped.";
+
+ ippSetString(job->attrs, &job->reasons, 0, "job-stopped");
break;
case IPP_JOB_CANCELED :
message = "Job canceled.";
+
+ ippSetString(job->attrs, &job->reasons, 0, "job-canceled-by-user");
break;
case IPP_JOB_ABORTED :
@@ -2940,7 +3107,10 @@ finalize_job(cupsd_job_t *job, /* I - Job */
if (WIFEXITED(exit_code))
exit_code = WEXITSTATUS(exit_code);
else
+ {
+ ippSetString(job->attrs, &job->reasons, 0, "cups-backend-crashed");
exit_code = job->status;
+ }
cupsdLogJob(job, CUPSD_LOG_INFO, "Backend returned status %d (%s)",
exit_code,
@@ -2950,6 +3120,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */
exit_code == CUPS_BACKEND_HOLD ? "hold job" :
exit_code == CUPS_BACKEND_STOP ? "stop printer" :
exit_code == CUPS_BACKEND_CANCEL ? "cancel job" :
+ exit_code == CUPS_BACKEND_RETRY ? "retry job later" :
+ exit_code == CUPS_BACKEND_RETRY_CURRENT ? "retry job immediately" :
exit_code < 0 ? "crashed" : "unknown");
/*
@@ -2965,7 +3137,7 @@ finalize_job(cupsd_job_t *job, /* I - Job */
* act...
*/
- if (job->dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ if (job->dtype & CUPS_PRINTER_CLASS)
{
/*
* Queued on a class - mark the job as pending and we'll retry on
@@ -2976,6 +3148,9 @@ finalize_job(cupsd_job_t *job, /* I - Job */
{
job_state = IPP_JOB_PENDING;
message = "Retrying job on another printer.";
+
+ ippSetString(job->attrs, &job->reasons, 0,
+ "resources-are-not-ready");
}
}
else if (!strcmp(job->printer->error_policy, "retry-current-job"))
@@ -2989,6 +3164,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */
{
job_state = IPP_JOB_PENDING;
message = "Retrying job on same printer.";
+
+ ippSetString(job->attrs, &job->reasons, 0, "none");
}
}
else if ((job->printer->type & CUPS_PRINTER_FAX) ||
@@ -3015,6 +3192,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */
JobRetryLimit);
job_state = IPP_JOB_ABORTED;
message = buffer;
+
+ ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system");
}
else
{
@@ -3029,6 +3208,9 @@ finalize_job(cupsd_job_t *job, /* I - Job */
job->hold_until = time(NULL) + JobRetryInterval;
job_state = IPP_JOB_HELD;
message = buffer;
+
+ ippSetString(job->attrs, &job->reasons, 0,
+ "resources-are-not-ready");
}
}
}
@@ -3038,6 +3220,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */
job_state = IPP_JOB_ABORTED;
message = "Job aborted due to backend errors; please consult "
"the error_log file for details.";
+
+ ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system");
}
else if (job->state_value == IPP_JOB_PROCESSING)
{
@@ -3045,19 +3229,22 @@ finalize_job(cupsd_job_t *job, /* I - Job */
printer_state = IPP_PRINTER_STOPPED;
message = "Printer stopped due to backend errors; please "
"consult the error_log file for details.";
+
+ ippSetString(job->attrs, &job->reasons, 0, "none");
}
break;
case CUPS_BACKEND_CANCEL :
/*
- * Abort the job...
+ * Cancel the job...
*/
if (job_state == IPP_JOB_COMPLETED)
{
- job_state = IPP_JOB_ABORTED;
- message = "Job aborted due to backend errors; please consult "
- "the error_log file for details.";
+ job_state = IPP_JOB_CANCELED;
+ message = "Job canceled at printer.";
+
+ ippSetString(job->attrs, &job->reasons, 0, "canceled-at-device");
}
break;
@@ -3069,6 +3256,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */
*/
cupsdSetJobHoldUntil(job, "indefinite", 1);
+ ippSetString(job->attrs, &job->reasons, 0,
+ "job-hold-until-specified");
job_state = IPP_JOB_HELD;
message = "Job held indefinitely due to backend errors; please "
@@ -3086,7 +3275,12 @@ finalize_job(cupsd_job_t *job, /* I - Job */
"consult the error_log file for details.";
if (job_state == IPP_JOB_COMPLETED)
+ {
job_state = IPP_JOB_PENDING;
+
+ ippSetString(job->attrs, &job->reasons, 0,
+ "resources-are-not-ready");
+ }
break;
case CUPS_BACKEND_AUTH_REQUIRED :
@@ -3100,6 +3294,9 @@ finalize_job(cupsd_job_t *job, /* I - Job */
job_state = IPP_JOB_HELD;
message = "Job held for authentication.";
+
+ ippSetString(job->attrs, &job->reasons, 0,
+ "cups-held-for-authentication");
}
break;
@@ -3124,6 +3321,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */
JobRetryLimit);
job_state = IPP_JOB_ABORTED;
message = buffer;
+
+ ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system");
}
else
{
@@ -3138,6 +3337,9 @@ finalize_job(cupsd_job_t *job, /* I - Job */
job->hold_until = time(NULL) + JobRetryInterval;
job_state = IPP_JOB_HELD;
message = buffer;
+
+ ippSetString(job->attrs, &job->reasons, 0,
+ "resources-are-not-ready");
}
}
break;
@@ -3151,6 +3353,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */
{
job_state = IPP_JOB_PENDING;
message = "Retrying job on same printer.";
+
+ ippSetString(job->attrs, &job->reasons, 0, "none");
}
break;
}
@@ -3166,6 +3370,11 @@ finalize_job(cupsd_job_t *job, /* I - Job */
job_state = IPP_JOB_STOPPED;
message = "Job stopped due to filter errors; please consult the "
"error_log file for details.";
+
+ if (WIFSIGNALED(job->status))
+ ippSetString(job->attrs, &job->reasons, 0, "cups-filter-crashed");
+ else
+ ippSetString(job->attrs, &job->reasons, 0, "job-completed-with-errors");
}
}
@@ -3193,6 +3402,21 @@ finalize_job(cupsd_job_t *job, /* I - Job */
cupsArrayRemove(PrintingJobs, job);
/*
+ * Apply any PPD updates...
+ */
+
+ if (job->num_keywords)
+ {
+ if (cupsdUpdatePrinterPPD(job->printer, job->num_keywords, job->keywords))
+ cupsdSetPrinterAttrs(job->printer);
+
+ cupsFreeOptions(job->num_keywords, job->keywords);
+
+ job->num_keywords = 0;
+ job->keywords = NULL;
+ }
+
+ /*
* Clear the printer <-> job association...
*/
@@ -3409,7 +3633,7 @@ get_options(cupsd_job_t *job, /* I - Job */
if (!optptr)
{
cupsdLogJob(job, CUPSD_LOG_CRIT,
- "Unable to allocate " CUPS_LLFMT " bytes for option buffer!",
+ "Unable to allocate " CUPS_LLFMT " bytes for option buffer.",
CUPS_LLCAST newlength);
return (NULL);
}
@@ -3460,7 +3684,13 @@ get_options(cupsd_job_t *job, /* I - Job */
attr->value_tag == IPP_TAG_BEGIN_COLLECTION) /* Not yet supported */
continue;
- if (!strcmp(attr->name, "job-hold-until"))
+ if (!strcmp(attr->name, "job-hold-until") ||
+ !strcmp(attr->name, "job-id") ||
+ !strcmp(attr->name, "job-k-octets") ||
+ !strcmp(attr->name, "job-media-sheets") ||
+ !strcmp(attr->name, "job-media-sheets-completed") ||
+ !strcmp(attr->name, "job-state") ||
+ !strcmp(attr->name, "job-state-reasons"))
continue;
if (!strncmp(attr->name, "job-", 4) &&
@@ -3537,7 +3767,7 @@ get_options(cupsd_job_t *job, /* I - Job */
"%dx%d%s", attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
break;
case IPP_TAG_STRING :
@@ -3758,14 +3988,14 @@ load_job_cache(const char *filename) /* I - job.cache filename */
{
if (job)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Missing </Job> directive on line %d!",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Missing </Job> directive on line %d.",
linenum);
continue;
}
if (!value)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Missing job ID on line %d!", linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Missing job ID on line %d.", linenum);
continue;
}
@@ -3773,7 +4003,7 @@ load_job_cache(const char *filename) /* I - job.cache filename */
if (jobid < 1)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad job ID %d on line %d!", jobid,
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad job ID %d on line %d.", jobid,
linenum);
continue;
}
@@ -3784,7 +4014,7 @@ load_job_cache(const char *filename) /* I - job.cache filename */
snprintf(jobfile, sizeof(jobfile), "%s/c%05d.N", RequestRoot, jobid);
if (access(jobfile, 0))
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Files have gone away!",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Files have gone away.",
jobid);
continue;
}
@@ -3794,7 +4024,7 @@ load_job_cache(const char *filename) /* I - job.cache filename */
if (!job)
{
cupsdLogMessage(CUPSD_LOG_EMERG,
- "[Job %d] Unable to allocate memory for job!", jobid);
+ "[Job %d] Unable to allocate memory for job.", jobid);
break;
}
@@ -3814,7 +4044,7 @@ load_job_cache(const char *filename) /* I - job.cache filename */
else if (!job)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Missing <Job #> directive on line %d!", linenum);
+ "Missing <Job #> directive on line %d.", linenum);
continue;
}
else if (!_cups_strcasecmp(line, "</Job>"))
@@ -3828,7 +4058,7 @@ load_job_cache(const char *filename) /* I - job.cache filename */
}
else if (!value)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d!", linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d.", linenum);
continue;
}
else if (!_cups_strcasecmp(line, "State"))
@@ -3866,7 +4096,7 @@ load_job_cache(const char *filename) /* I - job.cache filename */
if (job->num_files < 0)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad NumFiles value %d on line %d!",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad NumFiles value %d on line %d.",
job->num_files, linenum);
job->num_files = 0;
continue;
@@ -3878,7 +4108,7 @@ load_job_cache(const char *filename) /* I - job.cache filename */
job->id);
if (access(jobfile, 0))
{
- cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Data files have gone away!",
+ cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Data files have gone away.",
job->id);
job->num_files = 0;
continue;
@@ -3890,7 +4120,7 @@ load_job_cache(const char *filename) /* I - job.cache filename */
if (!job->filetypes || !job->compressions)
{
cupsdLogMessage(CUPSD_LOG_EMERG,
- "[Job %d] Unable to allocate memory for %d files!",
+ "[Job %d] Unable to allocate memory for %d files.",
job->id, job->num_files);
break;
}
@@ -3907,13 +4137,13 @@ load_job_cache(const char *filename) /* I - job.cache filename */
if (sscanf(value, "%d%*[ \t]%15[^/]/%255s%d", &number, super, type,
&compression) != 4)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad File on line %d!", linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad File on line %d.", linenum);
continue;
}
if (number < 1 || number > job->num_files)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad File number %d on line %d!",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad File number %d on line %d.",
number, linenum);
continue;
}
@@ -3930,7 +4160,7 @@ load_job_cache(const char *filename) /* I - job.cache filename */
*/
cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unknown MIME type %s/%s for file %d!",
+ "[Job %d] Unknown MIME type %s/%s for file %d.",
job->id, super, type, number + 1);
snprintf(jobfile, sizeof(jobfile), "%s/d%05d-%03d", RequestRoot,
@@ -3948,7 +4178,7 @@ load_job_cache(const char *filename) /* I - job.cache filename */
}
}
else
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown %s directive on line %d!",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown %s directive on line %d.",
line, linenum);
}
@@ -4048,7 +4278,7 @@ load_request_root(void)
if ((job = calloc(sizeof(cupsd_job_t), 1)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Ran out of memory for jobs!");
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Ran out of memory for jobs.");
cupsDirClose(dir);
return;
}
@@ -4087,6 +4317,8 @@ load_request_root(void)
else
unload_job(job);
}
+ else
+ free(job);
}
cupsDirClose(dir);
@@ -4094,6 +4326,67 @@ load_request_root(void)
/*
+ * 'remove_job_files()' - Remove the document files for a job.
+ */
+
+static void
+remove_job_files(cupsd_job_t *job) /* I - Job */
+{
+ int i; /* Looping var */
+ char filename[1024]; /* Document filename */
+
+
+ if (job->num_files <= 0)
+ return;
+
+ for (i = 1; i <= job->num_files; i ++)
+ {
+ snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
+ job->id, i);
+ if (Classification)
+ cupsdRemoveFile(filename);
+ else
+ unlink(filename);
+ }
+
+ free(job->filetypes);
+ free(job->compressions);
+
+ job->file_time = 0;
+ job->num_files = 0;
+ job->filetypes = NULL;
+ job->compressions = NULL;
+
+ LastEvent |= CUPSD_EVENT_PRINTER_STATE_CHANGED;
+}
+
+
+/*
+ * 'remove_job_history()' - Remove the control file for a job.
+ */
+
+static void
+remove_job_history(cupsd_job_t *job) /* I - Job */
+{
+ char filename[1024]; /* Control filename */
+
+
+ /*
+ * Remove the job info file...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot,
+ job->id);
+ if (Classification)
+ cupsdRemoveFile(filename);
+ else
+ unlink(filename);
+
+ LastEvent |= CUPSD_EVENT_PRINTER_STATE_CHANGED;
+}
+
+
+/*
* 'set_time()' - Set one of the "time-at-xyz" attributes.
*/
@@ -4102,12 +4395,39 @@ set_time(cupsd_job_t *job, /* I - Job to update */
const char *name) /* I - Name of attribute */
{
ipp_attribute_t *attr; /* Time attribute */
+ time_t curtime; /* Current time */
+ curtime = time(NULL);
+
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "%s=%ld", name, (long)curtime);
+
if ((attr = ippFindAttribute(job->attrs, name, IPP_TAG_ZERO)) != NULL)
{
attr->value_tag = IPP_TAG_INTEGER;
- attr->values[0].integer = time(NULL);
+ attr->values[0].integer = curtime;
+ }
+
+ if (!strcmp(name, "time-at-completed"))
+ {
+ if (JobHistory < INT_MAX && attr)
+ job->history_time = attr->values[0].integer + JobHistory;
+ else
+ job->history_time = INT_MAX;
+
+ if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
+ JobHistoryUpdate = job->history_time;
+
+ if (JobFiles < INT_MAX && attr)
+ job->file_time = attr->values[0].integer + JobFiles;
+ else
+ job->file_time = INT_MAX;
+
+ if (job->file_time < JobHistoryUpdate || !JobHistoryUpdate)
+ JobHistoryUpdate = job->file_time;
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_time: JobHistoryUpdate=%ld",
+ (long)JobHistoryUpdate);
}
}
@@ -4129,6 +4449,7 @@ start_job(cupsd_job_t *job, /* I - Job ID */
if (job->num_files == 0)
{
+ ippSetString(job->attrs, &job->reasons, 0, "aborted-by-system");
cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT,
"Aborting job because it has no files.");
return;
@@ -4148,6 +4469,7 @@ start_job(cupsd_job_t *job, /* I - Job ID */
if (job->printer_message)
cupsdSetString(&(job->printer_message->values[0].string.text), "");
+ ippSetString(job->attrs, &job->reasons, 0, "job-printing");
cupsdSetJobState(job, IPP_JOB_PROCESSING, CUPSD_JOB_DEFAULT, NULL);
cupsdSetPrinterState(printer, IPP_PRINTER_PROCESSING, 0);
cupsdSetPrinterReasons(printer, "-cups-remote-pending,"
@@ -4160,10 +4482,17 @@ start_job(cupsd_job_t *job, /* I - Job ID */
job->cost = 0;
job->current_file = 0;
+ job->file_time = 0;
+ job->history_time = 0;
job->progress = 0;
job->printer = printer;
printer->job = job;
+ if (MaxJobTime > 0)
+ job->cancel_time = time(NULL) + MaxJobTime;
+ else
+ job->cancel_time = 0;
+
/*
* Setup the last exit status and security profiles...
*/
@@ -4327,6 +4656,7 @@ unload_job(cupsd_job_t *job) /* I - Job */
job->attrs = NULL;
job->state = NULL;
+ job->reasons = NULL;
job->sheets = NULL;
job->job_sheets = NULL;
job->printer_message = NULL;
@@ -4420,9 +4750,25 @@ update_job(cupsd_job_t *job) /* I - Job to check */
cupsdStopPrinter(job->printer, 1);
return;
}
- else if (cupsdSetPrinterReasons(job->printer, message))
+ else if (message[0] && cupsdSetPrinterReasons(job->printer, message))
+ {
event |= CUPSD_EVENT_PRINTER_STATE;
+ if (MaxJobTime > 0 && strstr(message, "connecting-to-device") != NULL)
+ {
+ /*
+ * Reset cancel time after connecting to the device...
+ */
+
+ for (i = 0; i < job->printer->num_reasons; i ++)
+ if (!strcmp(job->printer->reasons[i], "connecting-to-device"))
+ break;
+
+ if (i >= job->printer->num_reasons)
+ job->cancel_time = time(NULL) + MaxJobTime;
+ }
+ }
+
update_job_attrs(job, 0);
}
else if (loglevel == CUPSD_LOG_ATTR)
@@ -4446,10 +4792,7 @@ update_job(cupsd_job_t *job) /* I - Job to check */
cupsdSetAuthInfoRequired(job->printer, attr, NULL);
cupsdSetPrinterAttrs(job->printer);
- if (job->printer->type & CUPS_PRINTER_DISCOVERED)
- cupsdMarkDirty(CUPSD_DIRTY_REMOTE);
- else
- cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
}
if ((attr = cupsGetOption("job-media-progress", num_attrs,
@@ -4546,18 +4889,10 @@ update_job(cupsd_job_t *job) /* I - Job to check */
* Set attribute(s)...
*/
- int num_keywords; /* Number of keywords */
- cups_option_t *keywords; /* Keywords */
-
-
cupsdLogJob(job, CUPSD_LOG_DEBUG, "PPD: %s", message);
- num_keywords = cupsParseOptions(message, 0, &keywords);
-
- if (cupsdUpdatePrinterPPD(job->printer, num_keywords, keywords))
- cupsdSetPrinterAttrs(job->printer);
-
- cupsFreeOptions(num_keywords, keywords);
+ job->num_keywords = cupsParseOptions(message, job->num_keywords,
+ &job->keywords);
}
else
{
@@ -4580,7 +4915,8 @@ update_job(cupsd_job_t *job) /* I - Job to check */
else
ptr = message;
- cupsdLogJob(job, loglevel, "%s", ptr);
+ if (*ptr)
+ cupsdLogJob(job, loglevel, "%s", ptr);
if (loglevel < CUPSD_LOG_DEBUG &&
strcmp(job->printer->state_message, ptr))
@@ -4708,11 +5044,21 @@ update_job_attrs(cupsd_job_t *job, /* I - Job to update */
if (job->state_value != IPP_JOB_PROCESSING &&
job->status_level == CUPSD_LOG_INFO)
+ {
cupsdSetString(&(job->printer_message->values[0].string.text), "");
+
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+ }
else if (job->printer->state_message[0] && do_message)
+ {
cupsdSetString(&(job->printer_message->values[0].string.text),
job->printer->state_message);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+ }
+
/*
* ... and the printer-state-reasons value...
*/
@@ -4768,9 +5114,12 @@ update_job_attrs(cupsd_job_t *job, /* I - Job to update */
for (i = 0; i < num_reasons; i ++)
job->printer_reasons->values[i].string.text = _cupsStrAlloc(reasons[i]);
+
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
/*
- * End of "$Id: job.c 10420 2012-04-20 03:01:06Z mike $".
+ * End of "$Id: job.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/job.h b/scheduler/job.h
index 130326f..6fb5ab8 100644
--- a/scheduler/job.h
+++ b/scheduler/job.h
@@ -1,5 +1,5 @@
/*
- * "$Id: job.h 9778 2011-05-18 02:27:11Z mike $"
+ * "$Id: job.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Print job definitions for the CUPS scheduler.
*
@@ -46,9 +46,13 @@ struct cupsd_job_s /**** Job request ****/
int *compressions; /* Compression status of each file */
ipp_attribute_t *sheets; /* job-media-sheets-completed */
time_t access_time, /* Last access time */
- kill_time, /* When to send SIGKILL */
- hold_until; /* Hold expiration date/time */
+ cancel_time, /* When to cancel/send SIGTERM */
+ file_time, /* Job file retain time */
+ history_time, /* Job history retain time */
+ hold_until, /* Hold expiration date/time */
+ kill_time; /* When to send SIGKILL */
ipp_attribute_t *state; /* Job state */
+ ipp_attribute_t *reasons; /* Job state reasons */
ipp_attribute_t *job_sheets; /* Job sheets (NULL if none) */
ipp_attribute_t *printer_message,
/* job-printer-state-message */
@@ -76,6 +80,8 @@ struct cupsd_job_s /**** Job request ****/
void *profile; /* Security profile */
cups_array_t *history; /* Debug log history */
int progress; /* Printing progress */
+ int num_keywords; /* Number of PPD keywords */
+ cups_option_t *keywords; /* PPD keywords */
};
typedef struct cupsd_joblog_s /**** Job log message ****/
@@ -89,18 +95,24 @@ typedef struct cupsd_joblog_s /**** Job log message ****/
* Globals...
*/
-VAR int JobHistory VALUE(1);
+VAR int JobHistory VALUE(INT_MAX);
/* Preserve job history? */
-VAR int JobFiles VALUE(0);
+VAR int JobFiles VALUE(86400);
/* Preserve job files? */
+VAR time_t JobHistoryUpdate VALUE(0);
+ /* Time for next job history update */
VAR int MaxJobs VALUE(0),
/* Max number of jobs */
MaxActiveJobs VALUE(0),
/* Max number of active jobs */
+ MaxHoldTime VALUE(0),
+ /* Max time for indefinite hold */
MaxJobsPerUser VALUE(0),
/* Max jobs per user */
- MaxJobsPerPrinter VALUE(0);
+ MaxJobsPerPrinter VALUE(0),
/* Max jobs per printer */
+ MaxJobTime VALUE(3 * 60 * 60);
+ /* Max time for a job */
VAR int JobAutoPurge VALUE(0);
/* Automatically purge jobs */
VAR cups_array_t *Jobs VALUE(NULL),
@@ -149,16 +161,15 @@ extern void cupsdSetJobState(cupsd_job_t *job,
ipp_jstate_t newstate,
cupsd_jobaction_t action,
const char *message, ...)
-#ifdef __GNUC__
-__attribute__ ((__format__ (__printf__, 4, 5)))
-#endif /* __GNUC__ */
-;
+ __attribute__((__format__(__printf__,
+ 4, 5)));
extern void cupsdStopAllJobs(cupsd_jobaction_t action,
int kill_delay);
extern int cupsdTimeoutJob(cupsd_job_t *job);
extern void cupsdUnloadCompletedJobs(void);
+extern void cupsdUpdateJobs(void);
/*
- * End of "$Id: job.h 9778 2011-05-18 02:27:11Z mike $".
+ * End of "$Id: job.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/listen.c b/scheduler/listen.c
index ce7a26d..a4c19c0 100644
--- a/scheduler/listen.c
+++ b/scheduler/listen.c
@@ -1,5 +1,5 @@
/*
- * "$Id: listen.c 9691 2011-04-15 23:38:13Z mike $"
+ * "$Id: listen.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Server listening routines for the CUPS scheduler.
*
@@ -427,5 +427,5 @@ cupsdStopListening(void)
/*
- * End of "$Id: listen.c 9691 2011-04-15 23:38:13Z mike $".
+ * End of "$Id: listen.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/log.c b/scheduler/log.c
index 11d180e..d739b58 100644
--- a/scheduler/log.c
+++ b/scheduler/log.c
@@ -1,5 +1,5 @@
/*
- * "$Id: log.c 9949 2011-08-31 04:58:33Z mike $"
+ * "$Id: log.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Log file routines for the CUPS scheduler.
*
@@ -41,6 +41,22 @@
static int log_linesize = 0; /* Size of line for output file */
static char *log_line = NULL; /* Line for output file */
+#ifdef HAVE_VSYSLOG
+static const int syslevels[] = /* SYSLOG levels... */
+ {
+ 0,
+ LOG_EMERG,
+ LOG_ALERT,
+ LOG_CRIT,
+ LOG_ERR,
+ LOG_WARNING,
+ LOG_NOTICE,
+ LOG_INFO,
+ LOG_DEBUG,
+ LOG_DEBUG
+ };
+#endif /* HAVE_VSYSLOG */
+
/*
* Local functions...
@@ -379,7 +395,23 @@ cupsdLogGSSMessage(
minor_status_string = GSS_C_EMPTY_BUFFER;
/* Minor status message */
int ret; /* Return value */
+ char buffer[8192]; /* Buffer for vsnprintf */
+
+
+ if (strchr(message, '%'))
+ {
+ /*
+ * Format the message string...
+ */
+ va_list ap; /* Pointer to arguments */
+
+ va_start(ap, message);
+ vsnprintf(buffer, sizeof(buffer), message, ap);
+ va_end(ap);
+
+ message = buffer;
+ }
msg_ctx = 0;
err_major_status = gss_display_status(&err_minor_status,
@@ -414,7 +446,7 @@ cupsdLogJob(cupsd_job_t *job, /* I - Job */
const char *message, /* I - Printf-style message string */
...) /* I - Additional arguments as needed */
{
- va_list ap; /* Argument pointer */
+ va_list ap, ap2; /* Argument pointers */
char jobmsg[1024]; /* Format string for job message */
int status; /* Formatting status */
@@ -435,19 +467,27 @@ cupsdLogJob(cupsd_job_t *job, /* I - Job */
* Format and write the log message...
*/
- snprintf(jobmsg, sizeof(jobmsg), "[Job %d] %s", job->id, message);
+ if (job)
+ snprintf(jobmsg, sizeof(jobmsg), "[Job %d] %s", job->id, message);
+ else
+ strlcpy(jobmsg, message, sizeof(jobmsg));
+
+ va_start(ap, message);
do
{
- va_start(ap, message);
- status = format_log_line(jobmsg, ap);
- va_end(ap);
+ va_copy(ap2, ap);
+ status = format_log_line(jobmsg, ap2);
+ va_end(ap2);
}
while (status == 0);
+ va_end(ap);
+
if (status > 0)
{
- if ((level > LogLevel ||
+ if (job &&
+ (level > LogLevel ||
(level == CUPSD_LOG_INFO && LogLevel < CUPSD_LOG_DEBUG)) &&
LogDebugHistory > 0)
{
@@ -508,7 +548,7 @@ cupsdLogMessage(int level, /* I - Log level */
const char *message, /* I - printf-style message string */
...) /* I - Additional args as needed */
{
- va_list ap; /* Argument pointer */
+ va_list ap, ap2; /* Argument pointers */
int status; /* Formatting status */
@@ -519,8 +559,12 @@ cupsdLogMessage(int level, /* I - Log level */
if ((TestConfigFile || !ErrorLog) && level <= CUPSD_LOG_WARN)
{
va_start(ap, message);
+#ifdef HAVE_VSYSLOG
+ vsyslog(LOG_LPR | syslevels[level], message, ap);
+#else
vfprintf(stderr, message, ap);
putc('\n', stderr);
+#endif /* HAVE_VSYSLOG */
va_end(ap);
return (1);
@@ -533,14 +577,18 @@ cupsdLogMessage(int level, /* I - Log level */
* Format and write the log message...
*/
+ va_start(ap, message);
+
do
{
- va_start(ap, message);
- status = format_log_line(message, ap);
- va_end(ap);
+ va_copy(ap2, ap);
+ status = format_log_line(message, ap2);
+ va_end(ap2);
}
while (status == 0);
+ va_end(ap);
+
if (status > 0)
return (cupsdWriteErrorLog(level, log_line));
else
@@ -956,21 +1004,6 @@ cupsdWriteErrorLog(int level, /* I - Log level */
'D',
'd'
};
-#ifdef HAVE_VSYSLOG
- static const int syslevels[] = /* SYSLOG levels... */
- {
- 0,
- LOG_EMERG,
- LOG_ALERT,
- LOG_CRIT,
- LOG_ERR,
- LOG_WARNING,
- LOG_NOTICE,
- LOG_INFO,
- LOG_DEBUG,
- LOG_DEBUG
- };
-#endif /* HAVE_VSYSLOG */
#ifdef HAVE_VSYSLOG
@@ -1070,5 +1103,5 @@ format_log_line(const char *message, /* I - Printf-style format string */
/*
- * End of "$Id: log.c 9949 2011-08-31 04:58:33Z mike $".
+ * End of "$Id: log.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/main.c b/scheduler/main.c
index c50ce9d..11eae52 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -1,9 +1,9 @@
/*
- * "$Id: main.c 9783 2011-05-18 20:44:16Z mike $"
+ * "$Id: main.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Main loop for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -65,10 +65,15 @@
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
# include <malloc.h>
#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
+
#ifdef HAVE_NOTIFY_H
# include <notify.h>
#endif /* HAVE_NOTIFY_H */
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
/*
* Local functions...
@@ -84,7 +89,7 @@ static void sigchld_handler(int sig);
static void sighup_handler(int sig);
static void sigterm_handler(int sig);
static long select_timeout(int fds);
-static void usage(int status);
+static void usage(int status) __attribute__((noreturn));
/*
@@ -120,7 +125,6 @@ main(int argc, /* I - Number of command-line args */
cupsd_listener_t *lis; /* Current listener */
time_t current_time, /* Current time */
activity, /* Client activity timer */
- browse_time, /* Next browse send time */
senddoc_time, /* Send-Document time */
expire_time, /* Subscription expire time */
report_time, /* Malloc/client/job report time */
@@ -208,7 +212,6 @@ main(int argc, /* I - Number of command-line args */
char *current; /* Current directory */
-
/*
* Allocate a buffer for the current working directory to
* reduce run-time stack usage; this approximates the
@@ -272,6 +275,29 @@ main(int argc, /* I - Number of command-line args */
UseProfiles = 0;
break;
+ case 's' : /* Set cups-files.conf location */
+ i ++;
+ if (i >= argc)
+ {
+ _cupsLangPuts(stderr, _("cupsd: Expected cups-files.conf "
+ "filename after \"-s\" option."));
+ usage(1);
+ }
+
+ if (argv[i][0] != '/')
+ {
+ /*
+ * Relative filename not allowed...
+ */
+
+ _cupsLangPuts(stderr, _("cupsd: Relative cups-files.conf "
+ "filename not allowed."));
+ usage(1);
+ }
+
+ cupsdSetString(&CupsFilesFile, argv[i]);
+ break;
+
#ifdef __APPLE__
case 'S' : /* Disable system management functions */
fputs("cupsd: -S (disable system management) for internal "
@@ -299,7 +325,39 @@ main(int argc, /* I - Number of command-line args */
}
if (!ConfigurationFile)
+ {
cupsdSetString(&ConfigurationFile, CUPS_SERVERROOT "/cupsd.conf");
+ cupsdSetString(&CupsFilesFile, CUPS_SERVERROOT "/cups-files.conf");
+ }
+
+ if (!CupsFilesFile)
+ {
+ char *filename, /* Copy of cupsd.conf filename */
+ *slash; /* Final slash in cupsd.conf filename */
+ size_t len; /* Size of buffer */
+
+ len = strlen(ConfigurationFile) + 15;
+ if ((filename = malloc(len)) == NULL)
+ {
+ _cupsLangPrintf(stderr,
+ _("cupsd: Unable to get path to "
+ "cups-files.conf file."));
+ return (1);
+ }
+
+ strlcpy(filename, ConfigurationFile, len);
+ if ((slash = strrchr(filename, '/')) == NULL)
+ {
+ _cupsLangPrintf(stderr,
+ _("cupsd: Unable to get path to "
+ "cups-files.conf file."));
+ return (1);
+ }
+
+ strlcpy(slash, "/cups-files.conf", len - (slash - filename));
+ cupsdSetString(&CupsFilesFile, filename);
+ free(filename);
+ }
/*
* If the user hasn't specified "-f", run in the background...
@@ -366,15 +424,15 @@ main(int argc, /* I - Number of command-line args */
}
}
-#ifdef __OpenBSD__
+#if defined(__OpenBSD__) && OpenBSD < 201211
/*
* Call _thread_sys_closefrom() so the child process doesn't reset the
* parent's file descriptors to be blocking. This is a workaround for a
- * limitation of userland libpthread on OpenBSD.
+ * limitation of userland libpthread on older versions of OpenBSD.
*/
_thread_sys_closefrom(0);
-#endif /* __OpenBSD__ */
+#endif /* __OpenBSD__ && OpenBSD < 201211 */
/*
* Since CoreFoundation and DBUS both create fork-unsafe data on execution of
@@ -484,17 +542,11 @@ main(int argc, /* I - Number of command-line args */
*/
if (!cupsdReadConfiguration())
- {
- if (TestConfigFile)
- printf("%s contains errors\n", ConfigurationFile);
- else
- syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
- ConfigurationFile);
return (1);
- }
else if (TestConfigFile)
{
- printf("%s is OK\n", ConfigurationFile);
+ printf("\"%s\" is OK.\n", CupsFilesFile);
+ printf("\"%s\" is OK.\n", ConfigurationFile);
return (0);
}
@@ -650,7 +702,6 @@ main(int argc, /* I - Number of command-line args */
*/
current_time = time(NULL);
- browse_time = current_time;
event_time = current_time;
expire_time = current_time;
fds = 1;
@@ -766,11 +817,9 @@ main(int argc, /* I - Number of command-line args */
* inactivity...
*/
- if (timeout == 86400 && Launchd && LaunchdTimeout && !NumPolled &&
+ if (timeout == 86400 && Launchd && LaunchdTimeout &&
!cupsArrayCount(ActiveJobs) &&
- (!Browsing ||
- (!BrowseRemoteProtocols &&
- (!BrowseLocalProtocols || !cupsArrayCount(Printers)))))
+ (!Browsing || !BrowseLocalProtocols || !cupsArrayCount(Printers)))
{
timeout = LaunchdTimeout;
launchd_idle_exit = 1;
@@ -785,9 +834,9 @@ main(int argc, /* I - Number of command-line args */
* Got an error from select!
*/
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
cupsd_printer_t *p; /* Current printer */
-#endif /* HAVE_DNSSD */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
if (errno == EINTR) /* Just interrupted by a signal */
@@ -812,8 +861,6 @@ main(int argc, /* I - Number of command-line args */
i ++, lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
cupsdLogMessage(CUPSD_LOG_EMERG, "Listeners[%d] = %d", i, lis->fd);
- cupsdLogMessage(CUPSD_LOG_EMERG, "BrowseSocket = %d", BrowseSocket);
-
cupsdLogMessage(CUPSD_LOG_EMERG, "CGIPipes[0] = %d", CGIPipes[0]);
#ifdef __APPLE__
@@ -830,13 +877,13 @@ main(int argc, /* I - Number of command-line args */
job->print_pipes[0], job->print_pipes[1],
job->back_pipes[0], job->back_pipes[1]);
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
cupsdLogMessage(CUPSD_LOG_EMERG, "printer[%s] reg_name=\"%s\"", p->name,
p->reg_name ? p->reg_name : "(null)");
-#endif /* HAVE_DNSSD */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
break;
}
@@ -914,31 +961,6 @@ main(int argc, /* I - Number of command-line args */
expire_time = current_time;
}
- /*
- * Update the browse list as needed...
- */
-
- if (Browsing)
- {
-#ifdef HAVE_LIBSLP
- if ((BrowseRemoteProtocols & BROWSE_SLP) &&
- BrowseSLPRefresh <= current_time)
- cupsdUpdateSLPBrowse();
-#endif /* HAVE_LIBSLP */
-
-#ifdef HAVE_LDAP
- if ((BrowseRemoteProtocols & BROWSE_LDAP) &&
- BrowseLDAPRefresh <= current_time)
- cupsdUpdateLDAPBrowse();
-#endif /* HAVE_LDAP */
- }
-
- if (Browsing && current_time > browse_time)
- {
- cupsdSendBrowseList();
- browse_time = current_time;
- }
-
#ifndef HAVE_AUTHORIZATION_H
/*
* Update the root certificate once every 5 minutes if we have client
@@ -953,7 +975,7 @@ main(int argc, /* I - Number of command-line args */
*/
cupsdDeleteCert(0);
- cupsdAddCert(0, "root", NULL);
+ cupsdAddCert(0, "root", cupsdDefaultAuthType());
}
#endif /* !HAVE_AUTHORIZATION_H */
@@ -998,11 +1020,17 @@ main(int argc, /* I - Number of command-line args */
if ((current_time - senddoc_time) >= 10)
{
cupsdCheckJobs();
- cupsdCleanJobs();
senddoc_time = current_time;
}
/*
+ * Clean job history...
+ */
+
+ if (JobHistoryUpdate && current_time >= JobHistoryUpdate)
+ cupsdCleanJobs();
+
+ /*
* Log statistics at most once a minute when in debug mode...
*/
@@ -1031,8 +1059,6 @@ main(int argc, /* I - Number of command-line args */
cupsArrayCount(ActiveJobs));
cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: printers=%d",
cupsArrayCount(Printers));
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: printers-implicit=%d",
- cupsArrayCount(ImplicitPrinters));
string_count = _cupsStrStatistics(&alloc_bytes, &total_bytes);
cupsdLogMessage(CUPSD_LOG_DEBUG,
@@ -1141,23 +1167,6 @@ main(int argc, /* I - Number of command-line args */
cupsdStopSystemMonitor();
#endif /* __APPLE__ */
-#ifdef HAVE_GSSAPI
- /*
- * Free the scheduler's Kerberos context...
- */
-
-# ifdef __APPLE__
- /*
- * If the weak-linked GSSAPI/Kerberos library is not present, don't try
- * to use it...
- */
-
- if (krb5_init_context != NULL)
-# endif /* __APPLE__ */
- if (KerberosContext)
- krb5_free_context(KerberosContext);
-#endif /* HAVE_GSSAPI */
-
#ifdef __sgi
/*
* Remove the fake IRIX lpsched lock file, but only if the existing
@@ -1317,7 +1326,7 @@ cupsdSetStringf(char **s, /* O - New string */
const char *f, /* I - Printf-style format string */
...) /* I - Additional args as needed */
{
- char v[4096]; /* Formatting string value */
+ char v[65536 + 64]; /* Formatting string value */
va_list ap; /* Argument pointer */
char *olds; /* Old string */
@@ -1512,10 +1521,8 @@ launchd_checkout(void)
* shared printers to advertise...
*/
- if (cupsArrayCount(ActiveJobs) || NumPolled ||
- (Browsing &&
- (BrowseRemoteProtocols ||
- (BrowseLocalProtocols && cupsArrayCount(Printers)))))
+ if (cupsArrayCount(ActiveJobs) ||
+ (Browsing && BrowseLocalProtocols && cupsArrayCount(Printers)))
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
"Creating launchd keepalive file \"" CUPS_KEEPALIVE
@@ -1564,6 +1571,7 @@ process_children(void)
cupsd_job_t *job; /* Current job */
int i; /* Looping var */
char name[1024]; /* Process name */
+ const char *type; /* Type of program */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "process_children()");
@@ -1603,7 +1611,12 @@ process_children(void)
* Handle completed job filters...
*/
- if (job_id > 0 && (job = cupsdFindJob(job_id)) != NULL)
+ if (job_id > 0)
+ job = cupsdFindJob(job_id);
+ else
+ job = NULL;
+
+ if (job)
{
for (i = 0; job->filters[i]; i ++)
if (job->filters[i] == pid)
@@ -1616,12 +1629,18 @@ process_children(void)
*/
if (job->filters[i])
+ {
job->filters[i] = -pid;
+ type = "Filter";
+ }
else
+ {
job->backend = -pid;
+ type = "Backend";
+ }
if (status && status != SIGTERM && status != SIGKILL &&
- status != SIGPIPE && job->status >= 0)
+ status != SIGPIPE)
{
/*
* An error occurred; save the exit status so we know to stop
@@ -1629,22 +1648,35 @@ process_children(void)
*
* A negative status indicates that the backend failed and the
* printer needs to be stopped.
+ *
+ * In order to preserve the most serious status, we always log
+ * when a process dies due to a signal (e.g. SIGABRT, SIGSEGV,
+ * and SIGBUS) and prefer to log the backend exit status over a
+ * filter's.
*/
- if (job->filters[i])
- job->status = status; /* Filter failed */
- else
- job->status = -status; /* Backend failed */
+ int old_status = abs(job->status);
+
+ if (WIFSIGNALED(status) || /* This process crashed, or */
+ !job->status || /* No process had a status, or */
+ (!job->filters[i] && WIFEXITED(old_status)))
+ { /* Backend and filter didn't crash */
+ if (job->filters[i])
+ job->status = status; /* Filter failed */
+ else
+ job->status = -status; /* Backend failed */
+ }
if (job->state_value == IPP_JOB_PROCESSING &&
- job->status_level > CUPSD_LOG_ERROR)
+ job->status_level > CUPSD_LOG_ERROR &&
+ (job->filters[i] || !WIFEXITED(status)))
{
char message[1024]; /* New printer-state-message */
job->status_level = CUPSD_LOG_ERROR;
- snprintf(message, sizeof(message), "%s failed", name);
+ snprintf(message, sizeof(message), "%s failed", type);
if (job->printer)
{
@@ -1714,15 +1746,15 @@ process_children(void)
if (status == SIGTERM || status == SIGKILL)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "PID %d (%s) was terminated normally with signal %d.",
- pid, name, status);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG,
+ "PID %d (%s) was terminated normally with signal %d.", pid,
+ name, status);
}
else if (status == SIGPIPE)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "PID %d (%s) did not catch or ignore signal %d.",
- pid, name, status);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG,
+ "PID %d (%s) did not catch or ignore signal %d.", pid, name,
+ status);
}
else if (status)
{
@@ -1731,26 +1763,25 @@ process_children(void)
int code = WEXITSTATUS(status); /* Exit code */
if (code > 100)
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "PID %d (%s) stopped with status %d (%s)", pid, name,
- code, strerror(code - 100));
+ cupsdLogJob(job, CUPSD_LOG_DEBUG,
+ "PID %d (%s) stopped with status %d (%s)", pid, name,
+ code, strerror(code - 100));
else
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "PID %d (%s) stopped with status %d.", pid, name,
- code);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG,
+ "PID %d (%s) stopped with status %d.", pid, name, code);
}
else
- cupsdLogMessage(CUPSD_LOG_ERROR, "PID %d (%s) crashed on signal %d.",
- pid, name, WTERMSIG(status));
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "PID %d (%s) crashed on signal %d.",
+ pid, name, WTERMSIG(status));
if (LogLevel < CUPSD_LOG_DEBUG)
- cupsdLogMessage(CUPSD_LOG_INFO,
- "Hint: Try setting the LogLevel to \"debug\" to find "
- "out more.");
+ cupsdLogJob(job, CUPSD_LOG_INFO,
+ "Hint: Try setting the LogLevel to \"debug\" to find out "
+ "more.");
}
else
- cupsdLogMessage(CUPSD_LOG_DEBUG, "PID %d (%s) exited with no errors.",
- pid, name);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "PID %d (%s) exited with no errors.",
+ pid, name);
}
/*
@@ -1773,12 +1804,14 @@ select_timeout(int fds) /* I - Number of descriptors returned */
long timeout; /* Timeout for select */
time_t now; /* Current time */
cupsd_client_t *con; /* Client information */
- cupsd_printer_t *p; /* Printer information */
cupsd_job_t *job; /* Job information */
cupsd_subscription_t *sub; /* Subscription information */
const char *why; /* Debugging aid */
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "select_timeout: JobHistoryUpdate=%ld",
+ (long)JobHistoryUpdate);
+
/*
* Check to see if any of the clients have pending data to be
* processed; if so, the timeout should be 0...
@@ -1848,54 +1881,6 @@ select_timeout(int fds) /* I - Number of descriptors returned */
}
/*
- * Update the browse list as needed...
- */
-
- if (Browsing && BrowseLocalProtocols)
- {
-#ifdef HAVE_LIBSLP
- if ((BrowseLocalProtocols & BROWSE_SLP) && (BrowseSLPRefresh < timeout))
- {
- timeout = BrowseSLPRefresh;
- why = "update SLP browsing";
- }
-#endif /* HAVE_LIBSLP */
-
-#ifdef HAVE_LDAP
- if ((BrowseLocalProtocols & BROWSE_LDAP) && (BrowseLDAPRefresh < timeout))
- {
- timeout = BrowseLDAPRefresh;
- why = "update LDAP browsing";
- }
-#endif /* HAVE_LDAP */
-
- if ((BrowseLocalProtocols & BROWSE_CUPS) && NumBrowsers)
- {
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- {
- if (p->type & CUPS_PRINTER_REMOTE)
- {
- if ((p->browse_time + BrowseTimeout) < timeout)
- {
- timeout = p->browse_time + BrowseTimeout;
- why = "browse timeout a printer";
- }
- }
- else if (p->shared && !(p->type & CUPS_PRINTER_IMPLICIT))
- {
- if (BrowseInterval && (p->browse_time + BrowseInterval) < timeout)
- {
- timeout = p->browse_time + BrowseInterval;
- why = "send browse update";
- }
- }
- }
- }
- }
-
- /*
* Write out changes to configuration and state files...
*/
@@ -1906,13 +1891,25 @@ select_timeout(int fds) /* I - Number of descriptors returned */
}
/*
- * Check for any active jobs...
+ * Check for any job activity...
*/
+ if (JobHistoryUpdate && timeout > JobHistoryUpdate)
+ {
+ timeout = JobHistoryUpdate;
+ why = "update job history";
+ }
+
for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
job;
job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
{
+ if (job->cancel_time && job->cancel_time < timeout)
+ {
+ timeout = job->cancel_time;
+ why = "cancel stuck jobs";
+ }
+
if (job->kill_time && job->kill_time < timeout)
{
timeout = job->kill_time;
@@ -1924,7 +1921,8 @@ select_timeout(int fds) /* I - Number of descriptors returned */
timeout = job->hold_until;
why = "release held jobs";
}
- else if (job->state_value == IPP_JOB_PENDING && timeout > (now + 10))
+
+ if (job->state_value == IPP_JOB_PENDING && timeout > (now + 10))
{
timeout = now + 10;
why = "start pending jobs";
@@ -1958,11 +1956,9 @@ select_timeout(int fds) /* I - Number of descriptors returned */
}
/*
- * Adjust from absolute to relative time. If p->browse_time above
- * was 0 then we can end up with a negative value here, so check.
- * We add 1 second to the timeout since events occur after the
- * timeout expires, and limit the timeout to 86400 seconds (1 day)
- * to avoid select() timeout limits present on some operating
+ * Adjust from absolute to relative time. We add 1 second to the timeout since
+ * events occur after the timeout expires, and limit the timeout to 86400
+ * seconds (1 day) to avoid select() timeout limits present on some operating
* systems...
*/
@@ -2056,8 +2052,7 @@ usage(int status) /* O - Exit status */
_cupsLangPuts(fp, _("Usage: cupsd [options]"));
_cupsLangPuts(fp, _("Options:"));
- _cupsLangPuts(fp, _(" -c config-file Load alternate configuration "
- "file."));
+ _cupsLangPuts(fp, _(" -c cupsd.conf Set cupsd.conf file to use."));
_cupsLangPuts(fp, _(" -f Run in the foreground."));
_cupsLangPuts(fp, _(" -F Run in the foreground but "
"detach from console."));
@@ -2071,5 +2066,5 @@ usage(int status) /* O - Exit status */
/*
- * End of "$Id: main.c 9783 2011-05-18 20:44:16Z mike $".
+ * End of "$Id: main.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/mime-private.h b/scheduler/mime-private.h
index 5891253..f984548 100644
--- a/scheduler/mime-private.h
+++ b/scheduler/mime-private.h
@@ -1,5 +1,5 @@
/*
- * "$Id: mime-private.h 9750 2011-05-06 22:53:53Z mike $"
+ * "$Id: mime-private.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Private MIME type/conversion database definitions for CUPS.
*
@@ -32,10 +32,7 @@ extern "C" {
*/
extern void _mimeError(mime_t *mime, const char *format, ...)
-#ifdef __GNUC__
-__attribute__ ((__format__ (__printf__, 2, 3)))
-#endif /* __GNUC__ */
-;
+ __attribute__ ((__format__ (__printf__, 2, 3)));
# ifdef __cplusplus
@@ -44,5 +41,5 @@ __attribute__ ((__format__ (__printf__, 2, 3)))
#endif /* !_CUPS_MIME_PRIVATE_H_ */
/*
- * End of "$Id: mime-private.h 9750 2011-05-06 22:53:53Z mike $".
+ * End of "$Id: mime-private.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/mime.c b/scheduler/mime.c
index fd7c12a..412c9e0 100644
--- a/scheduler/mime.c
+++ b/scheduler/mime.c
@@ -1,5 +1,5 @@
/*
- * "$Id: mime.c 9750 2011-05-06 22:53:53Z mike $"
+ * "$Id: mime.c 11173 2013-07-23 12:31:34Z msweet $"
*
* MIME database file routines for CUPS.
*
@@ -956,5 +956,5 @@ mime_load_types(mime_t *mime, /* I - MIME database */
/*
- * End of "$Id: mime.c 9750 2011-05-06 22:53:53Z mike $".
+ * End of "$Id: mime.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/mime.h b/scheduler/mime.h
index c9e2147..51d7a29 100644
--- a/scheduler/mime.h
+++ b/scheduler/mime.h
@@ -1,5 +1,5 @@
/*
- * "$Id: mime.h 9750 2011-05-06 22:53:53Z mike $"
+ * "$Id: mime.h 11173 2013-07-23 12:31:34Z msweet $"
*
* MIME type/conversion database definitions for CUPS.
*
@@ -158,5 +158,5 @@ extern void mimeSetErrorCallback(mime_t *mime, mime_error_cb_t cb,
#endif /* !_CUPS_MIME_H_ */
/*
- * End of "$Id: mime.h 9750 2011-05-06 22:53:53Z mike $".
+ * End of "$Id: mime.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/network.c b/scheduler/network.c
index 921ed17..07b5265 100644
--- a/scheduler/network.c
+++ b/scheduler/network.c
@@ -1,5 +1,5 @@
/*
- * "$Id: network.c 10379 2012-03-23 22:16:22Z mike $"
+ * "$Id: network.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Network interface functions for the CUPS scheduler.
*
@@ -296,5 +296,5 @@ compare_netif(cupsd_netif_t *a, /* I - First network interface */
/*
- * End of "$Id: network.c 10379 2012-03-23 22:16:22Z mike $".
+ * End of "$Id: network.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/network.h b/scheduler/network.h
index f16a06b..0570975 100644
--- a/scheduler/network.h
+++ b/scheduler/network.h
@@ -1,5 +1,5 @@
/*
- * "$Id: network.h 9350 2010-11-04 23:23:25Z mike $"
+ * "$Id: network.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Network interface definitions for the CUPS scheduler.
*
@@ -48,5 +48,5 @@ extern void cupsdNetIFUpdate(void);
/*
- * End of "$Id: network.h 9350 2010-11-04 23:23:25Z mike $".
+ * End of "$Id: network.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/policy.c b/scheduler/policy.c
index fb29ce0..75b5983 100644
--- a/scheduler/policy.c
+++ b/scheduler/policy.c
@@ -1,5 +1,5 @@
/*
- * "$Id: policy.c 9793 2011-05-20 03:49:49Z mike $"
+ * "$Id: policy.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Policy routines for the CUPS scheduler.
*
@@ -513,5 +513,5 @@ hash_op(cupsd_location_t *op) /* I - Operation */
/*
- * End of "$Id: policy.c 9793 2011-05-20 03:49:49Z mike $".
+ * End of "$Id: policy.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/policy.h b/scheduler/policy.h
index f718777..df17a11 100644
--- a/scheduler/policy.h
+++ b/scheduler/policy.h
@@ -1,5 +1,5 @@
/*
- * "$Id: policy.h 9352 2010-11-06 04:55:26Z mike $"
+ * "$Id: policy.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Policy definitions for the CUPS scheduler.
*
@@ -59,5 +59,5 @@ extern cups_array_t *cupsdGetPrivateAttrs(cupsd_policy_t *p,
/*
- * End of "$Id: policy.h 9352 2010-11-06 04:55:26Z mike $".
+ * End of "$Id: policy.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/printers.c b/scheduler/printers.c
index 1220db6..48c4a82 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -1,5 +1,5 @@
/*
- * "$Id: printers.c 10295 2012-02-15 23:21:06Z mike $"
+ * "$Id: printers.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Printer routines for the CUPS scheduler.
*
@@ -168,9 +168,6 @@ cupsdAddPrinter(const char *name) /* I - Name of printer */
"cupsdAddPrinter: Adding %s to Printers", p->name);
cupsArrayAdd(Printers, p);
- if (!ImplicitPrinters)
- ImplicitPrinters = cupsArrayNew(compare_printers, NULL);
-
/*
* Return the new printer...
*/
@@ -643,8 +640,7 @@ cupsdCreateCommonData(void)
/* operations-supported */
ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
- "operations-supported",
- sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, ops);
+ "operations-supported", sizeof(ops) / sizeof(ops[0]), ops);
/* orientation-requested-supported */
ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
@@ -752,16 +748,6 @@ cupsdDeletePrinter(
"Job stopped.");
/*
- * If this printer is the next for browsing, point to the next one...
- */
-
- if (p == BrowseNext)
- {
- cupsArrayFind(Printers, p);
- BrowseNext = (cupsd_printer_t *)cupsArrayNext(Printers);
- }
-
- /*
* Remove the printer from the list...
*/
@@ -769,14 +755,6 @@ cupsdDeletePrinter(
"cupsdDeletePrinter: Removing %s from Printers", p->name);
cupsArrayRemove(Printers, p);
- if (p->type & CUPS_PRINTER_IMPLICIT)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdDeletePrinter: Removing %s from ImplicitPrinters",
- p->name);
- cupsArrayRemove(ImplicitPrinters, p);
- }
-
/*
* Remove the dummy interface/icon/option files under IRIX...
*/
@@ -807,43 +785,19 @@ cupsdDeletePrinter(
*/
if (p == DefaultPrinter)
- {
DefaultPrinter = NULL;
- if (UseNetworkDefault)
- {
- /*
- * Find the first network default printer and use it...
- */
-
- cupsd_printer_t *dp; /* New default printer */
-
-
- for (dp = (cupsd_printer_t *)cupsArrayFirst(Printers);
- dp;
- dp = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (dp != p && (dp->type & CUPS_PRINTER_DEFAULT))
- {
- DefaultPrinter = dp;
- break;
- }
- }
- }
-
/*
* Remove this printer from any classes...
*/
- if (!(p->type & CUPS_PRINTER_IMPLICIT))
- {
- changed = cupsdDeletePrinterFromClasses(p);
+ changed = cupsdDeletePrinterFromClasses(p);
- /*
- * Deregister from any browse protocols...
- */
+ /*
+ * Deregister from any browse protocols...
+ */
- cupsdDeregisterPrinter(p, 1);
- }
+ cupsdDeregisterPrinter(p, 1);
/*
* Free all memory used by the printer...
@@ -883,15 +837,13 @@ cupsdDeletePrinter(
cupsdClearString(&p->alert);
cupsdClearString(&p->alert_description);
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
cupsdClearString(&p->pdl);
-#endif /* HAVE_DNSSD */
+ cupsdClearString(&p->reg_name);
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
cupsArrayDelete(p->filetypes);
- if (p->browse_attrs)
- free(p->browse_attrs);
-
cupsFreeOptions(p->num_options, p->options);
free(p);
@@ -1396,14 +1348,6 @@ cupsdRenamePrinter(
"cupsdRenamePrinter: Removing %s from Printers", p->name);
cupsArrayRemove(Printers, p);
- if (p->type & CUPS_PRINTER_IMPLICIT)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdRenamePrinter: Removing %s from ImplicitPrinters",
- p->name);
- cupsArrayRemove(ImplicitPrinters, p);
- }
-
/*
* Rename the printer type...
*/
@@ -1436,14 +1380,6 @@ cupsdRenamePrinter(
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"cupsdRenamePrinter: Adding %s to Printers", p->name);
cupsArrayAdd(Printers, p);
-
- if (p->type & CUPS_PRINTER_IMPLICIT)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdRenamePrinter: Adding %s to ImplicitPrinters",
- p->name);
- cupsArrayAdd(ImplicitPrinters, p);
- }
}
@@ -1501,12 +1437,10 @@ cupsdSaveAllPrinters(void)
printer = (cupsd_printer_t *)cupsArrayNext(Printers))
{
/*
- * Skip remote destinations and printer classes...
+ * Skip printer classes...
*/
- if ((printer->type & CUPS_PRINTER_DISCOVERED) ||
- (printer->type & CUPS_PRINTER_CLASS) ||
- (printer->type & CUPS_PRINTER_IMPLICIT))
+ if (printer->type & CUPS_PRINTER_CLASS)
continue;
/*
@@ -2138,27 +2072,14 @@ cupsdSetPrinterAttr(
void
cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
{
- int i, /* Looping var */
- length; /* Length of browse attributes */
+ int i; /* Looping var */
char resource[HTTP_MAX_URI]; /* Resource portion of URI */
- int num_air; /* Number of auth-info-required values */
- const char * const *air; /* auth-info-required values */
cupsd_location_t *auth; /* Pointer to authentication element */
const char *auth_supported; /* Authentication supported */
ipp_t *oldattrs; /* Old printer attributes */
ipp_attribute_t *attr; /* Attribute data */
- cups_option_t *option; /* Current printer option */
char *name, /* Current user/group name */
*filter; /* Current filter */
- static const char * const air_none[] =
- { /* No authentication */
- "none"
- };
- static const char * const air_userpass[] =
- { /* Basic/Digest authentication */
- "username",
- "password"
- };
DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name,
@@ -2182,20 +2103,6 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
*/
auth_supported = "requesting-user-name";
- num_air = 1;
- air = air_none;
-
- if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none"))
- {
- num_air = p->num_auth_info_required;
- air = p->auth_info_required;
- }
- else if ((p->type & CUPS_PRINTER_AUTHENTICATED) &&
- (p->type & CUPS_PRINTER_DISCOVERED))
- {
- num_air = 2;
- air = air_userpass;
- }
if (p->type & CUPS_PRINTER_CLASS)
snprintf(resource, sizeof(resource), "/classes/%s", p->name);
@@ -2212,7 +2119,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT)
- auth_type = DefaultAuthType;
+ auth_type = cupsdDefaultAuthType();
if (auth_type == CUPSD_AUTH_BASIC || auth_type == CUPSD_AUTH_BASICDIGEST)
auth_supported = "basic";
@@ -2223,15 +2130,12 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
auth_supported = "negotiate";
#endif /* HAVE_GSSAPI */
- if (!(p->type & CUPS_PRINTER_DISCOVERED))
- {
- if (auth_type != CUPSD_AUTH_NONE)
- p->type |= CUPS_PRINTER_AUTHENTICATED;
- else
- p->type &= ~CUPS_PRINTER_AUTHENTICATED;
- }
+ if (auth_type != CUPSD_AUTH_NONE)
+ p->type |= CUPS_PRINTER_AUTHENTICATED;
+ else
+ p->type &= ~CUPS_PRINTER_AUTHENTICATED;
}
- else if (!(p->type & CUPS_PRINTER_DISCOVERED))
+ else
p->type &= ~CUPS_PRINTER_AUTHENTICATED;
/*
@@ -2277,10 +2181,12 @@ 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);
- ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "auth-info-required", num_air, NULL, air);
+ if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none"))
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "auth-info-required", p->num_auth_info_required, NULL,
+ p->auth_info_required);
- if (cupsArrayCount(Banners) > 0 && !(p->type & CUPS_PRINTER_DISCOVERED))
+ if (cupsArrayCount(Banners) > 0)
{
/*
* Setup the job-sheets-default attribute...
@@ -2301,164 +2207,117 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
p->raw = 0;
p->remote = 0;
- if (p->type & CUPS_PRINTER_DISCOVERED)
+ /*
+ * Assign additional attributes depending on whether this is a printer
+ * or class...
+ */
+
+ if (p->type & CUPS_PRINTER_CLASS)
{
+ p->raw = 1;
+ p->type &= ~CUPS_PRINTER_OPTIONS;
+
/*
- * Tell the client this is a remote printer of some type...
+ * Add class-specific attributes...
*/
- if (strchr(p->uri, '?'))
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-make-and-model", NULL, "Local Printer Class");
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
+ "file:///dev/null");
+
+ if (p->num_printers > 0)
{
/*
- * Strip trailing "?options" from URI...
+ * Add a list of member names; URIs are added in copy_printer_attrs...
*/
- char *ptr; /* Pointer into URI */
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "member-names", p->num_printers, NULL, NULL);
+ p->type |= CUPS_PRINTER_OPTIONS;
- strlcpy(resource, p->uri, sizeof(resource));
- if ((ptr = strchr(resource, '?')) != NULL)
- *ptr = '\0';
+ for (i = 0; i < p->num_printers; i ++)
+ {
+ if (attr != NULL)
+ attr->values[i].string.text = _cupsStrRetain(p->printers[i]->name);
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI,
- "printer-uri-supported", NULL, resource);
+ p->type &= ~CUPS_PRINTER_OPTIONS | p->printers[i]->type;
+ }
}
- else
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI,
- "printer-uri-supported", NULL, p->uri);
-
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info",
- NULL, p->uri);
-
- if (p->make_model)
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
- "printer-make-and-model", NULL, p->make_model);
-
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
- p->uri);
-
- p->raw = 1;
- p->remote = 1;
}
else
{
/*
- * Assign additional attributes depending on whether this is a printer
- * or class...
+ * Add printer-specific attributes...
*/
- if (p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
- {
- p->raw = 1;
- p->type &= ~CUPS_PRINTER_OPTIONS;
-
- /*
- * Add class-specific attributes...
- */
-
- if ((p->type & CUPS_PRINTER_IMPLICIT) && p->num_printers > 0 &&
- p->printers[0]->make_model)
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
- "printer-make-and-model", NULL, p->printers[0]->make_model);
- else
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
- "printer-make-and-model", NULL, "Local Printer Class");
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
+ p->sanitized_device_uri);
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
- "file:///dev/null");
+ /*
+ * Assign additional attributes from the PPD file (if any)...
+ */
- if (p->num_printers > 0)
- {
- /*
- * Add a list of member names; URIs are added in copy_printer_attrs...
- */
+ load_ppd(p);
- attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
- "member-names", p->num_printers, NULL, NULL);
- p->type |= CUPS_PRINTER_OPTIONS;
+ /*
+ * Add filters for printer...
+ */
- for (i = 0; i < p->num_printers; i ++)
- {
- if (attr != NULL)
- attr->values[i].string.text = _cupsStrRetain(p->printers[i]->name);
+ cupsdSetPrinterReasons(p, "-cups-missing-filter-warning,"
+ "cups-insecure-filter-warning");
- p->type &= ~CUPS_PRINTER_OPTIONS | p->printers[i]->type;
- }
- }
+ if (p->pc && p->pc->filters)
+ {
+ for (filter = (char *)cupsArrayFirst(p->pc->filters);
+ filter;
+ filter = (char *)cupsArrayNext(p->pc->filters))
+ add_printer_filter(p, p->filetype, filter);
}
- else
+ else if (!(p->type & CUPS_PRINTER_REMOTE))
{
- /*
- * Add printer-specific attributes...
- */
+ char interface[1024]; /* Interface script */
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
- p->sanitized_device_uri);
- /*
- * Assign additional attributes from the PPD file (if any)...
- */
-
- load_ppd(p);
-
- /*
- * Add filters for printer...
- */
-
- cupsdSetPrinterReasons(p, "-cups-missing-filter-warning,"
- "cups-insecure-filter-warning");
-
- if (p->pc && p->pc->filters)
+ snprintf(interface, sizeof(interface), "%s/interfaces/%s", ServerRoot,
+ p->name);
+ if (!access(interface, X_OK))
{
- for (filter = (char *)cupsArrayFirst(p->pc->filters);
- filter;
- filter = (char *)cupsArrayNext(p->pc->filters))
- add_printer_filter(p, p->filetype, filter);
+ /*
+ * Yes, we have a System V style interface script; use it!
+ */
+
+ snprintf(interface, sizeof(interface), "*/* 0 %s/interfaces/%s",
+ ServerRoot, p->name);
+ add_printer_filter(p, p->filetype, interface);
}
- else if (!(p->type & CUPS_PRINTER_REMOTE))
+ else
{
- char interface[1024]; /* Interface script */
-
-
- snprintf(interface, sizeof(interface), "%s/interfaces/%s", ServerRoot,
- p->name);
- if (!access(interface, X_OK))
- {
- /*
- * Yes, we have a System V style interface script; use it!
- */
-
- snprintf(interface, sizeof(interface), "*/* 0 %s/interfaces/%s",
- ServerRoot, p->name);
- add_printer_filter(p, p->filetype, interface);
- }
- else
- {
- /*
- * Add a filter from application/vnd.cups-raw to printer/name to
- * handle "raw" printing by users.
- */
+ /*
+ * Add a filter from application/vnd.cups-raw to printer/name to
+ * handle "raw" printing by users.
+ */
- add_printer_filter(p, p->filetype, "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 a PostScript filter, since this is still possibly PS printer.
+ */
- add_printer_filter(p, p->filetype,
- "application/vnd.cups-postscript 0 -");
- }
+ add_printer_filter(p, p->filetype,
+ "application/vnd.cups-postscript 0 -");
}
+ }
- if (p->pc && p->pc->prefilters)
- {
- if (!p->prefiltertype)
- p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", p->name);
+ if (p->pc && p->pc->prefilters)
+ {
+ if (!p->prefiltertype)
+ p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", p->name);
- for (filter = (char *)cupsArrayFirst(p->pc->prefilters);
- filter;
- filter = (char *)cupsArrayNext(p->pc->prefilters))
- add_printer_filter(p, p->prefiltertype, filter);
- }
+ for (filter = (char *)cupsArrayFirst(p->pc->prefilters);
+ filter;
+ filter = (char *)cupsArrayNext(p->pc->prefilters))
+ add_printer_filter(p, p->prefiltertype, filter);
}
}
@@ -2558,98 +2417,8 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
* Force sharing off for remote queues...
*/
- if (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))
+ if (p->type & CUPS_PRINTER_REMOTE)
p->shared = 0;
- else
- {
- /*
- * Copy the printer options into a browse attributes string we can re-use.
- */
-
- const char *valptr; /* Pointer into value */
- char *attrptr; /* Pointer into attribute string */
-
-
- /*
- * Free the old browse attributes as needed...
- */
-
- if (p->browse_attrs)
- free(p->browse_attrs);
-
- /*
- * Compute the length of all attributes + job-sheets, lease-duration,
- * and BrowseLocalOptions.
- */
-
- for (length = 1, i = p->num_options, option = p->options;
- i > 0;
- i --, option ++)
- {
- length += strlen(option->name) + 2;
-
- if (option->value)
- {
- for (valptr = option->value; *valptr; valptr ++)
- if (strchr(" \"\'\\", *valptr))
- length += 2;
- else
- length ++;
- }
- }
-
- length += 13 + strlen(p->job_sheets[0]) + strlen(p->job_sheets[1]);
- length += 32;
- if (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!",
- length);
- else
- {
- /*
- * Got the allocated string, now copy the options and attributes over...
- */
-
- sprintf(p->browse_attrs, "job-sheets=%s,%s lease-duration=%d",
- p->job_sheets[0], p->job_sheets[1], BrowseTimeout);
- attrptr = p->browse_attrs + strlen(p->browse_attrs);
-
- if (BrowseLocalOptions)
- {
- sprintf(attrptr, " ipp-options=%s", BrowseLocalOptions);
- attrptr += strlen(attrptr);
- }
-
- for (i = p->num_options, option = p->options;
- i > 0;
- i --, option ++)
- {
- *attrptr++ = ' ';
- strcpy(attrptr, option->name);
- attrptr += strlen(attrptr);
-
- if (option->value)
- {
- *attrptr++ = '=';
-
- for (valptr = option->value; *valptr; valptr ++)
- {
- if (strchr(" \"\'\\", *valptr))
- *attrptr++ = '\\';
-
- *attrptr++ = *valptr;
- }
- }
- }
- }
- }
/*
* Populate the document-format-supported attribute...
@@ -2832,6 +2601,7 @@ cupsdSetPrinterState(
ipp_pstate_t s, /* I - New state */
int update) /* I - Update printers.conf? */
{
+ cupsd_job_t *job; /* Current job */
ipp_pstate_t old_state; /* Old printer state */
static const char * const printer_states[] =
{ /* State strings */
@@ -2842,13 +2612,6 @@ cupsdSetPrinterState(
/*
- * Can't set status of remote printers...
- */
-
- if (p->type & CUPS_PRINTER_DISCOVERED)
- return;
-
- /*
* Set the new state...
*/
@@ -2867,9 +2630,7 @@ cupsdSetPrinterState(
* Let the browse code know this needs to be updated...
*/
- BrowseNext = p;
- p->state_time = time(NULL);
- p->browse_time = 0;
+ p->state_time = time(NULL);
#ifdef __sgi
write_irix_state(p);
@@ -2885,6 +2646,17 @@ cupsdSetPrinterState(
else
cupsdSetPrinterReasons(p, "-paused");
+ if (old_state != s)
+ {
+ for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
+ job;
+ job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
+ if (job->reasons && job->state_value == IPP_JOB_PENDING &&
+ !_cups_strcasecmp(job->dest, p->name))
+ ippSetString(job->attrs, &job->reasons, 0,
+ s == IPP_PRINTER_STOPPED ? "printer-stopped" : "none");
+ }
+
/*
* Clear the message for the queue when going to processing...
*/
@@ -3068,22 +2840,6 @@ cupsdUpdatePrinters(void)
p = (cupsd_printer_t *)cupsArrayNext(Printers))
{
/*
- * Remove remote printers if we are no longer browsing...
- */
-
- if (!Browsing &&
- (p->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_DISCOVERED)))
- {
- if (p->type & CUPS_PRINTER_IMPLICIT)
- cupsArrayRemove(ImplicitPrinters, p);
-
- cupsArraySave(Printers);
- cupsdDeletePrinter(p, 0);
- cupsArrayRestore(Printers);
- continue;
- }
-
- /*
* Update the operation policy pointer...
*/
@@ -3091,11 +2847,10 @@ cupsdUpdatePrinters(void)
p->op_policy_ptr = DefaultPolicyPtr;
/*
- * Update printer attributes as needed...
+ * Update printer attributes...
*/
- if (!(p->type & CUPS_PRINTER_DISCOVERED))
- cupsdSetPrinterAttrs(p);
+ cupsdSetPrinterAttrs(p);
}
}
@@ -3188,8 +2943,7 @@ cupsdValidateDest(
*printer = p;
if (dtype)
- *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED);
+ *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
return (p->name);
}
@@ -3247,8 +3001,7 @@ cupsdValidateDest(
*printer = p;
if (dtype)
- *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
- CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED);
+ *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
return (p->name);
}
@@ -3797,7 +3550,7 @@ add_printer_formats(cupsd_printer_t *p) /* I - Printer */
attr->values[i].string.text = _cupsStrAlloc(mimetype);
}
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
{
char pdl[1024]; /* Buffer to build pdl list */
mime_filter_t *filter; /* MIME filter looping var */
@@ -3853,7 +3606,7 @@ add_printer_formats(cupsd_printer_t *p) /* I - Printer */
cupsdSetString(&p->pdl, pdl);
}
-#endif /* HAVE_DNSSD */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
}
@@ -3931,9 +3684,7 @@ delete_printer_filters(
static void
dirty_printer(cupsd_printer_t *p) /* I - Printer */
{
- if (p->type & CUPS_PRINTER_DISCOVERED)
- cupsdMarkDirty(CUPSD_DIRTY_REMOTE);
- else if (p->type & CUPS_PRINTER_CLASS)
+ if (p->type & CUPS_PRINTER_CLASS)
cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
else
cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
@@ -3973,7 +3724,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
_pwg_map_t *pwgsource, /* Current PWG source */
*pwgtype; /* Current PWG type */
ipp_attribute_t *attr; /* Attribute data */
- ipp_value_t *val; /* Attribute value */
+ _ipp_value_t *val; /* Attribute value */
int num_finishings, /* Number of finishings */
finishings[5]; /* finishings-supported values */
int num_qualities, /* Number of print-quality values */
@@ -4044,7 +3795,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
p->ppd_attrs = ippNew();
- if ((ppd = ppdOpenFile(ppd_name)) != NULL)
+ if ((ppd = _ppdOpenFile(ppd_name, _PPD_LOCALIZATION_NONE)) != NULL)
{
/*
* Add make/model and other various attributes...
@@ -4233,6 +3984,41 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
}
/*
+ * media-size-supported
+ */
+
+ num_media = p->pc->num_sizes;
+ if (p->pc->custom_min_keyword)
+ num_media ++;
+
+ if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER,
+ "media-size-supported", num_media,
+ NULL)) != NULL)
+ {
+ val = attr->values;
+
+ for (i = p->pc->num_sizes, pwgsize = p->pc->sizes;
+ i > 0;
+ i --, pwgsize ++, val ++)
+ {
+ val->collection = ippNew();
+ ippAddInteger(val->collection, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "x-dimension", pwgsize->width);
+ ippAddInteger(val->collection, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "y-dimension", pwgsize->length);
+ }
+
+ if (p->pc->custom_min_keyword)
+ {
+ val->collection = ippNew();
+ ippAddRange(val->collection, IPP_TAG_PRINTER, "x-dimension",
+ p->pc->custom_min_width, p->pc->custom_max_width);
+ ippAddRange(val->collection, IPP_TAG_PRINTER, "y-dimension",
+ p->pc->custom_min_length, p->pc->custom_max_length);
+ }
+ }
+
+ /*
* media-source-supported
*/
@@ -5021,12 +4807,13 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
"printer-make-and-model", NULL,
"Local System V Printer");
}
- else if (!strncmp(p->device_uri, "ipp://", 6) &&
- (strstr(p->device_uri, "/printers/") != NULL ||
- strstr(p->device_uri, "/classes/") != NULL ||
- (strstr(p->device_uri, "._ipp.") != NULL &&
- !strcmp(p->device_uri + strlen(p->device_uri) - 5,
- "/cups"))))
+ else if (((!strncmp(p->device_uri, "ipp://", 6) ||
+ !strncmp(p->device_uri, "ipps://", 7)) &&
+ (strstr(p->device_uri, "/printers/") != NULL ||
+ strstr(p->device_uri, "/classes/") != NULL)) ||
+ ((strstr(p->device_uri, "._ipp.") != NULL ||
+ strstr(p->device_uri, "._ipps.") != NULL) &&
+ !strcmp(p->device_uri + strlen(p->device_uri) - 5, "/cups")))
{
/*
* Tell the client this is really a hard-wired remote printer.
@@ -5145,6 +4932,8 @@ log_ipp_conformance(
message = "Printer does not support REQUIRED Validate-Job operation.";
else if (!strcmp(reason, "missing-get-printer-attributes"))
message = "Printer does not support REQUIRED Get-Printer-Attributes operation.";
+ else if (!strcmp(reason, "missing-send-document"))
+ message = "Printer supports Create-Job but not Send-Document operation.";
else if (!strcmp(reason, "missing-job-history"))
message = "Printer does not provide REQUIRED job history.";
else if (!strcmp(reason, "missing-job-id"))
@@ -5528,5 +5317,5 @@ write_xml_string(cups_file_t *fp, /* I - File to write to */
/*
- * End of "$Id: printers.c 10295 2012-02-15 23:21:06Z mike $".
+ * End of "$Id: printers.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/printers.h b/scheduler/printers.h
index 5a551a4..ad89d70 100644
--- a/scheduler/printers.h
+++ b/scheduler/printers.h
@@ -1,9 +1,9 @@
/*
- * "$Id: printers.h 9621 2011-03-18 18:42:46Z mike $"
+ * "$Id: printers.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Printer definitions for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -15,6 +15,11 @@
#ifdef HAVE_DNSSD
# include <dns_sd.h>
+#elif defined(HAVE_AVAHI)
+# include <avahi-client/client.h>
+# include <avahi-client/publish.h>
+# include <avahi-common/error.h>
+# include <avahi-common/thread-watch.h>
#endif /* HAVE_DNSSD */
#include <cups/pwg-private.h>
@@ -33,6 +38,20 @@ typedef struct
/*
+ * DNS-SD types to make the code cleaner/clearer...
+ */
+
+#ifdef HAVE_DNSSD
+typedef DNSServiceRef cupsd_srv_t; /* Service reference */
+typedef TXTRecordRef cupsd_txt_t; /* TXT record */
+
+#elif defined(HAVE_AVAHI)
+typedef AvahiEntryGroup *cupsd_srv_t; /* Service reference */
+typedef AvahiStringList *cupsd_txt_t; /* TXT record */
+#endif /* HAVE_DNSSD */
+
+
+/*
* Printer/class information structure...
*/
@@ -61,9 +80,6 @@ struct cupsd_printer_s
time_t state_time; /* Time at this state */
char *job_sheets[2]; /* Banners/job sheets */
cups_ptype_t type; /* Printer type (color, small, etc.) */
- char *browse_attrs; /* Attributes sent with browse data */
- time_t browse_expire; /* Expiration time for printer */
- time_t browse_time; /* Last time update was sent/received */
char *device_uri; /* Device URI */
char *sanitized_device_uri; /* Sanitized device URI */
char *port_monitor; /* Port monitor */
@@ -95,16 +111,17 @@ struct cupsd_printer_s
time_t marker_time; /* Last time marker attributes were updated */
_ppd_cache_t *pc; /* PPD cache and mapping data */
-#ifdef HAVE_DNSSD
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
char *reg_name, /* Name used for service registration */
- *pdl, /* pdl value for TXT record */
- *ipp_txt, /* IPP TXT record contents */
- *printer_txt; /* LPD TXT record contents */
- int ipp_len, /* IPP TXT record length */
- printer_len; /* LPD TXT record length */
- DNSServiceRef ipp_ref, /* Reference for _ipp._tcp,_cups */
- printer_ref; /* Reference for _printer._tcp */
-#endif /* HAVE_DNSSD */
+ *pdl; /* pdl value for TXT record */
+ cupsd_srv_t ipp_srv; /* IPP service(s) */
+# ifdef HAVE_DNSSD
+# ifdef HAVE_SSL
+ cupsd_srv_t ipps_srv; /* IPPS service(s) */
+# endif /* HAVE_SSL */
+ cupsd_srv_t printer_srv; /* LPD service */
+# endif /* HAVE_DNSSD */
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
};
@@ -116,10 +133,8 @@ 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),
+VAR cups_array_t *Printers VALUE(NULL);
/* Printer list */
- *ImplicitPrinters VALUE(NULL);
- /* Implicit class printers */
VAR cupsd_printer_t *DefaultPrinter VALUE(NULL);
/* Default printer */
VAR char *DefaultPolicy VALUE(NULL);
@@ -157,7 +172,8 @@ extern int 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))
+#define cupsdStartPrinter(p,u) cupsdSetPrinterState((p), \
+ IPP_PRINTER_IDLE, (u))
extern void cupsdStopPrinter(cupsd_printer_t *p, int update);
extern int cupsdUpdatePrinterPPD(cupsd_printer_t *p,
int num_keywords,
@@ -173,5 +189,5 @@ extern void cupsdWritePrintcap(void);
/*
- * End of "$Id: printers.h 9621 2011-03-18 18:42:46Z mike $".
+ * End of "$Id: printers.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/process.c b/scheduler/process.c
index c1ca526..a706ac2 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -1,9 +1,9 @@
/*
- * "$Id: process.c 9790 2011-05-19 22:40:03Z mike $"
+ * "$Id: process.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Process management routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -365,8 +365,8 @@ cupsdStartProcess(
if (envp)
{
/*
- * Add special voodoo magic for Mac OS X - this allows Mac OS X
- * programs to access their bundle resources properly...
+ * Add special voodoo magic for OS X - this allows OS X programs to access
+ * their bundle resources properly...
*/
if ((linkbytes = readlink(command, linkpath, sizeof(linkpath) - 1)) > 0)
@@ -577,7 +577,7 @@ cupsdStartProcess(
{
if (!process_array)
process_array = cupsArrayNew((cups_array_func_t)compare_procs, NULL);
-
+
if (process_array)
{
if ((proc = calloc(1, sizeof(cupsd_proc_t) + strlen(command))) != NULL)
@@ -652,5 +652,5 @@ cupsd_requote(char *dst, /* I - Destination buffer */
/*
- * End of "$Id: process.c 9790 2011-05-19 22:40:03Z mike $".
+ * End of "$Id: process.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/quotas.c b/scheduler/quotas.c
index 5051756..3ebfd8d 100644
--- a/scheduler/quotas.c
+++ b/scheduler/quotas.c
@@ -1,5 +1,5 @@
/*
- * "$Id: quotas.c 9793 2011-05-20 03:49:49Z mike $"
+ * "$Id: quotas.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Quota routines for the CUPS scheduler.
*
@@ -240,5 +240,5 @@ compare_quotas(const cupsd_quota_t *q1, /* I - First quota record */
/*
- * End of "$Id: quotas.c 9793 2011-05-20 03:49:49Z mike $".
+ * End of "$Id: quotas.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/select.c b/scheduler/select.c
index 99a2325..e2f40d8 100644
--- a/scheduler/select.c
+++ b/scheduler/select.c
@@ -1,5 +1,5 @@
/*
- * "$Id: select.c 9350 2010-11-04 23:23:25Z mike $"
+ * "$Id: select.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Select abstraction functions for the CUPS scheduler.
*
@@ -33,12 +33,12 @@
#ifdef HAVE_EPOLL
# include <sys/epoll.h>
-# include <sys/poll.h>
+# include <poll.h>
#elif defined(HAVE_KQUEUE)
# include <sys/event.h>
# include <sys/time.h>
#elif defined(HAVE_POLL)
-# include <sys/poll.h>
+# include <poll.h>
#elif defined(__hpux)
# include <sys/time.h>
#else
@@ -947,5 +947,5 @@ find_fd(int fd) /* I - File descriptor */
/*
- * End of "$Id: select.c 9350 2010-11-04 23:23:25Z mike $".
+ * End of "$Id: select.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/server.c b/scheduler/server.c
index ace9cc9..7e511c4 100644
--- a/scheduler/server.c
+++ b/scheduler/server.c
@@ -1,9 +1,9 @@
/*
- * "$Id: server.c 9632 2011-03-21 02:12:14Z mike $"
+ * "$Id: server.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Server start/stop routines for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -45,6 +45,12 @@ void
cupsdStartServer(void)
{
/*
+ * Start color management (as needed)...
+ */
+
+ cupsdStartColor();
+
+ /*
* Create the default security profile...
*/
@@ -56,7 +62,6 @@ cupsdStartServer(void)
cupsdStartListening();
cupsdStartBrowsing();
- cupsdStartPolling();
/*
* Create a pipe for CGI processes...
@@ -95,12 +100,17 @@ cupsdStopServer(void)
return;
/*
- * Close all network clients and stop all jobs...
+ * Stop color management (as needed)...
+ */
+
+ cupsdStopColor();
+
+ /*
+ * Close all network clients...
*/
cupsdCloseAllClients();
cupsdStopListening();
- cupsdStopPolling();
cupsdStopBrowsing();
cupsdStopAllNotifiers();
cupsdDeleteAllCerts();
@@ -126,16 +136,6 @@ cupsdStopServer(void)
CGIPipes[1] = -1;
}
-#ifdef HAVE_NOTIFY_POST
- /*
- * Send one last notification as the server shuts down.
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "notify_post(\"com.apple.printerListChange\") last");
- notify_post("com.apple.printerListChange");
-#endif /* HAVE_NOTIFY_POST */
-
/*
* Close all log files...
*/
@@ -180,5 +180,5 @@ cupsdStopServer(void)
/*
- * End of "$Id: server.c 9632 2011-03-21 02:12:14Z mike $".
+ * End of "$Id: server.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/statbuf.c b/scheduler/statbuf.c
index cb75877..7f99149 100644
--- a/scheduler/statbuf.c
+++ b/scheduler/statbuf.c
@@ -1,5 +1,5 @@
/*
- * "$Id: statbuf.c 9350 2010-11-04 23:23:25Z mike $"
+ * "$Id: statbuf.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Status buffer routines for the CUPS scheduler.
*
@@ -326,5 +326,5 @@ cupsdStatBufUpdate(
/*
- * End of "$Id: statbuf.c 9350 2010-11-04 23:23:25Z mike $".
+ * End of "$Id: statbuf.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/statbuf.h b/scheduler/statbuf.h
index acb793d..91564d0 100644
--- a/scheduler/statbuf.h
+++ b/scheduler/statbuf.h
@@ -1,5 +1,5 @@
/*
- * "$Id: statbuf.h 9350 2010-11-04 23:23:25Z mike $"
+ * "$Id: statbuf.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Status buffer definitions for the CUPS scheduler.
*
@@ -45,5 +45,5 @@ extern char *cupsdStatBufUpdate(cupsd_statbuf_t *sb, int *loglevel,
/*
- * End of "$Id: statbuf.h 9350 2010-11-04 23:23:25Z mike $".
+ * End of "$Id: statbuf.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/subscriptions.c b/scheduler/subscriptions.c
index e1e8219..0b9c452 100644
--- a/scheduler/subscriptions.c
+++ b/scheduler/subscriptions.c
@@ -1,5 +1,5 @@
/*
- * "$Id: subscriptions.c 10262 2012-02-12 05:48:09Z mike $"
+ * "$Id: subscriptions.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Subscription routines for the CUPS scheduler.
*
@@ -1638,5 +1638,5 @@ cupsd_update_notifier(void)
/*
- * End of "$Id: subscriptions.c 10262 2012-02-12 05:48:09Z mike $".
+ * End of "$Id: subscriptions.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/subscriptions.h b/scheduler/subscriptions.h
index 20d59b7..1a786ae 100644
--- a/scheduler/subscriptions.h
+++ b/scheduler/subscriptions.h
@@ -1,5 +1,5 @@
/*
- * "$Id: subscriptions.h 9350 2010-11-04 23:23:25Z mike $"
+ * "$Id: subscriptions.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Subscription definitions for the CUPS scheduler.
*
@@ -162,5 +162,5 @@ extern void cupsdStopAllNotifiers(void);
/*
- * End of "$Id: subscriptions.h 9350 2010-11-04 23:23:25Z mike $".
+ * End of "$Id: subscriptions.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/sysman.c b/scheduler/sysman.c
index bd7052b..d5f82c1 100644
--- a/scheduler/sysman.c
+++ b/scheduler/sysman.c
@@ -1,9 +1,9 @@
/*
- * "$Id: sysman.c 10273 2012-02-13 20:30:23Z mike $"
+ * "$Id: sysman.c 11173 2013-07-23 12:31:34Z msweet $"
*
* System management functions for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -87,9 +87,6 @@ cupsdCleanDirty(void)
if (DirtyFiles & CUPSD_DIRTY_CLASSES)
cupsdSaveAllClasses();
- if (DirtyFiles & CUPSD_DIRTY_REMOTE)
- cupsdSaveRemoteCache();
-
if (DirtyFiles & CUPSD_DIRTY_PRINTCAP)
cupsdWritePrintcap();
@@ -123,10 +120,9 @@ cupsdCleanDirty(void)
void
cupsdMarkDirty(int what) /* I - What file(s) are dirty? */
{
- cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdMarkDirty(%c%c%c%c%c%c)",
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdMarkDirty(%c%c%c%c%c)",
(what & CUPSD_DIRTY_PRINTERS) ? 'P' : '-',
(what & CUPSD_DIRTY_CLASSES) ? 'C' : '-',
- (what & CUPSD_DIRTY_REMOTE) ? 'R' : '-',
(what & CUPSD_DIRTY_PRINTCAP) ? 'p' : '-',
(what & CUPSD_DIRTY_JOBS) ? 'J' : '-',
(what & CUPSD_DIRTY_SUBSCRIPTIONS) ? 'S' : '-');
@@ -865,20 +861,9 @@ sysUpdate(void)
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
{
- if (p->type & CUPS_PRINTER_DISCOVERED)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Deleting remote destination \"%s\"", p->name);
- cupsArraySave(Printers);
- cupsdDeletePrinter(p, 0);
- cupsArrayRestore(Printers);
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Deregistering local printer \"%s\"", p->name);
- cupsdDeregisterPrinter(p, 0);
- }
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Deregistering local printer \"%s\"", p->name);
+ cupsdDeregisterPrinter(p, 0);
}
cupsdCleanDirty();
@@ -965,23 +950,8 @@ sysUpdate(void)
if (sysevent.event & SYSEVENT_NETCHANGED)
{
if (!Sleeping)
- {
cupsdLogMessage(CUPSD_LOG_DEBUG,
"System network configuration changed");
-
- /*
- * Resetting browse_time before calling cupsdSendBrowseList causes
- * browse packets to be sent for local shared printers.
- */
-
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- p->browse_time = 0;
-
- cupsdSendBrowseList();
- cupsdRestartPolling();
- }
else
cupsdLogMessage(CUPSD_LOG_DEBUG,
"System network configuration changed; "
@@ -1004,11 +974,13 @@ sysUpdate(void)
p = (cupsd_printer_t *)cupsArrayNext(Printers))
cupsdDeregisterPrinter(p, 1);
+# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
/*
* Update the computer name and BTMM domain list...
*/
cupsdUpdateDNSSDName();
+# endif /* HAVE_DNSSD || HAVE_AVAHI */
/*
* Now re-register them...
@@ -1017,10 +989,7 @@ sysUpdate(void)
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,
@@ -1033,5 +1002,5 @@ sysUpdate(void)
/*
- * End of "$Id: sysman.c 10273 2012-02-13 20:30:23Z mike $".
+ * End of "$Id: sysman.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/sysman.h b/scheduler/sysman.h
index b47655f..d603178 100644
--- a/scheduler/sysman.h
+++ b/scheduler/sysman.h
@@ -1,9 +1,9 @@
/*
- * "$Id: sysman.h 9350 2010-11-04 23:23:25Z mike $"
+ * "$Id: sysman.h 11173 2013-07-23 12:31:34Z msweet $"
*
* System management definitions for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2011 by Apple Inc.
* Copyright 2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -20,10 +20,10 @@
#define CUPSD_DIRTY_NONE 0 /* Nothing is dirty */
#define CUPSD_DIRTY_PRINTERS 1 /* printers.conf is dirty */
#define CUPSD_DIRTY_CLASSES 2 /* classes.conf is dirty */
-#define CUPSD_DIRTY_REMOTE 4 /* remote.cache is dirty */
-#define CUPSD_DIRTY_PRINTCAP 8 /* printcap is dirty */
-#define CUPSD_DIRTY_JOBS 16 /* jobs.cache or "c" file(s) are dirty */
-#define CUPSD_DIRTY_SUBSCRIPTIONS 32 /* subscriptions.conf is dirty */
+#define CUPSD_DIRTY_PRINTCAP 4 /* printcap is dirty */
+#define CUPSD_DIRTY_JOBS 8 /* jobs.cache or "c" file(s) are dirty */
+#define CUPSD_DIRTY_SUBSCRIPTIONS 16 /* subscriptions.conf is dirty */
+
/*
* Globals...
@@ -60,5 +60,5 @@ extern void cupsdStopSystemMonitor(void);
/*
- * End of "$Id: sysman.h 9350 2010-11-04 23:23:25Z mike $".
+ * End of "$Id: sysman.h 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/testdirsvc.c b/scheduler/testdirsvc.c
deleted file mode 100644
index 3ffaf3b..0000000
--- a/scheduler/testdirsvc.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * "$Id: testdirsvc.c 9691 2011-04-15 23:38:13Z mike $"
- *
- * Browsing test program for CUPS.
- *
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
- *
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * main() - Simulate one or more remote printers.
- * usage() - Show program usage...
- */
-
-/*
- * Include necessary headers...
- */
-
-#include <cups/cups.h>
-#include <cups/string-private.h>
-
-
-/*
- * Local functions...
- */
-
-static void usage(void);
-
-
-/*
- * 'main()' - Simulate one or more remote printers.
- */
-
-int /* O - Exit status */
-main(int argc, /* I - Number of command-line arguments */
- char *argv[]) /* I - Command-line arguments */
-{
- int i, /* Looping var */
- printer, /* Current printer */
- num_printers, /* Number of printers */
- pclass, /* Current printer class */
- num_pclasses, /* Number of printer classes */
- server, /* Current server */
- num_servers, /* Number of servers */
- count, /* Number of printers sent this cycle */
- interval, /* Browse Interval */
- lease, /* Browse lease-duration */
- continuous, /* Run continuously? */
- port, /* Browse port */
- sock, /* Browse socket */
- val, /* Socket option value */
- seconds, /* Seconds until next cycle */
- verbose; /* Verbose output? */
- const char *options; /* Options for URIs */
- time_t curtime; /* Current UNIX time */
- struct tm *curdate; /* Current date and time */
- struct sockaddr_in addr; /* Broadcast address */
- char packet[1540]; /* Data packet */
- static const char * const names[26] = /* Printer names */
- {
- "alpha",
- "bravo",
- "charlie",
- "delta",
- "echo",
- "foxtrot",
- "golf",
- "hotel",
- "india",
- "juliet",
- "kilo",
- "lima",
- "mike",
- "november",
- "oscar",
- "papa",
- "quebec",
- "romeo",
- "sierra",
- "tango",
- "uniform",
- "victor",
- "wiskey",
- "x-ray",
- "yankee",
- "zulu"
- };
-
-
- /*
- * Process command-line arguments...
- */
-
- num_printers = 10;
- num_pclasses = 5;
- num_servers = 1;
- interval = 30;
- lease = 60;
- port = 0;
- verbose = 0;
- continuous = 0;
- options = NULL;
-
- for (i = 1; i < argc; i ++)
- {
- if (!strcmp(argv[i], "-c"))
- continuous = 1;
- else if (!strcmp(argv[i], "-i"))
- {
- i ++;
- if (i < argc)
- interval = atoi(argv[i]);
- else
- usage();
-
- continuous = 1;
- }
- else if (!strcmp(argv[i], "-l"))
- {
- i ++;
- if (i < argc)
- lease = atoi(argv[i]);
- else
- usage();
- }
- else if (!strcmp(argv[i], "-o"))
- {
- i ++;
- if (i < argc)
- options = argv[i];
- else
- usage();
- }
- else if (!strcmp(argv[i], "-C"))
- {
- i ++;
- if (i < argc)
- num_pclasses = atoi(argv[i]);
- else
- usage();
- }
- else if (!strcmp(argv[i], "-p"))
- {
- i ++;
- if (i < argc)
- num_printers = atoi(argv[i]);
- else
- usage();
- }
- else if (!strcmp(argv[i], "-s"))
- {
- i ++;
- if (i < argc)
- num_servers = atoi(argv[i]);
- else
- usage();
- }
- else if (!strcmp(argv[i], "-v"))
- verbose = 1;
- else if (isdigit(argv[i][0] & 255))
- {
- port = atoi(argv[i]);
- }
- else
- usage();
- }
-
- if ((num_printers <= 0 && num_pclasses <= 0) || num_servers <= 0 ||
- interval <= 0 || lease < 1 || port <= 0)
- usage();
-
- /*
- * Open a broadcast socket...
- */
-
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("Unable to open broadcast socket");
- return (1);
- }
-
- /*
- * Set the "broadcast" flag...
- */
-
- val = 1;
- if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
- {
- perror("Unable to put socket in broadcast mode");
-
- close(sock);
- return (1);
- }
-
- /*
- * Broadcast to 127.0.0.1 (localhost)
- */
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_addr.s_addr = htonl(0x7f000001);
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
-
- /*
- * Send virtual printers continuously until we are stopped.
- */
-
- for (;;)
- {
- /*
- * Start a new cycle of N printers...
- */
-
- printf("Sending %d printers from %d servers...\n", num_printers,
- num_servers);
-
- count = num_servers * (num_printers + num_pclasses) / interval + 1;
- curtime = time(NULL);
- curdate = localtime(&curtime);
- seconds = interval;
-
- for (i = 0, printer = 0; printer < num_printers; printer ++)
- {
- for (server = 0; server < num_servers; server ++, i ++)
- {
- if (i == count)
- {
- seconds --;
- i = 0;
- sleep(1);
- curtime = time(NULL);
- curdate = localtime(&curtime);
- }
-
- snprintf(packet, sizeof(packet),
- "%x %x ipp://testserver-%d/printers/%s-%d \"Server Room %d\" "
- "\"Test Printer %d\" \"Acme Blazer 2000\"%s%s "
- "lease-duration=%d\n",
- CUPS_PRINTER_REMOTE, IPP_PRINTER_IDLE, server + 1,
- names[printer % 26], printer / 26 + 1, server + 1,
- printer + 1, options ? " ipp-options=" : "",
- options ? options : "", lease);
-
- if (verbose)
- printf("[%02d:%02d:%02d] %s", curdate->tm_hour, curdate->tm_min,
- curdate->tm_sec, packet);
-
- if (sendto(sock, packet, strlen(packet), 0,
- (struct sockaddr *)&addr, sizeof(addr)) < 0)
- perror("Unabled to send packet");
- }
- }
-
-
- for (i = 0, pclass = 0; pclass < num_pclasses; pclass ++)
- {
- for (server = 0; server < num_servers; server ++, i ++)
- {
- if (i == count)
- {
- seconds --;
- i = 0;
- sleep(1);
- curtime = time(NULL);
- curdate = localtime(&curtime);
- }
-
- snprintf(packet, sizeof(packet),
- "%x %x ipp://testserver-%d/classes/class-%s-%d \"Server Room %d\" "
- "\"Test Class %d\" \"Acme Blazer 2000\"%s%s "
- "lease-duration=%d\n",
- CUPS_PRINTER_REMOTE | CUPS_PRINTER_CLASS, IPP_PRINTER_IDLE,
- server + 1, names[pclass % 26], pclass / 26 + 1, server + 1,
- pclass + 1, options ? " ipp-options=" : "",
- options ? options : "", lease);
-
- if (verbose)
- printf("[%02d:%02d:%02d] %s", curdate->tm_hour, curdate->tm_min,
- curdate->tm_sec, packet);
-
- if (sendto(sock, packet, strlen(packet), 0,
- (struct sockaddr *)&addr, sizeof(addr)) < 0)
- perror("Unabled to send packet");
- }
- }
-
- if (!continuous)
- break;
-
- /*
- * Sleep for any remaining time...
- */
-
- if (seconds > 0)
- sleep(seconds);
- }
-
- return (0);
-}
-
-
-/*
- * 'usage()' - Show program usage...
- */
-
-static void
-usage(void)
-{
- puts("Usage: testdirsvc [-c] [-i interval] [-l lease-duration] "
- "[-o ipp-options] [-p printers] "
- "[-C classes] [-s servers] [-v] port");
- exit(0);
-}
-
-
-/*
- * End of "$Id: testdirsvc.c 9691 2011-04-15 23:38:13Z mike $".
- */
diff --git a/scheduler/testlpd.c b/scheduler/testlpd.c
index a7302ca..3ff483e 100644
--- a/scheduler/testlpd.c
+++ b/scheduler/testlpd.c
@@ -1,5 +1,5 @@
/*
- * "$Id: testlpd.c 9042 2010-03-24 00:45:34Z mike $"
+ * "$Id: testlpd.c 11173 2013-07-23 12:31:34Z msweet $"
*
* cups-lpd test program for CUPS.
*
@@ -47,7 +47,7 @@ static int print_waiting(int outfd, int infd, char *dest);
static int remove_job(int outfd, int infd, char *dest, char **args);
static int status_long(int outfd, int infd, char *dest, char **args);
static int status_short(int outfd, int infd, char *dest, char **args);
-static void usage(void);
+static void usage(void) __attribute__((noreturn));
/*
@@ -546,5 +546,5 @@ usage(void)
/*
- * End of "$Id: testlpd.c 9042 2010-03-24 00:45:34Z mike $".
+ * End of "$Id: testlpd.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/testmime.c b/scheduler/testmime.c
index de49544..5a71ea9 100644
--- a/scheduler/testmime.c
+++ b/scheduler/testmime.c
@@ -1,9 +1,9 @@
/*
- * "$Id: testmime.c 9862 2011-08-03 02:44:09Z mike $"
+ * "$Id: testmime.c 11173 2013-07-23 12:31:34Z msweet $"
*
* MIME test program for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2013 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -132,7 +132,7 @@ main(int argc, /* I - Number of command-line args */
}
else
{
- sscanf(argv[i], "%15[^/]/%31s", super, type);
+ sscanf(argv[i], "%15[^/]/%255s", super, type);
dst = mimeType(mime, super, type);
filters = mimeFilter2(mime, src, srcinfo.st_size, dst, &cost);
@@ -527,5 +527,5 @@ type_dir(mime_t *mime, /* I - MIME database */
/*
- * End of "$Id: testmime.c 9862 2011-08-03 02:44:09Z mike $".
+ * End of "$Id: testmime.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/testspeed.c b/scheduler/testspeed.c
index 1fe0a33..425f471 100644
--- a/scheduler/testspeed.c
+++ b/scheduler/testspeed.c
@@ -1,5 +1,5 @@
/*
- * "$Id: testspeed.c 9042 2010-03-24 00:45:34Z mike $"
+ * "$Id: testspeed.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Scheduler speed test for CUPS.
*
@@ -40,7 +40,7 @@
static int do_test(const char *server, int port,
http_encryption_t encryption, int requests,
int verbose);
-static void usage(void);
+static void usage(void) __attribute__((noreturn));
/*
@@ -361,5 +361,5 @@ usage(void)
/*
- * End of "$Id: testspeed.c 9042 2010-03-24 00:45:34Z mike $".
+ * End of "$Id: testspeed.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/testsub.c b/scheduler/testsub.c
index bff8e8b..66801af 100644
--- a/scheduler/testsub.c
+++ b/scheduler/testsub.c
@@ -1,9 +1,9 @@
/*
- * "$Id: testsub.c 9042 2010-03-24 00:45:34Z mike $"
+ * "$Id: testsub.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Scheduler notification tester for CUPS.
*
- * Copyright 2007-2010 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 2006-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -28,6 +28,7 @@
#include <cups/debug-private.h>
#include <cups/string-private.h>
#include <signal.h>
+#include <cups/ipp-private.h> /* TODO: Update so we don't need this */
/*
@@ -43,7 +44,7 @@ static int terminate = 0;
static void print_attributes(ipp_t *ipp, int indent);
static void sigterm_handler(int sig);
-static void usage(void);
+static void usage(void) __attribute__((noreturn));
/*
@@ -302,7 +303,7 @@ print_attributes(ipp_t *ipp, /* I - IPP request */
int i; /* Looping var */
ipp_tag_t group; /* Current group */
ipp_attribute_t *attr; /* Current attribute */
- ipp_value_t *val; /* Current value */
+ _ipp_value_t *val; /* Current value */
static const char * const tags[] = /* Value/group tag strings */
{
"reserved-00",
@@ -452,7 +453,7 @@ print_attributes(ipp_t *ipp, /* I - IPP request */
case IPP_TAG_RESOLUTION :
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
printf(" %dx%d%s", val->resolution.xres, val->resolution.yres,
- val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc");
+ val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
putchar('\n');
break;
@@ -518,5 +519,5 @@ usage(void)
/*
- * End of "$Id: testsub.c 9042 2010-03-24 00:45:34Z mike $".
+ * End of "$Id: testsub.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/tls-darwin.c b/scheduler/tls-darwin.c
new file mode 100644
index 0000000..bb6998b
--- /dev/null
+++ b/scheduler/tls-darwin.c
@@ -0,0 +1,570 @@
+/*
+ * "$Id: tls-darwin.c 11173 2013-07-23 12:31:34Z msweet $"
+ *
+ * TLS support code for the CUPS scheduler on OS X.
+ *
+ * Copyright 2007-2012 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ *
+ * Contents:
+ *
+ * cupsdEndTLS() - Shutdown a secure session with the client.
+ * cupsdStartTLS() - Start a secure session with the client.
+ * copy_cdsa_certificate() - Copy a SSL/TLS certificate from the System
+ * keychain.
+ * make_certificate() - Make a self-signed SSL/TLS certificate.
+ */
+
+
+/*
+ * Local functions...
+ */
+
+static CFArrayRef copy_cdsa_certificate(cupsd_client_t *con);
+static int make_certificate(cupsd_client_t *con);
+
+
+/*
+ * 'cupsdEndTLS()' - Shutdown a secure session with the client.
+ */
+
+int /* O - 1 on success, 0 on error */
+cupsdEndTLS(cupsd_client_t *con) /* I - Client connection */
+{
+ while (SSLClose(con->http.tls) == errSSLWouldBlock)
+ usleep(1000);
+
+ SSLDisposeContext(con->http.tls);
+ con->http.tls = NULL;
+
+ if (con->http.tls_credentials)
+ CFRelease(con->http.tls_credentials);
+
+ return (1);
+}
+
+
+/*
+ * 'cupsdStartTLS()' - Start a secure session with the client.
+ */
+
+int /* O - 1 on success, 0 on error */
+cupsdStartTLS(cupsd_client_t *con) /* I - Client connection */
+{
+ OSStatus error = 0; /* Error code */
+ CFArrayRef peerCerts; /* Peer certificates */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.",
+ con->http.fd);
+
+ con->http.tls_credentials = copy_cdsa_certificate(con);
+
+ if (!con->http.tls_credentials)
+ {
+ /*
+ * No keychain (yet), make a self-signed certificate...
+ */
+
+ if (make_certificate(con))
+ con->http.tls_credentials = copy_cdsa_certificate(con);
+ }
+
+ if (!con->http.tls_credentials)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Could not find signing key in keychain \"%s\"",
+ ServerCertificate);
+ error = errSSLBadConfiguration;
+ }
+
+ if (!error)
+ error = SSLNewContext(true, &con->http.tls);
+
+ if (!error)
+ error = SSLSetIOFuncs(con->http.tls, _httpReadCDSA, _httpWriteCDSA);
+
+ if (!error)
+ error = SSLSetConnection(con->http.tls, HTTP(con));
+
+ if (!error)
+ error = SSLSetAllowsExpiredCerts(con->http.tls, true);
+
+ if (!error)
+ error = SSLSetAllowsAnyRoot(con->http.tls, true);
+
+ if (!error)
+ error = SSLSetCertificate(con->http.tls, con->http.tls_credentials);
+
+ if (!error)
+ {
+ /*
+ * Perform SSL/TLS handshake
+ */
+
+ while ((error = SSLHandshake(con->http.tls)) == errSSLWouldBlock)
+ usleep(1000);
+ }
+
+ if (error)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to encrypt connection from %s - %s (%d)",
+ con->http.hostname, cssmErrorString(error), (int)error);
+
+ con->http.error = error;
+ con->http.status = HTTP_ERROR;
+
+ if (con->http.tls)
+ {
+ SSLDisposeContext(con->http.tls);
+ con->http.tls = NULL;
+ }
+
+ if (con->http.tls_credentials)
+ {
+ CFRelease(con->http.tls_credentials);
+ con->http.tls_credentials = NULL;
+ }
+
+ return (0);
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
+ con->http.hostname);
+
+ if (!SSLCopyPeerCertificates(con->http.tls, &peerCerts) && peerCerts)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates!",
+ (int)CFArrayGetCount(peerCerts));
+ CFRelease(peerCerts);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Received NO peer certificates!");
+
+ return (1);
+}
+
+
+/*
+ * 'copy_cdsa_certificate()' - Copy a SSL/TLS certificate from the System
+ * keychain.
+ */
+
+static CFArrayRef /* O - Array of certificates */
+copy_cdsa_certificate(
+ cupsd_client_t *con) /* I - Client connection */
+{
+ OSStatus err; /* Error info */
+ SecKeychainRef keychain = NULL;/* Keychain reference */
+ SecIdentitySearchRef search = NULL; /* Search reference */
+ SecIdentityRef identity = NULL;/* Identity */
+ CFArrayRef certificates = NULL;
+ /* Certificate array */
+# if HAVE_SECPOLICYCREATESSL
+ SecPolicyRef policy = NULL; /* Policy ref */
+ CFStringRef servername = NULL;
+ /* Server name */
+ CFMutableDictionaryRef query = NULL; /* Query qualifiers */
+ CFArrayRef list = NULL; /* Keychain list */
+# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ char localname[1024];/* Local hostname */
+# endif /* HAVE_DNSSD || HAVE_AVAHI */
+# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
+ SecPolicyRef policy = NULL; /* Policy ref */
+ SecPolicySearchRef policy_search = NULL;
+ /* Policy search ref */
+ CSSM_DATA options; /* Policy options */
+ CSSM_APPLE_TP_SSL_OPTIONS
+ ssl_options; /* SSL Option for hostname */
+ char localname[1024];/* Local hostname */
+# endif /* HAVE_SECPOLICYCREATESSL */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "copy_cdsa_certificate: Looking for certs for \"%s\"...",
+ con->servername);
+
+ if ((err = SecKeychainOpen(ServerCertificate, &keychain)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot open keychain \"%s\" - %s (%d)",
+ ServerCertificate, cssmErrorString(err), (int)err);
+ goto cleanup;
+ }
+
+# if HAVE_SECPOLICYCREATESSL
+ servername = CFStringCreateWithCString(kCFAllocatorDefault, con->servername,
+ kCFStringEncodingUTF8);
+
+ policy = SecPolicyCreateSSL(1, servername);
+
+ if (servername)
+ CFRelease(servername);
+
+ if (!policy)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
+ goto cleanup;
+ }
+
+ if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create query dictionary");
+ goto cleanup;
+ }
+
+ list = CFArrayCreate(kCFAllocatorDefault, (const void **)&keychain, 1,
+ &kCFTypeArrayCallBacks);
+
+ CFDictionaryAddValue(query, kSecClass, kSecClassIdentity);
+ CFDictionaryAddValue(query, kSecMatchPolicy, policy);
+ CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue);
+ CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne);
+ CFDictionaryAddValue(query, kSecMatchSearchList, list);
+
+ CFRelease(list);
+
+ err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
+
+# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ if (err && DNSSDHostName)
+ {
+ /*
+ * Search for the connection server name failed; try the DNS-SD .local
+ * hostname instead...
+ */
+
+ snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "copy_cdsa_certificate: Looking for certs for \"%s\"...",
+ localname);
+
+ servername = CFStringCreateWithCString(kCFAllocatorDefault, localname,
+ kCFStringEncodingUTF8);
+
+ CFRelease(policy);
+
+ policy = SecPolicyCreateSSL(1, servername);
+
+ if (servername)
+ CFRelease(servername);
+
+ if (!policy)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference");
+ goto cleanup;
+ }
+
+ CFDictionarySetValue(query, kSecMatchPolicy, policy);
+
+ err = SecItemCopyMatching(query, (CFTypeRef *)&identity);
+ }
+# endif /* HAVE_DNSSD || HAVE_AVAHI */
+
+ if (err)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Cannot find signing key in keychain \"%s\": %s (%d)",
+ ServerCertificate, cssmErrorString(err), (int)err);
+ goto cleanup;
+ }
+
+# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
+ /*
+ * Use a policy to search for valid certificates whose common name matches the
+ * servername...
+ */
+
+ if (SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL,
+ NULL, &policy_search))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create a policy search reference");
+ goto cleanup;
+ }
+
+ if (SecPolicySearchCopyNext(policy_search, &policy))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Cannot find a policy to use for searching");
+ goto cleanup;
+ }
+
+ memset(&ssl_options, 0, sizeof(ssl_options));
+ ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION;
+ ssl_options.ServerName = con->servername;
+ ssl_options.ServerNameLen = strlen(con->servername);
+
+ options.Data = (uint8 *)&ssl_options;
+ options.Length = sizeof(ssl_options);
+
+ if (SecPolicySetValue(policy, &options))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Cannot set policy value to use for searching");
+ goto cleanup;
+ }
+
+ if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
+ keychain, FALSE, &search)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Cannot create identity search reference: %s (%d)",
+ cssmErrorString(err), (int)err);
+ goto cleanup;
+ }
+
+ err = SecIdentitySearchCopyNext(search, &identity);
+
+# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ if (err && DNSSDHostName)
+ {
+ /*
+ * Search for the connection server name failed; try the DNS-SD .local
+ * hostname instead...
+ */
+
+ snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
+
+ ssl_options.ServerName = localname;
+ ssl_options.ServerNameLen = strlen(localname);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "copy_cdsa_certificate: Looking for certs for \"%s\"...",
+ localname);
+
+ if (SecPolicySetValue(policy, &options))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Cannot set policy value to use for searching");
+ goto cleanup;
+ }
+
+ CFRelease(search);
+ search = NULL;
+ if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN,
+ keychain, FALSE, &search)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Cannot create identity search reference: %s (%d)",
+ cssmErrorString(err), (int)err);
+ goto cleanup;
+ }
+
+ err = SecIdentitySearchCopyNext(search, &identity);
+
+ }
+# endif /* HAVE_DNSSD || HAVE_AVAHI */
+
+ if (err)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Cannot find signing key in keychain \"%s\": %s (%d)",
+ ServerCertificate, cssmErrorString(err), (int)err);
+ goto cleanup;
+ }
+
+# else
+ /*
+ * Assume there is exactly one SecIdentity in the keychain...
+ */
+
+ if ((err = SecIdentitySearchCreate(keychain, CSSM_KEYUSE_SIGN, &search)))
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Cannot create identity search reference (%d)", (int)err);
+ goto cleanup;
+ }
+
+ if ((err = SecIdentitySearchCopyNext(search, &identity)))
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Cannot find signing key in keychain \"%s\": %s (%d)",
+ ServerCertificate, cssmErrorString(err), (int)err);
+ goto cleanup;
+ }
+# endif /* HAVE_SECPOLICYCREATESSL */
+
+ if (CFGetTypeID(identity) != SecIdentityGetTypeID())
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "SecIdentity CFTypeID failure!");
+ goto cleanup;
+ }
+
+ if ((certificates = CFArrayCreate(NULL, (const void **)&identity,
+ 1, &kCFTypeArrayCallBacks)) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create certificate array");
+ goto cleanup;
+ }
+
+ cleanup :
+
+ if (keychain)
+ CFRelease(keychain);
+ if (search)
+ CFRelease(search);
+ if (identity)
+ CFRelease(identity);
+
+# if HAVE_SECPOLICYCREATESSL
+ if (policy)
+ CFRelease(policy);
+ if (query)
+ CFRelease(query);
+# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY)
+ if (policy)
+ CFRelease(policy);
+ if (policy_search)
+ CFRelease(policy_search);
+# endif /* HAVE_SECPOLICYCREATESSL */
+
+ return (certificates);
+}
+
+
+/*
+ * 'make_certificate()' - Make a self-signed SSL/TLS certificate.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+make_certificate(cupsd_client_t *con) /* I - Client connection */
+{
+ int pid, /* Process ID of command */
+ status; /* Status of command */
+ char command[1024], /* Command */
+ *argv[4], /* Command-line arguments */
+ *envp[MAX_ENV + 1], /* Environment variables */
+ keychain[1024], /* Keychain argument */
+ infofile[1024], /* Type-in information for cert */
+# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ localname[1024], /* Local hostname */
+# endif /* HAVE_DNSSD || HAVE_AVAHI */
+ *servername; /* Name of server in cert */
+ cups_file_t *fp; /* Seed/info file */
+ int infofd; /* Info file descriptor */
+
+
+# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
+ if (con->servername && isdigit(con->servername[0] & 255) && DNSSDHostName)
+ {
+ snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName);
+ servername = localname;
+ }
+ else
+# endif /* HAVE_DNSSD || HAVE_AVAHI */
+ servername = con->servername;
+
+ /*
+ * Run the "certtool" command to generate a self-signed certificate...
+ */
+
+ if (!cupsFileFind("certtool", getenv("PATH"), 1, command, sizeof(command)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "No SSL certificate and certtool command not found!");
+ return (0);
+ }
+
+ /*
+ * Create a file with the certificate information fields...
+ *
+ * Note: This assumes that the default questions are asked by the certtool
+ * command...
+ */
+
+ if ((fp = cupsTempFile2(infofile, sizeof(infofile))) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to create certificate information file %s - %s",
+ infofile, strerror(errno));
+ return (0);
+ }
+
+ cupsFilePrintf(fp,
+ "%s\n" /* Enter key and certificate label */
+ "r\n" /* Generate RSA key pair */
+ "2048\n" /* Key size in bits */
+ "y\n" /* OK (y = yes) */
+ "b\n" /* Usage (b=signing/encryption) */
+ "s\n" /* Sign with SHA1 */
+ "y\n" /* OK (y = yes) */
+ "%s\n" /* Common name */
+ "\n" /* Country (default) */
+ "\n" /* Organization (default) */
+ "\n" /* Organizational unit (default) */
+ "\n" /* State/Province (default) */
+ "%s\n" /* Email address */
+ "y\n", /* OK (y = yes) */
+ servername, servername, ServerAdmin);
+ cupsFileClose(fp);
+
+ cupsdLogMessage(CUPSD_LOG_INFO,
+ "Generating SSL server key and certificate...");
+
+ snprintf(keychain, sizeof(keychain), "k=%s", ServerCertificate);
+
+ argv[0] = "certtool";
+ argv[1] = "c";
+ argv[2] = keychain;
+ argv[3] = NULL;
+
+ cupsdLoadEnv(envp, MAX_ENV);
+
+ infofd = open(infofile, O_RDONLY);
+
+ if (!cupsdStartProcess(command, argv, envp, infofd, -1, -1, -1, -1, 1, NULL,
+ NULL, &pid))
+ {
+ close(infofd);
+ unlink(infofile);
+ return (0);
+ }
+
+ close(infofd);
+ unlink(infofile);
+
+ while (waitpid(pid, &status, 0) < 0)
+ if (errno != EINTR)
+ {
+ status = 1;
+ break;
+ }
+
+ cupsdFinishProcess(pid, command, sizeof(command), NULL);
+
+ if (status)
+ {
+ if (WIFEXITED(status))
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to create SSL server key and certificate - "
+ "the certtool command stopped with status %d!",
+ WEXITSTATUS(status));
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to create SSL server key and certificate - "
+ "the certtool command crashed on signal %d!",
+ WTERMSIG(status));
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO,
+ "Created SSL server certificate file \"%s\"...",
+ ServerCertificate);
+ }
+
+ return (!status);
+}
+
+
+/*
+ * End of "$Id: tls-darwin.c 11173 2013-07-23 12:31:34Z msweet $".
+ */
diff --git a/scheduler/tls-gnutls.c b/scheduler/tls-gnutls.c
new file mode 100644
index 0000000..c2d7032
--- /dev/null
+++ b/scheduler/tls-gnutls.c
@@ -0,0 +1,292 @@
+/*
+ * "$Id: tls-gnutls.c 11173 2013-07-23 12:31:34Z msweet $"
+ *
+ * TLS support code for the CUPS scheduler using GNU TLS.
+ *
+ * Copyright 2007-2012 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ *
+ * Contents:
+ *
+ * cupsdEndTLS() - Shutdown a secure session with the client.
+ * cupsdStartTLS() - Start a secure session with the client.
+ * make_certificate() - Make a self-signed SSL/TLS certificate.
+ */
+
+
+/*
+ * Local functions...
+ */
+
+static int make_certificate(cupsd_client_t *con);
+
+
+/*
+ * 'cupsdEndTLS()' - Shutdown a secure session with the client.
+ */
+
+int /* O - 1 on success, 0 on error */
+cupsdEndTLS(cupsd_client_t *con) /* I - Client connection */
+{
+ int error; /* Error code */
+ gnutls_certificate_server_credentials *credentials;
+ /* TLS credentials */
+
+
+ credentials = (gnutls_certificate_server_credentials *)
+ (con->http.tls_credentials);
+
+ error = gnutls_bye(con->http.tls, GNUTLS_SHUT_WR);
+ switch (error)
+ {
+ case GNUTLS_E_SUCCESS:
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "SSL shutdown successful!");
+ break;
+ default:
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "SSL shutdown failed: %s", gnutls_strerror(error));
+ break;
+ }
+
+ gnutls_deinit(con->http.tls);
+ con->http.tls = NULL;
+
+ gnutls_certificate_free_credentials(*credentials);
+ free(credentials);
+
+ return (1);
+}
+
+
+/*
+ * 'cupsdStartTLS()' - Start a secure session with the client.
+ */
+
+int /* O - 1 on success, 0 on error */
+cupsdStartTLS(cupsd_client_t *con) /* I - Client connection */
+{
+ int status; /* Error code */
+ gnutls_certificate_server_credentials *credentials;
+ /* TLS credentials */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.",
+ con->http.fd);
+
+ /*
+ * Verify that we have a certificate...
+ */
+
+ if (access(ServerKey, 0) || access(ServerCertificate, 0))
+ {
+ /*
+ * Nope, make a self-signed certificate...
+ */
+
+ if (!make_certificate(con))
+ return (0);
+ }
+
+ /*
+ * Create the SSL object and perform the SSL handshake...
+ */
+
+ credentials = (gnutls_certificate_server_credentials *)
+ malloc(sizeof(gnutls_certificate_server_credentials));
+ if (credentials == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to encrypt connection from %s - %s",
+ con->http.hostname, strerror(errno));
+
+ return (0);
+ }
+
+ gnutls_certificate_allocate_credentials(credentials);
+ gnutls_certificate_set_x509_key_file(*credentials, ServerCertificate,
+ ServerKey, GNUTLS_X509_FMT_PEM);
+
+ gnutls_init(&con->http.tls, GNUTLS_SERVER);
+ gnutls_set_default_priority(con->http.tls);
+
+ gnutls_credentials_set(con->http.tls, GNUTLS_CRD_CERTIFICATE, *credentials);
+ gnutls_transport_set_ptr(con->http.tls, (gnutls_transport_ptr)HTTP(con));
+ gnutls_transport_set_pull_function(con->http.tls, _httpReadGNUTLS);
+ gnutls_transport_set_push_function(con->http.tls, _httpWriteGNUTLS);
+
+ while ((status = gnutls_handshake(con->http.tls)) != GNUTLS_E_SUCCESS)
+ {
+ if (gnutls_error_is_fatal(status))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to encrypt connection from %s - %s",
+ con->http.hostname, gnutls_strerror(status));
+
+ gnutls_deinit(con->http.tls);
+ gnutls_certificate_free_credentials(*credentials);
+ con->http.tls = NULL;
+ free(credentials);
+ return (0);
+ }
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
+ con->http.hostname);
+
+ con->http.tls_credentials = credentials;
+ return (1);
+}
+
+
+/*
+ * 'make_certificate()' - Make a self-signed SSL/TLS certificate.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+make_certificate(cupsd_client_t *con) /* I - Client connection */
+{
+ gnutls_x509_crt crt; /* Self-signed certificate */
+ gnutls_x509_privkey key; /* Encryption key */
+ cups_lang_t *language; /* Default language info */
+ cups_file_t *fp; /* Key/cert file */
+ unsigned char buffer[8192]; /* Buffer for x509 data */
+ size_t bytes; /* Number of bytes of data */
+ unsigned char serial[4]; /* Serial number buffer */
+ time_t curtime; /* Current time */
+ int result; /* Result of GNU TLS calls */
+
+
+ /*
+ * Create the encryption key...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_INFO, "Generating SSL server key...");
+
+ gnutls_x509_privkey_init(&key);
+ gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 2048, 0);
+
+ /*
+ * Save it...
+ */
+
+ bytes = sizeof(buffer);
+
+ if ((result = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM,
+ buffer, &bytes)) < 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to export SSL server key - %s",
+ gnutls_strerror(result));
+ gnutls_x509_privkey_deinit(key);
+ return (0);
+ }
+ else if ((fp = cupsFileOpen(ServerKey, "w")) != NULL)
+ {
+ cupsFileWrite(fp, (char *)buffer, bytes);
+ cupsFileClose(fp);
+
+ cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server key file \"%s\"...",
+ ServerKey);
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to create SSL server key file \"%s\" - %s",
+ ServerKey, strerror(errno));
+ gnutls_x509_privkey_deinit(key);
+ return (0);
+ }
+
+ /*
+ * Create the self-signed certificate...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_INFO, "Generating self-signed SSL certificate...");
+
+ language = cupsLangDefault();
+ curtime = time(NULL);
+ serial[0] = curtime >> 24;
+ serial[1] = curtime >> 16;
+ serial[2] = curtime >> 8;
+ serial[3] = curtime;
+
+ gnutls_x509_crt_init(&crt);
+ if (strlen(language->language) == 5)
+ gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0,
+ language->language + 3, 2);
+ else
+ gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0,
+ "US", 2);
+ gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0,
+ ServerName, strlen(ServerName));
+ gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
+ ServerName, strlen(ServerName));
+ gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME,
+ 0, "Unknown", 7);
+ gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0,
+ "Unknown", 7);
+ gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_LOCALITY_NAME, 0,
+ "Unknown", 7);
+ gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_PKCS9_EMAIL, 0,
+ ServerAdmin, strlen(ServerAdmin));
+ gnutls_x509_crt_set_key(crt, key);
+ gnutls_x509_crt_set_serial(crt, serial, sizeof(serial));
+ gnutls_x509_crt_set_activation_time(crt, curtime);
+ gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400);
+ gnutls_x509_crt_set_ca_status(crt, 0);
+ gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME,
+ ServerName);
+ gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0);
+ gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT);
+ gnutls_x509_crt_set_version(crt, 3);
+
+ bytes = sizeof(buffer);
+ if (gnutls_x509_crt_get_key_id(crt, 0, buffer, &bytes) >= 0)
+ gnutls_x509_crt_set_subject_key_id(crt, buffer, bytes);
+
+ gnutls_x509_crt_sign(crt, crt, key);
+
+ /*
+ * Save it...
+ */
+
+ bytes = sizeof(buffer);
+ if ((result = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM,
+ buffer, &bytes)) < 0)
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to export SSL server certificate - %s",
+ gnutls_strerror(result));
+ else if ((fp = cupsFileOpen(ServerCertificate, "w")) != NULL)
+ {
+ cupsFileWrite(fp, (char *)buffer, bytes);
+ cupsFileClose(fp);
+
+ cupsdLogMessage(CUPSD_LOG_INFO,
+ "Created SSL server certificate file \"%s\"...",
+ ServerCertificate);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to create SSL server certificate file \"%s\" - %s",
+ ServerCertificate, strerror(errno));
+
+ /*
+ * Cleanup...
+ */
+
+ gnutls_x509_crt_deinit(crt);
+ gnutls_x509_privkey_deinit(key);
+
+ return (1);
+}
+
+
+/*
+ * End of "$Id: tls-gnutls.c 11173 2013-07-23 12:31:34Z msweet $".
+ */
diff --git a/scheduler/tls-openssl.c b/scheduler/tls-openssl.c
new file mode 100644
index 0000000..f123d28
--- /dev/null
+++ b/scheduler/tls-openssl.c
@@ -0,0 +1,353 @@
+/*
+ * "$Id: tls-openssl.c 11173 2013-07-23 12:31:34Z msweet $"
+ *
+ * TLS support code for the CUPS scheduler using OpenSSL.
+ *
+ * Copyright 2007-2012 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ *
+ * Contents:
+ *
+ * cupsdEndTLS() - Shutdown a secure session with the client.
+ * cupsdStartTLS() - Start a secure session with the client.
+ * make_certificate() - Make a self-signed SSL/TLS certificate.
+ */
+
+
+/*
+ * Local functions...
+ */
+
+static int make_certificate(cupsd_client_t *con);
+
+
+/*
+ * 'cupsdEndTLS()' - Shutdown a secure session with the client.
+ */
+
+int /* O - 1 on success, 0 on error */
+cupsdEndTLS(cupsd_client_t *con) /* I - Client connection */
+{
+ SSL_CTX *context; /* Context for encryption */
+ unsigned long error; /* Error code */
+ int status; /* Return status */
+
+
+ context = SSL_get_SSL_CTX(con->http.tls);
+
+ switch (SSL_shutdown(con->http.tls))
+ {
+ case 1 :
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "SSL shutdown successful!");
+ status = 1;
+ break;
+
+ case -1 :
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Fatal error during SSL shutdown!");
+
+ default :
+ while ((error = ERR_get_error()) != 0)
+ cupsdLogMessage(CUPSD_LOG_ERROR, "SSL shutdown failed: %s",
+ ERR_error_string(error, NULL));
+ status = 0;
+ break;
+ }
+
+ SSL_CTX_free(context);
+ SSL_free(con->http.tls);
+ con->http.tls = NULL;
+
+ return (status);
+}
+
+
+/*
+ * 'cupsdStartTLS()' - Start a secure session with the client.
+ */
+
+int /* O - 1 on success, 0 on error */
+cupsdStartTLS(cupsd_client_t *con) /* I - Client connection */
+{
+ SSL_CTX *context; /* Context for encryption */
+ BIO *bio; /* BIO data */
+ unsigned long error; /* Error code */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.",
+ con->http.fd);
+
+ /*
+ * Verify that we have a certificate...
+ */
+
+ if (access(ServerKey, 0) || access(ServerCertificate, 0))
+ {
+ /*
+ * Nope, make a self-signed certificate...
+ */
+
+ if (!make_certificate(con))
+ return (0);
+ }
+
+ /*
+ * Create the SSL context and accept the connection...
+ */
+
+ context = SSL_CTX_new(SSLv23_server_method());
+
+ SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
+ if (SSLOptions & CUPSD_SSL_NOEMPTY)
+ SSL_CTX_set_options(context, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
+ SSL_CTX_use_PrivateKey_file(context, ServerKey, SSL_FILETYPE_PEM);
+ SSL_CTX_use_certificate_chain_file(context, ServerCertificate);
+
+ bio = BIO_new(_httpBIOMethods());
+ BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)HTTP(con));
+
+ con->http.tls = SSL_new(context);
+ SSL_set_bio(con->http.tls, bio, bio);
+
+ if (SSL_accept(con->http.tls) != 1)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to encrypt connection from %s.",
+ con->http.hostname);
+
+ while ((error = ERR_get_error()) != 0)
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s", ERR_error_string(error, NULL));
+
+ SSL_CTX_free(context);
+ SSL_free(con->http.tls);
+ con->http.tls = NULL;
+ return (0);
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
+ con->http.hostname);
+
+ return (1);
+}
+
+
+/*
+ * 'make_certificate()' - Make a self-signed SSL/TLS certificate.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+make_certificate(cupsd_client_t *con) /* I - Client connection */
+{
+#ifdef HAVE_WAITPID
+ int pid, /* Process ID of command */
+ status; /* Status of command */
+ char command[1024], /* Command */
+ *argv[12], /* Command-line arguments */
+ *envp[MAX_ENV + 1], /* Environment variables */
+ infofile[1024], /* Type-in information for cert */
+ seedfile[1024]; /* Random number seed file */
+ int envc, /* Number of environment variables */
+ bytes; /* Bytes written */
+ cups_file_t *fp; /* Seed/info file */
+ int infofd; /* Info file descriptor */
+
+
+ /*
+ * Run the "openssl" command to seed the random number generator and
+ * generate a self-signed certificate that is good for 10 years:
+ *
+ * openssl rand -rand seedfile 1
+ *
+ * openssl req -new -x509 -keyout ServerKey \
+ * -out ServerCertificate -days 3650 -nodes
+ *
+ * The seeding step is crucial in ensuring that the openssl command
+ * does not block on systems without sufficient entropy...
+ */
+
+ if (!cupsFileFind("openssl", getenv("PATH"), 1, command, sizeof(command)))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "No SSL certificate and openssl command not found!");
+ return (0);
+ }
+
+ if (access("/dev/urandom", 0))
+ {
+ /*
+ * If the system doesn't provide /dev/urandom, then any random source
+ * will probably be blocking-style, so generate some random data to
+ * use as a seed for the certificate. Note that we have already
+ * seeded the random number generator in cupsdInitCerts()...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_INFO,
+ "Seeding the random number generator...");
+
+ /*
+ * Write the seed file...
+ */
+
+ if ((fp = cupsTempFile2(seedfile, sizeof(seedfile))) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create seed file %s - %s",
+ seedfile, strerror(errno));
+ return (0);
+ }
+
+ for (bytes = 0; bytes < 262144; bytes ++)
+ cupsFilePutChar(fp, CUPS_RAND());
+
+ cupsFileClose(fp);
+
+ /*
+ * Run the openssl command to seed its random number generator...
+ */
+
+ argv[0] = "openssl";
+ argv[1] = "rand";
+ argv[2] = "-rand";
+ argv[3] = seedfile;
+ argv[4] = "1";
+ argv[5] = NULL;
+
+ envc = cupsdLoadEnv(envp, MAX_ENV);
+ envp[envc] = NULL;
+
+ if (!cupsdStartProcess(command, argv, envp, -1, -1, -1, -1, -1, 1, NULL,
+ NULL, &pid))
+ {
+ unlink(seedfile);
+ return (0);
+ }
+
+ while (waitpid(pid, &status, 0) < 0)
+ if (errno != EINTR)
+ {
+ status = 1;
+ break;
+ }
+
+ cupsdFinishProcess(pid, command, sizeof(command), NULL);
+
+ /*
+ * Remove the seed file, as it is no longer needed...
+ */
+
+ unlink(seedfile);
+
+ if (status)
+ {
+ if (WIFEXITED(status))
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to seed random number generator - "
+ "the openssl command stopped with status %d!",
+ WEXITSTATUS(status));
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to seed random number generator - "
+ "the openssl command crashed on signal %d!",
+ WTERMSIG(status));
+
+ return (0);
+ }
+ }
+
+ /*
+ * Create a file with the certificate information fields...
+ *
+ * Note: This assumes that the default questions are asked by the openssl
+ * command...
+ */
+
+ if ((fp = cupsTempFile2(infofile, sizeof(infofile))) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to create certificate information file %s - %s",
+ infofile, strerror(errno));
+ return (0);
+ }
+
+ cupsFilePrintf(fp, ".\n.\n.\n%s\n.\n%s\n%s\n",
+ ServerName, ServerName, ServerAdmin);
+ cupsFileClose(fp);
+
+ cupsdLogMessage(CUPSD_LOG_INFO,
+ "Generating SSL server key and certificate...");
+
+ argv[0] = "openssl";
+ argv[1] = "req";
+ argv[2] = "-new";
+ argv[3] = "-x509";
+ argv[4] = "-keyout";
+ argv[5] = ServerKey;
+ argv[6] = "-out";
+ argv[7] = ServerCertificate;
+ argv[8] = "-days";
+ argv[9] = "3650";
+ argv[10] = "-nodes";
+ argv[11] = NULL;
+
+ cupsdLoadEnv(envp, MAX_ENV);
+
+ infofd = open(infofile, O_RDONLY);
+
+ if (!cupsdStartProcess(command, argv, envp, infofd, -1, -1, -1, -1, 1, NULL,
+ NULL, &pid))
+ {
+ close(infofd);
+ unlink(infofile);
+ return (0);
+ }
+
+ close(infofd);
+ unlink(infofile);
+
+ while (waitpid(pid, &status, 0) < 0)
+ if (errno != EINTR)
+ {
+ status = 1;
+ break;
+ }
+
+ cupsdFinishProcess(pid, command, sizeof(command), NULL);
+
+ if (status)
+ {
+ if (WIFEXITED(status))
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to create SSL server key and certificate - "
+ "the openssl command stopped with status %d!",
+ WEXITSTATUS(status));
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to create SSL server key and certificate - "
+ "the openssl command crashed on signal %d!",
+ WTERMSIG(status));
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server key file \"%s\"...",
+ ServerKey);
+ cupsdLogMessage(CUPSD_LOG_INFO,
+ "Created SSL server certificate file \"%s\"...",
+ ServerCertificate);
+ }
+
+ return (!status);
+
+#else
+ return (0);
+#endif /* HAVE_WAITPID */
+}
+
+
+/*
+ * End of "$Id: tls-openssl.c 11173 2013-07-23 12:31:34Z msweet $".
+ */
diff --git a/scheduler/tls.c b/scheduler/tls.c
new file mode 100644
index 0000000..bd18263
--- /dev/null
+++ b/scheduler/tls.c
@@ -0,0 +1,30 @@
+/*
+ * "$Id: tls.c 11173 2013-07-23 12:31:34Z msweet $"
+ *
+ * TLS support code for the CUPS scheduler.
+ *
+ * Copyright 2012 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ */
+
+#include "cupsd.h"
+
+#ifdef HAVE_SSL
+# ifdef HAVE_CDSASSL
+# include "tls-darwin.c"
+# elif defined(HAVE_GNUTLS)
+# include "tls-gnutls.c"
+# elif defined(HAVE_LIBSSL)
+# include "tls-openssl.c"
+# endif /* HAVE_CDSASSL */
+#endif /* HAVE_SSL */
+
+
+/*
+ * End of "$Id: tls.c 11173 2013-07-23 12:31:34Z msweet $".
+ */
diff --git a/scheduler/type.c b/scheduler/type.c
index d2e32b2..bf014be 100644
--- a/scheduler/type.c
+++ b/scheduler/type.c
@@ -1,5 +1,5 @@
/*
- * "$Id: type.c 9793 2011-05-20 03:49:49Z mike $"
+ * "$Id: type.c 11173 2013-07-23 12:31:34Z msweet $"
*
* MIME typing routines for CUPS.
*
@@ -1212,5 +1212,5 @@ mime_patmatch(const char *s, /* I - String to match against */
/*
- * End of "$Id: type.c 9793 2011-05-20 03:49:49Z mike $".
+ * End of "$Id: type.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/util.c b/scheduler/util.c
index 9bc8077..74dd9ff 100644
--- a/scheduler/util.c
+++ b/scheduler/util.c
@@ -1,5 +1,5 @@
/*
- * "$Id: util.c 9793 2011-05-20 03:49:49Z mike $"
+ * "$Id: util.c 11173 2013-07-23 12:31:34Z msweet $"
*
* Mini-daemon utility functions for CUPS.
*
@@ -170,7 +170,7 @@ cupsdCreateStringsArray(const char *s) /* I - Comma-delimited strings */
/*
* 'cupsdExec()' - Run a program with the correct environment.
*
- * On Mac OS X, we need to update the CFProcessPath environment variable that
+ * On OS X, we need to update the CFProcessPath environment variable that
* is passed in the environment so the child can access its bundled resources.
*/
@@ -187,7 +187,7 @@ cupsdExec(const char *command, /* I - Full path to program */
/*
- * Some Mac OS X programs are bundled and need the CFProcessPath environment
+ * Some OS X programs are bundled and need the CFProcessPath environment
* variable defined. If the command is a symlink, resolve the link and point
* to the resolved location, otherwise, use the command path itself.
*/
@@ -467,5 +467,5 @@ cupsdSendIPPTrailer(void)
/*
- * End of "$Id: util.c 9793 2011-05-20 03:49:49Z mike $".
+ * End of "$Id: util.c 11173 2013-07-23 12:31:34Z msweet $".
*/
diff --git a/scheduler/util.h b/scheduler/util.h
index 0080914..cf5ae0d 100644
--- a/scheduler/util.h
+++ b/scheduler/util.h
@@ -1,5 +1,5 @@
/*
- * "$Id: util.h 9755 2011-05-09 22:53:31Z mike $"
+ * "$Id: util.h 11173 2013-07-23 12:31:34Z msweet $"
*
* Mini-daemon utility definitions for CUPS.
*
@@ -67,5 +67,5 @@ extern void cupsdSendIPPTrailer(void);
#endif /* !_CUPSD_UTIL_H_ */
/*
- * End of "$Id: util.h 9755 2011-05-09 22:53:31Z mike $".
+ * End of "$Id: util.h 11173 2013-07-23 12:31:34Z msweet $".
*/