summaryrefslogtreecommitdiff
path: root/scheduler
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-01-27 10:47:25 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-01-27 10:47:52 +0900
commitef9b26ed48ff777f0ac2e84e92aa54a382d2b37e (patch)
tree13a008c6165a5ce4bd06a3b1dd53df91c8b01485 /scheduler
parent4daab3758f62250691d3994850ddd3a7faf80d5e (diff)
downloadcups-ef9b26ed48ff777f0ac2e84e92aa54a382d2b37e.tar.gz
cups-ef9b26ed48ff777f0ac2e84e92aa54a382d2b37e.tar.bz2
cups-ef9b26ed48ff777f0ac2e84e92aa54a382d2b37e.zip
Imported Upstream version 2.1.2upstream/2.1.2
Change-Id: Ia36f5862c3fcaa1f053ad69ed961e1fb9043e20b Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'scheduler')
-rw-r--r--scheduler/Dependencies459
-rw-r--r--scheduler/Makefile131
-rw-r--r--scheduler/auth.c694
-rw-r--r--scheduler/auth.h36
-rw-r--r--scheduler/banners.c4
-rw-r--r--scheduler/banners.h4
-rw-r--r--scheduler/cert.c85
-rw-r--r--scheduler/cert.h4
-rw-r--r--scheduler/classes.c42
-rw-r--r--scheduler/classes.h4
-rw-r--r--scheduler/client.c2076
-rw-r--r--scheduler/client.h38
-rw-r--r--scheduler/colorman.c95
-rw-r--r--scheduler/colorman.h4
-rw-r--r--scheduler/conf.c777
-rw-r--r--scheduler/conf.h90
-rw-r--r--scheduler/cups-deviced.c43
-rw-r--r--scheduler/cups-driverd.cxx162
-rw-r--r--scheduler/cups-exec.c175
-rw-r--r--scheduler/cups-lpd.c93
-rw-r--r--scheduler/cups.sh.in57
-rw-r--r--scheduler/cups.xml.in2
-rw-r--r--scheduler/cupsd.h38
-rw-r--r--scheduler/cupsfilter.c462
-rw-r--r--scheduler/dirsvc.c727
-rw-r--r--scheduler/dirsvc.h4
-rw-r--r--scheduler/env.c38
-rw-r--r--scheduler/file.c138
-rw-r--r--scheduler/filter.c4
-rw-r--r--scheduler/ipp.c1455
-rw-r--r--scheduler/job.c806
-rw-r--r--scheduler/job.h33
-rw-r--r--scheduler/listen.c199
-rw-r--r--scheduler/log.c590
-rw-r--r--scheduler/main.c989
-rw-r--r--scheduler/mime-private.h4
-rw-r--r--scheduler/mime.c69
-rw-r--r--scheduler/mime.h11
-rw-r--r--scheduler/network.c38
-rw-r--r--scheduler/network.h4
-rw-r--r--scheduler/org.cups.cups-lpd.plist.in6
-rw-r--r--scheduler/org.cups.cups-lpd.socket9
-rw-r--r--scheduler/org.cups.cups-lpdAT.service.in9
-rw-r--r--scheduler/org.cups.cupsd.path.in8
-rw-r--r--scheduler/org.cups.cupsd.plist23
-rw-r--r--scheduler/org.cups.cupsd.service.in11
-rw-r--r--scheduler/org.cups.cupsd.socket.in8
-rw-r--r--scheduler/policy.c52
-rw-r--r--scheduler/policy.h4
-rw-r--r--scheduler/printers.c947
-rw-r--r--scheduler/printers.h31
-rw-r--r--scheduler/process.c442
-rw-r--r--scheduler/quotas.c4
-rw-r--r--scheduler/select.c81
-rw-r--r--scheduler/server.c15
-rw-r--r--scheduler/statbuf.c38
-rw-r--r--scheduler/statbuf.h4
-rw-r--r--scheduler/subscriptions.c53
-rw-r--r--scheduler/subscriptions.h4
-rw-r--r--scheduler/sysman.c358
-rw-r--r--scheduler/sysman.h24
-rw-r--r--scheduler/testlpd.c83
-rw-r--r--scheduler/testmime.c32
-rw-r--r--scheduler/testspeed.c73
-rw-r--r--scheduler/testsub.c38
-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.c183
-rw-r--r--scheduler/util.c48
-rw-r--r--scheduler/util.h22
72 files changed, 6856 insertions, 7683 deletions
diff --git a/scheduler/Dependencies b/scheduler/Dependencies
index 2035646..e61c288 100644
--- a/scheduler/Dependencies
+++ b/scheduler/Dependencies
@@ -1,264 +1,270 @@
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/array-private.h ../cups/array.h ../cups/ipp-private.h \
+ ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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
+ client.h policy.h printers.h classes.h job.h colorman.h conf.h \
+ banners.h dirsvc.h network.h subscriptions.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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/array-private.h ../cups/array.h ../cups/ipp-private.h \
+ ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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.h policy.h printers.h classes.h job.h colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.h conf.h banners.h dirsvc.h network.h \
+ subscriptions.h
+colorman.o: colorman.c cupsd.h ../cups/cups-private.h \
+ ../cups/string-private.h ../config.h ../cups/debug-private.h \
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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/array-private.h ../cups/array.h ../cups/ipp-private.h \
+ ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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.h policy.h printers.h classes.h job.h colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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/array-private.h ../cups/array.h ../cups/ipp-private.h \
+ ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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.h policy.h printers.h classes.h job.h colorman.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/array-private.h ../cups/array.h ../cups/ipp-private.h \
+ ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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
+ client.h policy.h printers.h classes.h job.h colorman.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/array-private.h ../cups/array.h ../cups/ipp-private.h \
+ ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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.h policy.h printers.h classes.h job.h colorman.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/array-private.h ../cups/array.h ../cups/ipp-private.h \
+ ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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.h policy.h printers.h classes.h job.h colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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/array-private.h ../cups/array.h ../cups/ipp-private.h \
+ ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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
+ client.h policy.h printers.h classes.h job.h colorman.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/array-private.h ../cups/array.h ../cups/ipp-private.h \
+ ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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.h policy.h printers.h classes.h job.h colorman.h conf.h \
+ banners.h dirsvc.h network.h subscriptions.h
+network.o: network.c ../cups/http-private.h ../config.h \
+ ../cups/language.h ../cups/array.h ../cups/versioning.h ../cups/http.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/array-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.h conf.h banners.h dirsvc.h network.h \
+ subscriptions.h
+server.o: server.c ../cups/http-private.h ../config.h ../cups/language.h \
+ ../cups/array.h ../cups/versioning.h ../cups/http.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/array-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.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
+ ../cups/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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 colorman.h conf.h banners.h dirsvc.h network.h \
+ subscriptions.h
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
@@ -271,59 +277,60 @@ type.o: type.c ../cups/string-private.h ../config.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/versioning.h ../cups/array-private.h ../cups/array.h \
+ ../cups/ipp-private.h ../cups/ipp.h ../cups/http.h \
+ ../cups/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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-exec.o: cups-exec.c ../cups/string-private.h ../config.h \
+ ../cups/file.h ../cups/versioning.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/array-private.h ../cups/array.h ../cups/ipp-private.h \
+ ../cups/ipp.h ../cups/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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
+ ../cups/pwg.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
+ ../cups/array.h ../cups/language.h ../cups/pwg.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/http.h ../cups/array.h ../cups/language.h ../cups/pwg.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
+ ../cups/pwg.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/http-private.h ../cups/language.h ../cups/md5-private.h \
+ ../cups/language-private.h ../cups/transcode.h ../cups/pwg-private.h \
+ ../cups/cups.h ../cups/file.h ../cups/pwg.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/http.h ../cups/http-private.h ../cups/language.h \
+ ../cups/md5-private.h ../cups/language-private.h ../cups/transcode.h \
+ ../cups/pwg-private.h ../cups/cups.h ../cups/file.h ../cups/pwg.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 2790569..c7d244d 100644
--- a/scheduler/Makefile
+++ b/scheduler/Makefile
@@ -1,16 +1,16 @@
#
-# "$Id: Makefile 11173 2013-07-23 12:31:34Z msweet $"
+# "$Id: Makefile 12519 2015-02-17 13:10:19Z msweet $"
#
-# Scheduler Makefile for CUPS.
+# Scheduler Makefile for CUPS.
#
-# Copyright 2007-2012 by Apple Inc.
-# Copyright 1997-2007 by Easy Software Products, all rights reserved.
+# Copyright 2007-2015 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/".
+# 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 ../Makedefs
@@ -40,8 +40,7 @@ CUPSDOBJS = \
server.o \
statbuf.o \
subscriptions.o \
- sysman.o \
- tls.o
+ sysman.o
LIBOBJS = \
filter.o \
mime.o \
@@ -114,7 +113,7 @@ unittests: $(UNITTARGETS)
clean:
$(RM) $(OBJS)
$(RM) $(TARGETS) $(UNITTARGETS) convert
- $(RM) libcupsmime.so libcupsmime.sl libcupsmime.dylib
+ $(RM) libcupsmime.so libcupsmime.dylib
#
@@ -172,7 +171,7 @@ install-data:
echo Creating $(REQUESTS)/tmp...
$(INSTALL_DIR) -m 1770 -g $(CUPS_GROUP) $(REQUESTS)/tmp
echo Creating $(CACHEDIR)...
- $(INSTALL_DIR) -m 775 -g $(CUPS_GROUP) $(CACHEDIR)
+ $(INSTALL_DIR) -m 770 -g $(CUPS_GROUP) $(CACHEDIR)
if test "x$(INITDIR)" != x; then \
echo Installing init scripts...; \
$(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/init.d; \
@@ -180,32 +179,36 @@ install-data:
for level in $(RCLEVELS); do \
$(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc$${level}.d; \
$(LN) ../init.d/cups $(BUILDROOT)$(INITDIR)/rc$${level}.d/S$(RCSTART)cups; \
- if test `uname` = HP-UX; then \
- level=`expr $$level - 1`; \
- $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc$${level}.d; \
- fi; \
$(LN) ../init.d/cups $(BUILDROOT)$(INITDIR)/rc$${level}.d/K$(RCSTOP)cups; \
done; \
$(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc0.d; \
$(LN) ../init.d/cups $(BUILDROOT)$(INITDIR)/rc0.d/K$(RCSTOP)cups; \
fi
- if test "x$(INITDIR)" = x -a "x$(INITDDIR)" != x; then \
- $(INSTALL_DIR) $(BUILDROOT)$(INITDDIR); \
- if test "$(INITDDIR)" = "/System/Library/LaunchDaemons"; then \
- echo Installing LaunchDaemons configuration files...; \
- $(INSTALL_DATA) org.cups.cupsd.plist $(BUILDROOT)$(DEFAULT_LAUNCHD_CONF); \
- $(INSTALL_DATA) org.cups.cups-lpd.plist $(BUILDROOT)/System/Library/LaunchDaemons; \
- else \
- echo Installing RC script...; \
- $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDDIR)/cups; \
- fi \
+ if test "x$(INITDDIR)" != x; then \
+ echo Installing init script...; \
+ $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDDIR); \
+ $(INSTALL_SCRIPT) cups.sh $(BUILDROOT)$(INITDDIR); \
+ fi
+ if test "x$(LAUNCHD_DIR)" != x; then \
+ echo Installing launchd configuration files...; \
+ $(INSTALL_DIR) $(BUILDROOT)$(LAUNCHD_DIR); \
+ $(INSTALL_DATA) org.cups.cupsd.plist $(BUILDROOT)$(LAUNCHD_DIR); \
+ $(INSTALL_DATA) org.cups.cups-lpd.plist $(BUILDROOT)$(LAUNCHD_DIR); \
fi
if test "x$(SMFMANIFESTDIR)" != x; then \
echo Installing SMF manifest in $(SMFMANIFESTDIR)...;\
$(INSTALL_DIR) $(BUILDROOT)/$(SMFMANIFESTDIR); \
$(INSTALL_SCRIPT) cups.xml $(BUILDROOT)$(SMFMANIFESTDIR)/cups.xml; \
fi
- if test "x$(XINETD)" != x; then \
+ if test "x$(SYSTEMD_DIR)" != x; then \
+ echo Installing systemd configuration files...; \
+ $(INSTALL_DIR) $(BUILDROOT)$(SYSTEMD_DIR); \
+ $(INSTALL_DATA) org.cups.cupsd.path $(BUILDROOT)$(SYSTEMD_DIR); \
+ $(INSTALL_DATA) org.cups.cupsd.service $(BUILDROOT)$(SYSTEMD_DIR); \
+ $(INSTALL_DATA) org.cups.cupsd.socket $(BUILDROOT)$(SYSTEMD_DIR); \
+ $(INSTALL_DATA) org.cups.cups-lpdAT.service $(BUILDROOT)$(SYSTEMD_DIR)/org.cups.cups-lpd@.service; \
+ $(INSTALL_DATA) org.cups.cups-lpd.socket $(BUILDROOT)$(SYSTEMD_DIR); \
+ elif test "x$(XINETD)" != x; then \
echo Installing xinetd configuration file for cups-lpd...; \
$(INSTALL_DIR) -m 755 $(BUILDROOT)$(XINETD); \
$(INSTALL_DATA) cups-lpd.xinetd $(BUILDROOT)$(XINETD)/cups-lpd; \
@@ -232,6 +235,7 @@ install-exec:
$(INSTALL_DIR) $(SYMROOT); \
for file in $(PROGRAMS); do \
cp $$file $(SYMROOT); \
+ dsymutil $(SYMROOT)/$$file; \
done \
fi
@@ -254,7 +258,7 @@ install-libs: $(INSTALLSTATIC)
echo Installing libraries in $(LIBDIR)...
$(INSTALL_DIR) -m 755 $(LIBDIR)
$(INSTALL_LIB) $(LIBCUPSMIME) $(LIBDIR)
- if test $(LIBCUPSMIME) = "libcupsmime.so.1" -o $(LIBCUPSMIME) = "libcupsmime.sl.1"; then \
+ if test $(LIBCUPSMIME) = "libcupsmime.so.1"; then \
$(RM) $(LIBDIR)/`basename $(LIBCUPSMIME) .1`; \
$(LN) $(LIBCUPSMIME) $(LIBDIR)/`basename $(LIBCUPSMIME) .1`; \
fi
@@ -265,6 +269,7 @@ install-libs: $(INSTALLSTATIC)
if test "x$(SYMROOT)" != "x"; then \
$(INSTALL_DIR) $(SYMROOT); \
cp $(LIBCUPSMIME) $(SYMROOT); \
+ dsymutil $(SYMROOT)/$(LIBCUPSMIME); \
fi
installstatic:
@@ -285,7 +290,6 @@ uninstall:
$(RM) $(SERVERBIN)/daemon/cups-driverd
$(RM) $(SERVERBIN)/daemon/cups-exec
$(RM) $(SERVERBIN)/daemon/cups-lpd
- $(RM) $(BUILDROOT)/System/Library/Printers/Libraries/convert
-$(RMDIR) $(STATEDIR)/certs
-$(RMDIR) $(STATEDIR)
-$(RMDIR) $(SERVERROOT)/ppd
@@ -302,16 +306,13 @@ uninstall:
$(RM) $(LIBDIR)/libcupsmime.1.dylib
$(RM) $(LIBDIR)/libcupsmime.a
$(RM) $(LIBDIR)/libcupsmime.dylib
- $(RM) $(LIBDIR)/libcupsmime_s.a
- $(RM) $(LIBDIR)/libcupsmime.sl
- $(RM) $(LIBDIR)/libcupsmime.sl.1
$(RM) $(LIBDIR)/libcupsmime.so
$(RM) $(LIBDIR)/libcupsmime.so.1
-$(RMDIR) $(LIBDIR)
$(RM) $(INCLUDEDIR)/cups/mime.h
-$(RMDIR) $(INCLUDEDIR)/cups
- echo Uninstalling startup script...
if test "x$(INITDIR)" != x; then \
+ echo Uninstalling init scripts...; \
$(RM) $(BUILDROOT)$(INITDIR)/init.d/cups; \
$(RMDIR) $(BUILDROOT)$(INITDIR)/init.d; \
$(RM) $(BUILDROOT)$(INITDIR)/rc0.d/K00cups; \
@@ -323,23 +324,24 @@ uninstall:
$(RM) $(BUILDROOT)$(INITDIR)/rc5.d/S99cups; \
$(RMDIR) $(BUILDROOT)$(INITDIR)/rc5.d; \
fi
- if test "x$(INITDIR)" = x -a "x$(INITDDIR)" != x; then \
- if test "$(INITDDIR)" = "/System/Library/StartupItems/PrintingServices"; then \
- $(RM) $(BUILDROOT)$(INITDDIR)/PrintingServices; \
- $(RM) $(BUILDROOT)$(INITDDIR)/StartupParameters.plist; \
- $(RM) $(BUILDROOT)$(INITDDIR)/Resources/English.lproj/Localizable.strings; \
- $(RMDIR) $(BUILDROOT)$(INITDDIR)/Resources/English.lproj; \
- elif test "$(INITDDIR)" = "/System/Library/LaunchDaemons"; then \
- $(RM) $(BUILDROOT)$(INITDDIR)/org.cups.cupsd.plist; \
- $(RM) $(BUILDROOT)$(INITDDIR)/org.cups.cups-lpd.plist; \
- $(RMDIR) $(BUILDROOT)/System/Library/StartupItems/PrintingServices; \
- else \
- $(INSTALL_SCRIPT) init/cups.sh $(BUILDROOT)$(INITDDIR)/cups; \
- fi \
+ if test "x$(INITDDIR)" != x; then \
+ echo Uninstalling startup script...; \
+ $(RM) $(BUILDROOT)$(INITDDIR)/cups.sh; \
$(RMDIR) $(BUILDROOT)$(INITDDIR); \
fi
+ if test "x$LAUNCHD_DIR" != x; then \
+ echo Uninstalling launchd files...; \
+ $(RM) $(BUILDROOT)$(LAUNCHD_DIR)/org.cups.cupsd.plist; \
+ $(RM) $(BUILDROOT)$(LAUNCHD_DIR)/org.cups.cups-lpd.plist; \
+ fi
+ if test "x$SYSTEMD_DIR" != x; then \
+ echo Uninstalling systemd files...; \
+ $(RM) $(BUILDROOT)$(SYSTEMD_DIR)/org.cups.cupsd.path; \
+ $(RM) $(BUILDROOT)$(SYSTEMD_DIR)/org.cups.cupsd.service; \
+ $(RM) $(BUILDROOT)$(SYSTEMD_DIR)/org.cups.cupsd.socket; \
+ fi
if test "x$(SMFMANIFESTDIR)" != x; then \
- echo Uninstalling SMF manifest in $(SMFMANIFESTDIR)...;\
+ echo Uninstalling SMF manifest file...;\
$(RM) $(BUILDROOT)$(SMFMANIFESTDIR)/cups.xml; \
fi
if test "x$(XINETD)" != x; then \
@@ -378,18 +380,16 @@ cupsd: $(CUPSDOBJS) $(LIBCUPSMIME) ../cups/$(LIBCUPS)
echo Linking $@...
$(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) -L. -lcupsmime \
$(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
- $(LIBPAPER) $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBS) \
- $(LIBGSSAPI) $(LIBWRAP)
+ $(LIBPAPER) $(LIBMALLOC) $(SERVERLIBS) $(ONDEMANDLIBS) \
+ $(DNSSDLIBS) $(LIBS) $(LIBGSSAPI) $(LIBWRAP)
cupsd-static: $(CUPSDOBJS) libcupsmime.a ../cups/$(LIBCUPSSTATIC)
echo Linking $@...
$(CC) $(LDFLAGS) -o cupsd-static $(CUPSDOBJS) libcupsmime.a \
$(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \
../cups/$(LIBCUPSSTATIC) $(COMMONLIBS) $(LIBZ) $(LIBPAPER) \
- $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBGSSAPI) \
- $(LIBWRAP)
-
-tls.o: tls-darwin.c tls-gnutls.c tls-openssl.c
+ $(LIBMALLOC) $(SERVERLIBS) $(ONDEMANDLIBS) $(DNSSDLIBS) \
+ $(LIBGSSAPI) $(LIBWRAP)
#
@@ -402,6 +402,12 @@ cupsfilter: cupsfilter.o $(LIBCUPSMIME) ../cups/$(LIBCUPS)
$(RM) convert
$(LN) cupsfilter convert
+cupsfilter-static: cupsfilter.o libcupsmime.a ../cups/$(LIBCUPSSTATIC)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o cupsfilter-static cupsfilter.o libcupsmime.a \
+ ../cups/$(LIBCUPSSTATIC) $(COMMONLIBS) $(LIBZ) $(SSLLIBS) \
+ $(DNSSDLIBS) $(LIBGSSAPI)
+
#
# Make the device daemon, "cups-deviced".
@@ -441,10 +447,10 @@ cups-lpd: cups-lpd.o ../cups/$(LIBCUPS)
#
-# libcupsmime.so.1, libcupsmime.sl.1
+# libcupsmime.so.1
#
-libcupsmime.so.1 libcupsmime.sl.1: $(LIBOBJS)
+libcupsmime.so.1: $(LIBOBJS)
echo Linking $@...
$(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBS)
$(RM) `basename $@ .1`
@@ -468,17 +474,6 @@ libcupsmime.1.dylib: $(LIBOBJS) libcupsmime.exp
#
-# libcupsmime_s.a
-#
-
-libcupsmime_s.a: $(LIBOBJS)
- echo Creating $@...
- $(DSO) $(DSOFLAGS) -o libcupsmime_s.o $(LIBOBJS) $(LIBS)
- $(RM) $@
- $(AR) $(ARFLAGS) $@ libcupsmime_s.o
-
-
-#
# libcupsmime.la
#
@@ -559,5 +554,5 @@ include Dependencies
#
-# End of "$Id: Makefile 11173 2013-07-23 12:31:34Z msweet $".
+# End of "$Id: Makefile 12519 2015-02-17 13:10:19Z msweet $".
#
diff --git a/scheduler/auth.c b/scheduler/auth.c
index 1169adf..ac9badc 100644
--- a/scheduler/auth.c
+++ b/scheduler/auth.c
@@ -1,51 +1,19 @@
/*
- * "$Id: auth.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: auth.c 12945 2015-10-26 19:46:02Z msweet $"
*
- * Authorization routines for the CUPS scheduler.
+ * Authorization routines for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
- * This file contains Kerberos support code, copyright 2006 by
- * Jelmer Vernooij.
+ * This file contains Kerberos support code, copyright 2006 by
+ * Jelmer Vernooij.
*
- * 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:
- *
- * cupsdAddIPMask() - Add an IP address authorization mask.
- * cupsdAddLocation() - Add a location for authorization.
- * cupsdAddName() - Add a name to a location...
- * cupsdAddNameMask() - Add a host or interface name authorization
- * mask.
- * cupsdAuthorize() - Validate any authorization credentials.
- * cupsdCheckAccess() - Check whether the given address is allowed to
- * access a location.
- * cupsdCheckAuth() - Check authorization masks.
- * cupsdCheckGroup() - Check for a user's group membership.
- * cupsdCopyLocation() - Make a copy of a location...
- * cupsdDeleteAllLocations() - Free all memory used for location
- * authorization.
- * cupsdFindBest() - Find the location entry that best matches the
- * resource.
- * cupsdFindLocation() - Find the named location.
- * cupsdFreeLocation() - Free all memory used by a location.
- * cupsdIsAuthorized() - Check to see if the user is authorized...
- * cupsdNewLocation() - Create a new location for authorization.
- * check_authref() - Check if an authorization services reference
- * has the supplied right.
- * compare_locations() - Compare two locations.
- * copy_authmask() - Copy function for auth masks.
- * cups_crypt() - Encrypt the password using the DES or MD5
- * algorithms, as needed.
- * free_authmask() - Free function for auth masks.
- * get_md5_password() - Get an MD5 password.
- * pam_func() - PAM conversation function.
- * to64() - Base64-encode an integer value...
+ * 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/".
*/
/*
@@ -67,9 +35,6 @@
# include <security/pam_appl.h>
# endif /* HAVE_PAM_PAM_APPL_H */
#endif /* HAVE_LIBPAM */
-#ifdef HAVE_USERSEC_H
-# include <usersec.h>
-#endif /* HAVE_USERSEC_H */
#ifdef HAVE_MEMBERSHIP_H
# include <membership.h>
#endif /* HAVE_MEMBERSHIP_H */
@@ -108,16 +73,14 @@ static int check_authref(cupsd_client_t *con, const char *right);
static int compare_locations(cupsd_location_t *a,
cupsd_location_t *b);
static cupsd_authmask_t *copy_authmask(cupsd_authmask_t *am, void *data);
-#if !HAVE_LIBPAM && !defined(HAVE_USERSEC_H)
+#if !HAVE_LIBPAM
static char *cups_crypt(const char *pw, const char *salt);
-#endif /* !HAVE_LIBPAM && !HAVE_USERSEC_H */
+#endif /* !HAVE_LIBPAM */
static void free_authmask(cupsd_authmask_t *am, void *data);
-static char *get_md5_password(const char *username,
- const char *group, char passwd[33]);
#if HAVE_LIBPAM
static int pam_func(int, const struct pam_message **,
struct pam_response **, void *);
-#elif !defined(HAVE_USERSEC_H)
+#else
static void to64(char *s, unsigned long v, int n);
#endif /* HAVE_LIBPAM */
@@ -136,15 +99,6 @@ typedef struct cupsd_authdata_s /**** Authentication data ****/
/*
- * Local globals...
- */
-
-#if defined(__hpux) && HAVE_LIBPAM
-static cupsd_authdata_t *auth_data; /* Current client being authenticated */
-#endif /* __hpux && HAVE_LIBPAM */
-
-
-/*
* 'cupsdAddIPMask()' - Add an IP address authorization mask.
*/
@@ -157,12 +111,7 @@ cupsdAddIPMask(
cupsd_authmask_t temp; /* New host/domain mask */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdAddIPMask(masks=%p(%p), address=%x:%x:%x:%x, "
- "netmask=%x:%x:%x:%x)",
- masks, *masks,
- address[0], address[1], address[2], address[3],
- netmask[0], netmask[1], netmask[2], netmask[3]);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddIPMask(masks=%p(%p), address=%x:%x:%x:%x, netmask=%x:%x:%x:%x)", masks, *masks, address[0], address[1], address[2], address[3], netmask[0], netmask[1], netmask[2], netmask[3]);
temp.type = CUPSD_AUTH_IP;
memcpy(temp.mask.ip.address, address, sizeof(temp.mask.ip.address));
@@ -202,8 +151,7 @@ cupsdAddLocation(cupsd_location_t *loc) /* I - Location to add */
{
cupsArrayAdd(Locations, loc);
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddLocation: Added location \"%s\"",
- loc->location ? loc->location : "(null)");
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddLocation: Added location \"%s\"", loc->location ? loc->location : "(null)");
}
}
@@ -216,8 +164,7 @@ void
cupsdAddName(cupsd_location_t *loc, /* I - Location to add to */
char *name) /* I - Name to add */
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddName(loc=%p, name=\"%s\")",
- loc, name);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddName(loc=%p, name=\"%s\")", loc, name);
if (!loc->names)
loc->names = cupsArrayNew3(NULL, NULL, NULL, 0,
@@ -247,9 +194,7 @@ cupsdAddNameMask(cups_array_t **masks, /* IO - Masks array (created as needed) *
*ifptr; /* Pointer to end of name */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdAddNameMask(masks=%p(%p), name=\"%s\")",
- masks, *masks, name);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddNameMask(masks=%p(%p), name=\"%s\")", masks, *masks, name);
if (!_cups_strcasecmp(name, "@LOCAL"))
{
@@ -326,26 +271,6 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
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 */
- basicmd5[33]; /* MD5 of Basic password */
- static const char * const states[] = /* HTTP client states... */
- {
- "WAITING",
- "OPTIONS",
- "GET",
- "GET",
- "HEAD",
- "POST",
- "POST",
- "POST",
- "PUT",
- "PUT",
- "DELETE",
- "TRACE",
- "CLOSE",
- "STATUS"
- };
/*
@@ -353,13 +278,10 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* authentication to expect...
*/
- con->best = cupsdFindBest(con->uri, con->http.state);
+ con->best = cupsdFindBest(con->uri, httpGetState(con->http));
con->type = CUPSD_AUTH_NONE;
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] con->uri=\"%s\", con->best=%p(%s)",
- con->http.fd, con->uri, con->best,
- con->best ? con->best->location : "");
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "con->uri=\"%s\", con->best=%p(%s)", con->uri, con->best, con->best ? con->best->location : "");
if (con->best && con->best->type != CUPSD_AUTH_NONE)
{
@@ -375,10 +297,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* Decode the Authorization string...
*/
- authorization = httpGetField(&con->http, HTTP_FIELD_AUTHORIZATION);
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "[Client %d] Authorization=\"%s\"",
- con->http.fd, authorization);
+ authorization = httpGetField(con->http, HTTP_FIELD_AUTHORIZATION);
username[0] = '\0';
password[0] = '\0';
@@ -401,16 +320,16 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* No authorization data provided, return early...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] No authentication data provided.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "No authentication data provided.");
return;
}
#ifdef HAVE_AUTHORIZATION_H
else if (!strncmp(authorization, "AuthRef ", 8) &&
- !_cups_strcasecmp(con->http.hostname, "localhost"))
+ httpAddrLocalhost(httpGetAddress(con->http)))
{
OSStatus status; /* Status */
+ char authdata[HTTP_MAX_VALUE];
+ /* Nonce value from client */
int authlen; /* Auth string length */
AuthorizationItemSet *authinfo; /* Authorization item set */
@@ -422,24 +341,18 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
while (isspace(*authorization & 255))
authorization ++;
- authlen = sizeof(nonce);
- httpDecode64_2(nonce, &authlen, authorization);
+ authlen = sizeof(authdata);
+ httpDecode64_2(authdata, &authlen, authorization);
if (authlen != kAuthorizationExternalFormLength)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] External Authorization reference size is "
- "incorrect.", con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "External Authorization reference size is incorrect.");
return;
}
- if ((status = AuthorizationCreateFromExternalForm(
- (AuthorizationExternalForm *)nonce, &con->authref)) != 0)
+ if ((status = AuthorizationCreateFromExternalForm((AuthorizationExternalForm *)authdata, &con->authref)) != 0)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] AuthorizationCreateFromExternalForm "
- "returned %d (%s)", con->http.fd, (int)status,
- cssmErrorString(status));
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "AuthorizationCreateFromExternalForm returned %d (%s)", (int)status, cssmErrorString(status));
return;
}
@@ -453,9 +366,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
{
strlcpy(username, authinfo->items[0].value, sizeof(username));
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Authorized as \"%s\" using AuthRef",
- con->http.fd, username);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as \"%s\" using AuthRef.", username);
}
AuthorizationFreeItemSet(authinfo);
@@ -473,28 +384,21 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
peersize = sizeof(peercred);
- if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
+ if (getsockopt(httpGetFd(con->http), 0, LOCAL_PEERCRED, &peercred, &peersize))
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unable to get peer credentials - %s",
- con->http.fd, strerror(errno));
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to get peer credentials - %s", strerror(errno));
return;
}
if ((pwd = getpwuid(CUPSD_UCRED_UID(peercred))) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unable to find UID %d for peer "
- "credentials.", con->http.fd,
- (int)CUPSD_UCRED_UID(peercred));
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to find UID %d for peer credentials.", (int)CUPSD_UCRED_UID(peercred));
return;
}
strlcpy(username, pwd->pw_name, sizeof(username));
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Authorized as \"%s\" using "
- "AuthRef + PeerCred", con->http.fd, username);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as \"%s\" using AuthRef + PeerCred.", username);
}
con->type = CUPSD_AUTH_BASIC;
@@ -502,7 +406,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
#endif /* HAVE_AUTHORIZATION_H */
#if defined(SO_PEERCRED) && defined(AF_LOCAL)
else if (!strncmp(authorization, "PeerCred ", 9) &&
- con->http.hostaddr->addr.sa_family == AF_LOCAL)
+ con->http->hostaddr->addr.sa_family == AF_LOCAL && con->best)
{
/*
* Use peer credentials from domain socket connection...
@@ -539,50 +443,37 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (no_peer)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] PeerCred authentication not allowed for "
- "resource per AUTHKEY policy.", con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "PeerCred authentication not allowed for resource per AUTHKEY policy.");
return;
}
#endif /* HAVE_AUTHORIZATION_H */
if ((pwd = getpwnam(authorization + 9)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] User \"%s\" does not exist.", con->http.fd,
- authorization + 9);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "User \"%s\" does not exist.", authorization + 9);
return;
}
peersize = sizeof(peercred);
# ifdef __APPLE__
- if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
+ if (getsockopt(httpGetFd(con->http), 0, LOCAL_PEERCRED, &peercred, &peersize))
# else
- if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred, &peersize))
+ if (getsockopt(httpGetFd(con->http), SOL_SOCKET, SO_PEERCRED, &peercred, &peersize))
# endif /* __APPLE__ */
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unable to get peer credentials - %s",
- con->http.fd, strerror(errno));
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to get peer credentials - %s", strerror(errno));
return;
}
if (pwd->pw_uid != CUPSD_UCRED_UID(peercred))
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Invalid peer credentials for \"%s\" - got "
- "%d, expected %d!", con->http.fd, authorization + 9,
- CUPSD_UCRED_UID(peercred), pwd->pw_uid);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Invalid peer credentials for \"%s\" - got %d, expected %d.", authorization + 9, CUPSD_UCRED_UID(peercred), pwd->pw_uid);
# ifdef HAVE_SYS_UCRED_H
- 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]);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cr_version=%d", peercred.cr_version);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cr_uid=%d", peercred.cr_uid);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cr_ngroups=%d", peercred.cr_ngroups);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cr_groups[0]=%d", peercred.cr_groups[0]);
# endif /* HAVE_SYS_UCRED_H */
return;
}
@@ -593,15 +484,13 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
con->gss_uid = CUPSD_UCRED_UID(peercred);
# endif /* HAVE_GSSAPI */
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Authorized as %s using PeerCred", con->http.fd,
- username);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as %s using PeerCred.", username);
con->type = CUPSD_AUTH_BASIC;
}
#endif /* SO_PEERCRED && AF_LOCAL */
else if (!strncmp(authorization, "Local", 5) &&
- !_cups_strcasecmp(con->http.hostname, "localhost"))
+ httpAddrLocalhost(httpGetAddress(con->http)))
{
/*
* Get Local certificate authentication data...
@@ -613,18 +502,14 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if ((localuser = cupsdFindCert(authorization)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Local authentication certificate not found.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Local authentication certificate not found.");
return;
}
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);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as %s using Local.", username);
}
else if (!strncmp(authorization, "Basic", 5))
{
@@ -648,8 +533,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if ((ptr = strchr(username, ':')) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "[Client %d] Missing Basic password.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Missing Basic password.");
return;
}
@@ -661,8 +545,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* Username must not be empty...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR, "[Client %d] Empty Basic username.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Empty Basic username.");
return;
}
@@ -672,8 +555,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* Password must not be empty...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR, "[Client %d] Empty Basic password.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Empty Basic password.");
return;
}
@@ -703,59 +585,40 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
strlcpy(data.username, username, sizeof(data.username));
strlcpy(data.password, password, sizeof(data.password));
-# if defined(__sun) || defined(__hpux)
+# ifdef __sun
pamdata.conv = (int (*)(int, struct pam_message **,
struct pam_response **,
void *))pam_func;
# else
pamdata.conv = pam_func;
-# endif /* __sun || __hpux */
+# endif /* __sun */
pamdata.appdata_ptr = &data;
-# ifdef __hpux
- /*
- * Workaround for HP-UX bug in pam_unix; see pam_func() below for
- * more info...
- */
-
- auth_data = &data;
-# endif /* __hpux */
-
pamerr = pam_start("cups", username, &pamdata, &pamh);
if (pamerr != PAM_SUCCESS)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] pam_start() returned %d (%s)",
- con->http.fd, pamerr, pam_strerror(pamh, pamerr));
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "pam_start() returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
return;
}
# ifdef HAVE_PAM_SET_ITEM
# ifdef PAM_RHOST
- pamerr = pam_set_item(pamh, PAM_RHOST, con->http.hostname);
+ pamerr = pam_set_item(pamh, PAM_RHOST, con->http->hostname);
if (pamerr != PAM_SUCCESS)
- cupsdLogMessage(CUPSD_LOG_WARN,
- "[Client %d] pam_set_item(PAM_RHOST) "
- "returned %d (%s)", con->http.fd, pamerr,
- pam_strerror(pamh, pamerr));
+ cupsdLogClient(con, CUPSD_LOG_WARN, "pam_set_item(PAM_RHOST) returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
# endif /* PAM_RHOST */
# ifdef PAM_TTY
pamerr = pam_set_item(pamh, PAM_TTY, "cups");
if (pamerr != PAM_SUCCESS)
- cupsdLogMessage(CUPSD_LOG_WARN,
- "[Client %d] pam_set_item(PAM_TTY) "
- "returned %d (%s)!", con->http.fd, pamerr,
- pam_strerror(pamh, pamerr));
+ cupsdLogClient(con, CUPSD_LOG_WARN, "pam_set_item(PAM_TTY) returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
# endif /* PAM_TTY */
# endif /* HAVE_PAM_SET_ITEM */
pamerr = pam_authenticate(pamh, PAM_SILENT);
if (pamerr != PAM_SUCCESS)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] pam_authenticate() returned %d (%s)",
- con->http.fd, pamerr, pam_strerror(pamh, pamerr));
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "pam_authenticate() returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
pam_end(pamh, 0);
return;
}
@@ -763,47 +626,19 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
# ifdef HAVE_PAM_SETCRED
pamerr = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT);
if (pamerr != PAM_SUCCESS)
- cupsdLogMessage(CUPSD_LOG_WARN,
- "[Client %d] pam_setcred() returned %d (%s)",
- con->http.fd, pamerr,
- pam_strerror(pamh, pamerr));
+ cupsdLogClient(con, CUPSD_LOG_WARN, "pam_setcred() returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
# endif /* HAVE_PAM_SETCRED */
pamerr = pam_acct_mgmt(pamh, PAM_SILENT);
if (pamerr != PAM_SUCCESS)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] pam_acct_mgmt() returned %d (%s)",
- con->http.fd, pamerr, pam_strerror(pamh, pamerr));
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "pam_acct_mgmt() returned %d (%s)", pamerr, pam_strerror(pamh, pamerr));
pam_end(pamh, 0);
return;
}
pam_end(pamh, PAM_SUCCESS);
-#elif defined(HAVE_USERSEC_H)
- /*
- * Use AIX authentication interface...
- */
-
- char *authmsg; /* Authentication message */
- int reenter; /* ??? */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] AIX authenticate of username \"%s\"",
- con->http.fd, username);
-
- reenter = 1;
- if (authenticate(username, password, &reenter, &authmsg) != 0)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Unable to authenticate username "
- "\"%s\": %s", con->http.fd, username,
- strerror(errno));
- return;
- }
-
#else
/*
* Use normal UNIX password file-based authentication...
@@ -825,9 +660,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* No such user...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unknown username \"%s\".",
- con->http.fd, username);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Unknown username \"%s\".", username);
return;
}
@@ -841,9 +674,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* Don't allow blank passwords!
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Username \"%s\" has no shadow "
- "password.", con->http.fd, username);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Username \"%s\" has no shadow password.", username);
return;
}
@@ -856,9 +687,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* Don't allow blank passwords!
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Username \"%s\" has no password.",
- con->http.fd, username);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Username \"%s\" has no password.", username);
return;
}
@@ -869,10 +698,6 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
pass = cups_crypt(password, pw->pw_passwd);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] pw_passwd=\"%s\", crypt=\"%s\"",
- con->http.fd, pw->pw_passwd, pass);
-
if (!pass || strcmp(pw->pw_passwd, pass))
{
# ifdef HAVE_SHADOW_H
@@ -880,143 +705,28 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
{
pass = cups_crypt(password, spw->sp_pwdp);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[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,
- "[Client %d] Authentication failed for user "
- "\"%s\".", con->http.fd, username);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Authentication failed for user \"%s\".", username);
return;
}
}
else
# endif /* HAVE_SHADOW_H */
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Authentication failed for user "
- "\"%s\".", con->http.fd, username);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Authentication failed for user \"%s\".", username);
return;
}
}
#endif /* HAVE_LIBPAM */
}
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Authorized as %s using Basic",
- con->http.fd, username);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as \"%s\" using Basic.", username);
break;
-
- case CUPSD_AUTH_BASICDIGEST :
- /*
- * Do Basic authentication with the Digest password file...
- */
-
- if (!get_md5_password(username, NULL, md5))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unknown MD5 username \"%s\".",
- con->http.fd, username);
- return;
- }
-
- httpMD5(username, "CUPS", password, basicmd5);
-
- if (strcmp(md5, basicmd5))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Authentication failed for \"%s\".",
- con->http.fd, username);
- return;
- }
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Authorized as %s using BasicDigest",
- con->http.fd, username);
- break;
}
con->type = type;
}
- else if (!strncmp(authorization, "Digest", 6))
- {
- /*
- * Get the username, password, and nonce from the Digest attributes...
- */
-
- if (!httpGetSubField2(&(con->http), HTTP_FIELD_AUTHORIZATION, "username",
- username, sizeof(username)) || !username[0])
- {
- /*
- * Username must not be empty...
- */
-
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Empty or missing Digest username.",
- con->http.fd);
- return;
- }
-
- if (!httpGetSubField2(&(con->http), HTTP_FIELD_AUTHORIZATION, "response",
- password, sizeof(password)) || !password[0])
- {
- /*
- * Password must not be empty...
- */
-
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Empty or missing Digest password.",
- con->http.fd);
- return;
- }
-
- if (!httpGetSubField(&(con->http), HTTP_FIELD_AUTHORIZATION, "nonce",
- nonce))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] No nonce value for Digest authentication.",
- con->http.fd);
- return;
- }
-
- if (strcmp(con->http.hostname, nonce))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Bad nonce value, expected \"%s\", "
- "got \"%s\".", con->http.fd, con->http.hostname, nonce);
- return;
- }
-
- /*
- * Validate the username and password...
- */
-
- if (!get_md5_password(username, NULL, md5))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unknown MD5 username \"%s\".",
- con->http.fd, username);
- return;
- }
-
- httpMD5Final(nonce, states[con->http.state], con->uri, md5);
-
- if (strcmp(md5, password))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Authentication failed for \"%s\".",
- con->http.fd, username);
- return;
- }
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Authorized as %s using Digest", con->http.fd,
- username);
-
- con->type = CUPSD_AUTH_DIGEST;
- }
#ifdef HAVE_GSSAPI
else if (!strncmp(authorization, "Negotiate", 9))
{
@@ -1037,12 +747,9 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* to use it...
*/
- if (gss_init_sec_context == NULL)
+ if (&gss_init_sec_context == NULL)
{
- cupsdLogMessage(CUPSD_LOG_WARN,
- "[Client %d] GSSAPI/Kerberos authentication failed "
- "because the Kerberos framework is not present.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_WARN, "GSSAPI/Kerberos authentication failed because the Kerberos framework is not present.");
return;
}
# endif /* __APPLE__ */
@@ -1057,9 +764,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (!*authorization)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] No authentication data specified.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "No authentication data specified.");
return;
}
@@ -1067,11 +772,11 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* Decode the authorization string to get the input token...
*/
- len = strlen(authorization);
- input_token.value = malloc(len);
+ len = (int)strlen(authorization);
+ input_token.value = malloc((size_t)len);
input_token.value = httpDecode64_2(input_token.value, &len,
authorization);
- input_token.length = len;
+ input_token.length = (size_t)len;
/*
* Accept the input token to get the authorization info...
@@ -1096,9 +801,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (GSS_ERROR(major_status))
{
- cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
- "[Client %d] Error accepting GSSAPI security context",
- con->http.fd);
+ cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, "[Client %d] Error accepting GSSAPI security context.", con->number);
if (context != GSS_C_NO_CONTEXT)
gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
@@ -1112,8 +815,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
*/
if (major_status == GSS_S_CONTINUE_NEEDED)
- cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
- "[Client %d] Credentials not complete", con->http.fd);
+ cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, "[Client %d] Credentials not complete.", con->number);
else if (major_status == GSS_S_COMPLETE)
{
major_status = gss_display_name(&minor_status, client_name,
@@ -1121,8 +823,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (GSS_ERROR(major_status))
{
- cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status,
- "[Client %d] Error getting username", con->http.fd);
+ cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, "[Client %d] Error getting username.", con->number);
gss_release_name(&minor_status, &client_name);
gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER);
return;
@@ -1130,9 +831,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
strlcpy(username, output_token.value, sizeof(username));
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Authorized as %s using Negotiate",
- con->http.fd, username);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Authorized as \"%s\" using Negotiate.", username);
gss_release_name(&minor_status, &client_name);
gss_release_buffer(&minor_status, &output_token);
@@ -1148,7 +847,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
* to run as the correct user to get Kerberos credentials of its own.
*/
- if (_httpAddrFamily(con->http.hostaddr) == AF_LOCAL)
+ if (httpAddrFamily(con->http->hostaddr) == AF_LOCAL)
{
cupsd_ucred_t peercred; /* Peer credentials */
socklen_t peersize; /* Size of peer credentials */
@@ -1156,21 +855,17 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
peersize = sizeof(peercred);
# ifdef __APPLE__
- if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize))
+ if (getsockopt(httpGetFd(con->http), 0, LOCAL_PEERCRED, &peercred, &peersize))
# else
- if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred,
+ if (getsockopt(httpGetFd(con->http), SOL_SOCKET, SO_PEERCRED, &peercred,
&peersize))
# endif /* __APPLE__ */
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unable to get peer credentials - %s",
- con->http.fd, strerror(errno));
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to get peer credentials - %s", strerror(errno));
}
else
{
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Using credentials for UID %d.",
- con->http.fd, CUPSD_UCRED_UID(peercred));
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Using credentials for UID %d.", CUPSD_UCRED_UID(peercred));
con->gss_uid = CUPSD_UCRED_UID(peercred);
}
}
@@ -1183,11 +878,9 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
if (sscanf(authorization, "%255s", scheme) != 1)
- strcpy(scheme, "UNKNOWN");
+ strlcpy(scheme, "UNKNOWN", sizeof(scheme));
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Bad authentication data \"%s ...\"",
- con->http.fd, scheme);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Bad authentication data \"%s ...\".", scheme);
return;
}
@@ -1210,8 +903,8 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
int /* O - 1 if allowed, 0 otherwise */
cupsdCheckAccess(
unsigned ip[4], /* I - Client address */
- char *name, /* I - Client hostname */
- int namelen, /* I - Length of hostname */
+ const char *name, /* I - Client hostname */
+ size_t namelen, /* I - Length of hostname */
cupsd_location_t *loc) /* I - Location to check */
{
int allow; /* 1 if allowed, 0 otherwise */
@@ -1269,8 +962,8 @@ cupsdCheckAccess(
int /* O - 1 if mask matches, 0 otherwise */
cupsdCheckAuth(unsigned ip[4], /* I - Client address */
- char *name, /* I - Client hostname */
- int name_len, /* I - Length of hostname */
+ const char *name, /* I - Client hostname */
+ size_t name_len, /* I - Length of hostname */
cups_array_t *masks) /* I - Masks */
{
int i; /* Looping var */
@@ -1302,6 +995,8 @@ cupsdCheckAuth(unsigned ip[4], /* I - Client address */
netip6[3] = htonl(ip[3]);
#endif /* AF_INET6 */
+ cupsdNetIFUpdate();
+
if (!strcmp(mask->mask.name.name, "*"))
{
#ifdef __APPLE__
@@ -1317,8 +1012,6 @@ cupsdCheckAuth(unsigned ip[4], /* I - Client address */
* Check against all local interfaces...
*/
- cupsdNetIFUpdate();
-
for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList);
iface;
iface = (cupsd_netif_t *)cupsArrayNext(NetIFList))
@@ -1456,7 +1149,6 @@ cupsdCheckGroup(
{
int i; /* Looping var */
struct group *group; /* System group info */
- char junk[33]; /* MD5 password (not used) */
#ifdef HAVE_MBR_UID_TO_UUID
uuid_t useruuid, /* UUID for username */
groupuuid; /* UUID for groupname */
@@ -1464,9 +1156,7 @@ cupsdCheckGroup(
#endif /* HAVE_MBR_UID_TO_UUID */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdCheckGroup(username=\"%s\", user=%p, groupname=\"%s\")",
- username, user, groupname);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckGroup(username=\"%s\", user=%p, groupname=\"%s\")", username, user, groupname);
/*
* Validate input...
@@ -1543,15 +1233,6 @@ cupsdCheckGroup(
#endif /* HAVE_MBR_UID_TO_UUID */
/*
- * Username not found, group not found, or user is not part of the
- * system group... Check for a user and group in the MD5 password
- * file...
- */
-
- if (get_md5_password(username, groupname, junk) != NULL)
- return (1);
-
- /*
* If we get this far, then the user isn't part of the named group...
*/
@@ -1587,6 +1268,7 @@ cupsdCopyLocation(
if (loc->location)
temp->location = _cupsStrAlloc(loc->location);
+ temp->length = loc->length;
temp->limit = loc->limit;
temp->order_type = loc->order_type;
temp->type = loc->type;
@@ -1672,7 +1354,7 @@ cupsdFindBest(const char *path, /* I - Resource path */
*uriptr; /* Pointer into URI */
cupsd_location_t *loc, /* Current location */
*best; /* Best match for location so far */
- int bestlen; /* Length of best match */
+ size_t bestlen; /* Length of best match */
int limit; /* Limit field */
static const int limits[] = /* Map http_status_t to CUPSD_AUTH_LIMIT_xyz */
{
@@ -1689,6 +1371,8 @@ cupsdFindBest(const char *path, /* I - Resource path */
CUPSD_AUTH_LIMIT_DELETE,
CUPSD_AUTH_LIMIT_TRACE,
CUPSD_AUTH_LIMIT_ALL,
+ CUPSD_AUTH_LIMIT_ALL,
+ CUPSD_AUTH_LIMIT_ALL,
CUPSD_AUTH_LIMIT_ALL
};
@@ -1701,6 +1385,12 @@ cupsdFindBest(const char *path, /* I - Resource path */
strlcpy(uri, path, sizeof(uri));
+ if ((uriptr = strchr(uri, '?')) != NULL)
+ *uriptr = '\0'; /* Drop trailing query string */
+
+ if ((uriptr = uri + strlen(uri) - 1) > uri && *uriptr == '/')
+ *uriptr = '\0'; /* Remove trailing '/' */
+
if (!strncmp(uri, "/printers/", 10) ||
!strncmp(uri, "/classes/", 9))
{
@@ -1714,8 +1404,6 @@ cupsdFindBest(const char *path, /* I - Resource path */
*uriptr = '\0';
}
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: uri = \"%s\"...", uri);
-
/*
* Loop through the list of locations to find a match...
*/
@@ -1724,12 +1412,14 @@ cupsdFindBest(const char *path, /* I - Resource path */
best = NULL;
bestlen = 0;
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: uri=\"%s\", limit=%x...", uri, limit);
+
+
for (loc = (cupsd_location_t *)cupsArrayFirst(Locations);
loc;
loc = (cupsd_location_t *)cupsArrayNext(Locations))
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: Location %s Limit %x",
- loc->location ? loc->location : "nil", loc->limit);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: Location %s(%d) Limit %x", loc->location ? loc->location : "(null)", (int)loc->length, loc->limit);
if (!strncmp(uri, "/printers/", 10) || !strncmp(uri, "/classes/", 9))
{
@@ -1767,8 +1457,7 @@ cupsdFindBest(const char *path, /* I - Resource path */
* Return the match, if any...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: best = %s",
- best ? best->location : "NONE");
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: best=%s", best ? best->location : "NONE");
return (best);
}
@@ -1817,9 +1506,13 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
int i, /* Looping vars */
auth, /* Authorization status */
type; /* Type of authentication */
+ http_addr_t *hostaddr = httpGetAddress(con->http);
+ /* Client address */
+ const char *hostname = httpGetHostname(con->http, NULL, 0);
+ /* Client hostname */
unsigned address[4]; /* Authorization address */
cupsd_location_t *best; /* Best match for location so far */
- int hostlen; /* Length of hostname */
+ size_t hostlen; /* Length of hostname */
char *name, /* Current username */
username[256], /* Username to authorize */
ownername[256], /* Owner name to authorize */
@@ -1835,19 +1528,13 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
{
"None",
"Basic",
- "Digest",
- "BasicDigest",
"Negotiate"
};
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdIsAuthorized: con->uri=\"%s\", con->best=%p(%s)",
- con->uri, con->best, con->best ? con->best->location ?
- con->best->location : "(null)" : "");
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: con->uri=\"%s\", con->best=%p(%s)", con->uri, con->best, con->best ? con->best->location ? con->best->location : "(null)" : "");
if (owner)
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdIsAuthorized: owner=\"%s\"", owner);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: owner=\"%s\"", owner);
/*
* If there is no "best" authentication rule for this request, then
@@ -1857,8 +1544,9 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
if (!con->best)
{
- if (!strcmp(con->http.hostname, "localhost") ||
- !strcmp(con->http.hostname, ServerName))
+ if (httpAddrLocalhost(httpGetAddress(con->http)) ||
+ !strcmp(hostname, ServerName) ||
+ cupsArrayFind(ServerAlias, (void *)hostname))
return (HTTP_OK);
else
return (HTTP_FORBIDDEN);
@@ -1869,35 +1557,30 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
if ((type = best->type) == CUPSD_AUTH_DEFAULT)
type = cupsdDefaultAuthType();
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdIsAuthorized: level=CUPSD_AUTH_%s, type=%s, "
- "satisfy=CUPSD_AUTH_SATISFY_%s, num_names=%d",
- levels[best->level], types[type],
- best->satisfy ? "ANY" : "ALL", cupsArrayCount(best->names));
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: level=CUPSD_AUTH_%s, type=%s, satisfy=CUPSD_AUTH_SATISFY_%s, num_names=%d", levels[best->level], types[type], best->satisfy ? "ANY" : "ALL", cupsArrayCount(best->names));
if (best->limit == CUPSD_AUTH_LIMIT_IPP)
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: op=%x(%s)",
- best->op, ippOpString(best->op));
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: op=%x(%s)", best->op, ippOpString(best->op));
/*
* Check host/ip-based accesses...
*/
#ifdef AF_INET6
- if (con->http.hostaddr->addr.sa_family == AF_INET6)
+ if (httpAddrFamily(hostaddr) == AF_INET6)
{
/*
* Copy IPv6 address...
*/
- address[0] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[0]);
- address[1] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[1]);
- address[2] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2]);
- address[3] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[3]);
+ address[0] = ntohl(hostaddr->ipv6.sin6_addr.s6_addr32[0]);
+ address[1] = ntohl(hostaddr->ipv6.sin6_addr.s6_addr32[1]);
+ address[2] = ntohl(hostaddr->ipv6.sin6_addr.s6_addr32[2]);
+ address[3] = ntohl(hostaddr->ipv6.sin6_addr.s6_addr32[3]);
}
else
#endif /* AF_INET6 */
- if (con->http.hostaddr->addr.sa_family == AF_INET)
+ if (con->http->hostaddr->addr.sa_family == AF_INET)
{
/*
* Copy IPv4 address...
@@ -1906,18 +1589,17 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
address[0] = 0;
address[1] = 0;
address[2] = 0;
- address[3] = ntohl(con->http.hostaddr->ipv4.sin_addr.s_addr);
+ address[3] = ntohl(hostaddr->ipv4.sin_addr.s_addr);
}
else
memset(address, 0, sizeof(address));
- hostlen = strlen(con->http.hostname);
+ hostlen = strlen(hostname);
- auth = cupsdCheckAccess(address, con->http.hostname, hostlen, best)
+ auth = cupsdCheckAccess(address, hostname, hostlen, best)
? CUPSD_AUTH_ALLOW : CUPSD_AUTH_DENY;
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: auth=CUPSD_AUTH_%s...",
- auth ? "DENY" : "ALLOW");
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: auth=CUPSD_AUTH_%s...", auth ? "DENY" : "ALLOW");
if (auth == CUPSD_AUTH_DENY && best->satisfy == CUPSD_AUTH_SATISFY_ALL)
return (HTTP_FORBIDDEN);
@@ -1927,8 +1609,9 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
* See if encryption is required...
*/
- if ((best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls &&
- _cups_strcasecmp(con->http.hostname, "localhost") &&
+ if ((best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http->tls &&
+ _cups_strcasecmp(hostname, "localhost") &&
+ !httpAddrLocalhost(hostaddr) &&
best->satisfy == CUPSD_AUTH_SATISFY_ALL) &&
!(type == CUPSD_AUTH_NEGOTIATE ||
(type == CUPSD_AUTH_NONE &&
@@ -1993,9 +1676,9 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
#ifdef HAVE_GSSAPI
(type != CUPSD_AUTH_NEGOTIATE || con->gss_uid <= 0) &&
#endif /* HAVE_GSSAPI */
- (con->type != CUPSD_AUTH_BASIC || type != CUPSD_AUTH_BASICDIGEST))
+ con->type != CUPSD_AUTH_BASIC)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Authorized using %s, expected %s!",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Authorized using %s, expected %s.",
types[con->type], types[type]);
return (HTTP_UNAUTHORIZED);
@@ -2056,8 +1739,7 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
* allowed...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdIsAuthorized: Checking user membership...");
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: Checking user membership...");
#ifdef HAVE_AUTHORIZATION_H
/*
@@ -2110,8 +1792,7 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
* Check to see if this user is in any of the named groups...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdIsAuthorized: Checking group membership...");
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: Checking group membership...");
/*
* Check to see if this user is in any of the named groups...
@@ -2121,9 +1802,7 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
name;
name = (char *)cupsArrayNext(best->names))
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdIsAuthorized: Checking group \"%s\" membership...",
- name);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: Checking group \"%s\" membership...", name);
if (!_cups_strcasecmp(name, "@SYSTEM"))
{
@@ -2139,8 +1818,7 @@ cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */
* The user isn't part of the specified group, so deny access...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdIsAuthorized: User not in group(s)!");
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdIsAuthorized: User not in group(s).");
return (con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED);
}
@@ -2230,9 +1908,7 @@ check_authref(cupsd_client_t *con, /* I - Connection */
return (0);
}
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "AuthorizationCopyRights(\"%s\") succeeded!",
- authright.name);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "AuthorizationCopyRights(\"%s\") succeeded.", authright.name);
return (1);
}
@@ -2290,7 +1966,7 @@ copy_authmask(cupsd_authmask_t *mask, /* I - Existing auth mask */
}
-#if !HAVE_LIBPAM && !defined(HAVE_USERSEC_H)
+#if !HAVE_LIBPAM
/*
* 'cups_crypt()' - Encrypt the password using the DES or MD5 algorithms,
* as needed.
@@ -2379,23 +2055,23 @@ cups_crypt(const char *pw, /* I - Password string */
* Copy the final sum to the result string and return...
*/
- memcpy(result, salt, salt_end - salt);
+ memcpy(result, salt, (size_t)(salt_end - salt));
ptr = result + (salt_end - salt);
*ptr++ = '$';
for (i = 0; i < 5; i ++, ptr += 4)
{
- n = (((digest[i] << 8) | digest[i + 6]) << 8);
+ n = ((((unsigned)digest[i] << 8) | (unsigned)digest[i + 6]) << 8);
if (i < 4)
- n |= digest[i + 12];
+ n |= (unsigned)digest[i + 12];
else
- n |= digest[5];
+ n |= (unsigned)digest[5];
to64(ptr, n, 4);
}
- to64(ptr, digest[11], 2);
+ to64(ptr, (unsigned)digest[11], 2);
ptr += 2;
*ptr = '\0';
@@ -2410,7 +2086,7 @@ cups_crypt(const char *pw, /* I - Password string */
return (crypt(pw, salt));
}
}
-#endif /* !HAVE_LIBPAM && !HAVE_USERSEC_H */
+#endif /* !HAVE_LIBPAM */
/*
@@ -2430,68 +2106,6 @@ free_authmask(cupsd_authmask_t *mask, /* I - Auth mask to free */
}
-/*
- * 'get_md5_password()' - Get an MD5 password.
- */
-
-static char * /* O - MD5 password string */
-get_md5_password(const char *username, /* I - Username */
- const char *group, /* I - Group */
- char passwd[33]) /* O - MD5 password string */
-{
- cups_file_t *fp; /* passwd.md5 file */
- char filename[1024], /* passwd.md5 filename */
- line[256], /* Line from file */
- tempuser[33], /* User from file */
- tempgroup[33]; /* Group from file */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "get_md5_password(username=\"%s\", group=\"%s\", passwd=%p)",
- username, group ? group : "(null)", passwd);
-
- snprintf(filename, sizeof(filename), "%s/passwd.md5", ServerRoot);
- if ((fp = cupsFileOpen(filename, "r")) == NULL)
- {
- if (errno != ENOENT)
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open %s - %s", filename,
- strerror(errno));
-
- return (NULL);
- }
-
- while (cupsFileGets(fp, line, sizeof(line)) != NULL)
- {
- if (sscanf(line, "%32[^:]:%32[^:]:%32s", tempuser, tempgroup, passwd) != 3)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad MD5 password line: %s", line);
- continue;
- }
-
- if (!strcmp(username, tempuser) &&
- (group == NULL || !strcmp(group, tempgroup)))
- {
- /*
- * Found the password entry!
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "Found MD5 user %s, group %s...",
- username, tempgroup);
-
- cupsFileClose(fp);
- return (passwd);
- }
- }
-
- /*
- * Didn't find a password entry - return NULL!
- */
-
- cupsFileClose(fp);
- return (NULL);
-}
-
-
#if HAVE_LIBPAM
/*
* 'pam_func()' - PAM conversation function.
@@ -2514,7 +2128,7 @@ pam_func(
* Allocate memory for the responses...
*/
- if ((replies = malloc(sizeof(struct pam_response) * num_msg)) == NULL)
+ if ((replies = malloc(sizeof(struct pam_response) * (size_t)num_msg)) == NULL)
return (PAM_CONV_ERR);
/*
@@ -2523,17 +2137,7 @@ pam_func(
DEBUG_printf(("pam_func: appdata_ptr = %p\n", appdata_ptr));
-#ifdef __hpux
- /*
- * Apparently some versions of HP-UX 11 have a broken pam_unix security
- * module. This is a workaround...
- */
-
- data = auth_data;
- (void)appdata_ptr;
-#else
data = (cupsd_authdata_t *)appdata_ptr;
-#endif /* __hpux */
for (i = 0; i < num_msg; i ++)
{
@@ -2583,7 +2187,7 @@ pam_func(
return (PAM_SUCCESS);
}
-#elif !defined(HAVE_USERSEC_H)
+#else
/*
@@ -2607,5 +2211,5 @@ to64(char *s, /* O - Output string */
/*
- * End of "$Id: auth.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: auth.c 12945 2015-10-26 19:46:02Z msweet $".
*/
diff --git a/scheduler/auth.h b/scheduler/auth.h
index 8979023..c42c0a2 100644
--- a/scheduler/auth.h
+++ b/scheduler/auth.h
@@ -1,16 +1,16 @@
/*
- * "$Id: auth.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: auth.h 11776 2014-03-28 19:16:05Z msweet $"
*
- * Authorization definitions for the CUPS scheduler.
+ * Authorization definitions for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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/".
+ * 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/".
*/
/*
@@ -27,10 +27,8 @@
#define CUPSD_AUTH_DEFAULT -1 /* Use DefaultAuthType */
#define CUPSD_AUTH_NONE 0 /* No authentication */
#define CUPSD_AUTH_BASIC 1 /* Basic authentication */
-#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_NEGOTIATE 2 /* Kerberos authentication */
+#define CUPSD_AUTH_AUTO 3 /* 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 */
@@ -74,7 +72,7 @@ typedef struct
typedef struct
{
- int length; /* Length of name */
+ size_t length; /* Length of name */
char *name; /* Name string */
} cupsd_namemask_t;
@@ -91,9 +89,9 @@ typedef struct
typedef struct
{
char *location; /* Location of resource */
+ size_t length; /* Length of location string */
ipp_op_t op; /* IPP operation */
int limit, /* Limit for these types of requests */
- length, /* Length of location string */
order_type, /* Allow or Deny */
type, /* Type of authentication */
level, /* Access level required */
@@ -130,10 +128,8 @@ extern void cupsdAddLocation(cupsd_location_t *loc);
extern void cupsdAddName(cupsd_location_t *loc, char *name);
extern int cupsdAddNameMask(cups_array_t **masks, char *name);
extern void cupsdAuthorize(cupsd_client_t *con);
-extern int cupsdCheckAccess(unsigned ip[4], char *name,
- int namelen, cupsd_location_t *loc);
-extern int cupsdCheckAuth(unsigned ip[4], char *name, int namelen,
- cups_array_t *masks);
+extern int cupsdCheckAccess(unsigned ip[4], const char *name, size_t namelen, cupsd_location_t *loc);
+extern int cupsdCheckAuth(unsigned ip[4], const char *name, size_t namelen, cups_array_t *masks);
extern int cupsdCheckGroup(const char *username,
struct passwd *user,
const char *groupname);
@@ -147,5 +143,5 @@ extern cupsd_location_t *cupsdNewLocation(const char *location);
/*
- * End of "$Id: auth.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: auth.h 11776 2014-03-28 19:16:05Z msweet $".
*/
diff --git a/scheduler/banners.c b/scheduler/banners.c
index 87a1a68..631a891 100644
--- a/scheduler/banners.c
+++ b/scheduler/banners.c
@@ -1,5 +1,5 @@
/*
- * "$Id: banners.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: banners.c 10996 2013-05-29 11:51:34Z msweet $"
*
* Banner routines for the CUPS scheduler.
*
@@ -220,5 +220,5 @@ free_banners(void)
/*
- * End of "$Id: banners.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: banners.c 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/banners.h b/scheduler/banners.h
index 4a91e8a..19ab6f7 100644
--- a/scheduler/banners.h
+++ b/scheduler/banners.h
@@ -1,5 +1,5 @@
/*
- * "$Id: banners.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: banners.h 10996 2013-05-29 11:51:34Z msweet $"
*
* Banner definitions for the CUPS scheduler.
*
@@ -41,5 +41,5 @@ extern void cupsdLoadBanners(const char *d);
/*
- * End of "$Id: banners.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: banners.h 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/cert.c b/scheduler/cert.c
index cd47228..6d93426 100644
--- a/scheduler/cert.c
+++ b/scheduler/cert.c
@@ -1,25 +1,16 @@
/*
- * "$Id: cert.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: cert.c 12972 2015-11-13 20:30:37Z msweet $"
*
- * Authentication certificate routines for the CUPS scheduler.
+ * Authentication certificate routines for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2007-2015 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * cupsdAddCert() - Add a certificate.
- * cupsdDeleteCert() - Delete a single certificate.
- * cupsdDeleteAllCerts() - Delete all certificates...
- * cupsdFindCert() - Find a certificate.
- * cupsdInitCerts() - Initialize the certificate "system" and root
- * certificate.
+ * 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/".
*/
/*
@@ -36,6 +27,13 @@
/*
+ * Local functions...
+ */
+
+static int ctcompare(const char *a, const char *b);
+
+
+/*
* 'cupsdAddCert()' - Add a certificate.
*/
@@ -52,8 +50,7 @@ cupsdAddCert(int pid, /* I - Process ID */
/* Hex constants... */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdAddCert: Adding certificate for PID %d", pid);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAddCert: Adding certificate for PID %d", pid);
/*
* Allocate memory for the certificate...
@@ -111,8 +108,7 @@ cupsdAddCert(int pid, /* I - Process ID */
fchmod(fd, 0440);
fchown(fd, RunUser, SystemGroupIDs[0]);
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddCert: NumSystemGroups=%d",
- NumSystemGroups);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddCert: NumSystemGroups=%d", NumSystemGroups);
#ifdef HAVE_ACL_INIT
if (NumSystemGroups > 1)
@@ -288,8 +284,7 @@ cupsdDeleteCert(int pid) /* I - Process ID */
* Remove this certificate from the list...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdDeleteCert: Removing certificate for PID %d", pid);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDeleteCert: Removing certificate for PID %d.", pid);
DEBUG_printf(("DELETE pid=%d, username=%s, cert=%s\n", cert->pid,
cert->username, cert->certificate));
@@ -363,17 +358,15 @@ cupsdFindCert(const char *certificate) /* I - Certificate */
cupsd_cert_t *cert; /* Current certificate */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert(certificate=%s)",
- certificate);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert(certificate=%s)", certificate);
for (cert = Certs; cert != NULL; cert = cert->next)
- if (!_cups_strcasecmp(certificate, cert->certificate))
+ if (!ctcompare(certificate, cert->certificate))
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert: Returning %s...",
- cert->username);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert: Returning \"%s\".", cert->username);
return (cert);
}
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert: Certificate not found!");
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert: Certificate not found.");
return (NULL);
}
@@ -417,10 +410,10 @@ cupsdInitCerts(void)
* them as the seed...
*/
- seed = cupsFileGetChar(fp);
- seed = (seed << 8) | cupsFileGetChar(fp);
- seed = (seed << 8) | cupsFileGetChar(fp);
- CUPS_SRAND((seed << 8) | cupsFileGetChar(fp));
+ seed = (unsigned)cupsFileGetChar(fp);
+ seed = (seed << 8) | (unsigned)cupsFileGetChar(fp);
+ seed = (seed << 8) | (unsigned)cupsFileGetChar(fp);
+ CUPS_SRAND((seed << 8) | (unsigned)cupsFileGetChar(fp));
cupsFileClose(fp);
}
@@ -436,5 +429,27 @@ cupsdInitCerts(void)
/*
- * End of "$Id: cert.c 11173 2013-07-23 12:31:34Z msweet $".
+ * 'ctcompare()' - Compare two strings in constant time.
+ */
+
+static int /* O - 0 on match, non-zero on non-match */
+ctcompare(const char *a, /* I - First string */
+ const char *b) /* I - Second string */
+{
+ int result = 0; /* Result */
+
+
+ while (*a && *b)
+ {
+ result |= *a ^ *b;
+ a ++;
+ b ++;
+ }
+
+ return (result);
+}
+
+
+/*
+ * End of "$Id: cert.c 12972 2015-11-13 20:30:37Z msweet $".
*/
diff --git a/scheduler/cert.h b/scheduler/cert.h
index 26eaa9f..063c5de 100644
--- a/scheduler/cert.h
+++ b/scheduler/cert.h
@@ -1,5 +1,5 @@
/*
- * "$Id: cert.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: cert.h 10996 2013-05-29 11:51:34Z msweet $"
*
* Authentication certificate definitions for the CUPS scheduler.
*
@@ -49,5 +49,5 @@ extern void cupsdInitCerts(void);
/*
- * End of "$Id: cert.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: cert.h 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/classes.c b/scheduler/classes.c
index 1aed92c..17add06 100644
--- a/scheduler/classes.c
+++ b/scheduler/classes.c
@@ -1,27 +1,16 @@
/*
- * "$Id: classes.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: classes.c 11781 2014-03-28 20:57:22Z msweet $"
*
- * Printer class routines for the CUPS scheduler.
+ * Printer class routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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:
- *
- * cupsdAddClass() - Add a class to the system.
- * cupsdAddPrinterToClass() - Add a printer to a class...
- * cupsdDeletePrinterFromClass() - Delete a printer from a class.
- * cupsdDeletePrinterFromClasses() - Delete a printer from all classes.
- * cupsdFindAvailablePrinter() - Find an available printer in a class.
- * cupsdFindClass() - Find the named class.
- * cupsdLoadAllClasses() - Load classes from the classes.conf file.
- * cupsdSaveAllClasses() - Save classes to the classes.conf file.
+ * 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/".
*/
/*
@@ -93,7 +82,7 @@ cupsdAddPrinterToClass(
if (c->num_printers == 0)
temp = malloc(sizeof(cupsd_printer_t *));
else
- temp = realloc(c->printers, sizeof(cupsd_printer_t *) * (c->num_printers + 1));
+ temp = realloc(c->printers, sizeof(cupsd_printer_t *) * (size_t)(c->num_printers + 1));
if (temp == NULL)
{
@@ -147,7 +136,7 @@ cupsdDeletePrinterFromClass(
c->num_printers --;
if (i < c->num_printers)
memmove(c->printers + i, c->printers + i + 1,
- (c->num_printers - i) * sizeof(cupsd_printer_t *));
+ (size_t)(c->num_printers - i) * sizeof(cupsd_printer_t *));
}
else
return (0);
@@ -343,7 +332,7 @@ cupsdLoadAllClasses(void)
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of classes.conf.", linenum);
}
- else if (!_cups_strcasecmp(line, "</Class>"))
+ else if (!_cups_strcasecmp(line, "</Class>") || !_cups_strcasecmp(line, "</DefaultClass>"))
{
if (p != NULL)
{
@@ -806,7 +795,10 @@ cupsdSaveAllClasses(void)
cupsFilePutConf(fp, "Option", value);
}
- cupsFilePuts(fp, "</Class>\n");
+ if (pclass == DefaultPrinter)
+ cupsFilePuts(fp, "</DefaultClass>\n");
+ else
+ cupsFilePuts(fp, "</Class>\n");
}
cupsdCloseCreatedConfFile(fp, filename);
@@ -814,5 +806,5 @@ cupsdSaveAllClasses(void)
/*
- * End of "$Id: classes.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: classes.c 11781 2014-03-28 20:57:22Z msweet $".
*/
diff --git a/scheduler/classes.h b/scheduler/classes.h
index 6d94de2..bc0196e 100644
--- a/scheduler/classes.h
+++ b/scheduler/classes.h
@@ -1,5 +1,5 @@
/*
- * "$Id: classes.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: classes.h 10996 2013-05-29 11:51:34Z msweet $"
*
* Printer class definitions for the CUPS scheduler.
*
@@ -31,5 +31,5 @@ extern void cupsdSaveAllClasses(void);
/*
- * End of "$Id: classes.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: classes.h 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/client.c b/scheduler/client.c
index b341e9d..3ec3b5c 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -1,90 +1,38 @@
/*
- * "$Id: client.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: client.c 12978 2015-11-17 19:29:52Z msweet $"
*
- * Client routines for the CUPS scheduler.
+ * Client routines for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
- * This file contains Kerberos support code, copyright 2006 by
- * Jelmer Vernooij.
+ * This file contains Kerberos support code, copyright 2006 by
+ * Jelmer Vernooij.
*
- * 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:
- *
- * 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.
+ * 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 necessary headers...
*/
+#define _CUPS_NO_DEPRECATED
+#define _HTTP_NO_PRIVATE
#include "cupsd.h"
+#ifdef __APPLE__
+# include <libproc.h>
+#endif /* __APPLE__ */
#ifdef HAVE_TCPD_H
# include <tcpd.h>
#endif /* HAVE_TCPD_H */
/*
- * 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...
*/
@@ -92,9 +40,11 @@ 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);
-static int data_ready(cupsd_client_t *con);
+#ifdef HAVE_SSL
+static int cupsd_start_tls(cupsd_client_t *con, http_encryption_t e);
+#endif /* HAVE_SSL */
static char *get_file(cupsd_client_t *con, struct stat *filestats,
- char *filename, int len);
+ char *filename, size_t len);
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);
@@ -115,14 +65,12 @@ static void write_pipe(cupsd_client_t *con);
void
cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
{
+ const char *hostname; /* Hostname of client */
+ char name[256]; /* Hostname of client */
int count; /* Count of connections on a host */
- int val; /* Parameter value */
cupsd_client_t *con, /* New client pointer */
*tempcon; /* Temporary client pointer */
- http_addrlist_t *addrlist, /* List of adddresses for host */
- *addr; /* Current address */
socklen_t addrlen; /* Length of address */
- char *hostname; /* Hostname for address */
http_addr_t temp; /* Temporary address variable */
static time_t last_dos = 0; /* Time of last DoS attack */
#ifdef HAVE_TCPD_H
@@ -130,9 +78,7 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
#endif /* HAVE_TCPD_H */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdAcceptClient(lis=%p(%d)) Clients=%d",
- lis, lis->fd, cupsArrayCount(Clients));
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAcceptClient(lis=%p(%d)) Clients=%d", lis, lis->fd, cupsArrayCount(Clients));
/*
* Make sure we don't have a full set of clients already...
@@ -174,19 +120,14 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
return;
}
- con->file = -1;
- con->http.activity = time(NULL);
- con->http.hostaddr = &(con->clientaddr);
- con->http.wait_value = 10000;
-
/*
* Accept the client and get the remote address...
*/
- addrlen = sizeof(http_addr_t);
+ con->number = ++ LastClientNumber;
+ con->file = -1;
- if ((con->http.fd = accept(lis->fd, (struct sockaddr *)con->http.hostaddr,
- &addrlen)) < 0)
+ if ((con->http = httpAcceptConnection(lis->fd, 0)) == NULL)
{
if (errno == ENFILE || errno == EMFILE)
cupsdPauseListening();
@@ -199,23 +140,10 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
}
/*
- * Save the connected port number...
- */
-
- _httpAddrSetPort(con->http.hostaddr, _httpAddrPort(&(lis->address)));
-
-#ifdef AF_INET6
- /*
- * Convert IPv4 over IPv6 addresses (::ffff:n.n.n.n) to IPv4 forms we
- * can more easily use...
+ * Save the connected address and port number...
*/
- if (lis->address.addr.sa_family == AF_INET6 &&
- con->http.hostaddr->ipv6.sin6_addr.s6_addr32[0] == 0 &&
- con->http.hostaddr->ipv6.sin6_addr.s6_addr32[1] == 0 &&
- ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2]) == 0xffff)
- con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2] = 0;
-#endif /* AF_INET6 */
+ con->clientaddr = lis->address;
/*
* Check the number of clients on the same address...
@@ -224,7 +152,7 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
for (count = 0, tempcon = (cupsd_client_t *)cupsArrayFirst(Clients);
tempcon;
tempcon = (cupsd_client_t *)cupsArrayNext(Clients))
- if (httpAddrEqual(tempcon->http.hostaddr, con->http.hostaddr))
+ if (httpAddrEqual(httpGetAddress(tempcon->http), httpGetAddress(con->http)))
{
count ++;
if (count >= MaxClientsPerHost)
@@ -238,18 +166,12 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
last_dos = time(NULL);
cupsdLogMessage(CUPSD_LOG_WARN,
"Possible DoS attack - more than %d clients connecting "
- "from %s!",
+ "from %s.",
MaxClientsPerHost,
- httpAddrString(con->http.hostaddr, con->http.hostname,
- sizeof(con->http.hostname)));
+ httpGetHostname(con->http, name, sizeof(name)));
}
-#ifdef WIN32
- closesocket(con->http.fd);
-#else
- close(con->http.fd);
-#endif /* WIN32 */
-
+ httpClose(con->http);
free(con);
return;
}
@@ -258,31 +180,10 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
* Get the hostname or format the IP address as needed...
*/
- if (httpAddrLocalhost(con->http.hostaddr))
- {
- /*
- * Map accesses from the loopback interface to "localhost"...
- */
-
- strlcpy(con->http.hostname, "localhost", sizeof(con->http.hostname));
- hostname = con->http.hostname;
- }
+ if (HostNameLookups)
+ hostname = httpResolveHostname(con->http, NULL, 0);
else
- {
- /*
- * Map accesses from the same host to the server name.
- */
-
- if (HostNameLookups)
- hostname = httpAddrLookup(con->http.hostaddr, con->http.hostname,
- sizeof(con->http.hostname));
- else
- {
- hostname = NULL;
- httpAddrString(con->http.hostaddr, con->http.hostname,
- sizeof(con->http.hostname));
- }
- }
+ hostname = httpGetHostname(con->http, NULL, 0);
if (hostname == NULL && HostNameLookups == 2)
{
@@ -290,15 +191,11 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
* Can't have an unresolved IP address with double-lookups enabled...
*/
-#ifdef WIN32
- closesocket(con->http.fd);
-#else
- close(con->http.fd);
-#endif /* WIN32 */
+ httpClose(con->http);
- cupsdLogMessage(CUPSD_LOG_WARN,
+ cupsdLogClient(con, CUPSD_LOG_WARN,
"Name lookup failed - connection from %s closed!",
- con->http.hostname);
+ httpGetHostname(con->http, NULL, 0));
free(con);
return;
@@ -310,15 +207,17 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
* Do double lookups as needed...
*/
- if ((addrlist = httpAddrGetList(con->http.hostname, AF_UNSPEC, NULL))
- != NULL)
+ http_addrlist_t *addrlist, /* List of addresses */
+ *addr; /* Current address */
+
+ if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, NULL)) != NULL)
{
/*
* See if the hostname maps to the same IP address...
*/
for (addr = addrlist; addr; addr = addr->next)
- if (httpAddrEqual(con->http.hostaddr, &(addr->addr)))
+ if (httpAddrEqual(httpGetAddress(con->http), &(addr->addr)))
break;
}
else
@@ -333,15 +232,11 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
* with double-lookups enabled...
*/
-#ifdef WIN32
- closesocket(con->http.fd);
-#else
- close(con->http.fd);
-#endif /* WIN32 */
+ httpClose(con->http);
- cupsdLogMessage(CUPSD_LOG_WARN,
+ cupsdLogClient(con, CUPSD_LOG_WARN,
"IP lookup failed - connection from %s closed!",
- con->http.hostname);
+ httpGetHostname(con->http, NULL, 0));
free(con);
return;
}
@@ -352,53 +247,73 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
* See if the connection is denied by TCP wrappers...
*/
- request_init(&wrap_req, RQ_DAEMON, "cupsd", RQ_FILE, con->http.fd, NULL);
+ request_init(&wrap_req, RQ_DAEMON, "cupsd", RQ_FILE, httpGetFd(con->http),
+ NULL);
fromhost(&wrap_req);
if (!hosts_access(&wrap_req))
{
-#ifdef WIN32
- closesocket(con->http.fd);
-#else
- close(con->http.fd);
-#endif /* WIN32 */
+ httpClose(con->http);
- cupsdLogMessage(CUPSD_LOG_WARN,
+ cupsdLogClient(con, CUPSD_LOG_WARN,
"Connection from %s refused by /etc/hosts.allow and "
- "/etc/hosts.deny rules.", con->http.hostname);
+ "/etc/hosts.deny rules.", httpGetHostname(con->http, NULL, 0));
free(con);
return;
}
#endif /* HAVE_TCPD_H */
#ifdef AF_LOCAL
- if (con->http.hostaddr->addr.sa_family == AF_LOCAL)
- cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Accepted from %s (Domain)",
- con->http.fd, con->http.hostname);
+ if (httpAddrFamily(httpGetAddress(con->http)) == AF_LOCAL)
+ {
+# ifdef __APPLE__
+ socklen_t peersize; /* Size of peer credentials */
+ pid_t peerpid; /* Peer process ID */
+ char peername[256]; /* Name of process */
+
+ peersize = sizeof(peerpid);
+ if (!getsockopt(httpGetFd(con->http), SOL_LOCAL, LOCAL_PEERPID, &peerpid,
+ &peersize))
+ {
+ if (!proc_name((int)peerpid, peername, sizeof(peername)))
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "Accepted from %s (Domain ???[%d])",
+ httpGetHostname(con->http, NULL, 0), (int)peerpid);
+ else
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "Accepted from %s (Domain %s[%d])",
+ httpGetHostname(con->http, NULL, 0), peername, (int)peerpid);
+ }
+ else
+# endif /* __APPLE__ */
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Accepted from %s (Domain)",
+ httpGetHostname(con->http, NULL, 0));
+ }
else
#endif /* AF_LOCAL */
- 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);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Accepted from %s:%d (IPv%d)",
+ httpGetHostname(con->http, NULL, 0),
+ httpAddrPort(httpGetAddress(con->http)),
+ httpAddrFamily(httpGetAddress(con->http)) == AF_INET ? 4 : 6);
/*
* Get the local address the client connected to...
*/
addrlen = sizeof(temp);
- if (getsockname(con->http.fd, (struct sockaddr *)&temp, &addrlen))
+ if (getsockname(httpGetFd(con->http), (struct sockaddr *)&temp, &addrlen))
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get local address - %s",
- strerror(errno));
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to get local address - %s",
+ strerror(errno));
- strcpy(con->servername, "localhost");
+ strlcpy(con->servername, "localhost", sizeof(con->servername));
con->serverport = LocalPort;
}
#ifdef AF_LOCAL
- else if (_httpAddrFamily(&temp) == AF_LOCAL)
+ else if (httpAddrFamily(&temp) == AF_LOCAL)
{
- strcpy(con->servername, "localhost");
+ strlcpy(con->servername, "localhost", sizeof(con->servername));
con->serverport = LocalPort;
}
#endif /* AF_LOCAL */
@@ -411,7 +326,7 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
else
httpAddrString(&temp, con->servername, sizeof(con->servername));
- con->serverport = _httpAddrPort(&(lis->address));
+ con->serverport = httpAddrPort(&(lis->address));
}
/*
@@ -421,25 +336,13 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
cupsArrayAdd(Clients, con);
/*
- * Using TCP_NODELAY improves responsiveness, especially on systems with a slow
- * loopback interface. Since we write large buffers when sending print files
- * and requests there shouldn't be any performance penalty for this...
- */
-
- val = 1;
- setsockopt(con->http.fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
-
- /*
- * Close this file on all execs...
- */
-
- fcntl(con->http.fd, F_SETFD, fcntl(con->http.fd, F_GETFD) | FD_CLOEXEC);
-
- /*
* Add the socket to the server select.
*/
- cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, NULL, con);
+ cupsdAddSelect(httpGetFd(con->http), (cupsd_selfunc_t)cupsdReadClient, NULL,
+ con);
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Waiting for request.");
/*
* Temporarily suspend accept()'s until we lose a client...
@@ -453,15 +356,13 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
* See if we are connecting on a secure port...
*/
- if (lis->encryption == HTTP_ENCRYPT_ALWAYS)
+ if (lis->encryption == HTTP_ENCRYPTION_ALWAYS)
{
/*
* https connection; go secure...
*/
- con->http.encryption = HTTP_ENCRYPT_ALWAYS;
-
- if (!cupsdStartTLS(con))
+ if (cupsd_start_tls(con, HTTP_ENCRYPTION_ALWAYS))
cupsdCloseClient(con);
}
else
@@ -480,8 +381,7 @@ cupsdCloseAllClients(void)
cupsd_client_t *con; /* Current client */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCloseAllClients() Clients=%d",
- cupsArrayCount(Clients));
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCloseAllClients() Clients=%d", cupsArrayCount(Clients));
for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
con;
@@ -499,36 +399,18 @@ int /* O - 1 if partial close, 0 if fully closed */
cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */
{
int partial; /* Do partial close for SSL? */
-#ifdef HAVE_LIBSSL
-#elif defined(HAVE_GNUTLS)
-# elif defined(HAVE_CDSASSL)
-#endif /* HAVE_LIBSSL */
- cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Closing connection.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing connection.");
/*
* Flush pending writes before closing...
*/
- httpFlushWrite(HTTP(con));
+ httpFlushWrite(con->http);
partial = 0;
-#ifdef HAVE_SSL
- /*
- * Shutdown encryption as needed...
- */
-
- if (con->http.tls)
- {
- partial = 1;
-
- cupsdEndTLS(con);
- }
-#endif /* HAVE_SSL */
-
if (con->pipe_pid != 0)
{
/*
@@ -551,19 +433,31 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */
* Close the socket and clear the file from the input set for select()...
*/
- if (con->http.fd >= 0)
+ if (httpGetFd(con->http) >= 0)
{
cupsArrayRemove(ActiveClients, con);
cupsdSetBusyState();
+#ifdef HAVE_SSL
+ /*
+ * Shutdown encryption as needed...
+ */
+
+ if (httpIsEncrypted(con->http))
+ partial = 1;
+#endif /* HAVE_SSL */
+
if (partial)
{
/*
* Only do a partial close so that the encrypted client gets everything.
*/
- shutdown(con->http.fd, 0);
- cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, NULL, con);
+ httpShutdown(con->http);
+ cupsdAddSelect(httpGetFd(con->http), (cupsd_selfunc_t)cupsdReadClient,
+ NULL, con);
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Waiting for socket close.");
}
else
{
@@ -571,9 +465,9 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */
* Shut the socket down fully...
*/
- cupsdRemoveSelect(con->http.fd);
- close(con->http.fd);
- con->http.fd = -1;
+ cupsdRemoveSelect(httpGetFd(con->http));
+ httpClose(con->http);
+ con->http = NULL;
}
}
@@ -583,13 +477,16 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */
* Free memory...
*/
- if (con->http.input_set)
- free(con->http.input_set);
+ cupsdRemoveSelect(httpGetFd(con->http));
+
+ httpClose(con->http);
- httpClearCookie(HTTP(con));
- httpClearFields(HTTP(con));
+ if (con->filename)
+ {
+ unlink(con->filename);
+ cupsdClearString(&con->filename);
+ }
- cupsdClearString(&con->filename);
cupsdClearString(&con->command);
cupsdClearString(&con->options);
cupsdClearString(&con->query_string);
@@ -642,21 +539,6 @@ cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */
/*
- * 'cupsdFlushHeader()' - Flush the header fields to the client.
- */
-
-int /* I - Bytes written or -1 on error */
-cupsdFlushHeader(cupsd_client_t *con) /* I - Client to flush to */
-{
- int bytes = httpFlushWrite(HTTP(con));
-
- con->http.data_encoding = HTTP_ENCODE_LENGTH;
-
- return (bytes);
-}
-
-
-/*
* 'cupsdReadClient()' - Read data from a client.
*/
@@ -664,11 +546,8 @@ void
cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
{
char line[32768], /* Line from client... */
- operation[64], /* Operation code from socket */
- version[64], /* HTTP version number string */
locale[64], /* Locale */
*ptr; /* Pointer into strings */
- int major, minor; /* HTTP version numbers */
http_status_t status; /* Transfer status */
ipp_state_t ipp_state; /* State of IPP transfer */
int bytes; /* Number of bytes to POST */
@@ -680,25 +559,34 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
static unsigned request_id = 0; /* Request ID for temp files */
- status = HTTP_CONTINUE;
-
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[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->request,
- con->request ? ipp_states[con->request->state] : "",
- con->file);
+ status = HTTP_STATUS_CONTINUE;
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cupsdReadClient: error=%d, used=%d, state=%s, data_encoding=HTTP_ENCODING_%s, data_remaining=" CUPS_LLFMT ", request=%p(%s), file=%d", httpError(con->http), (int)httpGetReady(con->http), httpStateString(httpGetState(con->http)), httpIsChunked(con->http) ? "CHUNKED" : "LENGTH", CUPS_LLCAST httpGetRemaining(con->http), con->request, con->request ? ippStateString(ippGetState(con->request)) : "", con->file);
+
+ if (httpGetState(con->http) == HTTP_STATE_GET_SEND ||
+ httpGetState(con->http) == HTTP_STATE_POST_SEND ||
+ httpGetState(con->http) == HTTP_STATE_STATUS)
+ {
+ /*
+ * If we get called in the wrong state, then something went wrong with the
+ * connection and we need to shut it down...
+ */
+
+ if (!httpGetReady(con->http) && recv(httpGetFd(con->http), buf, 1, MSG_PEEK) < 1)
+ {
+ /*
+ * Connection closed...
+ */
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on EOF.");
+ cupsdCloseClient(con);
+ return;
+ }
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on unexpected HTTP read state %s.", httpStateString(httpGetState(con->http)));
+ cupsdCloseClient(con);
+ return;
+ }
#ifdef HAVE_SSL
if (con->auto_ssl)
@@ -709,18 +597,16 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
con->auto_ssl = 0;
- if (recv(con->http.fd, buf, 1, MSG_PEEK) == 1 &&
+ if (recv(httpGetFd(con->http), buf, 1, MSG_PEEK) == 1 &&
(!buf[0] || !strchr("DGHOPT", buf[0])))
{
/*
* Encrypt this connection...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] Saw first byte %02X, auto-negotiating "
- "SSL/TLS session.", con->http.fd, buf[0] & 255);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "Saw first byte %02X, auto-negotiating SSL/TLS session.", buf[0] & 255);
- if (!cupsdStartTLS(con))
+ if (cupsd_start_tls(con, HTTP_ENCRYPTION_ALWAYS))
cupsdCloseClient(con);
return;
@@ -728,24 +614,26 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
}
#endif /* HAVE_SSL */
- switch (con->http.state)
+ switch (httpGetState(con->http))
{
- case HTTP_WAITING :
+ case HTTP_STATE_WAITING :
/*
* See if we've received a request line...
*/
- if (httpGets(line, sizeof(line) - 1, HTTP(con)) == NULL)
+ con->operation = httpReadRequest(con->http, con->uri, sizeof(con->uri));
+ if (con->operation == HTTP_STATE_ERROR ||
+ con->operation == HTTP_STATE_UNKNOWN_METHOD ||
+ con->operation == HTTP_STATE_UNKNOWN_VERSION)
{
- if (con->http.error && con->http.error != EPIPE)
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] HTTP_WAITING Closing for error %d "
- "(%s)", con->http.fd, con->http.error,
- strerror(con->http.error));
+ if (httpError(con->http))
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "HTTP_STATE_WAITING Closing for error %d (%s)",
+ httpError(con->http), strerror(httpError(con->http)));
else
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] HTTP_WAITING Closing on EOF",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "HTTP_STATE_WAITING Closing on error: %s",
+ cupsLastErrorString());
cupsdCloseClient(con);
return;
@@ -755,29 +643,19 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Ignore blank request lines...
*/
- if (line[0] == '\0')
+ if (con->operation == HTTP_STATE_WAITING)
break;
/*
* Clear other state variables...
*/
- httpClearFields(HTTP(con));
-
- con->http.activity = time(NULL);
- con->http.version = HTTP_1_0;
- con->http.keep_alive = HTTP_KEEPALIVE_OFF;
- con->http.data_encoding = HTTP_ENCODE_LENGTH;
- con->http.data_remaining = 0;
- con->http._data_remaining = 0;
- con->operation = HTTP_WAITING;
- con->bytes = 0;
- con->file = -1;
- con->file_ready = 0;
- con->pipe_pid = 0;
- con->username[0] = '\0';
- con->password[0] = '\0';
- con->uri[0] = '\0';
+ con->bytes = 0;
+ con->file = -1;
+ con->file_ready = 0;
+ con->pipe_pid = 0;
+ con->username[0] = '\0';
+ con->password[0] = '\0';
cupsdClearString(&con->command);
cupsdClearString(&con->options);
@@ -807,62 +685,6 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
#endif /* HAVE_GSSAPI */
/*
- * Grab the request line...
- */
-
- switch (sscanf(line, "%63s%1023s%63s", operation, con->uri, version))
- {
- case 1 :
- if (line[0])
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[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);
- cupsdCloseClient(con);
- }
- return;
- case 2 :
- con->http.version = HTTP_0_9;
- break;
- case 3 :
- if (sscanf(version, "HTTP/%d.%d", &major, &minor) != 2)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[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);
- cupsdCloseClient(con);
- return;
- }
-
- if (major < 2)
- {
- con->http.version = (http_version_t)(major * 100 + minor);
- if (con->http.version == HTTP_1_1 && KeepAlive)
- con->http.keep_alive = HTTP_KEEPALIVE_ON;
- else
- con->http.keep_alive = HTTP_KEEPALIVE_OFF;
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[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);
- cupsdCloseClient(con);
- return;
- }
- break;
- }
-
- /*
* Handle full URLs in the request line...
*/
@@ -874,18 +696,24 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
resource[HTTP_MAX_URI]; /* Resource path */
int port; /* Port number */
-
/*
* Separate the URI into its components...
*/
- httpSeparateURI(HTTP_URI_CODING_MOST, con->uri,
- scheme, sizeof(scheme),
- userpass, sizeof(userpass),
- hostname, sizeof(hostname), &port,
- resource, sizeof(resource));
+ if (httpSeparateURI(HTTP_URI_CODING_MOST, con->uri,
+ scheme, sizeof(scheme),
+ userpass, sizeof(userpass),
+ hostname, sizeof(hostname), &port,
+ resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
+ {
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Bad URI \"%s\" in request.",
+ con->uri);
+ cupsdSendError(con, HTTP_STATUS_METHOD_NOT_ALLOWED, CUPSD_AUTH_NONE);
+ cupsdCloseClient(con);
+ return;
+ }
- /*
+ /*
* Only allow URIs with the servername, localhost, or an IP
* address...
*/
@@ -893,16 +721,16 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (strcmp(scheme, "file") &&
_cups_strcasecmp(hostname, ServerName) &&
_cups_strcasecmp(hostname, "localhost") &&
+ !cupsArrayFind(ServerAlias, hostname) &&
!isdigit(hostname[0]) && hostname[0] != '[')
{
/*
* Nope, we don't do proxies...
*/
- 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);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Bad URI \"%s\" in request.",
+ con->uri);
+ cupsdSendError(con, HTTP_STATUS_METHOD_NOT_ALLOWED, CUPSD_AUTH_NONE);
cupsdCloseClient(con);
return;
}
@@ -912,45 +740,19 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* con->uri are HTTP_MAX_URI bytes in size...
*/
- strcpy(con->uri, resource);
+ strlcpy(con->uri, resource, sizeof(con->uri));
}
/*
* Process the request...
*/
- if (!strcmp(operation, "GET"))
- con->http.state = HTTP_GET;
- else if (!strcmp(operation, "PUT"))
- con->http.state = HTTP_PUT;
- else if (!strcmp(operation, "POST"))
- con->http.state = HTTP_POST;
- else if (!strcmp(operation, "DELETE"))
- con->http.state = HTTP_DELETE;
- else if (!strcmp(operation, "TRACE"))
- con->http.state = HTTP_TRACE;
- else if (!strcmp(operation, "OPTIONS"))
- con->http.state = HTTP_OPTIONS;
- else if (!strcmp(operation, "HEAD"))
- con->http.state = HTTP_HEAD;
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Bad operation \"%s\".", con->http.fd,
- operation);
- cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
- cupsdCloseClient(con);
- return;
- }
-
gettimeofday(&(con->start), NULL);
- con->operation = con->http.state;
- 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);
-
- con->http.status = HTTP_OK;
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "%s %s HTTP/%d.%d",
+ httpStateString(con->operation) + 11, con->uri,
+ httpGetVersion(con->http) / 100,
+ httpGetVersion(con->http) % 100);
if (!cupsArrayFind(ActiveClients, con))
{
@@ -958,49 +760,45 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
cupsdSetBusyState();
}
- case HTTP_OPTIONS :
- case HTTP_DELETE :
- case HTTP_GET :
- case HTTP_HEAD :
- case HTTP_POST :
- case HTTP_PUT :
- case HTTP_TRACE :
+ case HTTP_STATE_OPTIONS :
+ case HTTP_STATE_DELETE :
+ case HTTP_STATE_GET :
+ case HTTP_STATE_HEAD :
+ case HTTP_STATE_POST :
+ case HTTP_STATE_PUT :
+ case HTTP_STATE_TRACE :
/*
* Parse incoming parameters until the status changes...
*/
- while ((status = httpUpdate(HTTP(con))) == HTTP_CONTINUE)
- if (!data_ready(con))
+ while ((status = httpUpdate(con->http)) == HTTP_STATUS_CONTINUE)
+ if (!httpGetReady(con->http))
break;
- if (status != HTTP_OK && status != HTTP_CONTINUE)
+ if (status != HTTP_STATUS_OK && status != HTTP_STATUS_CONTINUE)
{
- if (con->http.error && con->http.error != EPIPE)
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Closing for error %d (%s) while "
- "reading headers.",
- con->http.fd, con->http.error,
- strerror(con->http.error));
+ if (httpError(con->http) && httpError(con->http) != EPIPE)
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "Closing for error %d (%s) while reading headers.",
+ httpError(con->http), strerror(httpError(con->http)));
else
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Closing on EOF while reading headers.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "Closing on EOF while reading headers.");
- cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
+ cupsdSendError(con, HTTP_STATUS_BAD_REQUEST, CUPSD_AUTH_NONE);
cupsdCloseClient(con);
return;
}
break;
default :
- if (!data_ready(con) && recv(con->http.fd, buf, 1, MSG_PEEK) < 1)
+ if (!httpGetReady(con->http) && recv(httpGetFd(con->http), buf, 1, MSG_PEEK) < 1)
{
/*
* Connection closed...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Closing on EOF", con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on EOF.");
cupsdCloseClient(con);
return;
}
@@ -1011,24 +809,26 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Handle new transfers...
*/
- if (status == HTTP_OK)
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Read: status=%d", status);
+
+ if (status == HTTP_STATUS_OK)
{
- if (con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE][0])
+ if (httpGetField(con->http, HTTP_FIELD_ACCEPT_LANGUAGE)[0])
{
/*
* Figure out the locale from the Accept-Language and Content-Type
* fields...
*/
- if ((ptr = strchr(con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE],
+ if ((ptr = strchr(httpGetField(con->http, HTTP_FIELD_ACCEPT_LANGUAGE),
',')) != NULL)
*ptr = '\0';
- if ((ptr = strchr(con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE],
+ if ((ptr = strchr(httpGetField(con->http, HTTP_FIELD_ACCEPT_LANGUAGE),
';')) != NULL)
*ptr = '\0';
- if ((ptr = strstr(con->http.fields[HTTP_FIELD_CONTENT_TYPE],
+ if ((ptr = strstr(httpGetField(con->http, HTTP_FIELD_CONTENT_TYPE),
"charset=")) != NULL)
{
/*
@@ -1037,14 +837,14 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
*/
snprintf(locale, sizeof(locale), "%s.%s",
- con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE], ptr + 8);
+ httpGetField(con->http, HTTP_FIELD_ACCEPT_LANGUAGE), ptr + 8);
if ((ptr = strchr(locale, ',')) != NULL)
*ptr = '\0';
}
else
snprintf(locale, sizeof(locale), "%s.UTF-8",
- con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE]);
+ httpGetField(con->http, HTTP_FIELD_ACCEPT_LANGUAGE));
con->language = cupsLangGet(locale);
}
@@ -1053,25 +853,23 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
cupsdAuthorize(con);
- if (!_cups_strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION],
+ if (!_cups_strncasecmp(httpGetField(con->http, HTTP_FIELD_CONNECTION),
"Keep-Alive", 10) && KeepAlive)
- con->http.keep_alive = HTTP_KEEPALIVE_ON;
- else if (!_cups_strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION],
+ httpSetKeepAlive(con->http, HTTP_KEEPALIVE_ON);
+ else if (!_cups_strncasecmp(httpGetField(con->http, HTTP_FIELD_CONNECTION),
"close", 5))
- con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+ httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF);
- if (!con->http.fields[HTTP_FIELD_HOST][0] &&
- con->http.version >= HTTP_1_1)
+ if (!httpGetField(con->http, HTTP_FIELD_HOST)[0] &&
+ httpGetVersion(con->http) >= HTTP_VERSION_1_1)
{
/*
* HTTP/1.1 and higher require the "Host:" field...
*/
- if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_BAD_REQUEST, CUPSD_AUTH_NONE))
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Missing Host: field in request.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Missing Host: field in request.");
cupsdCloseClient(con);
return;
}
@@ -1083,18 +881,17 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* or IPv6 values in the Host: field.
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Request from \"%s\" using invalid Host: "
- "field \"%s\"", con->http.fd, con->http.hostname,
- con->http.fields[HTTP_FIELD_HOST]);
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
+ "Request from \"%s\" using invalid Host: field \"%s\".",
+ httpGetHostname(con->http, NULL, 0), httpGetField(con->http, HTTP_FIELD_HOST));
- if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_BAD_REQUEST, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
}
- else if (con->operation == HTTP_OPTIONS)
+ else if (con->operation == HTTP_STATE_OPTIONS)
{
/*
* Do OPTIONS command...
@@ -1102,45 +899,37 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (con->best && con->best->type != CUPSD_AUTH_NONE)
{
- if (!cupsdSendHeader(con, HTTP_UNAUTHORIZED, NULL, CUPSD_AUTH_NONE))
+ httpClearFields(con->http);
+
+ if (!cupsdSendHeader(con, HTTP_STATUS_UNAUTHORIZED, NULL, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
}
- if (!_cups_strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Upgrade") &&
- con->http.tls == NULL)
+ if (!_cups_strcasecmp(httpGetField(con->http, HTTP_FIELD_CONNECTION), "Upgrade") && strstr(httpGetField(con->http, HTTP_FIELD_UPGRADE), "TLS/") != NULL && !httpIsEncrypted(con->http))
{
#ifdef HAVE_SSL
/*
* Do encryption stuff...
*/
- if (!cupsdSendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL, CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
-
- httpPrintf(HTTP(con), "Connection: Upgrade\r\n");
- httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n");
- httpPrintf(HTTP(con), "Content-Length: 0\r\n");
- httpPrintf(HTTP(con), "\r\n");
+ httpClearFields(con->http);
- if (cupsdFlushHeader(con) < 0)
- {
+ if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL, CUPSD_AUTH_NONE))
+ {
cupsdCloseClient(con);
return;
}
- if (!cupsdStartTLS(con))
+ if (cupsd_start_tls(con, HTTP_ENCRYPTION_REQUIRED))
{
cupsdCloseClient(con);
return;
}
#else
- if (!cupsdSendError(con, HTTP_NOT_IMPLEMENTED, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_IMPLEMENTED, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1148,17 +937,12 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
#endif /* HAVE_SSL */
}
- if (!cupsdSendHeader(con, HTTP_OK, NULL, CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
-
- httpPrintf(HTTP(con), "Allow: GET, HEAD, OPTIONS, POST, PUT\r\n");
- httpPrintf(HTTP(con), "Content-Length: 0\r\n");
- httpPrintf(HTTP(con), "\r\n");
+ httpClearFields(con->http);
+ httpSetField(con->http, HTTP_FIELD_ALLOW,
+ "GET, HEAD, OPTIONS, POST, PUT");
+ httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
- if (cupsdFlushHeader(con) < 0)
+ if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1170,11 +954,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Protect against malicious users!
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Request for non-absolute resource \"%s\".",
- con->http.fd, con->uri);
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
+ "Request for non-absolute resource \"%s\".", con->uri);
- if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_FORBIDDEN, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1182,39 +965,30 @@ 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(httpGetField(con->http, HTTP_FIELD_CONNECTION),
+ "Upgrade") && !httpIsEncrypted(con->http))
{
#ifdef HAVE_SSL
/*
* Do encryption stuff...
*/
- if (!cupsdSendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL,
+ httpClearFields(con->http);
+
+ if (!cupsdSendHeader(con, HTTP_STATUS_SWITCHING_PROTOCOLS, NULL,
CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
- httpPrintf(HTTP(con), "Connection: Upgrade\r\n");
- httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n");
- httpPrintf(HTTP(con), "Content-Length: 0\r\n");
- httpPrintf(HTTP(con), "\r\n");
-
- if (cupsdFlushHeader(con) < 0)
- {
- cupsdCloseClient(con);
- return;
- }
-
- if (!cupsdStartTLS(con))
+ if (cupsd_start_tls(con, HTTP_ENCRYPTION_REQUIRED))
{
cupsdCloseClient(con);
return;
}
#else
- if (!cupsdSendError(con, HTTP_NOT_IMPLEMENTED, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_IMPLEMENTED, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1222,23 +996,23 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
#endif /* HAVE_SSL */
}
- if ((status = cupsdIsAuthorized(con, NULL)) != HTTP_OK)
+ if ((status = cupsdIsAuthorized(con, NULL)) != HTTP_STATUS_OK)
{
cupsdSendError(con, status, CUPSD_AUTH_NONE);
cupsdCloseClient(con);
return;
}
- if (con->http.expect &&
- (con->operation == HTTP_POST || con->operation == HTTP_PUT))
+ if (httpGetExpect(con->http) &&
+ (con->operation == HTTP_STATE_POST || con->operation == HTTP_STATE_PUT))
{
- if (con->http.expect == HTTP_CONTINUE)
+ if (httpGetExpect(con->http) == HTTP_STATUS_CONTINUE)
{
/*
* Send 100-continue header...
*/
- if (!cupsdSendHeader(con, HTTP_CONTINUE, NULL, CUPSD_AUTH_NONE))
+ if (httpWriteResponse(con->http, HTTP_STATUS_CONTINUE))
{
cupsdCloseClient(con);
return;
@@ -1250,29 +1024,23 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Send 417-expectation-failed header...
*/
- if (!cupsdSendHeader(con, HTTP_EXPECTATION_FAILED, NULL,
- CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
-
- httpPrintf(HTTP(con), "Content-Length: 0\r\n");
- httpPrintf(HTTP(con), "\r\n");
+ httpClearFields(con->http);
+ httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
- if (cupsdFlushHeader(con) < 0)
- {
- cupsdCloseClient(con);
- return;
- }
+ cupsdSendError(con, HTTP_STATUS_EXPECTATION_FAILED, CUPSD_AUTH_NONE);
+ cupsdCloseClient(con);
+ return;
}
}
- switch (con->http.state)
+ switch (httpGetState(con->http))
{
- case HTTP_GET_SEND :
+ case HTTP_STATE_GET_SEND :
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Processing GET %s", con->uri);
+
if ((!strncmp(con->uri, "/ppd/", 5) ||
- !strncmp(con->uri, "/printers/", 10)) &&
+ !strncmp(con->uri, "/printers/", 10) ||
+ !strncmp(con->uri, "/classes/", 9)) &&
!strcmp(con->uri + strlen(con->uri) - 4, ".ppd"))
{
/*
@@ -1284,8 +1052,36 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (!strncmp(con->uri, "/ppd/", 5))
p = cupsdFindPrinter(con->uri + 5);
- else
+ else if (!strncmp(con->uri, "/printers/", 10))
p = cupsdFindPrinter(con->uri + 10);
+ else
+ {
+ p = cupsdFindClass(con->uri + 9);
+
+ if (p)
+ {
+ int i; /* Looping var */
+
+ for (i = 0; i < p->num_printers; i ++)
+ {
+ if (!(p->printers[i]->type & CUPS_PRINTER_CLASS))
+ {
+ char ppdname[1024];/* PPD filename */
+
+ snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd",
+ ServerRoot, p->printers[i]->name);
+ if (!access(ppdname, 0))
+ {
+ p = p->printers[i];
+ break;
+ }
+ }
+ }
+
+ if (i >= p->num_printers)
+ p = NULL;
+ }
+ }
if (p)
{
@@ -1293,7 +1089,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
}
else
{
- if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1319,13 +1115,39 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
else if (!strncmp(con->uri, "/printers/", 10))
p = cupsdFindPrinter(con->uri + 10);
else
- p = cupsdFindClass(con->uri + 9);
+ {
+ p = cupsdFindClass(con->uri + 9);
+
+ if (p)
+ {
+ int i; /* Looping var */
+
+ for (i = 0; i < p->num_printers; i ++)
+ {
+ if (!(p->printers[i]->type & CUPS_PRINTER_CLASS))
+ {
+ char ppdname[1024];/* PPD filename */
+
+ snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd",
+ ServerRoot, p->printers[i]->name);
+ if (!access(ppdname, 0))
+ {
+ p = p->printers[i];
+ break;
+ }
+ }
+ }
+
+ if (i >= p->num_printers)
+ p = NULL;
+ }
+ }
if (p)
snprintf(con->uri, sizeof(con->uri), "/icons/%s.png", p->name);
else
{
- if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1340,7 +1162,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Web interface is disabled. Show an appropriate message...
*/
- if (!cupsdSendError(con, HTTP_WEBIF_DISABLED, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_CUPS_WEBIF_DISABLED, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1411,17 +1233,17 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (!cupsdSendCommand(con, con->command, con->options, 0))
{
- if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
}
else
- cupsdLogRequest(con, HTTP_OK);
+ cupsdLogRequest(con, HTTP_STATUS_OK);
- if (con->http.version <= HTTP_1_0)
- con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+ if (httpGetVersion(con->http) <= HTTP_VERSION_1_0)
+ httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF);
}
else if ((!strncmp(con->uri, "/admin/conf/", 12) &&
(strchr(con->uri + 12, '/') ||
@@ -1435,10 +1257,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* /admin/conf...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
"Request for subdirectory \"%s\"!", con->uri);
- if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_FORBIDDEN, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1455,7 +1277,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if ((filename = get_file(con, &filestats, buf,
sizeof(buf))) == NULL)
{
- if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1466,6 +1288,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
type = mimeFileType(MimeDatabase, filename, NULL, NULL);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "filename=\"%s\", type=%s/%s", filename, type ? type->super : "", type ? type->type : "");
+
if (is_cgi(con, filename, &filestats, type))
{
/*
@@ -1475,23 +1299,23 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (!cupsdSendCommand(con, con->command, con->options, 0))
{
- if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
}
else
- cupsdLogRequest(con, HTTP_OK);
+ cupsdLogRequest(con, HTTP_STATUS_OK);
- if (con->http.version <= HTTP_1_0)
- con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+ if (httpGetVersion(con->http) <= HTTP_VERSION_1_0)
+ httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF);
break;
}
if (!check_if_modified(con, &filestats))
{
- if (!cupsdSendError(con, HTTP_NOT_MODIFIED, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_MODIFIED, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1500,11 +1324,11 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
else
{
if (type == NULL)
- strcpy(line, "text/plain");
+ strlcpy(line, "text/plain", sizeof(line));
else
snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
- if (!write_file(con, HTTP_OK, filename, line, &filestats))
+ if (!write_file(con, HTTP_STATUS_OK, filename, line, &filestats))
{
cupsdCloseClient(con);
return;
@@ -1513,21 +1337,21 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
}
break;
- case HTTP_POST_RECV :
+ case HTTP_STATE_POST_RECV :
/*
* See if the POST request includes a Content-Length field, and if
* so check the length against any limits that are set...
*/
- if (con->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] &&
+ if (httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0] &&
MaxRequestSize > 0 &&
- con->http.data_remaining > MaxRequestSize)
+ httpGetLength2(con->http) > MaxRequestSize)
{
/*
* Request too large...
*/
- if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1535,15 +1359,13 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
break;
}
- else if (con->http.data_remaining < 0 ||
- (!con->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] &&
- con->http.data_encoding == HTTP_ENCODE_LENGTH))
+ else if (httpGetLength2(con->http) < 0)
{
/*
* Negative content lengths are invalid!
*/
- if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_BAD_REQUEST, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1557,7 +1379,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* content-type field will be "application/ipp"...
*/
- if (!strcmp(con->http.fields[HTTP_FIELD_CONTENT_TYPE],
+ if (!strcmp(httpGetField(con->http, HTTP_FIELD_CONTENT_TYPE),
"application/ipp"))
con->request = ippNew();
else if (!WebInterface)
@@ -1566,7 +1388,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Web interface is disabled. Show an appropriate message...
*/
- if (!cupsdSendError(con, HTTP_WEBIF_DISABLED, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_CUPS_WEBIF_DISABLED, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1634,8 +1456,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
cupsdSetString(&con->options, NULL);
}
- if (con->http.version <= HTTP_1_0)
- con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+ if (httpGetVersion(con->http) <= HTTP_VERSION_1_0)
+ httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF);
}
else
{
@@ -1646,7 +1468,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if ((filename = get_file(con, &filestats, buf,
sizeof(buf))) == NULL)
{
- if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1663,7 +1485,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Only POST to CGI's...
*/
- if (!cupsdSendError(con, HTTP_UNAUTHORIZED, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_UNAUTHORIZED, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1672,7 +1494,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
}
break;
- case HTTP_PUT_RECV :
+ case HTTP_STATE_PUT_RECV :
/*
* Validate the resource name...
*/
@@ -1683,11 +1505,10 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* PUT can only be done to the cupsd.conf file...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Disallowed PUT request for \"%s\".",
- con->http.fd, con->uri);
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
+ "Disallowed PUT request for \"%s\".", con->uri);
- if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_FORBIDDEN, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1701,15 +1522,15 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* so check the length against any limits that are set...
*/
- if (con->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] &&
+ if (httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0] &&
MaxRequestSize > 0 &&
- con->http.data_remaining > MaxRequestSize)
+ httpGetLength2(con->http) > MaxRequestSize)
{
/*
* Request too large...
*/
- if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1717,13 +1538,13 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
break;
}
- else if (con->http.data_remaining < 0)
+ else if (httpGetLength2(con->http) < 0)
{
/*
* Negative content lengths are invalid!
*/
- if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_BAD_REQUEST, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1742,12 +1563,11 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (con->file < 0)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unable to create request file "
- "\"%s\": %s", con->http.fd, con->filename,
- strerror(errno));
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
+ "Unable to create request file \"%s\": %s",
+ con->filename, strerror(errno));
- if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -1759,13 +1579,13 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
break;
- case HTTP_DELETE :
- case HTTP_TRACE :
- cupsdSendError(con, HTTP_NOT_IMPLEMENTED, CUPSD_AUTH_NONE);
+ case HTTP_STATE_DELETE :
+ case HTTP_STATE_TRACE :
+ cupsdSendError(con, HTTP_STATUS_NOT_IMPLEMENTED, CUPSD_AUTH_NONE);
cupsdCloseClient(con);
return;
- case HTTP_HEAD :
+ case HTTP_STATE_HEAD :
if (!strncmp(con->uri, "/printers/", 10) &&
!strcmp(con->uri + strlen(con->uri) - 4, ".ppd"))
{
@@ -1780,12 +1600,13 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name);
else
{
- if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
+ cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND);
break;
}
}
@@ -1803,36 +1624,27 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
snprintf(con->uri, sizeof(con->uri), "/icons/%s.png", p->name);
else
{
- if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
+ cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND);
break;
}
}
else if (!WebInterface)
{
- if (!cupsdSendHeader(con, HTTP_OK, line, CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
-
- if (httpPrintf(HTTP(con), "\r\n") < 0)
- {
- cupsdCloseClient(con);
- return;
- }
+ httpClearFields(con->http);
- if (cupsdFlushHeader(con) < 0)
+ if (!cupsdSendHeader(con, HTTP_STATUS_OK, NULL, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
- con->http.state = HTTP_WAITING;
+ cupsdLogRequest(con, HTTP_STATUS_OK);
break;
}
@@ -1848,25 +1660,15 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* CGI output...
*/
- if (!cupsdSendHeader(con, HTTP_OK, "text/html", CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
-
- if (httpPrintf(HTTP(con), "\r\n") < 0)
- {
- cupsdCloseClient(con);
- return;
- }
+ httpClearFields(con->http);
- if (cupsdFlushHeader(con) < 0)
+ if (!cupsdSendHeader(con, HTTP_STATUS_OK, "text/html", CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
- cupsdLogRequest(con, HTTP_OK);
+ cupsdLogRequest(con, HTTP_STATUS_OK);
}
else if ((!strncmp(con->uri, "/admin/conf/", 12) &&
(strchr(con->uri + 12, '/') ||
@@ -1880,39 +1682,41 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* /admin/conf...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Request for subdirectory \"%s\".",
- con->http.fd, con->uri);
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
+ "Request for subdirectory \"%s\".", con->uri);
- if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_FORBIDDEN, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
+ cupsdLogRequest(con, HTTP_STATUS_FORBIDDEN);
break;
}
else if ((filename = get_file(con, &filestats, buf,
sizeof(buf))) == NULL)
{
- if (!cupsdSendHeader(con, HTTP_NOT_FOUND, "text/html",
+ httpClearFields(con->http);
+
+ if (!cupsdSendHeader(con, HTTP_STATUS_NOT_FOUND, "text/html",
CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
- cupsdLogRequest(con, HTTP_NOT_FOUND);
+ cupsdLogRequest(con, HTTP_STATUS_NOT_FOUND);
}
else if (!check_if_modified(con, &filestats))
{
- if (!cupsdSendError(con, HTTP_NOT_MODIFIED, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_MODIFIED, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
- cupsdLogRequest(con, HTTP_NOT_MODIFIED);
+ cupsdLogRequest(con, HTTP_STATUS_NOT_MODIFIED);
}
else
{
@@ -1922,46 +1726,24 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
type = mimeFileType(MimeDatabase, filename, NULL, NULL);
if (type == NULL)
- strcpy(line, "text/plain");
+ strlcpy(line, "text/plain", sizeof(line));
else
snprintf(line, sizeof(line), "%s/%s", type->super, type->type);
- if (!cupsdSendHeader(con, HTTP_OK, line, CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
+ httpClearFields(con->http);
- if (httpPrintf(HTTP(con), "Last-Modified: %s\r\n",
- httpGetDateString(filestats.st_mtime)) < 0)
- {
- cupsdCloseClient(con);
- return;
- }
+ httpSetField(con->http, HTTP_FIELD_LAST_MODIFIED,
+ httpGetDateString(filestats.st_mtime));
+ httpSetLength(con->http, (size_t)filestats.st_size);
- if (httpPrintf(HTTP(con), "Content-Length: %lu\r\n",
- (unsigned long)filestats.st_size) < 0)
+ if (!cupsdSendHeader(con, HTTP_STATUS_OK, line, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
- cupsdLogRequest(con, HTTP_OK);
- }
-
- if (httpPrintf(HTTP(con), "\r\n") < 0)
- {
- cupsdCloseClient(con);
- return;
- }
-
- if (cupsdFlushHeader(con) < 0)
- {
- cupsdCloseClient(con);
- return;
+ cupsdLogRequest(con, HTTP_STATUS_OK);
}
-
- con->http.state = HTTP_WAITING;
break;
default :
@@ -1974,22 +1756,20 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Handle any incoming data...
*/
- switch (con->http.state)
+ switch (httpGetState(con->http))
{
- case HTTP_PUT_RECV :
+ case HTTP_STATE_PUT_RECV :
do
{
- if ((bytes = httpRead2(HTTP(con), line, sizeof(line))) < 0)
+ if ((bytes = httpRead2(con->http, line, sizeof(line))) < 0)
{
- if (con->http.error && con->http.error != EPIPE)
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] HTTP_PUT_RECV Closing for error "
- "%d (%s)", con->http.fd, con->http.error,
- strerror(con->http.error));
+ if (httpError(con->http) && httpError(con->http) != EPIPE)
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "HTTP_STATE_PUT_RECV Closing for error %d (%s)",
+ httpError(con->http), strerror(httpError(con->http)));
else
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] HTTP_PUT_RECV Closing on EOF",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "HTTP_STATE_PUT_RECV Closing on EOF.");
cupsdCloseClient(con);
return;
@@ -1998,29 +1778,47 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
{
con->bytes += bytes;
- if (write(con->file, line, bytes) < bytes)
+ if (MaxRequestSize > 0 && con->bytes > MaxRequestSize)
+ {
+ close(con->file);
+ con->file = -1;
+ unlink(con->filename);
+ cupsdClearString(&con->filename);
+
+ if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
+ {
+ cupsdCloseClient(con);
+ return;
+ }
+ }
+
+ if (write(con->file, line, (size_t)bytes) < bytes)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unable to write %d bytes to "
- "\"%s\": %s", con->http.fd, bytes, con->filename,
- strerror(errno));
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
+ "Unable to write %d bytes to \"%s\": %s", bytes,
+ con->filename, strerror(errno));
close(con->file);
con->file = -1;
unlink(con->filename);
cupsdClearString(&con->filename);
- if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
}
}
+ else if (httpGetState(con->http) == HTTP_STATE_PUT_RECV)
+ {
+ cupsdCloseClient(con);
+ return;
+ }
}
- while (con->http.state == HTTP_PUT_RECV && data_ready(con));
+ while (httpGetState(con->http) == HTTP_STATE_PUT_RECV && httpGetReady(con->http));
- if (con->http.state == HTTP_WAITING)
+ if (httpGetState(con->http) == HTTP_STATE_STATUS)
{
/*
* End of file, see how big it is...
@@ -2041,7 +1839,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
unlink(con->filename);
cupsdClearString(&con->filename);
- if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -2066,7 +1864,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
}
break;
- case HTTP_POST_RECV :
+ case HTTP_STATE_POST_RECV :
do
{
if (con->request && con->file < 0)
@@ -2075,39 +1873,43 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
* Grab any request data from the connection...
*/
- if ((ipp_state = ippRead(&(con->http), con->request)) == IPP_ERROR)
+ if (!httpWait(con->http, 0))
+ return;
+
+ if ((ipp_state = ippRead(con->http, con->request)) == IPP_STATE_ERROR)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] IPP read error: %s", con->http.fd,
- cupsLastErrorString());
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "IPP read error: %s",
+ cupsLastErrorString());
- cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
+ cupsdSendError(con, HTTP_STATUS_BAD_REQUEST, CUPSD_AUTH_NONE);
cupsdCloseClient(con);
return;
}
- else if (ipp_state != IPP_DATA)
+ else if (ipp_state != IPP_STATE_DATA)
{
- if (con->http.state == HTTP_POST_SEND)
+ if (httpGetState(con->http) == HTTP_STATE_POST_SEND)
{
- cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
+ cupsdSendError(con, HTTP_STATUS_BAD_REQUEST, CUPSD_AUTH_NONE);
cupsdCloseClient(con);
return;
}
+ if (httpGetReady(con->http))
+ continue;
break;
}
else
{
- cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] %d.%d %s %d",
- con->http.fd, con->request->request.op.version[0],
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "%d.%d %s %d",
+ con->request->request.op.version[0],
con->request->request.op.version[1],
ippOpString(con->request->request.op.operation_id),
con->request->request.op.request_id);
- con->bytes += ippLength(con->request);
+ con->bytes += (off_t)ippLength(con->request);
}
}
- if (con->file < 0 && con->http.state != HTTP_POST_SEND)
+ if (con->file < 0 && httpGetState(con->http) != HTTP_STATE_POST_SEND)
{
/*
* Create a file as needed for the request data...
@@ -2119,12 +1921,11 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
if (con->file < 0)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unable to create request file "
- "\"%s\": %s", con->http.fd, con->filename,
- strerror(errno));
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
+ "Unable to create request file \"%s\": %s",
+ con->filename, strerror(errno));
- if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -2136,19 +1937,19 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
}
- if (con->http.state != HTTP_POST_SEND)
+ if (httpGetState(con->http) != HTTP_STATE_POST_SEND)
{
- if ((bytes = httpRead2(HTTP(con), line, sizeof(line))) < 0)
+ if (!httpWait(con->http, 0))
+ return;
+ else if ((bytes = httpRead2(con->http, line, sizeof(line))) < 0)
{
- if (con->http.error && con->http.error != EPIPE)
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] HTTP_POST_SEND Closing for "
- "error %d (%s)", con->http.fd, con->http.error,
- strerror(con->http.error));
+ if (httpError(con->http) && httpError(con->http) != EPIPE)
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "HTTP_STATE_POST_SEND Closing for error %d (%s)",
+ httpError(con->http), strerror(httpError(con->http)));
else
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] HTTP_POST_SEND Closing on EOF",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "HTTP_STATE_POST_SEND Closing on EOF.");
cupsdCloseClient(con);
return;
@@ -2157,19 +1958,32 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
{
con->bytes += bytes;
- if (write(con->file, line, bytes) < bytes)
+ if (MaxRequestSize > 0 && con->bytes > MaxRequestSize)
+ {
+ close(con->file);
+ con->file = -1;
+ unlink(con->filename);
+ cupsdClearString(&con->filename);
+
+ if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
+ {
+ cupsdCloseClient(con);
+ return;
+ }
+ }
+
+ if (write(con->file, line, (size_t)bytes) < bytes)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unable to write %d bytes to "
- "\"%s\": %s", con->http.fd, bytes,
- con->filename, strerror(errno));
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
+ "Unable to write %d bytes to \"%s\": %s",
+ bytes, con->filename, strerror(errno));
close(con->file);
con->file = -1;
unlink(con->filename);
cupsdClearString(&con->filename);
- if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE,
+ if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE,
CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
@@ -2177,21 +1991,21 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
}
}
}
- else if (con->http.state == HTTP_POST_RECV)
+ else if (httpGetState(con->http) == HTTP_STATE_POST_RECV)
return;
- else if (con->http.state != HTTP_POST_SEND)
+ else if (httpGetState(con->http) != HTTP_STATE_POST_SEND)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Closing on unexpected state %s.",
- con->http.fd, http_states[con->http.state]);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "Closing on unexpected state %s.",
+ httpStateString(httpGetState(con->http)));
cupsdCloseClient(con);
return;
}
}
}
- while (con->http.state == HTTP_POST_RECV && data_ready(con));
+ while (httpGetState(con->http) == HTTP_STATE_POST_RECV && httpGetReady(con->http));
- if (con->http.state == HTTP_POST_SEND)
+ if (httpGetState(con->http) == HTTP_STATE_POST_SEND)
{
if (con->file >= 0)
{
@@ -2220,7 +2034,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
con->request = NULL;
}
- if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
@@ -2240,14 +2054,14 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
{
if (!cupsdSendCommand(con, con->command, con->options, 0))
{
- if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE))
+ if (!cupsdSendError(con, HTTP_STATUS_NOT_FOUND, CUPSD_AUTH_NONE))
{
cupsdCloseClient(con);
return;
}
}
else
- cupsdLogRequest(con, HTTP_OK);
+ cupsdLogRequest(con, HTTP_STATUS_OK);
}
}
@@ -2270,13 +2084,12 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
break; /* Anti-compiler-warning-code */
}
- if (con->http.state == HTTP_WAITING)
+ if (httpGetState(con->http) == HTTP_STATE_WAITING)
{
- if (!con->http.keep_alive)
+ if (!httpGetKeepAlive(con->http))
{
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Closing because Keep-Alive disabled",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "Closing because Keep-Alive is disabled.");
cupsdCloseClient(con);
}
else
@@ -2308,10 +2121,10 @@ cupsdSendCommand(
if (fd < 0)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Client %d] Unable to open \"%s\" for reading: %s",
- con->http.fd, con->filename ? con->filename : "/dev/null",
- strerror(errno));
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
+ "Unable to open \"%s\" for reading: %s",
+ con->filename ? con->filename : "/dev/null",
+ strerror(errno));
return (0);
}
@@ -2320,16 +2133,16 @@ cupsdSendCommand(
else
fd = -1;
- con->pipe_pid = pipe_command(con, fd, &(con->file), command, options, root);
+ con->pipe_pid = pipe_command(con, fd, &(con->file), command, options, root);
+ con->pipe_status = HTTP_STATUS_OK;
+
+ httpClearFields(con->http);
if (fd >= 0)
close(fd);
- cupsdLogMessage(CUPSD_LOG_INFO, "[Client %d] Started \"%s\" (pid=%d)",
- con->http.fd, command, con->pipe_pid);
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] file=%d", con->http.fd,
- con->file);
+ cupsdLogClient(con, CUPSD_LOG_INFO, "Started \"%s\" (pid=%d, file=%d)",
+ command, con->pipe_pid, con->file);
if (con->pipe_pid == 0)
return (0);
@@ -2338,6 +2151,8 @@ cupsdSendCommand(
cupsdAddSelect(con->file, (cupsd_selfunc_t)write_pipe, NULL, con);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Waiting for CGI data.");
+
con->sent_header = 0;
con->file_ready = 0;
con->got_fields = 0;
@@ -2356,9 +2171,10 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */
http_status_t code, /* I - Error code */
int auth_type)/* I - Authentication type */
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] cupsdSendError code=%d, auth_type=%d",
- con->http.fd, code, auth_type);
+ char location[HTTP_MAX_VALUE]; /* Location field */
+
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "cupsdSendError code=%d, auth_type=%d", code, auth_type);
#ifdef HAVE_SSL
/*
@@ -2366,12 +2182,12 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */
* server is configured...
*/
- if (code == HTTP_UNAUTHORIZED &&
- DefaultEncryption == HTTP_ENCRYPT_REQUIRED &&
- _cups_strcasecmp(con->http.hostname, "localhost") &&
- !con->http.tls)
+ if (code == HTTP_STATUS_UNAUTHORIZED &&
+ DefaultEncryption == HTTP_ENCRYPTION_REQUIRED &&
+ _cups_strcasecmp(httpGetHostname(con->http, NULL, 0), "localhost") &&
+ !httpIsEncrypted(con->http))
{
- code = HTTP_UPGRADE_REQUIRED;
+ code = HTTP_STATUS_UPGRADE_REQUIRED;
}
#endif /* HAVE_SSL */
@@ -2389,34 +2205,20 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */
* never disable it in that case.
*/
- if (code >= HTTP_BAD_REQUEST && con->http.auth_type != CUPSD_AUTH_NEGOTIATE)
- con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+ strlcpy(location, httpGetField(con->http, HTTP_FIELD_LOCATION), sizeof(location));
- /*
- * Send an error message back to the client. If the error code is a
- * 400 or 500 series, make sure the message contains some text, too!
- */
+ httpClearFields(con->http);
- if (!cupsdSendHeader(con, code, NULL, auth_type))
- return (0);
+ httpSetField(con->http, HTTP_FIELD_LOCATION, location);
-#ifdef HAVE_SSL
- if (code == HTTP_UPGRADE_REQUIRED)
- if (httpPrintf(HTTP(con), "Connection: Upgrade\r\n") < 0)
- return (0);
+ if (code >= HTTP_STATUS_BAD_REQUEST && con->type != CUPSD_AUTH_NEGOTIATE)
+ httpSetKeepAlive(con->http, HTTP_KEEPALIVE_OFF);
- if (httpPrintf(HTTP(con), "Upgrade: TLS/1.0,HTTP/1.1\r\n") < 0)
- return (0);
-#endif /* HAVE_SSL */
+ if (httpGetVersion(con->http) >= HTTP_VERSION_1_1 &&
+ httpGetKeepAlive(con->http) == HTTP_KEEPALIVE_OFF)
+ httpSetField(con->http, HTTP_FIELD_CONNECTION, "close");
- if (con->http.version >= HTTP_1_1 &&
- con->http.keep_alive == HTTP_KEEPALIVE_OFF)
- {
- if (httpPrintf(HTTP(con), "Connection: close\r\n") < 0)
- return (0);
- }
-
- if (code >= HTTP_BAD_REQUEST)
+ if (code >= HTTP_STATUS_BAD_REQUEST)
{
/*
* Send a human-readable error message.
@@ -2430,13 +2232,13 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */
redirect[0] = '\0';
- if (code == HTTP_UNAUTHORIZED)
+ if (code == HTTP_STATUS_UNAUTHORIZED)
text = _cupsLangString(con->language,
_("Enter your username and password or the "
"root username and password to access this "
"page. If you are using Kerberos authentication, "
"make sure you have a valid Kerberos ticket."));
- else if (code == HTTP_UPGRADE_REQUIRED)
+ else if (code == HTTP_STATUS_UPGRADE_REQUIRED)
{
text = urltext;
@@ -2453,7 +2255,7 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */
"CONTENT=\"3;URL=https://%s:%d%s\">\n",
con->servername, con->serverport, con->uri);
}
- else if (code == HTTP_WEBIF_DISABLED)
+ else if (code == HTTP_STATUS_CUPS_WEBIF_DISABLED)
text = _cupsLangString(con->language,
_("The web interface is currently disabled. Run "
"\"cupsctl WebInterface=yes\" to enable it."));
@@ -2477,25 +2279,34 @@ cupsdSendError(cupsd_client_t *con, /* I - Connection */
"<P>%s</P>\n"
"</BODY>\n"
"</HTML>\n",
- httpStatus(code), redirect, httpStatus(code), text);
+ _httpStatus(con->language, code), redirect,
+ _httpStatus(con->language, code), text);
- if (httpPrintf(HTTP(con), "Content-Type: text/html; charset=utf-8\r\n") < 0)
- return (0);
- if (httpPrintf(HTTP(con), "Content-Length: %d\r\n",
- (int)strlen(message)) < 0)
+ /*
+ * Send an error message back to the client. If the error code is a
+ * 400 or 500 series, make sure the message contains some text, too!
+ */
+
+ size_t length = strlen(message); /* Length of message */
+
+ httpSetLength(con->http, length);
+
+ if (!cupsdSendHeader(con, code, "text/html", auth_type))
return (0);
- if (httpPrintf(HTTP(con), "\r\n") < 0)
+
+ if (httpWrite2(con->http, message, length) < 0)
return (0);
- if (httpPrintf(HTTP(con), "%s", message) < 0)
+
+ if (httpFlushWrite(con->http) < 0)
return (0);
}
- else if (httpPrintf(HTTP(con), "\r\n") < 0)
- return (0);
-
- if (cupsdFlushHeader(con) < 0)
- return (0);
+ else
+ {
+ httpSetField(con->http, HTTP_FIELD_CONTENT_LENGTH, "0");
- con->http.state = HTTP_WAITING;
+ if (!cupsdSendHeader(con, code, NULL, auth_type))
+ return (0);
+ }
return (1);
}
@@ -2515,54 +2326,29 @@ cupsdSendHeader(
char auth_str[1024]; /* Authorization string */
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "cupsdSendHeader: code=%d, type=\"%s\", auth_type=%d", code, type, auth_type);
+
/*
* Send the HTTP status header...
*/
- if (code == HTTP_CONTINUE)
- {
- /*
- * 100-continue doesn't send any headers...
- */
-
- return (httpPrintf(HTTP(con), "HTTP/%d.%d 100 Continue\r\n\r\n",
- con->http.version / 100, con->http.version % 100) > 0);
- }
- else if (code == HTTP_WEBIF_DISABLED)
+ if (code == HTTP_STATUS_CUPS_WEBIF_DISABLED)
{
/*
* Treat our special "web interface is disabled" status as "200 OK" for web
* browsers.
*/
- code = HTTP_OK;
+ code = HTTP_STATUS_OK;
}
- httpFlushWrite(HTTP(con));
-
- con->http.data_encoding = HTTP_ENCODE_FIELDS;
-
- if (httpPrintf(HTTP(con), "HTTP/%d.%d %d %s\r\n", con->http.version / 100,
- con->http.version % 100, code, httpStatus(code)) < 0)
- return (0);
- if (httpPrintf(HTTP(con), "Date: %s\r\n", httpGetDateString(time(NULL))) < 0)
- return (0);
if (ServerHeader)
- if (httpPrintf(HTTP(con), "Server: %s\r\n", ServerHeader) < 0)
- return (0);
- if (con->http.keep_alive && con->http.version >= HTTP_1_0)
- {
- if (httpPrintf(HTTP(con), "Connection: Keep-Alive\r\n") < 0)
- return (0);
- if (httpPrintf(HTTP(con), "Keep-Alive: timeout=%d\r\n",
- KeepAliveTimeout) < 0)
- return (0);
- }
- if (code == HTTP_METHOD_NOT_ALLOWED)
- if (httpPrintf(HTTP(con), "Allow: GET, HEAD, OPTIONS, POST, PUT\r\n") < 0)
- return (0);
+ httpSetField(con->http, HTTP_FIELD_SERVER, ServerHeader);
+
+ if (code == HTTP_STATUS_METHOD_NOT_ALLOWED)
+ httpSetField(con->http, HTTP_FIELD_ALLOW, "GET, HEAD, OPTIONS, POST, PUT");
- if (code == HTTP_UNAUTHORIZED)
+ if (code == HTTP_STATUS_UNAUTHORIZED)
{
if (auth_type == CUPSD_AUTH_NONE)
{
@@ -2574,16 +2360,13 @@ cupsdSendHeader(
auth_str[0] = '\0';
- if (auth_type == CUPSD_AUTH_BASIC || auth_type == CUPSD_AUTH_BASICDIGEST)
+ if (auth_type == CUPSD_AUTH_BASIC)
strlcpy(auth_str, "Basic realm=\"CUPS\"", sizeof(auth_str));
- else if (auth_type == CUPSD_AUTH_DIGEST)
- snprintf(auth_str, sizeof(auth_str), "Digest realm=\"CUPS\", nonce=\"%s\"",
- con->http.hostname);
#ifdef HAVE_GSSAPI
else if (auth_type == CUPSD_AUTH_NEGOTIATE)
{
# ifdef AF_LOCAL
- if (_httpAddrFamily(con->http.hostaddr) == AF_LOCAL)
+ if (httpAddrFamily(httpGetAddress(con->http)) == AF_LOCAL)
strlcpy(auth_str, "Basic realm=\"CUPS\"", sizeof(auth_str));
else
# endif /* AF_LOCAL */
@@ -2592,7 +2375,7 @@ cupsdSendHeader(
#endif /* HAVE_GSSAPI */
if (con->best && auth_type != CUPSD_AUTH_NEGOTIATE &&
- !_cups_strcasecmp(con->http.hostname, "localhost"))
+ !_cups_strcasecmp(httpGetHostname(con->http, NULL, 0), "localhost"))
{
/*
* Add a "trc" (try root certification) parameter for local non-Kerberos
@@ -2608,7 +2391,7 @@ cupsdSendHeader(
size_t auth_size; /* Size of remaining buffer */
auth_key = auth_str + strlen(auth_str);
- auth_size = sizeof(auth_str) - (auth_key - auth_str);
+ auth_size = sizeof(auth_str) - (size_t)(auth_key - auth_str);
for (name = (char *)cupsArrayFirst(con->best->names);
name;
@@ -2641,35 +2424,24 @@ cupsdSendHeader(
if (auth_str[0])
{
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] WWW-Authenticate: %s", con->http.fd,
- auth_str);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "WWW-Authenticate: %s", auth_str);
- if (httpPrintf(HTTP(con), "WWW-Authenticate: %s\r\n", auth_str) < 0)
- return (0);
+ httpSetField(con->http, HTTP_FIELD_WWW_AUTHENTICATE, auth_str);
}
}
if (con->language && strcmp(con->language->language, "C"))
- {
- if (httpPrintf(HTTP(con), "Content-Language: %s\r\n",
- con->language->language) < 0)
- return (0);
- }
+ httpSetField(con->http, HTTP_FIELD_CONTENT_LANGUAGE, con->language->language);
if (type)
{
if (!strcmp(type, "text/html"))
- {
- if (httpPrintf(HTTP(con),
- "Content-Type: text/html; charset=utf-8\r\n") < 0)
- return (0);
- }
- else if (httpPrintf(HTTP(con), "Content-Type: %s\r\n", type) < 0)
- return (0);
+ httpSetField(con->http, HTTP_FIELD_CONTENT_TYPE, "text/html; charset=utf-8");
+ else
+ httpSetField(con->http, HTTP_FIELD_CONTENT_TYPE, type);
}
- return (1);
+ return (!httpWriteResponse(con->http, code));
}
@@ -2722,36 +2494,35 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
ipp_state_t ipp_state; /* IPP state value */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[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)
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "con->http=%p", con->http);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "cupsdWriteClient "
+ "error=%d, "
+ "used=%d, "
+ "state=%s, "
+ "data_encoding=HTTP_ENCODING_%s, "
+ "data_remaining=" CUPS_LLFMT ", "
+ "response=%p(%s), "
+ "pipe_pid=%d, "
+ "file=%d",
+ httpError(con->http), (int)httpGetReady(con->http),
+ httpStateString(httpGetState(con->http)),
+ httpIsChunked(con->http) ? "CHUNKED" : "LENGTH",
+ CUPS_LLCAST httpGetLength2(con->http),
+ con->response,
+ con->response ? ippStateString(ippGetState(con->request)) : "",
+ con->pipe_pid, con->file);
+
+ if (httpGetState(con->http) != HTTP_STATE_GET_SEND &&
+ httpGetState(con->http) != HTTP_STATE_POST_SEND)
{
/*
* If we get called in the wrong state, then something went wrong with the
* connection and we need to shut it down...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Closing on unexpected HTTP state %s.",
- con->http.fd, http_states[con->http.state]);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing on unexpected HTTP write state %s.",
+ httpStateString(httpGetState(con->http)));
cupsdCloseClient(con);
return;
}
@@ -2764,27 +2535,71 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
cupsdAddSelect(con->file, (cupsd_selfunc_t)write_pipe, NULL, con);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Waiting for CGI data.");
+
if (!con->file_ready)
{
/*
* Try again later when there is CGI output available...
*/
- cupsdRemoveSelect(con->http.fd);
+ cupsdRemoveSelect(httpGetFd(con->http));
return;
}
con->file_ready = 0;
}
- if (con->response && con->response->state != IPP_DATA)
+ bytes = (ssize_t)(sizeof(con->header) - (size_t)con->header_used);
+
+ if (!con->pipe_pid && bytes > (ssize_t)httpGetRemaining(con->http))
{
- ipp_state = ippWrite(HTTP(con), con->response);
- bytes = ipp_state != IPP_ERROR &&
- (con->file >= 0 || ipp_state != IPP_DATA);
+ /*
+ * Limit GET bytes to original size of file (STR #3265)...
+ */
+
+ bytes = (ssize_t)httpGetRemaining(con->http);
}
- else if ((bytes = read(con->file, con->header + con->header_used,
- sizeof(con->header) - con->header_used)) > 0)
+
+ if (con->response && con->response->state != IPP_STATE_DATA)
+ {
+ size_t wused = httpGetPending(con->http); /* Previous write buffer use */
+
+ do
+ {
+ /*
+ * Write a single attribute or the IPP message header...
+ */
+
+ ipp_state = ippWrite(con->http, con->response);
+
+ /*
+ * If the write buffer has been flushed, stop buffering up attributes...
+ */
+
+ if (httpGetPending(con->http) <= wused)
+ break;
+ }
+ while (ipp_state != IPP_STATE_DATA && ipp_state != IPP_STATE_ERROR);
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "Writing IPP response, ipp_state=%s, old "
+ "wused=" CUPS_LLFMT ", new wused=" CUPS_LLFMT,
+ ippStateString(ipp_state),
+ CUPS_LLCAST wused, CUPS_LLCAST httpGetPending(con->http));
+
+ if (httpGetPending(con->http) > 0)
+ httpFlushWrite(con->http);
+
+ bytes = ipp_state != IPP_STATE_ERROR &&
+ (con->file >= 0 || ipp_state != IPP_STATE_DATA);
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "bytes=%d, http_state=%d, data_remaining=" CUPS_LLFMT,
+ (int)bytes, httpGetState(con->http),
+ CUPS_LLCAST httpGetLength2(con->http));
+ }
+ else if ((bytes = read(con->file, con->header + con->header_used, (size_t)bytes)) > 0)
{
con->header_used += bytes;
@@ -2809,7 +2624,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
bufptr[-1] = '\0';
*bufptr++ = '\0';
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Script header: %s", con->header);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Script header: %s", con->header);
if (!con->sent_header)
{
@@ -2817,46 +2632,43 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
* Handle redirection and CGI status codes...
*/
- if (!_cups_strncasecmp(con->header, "Location:", 9))
+ http_field_t field; /* HTTP field */
+ char *value = strchr(con->header, ':');
+ /* Value of field */
+
+ if (value)
{
- if (!cupsdSendHeader(con, HTTP_SEE_OTHER, NULL, CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
+ *value++ = '\0';
+ while (isspace(*value & 255))
+ value ++;
+ }
- con->sent_header = 2;
+ field = httpFieldValue(con->header);
- if (httpPrintf(HTTP(con), "Content-Length: 0\r\n") < 0)
- return;
+ if (field != HTTP_FIELD_UNKNOWN && value)
+ {
+ httpSetField(con->http, field, value);
+
+ if (field == HTTP_FIELD_LOCATION)
+ {
+ con->pipe_status = HTTP_STATUS_SEE_OTHER;
+ con->sent_header = 2;
+ }
+ else
+ con->sent_header = 1;
}
- else if (!_cups_strncasecmp(con->header, "Status:", 7))
+ else if (!_cups_strcasecmp(con->header, "Status") && value)
{
- cupsdSendError(con, (http_status_t)atoi(con->header + 7),
- CUPSD_AUTH_NONE);
+ con->pipe_status = (http_status_t)atoi(value);
con->sent_header = 2;
}
- else
+ else if (!_cups_strcasecmp(con->header, "Set-Cookie") && value)
{
- if (!cupsdSendHeader(con, HTTP_OK, NULL, CUPSD_AUTH_NONE))
- {
- cupsdCloseClient(con);
- return;
- }
-
+ httpSetCookie(con->http, value);
con->sent_header = 1;
-
- if (con->http.version == HTTP_1_1)
- {
- if (httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n") < 0)
- return;
- }
- }
+ }
}
- if (_cups_strncasecmp(con->header, "Status:", 7))
- httpPrintf(HTTP(con), "%s\r\n", con->header);
-
/*
* Update buffer...
*/
@@ -2864,7 +2676,7 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
con->header_used -= bufptr - con->header;
if (con->header_used > 0)
- memmove(con->header, bufptr, con->header_used);
+ memmove(con->header, bufptr, (size_t)con->header_used);
bufptr = con->header - 1;
@@ -2876,14 +2688,28 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
{
con->got_fields = 1;
- if (cupsdFlushHeader(con) < 0)
+ if (httpGetVersion(con->http) == HTTP_VERSION_1_1 &&
+ !httpGetField(con->http, HTTP_FIELD_CONTENT_LENGTH)[0])
+ httpSetLength(con->http, 0);
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Sending status %d for CGI.", con->pipe_status);
+
+ if (con->pipe_status == HTTP_STATUS_OK)
{
- cupsdCloseClient(con);
- return;
+ if (!cupsdSendHeader(con, con->pipe_status, NULL, CUPSD_AUTH_NONE))
+ {
+ cupsdCloseClient(con);
+ return;
+ }
+ }
+ else
+ {
+ if (!cupsdSendError(con, con->pipe_status, CUPSD_AUTH_NONE))
+ {
+ cupsdCloseClient(con);
+ return;
+ }
}
-
- if (con->http.version == HTTP_1_1)
- con->http.data_encoding = HTTP_ENCODE_CHUNKED;
}
else
field_col = 0;
@@ -2893,30 +2719,25 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
}
if (!con->got_fields)
- {
- con->http.activity = time(NULL);
return;
- }
}
if (con->header_used > 0)
{
- if (httpWrite2(HTTP(con), con->header, con->header_used) < 0)
+ if (httpWrite2(con->http, con->header, (size_t)con->header_used) < 0)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Closing for error %d (%s)",
- con->http.fd, con->http.error,
- strerror(con->http.error));
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing for error %d (%s)",
+ httpError(con->http), strerror(httpError(con->http)));
cupsdCloseClient(con);
return;
}
- if (con->http.data_encoding == HTTP_ENCODE_CHUNKED)
- httpFlushWrite(HTTP(con));
+ if (httpIsChunked(con->http))
+ httpFlushWrite(con->http);
con->bytes += con->header_used;
- if (con->http.state == HTTP_WAITING)
+ if (httpGetState(con->http) == HTTP_STATE_WAITING)
bytes = 0;
else
bytes = con->header_used;
@@ -2926,33 +2747,36 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
}
if (bytes <= 0 ||
- (con->http.state != HTTP_GET_SEND && con->http.state != HTTP_POST_SEND))
+ (httpGetState(con->http) != HTTP_STATE_GET_SEND &&
+ httpGetState(con->http) != HTTP_STATE_POST_SEND))
{
if (!con->sent_header && con->pipe_pid)
- cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE);
+ cupsdSendError(con, HTTP_STATUS_SERVER_ERROR, CUPSD_AUTH_NONE);
else
{
- cupsdLogRequest(con, HTTP_OK);
-
- httpFlushWrite(HTTP(con));
+ cupsdLogRequest(con, HTTP_STATUS_OK);
- if (con->http.data_encoding == HTTP_ENCODE_CHUNKED && con->sent_header == 1)
+ if (httpIsChunked(con->http) && (!con->pipe_pid || con->sent_header > 0))
{
- if (httpWrite2(HTTP(con), "", 0) < 0)
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Sending 0-length chunk.");
+
+ if (httpWrite2(con->http, "", 0) < 0)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Closing for error %d (%s)",
- con->http.fd, con->http.error,
- strerror(con->http.error));
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Closing for error %d (%s)",
+ httpError(con->http), strerror(httpError(con->http)));
cupsdCloseClient(con);
return;
}
}
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Flushing write buffer.");
+ httpFlushWrite(con->http);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "New state is %s", httpStateString(httpGetState(con->http)));
}
- con->http.state = HTTP_WAITING;
+ cupsdAddSelect(httpGetFd(con->http), (cupsd_selfunc_t)cupsdReadClient, NULL, con);
- cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, NULL, con);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Waiting for request.");
if (con->file >= 0)
{
@@ -2988,11 +2812,10 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
cupsdClearString(&con->options);
cupsdClearString(&con->query_string);
- if (!con->http.keep_alive)
+ if (!httpGetKeepAlive(con->http))
{
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Client %d] Closing because Keep-Alive disabled.",
- con->http.fd);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG,
+ "Closing because Keep-Alive is disabled.");
cupsdCloseClient(con);
return;
}
@@ -3002,8 +2825,6 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
cupsdSetBusyState();
}
}
-
- con->http.activity = time(NULL);
}
@@ -3016,23 +2837,19 @@ check_if_modified(
cupsd_client_t *con, /* I - Client connection */
struct stat *filestats) /* I - File information */
{
- char *ptr; /* Pointer into field */
+ const char *ptr; /* Pointer into field */
time_t date; /* Time/date value */
off_t size; /* Size/length value */
size = 0;
date = 0;
- ptr = con->http.fields[HTTP_FIELD_IF_MODIFIED_SINCE];
+ ptr = httpGetField(con->http, HTTP_FIELD_IF_MODIFIED_SINCE);
if (*ptr == '\0')
return (1);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] check_if_modified "
- "filestats=%p(" CUPS_LLFMT ", %d)) If-Modified-Since=\"%s\"",
- con->http.fd, filestats, CUPS_LLCAST filestats->st_size,
- (int)filestats->st_mtime, ptr);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "check_if_modified: filestats=%p(" CUPS_LLFMT ", %d)) If-Modified-Since=\"%s\"", filestats, CUPS_LLCAST filestats->st_size, (int)filestats->st_mtime, ptr);
while (*ptr != '\0')
{
@@ -3083,35 +2900,26 @@ compare_clients(cupsd_client_t *a, /* I - First client */
}
+#ifdef HAVE_SSL
/*
- * 'data_ready()' - Check whether data is available from a client.
+ * 'cupsd_start_tls()' - Start encryption on a connection.
*/
-static int /* O - 1 if data is ready, 0 otherwise */
-data_ready(cupsd_client_t *con) /* I - Client */
+static int /* O - 0 on success, -1 on error */
+cupsd_start_tls(cupsd_client_t *con, /* I - Client connection */
+ http_encryption_t e) /* I - Encryption mode */
{
- if (con->http.used > 0)
- return (1);
-#ifdef HAVE_SSL
- else if (con->http.tls)
+ if (httpEncryption(con->http, e))
{
-# ifdef HAVE_LIBSSL
- if (SSL_pending((SSL *)(con->http.tls)))
- return (1);
-# elif defined(HAVE_GNUTLS)
- if (gnutls_record_check_pending(con->http.tls))
- return (1);
-# elif defined(HAVE_CDSASSL)
- size_t bytes; /* Bytes that are available */
-
- if (!SSLGetBufferedReadSize(con->http.tls, &bytes) && bytes > 0)
- return (1);
-# endif /* HAVE_LIBSSL */
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to encrypt connection: %s",
+ cupsLastErrorString());
+ return (-1);
}
-#endif /* HAVE_SSL */
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Connection now encrypted.");
return (0);
}
+#endif /* HAVE_SSL */
/*
@@ -3122,12 +2930,14 @@ static char * /* O - Real filename */
get_file(cupsd_client_t *con, /* I - Client connection */
struct stat *filestats, /* O - File information */
char *filename, /* IO - Filename buffer */
- int len) /* I - Buffer length */
+ size_t len) /* I - Buffer length */
{
int status; /* Status of filesystem calls */
char *ptr; /* Pointer info filename */
- int plen; /* Remaining length after pointer */
- char language[7]; /* Language subdirectory, if any */
+ size_t plen; /* Remaining length after pointer */
+ char language[7], /* Language subdirectory, if any */
+ dest[1024]; /* Destination name */
+ int perm_check = 1; /* Do permissions check? */
/*
@@ -3137,17 +2947,59 @@ get_file(cupsd_client_t *con, /* I - Client connection */
language[0] = '\0';
if (!strncmp(con->uri, "/ppd/", 5) && !strchr(con->uri + 5, '/'))
+ {
+ strlcpy(dest, con->uri + 5, sizeof(dest));
+ ptr = dest + strlen(dest) - 4;
+
+ if (ptr <= dest || strcmp(ptr, ".ppd"))
+ {
+ cupsdLogClient(con, CUPSD_LOG_INFO, "Disallowed path \"%s\".", con->uri);
+ return (NULL);
+ }
+
+ *ptr = '\0';
+ if (!cupsdFindPrinter(dest))
+ {
+ cupsdLogClient(con, CUPSD_LOG_INFO, "No printer \"%s\" found.", dest);
+ return (NULL);
+ }
+
snprintf(filename, len, "%s%s", ServerRoot, con->uri);
+
+ perm_check = 0;
+ }
else if (!strncmp(con->uri, "/icons/", 7) && !strchr(con->uri + 7, '/'))
{
- snprintf(filename, len, "%s/%s", CacheDir, con->uri + 7);
+ strlcpy(dest, con->uri + 7, sizeof(dest));
+ ptr = dest + strlen(dest) - 4;
+
+ if (ptr <= dest || strcmp(ptr, ".png"))
+ {
+ cupsdLogClient(con, CUPSD_LOG_INFO, "Disallowed path \"%s\".", con->uri);
+ return (NULL);
+ }
+
+ *ptr = '\0';
+ if (!cupsdFindDest(dest))
+ {
+ cupsdLogClient(con, CUPSD_LOG_INFO, "No printer \"%s\" found.", dest);
+ return (NULL);
+ }
+
+ snprintf(filename, len, "%s/%s.png", CacheDir, dest);
if (access(filename, F_OK) < 0)
snprintf(filename, len, "%s/images/generic.png", DocumentRoot);
+
+ perm_check = 0;
}
else if (!strncmp(con->uri, "/rss/", 5) && !strchr(con->uri + 5, '/'))
snprintf(filename, len, "%s/rss/%s", CacheDir, con->uri + 5);
- else if (!strncmp(con->uri, "/admin/conf/", 12))
- snprintf(filename, len, "%s%s", ServerRoot, con->uri + 11);
+ else if (!strcmp(con->uri, "/admin/conf/cupsd.conf"))
+ {
+ strlcpy(filename, ConfigurationFile, len);
+
+ perm_check = 0;
+ }
else if (!strncmp(con->uri, "/admin/log/", 11))
{
if (!strncmp(con->uri + 11, "access_log", 10) && AccessLog[0] == '/')
@@ -3158,6 +3010,8 @@ get_file(cupsd_client_t *con, /* I - Client connection */
strlcpy(filename, PageLog, len);
else
return (NULL);
+
+ perm_check = 0;
}
else if (con->language)
{
@@ -3175,7 +3029,7 @@ get_file(cupsd_client_t *con, /* I - Client connection */
* then fallback to the default one...
*/
- if ((status = stat(filename, filestats)) != 0 && language[0] &&
+ if ((status = lstat(filename, filestats)) != 0 && language[0] &&
strncmp(con->uri, "/icons/", 7) &&
strncmp(con->uri, "/ppd/", 5) &&
strncmp(con->uri, "/rss/", 5) &&
@@ -3192,7 +3046,7 @@ get_file(cupsd_client_t *con, /* I - Client connection */
if ((ptr = strchr(filename, '?')) != NULL)
*ptr = '\0';
- if ((status = stat(filename, filestats)) != 0)
+ if ((status = lstat(filename, filestats)) != 0)
{
/*
* Drop the language prefix and try the root directory...
@@ -3204,12 +3058,33 @@ get_file(cupsd_client_t *con, /* I - Client connection */
if ((ptr = strchr(filename, '?')) != NULL)
*ptr = '\0';
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
}
/*
- * If we're found a directory, get the index.html file instead...
+ * If we've found a symlink, 404 the sucker to avoid disclosing information.
+ */
+
+ if (!status && S_ISLNK(filestats->st_mode))
+ {
+ cupsdLogClient(con, CUPSD_LOG_INFO, "Symlinks such as \"%s\" are not allowed.", filename);
+ return (NULL);
+ }
+
+ /*
+ * Similarly, if the file/directory does not have world read permissions, do
+ * not allow access...
+ */
+
+ if (!status && perm_check && !(filestats->st_mode & S_IROTH))
+ {
+ cupsdLogClient(con, CUPSD_LOG_INFO, "Files/directories such as \"%s\" must be world-readable.", filename);
+ return (NULL);
+ }
+
+ /*
+ * If we've found a directory, get the index.html file instead...
*/
if (!status && S_ISDIR(filestats->st_mode))
@@ -3249,16 +3124,16 @@ get_file(cupsd_client_t *con, /* I - Client connection */
*ptr = '\0';
ptr = filename + strlen(filename);
- plen = len - (ptr - filename);
+ plen = len - (size_t)(ptr - filename);
strlcpy(ptr, "index.html", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
#ifdef HAVE_JAVA
if (status)
{
strlcpy(ptr, "index.class", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
#endif /* HAVE_JAVA */
@@ -3266,7 +3141,7 @@ get_file(cupsd_client_t *con, /* I - Client connection */
if (status)
{
strlcpy(ptr, "index.pl", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
#endif /* HAVE_PERL */
@@ -3274,7 +3149,7 @@ get_file(cupsd_client_t *con, /* I - Client connection */
if (status)
{
strlcpy(ptr, "index.php", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
#endif /* HAVE_PHP */
@@ -3282,24 +3157,42 @@ get_file(cupsd_client_t *con, /* I - Client connection */
if (status)
{
strlcpy(ptr, "index.pyc", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
if (status)
{
strlcpy(ptr, "index.py", plen);
- status = stat(filename, filestats);
+ status = lstat(filename, filestats);
}
#endif /* HAVE_PYTHON */
}
while (status && language[0]);
+
+ /*
+ * If we've found a symlink, 404 the sucker to avoid disclosing information.
+ */
+
+ if (!status && S_ISLNK(filestats->st_mode))
+ {
+ cupsdLogClient(con, CUPSD_LOG_INFO, "Symlinks such as \"%s\" are not allowed.", filename);
+ return (NULL);
+ }
+
+ /*
+ * Similarly, if the file/directory does not have world read permissions, do
+ * not allow access...
+ */
+
+ if (!status && perm_check && !(filestats->st_mode & S_IROTH))
+ {
+ cupsdLogClient(con, CUPSD_LOG_INFO, "Files/directories such as \"%s\" must be world-readable.", filename);
+ return (NULL);
+ }
}
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] get_file filestats=%p, filename=%p, len=%d, "
- "returning \"%s\".", con->http.fd, filestats, filename, len,
- status ? "(null)" : filename);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "get_file: filestats=%p, filename=%p, len=" CUPS_LLFMT ", returning \"%s\".", filestats, filename, CUPS_LLCAST len, status ? "(null)" : filename);
if (status)
return (NULL);
@@ -3328,9 +3221,9 @@ install_cupsd_conf(cupsd_client_t *con) /* I - Connection */
if ((in = cupsFileOpen(con->filename, "rb")) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open request file \"%s\": %s",
+ cupsdLogClient(con, CUPSD_LOG_ERROR, "Unable to open request file \"%s\": %s",
con->filename, strerror(errno));
- return (HTTP_SERVER_ERROR);
+ goto server_error;
}
/*
@@ -3340,10 +3233,10 @@ install_cupsd_conf(cupsd_client_t *con) /* I - Connection */
if ((out = cupsdCreateConfFile(ConfigurationFile, ConfigFilePerm)) == NULL)
{
cupsFileClose(in);
- return (HTTP_SERVER_ERROR);
+ goto server_error;
}
- cupsdLogMessage(CUPSD_LOG_INFO, "Installing config file \"%s\"...",
+ cupsdLogClient(con, CUPSD_LOG_INFO, "Installing config file \"%s\"...",
ConfigurationFile);
/*
@@ -3351,9 +3244,9 @@ install_cupsd_conf(cupsd_client_t *con) /* I - Connection */
*/
while ((bytes = cupsFileRead(in, buffer, sizeof(buffer))) > 0)
- if (cupsFileWrite(out, buffer, bytes) < bytes)
+ if (cupsFileWrite(out, buffer, (size_t)bytes) < bytes)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
+ cupsdLogClient(con, CUPSD_LOG_ERROR,
"Unable to copy to config file \"%s\": %s",
ConfigurationFile, strerror(errno));
@@ -3361,9 +3254,9 @@ install_cupsd_conf(cupsd_client_t *con) /* I - Connection */
cupsFileClose(out);
snprintf(filename, sizeof(filename), "%s.N", ConfigurationFile);
- cupsdRemoveFile(filename);
+ cupsdUnlinkOrRemoveFile(filename);
- return (HTTP_SERVER_ERROR);
+ goto server_error;
}
/*
@@ -3373,13 +3266,13 @@ install_cupsd_conf(cupsd_client_t *con) /* I - Connection */
cupsFileClose(in);
if (cupsdCloseCreatedConfFile(out, ConfigurationFile))
- return (HTTP_SERVER_ERROR);
+ goto server_error;
/*
* Remove the request file...
*/
- cupsdRemoveFile(con->filename);
+ cupsdUnlinkOrRemoveFile(con->filename);
cupsdClearString(&con->filename);
/*
@@ -3393,7 +3286,18 @@ install_cupsd_conf(cupsd_client_t *con) /* I - Connection */
* Return that the file was created successfully...
*/
- return (HTTP_CREATED);
+ return (HTTP_STATUS_CREATED);
+
+ /*
+ * Common exit for errors...
+ */
+
+ server_error:
+
+ cupsdUnlinkOrRemoveFile(con->filename);
+ cupsdClearString(&con->filename);
+
+ return (HTTP_STATUS_SERVER_ERROR);
}
@@ -3426,11 +3330,7 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
if (!type || _cups_strcasecmp(type->super, "application"))
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[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");
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "is_cgi: filename=\"%s\", filestats=%p, type=%s/%s, returning 0.", filename, filestats, type ? type->super : "unknown", type ? type->type : "unknown");
return (0);
}
@@ -3446,10 +3346,7 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
if (options)
cupsdSetStringf(&con->options, " %s", options);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
- "type=%s/%s, returning 1", con->http.fd, filename,
- filestats, type->super, type->type);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "is_cgi: filename=\"%s\", filestats=%p, type=%s/%s, returning 1.", filename, filestats, type->super, type->type);
return (1);
}
#ifdef HAVE_JAVA
@@ -3466,10 +3363,7 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
else
cupsdSetStringf(&con->options, " %s", filename);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
- "type=%s/%s, returning 1", con->http.fd, filename,
- filestats, type->super, type->type);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "is_cgi: filename=\"%s\", filestats=%p, type=%s/%s, returning 1.", filename, filestats, type->super, type->type);
return (1);
}
#endif /* HAVE_JAVA */
@@ -3487,10 +3381,7 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
else
cupsdSetStringf(&con->options, " %s", filename);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
- "type=%s/%s, returning 1", con->http.fd, filename,
- filestats, type->super, type->type);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "is_cgi: filename=\"%s\", filestats=%p, type=%s/%s, returning 1.", filename, filestats, type->super, type->type);
return (1);
}
#endif /* HAVE_PERL */
@@ -3508,10 +3399,7 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
else
cupsdSetStringf(&con->options, " %s", filename);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
- "type=%s/%s, returning 1", con->http.fd, filename,
- filestats, type->super, type->type);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "is_cgi: filename=\"%s\", filestats=%p, type=%s/%s, returning 1.", filename, filestats, type->super, type->type);
return (1);
}
#endif /* HAVE_PHP */
@@ -3529,18 +3417,12 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
else
cupsdSetStringf(&con->options, " %s", filename);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
- "type=%s/%s, returning 1", con->http.fd, filename,
- filestats, type->super, type->type);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "is_cgi: filename=\"%s\", filestats=%p, type=%s/%s, returning 1.", filename, filestats, type->super, type->type);
return (1);
}
#endif /* HAVE_PYTHON */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] is_cgi filename=\"%s\", filestats=%p, "
- "type=%s/%s, returning 0", con->http.fd, filename,
- filestats, type->super, type->type);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "is_cgi: filename=\"%s\", filestats=%p, type=%s/%s, returning 0.", filename, filestats, type->super, type->type);
return (0);
}
@@ -3560,6 +3442,14 @@ is_path_absolute(const char *path) /* I - Input path */
return (0);
/*
+ * Check for "<" or quotes in the path and reject since this is probably
+ * someone trying to inject HTML...
+ */
+
+ if (strchr(path, '<') != NULL || strchr(path, '\"') != NULL || strchr(path, '\'') != NULL)
+ return (0);
+
+ /*
* Check for "/.." in the path...
*/
@@ -3639,21 +3529,12 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
* be consistent with Apache...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] pipe_command infile=%d, outfile=%p, "
- "command=\"%s\", options=\"%s\", root=%d",
- con->http.fd, infile, outfile, command,
- options ? options : "(null)", root);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "pipe_command: infile=%d, outfile=%p, command=\"%s\", options=\"%s\", root=%d", infile, outfile, command, options ? options : "(null)", root);
argv[0] = command;
if (options)
- {
- commptr = options;
- if (*commptr == ' ')
- commptr ++;
- strlcpy(argbuf, commptr, sizeof(argbuf));
- }
+ strlcpy(argbuf, options, sizeof(argbuf));
else
argbuf[0] = '\0';
@@ -3680,7 +3561,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
commptr ++;
}
- if (*commptr == '?' && con->operation == HTTP_GET && !con->query_string)
+ if (*commptr == '?' && con->operation == HTTP_STATE_GET && !con->query_string)
{
commptr ++;
cupsdSetStringf(&(con->query_string), "QUERY_STRING=%s", commptr);
@@ -3723,9 +3604,9 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
*/
if (commptr[1] >= '0' && commptr[1] <= '9')
- *commptr = (commptr[1] - '0') << 4;
+ *commptr = (char)((commptr[1] - '0') << 4);
else
- *commptr = (tolower(commptr[1]) - 'a' + 10) << 4;
+ *commptr = (char)((tolower(commptr[1]) - 'a' + 10) << 4);
if (commptr[2] >= '0' && commptr[2] <= '9')
*commptr |= commptr[2] - '0';
@@ -3753,7 +3634,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
if (con->username[0])
{
snprintf(auth_type, sizeof(auth_type), "AUTH_TYPE=%s",
- httpGetField(HTTP(con), HTTP_FIELD_AUTHORIZATION));
+ httpGetField(con->http, HTTP_FIELD_AUTHORIZATION));
if ((uriptr = strchr(auth_type + 10, ' ')) != NULL)
*uriptr = '\0';
@@ -3773,7 +3654,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
* the POSIX locale...
*/
- strcpy(lang, "LANG=C");
+ strlcpy(lang, "LANG=C", sizeof(lang));
break;
case 2 :
@@ -3801,14 +3682,14 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
else if (con->language)
snprintf(lang, sizeof(lang), "LANG=%s.UTF8", con->language->language);
else
- strcpy(lang, "LANG=C");
+ strlcpy(lang, "LANG=C", sizeof(lang));
- strcpy(remote_addr, "REMOTE_ADDR=");
- httpAddrString(con->http.hostaddr, remote_addr + 12,
+ strlcpy(remote_addr, "REMOTE_ADDR=", sizeof(remote_addr));
+ httpAddrString(httpGetAddress(con->http), remote_addr + 12,
sizeof(remote_addr) - 12);
snprintf(remote_host, sizeof(remote_host), "REMOTE_HOST=%s",
- con->http.hostname);
+ httpGetHostname(con->http, NULL, 0));
snprintf(script_name, sizeof(script_name), "SCRIPT_NAME=%s", con->uri);
if ((uriptr = strchr(script_name, '?')) != NULL)
@@ -3817,14 +3698,14 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
snprintf(script_filename, sizeof(script_filename), "SCRIPT_FILENAME=%s%s",
DocumentRoot, script_name + 12);
- sprintf(server_port, "SERVER_PORT=%d", con->serverport);
+ snprintf(server_port, sizeof(server_port), "SERVER_PORT=%d", con->serverport);
- if (con->http.fields[HTTP_FIELD_HOST][0])
+ if (httpGetField(con->http, HTTP_FIELD_HOST)[0])
{
char *nameptr; /* Pointer to ":port" */
snprintf(server_name, sizeof(server_name), "SERVER_NAME=%s",
- con->http.fields[HTTP_FIELD_HOST]);
+ httpGetField(con->http, HTTP_FIELD_HOST));
if ((nameptr = strrchr(server_name, ':')) != NULL && !strchr(nameptr, ']'))
*nameptr = '\0'; /* Strip trailing ":port" */
}
@@ -3857,35 +3738,35 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
envp[envc ++] = remote_user;
}
- if (con->http.version == HTTP_1_1)
+ if (httpGetVersion(con->http) == HTTP_VERSION_1_1)
envp[envc ++] = "SERVER_PROTOCOL=HTTP/1.1";
- else if (con->http.version == HTTP_1_0)
+ else if (httpGetVersion(con->http) == HTTP_VERSION_1_0)
envp[envc ++] = "SERVER_PROTOCOL=HTTP/1.0";
else
envp[envc ++] = "SERVER_PROTOCOL=HTTP/0.9";
- if (con->http.cookie)
+ if (httpGetCookie(con->http))
{
snprintf(http_cookie, sizeof(http_cookie), "HTTP_COOKIE=%s",
- con->http.cookie);
+ httpGetCookie(con->http));
envp[envc ++] = http_cookie;
}
- if (con->http.fields[HTTP_FIELD_USER_AGENT][0])
+ if (httpGetField(con->http, HTTP_FIELD_USER_AGENT)[0])
{
snprintf(http_user_agent, sizeof(http_user_agent), "HTTP_USER_AGENT=%s",
- con->http.fields[HTTP_FIELD_USER_AGENT]);
+ httpGetField(con->http, HTTP_FIELD_USER_AGENT));
envp[envc ++] = http_user_agent;
}
- if (con->http.fields[HTTP_FIELD_REFERER][0])
+ if (httpGetField(con->http, HTTP_FIELD_REFERER)[0])
{
snprintf(http_referer, sizeof(http_referer), "HTTP_REFERER=%s",
- con->http.fields[HTTP_FIELD_REFERER]);
+ httpGetField(con->http, HTTP_FIELD_REFERER));
envp[envc ++] = http_referer;
}
- if (con->operation == HTTP_GET)
+ if (con->operation == HTTP_STATE_GET)
{
envp[envc ++] = "REQUEST_METHOD=GET";
@@ -3905,7 +3786,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
sprintf(content_length, "CONTENT_LENGTH=" CUPS_LLFMT,
CUPS_LLCAST con->bytes);
snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s",
- con->http.fields[HTTP_FIELD_CONTENT_TYPE]);
+ httpGetField(con->http, HTTP_FIELD_CONTENT_TYPE));
envp[envc ++] = "REQUEST_METHOD=POST";
envp[envc ++] = content_length;
@@ -3916,7 +3797,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
* Tell the CGI if we are using encryption...
*/
- if (con->http.tls)
+ if (httpIsEncrypted(con->http))
envp[envc ++] = "HTTPS=ON";
/*
@@ -3991,31 +3872,42 @@ valid_host(cupsd_client_t *con) /* I - Client connection */
{
cupsd_alias_t *a; /* Current alias */
cupsd_netif_t *netif; /* Current network interface */
- const char *host, /* Host field */
- *end; /* End character */
+ const char *end; /* End character */
+ char *ptr; /* Pointer into host value */
+
+ /*
+ * Copy the Host: header for later use...
+ */
+
+ strlcpy(con->clientname, httpGetField(con->http, HTTP_FIELD_HOST),
+ sizeof(con->clientname));
+ if ((ptr = strrchr(con->clientname, ':')) != NULL && !strchr(ptr, ']'))
+ {
+ *ptr++ = '\0';
+ con->clientport = atoi(ptr);
+ }
+ else
+ con->clientport = con->serverport;
- host = con->http.fields[HTTP_FIELD_HOST];
+ /*
+ * Then validate...
+ */
- if (httpAddrLocalhost(con->http.hostaddr))
+ if (httpAddrLocalhost(httpGetAddress(con->http)))
{
/*
* Only allow "localhost" or the equivalent IPv4 or IPv6 numerical
* addresses when accessing CUPS via the loopback interface...
*/
- return (!_cups_strcasecmp(host, "localhost") ||
- !_cups_strncasecmp(host, "localhost:", 10) ||
- !_cups_strcasecmp(host, "localhost.") ||
- !_cups_strncasecmp(host, "localhost.:", 11) ||
+ return (!_cups_strcasecmp(con->clientname, "localhost") ||
+ !_cups_strcasecmp(con->clientname, "localhost.") ||
#ifdef __linux
- !_cups_strcasecmp(host, "localhost.localdomain") ||
- !_cups_strncasecmp(host, "localhost.localdomain:", 22) ||
+ !_cups_strcasecmp(con->clientname, "localhost.localdomain") ||
#endif /* __linux */
- !strcmp(host, "127.0.0.1") ||
- !strncmp(host, "127.0.0.1:", 10) ||
- !strcmp(host, "[::1]") ||
- !strncmp(host, "[::1]:", 6));
+ !strcmp(con->clientname, "127.0.0.1") ||
+ !strcmp(con->clientname, "[::1]"));
}
#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
@@ -4023,19 +3915,18 @@ valid_host(cupsd_client_t *con) /* I - Client connection */
* Check if the hostname is something.local (Bonjour); if so, allow it.
*/
- if ((end = strrchr(host, '.')) != NULL && end > host &&
- (!end[1] || end[1] == ':'))
+ if ((end = strrchr(con->clientname, '.')) != NULL && end > con->clientname &&
+ !end[1])
{
/*
* "." on end, work back to second-to-last "."...
*/
- for (end --; end > host && *end != '.'; end --);
+
+ for (end --; end > con->clientname && *end != '.'; end --);
}
if (end && (!_cups_strcasecmp(end, ".local") ||
- !_cups_strncasecmp(end, ".local:", 7) ||
- !_cups_strcasecmp(end, ".local.") ||
- !_cups_strncasecmp(end, ".local.:", 8)))
+ !_cups_strcasecmp(end, ".local.")))
return (1);
#endif /* HAVE_DNSSD || HAVE_AVAHI */
@@ -4043,22 +3934,16 @@ valid_host(cupsd_client_t *con) /* I - Client connection */
* Check if the hostname is an IP address...
*/
- if (isdigit(*host & 255) || *host == '[')
+ if (isdigit(con->clientname[0] & 255) || con->clientname[0] == '[')
{
/*
* Possible IPv4/IPv6 address...
*/
- char temp[1024], /* Temporary string */
- *ptr; /* Pointer into temporary string */
http_addrlist_t *addrlist; /* List of addresses */
- strlcpy(temp, host, sizeof(temp));
- if ((ptr = strrchr(temp, ':')) != NULL && !strchr(ptr, ']'))
- *ptr = '\0'; /* Strip :port from host value */
-
- if ((addrlist = httpAddrGetList(temp, AF_UNSPEC, NULL)) != NULL)
+ if ((addrlist = httpAddrGetList(con->clientname, AF_UNSPEC, NULL)) != NULL)
{
/*
* Good IPv4/IPv6 address...
@@ -4084,16 +3969,15 @@ valid_host(cupsd_client_t *con) /* I - Client connection */
if (!strcmp(a->name, "*"))
return (1);
- if (!_cups_strncasecmp(host, a->name, a->namelen))
+ if (!_cups_strncasecmp(con->clientname, a->name, a->namelen))
{
/*
- * Prefix matches; check the character at the end - it must be ":", ".",
- * ".:", or nul...
+ * Prefix matches; check the character at the end - it must be "." or nul.
*/
- end = host + a->namelen;
+ end = con->clientname + a->namelen;
- if (!*end || *end == ':' || (*end == '.' && (!end[1] || end[1] == ':')))
+ if (!*end || (*end == '.' && !end[1]))
return (1);
}
}
@@ -4110,16 +3994,15 @@ valid_host(cupsd_client_t *con) /* I - Client connection */
if (!strcmp(a->name, "*"))
return (1);
- if (!_cups_strncasecmp(host, a->name, a->namelen))
+ if (!_cups_strncasecmp(con->clientname, a->name, a->namelen))
{
/*
- * Prefix matches; check the character at the end - it must be ":", ".",
- * ".:", or nul...
+ * Prefix matches; check the character at the end - it must be "." or nul.
*/
- end = host + a->namelen;
+ end = con->clientname + a->namelen;
- if (!*end || *end == ':' || (*end == '.' && (!end[1] || end[1] == ':')))
+ if (!*end || (*end == '.' && !end[1]))
return (1);
}
}
@@ -4133,16 +4016,15 @@ valid_host(cupsd_client_t *con) /* I - Client connection */
netif;
netif = (cupsd_netif_t *)cupsArrayNext(NetIFList))
{
- if (!_cups_strncasecmp(host, netif->hostname, netif->hostlen))
+ if (!_cups_strncasecmp(con->clientname, netif->hostname, netif->hostlen))
{
/*
- * Prefix matches; check the character at the end - it must be ":", ".",
- * ".:", or nul...
+ * Prefix matches; check the character at the end - it must be "." or nul.
*/
- end = host + netif->hostlen;
+ end = con->clientname + netif->hostlen;
- if (!*end || *end == ':' || (*end == '.' && (!end[1] || end[1] == ':')))
+ if (!*end || (*end == '.' && !end[1]))
return (1);
}
}
@@ -4164,43 +4046,29 @@ write_file(cupsd_client_t *con, /* I - Client connection */
{
con->file = open(filename, O_RDONLY);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] write_file code=%d, filename=\"%s\" (%d), "
- "type=\"%s\", filestats=%p", con->http.fd,
- code, filename, con->file, type ? type : "(null)", filestats);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "write_file: code=%d, filename=\"%s\" (%d), type=\"%s\", filestats=%p.", code, filename, con->file, type ? type : "(null)", filestats);
if (con->file < 0)
return (0);
fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
- con->pipe_pid = 0;
+ con->pipe_pid = 0;
+ con->sent_header = 1;
- if (!cupsdSendHeader(con, code, type, CUPSD_AUTH_NONE))
- return (0);
+ httpClearFields(con->http);
- if (httpPrintf(HTTP(con), "Last-Modified: %s\r\n",
- httpGetDateString(filestats->st_mtime)) < 0)
- return (0);
- if (httpPrintf(HTTP(con), "Content-Length: " CUPS_LLFMT "\r\n",
- CUPS_LLCAST filestats->st_size) < 0)
- return (0);
- if (httpPrintf(HTTP(con), "\r\n") < 0)
- return (0);
+ httpSetLength(con->http, (size_t)filestats->st_size);
- if (cupsdFlushHeader(con) < 0)
- return (0);
+ httpSetField(con->http, HTTP_FIELD_LAST_MODIFIED,
+ httpGetDateString(filestats->st_mtime));
- con->http.data_encoding = HTTP_ENCODE_LENGTH;
- con->http.data_remaining = filestats->st_size;
+ if (!cupsdSendHeader(con, code, type, CUPSD_AUTH_NONE))
+ return (0);
- if (con->http.data_remaining <= INT_MAX)
- con->http._data_remaining = con->http.data_remaining;
- else
- con->http._data_remaining = INT_MAX;
+ cupsdAddSelect(httpGetFd(con->http), NULL, (cupsd_selfunc_t)cupsdWriteClient, con);
- cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient,
- (cupsd_selfunc_t)cupsdWriteClient, con);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "Sending file.");
return (1);
}
@@ -4213,17 +4081,17 @@ write_file(cupsd_client_t *con, /* I - Client connection */
static void
write_pipe(cupsd_client_t *con) /* I - Client connection */
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "[Client %d] write_pipe CGI output on fd %d",
- con->http.fd, con->file);
+ cupsdLogClient(con, CUPSD_LOG_DEBUG2, "write_pipe: CGI output on fd %d.", con->file);
con->file_ready = 1;
cupsdRemoveSelect(con->file);
- cupsdAddSelect(con->http.fd, NULL, (cupsd_selfunc_t)cupsdWriteClient, con);
+ cupsdAddSelect(httpGetFd(con->http), NULL, (cupsd_selfunc_t)cupsdWriteClient, con);
+
+ cupsdLogClient(con, CUPSD_LOG_DEBUG, "CGI data ready to be sent.");
}
/*
- * End of "$Id: client.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: client.c 12978 2015-11-17 19:29:52Z msweet $".
*/
diff --git a/scheduler/client.h b/scheduler/client.h
index 106e43e..5096c4f 100644
--- a/scheduler/client.h
+++ b/scheduler/client.h
@@ -1,16 +1,16 @@
/*
- * "$Id: client.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: client.h 11717 2014-03-21 16:42:53Z msweet $"
*
- * Client definitions for the CUPS scheduler.
+ * Client definitions for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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/".
+ * 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/".
*/
#ifdef HAVE_AUTHORIZATION_H
@@ -24,7 +24,8 @@
struct cupsd_client_s
{
- http_t http; /* HTTP client connection */
+ int number; /* Connection number */
+ http_t *http; /* HTTP client connection */
ipp_t *request, /* IPP request information */
*response; /* IPP response information */
cupsd_location_t *best; /* Best match for AAA */
@@ -45,6 +46,7 @@ struct cupsd_client_s
int file; /* Input/output file */
int file_ready; /* Input ready on file/pipe? */
int pipe_pid; /* Pipe process ID (or 0 if not a pipe) */
+ http_status_t pipe_status; /* HTTP status from pipe process */
int sent_header, /* Non-zero if sent HTTP header */
got_fields, /* Non-zero if all fields seen */
header_used; /* Number of header bytes used */
@@ -53,7 +55,9 @@ struct cupsd_client_s
#ifdef HAVE_SSL
int auto_ssl; /* Automatic test for SSL/TLS */
#endif /* HAVE_SSL */
- http_addr_t clientaddr; /* Client address */
+ http_addr_t clientaddr; /* Client's server address */
+ char clientname[256];/* Client's server name for connection */
+ int clientport; /* Client's server port for connection */
char servername[256];/* Server name for connection */
int serverport; /* Server port for connection */
#ifdef HAVE_GSSAPI
@@ -65,7 +69,7 @@ struct cupsd_client_s
#endif /* HAVE_AUTHORIZATION_H */
};
-#define HTTP(con) &((con)->http)
+#define HTTP(con) ((con)->http)
/*
@@ -77,6 +81,9 @@ typedef struct
int fd; /* File descriptor for this server */
http_addr_t address; /* Bind address of socket */
http_encryption_t encryption; /* To encrypt or not to encrypt... */
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ int on_demand; /* Is this a socket from launchd/systemd? */
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
} cupsd_listener_t;
@@ -84,7 +91,9 @@ typedef struct
* Globals...
*/
-VAR int ListenBackLog VALUE(SOMAXCONN),
+VAR int LastClientNumber VALUE(0),
+ /* Last client connection number */
+ ListenBackLog VALUE(SOMAXCONN),
/* Max backlog of pending connections */
LocalPort VALUE(631),
/* Local port to use */
@@ -116,7 +125,6 @@ extern void cupsdAcceptClient(cupsd_listener_t *lis);
extern void cupsdCloseAllClients(void);
extern int cupsdCloseClient(cupsd_client_t *con);
extern void cupsdDeleteAllListeners(void);
-extern int cupsdFlushHeader(cupsd_client_t *con);
extern void cupsdPauseListening(void);
extern int cupsdProcessIPPRequest(cupsd_client_t *con);
extern void cupsdReadClient(cupsd_client_t *con);
@@ -140,5 +148,5 @@ extern int cupsdStartTLS(cupsd_client_t *con);
/*
- * End of "$Id: client.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: client.h 11717 2014-03-21 16:42:53Z msweet $".
*/
diff --git a/scheduler/colorman.c b/scheduler/colorman.c
index be064b6..0d90dde 100644
--- a/scheduler/colorman.c
+++ b/scheduler/colorman.c
@@ -1,22 +1,22 @@
/*
- * "$Id: colorman.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: colorman.c 12619 2015-05-06 21:00:19Z msweet $"
*
- * Color management routines for the CUPS scheduler.
+ * Color management routines for the CUPS scheduler.
*
- * Copyright 2007-2013 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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/".
+ * 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.
+ * 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:
+ * 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.
@@ -25,40 +25,18 @@
* 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.
+ * 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.
*/
/*
@@ -173,8 +151,11 @@ cupsdRegisterColor(cupsd_printer_t *p) /* I - Printer */
}
#elif defined(HAVE_DBUS)
- colord_unregister_printer(p);
- colord_register_printer(p);
+ if (!RunUser)
+ {
+ colord_unregister_printer(p);
+ colord_register_printer(p);
+ }
#endif /* __APPLE__ */
}
@@ -208,7 +189,8 @@ void
cupsdStopColor(void)
{
#if !defined(__APPLE__) && defined(HAVE_DBUS)
- dbus_connection_unref(colord_con);
+ if (colord_con)
+ dbus_connection_unref(colord_con);
colord_con = NULL;
#endif /* !__APPLE__ && HAVE_DBUS */
}
@@ -226,7 +208,8 @@ cupsdUnregisterColor(cupsd_printer_t *p)/* I - Printer */
apple_unregister_profiles(p);
#elif defined(HAVE_DBUS)
- colord_unregister_printer(p);
+ if (!RunUser)
+ colord_unregister_printer(p);
#endif /* __APPLE__ */
}
@@ -327,9 +310,7 @@ apple_init_profile(
if (iccfile && *iccfile)
{
- url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
- (const UInt8 *)iccfile,
- strlen(iccfile), false);
+ url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)iccfile, (CFIndex)strlen(iccfile), false);
if (url)
{
@@ -387,7 +368,7 @@ apple_register_profiles(
* Make sure ColorSync is available...
*/
- if (ColorSyncRegisterDevice == NULL)
+ if (&ColorSyncRegisterDevice == NULL)
return;
/*
@@ -887,7 +868,7 @@ apple_unregister_profiles(
* Make sure ColorSync is available...
*/
- if (ColorSyncUnregisterDevice != NULL)
+ if (&ColorSyncUnregisterDevice != NULL)
{
CFUUIDRef deviceUUID; /* Device UUID */
@@ -1538,5 +1519,5 @@ colord_unregister_printer(
/*
- * End of "$Id: colorman.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: colorman.c 12619 2015-05-06 21:00:19Z msweet $".
*/
diff --git a/scheduler/colorman.h b/scheduler/colorman.h
index a95adcf..3360fd4 100644
--- a/scheduler/colorman.h
+++ b/scheduler/colorman.h
@@ -1,5 +1,5 @@
/*
- * "$Id: colorman.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: colorman.h 3833 2012-05-23 22:51:18Z msweet $"
*
* Color management definitions for the CUPS scheduler.
*
@@ -24,5 +24,5 @@ extern void cupsdUnregisterColor(cupsd_printer_t *p);
/*
- * End of "$Id: colorman.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: colorman.h 3833 2012-05-23 22:51:18Z msweet $".
*/
diff --git a/scheduler/conf.c b/scheduler/conf.c
index 7ae8fed..f3e6514 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -1,39 +1,16 @@
/*
- * "$Id: conf.c 11221 2013-08-06 16:16:01Z msweet $"
+ * "$Id: conf.c 12819 2015-07-31 13:52:00Z msweet $"
*
- * Configuration routines for the CUPS scheduler.
+ * Configuration routines for the CUPS scheduler.
*
- * Copyright 2007-2013 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 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:
- *
- * cupsdAddAlias() - Add a host alias.
- * cupsdCheckPermissions() - Fix the mode and ownership of a file or
- * 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_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.
- * 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.
- * 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.
+ * 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/".
*/
/*
@@ -44,6 +21,12 @@
#include <stdarg.h>
#include <grp.h>
#include <sys/utsname.h>
+#ifdef HAVE_ASL_H
+# include <asl.h>
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+# define SD_JOURNAL_SUPPRESS_LOCATION
+# include <systemd/sd-journal.h>
+#endif /* HAVE_ASL_H */
#include <syslog.h>
#ifdef HAVE_LIBPAPER
@@ -70,7 +53,8 @@ typedef enum
CUPSD_VARTYPE_TIME, /* Time interval option */
CUPSD_VARTYPE_STRING, /* String option */
CUPSD_VARTYPE_BOOLEAN, /* Boolean option */
- CUPSD_VARTYPE_PATHNAME /* File/directory name option */
+ CUPSD_VARTYPE_PATHNAME, /* File/directory name option */
+ CUPSD_VARTYPE_PERM /* File/directory permissions */
} cupsd_vartype_t;
typedef struct
@@ -107,13 +91,16 @@ static const cupsd_var_t cupsd_vars[] =
#ifdef HAVE_GSSAPI
{ "GSSServiceName", &GSSServiceName, CUPSD_VARTYPE_STRING },
#endif /* HAVE_GSSAPI */
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ { "IdleExitTimeout", &IdleExitTimeout, CUPSD_VARTYPE_TIME },
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
{ "JobKillDelay", &JobKillDelay, CUPSD_VARTYPE_TIME },
{ "JobRetryLimit", &JobRetryLimit, 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_TIME },
+ { "LaunchdTimeout", &IdleExitTimeout, CUPSD_VARTYPE_TIME },
#endif /* HAVE_LAUNCHD */
{ "LimitRequestBody", &MaxRequestSize, CUPSD_VARTYPE_INTEGER },
{ "ListenBackLog", &ListenBackLog, CUPSD_VARTYPE_INTEGER },
@@ -127,7 +114,7 @@ static const cupsd_var_t cupsd_vars[] =
{ "MaxJobs", &MaxJobs, CUPSD_VARTYPE_INTEGER },
{ "MaxJobsPerPrinter", &MaxJobsPerPrinter, CUPSD_VARTYPE_INTEGER },
{ "MaxJobsPerUser", &MaxJobsPerUser, CUPSD_VARTYPE_INTEGER },
- { "MaxJobTime", &MaxJobTime, CUPSD_VARTYPE_INTEGER },
+ { "MaxJobTime", &MaxJobTime, CUPSD_VARTYPE_TIME },
{ "MaxLeaseDuration", &MaxLeaseDuration, CUPSD_VARTYPE_TIME },
{ "MaxLogSize", &MaxLogSize, CUPSD_VARTYPE_INTEGER },
{ "MaxRequestSize", &MaxRequestSize, CUPSD_VARTYPE_INTEGER },
@@ -152,13 +139,13 @@ static const cupsd_var_t cupsfiles_vars[] =
{
{ "AccessLog", &AccessLog, CUPSD_VARTYPE_STRING },
{ "CacheDir", &CacheDir, CUPSD_VARTYPE_STRING },
- { "ConfigFilePerm", &ConfigFilePerm, CUPSD_VARTYPE_INTEGER },
+ { "ConfigFilePerm", &ConfigFilePerm, CUPSD_VARTYPE_PERM },
{ "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 },
+ { "LogFilePerm", &LogFilePerm, CUPSD_VARTYPE_PERM },
{ "LPDConfigFile", &LPDConfigFile, CUPSD_VARTYPE_STRING },
{ "PageLog", &PageLog, CUPSD_VARTYPE_STRING },
{ "Printcap", &Printcap, CUPSD_VARTYPE_STRING },
@@ -166,10 +153,7 @@ static const cupsd_var_t cupsfiles_vars[] =
{ "RequestRoot", &RequestRoot, CUPSD_VARTYPE_STRING },
{ "ServerBin", &ServerBin, CUPSD_VARTYPE_PATHNAME },
#ifdef HAVE_SSL
- { "ServerCertificate", &ServerCertificate, CUPSD_VARTYPE_PATHNAME },
-# if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
- { "ServerKey", &ServerKey, CUPSD_VARTYPE_PATHNAME },
-# endif /* HAVE_LIBSSL || HAVE_GNUTLS */
+ { "ServerKeychain", &ServerKeychain, CUPSD_VARTYPE_PATHNAME },
#endif /* HAVE_SSL */
{ "ServerRoot", &ServerRoot, CUPSD_VARTYPE_PATHNAME },
{ "SMBConfigFile", &SMBConfigFile, CUPSD_VARTYPE_STRING },
@@ -236,7 +220,7 @@ cupsdAddAlias(cups_array_t *aliases, /* I - Array of aliases */
return;
a->namelen = namelen;
- strcpy(a->name, name); /* OK since a->name is allocated */
+ memcpy(a->name, name, namelen + 1); /* OK since a->name is allocated */
cupsArrayAdd(aliases, a);
}
@@ -250,9 +234,9 @@ int /* O - 0 on success, -1 on error, 1 on warning */
cupsdCheckPermissions(
const char *filename, /* I - File/directory name */
const char *suffix, /* I - Additional file/directory name */
- int mode, /* I - Permissions */
- int user, /* I - Owner */
- int group, /* I - Group */
+ mode_t mode, /* I - Permissions */
+ uid_t user, /* I - Owner */
+ gid_t group, /* I - Group */
int is_dir, /* I - 1 = directory, 0 = file */
int create_dir) /* I - 1 = create directory, -1 = create w/o logging, 0 = not */
{
@@ -291,8 +275,20 @@ cupsdCheckPermissions(
"Unable to create directory \"%s\" - %s", filename,
strerror(errno));
else
- syslog(LOG_ERR, "Unable to create directory \"%s\" - %s", filename,
- strerror(errno));
+#ifdef HAVE_ASL_H
+ {
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to create directory \"%s\" - %s", filename, strerror(errno));
+ asl_release(m);
+ }
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "Unable to create directory \"%s\" - %s", filename, strerror(errno));
+#else
+ syslog(LOG_ERR, "Unable to create directory \"%s\" - %s", filename, strerror(errno));
+#endif /* HAVE_ASL_H */
return (-1);
}
@@ -329,7 +325,20 @@ cupsdCheckPermissions(
if (create_dir >= 0)
cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a directory.", filename);
else
+#ifdef HAVE_ASL_H
+ {
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "\"%s\" is not a directory.", filename);
+ asl_release(m);
+ }
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "\"%s\" is not a directory.", filename);
+#else
syslog(LOG_ERR, "\"%s\" is not a directory.", filename);
+#endif /* HAVE_ASL_H */
return (-1);
}
@@ -358,8 +367,20 @@ cupsdCheckPermissions(
"Unable to change ownership of \"%s\" - %s", filename,
strerror(errno));
else
- syslog(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename,
- strerror(errno));
+#ifdef HAVE_ASL_H
+ {
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to change ownership of \"%s\" - %s", filename, strerror(errno));
+ asl_release(m);
+ }
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename, strerror(errno));
+#else
+ syslog(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename, strerror(errno));
+#endif /* HAVE_ASL_H */
return (1);
}
@@ -378,8 +399,20 @@ cupsdCheckPermissions(
"Unable to change permissions of \"%s\" - %s", filename,
strerror(errno));
else
- syslog(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename,
- strerror(errno));
+#ifdef HAVE_ASL_H
+ {
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to change permissions of \"%s\" - %s", filename, strerror(errno));
+ asl_release(m);
+ }
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename, strerror(errno));
+#else
+ syslog(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename, strerror(errno));
+#endif /* HAVE_ASL_H */
return (1);
}
@@ -429,7 +462,7 @@ cupsdDefaultAuthType(void)
* to use it...
*/
- if (gss_init_sec_context == NULL)
+ if (&gss_init_sec_context == NULL)
return (default_auth_type = CUPSD_AUTH_BASIC);
# endif /* __APPLE__ */
@@ -589,7 +622,6 @@ cupsdReadConfiguration(void)
"%p %u %j %T %P %C %{job-billing} "
"%{job-originating-host-name} %{job-name} %{media} %{sides}");
cupsdSetString(&Printcap, CUPS_DEFAULT_PRINTCAP);
- cupsdSetString(&PrintcapGUI, "/usr/bin/glpoptions");
cupsdSetString(&FontPath, CUPS_FONTPATH);
cupsdSetString(&RemoteRoot, "remroot");
cupsdSetStringf(&ServerHeader, "CUPS/%d.%d IPP/2.1", CUPS_VERSION_MAJOR,
@@ -614,12 +646,13 @@ cupsdReadConfiguration(void)
ClassifyOverride = 0;
#ifdef HAVE_SSL
-# ifdef HAVE_CDSASSL
- cupsdSetString(&ServerCertificate, "/Library/Keychains/System.keychain");
+# ifdef HAVE_GNUTLS
+ cupsdSetString(&ServerKeychain, "ssl");
# else
- cupsdSetString(&ServerCertificate, "ssl/server.crt");
- cupsdSetString(&ServerKey, "ssl/server.key");
-# endif /* HAVE_CDSASSL */
+ cupsdSetString(&ServerKeychain, "/Library/Keychains/System.keychain");
+# endif /* HAVE_GNUTLS */
+
+ _httpTLSSetOptions(0);
#endif /* HAVE_SSL */
language = cupsLangDefault();
@@ -709,7 +742,6 @@ cupsdReadConfiguration(void)
default_auth_type = CUPSD_AUTH_BASIC;
#ifdef HAVE_SSL
DefaultEncryption = HTTP_ENCRYPT_REQUIRED;
- SSLOptions = CUPSD_SSL_NONE;
#endif /* HAVE_SSL */
DirtyCleanInterval = DEFAULT_KEEPALIVE;
JobKillDelay = DEFAULT_TIMEOUT;
@@ -735,6 +767,7 @@ cupsdReadConfiguration(void)
NumSystemGroups = 0;
ReloadTimeout = DEFAULT_KEEPALIVE;
RootCertDuration = 300;
+ Sandboxing = CUPSD_SANDBOXING_STRICT;
StrictConformance = FALSE;
SyncOnClose = FALSE;
Timeout = DEFAULT_TIMEOUT;
@@ -779,9 +812,9 @@ cupsdReadConfiguration(void)
DefaultLeaseDuration = 86400;
MaxLeaseDuration = 0;
-#ifdef HAVE_LAUNCHD
- LaunchdTimeout = 10;
-#endif /* HAVE_LAUNCHD */
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ IdleExitTimeout = 60;
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
/*
* Setup environment variables...
@@ -804,8 +837,20 @@ cupsdReadConfiguration(void)
if (TestConfigFile)
printf("\"%s\" contains errors.\n", CupsFilesFile);
else
- syslog(LOG_LPR, "Unable to read \"%s\" due to errors.",
- CupsFilesFile);
+#ifdef HAVE_ASL_H
+ {
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to read \"%s\" due to errors.", CupsFilesFile);
+ asl_release(m);
+ }
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "Unable to read \"%s\" due to errors.", CupsFilesFile);
+#else
+ syslog(LOG_LPR, "Unable to read \"%s\" due to errors.", CupsFilesFile);
+#endif /* HAVE_ASL_H */
return (0);
}
@@ -814,8 +859,20 @@ cupsdReadConfiguration(void)
cupsdLogMessage(CUPSD_LOG_INFO, "No %s, using defaults.", CupsFilesFile);
else
{
- syslog(LOG_LPR, "Unable to open \"%s\": %s", CupsFilesFile,
- strerror(errno));
+#ifdef HAVE_ASL_H
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno));
+ asl_release(m);
+
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno));
+#else
+ syslog(LOG_LPR, "Unable to open \"%s\" - %s", CupsFilesFile, strerror(errno));
+#endif /* HAVE_ASL_H */
+
return (0);
}
@@ -828,8 +885,19 @@ cupsdReadConfiguration(void)
if ((fp = cupsFileOpen(ConfigurationFile, "r")) == NULL)
{
- syslog(LOG_LPR, "Unable to open \"%s\": %s", ConfigurationFile,
- strerror(errno));
+#ifdef HAVE_ASL_H
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to open \"%s\" - %s", ConfigurationFile, strerror(errno));
+ asl_release(m);
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "Unable to open \"%s\" - %s", ConfigurationFile, strerror(errno));
+#else
+ syslog(LOG_LPR, "Unable to open \"%s\" - %s", ConfigurationFile, strerror(errno));
+#endif /* HAVE_ASL_H */
+
return (0);
}
@@ -842,8 +910,20 @@ cupsdReadConfiguration(void)
if (TestConfigFile)
printf("\"%s\" contains errors.\n", ConfigurationFile);
else
- syslog(LOG_LPR, "Unable to read \"%s\" due to errors.",
- ConfigurationFile);
+#ifdef HAVE_ASL_H
+ {
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to read \"%s\" due to errors.", ConfigurationFile);
+ asl_release(m);
+ }
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "Unable to read \"%s\" due to errors.", ConfigurationFile);
+#else
+ syslog(LOG_LPR, "Unable to read \"%s\" due to errors.", ConfigurationFile);
+#endif /* HAVE_ASL_H */
return (0);
}
@@ -970,12 +1050,24 @@ cupsdReadConfiguration(void)
* Open the system log for cupsd if necessary...
*/
-#ifdef HAVE_VSYSLOG
+ if (!LogStderr)
+ {
+ if (!strcmp(AccessLog, "stderr"))
+ cupsdSetString(&AccessLog, "syslog");
+
+ if (!strcmp(ErrorLog, "stderr"))
+ cupsdSetString(&ErrorLog, "syslog");
+
+ if (!strcmp(PageLog, "stderr"))
+ cupsdSetString(&PageLog, "syslog");
+ }
+
+#if defined(HAVE_VSYSLOG) && !defined(HAVE_ASL_H) && !defined(HAVE_SYSTEMD_SD_JOURNAL_H)
if (!strcmp(AccessLog, "syslog") ||
!strcmp(ErrorLog, "syslog") ||
!strcmp(PageLog, "syslog"))
openlog("cupsd", LOG_PID | LOG_NOWAIT | LOG_NDELAY, LOG_LPR);
-#endif /* HAVE_VSYSLOG */
+#endif /* HAVE_VSYSLOG && !HAVE_ASL_H && !HAVE_SYSTEMD_SD_JOURNAL_H */
/*
* Make sure each of the log files exists and gets rotated as necessary...
@@ -1015,8 +1107,11 @@ cupsdReadConfiguration(void)
* Log the error and reset the group to a safe value...
*/
- cupsdLogMessage(CUPSD_LOG_NOTICE,
+ cupsdLogMessage(CUPSD_LOG_ERROR,
"Group and SystemGroup cannot use the same groups.");
+ if (FatalErrors & (CUPSD_FATAL_CONFIG | CUPSD_FATAL_PERMISSIONS))
+ return (0);
+
cupsdLogMessage(CUPSD_LOG_INFO, "Resetting Group to \"nobody\"...");
group = getgrnam("nobody");
@@ -1084,24 +1179,11 @@ cupsdReadConfiguration(void)
cupsdSetStringf(&CacheDir, "%s/%s", ServerRoot, CacheDir);
#ifdef HAVE_SSL
- if (ServerCertificate[0] != '/')
- cupsdSetStringf(&ServerCertificate, "%s/%s", ServerRoot, ServerCertificate);
-
- if (!strncmp(ServerRoot, ServerCertificate, strlen(ServerRoot)) &&
- cupsdCheckPermissions(ServerCertificate, NULL, 0600, RunUser, Group,
- 0, 0) < 0 &&
- (FatalErrors & CUPSD_FATAL_PERMISSIONS))
- return (0);
+ if (ServerKeychain[0] != '/')
+ cupsdSetStringf(&ServerKeychain, "%s/%s", ServerRoot, ServerKeychain);
-# if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
- if (ServerKey[0] != '/')
- cupsdSetStringf(&ServerKey, "%s/%s", ServerRoot, ServerKey);
-
- if (!strncmp(ServerRoot, ServerKey, strlen(ServerRoot)) &&
- cupsdCheckPermissions(ServerKey, NULL, 0600, RunUser, Group, 0, 0) < 0 &&
- (FatalErrors & CUPSD_FATAL_PERMISSIONS))
- return (0);
-# endif /* HAVE_LIBSSL || HAVE_GNUTLS */
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Using keychain \"%s\" for server name \"%s\".", ServerKeychain, ServerName);
+ cupsSetServerCredentials(ServerKeychain, ServerName, 1);
#endif /* HAVE_SSL */
/*
@@ -1113,7 +1195,7 @@ cupsdReadConfiguration(void)
if ((cupsdCheckPermissions(RequestRoot, NULL, 0710, RunUser,
Group, 1, 1) < 0 ||
- cupsdCheckPermissions(CacheDir, NULL, 0775, RunUser,
+ cupsdCheckPermissions(CacheDir, NULL, 0770, RunUser,
Group, 1, 1) < 0 ||
cupsdCheckPermissions(temp, NULL, 0775, RunUser,
Group, 1, 1) < 0 ||
@@ -1189,6 +1271,8 @@ cupsdReadConfiguration(void)
cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot);
}
+ setenv("TMPDIR", TempDir, 1);
+
/*
* Make sure the temporary directory has the right permissions...
*/
@@ -1212,6 +1296,19 @@ cupsdReadConfiguration(void)
cupsdUpdateEnv();
+ /*
+ * Validate the default error policy...
+ */
+
+ if (strcmp(ErrorPolicy, "retry-current-job") &&
+ strcmp(ErrorPolicy, "abort-job") &&
+ strcmp(ErrorPolicy, "retry-job") &&
+ strcmp(ErrorPolicy, "stop-printer"))
+ {
+ cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid ErrorPolicy \"%s\", resetting to \"stop-printer\".", ErrorPolicy);
+ cupsdSetString(&ErrorPolicy, "stop-printer");
+ }
+
/*
* Update default paper size setting as needed...
*/
@@ -1334,6 +1431,7 @@ cupsdReadConfiguration(void)
cupsdAddString(&(p->job_attrs), "job-name");
cupsdAddString(&(p->job_attrs), "job-originating-host-name");
cupsdAddString(&(p->job_attrs), "job-originating-user-name");
+ cupsdAddString(&(p->job_attrs), "phone");
cupsdLogMessage(CUPSD_LOG_INFO, "SubscriptionPrivateAccess default");
cupsdAddString(&(p->sub_access), "@OWNER");
@@ -1542,7 +1640,7 @@ cupsdReadConfiguration(void)
if (!mimeType(MimeDatabase, "application", "octet-stream"))
NumMimeTypes ++;
- if ((MimeTypes = calloc(NumMimeTypes, sizeof(const char *))) == NULL)
+ if ((MimeTypes = calloc((size_t)NumMimeTypes, sizeof(const char *))) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"Unable to allocate memory for %d MIME types.",
@@ -1816,7 +1914,8 @@ get_addr_and_mask(const char *value, /* I - String from config file */
* Merge everything into a 32-bit IPv4 address in ip[3]...
*/
- ip[3] = (((((val[0] << 8) | val[1]) << 8) | val[2]) << 8) | val[3];
+ ip[3] = ((((((unsigned)val[0] << 8) | (unsigned)val[1]) << 8) |
+ (unsigned)val[2]) << 8) | (unsigned)val[3];
if (ipcount < 4)
mask[3] = (0xffffffff << (32 - 8 * ipcount)) & 0xffffffff;
@@ -1884,7 +1983,8 @@ get_addr_and_mask(const char *value, /* I - String from config file */
* Merge everything into a 32-bit IPv4 address in ip[3]...
*/
- ip[3] = (((((val[0] << 8) | val[1]) << 8) | val[2]) << 8) | val[3];
+ ip[3] = ((((((unsigned)val[0] << 8) | (unsigned)val[1]) << 8) |
+ (unsigned)val[2]) << 8) | (unsigned)val[3];
if (ipcount < 4)
mask[3] = (0xffffffff << (32 - 8 * ipcount)) & 0xffffffff;
@@ -1911,7 +2011,8 @@ get_addr_and_mask(const char *value, /* I - String from config file */
mask + 3) != 4)
return (0);
- mask[3] |= ((((mask[0] << 8) | mask[1]) << 8) | mask[2]) << 8;
+ mask[3] |= (((((unsigned)mask[0] << 8) | (unsigned)mask[1]) << 8) |
+ (unsigned)mask[2]) << 8;
mask[0] = mask[1] = mask[2] = 0;
}
else
@@ -2034,8 +2135,8 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
else if (!_cups_strcasecmp(value, "always"))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Encryption value \"%s\" on line %d is invalid in this "
- "context. Using \"required\" instead.", value, linenum);
+ "Encryption value \"%s\" on line %d of %s is invalid in this "
+ "context. Using \"required\" instead.", value, linenum, ConfigurationFile);
loc->encryption = HTTP_ENCRYPT_REQUIRED;
}
@@ -2046,7 +2147,7 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
else
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown Encryption value %s on line %d.", value, linenum);
+ "Unknown Encryption value %s on line %d of %s.", value, linenum, ConfigurationFile);
return (0);
}
}
@@ -2062,8 +2163,8 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
loc->order_type = CUPSD_AUTH_DENY;
else
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown Order value %s on line %d.",
- value, linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown Order value %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
return (0);
}
}
@@ -2165,8 +2266,8 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
if (!get_addr_and_mask(value, ip, mask))
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.",
- value, linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
return (0);
}
@@ -2201,20 +2302,6 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
if (loc->level == CUPSD_AUTH_ANON)
loc->level = CUPSD_AUTH_USER;
}
- else if (!_cups_strcasecmp(value, "digest"))
- {
- loc->type = CUPSD_AUTH_DIGEST;
-
- if (loc->level == CUPSD_AUTH_ANON)
- loc->level = CUPSD_AUTH_USER;
- }
- else if (!_cups_strcasecmp(value, "basicdigest"))
- {
- loc->type = CUPSD_AUTH_BASICDIGEST;
-
- if (loc->level == CUPSD_AUTH_ANON)
- loc->level = CUPSD_AUTH_USER;
- }
else if (!_cups_strcasecmp(value, "default"))
{
loc->type = CUPSD_AUTH_DEFAULT;
@@ -2234,8 +2321,8 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
else
{
cupsdLogMessage(CUPSD_LOG_WARN,
- "Unknown authorization type %s on line %d.",
- value, linenum);
+ "Unknown authorization type %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
return (0);
}
}
@@ -2261,8 +2348,8 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
cupsdLogMessage(CUPSD_LOG_WARN,
"\"AuthClass %s\" is deprecated; consider using "
- "\"Require valid-user\" on line %d.",
- value, linenum);
+ "\"Require valid-user\" on line %d of %s.",
+ value, linenum, ConfigurationFile);
}
else if (!_cups_strcasecmp(value, "group"))
{
@@ -2270,8 +2357,8 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
cupsdLogMessage(CUPSD_LOG_WARN,
"\"AuthClass %s\" is deprecated; consider using "
- "\"Require user @groupname\" on line %d.",
- value, linenum);
+ "\"Require user @groupname\" on line %d of %s.",
+ value, linenum, ConfigurationFile);
}
else if (!_cups_strcasecmp(value, "system"))
{
@@ -2281,14 +2368,14 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
cupsdLogMessage(CUPSD_LOG_WARN,
"\"AuthClass %s\" is deprecated; consider using "
- "\"Require user @SYSTEM\" on line %d.",
- value, linenum);
+ "\"Require user @SYSTEM\" on line %d of %s.",
+ value, linenum, ConfigurationFile);
}
else
{
cupsdLogMessage(CUPSD_LOG_WARN,
- "Unknown authorization class %s on line %d.",
- value, linenum);
+ "Unknown authorization class %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
return (0);
}
}
@@ -2298,8 +2385,8 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
cupsdLogMessage(CUPSD_LOG_WARN,
"\"AuthGroupName %s\" directive is deprecated; consider "
- "using \"Require user @%s\" on line %d.",
- value, value, linenum);
+ "using \"Require user @%s\" on line %d of %s.",
+ value, value, linenum, ConfigurationFile);
}
else if (!_cups_strcasecmp(line, "Require"))
{
@@ -2325,8 +2412,8 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
loc->level = CUPSD_AUTH_GROUP;
else
{
- cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Require type %s on line %d.",
- value, linenum);
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Require type %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
return (0);
}
@@ -2388,8 +2475,8 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */
loc->satisfy = CUPSD_AUTH_SATISFY_ANY;
else
{
- cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Satisfy value %s on line %d.",
- value, linenum);
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Satisfy value %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
return (0);
}
}
@@ -2714,6 +2801,41 @@ parse_variable(
}
break;
+ case CUPSD_VARTYPE_PERM :
+ if (!value)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Missing permissions value for %s on line %d of %s.",
+ line, linenum, filename);
+ return (0);
+ }
+ else if (!isdigit(*value & 255))
+ {
+ /* TODO: Add chmod UGO syntax support */
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Bad permissions value for %s on line %d of %s.",
+ line, linenum, filename);
+ return (0);
+ }
+ else
+ {
+ int n = strtol(value, NULL, 8);
+ /* Permissions value */
+
+ if (n < 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Bad negative permissions value for %s on line %d of "
+ "%s.", line, linenum, filename);
+ return (0);
+ }
+ else
+ {
+ *((mode_t *)var->ptr) = (mode_t)n;
+ }
+ }
+ break;
+
case CUPSD_VARTYPE_TIME :
if (!value)
{
@@ -2930,15 +3052,60 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
JobRetryInterval = atoi(value);
cupsdLogMessage(CUPSD_LOG_WARN,
"FaxRetryInterval is deprecated; use "
- "JobRetryInterval on line %d.", linenum);
+ "JobRetryInterval on line %d of %s.", linenum, ConfigurationFile);
}
else if (!_cups_strcasecmp(line, "FaxRetryLimit") && value)
{
JobRetryLimit = atoi(value);
cupsdLogMessage(CUPSD_LOG_WARN,
"FaxRetryLimit is deprecated; use "
- "JobRetryLimit on line %d.", linenum);
+ "JobRetryLimit on line %d of %s.", linenum, ConfigurationFile);
}
+#ifdef HAVE_SSL
+ else if (!_cups_strcasecmp(line, "SSLOptions"))
+ {
+ /*
+ * SSLOptions [AllowRC4] [AllowSSL3] [None]
+ */
+
+ int options = 0; /* SSL/TLS options */
+
+ if (value)
+ {
+ char *start, /* Start of option */
+ *end; /* End of option */
+
+ for (start = value; *start; start = end)
+ {
+ /*
+ * Find end of keyword...
+ */
+
+ end = start;
+ while (*end && !_cups_isspace(*end))
+ end ++;
+
+ if (*end)
+ *end++ = '\0';
+
+ /*
+ * Compare...
+ */
+
+ if (!_cups_strcasecmp(start, "AllowRC4"))
+ options |= _HTTP_TLS_ALLOW_RC4;
+ else if (!_cups_strcasecmp(start, "AllowSSL3"))
+ options |= _HTTP_TLS_ALLOW_SSL3;
+ else if (!_cups_strcasecmp(start, "None"))
+ options = 0;
+ else if (_cups_strcasecmp(start, "NoEmptyFragments"))
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown SSL option %s at line %d.", start, linenum);
+ }
+ }
+
+ _httpTLSSetOptions(options);
+ }
+#endif /* HAVE_SSL */
else if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")
#ifdef HAVE_SSL
|| !_cups_strcasecmp(line, "SSLPort") || !_cups_strcasecmp(line, "SSLListen")
@@ -2979,14 +3146,20 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
lis;
lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
if (httpAddrEqual(&(addr->addr), &(lis->address)) &&
- _httpAddrPort(&(addr->addr)) == _httpAddrPort(&(lis->address)))
+ httpAddrPort(&(addr->addr)) == httpAddrPort(&(lis->address)))
break;
if (lis)
{
- httpAddrString(&lis->address, temp, sizeof(temp));
- cupsdLogMessage(CUPSD_LOG_WARN,
- "Duplicate listen address \"%s\" ignored.", temp);
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ if (!lis->on_demand)
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
+ {
+ httpAddrString(&lis->address, temp, sizeof(temp));
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "Duplicate listen address \"%s\" ignored.", temp);
+ }
+
continue;
}
@@ -3035,11 +3208,11 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
else
#endif /* AF_LOCAL */
cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv%d)", temp,
- _httpAddrPort(&(lis->address)),
- _httpAddrFamily(&(lis->address)) == AF_INET ? 4 : 6);
+ httpAddrPort(&(lis->address)),
+ httpAddrFamily(&(lis->address)) == AF_INET ? 4 : 6);
if (!httpAddrLocalhost(&(lis->address)))
- RemotePort = _httpAddrPort(&(lis->address));
+ RemotePort = httpAddrPort(&(lis->address));
}
/*
@@ -3061,8 +3234,8 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
if (protocols < 0)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown browse protocol \"%s\" on line %d.",
- value, linenum);
+ "Unknown browse protocol \"%s\" on line %d of %s.",
+ value, linenum, ConfigurationFile);
break;
}
@@ -3078,10 +3251,6 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
default_auth_type = CUPSD_AUTH_NONE;
else if (!_cups_strcasecmp(value, "basic"))
default_auth_type = CUPSD_AUTH_BASIC;
- else if (!_cups_strcasecmp(value, "digest"))
- default_auth_type = CUPSD_AUTH_DIGEST;
- else if (!_cups_strcasecmp(value, "basicdigest"))
- default_auth_type = CUPSD_AUTH_BASICDIGEST;
#ifdef HAVE_GSSAPI
else if (!_cups_strcasecmp(value, "negotiate"))
default_auth_type = CUPSD_AUTH_NEGOTIATE;
@@ -3091,8 +3260,8 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
else
{
cupsdLogMessage(CUPSD_LOG_WARN,
- "Unknown default authorization type %s on line %d.",
- value, linenum);
+ "Unknown default authorization type %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
if (FatalErrors & CUPSD_FATAL_CONFIG)
return (0);
}
@@ -3113,8 +3282,8 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
else
{
cupsdLogMessage(CUPSD_LOG_WARN,
- "Unknown default encryption %s on line %d.",
- value, linenum);
+ "Unknown default encryption %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
if (FatalErrors & CUPSD_FATAL_CONFIG)
return (0);
}
@@ -3135,8 +3304,8 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
else if (!_cups_strcasecmp(value, "double"))
HostNameLookups = 2;
else
- cupsdLogMessage(CUPSD_LOG_WARN, "Unknown HostNameLookups %s on line %d.",
- value, linenum);
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown HostNameLookups %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
}
else if (!_cups_strcasecmp(line, "AccessLogLevel") && value)
{
@@ -3150,9 +3319,11 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
AccessLogLevel = CUPSD_ACCESSLOG_ACTIONS;
else if (!_cups_strcasecmp(value, "config"))
AccessLogLevel = CUPSD_ACCESSLOG_CONFIG;
+ else if (!_cups_strcasecmp(value, "none"))
+ AccessLogLevel = CUPSD_ACCESSLOG_NONE;
else
- cupsdLogMessage(CUPSD_LOG_WARN, "Unknown AccessLogLevel %s on line %d.",
- value, linenum);
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown AccessLogLevel %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
}
else if (!_cups_strcasecmp(line, "LogLevel") && value)
{
@@ -3181,8 +3352,8 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
else if (!_cups_strcasecmp(value, "none"))
LogLevel = CUPSD_LOG_NONE;
else
- cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogLevel %s on line %d.",
- value, linenum);
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogLevel %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
}
else if (!_cups_strcasecmp(line, "LogTimeFormat") && value)
{
@@ -3195,8 +3366,8 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
else if (!_cups_strcasecmp(value, "usecs"))
LogTimeFormat = CUPSD_TIME_USECS;
else
- cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogTimeFormat %s on line %d.",
- value, linenum);
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogTimeFormat %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
}
else if (!_cups_strcasecmp(line, "ServerTokens") && value)
{
@@ -3227,8 +3398,8 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
else if (!_cups_strcasecmp(value, "None"))
cupsdClearString(&ServerHeader);
else
- cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d.",
- value, linenum);
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
}
else if (!_cups_strcasecmp(line, "PassEnv") && value)
{
@@ -3304,26 +3475,9 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
}
else
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Missing value for SetEnv directive on line %d.",
- linenum);
+ "Missing value for SetEnv directive on line %d of %s.",
+ linenum, ConfigurationFile);
}
-#ifdef HAVE_SSL
- else if (!_cups_strcasecmp(line, "SSLOptions"))
- {
- /*
- * SSLOptions options
- */
-
- if (!value || !_cups_strcasecmp(value, "none"))
- SSLOptions = CUPSD_SSL_NONE;
- else if (!_cups_strcasecmp(value, "noemptyfragments"))
- SSLOptions = CUPSD_SSL_NOEMPTY;
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown value \"%s\" for SSLOptions directive on "
- "line %d.", value, linenum);
- }
-#endif /* HAVE_SSL */
else if (!_cups_strcasecmp(line, "AccessLog") ||
!_cups_strcasecmp(line, "CacheDir") ||
!_cups_strcasecmp(line, "ConfigFilePerm") ||
@@ -3344,6 +3498,7 @@ read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
!_cups_strcasecmp(line, "ServerBin") ||
!_cups_strcasecmp(line, "ServerCertificate") ||
!_cups_strcasecmp(line, "ServerKey") ||
+ !_cups_strcasecmp(line, "ServerKeychain") ||
!_cups_strcasecmp(line, "ServerRoot") ||
!_cups_strcasecmp(line, "SMBConfigFile") ||
!_cups_strcasecmp(line, "StateDir") ||
@@ -3397,7 +3552,7 @@ read_cups_files_conf(cups_file_t *fp) /* I - File to read from */
*/
if (isdigit(value[0]))
- Group = atoi(value);
+ Group = (gid_t)atoi(value);
else
{
endgrent();
@@ -3436,6 +3591,30 @@ read_cups_files_conf(cups_file_t *fp) /* I - File to read from */
return (0);
}
}
+ else if (!_cups_strcasecmp(line, "Sandboxing") && value)
+ {
+ /*
+ * Level of sandboxing?
+ */
+
+ if (!_cups_strcasecmp(value, "off") && getuid())
+ {
+ Sandboxing = CUPSD_SANDBOXING_OFF;
+ cupsdLogMessage(CUPSD_LOG_WARN, "Disabling sandboxing is not recommended (line %d of %s)", linenum, CupsFilesFile);
+ }
+ else if (!_cups_strcasecmp(value, "relaxed"))
+ Sandboxing = CUPSD_SANDBOXING_RELAXED;
+ else if (!_cups_strcasecmp(value, "strict"))
+ Sandboxing = CUPSD_SANDBOXING_STRICT;
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unknown Sandboxing \"%s\" on line %d of %s.",
+ value, linenum, CupsFilesFile);
+ if (FatalErrors & CUPSD_FATAL_CONFIG)
+ return (0);
+ }
+ }
else if (!_cups_strcasecmp(line, "SystemGroup") && value)
{
/*
@@ -3472,7 +3651,7 @@ read_cups_files_conf(cups_file_t *fp) /* I - File to read from */
return (0);
}
else
- User = atoi(value);
+ User = (uid_t)atoi(value);
}
else
{
@@ -3506,6 +3685,15 @@ read_cups_files_conf(cups_file_t *fp) /* I - File to read from */
}
}
}
+ else if (!_cups_strcasecmp(line, "ServerCertificate") ||
+ !_cups_strcasecmp(line, "ServerKey"))
+ {
+ cupsdLogMessage(CUPSD_LOG_INFO,
+ "The \"%s\" directive on line %d of %s is no longer "
+ "supported; this will become an error in a future "
+ "release.",
+ line, linenum, CupsFilesFile);
+ }
else if (!parse_variable(CupsFilesFile, linenum, line, value,
sizeof(cupsfiles_vars) / sizeof(cupsfiles_vars[0]),
cupsfiles_vars) &&
@@ -3535,8 +3723,8 @@ read_location(cups_file_t *fp, /* I - Configuration file */
if ((parent = cupsdFindLocation(location)) != NULL)
- cupsdLogMessage(CUPSD_LOG_WARN, "Duplicate <Location %s> on line %d.",
- location, linenum);
+ cupsdLogMessage(CUPSD_LOG_WARN, "Duplicate <Location %s> on line %d of %s.",
+ location, linenum, ConfigurationFile);
else if ((parent = cupsdNewLocation(location)) == NULL)
return (0);
else
@@ -3561,7 +3749,7 @@ read_location(cups_file_t *fp, /* I - Configuration file */
{
if (!value)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of %s.", linenum, ConfigurationFile);
if (FatalErrors & CUPSD_FATAL_CONFIG)
return (0);
else
@@ -3596,8 +3784,8 @@ read_location(cups_file_t *fp, /* I - Configuration file */
else if (!strcmp(value, "TRACE"))
loc->limit |= CUPSD_AUTH_LIMIT_TRACE;
else
- cupsdLogMessage(CUPSD_LOG_WARN, "Unknown request type %s on line %d.",
- value, linenum);
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown request type %s on line %d of %s.",
+ value, linenum, ConfigurationFile);
for (value = valptr; isspace(*value & 255); value ++);
}
@@ -3612,15 +3800,15 @@ read_location(cups_file_t *fp, /* I - Configuration file */
loc = parent;
else if (!value)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d.", linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d of %s.", linenum, ConfigurationFile);
if (FatalErrors & CUPSD_FATAL_CONFIG)
return (0);
}
else if (!parse_aaa(loc, line, value, linenum))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown Location directive %s on line %d.",
- line, linenum);
+ "Unknown Location directive %s on line %d of %s.",
+ line, linenum, ConfigurationFile);
if (FatalErrors & CUPSD_FATAL_CONFIG)
return (0);
}
@@ -3659,8 +3847,8 @@ read_policy(cups_file_t *fp, /* I - Configuration file */
*/
if ((pol = cupsdFindPolicy(policy)) != NULL)
- cupsdLogMessage(CUPSD_LOG_WARN, "Duplicate <Policy %s> on line %d.",
- policy, linenum);
+ cupsdLogMessage(CUPSD_LOG_WARN, "Duplicate <Policy %s> on line %d of %s.",
+ policy, linenum, ConfigurationFile);
else if ((pol = cupsdAddPolicy(policy)) == NULL)
return (0);
@@ -3681,8 +3869,8 @@ read_policy(cups_file_t *fp, /* I - Configuration file */
{
if (op)
cupsdLogMessage(CUPSD_LOG_WARN,
- "Missing </Limit> before </Policy> on line %d.",
- linenum);
+ "Missing </Limit> before </Policy> on line %d of %s.",
+ linenum, ConfigurationFile);
set_policy_defaults(pol);
@@ -3692,7 +3880,7 @@ read_policy(cups_file_t *fp, /* I - Configuration file */
{
if (!value)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of %s.", linenum, ConfigurationFile);
if (FatalErrors & CUPSD_FATAL_CONFIG)
return (0);
else
@@ -3718,15 +3906,15 @@ read_policy(cups_file_t *fp, /* I - Configuration file */
ops[num_ops] = IPP_ANY_OPERATION;
else if ((ops[num_ops] = ippOpValue(value)) == IPP_BAD_OPERATION)
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Bad IPP operation name \"%s\" on line %d.",
- value, linenum);
+ "Bad IPP operation name \"%s\" on line %d of %s.",
+ value, linenum, ConfigurationFile);
else
num_ops ++;
}
else
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Too many operations listed on line %d.",
- linenum);
+ "Too many operations listed on line %d of %s.",
+ linenum, ConfigurationFile);
for (value = valptr; isspace(*value & 255); value ++);
}
@@ -3767,7 +3955,7 @@ read_policy(cups_file_t *fp, /* I - Configuration file */
}
else if (!value)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d.", linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d of %s.", linenum, ConfigurationFile);
if (FatalErrors & CUPSD_FATAL_CONFIG)
return (0);
}
@@ -3780,7 +3968,7 @@ read_policy(cups_file_t *fp, /* I - Configuration file */
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"%s directive must appear outside <Limit>...</Limit> "
- "on line %d.", line, linenum);
+ "on line %d of %s.", line, linenum, ConfigurationFile);
if (FatalErrors & CUPSD_FATAL_CONFIG)
return (0);
}
@@ -3878,16 +4066,16 @@ read_policy(cups_file_t *fp, /* I - Configuration file */
else if (!op)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Missing <Limit ops> directive before %s on line %d.",
- line, linenum);
+ "Missing <Limit ops> directive before %s on line %d of %s.",
+ line, linenum, ConfigurationFile);
if (FatalErrors & CUPSD_FATAL_CONFIG)
return (0);
}
else if (!parse_aaa(op, line, value, linenum))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unknown Policy Limit directive %s on line %d.",
- line, linenum);
+ "Unknown Policy Limit directive %s on line %d of %s.",
+ line, linenum, ConfigurationFile);
if (FatalErrors & CUPSD_FATAL_CONFIG)
return (0);
@@ -3916,121 +4104,106 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */
* Verify that we have an explicit policy for Validate-Job, Cancel-Jobs,
* Cancel-My-Jobs, Close-Job, and CUPS-Get-Document, which ensures that
* upgrades do not introduce new security issues...
+ *
+ * CUPS STR #4659: Allow a lone <Limit All> policy.
*/
- if ((op = cupsdFindPolicyOp(pol, IPP_VALIDATE_JOB)) == NULL ||
- op->op == IPP_ANY_OPERATION)
+ if (cupsArrayCount(pol->ops) > 1)
{
- if ((op = cupsdFindPolicyOp(pol, IPP_PRINT_JOB)) != NULL &&
- op->op != IPP_ANY_OPERATION)
+ if ((op = cupsdFindPolicyOp(pol, IPP_VALIDATE_JOB)) == NULL ||
+ op->op == IPP_ANY_OPERATION)
{
- /*
- * Add a new limit for Validate-Job using the Print-Job limit as a
- * template...
- */
+ if ((op = cupsdFindPolicyOp(pol, IPP_PRINT_JOB)) != NULL &&
+ op->op != IPP_ANY_OPERATION)
+ {
+ /*
+ * Add a new limit for Validate-Job using the Print-Job limit as a
+ * template...
+ */
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No limit for Validate-Job defined in policy %s "
- "- using Print-Job's policy.", pol->name);
+ cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Validate-Job defined in policy %s - using Print-Job's policy.", pol->name);
- cupsdAddPolicyOp(pol, op, IPP_VALIDATE_JOB);
+ cupsdAddPolicyOp(pol, op, IPP_VALIDATE_JOB);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Validate-Job defined in policy %s and no suitable template found.", pol->name);
}
- else
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No limit for Validate-Job defined in policy %s "
- "and no suitable template found.", pol->name);
- }
- if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_JOBS)) == NULL ||
- op->op == IPP_ANY_OPERATION)
- {
- if ((op = cupsdFindPolicyOp(pol, IPP_PAUSE_PRINTER)) != NULL &&
- op->op != IPP_ANY_OPERATION)
+ if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_JOBS)) == NULL ||
+ op->op == IPP_ANY_OPERATION)
{
- /*
- * Add a new limit for Cancel-Jobs using the Pause-Printer limit as a
- * template...
- */
+ if ((op = cupsdFindPolicyOp(pol, IPP_PAUSE_PRINTER)) != NULL &&
+ op->op != IPP_ANY_OPERATION)
+ {
+ /*
+ * Add a new limit for Cancel-Jobs using the Pause-Printer limit as a
+ * template...
+ */
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No limit for Cancel-Jobs defined in policy %s "
- "- using Pause-Printer's policy.", pol->name);
+ cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Cancel-Jobs defined in policy %s - using Pause-Printer's policy.", pol->name);
- cupsdAddPolicyOp(pol, op, IPP_CANCEL_JOBS);
+ cupsdAddPolicyOp(pol, op, IPP_CANCEL_JOBS);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Cancel-Jobs defined in policy %s and no suitable template found.", pol->name);
}
- else
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No limit for Cancel-Jobs defined in policy %s "
- "and no suitable template found.", pol->name);
- }
- if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_MY_JOBS)) == NULL ||
- op->op == IPP_ANY_OPERATION)
- {
- if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
- op->op != IPP_ANY_OPERATION)
+ if ((op = cupsdFindPolicyOp(pol, IPP_CANCEL_MY_JOBS)) == NULL ||
+ op->op == IPP_ANY_OPERATION)
{
- /*
- * Add a new limit for Cancel-My-Jobs using the Send-Document limit as
- * a template...
- */
+ if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
+ op->op != IPP_ANY_OPERATION)
+ {
+ /*
+ * Add a new limit for Cancel-My-Jobs using the Send-Document limit as
+ * a template...
+ */
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No limit for Cancel-My-Jobs defined in policy %s "
- "- using Send-Document's policy.", pol->name);
+ cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Cancel-My-Jobs defined in policy %s - using Send-Document's policy.", pol->name);
- cupsdAddPolicyOp(pol, op, IPP_CANCEL_MY_JOBS);
+ cupsdAddPolicyOp(pol, op, IPP_CANCEL_MY_JOBS);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Cancel-My-Jobs defined in policy %s and no suitable template found.", pol->name);
}
- else
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No limit for Cancel-My-Jobs defined in policy %s "
- "and no suitable template found.", pol->name);
- }
- if ((op = cupsdFindPolicyOp(pol, IPP_CLOSE_JOB)) == NULL ||
- op->op == IPP_ANY_OPERATION)
- {
- if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
- op->op != IPP_ANY_OPERATION)
+ if ((op = cupsdFindPolicyOp(pol, IPP_CLOSE_JOB)) == NULL ||
+ op->op == IPP_ANY_OPERATION)
{
- /*
- * Add a new limit for Close-Job using the Send-Document limit as a
- * template...
- */
+ if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
+ op->op != IPP_ANY_OPERATION)
+ {
+ /*
+ * Add a new limit for Close-Job using the Send-Document limit as a
+ * template...
+ */
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No limit for Close-Job defined in policy %s "
- "- using Send-Document's policy.", pol->name);
+ cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Close-Job defined in policy %s - using Send-Document's policy.", pol->name);
- cupsdAddPolicyOp(pol, op, IPP_CLOSE_JOB);
+ cupsdAddPolicyOp(pol, op, IPP_CLOSE_JOB);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_WARN, "No limit for Close-Job defined in policy %s and no suitable template found.", pol->name);
}
- else
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No limit for Close-Job defined in policy %s "
- "and no suitable template found.", pol->name);
- }
- if ((op = cupsdFindPolicyOp(pol, CUPS_GET_DOCUMENT)) == NULL ||
- op->op == IPP_ANY_OPERATION)
- {
- if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
- op->op != IPP_ANY_OPERATION)
+ if ((op = cupsdFindPolicyOp(pol, CUPS_GET_DOCUMENT)) == NULL ||
+ op->op == IPP_ANY_OPERATION)
{
- /*
- * Add a new limit for CUPS-Get-Document using the Send-Document
- * limit as a template...
- */
+ if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL &&
+ op->op != IPP_ANY_OPERATION)
+ {
+ /*
+ * Add a new limit for CUPS-Get-Document using the Send-Document
+ * limit as a template...
+ */
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No limit for CUPS-Get-Document defined in policy %s "
- "- using Send-Document's policy.", pol->name);
+ cupsdLogMessage(CUPSD_LOG_WARN, "No limit for CUPS-Get-Document defined in policy %s - using Send-Document's policy.", pol->name);
- cupsdAddPolicyOp(pol, op, CUPS_GET_DOCUMENT);
+ cupsdAddPolicyOp(pol, op, CUPS_GET_DOCUMENT);
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_WARN, "No limit for CUPS-Get-Document defined in policy %s and no suitable template found.", pol->name);
}
- else
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No limit for CUPS-Get-Document defined in policy %s "
- "and no suitable template found.", pol->name);
}
/*
@@ -4040,18 +4213,14 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */
if (!pol->job_access)
{
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No JobPrivateAccess defined in policy %s "
- "- using defaults.", pol->name);
+ cupsdLogMessage(CUPSD_LOG_WARN, "No JobPrivateAccess defined in policy %s - using defaults.", pol->name);
cupsdAddString(&(pol->job_access), "@OWNER");
cupsdAddString(&(pol->job_access), "@SYSTEM");
}
if (!pol->job_attrs)
{
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No JobPrivateValues defined in policy %s "
- "- using defaults.", pol->name);
+ cupsdLogMessage(CUPSD_LOG_WARN, "No JobPrivateValues defined in policy %s - using defaults.", pol->name);
cupsdAddString(&(pol->job_attrs), "job-name");
cupsdAddString(&(pol->job_attrs), "job-originating-host-name");
cupsdAddString(&(pol->job_attrs), "job-originating-user-name");
@@ -4060,18 +4229,14 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */
if (!pol->sub_access)
{
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No SubscriptionPrivateAccess defined in policy %s "
- "- using defaults.", pol->name);
+ cupsdLogMessage(CUPSD_LOG_WARN, "No SubscriptionPrivateAccess defined in policy %s - using defaults.", pol->name);
cupsdAddString(&(pol->sub_access), "@OWNER");
cupsdAddString(&(pol->sub_access), "@SYSTEM");
}
if (!pol->sub_attrs)
{
- cupsdLogMessage(CUPSD_LOG_WARN,
- "No SubscriptionPrivateValues defined in policy %s "
- "- using defaults.", pol->name);
+ cupsdLogMessage(CUPSD_LOG_WARN, "No SubscriptionPrivateValues defined in policy %s - using defaults.", pol->name);
cupsdAddString(&(pol->sub_attrs), "notify-events");
cupsdAddString(&(pol->sub_attrs), "notify-pull-method");
cupsdAddString(&(pol->sub_attrs), "notify-recipient-uri");
@@ -4082,5 +4247,5 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */
/*
- * End of "$Id: conf.c 11221 2013-08-06 16:16:01Z msweet $".
+ * End of "$Id: conf.c 12819 2015-07-31 13:52:00Z msweet $".
*/
diff --git a/scheduler/conf.h b/scheduler/conf.h
index 8bf0749..59cb157 100644
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -1,16 +1,16 @@
/*
- * "$Id: conf.h 11221 2013-08-06 16:16:01Z msweet $"
+ * "$Id: conf.h 12689 2015-06-03 19:49:54Z msweet $"
*
- * Configuration file definitions for the CUPS scheduler.
+ * Configuration file definitions for the CUPS scheduler.
*
- * Copyright 2007-2013 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 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/".
+ * 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/".
*/
@@ -20,9 +20,10 @@
typedef enum
{
- CUPSD_LOG_PPD = -4, /* Used internally for PPD keywords */
+ CUPSD_LOG_PPD = -5, /* Used internally for PPD keywords */
CUPSD_LOG_ATTR, /* Used internally for attributes */
- CUPSD_LOG_STATE, /* Used internally for state-reasons */
+ CUPSD_LOG_STATE, /* Used internally for printer-state-reasons */
+ CUPSD_LOG_JOBSTATE, /* Used internally for job-state-reasons */
CUPSD_LOG_PAGE, /* Used internally for page logging */
CUPSD_LOG_NONE,
CUPSD_LOG_EMERG, /* Emergency issues */
@@ -38,6 +39,7 @@ typedef enum
typedef enum
{
+ CUPSD_ACCESSLOG_NONE, /* Log no requests */
CUPSD_ACCESSLOG_CONFIG, /* Log config requests */
CUPSD_ACCESSLOG_ACTIONS, /* Log config, print, and job management requests */
CUPSD_ACCESSLOG_ALL /* Log everything */
@@ -49,6 +51,13 @@ typedef enum
CUPSD_TIME_USECS /* Standard format with microseconds */
} cupsd_time_t;
+typedef enum
+{
+ CUPSD_SANDBOXING_OFF, /* No sandboxing */
+ CUPSD_SANDBOXING_RELAXED, /* Relaxed sandboxing */
+ CUPSD_SANDBOXING_STRICT /* Strict sandboxing */
+} cupsd_sandboxing_t;
+
/*
* FatalErrors flags...
@@ -73,14 +82,6 @@ typedef enum
/*
- * SSL options (bits)...
- */
-
-#define CUPSD_SSL_NONE 0 /* No special options */
-#define CUPSD_SSL_NOEMPTY 1 /* Do not insert empty fragments */
-
-
-/*
* ServerAlias data...
*/
@@ -149,38 +150,44 @@ VAR char *AccessLog VALUE(NULL),
/* Temporary directory */
*Printcap VALUE(NULL),
/* Printcap file */
- *PrintcapGUI VALUE(NULL),
- /* GUI program to use for IRIX */
*FontPath VALUE(NULL),
/* Font search path */
*RemoteRoot VALUE(NULL),
/* Remote root user */
*Classification VALUE(NULL);
/* Classification of system */
-VAR uid_t User VALUE(1);
+VAR uid_t User VALUE(1),
/* User ID for server */
+ RunUser VALUE(0);
+ /* User to run as, used for files */
VAR gid_t Group VALUE(0);
/* Group ID for server */
VAR cupsd_accesslog_t AccessLogLevel VALUE(CUPSD_ACCESSLOG_ACTIONS);
/* Access log level */
VAR int ClassifyOverride VALUE(0),
/* Allow overrides? */
- ConfigFilePerm VALUE(0640),
- /* Permissions for config files */
LogDebugHistory VALUE(200),
/* Amount of automatic debug history */
FatalErrors VALUE(CUPSD_FATAL_CONFIG),
/* Which errors are fatal? */
StrictConformance VALUE(FALSE),
/* Require strict IPP conformance? */
- SyncOnClose VALUE(FALSE),
+ SyncOnClose VALUE(FALSE);
/* Call fsync() when closing files? */
- LogFilePerm VALUE(0644);
+VAR mode_t ConfigFilePerm VALUE(0640U),
+ /* Permissions for config files */
+ LogFilePerm VALUE(0644U);
/* Permissions for log files */
VAR cupsd_loglevel_t LogLevel VALUE(CUPSD_LOG_WARN);
/* Error log level */
VAR cupsd_time_t LogTimeFormat VALUE(CUPSD_TIME_STANDARD);
/* Log file time format */
+VAR cups_file_t *LogStderr VALUE(NULL);
+ /* Stderr file, if any */
+VAR cupsd_sandboxing_t Sandboxing VALUE(CUPSD_SANDBOXING_STRICT);
+ /* Sandboxing level */
+VAR int UseSandboxing VALUE(1);
+ /* Use sandboxing for child procs? */
VAR int MaxClients VALUE(100),
/* Maximum number of clients */
MaxClientsPerHost VALUE(0),
@@ -211,8 +218,6 @@ VAR int MaxClients VALUE(100),
/* Timeout before reload from SIGHUP */
RootCertDuration VALUE(300),
/* Root certificate update interval */
- RunUser VALUE(0),
- /* User to run as, used for files */
PrintcapFormat VALUE(PRINTCAP_BSD),
/* Format of printcap file? */
DefaultShared VALUE(TRUE),
@@ -237,20 +242,14 @@ VAR const char **MimeTypes VALUE(NULL);
/* Array of MIME types */
#ifdef HAVE_SSL
-VAR char *ServerCertificate VALUE(NULL);
- /* Server certificate file */
-# if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS)
-VAR char *ServerKey VALUE(NULL);
- /* Server key file */
-# endif /* HAVE_LIBSSL || HAVE_GNUTLS */
-VAR int SSLOptions VALUE(CUPSD_SSL_NONE);
- /* SSL/TLS options */
+VAR char *ServerKeychain VALUE(NULL);
+ /* Keychain holding cert + key */
#endif /* HAVE_SSL */
-#ifdef HAVE_LAUNCHD
-VAR int LaunchdTimeout VALUE(10);
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+VAR int IdleExitTimeout VALUE(60);
/* Time after which an idle cupsd will exit */
-#endif /* HAVE_LAUNCHD */
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
#ifdef HAVE_AUTHORIZATION_H
VAR char *SystemGroupAuthKey VALUE(NULL);
@@ -273,18 +272,21 @@ gss_cred_id_t ServerCreds; /* Server's GSS credentials */
extern void cupsdAddAlias(cups_array_t *aliases, const char *name);
extern int cupsdCheckLogFile(cups_file_t **lf, const char *logname);
extern int cupsdCheckPermissions(const char *filename,
- const char *suffix, int mode,
- int user, int group, int is_dir,
+ const char *suffix, mode_t mode,
+ uid_t user, gid_t 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 int cupsdLogClient(cupsd_client_t *con, int level,
+ const char *message, ...)
+ __attribute__((__format__(__printf__, 3, 4)));
extern void cupsdLogFCMessage(void *context, _cups_fc_result_t result,
const char *message);
#ifdef HAVE_GSSAPI
-extern int cupsdLogGSSMessage(int level, int major_status,
- int minor_status,
+extern int cupsdLogGSSMessage(int level, OM_uint32 major_status,
+ OM_uint32 minor_status,
const char *message, ...);
#endif /* HAVE_GSSAPI */
extern int cupsdLogJob(cupsd_job_t *job, int level, const char *message,
@@ -298,5 +300,5 @@ extern int cupsdWriteErrorLog(int level, const char *message);
/*
- * End of "$Id: conf.h 11221 2013-08-06 16:16:01Z msweet $".
+ * End of "$Id: conf.h 12689 2015-06-03 19:49:54Z msweet $".
*/
diff --git a/scheduler/cups-deviced.c b/scheduler/cups-deviced.c
index 7a5929f..85264ed 100644
--- a/scheduler/cups-deviced.c
+++ b/scheduler/cups-deviced.c
@@ -1,27 +1,16 @@
/*
- * "$Id: cups-deviced.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: cups-deviced.c 11782 2014-03-28 21:03:43Z msweet $"
*
- * Device scanning mini-daemon for CUPS.
+ * Device scanning mini-daemon for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * main() - Scan for devices and return an IPP response.
- * add_device() - Add a new device to the list.
- * compare_devices() - Compare device names to eliminate duplicates.
- * get_current_time() - Get the current time as a double value in seconds.
- * get_device() - Get a device from a backend.
- * process_children() - Process all dead children...
- * sigchld_handler() - Handle 'child' signals from old processes.
- * start_backend() - Run a backend to gather the available devices.
+ * 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/".
*/
/*
@@ -82,7 +71,7 @@ static cupsd_backend_t backends[MAX_BACKENDS];
static struct pollfd backend_fds[MAX_BACKENDS];
/* Array for poll() */
static cups_array_t *devices; /* Array of devices */
-static int normal_user; /* Normal user ID */
+static uid_t normal_user; /* Normal user ID */
static int device_limit; /* Maximum number of devices */
static int send_class, /* Send device-class attribute? */
send_info, /* Send device-info attribute? */
@@ -182,7 +171,7 @@ main(int argc, /* I - Number of command-line args */
return (1);
}
- normal_user = atoi(argv[4]);
+ normal_user = (uid_t)atoi(argv[4]);
if (normal_user <= 0)
{
fprintf(stderr, "ERROR: [cups-deviced] Bad user %d!\n", normal_user);
@@ -281,8 +270,7 @@ main(int argc, /* I - Number of command-line args */
* all others run as the unprivileged user...
*/
- start_backend(dent->filename,
- !(dent->fileinfo.st_mode & (S_IRWXG | S_IRWXO)));
+ start_backend(dent->filename, !(dent->fileinfo.st_mode & (S_IWGRP | S_IRWXO)));
}
cupsDirClose(dir);
@@ -309,7 +297,7 @@ main(int argc, /* I - Number of command-line args */
timeout = (int)(1000 * (end_time - current_time));
- if (poll(backend_fds, num_backends, timeout) > 0)
+ if (poll(backend_fds, (nfds_t)num_backends, timeout) > 0)
{
for (i = 0; i < num_backends; i ++)
if (backend_fds[i].revents && backends[i].pipe)
@@ -326,8 +314,7 @@ main(int argc, /* I - Number of command-line args */
break;
}
}
- while (bpipe->ptr &&
- memchr(bpipe->ptr, '\n', bpipe->end - bpipe->ptr));
+ while (bpipe->ptr && memchr(bpipe->ptr, '\n', (size_t)(bpipe->end - bpipe->ptr)));
}
}
@@ -806,5 +793,5 @@ start_backend(const char *name, /* I - Backend to run */
/*
- * End of "$Id: cups-deviced.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: cups-deviced.c 11782 2014-03-28 21:03:43Z msweet $".
*/
diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx
index 4a3d34f..7da6572 100644
--- a/scheduler/cups-driverd.cxx
+++ b/scheduler/cups-driverd.cxx
@@ -1,48 +1,20 @@
/*
- * "$Id: cups-driverd.cxx 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: cups-driverd.cxx 12733 2015-06-12 01:21:05Z msweet $"
*
- * PPD/driver support for CUPS.
+ * PPD/driver support for CUPS.
*
- * This program handles listing and installing static PPD files, PPD files
- * created from driver information files, and dynamically generated PPD files
- * using driver helper programs.
+ * This program handles listing and installing static PPD files, PPD files
+ * created from driver information files, and dynamically generated PPD files
+ * using driver helper programs.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products.
+ * Copyright 2007-2015 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * main() - 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.
- * regex_string() - Construct a regular expression to compare a simple
- * string.
+ * 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/".
*/
/*
@@ -61,7 +33,7 @@
* Constants...
*/
-#define PPD_SYNC 0x50504437 /* Sync word for ppds.dat (PPD7) */
+#define PPD_SYNC 0x50504438 /* Sync word for ppds.dat (PPD8) */
#define PPD_MAX_LANG 32 /* Maximum languages */
#define PPD_MAX_PROD 32 /* Maximum products */
#define PPD_MAX_VERS 32 /* Maximum versions */
@@ -70,9 +42,12 @@
#define PPD_TYPE_PDF 1 /* PDF PPD */
#define PPD_TYPE_RASTER 2 /* CUPS raster PPD */
#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 */
+#define PPD_TYPE_OBJECT_ANY 4 /* 3D (AMF/STL/g-code) PPD */
+#define PPD_TYPE_OBJECT_DIRECT 5 /* 3D (AMF/STL/g-code) PPD over any connection */
+#define PPD_TYPE_OBJECT_STORAGE 6 /* 3D (AMF/STL/g-code) PPD for storage to SD card, etc. */
+#define PPD_TYPE_UNKNOWN 7 /* Other/hybrid PPD */
+#define PPD_TYPE_DRV 8 /* Driver info file */
+#define PPD_TYPE_ARCHIVE 9 /* Archive file */
#define TAR_BLOCK 512 /* Number of bytes in a block */
#define TAR_BLOCKS 10 /* Blocking factor */
@@ -163,6 +138,9 @@ static const char * const PPDTypes[] = /* ppd-type values */
"pdf",
"raster",
"fax",
+ "object",
+ "object-direct",
+ "object-storage",
"unknown",
"drv",
"archive"
@@ -291,7 +269,7 @@ add_ppd(const char *filename, /* I - PPD filename */
ppd->found = 1;
ppd->record.mtime = mtime;
- ppd->record.size = size;
+ ppd->record.size = (off_t)size;
ppd->record.model_number = model_number;
ppd->record.type = type;
@@ -645,7 +623,7 @@ cat_tar(const char *name, /* I - PPD name */
*/
if ((fp = get_file(name, request_id, "model", filename, sizeof(filename),
- &ppdname)) == NULL)
+ &ppdname)) == NULL || !ppdname)
return (1);
/*
@@ -674,7 +652,7 @@ cat_tar(const char *name, /* I - PPD name */
if ((size_t)(bytes = (curinfo.st_size - total)) > sizeof(buffer))
bytes = sizeof(buffer);
- if ((bytes = cupsFileRead(fp, buffer, bytes)) < 0)
+ if ((bytes = cupsFileRead(fp, buffer, (size_t)bytes)) < 0)
{
if (errno == EINTR || errno == EAGAIN)
{
@@ -686,7 +664,7 @@ cat_tar(const char *name, /* I - PPD name */
break;
}
}
- else if (bytes > 0 && fwrite(buffer, bytes, 1, stdout) != 1)
+ else if (bytes > 0 && fwrite(buffer, (size_t)bytes, 1, stdout) != 1)
break;
}
@@ -1053,8 +1031,6 @@ list_ppds(int request_id, /* I - Request ID */
*type_str; /* ppd-type option */
int model_number, /* ppd-model-number value */
type, /* ppd-type value */
- make_and_model_len, /* Length of ppd-make-and-model */
- product_len, /* Length of ppd-product */
send_device_id, /* Send ppd-device-id? */
send_make, /* Send ppd-make? */
send_make_and_model, /* Send ppd-make-and-model? */
@@ -1065,6 +1041,8 @@ list_ppds(int request_id, /* I - Request ID */
send_psversion, /* Send ppd-psversion? */
send_type, /* Send ppd-type? */
sent_header; /* Sent the IPP header? */
+ size_t make_and_model_len, /* Length of ppd-make-and-model */
+ product_len; /* Length of ppd-product */
regex_t *device_id_re, /* Regular expression for matching device ID */
*make_and_model_re; /* Regular expression for matching make and model */
regmatch_t re_matches[6]; /* Regular expression matches */
@@ -1349,7 +1327,7 @@ list_ppds(int request_id, /* I - Request ID */
if (device_id_re &&
!regexec(device_id_re, ppd->record.device_id,
- (int)(sizeof(re_matches) / sizeof(re_matches[0])),
+ (size_t)(sizeof(re_matches) / sizeof(re_matches[0])),
re_matches, 0))
{
/*
@@ -1379,13 +1357,13 @@ list_ppds(int request_id, /* I - Request ID */
if (make_and_model_re &&
!regexec(make_and_model_re, ppd->record.make_and_model,
- (int)(sizeof(re_matches) / sizeof(re_matches[0])),
+ (size_t)(sizeof(re_matches) / sizeof(re_matches[0])),
re_matches, 0))
{
// See how much of the make-and-model string we matched...
if (re_matches[0].rm_so == 0)
{
- if (re_matches[0].rm_eo == make_and_model_len)
+ if ((size_t)re_matches[0].rm_eo == make_and_model_len)
ppd->matches += 3; // Exact match
else
ppd->matches += 2; // Prefix match
@@ -1637,8 +1615,7 @@ load_drv(const char *filename, /* I - Actual filename */
* Add a dummy entry for the file...
*/
- add_ppd(name, name, "", "", "", "", "", "", mtime, size, 0,
- PPD_TYPE_DRV, "drv");
+ add_ppd(name, name, "", "", "", "", "", "", mtime, (size_t)size, 0, PPD_TYPE_DRV, "drv");
ChangedPPD = 1;
/*
@@ -1696,14 +1673,10 @@ load_drv(const char *filename, /* I - Actual filename */
if (!strcmp(product->name->value, "Product"))
{
if (!products_found)
- ppd = add_ppd(name, uri, "en", d->manufacturer->value, make_model,
- device_id ? device_id->value->value : "",
- product->value->value,
- ps_version ? ps_version->value->value : "(3010) 0",
- mtime, size, d->model_number, type, "drv");
+ ppd = add_ppd(name, uri, "en", d->manufacturer->value, make_model, device_id ? device_id->value->value : "", product->value->value,
+ ps_version ? ps_version->value->value : "(3010) 0", mtime, (size_t)size, d->model_number, type, "drv");
else if (products_found < PPD_MAX_PROD)
- strlcpy(ppd->record.products[products_found], product->value->value,
- sizeof(ppd->record.products[0]));
+ strlcpy(ppd->record.products[products_found], product->value->value, sizeof(ppd->record.products[0]));
else
break;
@@ -1711,11 +1684,7 @@ load_drv(const char *filename, /* I - Actual filename */
}
if (!products_found)
- add_ppd(name, uri, "en", d->manufacturer->value, make_model,
- device_id ? device_id->value->value : "",
- d->model_name->value,
- ps_version ? ps_version->value->value : "(3010) 0",
- mtime, size, d->model_number, type, "drv");
+ add_ppd(name, uri, "en", d->manufacturer->value, make_model, device_id ? device_id->value->value : "", d->model_name->value, ps_version ? ps_version->value->value : "(3010) 0", mtime, (size_t)size, d->model_number, type, "drv");
}
src->release();
@@ -1810,7 +1779,7 @@ load_drivers(cups_array_t *include, /* I - Drivers to include */
scheme_end = scheme + strlen(scheme) - 1;
if ((scheme_end > scheme && *scheme_end == '*' &&
- !strncmp(scheme, dent->filename, scheme_end - scheme)) ||
+ !strncmp(scheme, dent->filename, (size_t)(scheme_end - scheme))) ||
!strcmp(scheme, dent->filename))
{
fputs("DEBUG: [cups-driverd] Yes, exclude!\n", stderr);
@@ -1837,7 +1806,7 @@ load_drivers(cups_array_t *include, /* I - Drivers to include */
scheme_end = scheme + strlen(scheme) - 1;
if ((scheme_end > scheme && *scheme_end == '*' &&
- !strncmp(scheme, dent->filename, scheme_end - scheme)) ||
+ !strncmp(scheme, dent->filename, (size_t)(scheme_end - scheme))) ||
!strcmp(scheme, dent->filename))
{
fputs("DEBUG: [cups-driverd] Yes, include!\n", stderr);
@@ -1877,7 +1846,7 @@ load_drivers(cups_array_t *include, /* I - Drivers to include */
device_id[0] = '\0';
product[0] = '\0';
psversion[0] = '\0';
- strcpy(type_str, "postscript");
+ strlcpy(type_str, "postscript", sizeof(type_str));
if (sscanf(line, "\"%511[^\"]\"%127s%*[ \t]\"%127[^\"]\""
"%*[ \t]\"%127[^\"]\"%*[ \t]\"%255[^\"]\""
@@ -2043,7 +2012,7 @@ load_ppd(const char *filename, /* I - Real filename */
manufacturer[0] = '\0';
device_id[0] = '\0';
lang_encoding[0] = '\0';
- strcpy(lang_version, "en");
+ strlcpy(lang_version, "en", sizeof(lang_version));
model_number = 0;
install_group = 0;
type = PPD_TYPE_POSTSCRIPT;
@@ -2132,12 +2101,28 @@ load_ppd(const char *filename, /* I - Real filename */
if (!_cups_strncasecmp(ptr, "true", 4))
type = PPD_TYPE_FAX;
}
- else if (!strncmp(line, "*cupsFilter:", 12) && type == PPD_TYPE_POSTSCRIPT)
+ else if ((!strncmp(line, "*cupsFilter:", 12) || !strncmp(line, "*cupsFilter2:", 13)) && 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 (strstr(line + 12, "application/amf") ||
+ strstr(line + 12, "application/g-code") ||
+ strstr(line + 12, "application/sla"))
+ type = PPD_TYPE_OBJECT_ANY;
+ }
+ else if (!strncmp(line, "*cups3DWorkflows:", 17))
+ {
+ int is_direct = strstr(line + 17, "direct") != NULL;
+ int is_storage = strstr(line + 17, "storage") != NULL;
+
+ if (is_direct && !is_storage)
+ type = PPD_TYPE_OBJECT_DIRECT;
+ if (!is_direct && is_storage)
+ type = PPD_TYPE_OBJECT_STORAGE;
+ else
+ type = PPD_TYPE_OBJECT_ANY;
}
else if (!strncmp(line, "*cupsModelNumber:", 17))
sscanf(line, "*cupsModelNumber:%d", &model_number);
@@ -2166,7 +2151,7 @@ load_ppd(const char *filename, /* I - Real filename */
cupsCharsetToUTF8((cups_utf8_t *)make_model, nick_name,
sizeof(make_model), _ppdGetEncoding(lang_encoding));
else
- strcpy(make_model, model_name);
+ strlcpy(make_model, model_name, sizeof(make_model));
while (isspace(make_model[0] & 255))
_cups_strcpy(make_model, make_model + 1);
@@ -2236,13 +2221,13 @@ load_ppd(const char *filename, /* I - Real filename */
if (*ptr && ptr > manufacturer)
*ptr = '\0';
else
- strcpy(manufacturer, "Other");
+ strlcpy(manufacturer, "Other", sizeof(manufacturer));
}
else if (!_cups_strncasecmp(manufacturer, "LHAG", 4) ||
!_cups_strncasecmp(manufacturer, "linotype", 8))
- strcpy(manufacturer, "LHAG");
+ strlcpy(manufacturer, "LHAG", sizeof(manufacturer));
else if (!_cups_strncasecmp(manufacturer, "Hewlett", 7))
- strcpy(manufacturer, "HP");
+ strlcpy(manufacturer, "HP", sizeof(manufacturer));
/*
* Fix the lang_version as needed...
@@ -2290,7 +2275,7 @@ load_ppd(const char *filename, /* I - Real filename */
* Unknown language; use "xx"...
*/
- strcpy(lang_version, "xx");
+ strlcpy(lang_version, "xx", sizeof(lang_version));
}
/*
@@ -2307,11 +2292,7 @@ load_ppd(const char *filename, /* I - Real filename */
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);
+ ppd = add_ppd(name, name, lang_version, manufacturer, make_model, device_id, (char *)cupsArrayFirst(products), (char *)cupsArrayFirst(psversions), fileinfo->st_mtime, (size_t)fileinfo->st_size, model_number, type, scheme);
if (!ppd)
return;
@@ -2519,8 +2500,8 @@ load_ppds(const char *d, /* I - Actual directory */
* See if this file has been scanned before...
*/
- strcpy(key.record.filename, name);
- strcpy(key.record.name, name);
+ strlcpy(key.record.filename, name, sizeof(key.record.filename));
+ strlcpy(key.record.name, name, sizeof(key.record.name));
ppd = (ppd_info_t *)cupsArrayFind(PPDsByName, &key);
@@ -2634,13 +2615,11 @@ load_ppds_dat(char *filename, /* I - Filename buffer */
unsigned ppdsync; /* Sync word */
int num_ppds; /* Number of PPDs */
- if (cupsFileRead(fp, (char *)&ppdsync, sizeof(ppdsync))
- == sizeof(ppdsync) &&
+ if (cupsFileRead(fp, (char *)&ppdsync, sizeof(ppdsync)) == sizeof(ppdsync) &&
ppdsync == PPD_SYNC &&
!stat(filename, &fileinfo) &&
- ((fileinfo.st_size - sizeof(ppdsync)) % sizeof(ppd_rec_t)) == 0 &&
- (num_ppds = (fileinfo.st_size - sizeof(ppdsync)) /
- sizeof(ppd_rec_t)) > 0)
+ (((size_t)fileinfo.st_size - sizeof(ppdsync)) % sizeof(ppd_rec_t)) == 0 &&
+ (num_ppds = ((size_t)fileinfo.st_size - sizeof(ppdsync)) / sizeof(ppd_rec_t)) > 0)
{
/*
* We have a ppds.dat file, so read it!
@@ -2702,8 +2681,7 @@ load_tar(const char *filename, /* I - Actual filename */
(void)filename;
- add_ppd(name, name, "", "", "", "", "", "", mtime, size, 0,
- PPD_TYPE_ARCHIVE, "file");
+ add_ppd(name, name, "", "", "", "", "", "", mtime, (size_t)size, 0, PPD_TYPE_ARCHIVE, "file");
ChangedPPD = 1;
/*
@@ -2947,5 +2925,5 @@ regex_string(const char *s) /* I - String to compare */
/*
- * End of "$Id: cups-driverd.cxx 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: cups-driverd.cxx 12733 2015-06-12 01:21:05Z msweet $".
*/
diff --git a/scheduler/cups-exec.c b/scheduler/cups-exec.c
index 6d0d3d8..e63b163 100644
--- a/scheduler/cups-exec.c
+++ b/scheduler/cups-exec.c
@@ -1,23 +1,19 @@
/*
- * "$Id: cups-exec.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: cups-exec.c 11817 2014-04-15 16:31:11Z msweet $"
*
- * Sandbox helper for CUPS.
+ * Sandbox helper for CUPS.
*
- * Copyright 2007-2012 by Apple Inc.
+ * Copyright 2007-2014 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/".
+ * 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/".
*
* Usage:
*
- * cups-exec /path/to/profile /path/to/program argv0 argv1 ... argvN
- *
- * Contents:
- *
- * main() - Apply sandbox profile and execute program.
+ * cups-exec /path/to/profile [-u UID] [-g GID] [-n NICE] /path/to/program argv0 argv1 ... argvN
*/
/*
@@ -25,7 +21,11 @@
*/
#include <cups/string-private.h>
+#include <cups/file.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <sys/stat.h>
#ifdef HAVE_SANDBOX_H
# include <sandbox.h>
# ifndef SANDBOX_NAMED_EXTERNAL
@@ -36,6 +36,13 @@
/*
+ * Local functions...
+ */
+
+static void usage(void) __attribute__((noreturn));
+
+
+/*
* 'main()' - Apply sandbox profile and execute program.
*/
@@ -43,67 +50,157 @@ int /* O - Exit status */
main(int argc, /* I - Number of command-line args */
char *argv[]) /* I - Command-line arguments */
{
- int i; /* Looping var */
+ int i; /* Looping var */
+ const char *opt; /* Current option character */
+ uid_t uid = getuid(); /* UID */
+ gid_t gid = getgid(); /* GID */
+ int niceval = 0; /* Nice value */
#ifdef HAVE_SANDBOX_H
- char *sandbox_error = NULL; /* Sandbox error, if any */
+ char *sandbox_error = NULL; /* Sandbox error, if any */
#endif /* HAVE_SANDBOX_H */
/*
+ * Parse command-line...
+ */
+
+ for (i = 1; i < argc; i ++)
+ {
+ if (argv[i][0] == '-')
+ {
+ for (opt = argv[i] + 1; *opt; opt ++)
+ {
+ switch (*opt)
+ {
+ case 'g' : /* -g gid */
+ i ++;
+ if (i >= argc)
+ usage();
+
+ gid = (gid_t)atoi(argv[i]);
+ break;
+
+ case 'n' : /* -n nice-value */
+ i ++;
+ if (i >= argc)
+ usage();
+
+ niceval = atoi(argv[i]);
+ break;
+
+ case 'u' : /* -g gid */
+ i ++;
+ if (i >= argc)
+ usage();
+
+ uid = (uid_t)atoi(argv[i]);
+ break;
+
+ default :
+ fprintf(stderr, "cups-exec: Unknown option '-%c'.\n", *opt);
+ usage();
+ }
+ }
+ }
+ else
+ break;
+ }
+
+ /*
* Check that we have enough arguments...
*/
- if (argc < 4)
+ if ((i + 3) > argc)
+ {
+ fputs("cups-exec: Insufficient arguments.\n", stderr);
+ usage();
+ }
+
+ /*
+ * Make sure side and back channel FDs are non-blocking...
+ */
+
+ fcntl(3, F_SETFL, O_NDELAY);
+ fcntl(4, F_SETFL, O_NDELAY);
+
+ /*
+ * Change UID, GID, and nice value...
+ */
+
+ if (uid)
+ nice(niceval);
+
+ if (!getuid())
{
- puts("Usage: cups-exec /path/to/profile /path/to/program argv0 argv1 ... "
- "argvN");
- return (1);
+ if (setgid(gid))
+ exit(errno + 100);
+
+ if (setgroups(1, &gid))
+ exit(errno + 100);
+
+ if (uid && setuid(uid))
+ exit(errno + 100);
}
+ umask(077);
+
#ifdef HAVE_SANDBOX_H
/*
* Run in a separate security profile...
*/
- if (strcmp(argv[1], "none") &&
- sandbox_init(argv[1], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
+ if (strcmp(argv[i], "none") &&
+ sandbox_init(argv[i], SANDBOX_NAMED_EXTERNAL, &sandbox_error))
{
+ cups_file_t *fp; /* File */
+ char line[1024]; /* Line from file */
+ int linenum = 0; /* Line number in file */
+
fprintf(stderr, "DEBUG: sandbox_init failed: %s (%s)\n", sandbox_error,
strerror(errno));
sandbox_free_error(sandbox_error);
- return (1);
+
+ if ((fp = cupsFileOpen(argv[i], "r")) != NULL)
+ {
+ while (cupsFileGets(fp, line, sizeof(line)))
+ {
+ linenum ++;
+ fprintf(stderr, "DEBUG: %4d %s\n", linenum, line);
+ }
+ cupsFileClose(fp);
+ }
+
+ return (100 + EINVAL);
}
#endif /* HAVE_SANDBOX_H */
/*
- * Close file descriptors we don't need (insurance):
- *
- * 0 = stdin
- * 1 = stdout
- * 2 = stderr
- * 3 = back-channel
- * 4 = side-channel
- * 5-N = unused
- */
-
- for (i = 5; i < 1024; i ++)
- close(i);
-
- /*
* Execute the program...
*/
- execv(argv[2], argv + 3);
+ execv(argv[i + 1], argv + i + 2);
/*
* If we get here, execv() failed...
*/
fprintf(stderr, "DEBUG: execv failed: %s\n", strerror(errno));
- return (1);
+ return (errno + 100);
+}
+
+
+/*
+ * 'usage()' - Show program usage.
+ */
+
+static void
+usage(void)
+{
+ fputs("Usage: cups-exec [-g gid] [-n nice-value] [-u uid] /path/to/profile /path/to/program argv0 argv1 ... argvN\n", stderr);
+ exit(1);
}
/*
- * End of "$Id: cups-exec.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: cups-exec.c 11817 2014-04-15 16:31:11Z msweet $".
*/
diff --git a/scheduler/cups-lpd.c b/scheduler/cups-lpd.c
index bd6757b..4748ce0 100644
--- a/scheduler/cups-lpd.c
+++ b/scheduler/cups-lpd.c
@@ -1,27 +1,16 @@
/*
- * "$Id: cups-lpd.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: cups-lpd.c 12611 2015-05-06 15:30:36Z msweet $"
*
- * Line Printer Daemon interface for CUPS.
+ * Line Printer Daemon interface for CUPS.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 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() - Process an incoming LPD request...
- * create_job() - Create a new print job.
- * get_printer() - Get the named printer and its options.
- * print_file() - Add a file to the current job.
- * recv_print_job() - Receive a print job from the client.
- * remove_jobs() - Cancel one or more jobs.
- * send_state() - Send the queue state.
- * smart_gets() - Get a line of text, removing the trailing CR and/or LF.
+ * 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/".
*/
/*
@@ -40,6 +29,9 @@
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif /* HAVE_INTTYPES_H */
+#ifdef __APPLE__
+# include <vproc.h>
+#endif /* __APPLE__ */
/*
@@ -70,7 +62,7 @@ static int create_job(http_t *http, const char *dest, const char *title,
const char *docname, const char *user,
int num_options, cups_option_t *options);
static int get_printer(http_t *http, const char *name, char *dest,
- int destsize, cups_option_t **options,
+ size_t destsize, cups_option_t **options,
int *accepting, int *shared, ipp_pstate_t *state);
static int print_file(http_t *http, int id, const char *filename,
const char *docname, const char *user,
@@ -107,6 +99,9 @@ main(int argc, /* I - Number of command-line arguments */
hostip[256], /* IP address */
*hostfamily; /* Address family */
int hostlookups; /* Do hostname lookups? */
+#ifdef __APPLE__
+ vproc_transaction_t vtran = vproc_transaction_begin(NULL);
+#endif /* __APPLE__ */
/*
@@ -184,7 +179,7 @@ main(int argc, /* I - Number of command-line arguments */
if (getpeername(0, (struct sockaddr *)&hostaddr, &hostlen))
{
syslog(LOG_WARNING, "Unable to get client address - %s", strerror(errno));
- strcpy(hostname, "unknown");
+ strlcpy(hostname, "unknown", sizeof(hostname));
}
else
{
@@ -222,6 +217,11 @@ main(int argc, /* I - Number of command-line arguments */
syslog(LOG_ERR, "Unable to get command line from client!");
putchar(1);
+
+#ifdef __APPLE__
+ vproc_transaction_end(NULL, vtran);
+#endif /* __APPLE__ */
+
return (1);
}
@@ -230,8 +230,10 @@ main(int argc, /* I - Number of command-line arguments */
* resource list, and/or user name.
*/
- command = line[0];
- dest = line + 1;
+ if ((command = line[0]) == '\0')
+ dest = line;
+ else
+ dest = line + 1;
if (command == 0x02)
list = NULL;
@@ -268,21 +270,21 @@ main(int argc, /* I - Number of command-line arguments */
syslog(LOG_INFO, "Receive print job for %s", dest);
/* recv_print_job() sends initial status byte */
- status = recv_print_job(dest, num_defaults, defaults);
+ status = (char)recv_print_job(dest, num_defaults, defaults);
break;
case 0x03 : /* Send queue state (short) */
syslog(LOG_INFO, "Send queue state (short) for %s %s", dest, list);
/* no status byte for this command */
- status = send_state(dest, list, 0);
+ status = (char)send_state(dest, list, 0);
break;
case 0x04 : /* Send queue state (long) */
syslog(LOG_INFO, "Send queue state (long) for %s %s", dest, list);
/* no status byte for this command */
- status = send_state(dest, list, 1);
+ status = (char)send_state(dest, list, 1);
break;
case 0x05 : /* Remove jobs */
@@ -300,7 +302,7 @@ main(int argc, /* I - Number of command-line arguments */
syslog(LOG_INFO, "Remove jobs %s on %s by %s", list, dest, agent);
- status = remove_jobs(dest, agent, list);
+ status = (char)remove_jobs(dest, agent, list);
}
else
status = 1;
@@ -312,6 +314,10 @@ main(int argc, /* I - Number of command-line arguments */
syslog(LOG_INFO, "Closing connection");
closelog();
+#ifdef __APPLE__
+ vproc_transaction_end(NULL, vtran);
+#endif /* __APPLE__ */
+
return (status);
}
@@ -409,7 +415,7 @@ static int /* O - Number of options or -1 on error */
get_printer(http_t *http, /* I - HTTP connection */
const char *name, /* I - Printer name from request */
char *dest, /* I - Destination buffer */
- int destsize, /* I - Size of destination buffer */
+ size_t destsize, /* I - Size of destination buffer */
cups_option_t **options, /* O - Printer options */
int *accepting, /* O - printer-is-accepting-jobs value */
int *shared, /* O - printer-is-shared value */
@@ -744,7 +750,7 @@ print_file(http_t *http, /* I - HTTP connection */
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
"document-format", NULL, format);
- ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last);
+ ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", (char)last);
/*
* Do the request...
@@ -781,7 +787,8 @@ recv_print_job(
int fd; /* Temporary file */
FILE *fp; /* File pointer */
char filename[1024]; /* Temporary filename */
- int bytes; /* Bytes received */
+ ssize_t bytes; /* Bytes received */
+ size_t total; /* Total bytes */
char line[256], /* Line from file/stdin */
command, /* Command from line */
*count, /* Number of bytes */
@@ -914,7 +921,7 @@ recv_print_job(
break;
}
- strcpy(filename, control);
+ strlcpy(filename, control, sizeof(filename));
}
break;
@@ -950,7 +957,7 @@ recv_print_job(
break;
}
- strcpy(filename, temp[num_data]);
+ strlcpy(filename, temp[num_data], sizeof(filename));
num_data ++;
break;
@@ -965,15 +972,15 @@ recv_print_job(
* Copy the data or control file from the client...
*/
- for (i = atoi(count); i > 0; i -= bytes)
+ for (total = (size_t)strtoll(count, NULL, 10); total > 0; total -= (size_t)bytes)
{
- if (i > sizeof(line))
- bytes = sizeof(line);
+ if (total > sizeof(line))
+ bytes = (ssize_t)sizeof(line);
else
- bytes = i;
+ bytes = (ssize_t)total;
- if ((bytes = fread(line, 1, bytes, stdin)) > 0)
- bytes = write(fd, line, bytes);
+ if ((bytes = (ssize_t)fread(line, 1, (size_t)bytes, stdin)) > 0)
+ bytes = write(fd, line, (size_t)bytes);
if (bytes < 1)
{
@@ -1116,7 +1123,7 @@ recv_print_job(
{
syslog(LOG_WARNING, "No username specified by client! "
"Using \"anonymous\"...");
- strcpy(user, "anonymous");
+ strlcpy(user, "anonymous", sizeof(user));
}
/*
@@ -1528,7 +1535,7 @@ send_state(const char *queue, /* I - Destination */
*/
if (jobstate == IPP_JOB_PROCESSING)
- strcpy(rankstr, "active");
+ strlcpy(rankstr, "active", sizeof(rankstr));
else
{
snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]);
@@ -1609,7 +1616,7 @@ smart_gets(char *s, /* I - Pointer to line buffer */
break;
}
else if (ptr < end)
- *ptr++ = ch;
+ *ptr++ = (char)ch;
}
*ptr = '\0';
@@ -1622,5 +1629,5 @@ smart_gets(char *s, /* I - Pointer to line buffer */
/*
- * End of "$Id: cups-lpd.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: cups-lpd.c 12611 2015-05-06 15:30:36Z msweet $".
*/
diff --git a/scheduler/cups.sh.in b/scheduler/cups.sh.in
index ff72c1c..c50e893 100644
--- a/scheduler/cups.sh.in
+++ b/scheduler/cups.sh.in
@@ -1,17 +1,17 @@
#!/bin/sh
#
-# "$Id: cups.sh.in 11173 2013-07-23 12:31:34Z msweet $"
+# "$Id: cups.sh.in 11342 2013-10-18 20:36:01Z msweet $"
#
-# Startup/shutdown script for CUPS.
+# Startup/shutdown script for CUPS.
#
-# Copyright 2007-2011 by Apple Inc.
-# Copyright 1997-2007 by Easy Software Products, all rights reserved.
+# 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/".
+# 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/".
#
#### OS-Dependent Information
@@ -35,18 +35,6 @@
#### OS-Dependent Configuration
case "`uname`" in
- IRIX*)
- IS_ON=/sbin/chkconfig
-
- if $IS_ON verbose; then
- ECHO=echo
- else
- ECHO=:
- fi
- ECHO_OK=:
- ECHO_ERROR=:
- ;;
-
*BSD*)
IS_ON=:
ECHO=echo
@@ -127,8 +115,7 @@ unset TMPDIR
#
# Make sure we have the standard program directories in the path
-# since some operating systems (this means YOU HP-UX!) don't
-# provide a standard path on boot-up...
+# since some operating systems don't provide a standard path on boot-up...
#
if test "x$PATH" = x; then
@@ -144,19 +131,9 @@ export PATH
#
case "`uname`" in
- HP-UX* | AIX* | SINIX*)
- pid=`ps -e | awk '{if (match($4, ".*/cupsd$") || $4 == "cupsd") print $1}'`
- ;;
- IRIX* | SunOS*)
+ SunOS*)
pid=`ps -e | nawk '{if (match($4, ".*/cupsd$") || $4 == "cupsd") print $1}'`
;;
- UnixWare*)
- pid=`ps -e | awk '{if (match($6, ".*/cupsd$") || $6 == "cupsd") print $1}'`
- . /etc/TIMEZONE
- ;;
- OSF1*)
- pid=`ps -e | awk '{if (match($5, ".*/cupsd$") || $5 == "cupsd") print $1}'`
- ;;
Linux* | *BSD* | Darwin*)
pid=`ps ax | awk '{if (match($5, ".*/cupsd$") || $5 == "cupsd") print $1}'`
;;
@@ -209,16 +186,6 @@ case $1 in
fi
;;
- start_msg)
- # HP-UX non-standard...
- echo "Starting CUPS Server"
- ;;
-
- stop_msg)
- # HP-UX non-standard...
- echo "Starting CUPS Server"
- ;;
-
*)
echo "Usage: cups {reload|restart|start|status|stop}"
exit 1
@@ -233,5 +200,5 @@ exit 0
#
-# End of "$Id: cups.sh.in 11173 2013-07-23 12:31:34Z msweet $".
+# End of "$Id: cups.sh.in 11342 2013-10-18 20:36:01Z msweet $".
#
diff --git a/scheduler/cups.xml.in b/scheduler/cups.xml.in
index b76ad02..ac63585 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 11173 2013-07-23 12:31:34Z msweet $
+ $Id: cups.xml.in 2309 2010-07-08 20:45:48Z msweet $
Service manifest for CUPS.
diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h
index 48ea1d7..f8b2c11 100644
--- a/scheduler/cupsd.h
+++ b/scheduler/cupsd.h
@@ -1,16 +1,16 @@
/*
- * "$Id: cupsd.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: cupsd.h 11717 2014-03-21 16:42:53Z msweet $"
*
- * Main header file for the CUPS scheduler.
+ * Main header file for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * "LICENSE" which should have been included with this file. If this
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*/
@@ -144,10 +144,8 @@ typedef void (*cupsd_selfunc_t)(void *data);
* Globals...
*/
-VAR int TestConfigFile VALUE(0),
+VAR int TestConfigFile VALUE(0);
/* Test the cupsd.conf file? */
- UseProfiles VALUE(1);
- /* Use security profiles for child procs? */
VAR int MaxFDs VALUE(0);
/* Maximum number of files */
@@ -160,10 +158,10 @@ VAR int NeedReload VALUE(RELOAD_ALL),
VAR void *DefaultProfile VALUE(0);
/* Default security profile */
-#ifdef HAVE_LAUNCH_H
-VAR int Launchd VALUE(0);
- /* Running from launchd */
-#endif /* HAVE_LAUNCH_H */
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+VAR int OnDemand VALUE(0);
+ /* Launched on demand */
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
/*
@@ -187,6 +185,7 @@ extern cups_file_t *cupsdCreateConfFile(const char *filename, mode_t mode);
extern cups_file_t *cupsdOpenConfFile(const char *filename);
extern int cupsdOpenPipe(int *fds);
extern int cupsdRemoveFile(const char *filename);
+extern int cupsdUnlinkOrRemoveFile(const char *filename);
/* main.c */
extern int cupsdAddString(cups_array_t **a, const char *s);
@@ -202,11 +201,10 @@ extern void cupsdSetStringf(char **s, const char *f, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
/* process.c */
-extern void *cupsdCreateProfile(int job_id);
+extern void *cupsdCreateProfile(int job_id, int allow_networking);
extern void cupsdDestroyProfile(void *profile);
extern int cupsdEndProcess(int pid, int force);
-extern const char *cupsdFinishProcess(int pid, char *name, int namelen,
- int *job_id);
+extern const char *cupsdFinishProcess(int pid, char *name, size_t namelen, int *job_id);
extern int cupsdStartProcess(const char *command, char *argv[],
char *envp[], int infd, int outfd,
int errfd, int backfd, int sidefd,
@@ -230,5 +228,5 @@ extern void cupsdStopServer(void);
/*
- * End of "$Id: cupsd.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: cupsd.h 11717 2014-03-21 16:42:53Z msweet $".
*/
diff --git a/scheduler/cupsfilter.c b/scheduler/cupsfilter.c
index 4b471d5..81e159d 100644
--- a/scheduler/cupsfilter.c
+++ b/scheduler/cupsfilter.c
@@ -1,34 +1,16 @@
/*
- * "$Id: cupsfilter.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: cupsfilter.c 12304 2014-12-09 16:16:28Z msweet $"
*
- * Filtering program for CUPS.
+ * Filtering program for CUPS.
*
- * Copyright 2007-2013 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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() - Main entry for the test program.
- * add_printer_filter() - Add a single filters from a PPD file.
- * add_printer_filters() - Add filters from a PPD file.
- * check_cb() - Callback function for _cupsFileCheck.
- * compare_pids() - Compare two filter PIDs...
- * escape_options() - Convert an options array to a string.
- * exec_filter() - Execute a single filter.
- * exec_filters() - Execute filters for the given file and options.
- * get_job_file() - Get the specified job file.
- * open_pipe() - Create a pipe which is closed on exec.
- * read_cupsd_conf() - Read the cupsd.conf file to get the filter
- * settings.
- * set_string() - Copy and set a string.
- * sighandler() - Signal catcher for when we print from stdin...
- * usage() - Show program usage...
+ * 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/".
*/
/*
@@ -99,7 +81,7 @@ static int exec_filters(mime_type_t *srctype,
cups_option_t *options);
static void get_job_file(const char *job);
static int open_pipe(int *fds);
-static int read_cupsd_conf(const char *filename);
+static int read_cups_files_conf(const char *filename);
static void set_string(char **s, const char *val);
static void sighandler(int sig);
static void usage(const char *opt) __attribute__((noreturn));
@@ -113,7 +95,8 @@ int /* O - Exit status */
main(int argc, /* I - Number of command-line args */
char *argv[]) /* I - Command-line arguments */
{
- int i; /* Looping vars */
+ int i, /* Looping vars */
+ list_filters = 0; /* Just list the filters? */
const char *command, /* Command name */
*opt, /* Current option */
*printer; /* Printer name */
@@ -129,7 +112,7 @@ main(int argc, /* I - Number of command-line args */
char mimedir[1024]; /* MIME directory */
char *infile, /* File to filter */
*outfile; /* File to create */
- char cupsdconf[1024]; /* cupsd.conf file */
+ char cupsfilesconf[1024]; /* cups-files.conf file */
const char *server_root; /* CUPS_SERVERROOT environment variable */
mime_type_t *src, /* Source type */
*dst; /* Destination type */
@@ -173,7 +156,7 @@ main(int argc, /* I - Number of command-line args */
if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
server_root = CUPS_SERVERROOT;
- snprintf(cupsdconf, sizeof(cupsdconf), "%s/cupsd.conf", server_root);
+ snprintf(cupsfilesconf, sizeof(cupsfilesconf), "%s/cups-files.conf", server_root);
/*
* Process command-line arguments...
@@ -182,168 +165,175 @@ main(int argc, /* I - Number of command-line args */
_cupsSetLocale(argv);
for (i = 1; i < argc; i ++)
+ {
if (argv[i][0] == '-')
{
- for (opt = argv[i] + 1; *opt; opt ++)
- switch (*opt)
+ if (!strcmp(argv[i], "--list-filters"))
+ {
+ list_filters = 1;
+ }
+ else if (!strcmp(argv[i], "--"))
+ {
+ i ++;
+ if (i < argc && !infile)
+ infile = argv[i];
+ else
+ usage(NULL);
+ }
+ else
+ {
+ for (opt = argv[i] + 1; *opt; opt ++)
{
- case '-' : /* Next argument is a filename... */
- i ++;
- if (i < argc && !infile)
- infile = argv[i];
- else
- usage(opt);
- break;
-
- case 'a' : /* Specify option... */
- i ++;
- if (i < argc)
- num_options = cupsParseOptions(argv[i], num_options, &options);
- else
- usage(opt);
- break;
-
- case 'c' : /* Specify cupsd.conf file location... */
- i ++;
- if (i < argc)
- {
- if (!strcmp(command, "convert"))
- num_options = cupsAddOption("copies", argv[i], num_options,
- &options);
+ switch (*opt)
+ {
+ case 'a' : /* Specify option... */
+ i ++;
+ if (i < argc)
+ num_options = cupsParseOptions(argv[i], num_options, &options);
else
- strlcpy(cupsdconf, argv[i], sizeof(cupsdconf));
- }
- else
- usage(opt);
- break;
-
- case 'd' : /* Specify the real printer name */
- i ++;
- if (i < argc)
- printer = argv[i];
- else
- usage(opt);
- break;
-
- case 'D' : /* Delete input file after conversion */
- removeinfile = 1;
- break;
-
- case 'e' : /* Use every filter from the PPD file */
- all_filters = 1;
- break;
-
- case 'f' : /* Specify input file... */
- i ++;
- if (i < argc && !infile)
- infile = argv[i];
- else
- usage(opt);
- break;
-
- case 'i' : /* Specify source MIME type... */
- i ++;
- if (i < argc)
- {
- if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2)
usage(opt);
+ break;
- srctype = argv[i];
- }
- else
- usage(opt);
- break;
+ case 'c' : /* Specify cups-files.conf file location... */
+ i ++;
+ if (i < argc)
+ {
+ if (!strcmp(command, "convert"))
+ num_options = cupsAddOption("copies", argv[i], num_options, &options);
+ else
+ strlcpy(cupsfilesconf, argv[i], sizeof(cupsfilesconf));
+ }
+ else
+ usage(opt);
+ break;
- case 'j' : /* Get job file or specify destination MIME type... */
- if (strcmp(command, "convert"))
- {
- i ++;
+ case 'd' : /* Specify the real printer name */
+ i ++;
+ if (i < argc)
+ printer = argv[i];
+ else
+ usage(opt);
+ break;
+
+ case 'D' : /* Delete input file after conversion */
+ removeinfile = 1;
+ break;
+
+ case 'e' : /* Use every filter from the PPD file */
+ all_filters = 1;
+ break;
+
+ case 'f' : /* Specify input file... */
+ i ++;
+ if (i < argc && !infile)
+ infile = argv[i];
+ else
+ usage(opt);
+ break;
+
+ case 'i' : /* Specify source MIME type... */
+ i ++;
if (i < argc)
{
- get_job_file(argv[i]);
- infile = TempFile;
+ if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2)
+ usage(opt);
+
+ srctype = argv[i];
}
else
usage(opt);
+ break;
+
+ case 'j' : /* Get job file or specify destination MIME type... */
+ if (strcmp(command, "convert"))
+ {
+ i ++;
+ if (i < argc)
+ {
+ get_job_file(argv[i]);
+ infile = TempFile;
+ }
+ else
+ usage(opt);
- break;
- }
+ break;
+ }
+
+ case 'm' : /* Specify destination MIME type... */
+ i ++;
+ if (i < argc)
+ {
+ if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2)
+ usage(opt);
- case 'm' : /* Specify destination MIME type... */
- i ++;
- if (i < argc)
- {
- if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2)
+ dsttype = argv[i];
+ }
+ else
usage(opt);
+ break;
- dsttype = argv[i];
- }
- else
- usage(opt);
- break;
-
- case 'n' : /* Specify number of copies... */
- i ++;
- if (i < argc)
- num_options = cupsAddOption("copies", argv[i], num_options,
- &options);
- else
- usage(opt);
- break;
-
- case 'o' : /* Specify option(s) or output filename */
- i ++;
- if (i < argc)
- {
- if (!strcmp(command, "convert"))
+ case 'n' : /* Specify number of copies... */
+ i ++;
+ if (i < argc)
+ num_options = cupsAddOption("copies", argv[i], num_options, &options);
+ else
+ usage(opt);
+ break;
+
+ case 'o' : /* Specify option(s) or output filename */
+ i ++;
+ if (i < argc)
{
- if (outfile)
- usage(NULL);
+ if (!strcmp(command, "convert"))
+ {
+ if (outfile)
+ usage(NULL);
+ else
+ outfile = argv[i];
+ }
else
- outfile = argv[i];
+ num_options = cupsParseOptions(argv[i], num_options, &options);
}
else
- num_options = cupsParseOptions(argv[i], num_options,
- &options);
- }
- else
- usage(opt);
- break;
-
- case 'p' : /* Specify PPD file... */
- case 'P' : /* Specify PPD file... */
- i ++;
- if (i < argc)
- ppdfile = argv[i];
- else
- usage(opt);
- break;
-
- case 't' : /* Specify title... */
- case 'J' : /* Specify title... */
- i ++;
- if (i < argc)
- title = argv[i];
- else
- usage(opt);
- break;
-
- case 'u' : /* Delete PPD file after conversion */
- removeppd = 1;
- break;
-
- case 'U' : /* Specify username... */
- i ++;
- if (i < argc)
- user = argv[i];
- else
- usage(opt);
- break;
-
- default : /* Something we don't understand... */
- usage(opt);
- break;
+ usage(opt);
+ break;
+
+ case 'p' : /* Specify PPD file... */
+ case 'P' : /* Specify PPD file... */
+ i ++;
+ if (i < argc)
+ ppdfile = argv[i];
+ else
+ usage(opt);
+ break;
+
+ case 't' : /* Specify title... */
+ case 'J' : /* Specify title... */
+ i ++;
+ if (i < argc)
+ title = argv[i];
+ else
+ usage(opt);
+ break;
+
+ case 'u' : /* Delete PPD file after conversion */
+ removeppd = 1;
+ break;
+
+ case 'U' : /* Specify username... */
+ i ++;
+ if (i < argc)
+ user = argv[i];
+ else
+ usage(opt);
+ break;
+
+ default : /* Something we don't understand... */
+ usage(opt);
+ break;
+ }
}
+ }
}
else if (!infile)
{
@@ -358,6 +348,7 @@ main(int argc, /* I - Number of command-line args */
_("cupsfilter: Only one filename can be specified."));
usage(NULL);
}
+ }
if (!infile && !srctype)
usage(NULL);
@@ -373,10 +364,10 @@ main(int argc, /* I - Number of command-line args */
}
/*
- * Load the cupsd.conf file and create the MIME database...
+ * Load the cups-files.conf file and create the MIME database...
*/
- if (read_cupsd_conf(cupsdconf))
+ if (read_cups_files_conf(cupsfilesconf))
return (1);
snprintf(mimedir, sizeof(mimedir), "%s/mime", DataDir);
@@ -491,12 +482,31 @@ main(int argc, /* I - Number of command-line args */
filters = prefilters;
}
- /*
- * Do it!
- */
+ if (list_filters)
+ {
+ /*
+ * List filters...
+ */
+
+ mime_filter_t *filter; /* Current filter */
- status = exec_filters(src, filters, infile, outfile, ppdfile, printer, user,
- title, num_options, options);
+ for (filter = (mime_filter_t *)cupsArrayFirst(filters);
+ filter;
+ filter = (mime_filter_t *)cupsArrayNext(filters))
+ if (strcmp(filter->filter, "-"))
+ _cupsLangPuts(stdout, filter->filter);
+
+ status = 0;
+ }
+ else
+ {
+ /*
+ * Run filters...
+ */
+
+ status = exec_filters(src, filters, infile, outfile, ppdfile, printer, user,
+ title, num_options, options);
+ }
/*
* Remove files as needed, then exit...
@@ -576,7 +586,7 @@ add_printer_filter(
{
char *ptr; /* Pointer into maxsize(nnnn) program */
- maxsize = strtoll(program + 8, &ptr, 10);
+ maxsize = (size_t)strtoll(program + 8, &ptr, 10);
if (*ptr != ')')
{
@@ -745,7 +755,7 @@ escape_options(
{
int i; /* Looping var */
cups_option_t *option; /* Current option */
- int bytes; /* Number of bytes needed */
+ size_t bytes; /* Number of bytes needed */
char *s, /* Option string */
*sptr, /* Pointer into string */
*vptr; /* Pointer into value */
@@ -773,7 +783,7 @@ escape_options(
if (sptr > s)
*sptr++ = ' ';
- strcpy(sptr, option->name);
+ strlcpy(sptr, option->name, bytes - (size_t)(sptr - s));
sptr += strlen(sptr);
*sptr++ = '=';
@@ -917,7 +927,7 @@ exec_filters(mime_type_t *srctype, /* I - Source type */
{
int i; /* Looping var */
const char *argv[8], /* Command-line arguments */
- *envp[16], /* Environment variables */
+ *envp[17], /* Environment variables */
*temp; /* Temporary string */
char *optstr, /* Filter options */
content_type[1024], /* CONTENT_TYPE */
@@ -925,6 +935,8 @@ exec_filters(mime_type_t *srctype, /* I - Source type */
cups_fontpath[1024], /* CUPS_FONTPATH */
cups_serverbin[1024], /* CUPS_SERVERBIN */
cups_serverroot[1024], /* CUPS_SERVERROOT */
+ final_content_type[1024] = "",
+ /* FINAL_CONTENT_TYPE */
lang[1024], /* LANG */
path[1024], /* PATH */
ppd[1024], /* PPD */
@@ -948,6 +960,39 @@ exec_filters(mime_type_t *srctype, /* I - Source type */
/*
+ * Figure out the final content type...
+ */
+
+ for (filter = (mime_filter_t *)cupsArrayLast(filters);
+ filter && filter->dst;
+ filter = (mime_filter_t *)cupsArrayPrev(filters))
+ if (strcmp(filter->dst->super, "printer"))
+ break;
+
+ if (filter && filter->dst)
+ {
+ const char *ptr; /* Pointer in type name */
+
+ 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...
+ */
+
+ for (filter = (mime_filter_t *)cupsArrayFirst(filters);
+ filter;
+ filter = (mime_filter_t *)cupsArrayNext(filters))
+ if (!strcmp(filter->filter, "-"))
+ cupsArrayRemove(filters, filter);
+
+ /*
* Setup the filter environment and command-line...
*/
@@ -1041,7 +1086,13 @@ exec_filters(mime_type_t *srctype, /* I - Source type */
envp[12] = rip_max_cache;
envp[13] = userenv;
envp[14] = "CHARSET=utf-8";
- envp[15] = NULL;
+ if (final_content_type[0])
+ {
+ envp[15] = final_content_type;
+ envp[16] = NULL;
+ }
+ else
+ envp[15] = NULL;
for (i = 0; argv[i]; i ++)
fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);
@@ -1313,13 +1364,14 @@ open_pipe(int *fds) /* O - Pipe file descriptors (2) */
/*
- * 'read_cupsd_conf()' - Read the cupsd.conf file to get the filter settings.
+ * 'read_cups_files_conf()' - Read the cups-files.conf file to get the filter settings.
*/
static int /* O - 0 on success, 1 on error */
-read_cupsd_conf(const char *filename) /* I - File to read */
+read_cups_files_conf(
+ const char *filename) /* I - File to read */
{
- cups_file_t *fp; /* cupsd.conf file */
+ cups_file_t *fp; /* cups-files.conf file */
const char *temp; /* Temporary string */
char line[1024], /* Line from file */
*ptr; /* Pointer into line */
@@ -1372,9 +1424,7 @@ read_cupsd_conf(const char *filename) /* I - File to read */
cupsFileClose(fp);
}
- snprintf(line, sizeof(line),
- "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR ":/bin:/usr/bin",
- ServerBin);
+ snprintf(line, sizeof(line), "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR ":/bin:/usr/bin", ServerBin);
set_string(&Path, line);
return (0);
@@ -1426,38 +1476,30 @@ static void
usage(const char *opt) /* I - Incorrect option, if any */
{
if (opt)
- _cupsLangPrintf(stderr, _("%s: Unknown option \"%c\"."), "cupsfilter",
- *opt);
+ _cupsLangPrintf(stderr, _("%s: Unknown option \"%c\"."), "cupsfilter", *opt);
- _cupsLangPuts(stdout, _("Usage: cupsfilter [ options ] filename"));
+ _cupsLangPuts(stdout, _("Usage: cupsfilter [ options ] [ -- ] filename"));
_cupsLangPuts(stdout, _("Options:"));
- _cupsLangPuts(stdout, _(" -D Remove the input file "
- "when finished."));
+ _cupsLangPuts(stdout, _(" --list-filters List filters that will be used."));
+ _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, _(" -c cups-files.conf Set cups-files.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."));
+ _cupsLangPuts(stdout, _(" -u Remove the PPD file when finished."));
exit(1);
}
/*
- * End of "$Id: cupsfilter.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: cupsfilter.c 12304 2014-12-09 16:16:28Z msweet $".
*/
diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c
index bce0d64..54a08e2 100644
--- a/scheduler/dirsvc.c
+++ b/scheduler/dirsvc.c
@@ -1,46 +1,16 @@
/*
- * "$Id: dirsvc.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: dirsvc.c 12458 2015-01-30 16:15:53Z msweet $"
*
- * Directory services routines for the CUPS scheduler.
+ * Directory services routines for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 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:
- *
- * 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.
+ * 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/".
*/
/*
@@ -58,6 +28,15 @@
/*
+ * Local globals...
+ */
+
+#ifdef HAVE_AVAHI
+static int avahi_running = 0;
+#endif /* HAVE_AVAHI */
+
+
+/*
* Local functions...
*/
@@ -78,11 +57,15 @@ 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);
+# ifdef HAVE_AVAHI
+static void dnssdClientCallback(AvahiClient *c, AvahiClientState state, void *userdata);
+# endif /* HAVE_AVAHI */
+static void dnssdDeregisterAllPrinters(int from_callback);
+static void dnssdDeregisterInstance(cupsd_srv_t *srv, int from_callback);
+static void dnssdDeregisterPrinter(cupsd_printer_t *p, int clear_name, int from_callback);
static const char *dnssdErrorString(int error);
static void dnssdFreeTxtRecord(cupsd_txt_t *txt);
+static void dnssdRegisterAllPrinters(int from_callback);
# ifdef HAVE_DNSSD
static void dnssdRegisterCallback(DNSServiceRef sdRef,
DNSServiceFlags flags,
@@ -96,16 +79,13 @@ 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 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, int from_callback);
+static void dnssdRegisterPrinter(cupsd_printer_t *p, int from_callback);
static void dnssdStop(void);
# ifdef HAVE_DNSSD
static void dnssdUpdate(void);
# endif /* HAVE_DNSSD */
+static void dnssdUpdateDNSSDName(int from_callback);
#endif /* HAVE_DNSSD || HAVE_AVAHI */
@@ -138,7 +118,7 @@ cupsdDeregisterPrinter(
#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
- dnssdDeregisterPrinter(p, 1);
+ dnssdDeregisterPrinter(p, 1, 0);
#endif /* HAVE_DNSSD || HAVE_AVAHI */
}
@@ -160,7 +140,7 @@ cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
- dnssdRegisterPrinter(p);
+ dnssdRegisterPrinter(p, 0);
#endif /* HAVE_DNSSD || HAVE_AVAHI */
}
@@ -172,16 +152,12 @@ cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
void
cupsdStartBrowsing(void)
{
- cupsd_printer_t *p; /* Current printer */
-
-
if (!Browsing || !BrowseLocalProtocols)
return;
#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
if (BrowseLocalProtocols & BROWSE_DNSSD)
{
- cupsd_listener_t *lis; /* Current listening socket */
# ifdef HAVE_DNSSD
DNSServiceErrorType error; /* Error from service creation */
@@ -211,6 +187,13 @@ cupsdStartBrowsing(void)
cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
}
+ /*
+ * Set the computer name and register the web interface...
+ */
+
+ DNSSDPort = 0;
+ cupsdUpdateDNSSDName();
+
# else /* HAVE_AVAHI */
if ((DNSSDMaster = avahi_threaded_poll_new()) == NULL)
{
@@ -223,8 +206,7 @@ cupsdStartBrowsing(void)
{
int error; /* Error code, if any */
- DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), 0,
- NULL, NULL, &error);
+ DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), AVAHI_CLIENT_NO_FAIL, dnssdClientCallback, NULL, &error);
if (DNSSDClient == NULL)
{
@@ -242,31 +224,6 @@ cupsdStartBrowsing(void)
avahi_threaded_poll_start(DNSSDMaster);
}
# endif /* HAVE_DNSSD */
-
- /*
- * 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;
-
- DNSSDPort = _httpAddrPort(&(lis->address));
- break;
- }
-
- /*
- * Set the computer name and register the web interface...
- */
-
- cupsdUpdateDNSSDName();
}
#endif /* HAVE_DNSSD || HAVE_AVAHI */
@@ -280,15 +237,13 @@ cupsdStartBrowsing(void)
if (BrowseLocalProtocols & BROWSE_SMB)
update_smb(1);
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
/*
* Register the individual printers
*/
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
- cupsdRegisterPrinter(p);
+ dnssdRegisterAllPrinters(0);
+#endif /* HAVE_DNSSD || HAVE_AVAHI */
}
@@ -299,27 +254,20 @@ cupsdStartBrowsing(void)
void
cupsdStopBrowsing(void)
{
- cupsd_printer_t *p; /* Current printer */
-
-
if (!Browsing || !BrowseLocalProtocols)
return;
+#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
/*
* De-register the individual printers
*/
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
- cupsdDeregisterPrinter(p, 1);
+ dnssdDeregisterAllPrinters(0);
/*
* Shut down browsing sockets...
*/
-#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
dnssdStop();
#endif /* HAVE_DNSSD || HAVE_AVAHI */
@@ -344,161 +292,7 @@ cupsdStopBrowsing(void)
void
cupsdUpdateDNSSDName(void)
{
- char webif[1024]; /* Web interface share name */
-# 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 /* __APPLE__ */
-
-
- /*
- * Only share the web interface and printers when non-local listening is
- * enabled...
- */
-
- if (!DNSSDPort)
- return;
-
- /*
- * Get the computer name as a c-string...
- */
-
-# ifdef __APPLE__
- sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL);
-
- if (sc)
- {
- /*
- * Get the computer name from the dynamic store...
- */
-
- cupsdClearString(&DNSSDComputerName);
-
- if ((nameRef = SCDynamicStoreCopyComputerName(sc, &nameEncoding)) != NULL)
- {
- if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
- kCFStringEncodingUTF8))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Dynamic store computer name is \"%s\".", nameBuffer);
- cupsdSetString(&DNSSDComputerName, nameBuffer);
- }
-
- CFRelease(nameRef);
- }
-
- if (!DNSSDComputerName)
- {
- /*
- * Use the ServerName instead...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Using ServerName \"%s\" as computer name.", ServerName);
- cupsdSetString(&DNSSDComputerName, ServerName);
- }
-
- /*
- * Get the local hostname from the dynamic store...
- */
-
- cupsdClearString(&DNSSDHostName);
-
- if ((nameRef = SCDynamicStoreCopyLocalHostName(sc)) != NULL)
- {
- if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
- kCFStringEncodingUTF8))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Dynamic store host name is \"%s\".", nameBuffer);
- cupsdSetString(&DNSSDHostName, nameBuffer);
- }
-
- CFRelease(nameRef);
- }
-
- if (!DNSSDHostName)
- {
- /*
- * Use the ServerName instead...
- */
-
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Using ServerName \"%s\" as host name.", ServerName);
- cupsdSetString(&DNSSDHostName, ServerName);
- }
-
- /*
- * Get any Back-to-My-Mac domains and add them as aliases...
- */
-
- cupsdFreeAliases(DNSSDAlias);
- DNSSDAlias = NULL;
-
- btmm = SCDynamicStoreCopyValue(sc, CFSTR("Setup:/Network/BackToMyMac"));
- if (btmm && CFGetTypeID(btmm) == CFDictionaryGetTypeID())
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG, "%d Back to My Mac aliases to add.",
- (int)CFDictionaryGetCount(btmm));
- CFDictionaryApplyFunction(btmm, dnssdAddAlias, NULL);
- }
- else if (btmm)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Bad Back to My Mac data in dynamic store!");
- else
- cupsdLogMessage(CUPSD_LOG_DEBUG, "No Back to My Mac aliases to add.");
-
- if (btmm)
- CFRelease(btmm);
-
- CFRelease(sc);
- }
- else
-# endif /* __APPLE__ */
-# ifdef HAVE_AVAHI
- if (DNSSDClient)
- {
- const char *host_name = avahi_client_get_host_name(DNSSDClient);
- const char *host_fqdn = avahi_client_get_host_name_fqdn(DNSSDClient);
-
- cupsdSetString(&DNSSDComputerName, host_name ? host_name : ServerName);
-
- if (host_fqdn)
- cupsdSetString(&DNSSDHostName, host_fqdn);
- else if (strchr(ServerName, '.'))
- cupsdSetString(&DNSSDHostName, ServerName);
- else
- cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
- }
- else
-# endif /* HAVE_AVAHI */
- {
- cupsdSetString(&DNSSDComputerName, ServerName);
-
- if (strchr(ServerName, '.'))
- cupsdSetString(&DNSSDHostName, ServerName);
- else
- cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
- }
-
- /*
- * Then (re)register the web interface if enabled...
- */
-
- if (BrowseWebIF)
- {
- if (DNSSDComputerName)
- snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDComputerName);
- else
- strlcpy(webif, "CUPS", sizeof(webif));
-
- dnssdDeregisterInstance(&WebIFSrv);
- dnssdRegisterInstance(&WebIFSrv, NULL, webif, "_http._tcp", "_printer",
- DNSSDPort, NULL, 1);
- }
+ dnssdUpdateDNSSDName(0);
}
@@ -639,7 +433,9 @@ dnssdBuildTxtRecord(
if (p->type & CUPS_PRINTER_FAX)
{
keyvalue[count ][0] = "Fax";
- keyvalue[count++][1] = (p->type & CUPS_PRINTER_FAX) ? "T" : "F";
+ keyvalue[count++][1] = "T";
+ keyvalue[count ][0] = "rfo";
+ keyvalue[count++][1] = rp_str;
}
if (p->type & CUPS_PRINTER_COLOR)
@@ -731,24 +527,158 @@ dnssdBuildTxtRecord(
}
+# ifdef HAVE_AVAHI
+/*
+ * 'dnssdClientCallback()' - Client callback for Avahi.
+ *
+ * Called whenever the client or server state changes...
+ */
+
+static void
+dnssdClientCallback(
+ AvahiClient *c, /* I - Client */
+ AvahiClientState state, /* I - Current state */
+ void *userdata) /* I - User data (unused) */
+{
+ int error; /* Error code, if any */
+
+
+ (void)userdata;
+
+ if (!c)
+ return;
+
+ /*
+ * Make sure DNSSDClient is already set also if this callback function is
+ * already running before avahi_client_new() in dnssdStartBrowsing()
+ * finishes.
+ */
+
+ if (!DNSSDClient)
+ DNSSDClient = c;
+
+ switch (state)
+ {
+ case AVAHI_CLIENT_S_REGISTERING:
+ case AVAHI_CLIENT_S_RUNNING:
+ case AVAHI_CLIENT_S_COLLISION:
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Avahi server connection now available, registering printers for Bonjour broadcasting.");
+
+ /*
+ * Mark that Avahi server is running...
+ */
+
+ avahi_running = 1;
+
+ /*
+ * Set the computer name and register the web interface...
+ */
+
+ DNSSDPort = 0;
+ dnssdUpdateDNSSDName(1);
+
+ /*
+ * Register the individual printers
+ */
+
+ dnssdRegisterAllPrinters(1);
+ break;
+
+ case AVAHI_CLIENT_FAILURE:
+ if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Avahi server disappeared, unregistering printers for Bonjour broadcasting.");
+
+ /*
+ * Unregister everything and close the client...
+ */
+
+ dnssdDeregisterAllPrinters(1);
+ dnssdDeregisterInstance(&WebIFSrv, 1);
+ avahi_client_free(DNSSDClient);
+ DNSSDClient = NULL;
+
+ /*
+ * Mark that Avahi server is not running...
+ */
+
+ avahi_running = 0;
+
+ /*
+ * Renew Avahi client...
+ */
+
+ DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), AVAHI_CLIENT_NO_FAIL, dnssdClientCallback, NULL, &error);
+
+ if (!DNSSDClient)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to communicate with avahi-daemon: %s", dnssdErrorString(error));
+ if (FatalErrors & CUPSD_FATAL_BROWSE)
+ cupsdEndProcess(getpid(), 0);
+ }
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Communication with avahi-daemon has failed: %s", avahi_strerror(avahi_client_errno(c)));
+ if (FatalErrors & CUPSD_FATAL_BROWSE)
+ cupsdEndProcess(getpid(), 0);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+# endif /* HAVE_AVAHI */
+
+
+/*
+ * 'dnssdDeregisterAllPrinters()' - Deregister all printers.
+ */
+
+static void
+dnssdDeregisterAllPrinters(
+ int from_callback) /* I - Deregistering because of callback? */
+{
+ cupsd_printer_t *p; /* Current printer */
+
+
+ if (!DNSSDMaster)
+ return;
+
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
+ p;
+ p = (cupsd_printer_t *)cupsArrayNext(Printers))
+ if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
+ dnssdDeregisterPrinter(p, 1, from_callback);
+}
+
+
/*
* 'dnssdDeregisterInstance()' - Deregister a DNS-SD service instance.
*/
static void
dnssdDeregisterInstance(
- cupsd_srv_t *srv) /* I - Service */
+ cupsd_srv_t *srv, /* I - Service */
+ int from_callback) /* I - Called from callback? */
{
if (!srv || !*srv)
return;
# ifdef HAVE_DNSSD
+ (void)from_callback;
+
DNSServiceRefDeallocate(*srv);
# else /* HAVE_AVAHI */
- avahi_threaded_poll_lock(DNSSDMaster);
+ if (!from_callback)
+ avahi_threaded_poll_lock(DNSSDMaster);
+
avahi_entry_group_free(*srv);
- avahi_threaded_poll_unlock(DNSSDMaster);
+
+ if (!from_callback)
+ avahi_threaded_poll_unlock(DNSSDMaster);
# endif /* HAVE_DNSSD */
*srv = NULL;
@@ -762,7 +692,8 @@ dnssdDeregisterInstance(
static void
dnssdDeregisterPrinter(
cupsd_printer_t *p, /* I - Printer */
- int clear_name) /* I - Clear the name? */
+ int clear_name, /* I - Clear the name? */
+ int from_callback) /* I - Called from callback? */
{
cupsdLogMessage(CUPSD_LOG_DEBUG2,
@@ -771,13 +702,13 @@ dnssdDeregisterPrinter(
if (p->ipp_srv)
{
- dnssdDeregisterInstance(&p->ipp_srv);
+ dnssdDeregisterInstance(&p->ipp_srv, from_callback);
# ifdef HAVE_DNSSD
# ifdef HAVE_SSL
- dnssdDeregisterInstance(&p->ipps_srv);
+ dnssdDeregisterInstance(&p->ipps_srv, from_callback);
# endif /* HAVE_SSL */
- dnssdDeregisterInstance(&p->printer_srv);
+ dnssdDeregisterInstance(&p->printer_srv, from_callback);
# endif /* HAVE_DNSSD */
}
@@ -929,6 +860,27 @@ dnssdFreeTxtRecord(cupsd_txt_t *txt) /* I - TXT record */
/*
+ * 'dnssdRegisterAllPrinters()' - Register all printers.
+ */
+
+static void
+dnssdRegisterAllPrinters(int from_callback) /* I - Called from callback? */
+{
+ cupsd_printer_t *p; /* Current printer */
+
+
+ if (!DNSSDMaster)
+ return;
+
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
+ p;
+ p = (cupsd_printer_t *)cupsArrayNext(Printers))
+ if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
+ dnssdRegisterPrinter(p, from_callback);
+}
+
+
+/*
* 'dnssdRegisterCallback()' - DNSServiceRegister callback.
*/
@@ -1008,15 +960,19 @@ dnssdRegisterInstance(
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? */
+ int commit, /* I - Commit registration? */
+ int from_callback) /* I - Called from callback? */
{
char temp[256], /* Temporary string */
*ptr; /* Pointer into string */
int error; /* Any error */
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Registering \"%s\" with DNS-SD type \"%s\".", name, type);
+# ifdef HAVE_DNSSD
+ (void)from_callback;
+# endif /* HAVE_DNSSD */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Registering \"%s\" with DNS-SD type \"%s\".", name, type);
if (p && !srv)
{
@@ -1043,13 +999,15 @@ dnssdRegisterInstance(
(void)commit;
# else /* HAVE_AVAHI */
- avahi_threaded_poll_lock(DNSSDMaster);
+ if (!from_callback)
+ avahi_threaded_poll_lock(DNSSDMaster);
if (!*srv)
*srv = avahi_entry_group_new(DNSSDClient, dnssdRegisterCallback, NULL);
if (!*srv)
{
- avahi_threaded_poll_unlock(DNSSDMaster);
+ if (!from_callback)
+ avahi_threaded_poll_unlock(DNSSDMaster);
cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
name, dnssdErrorString(avahi_client_errno(DNSSDClient)));
@@ -1166,7 +1124,8 @@ dnssdRegisterInstance(
name);
}
- avahi_threaded_poll_unlock(DNSSDMaster);
+ if (!from_callback)
+ avahi_threaded_poll_unlock(DNSSDMaster);
# endif /* HAVE_DNSSD */
if (error)
@@ -1188,7 +1147,9 @@ dnssdRegisterInstance(
*/
static void
-dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
+dnssdRegisterPrinter(
+ cupsd_printer_t *p, /* I - Printer */
+ int from_callback) /* I - Called from callback? */
{
char name[256]; /* Service name */
int printer_port; /* LPD port number */
@@ -1196,15 +1157,21 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
cupsd_txt_t ipp_txt, /* IPP(S) TXT record */
printer_txt; /* LPD TXT record */
+
cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
!p->ipp_srv ? "new" : "update");
+# ifdef HAVE_AVAHI
+ if (!avahi_running)
+ return;
+# endif /* HAVE_AVAHI */
+
/*
* Remove the current registrations if we have them and then return if
* per-printer sharing was just disabled...
*/
- dnssdDeregisterPrinter(p, 0);
+ dnssdDeregisterPrinter(p, 0, from_callback);
if (!p->shared)
return;
@@ -1247,13 +1214,11 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
else
printer_port = 0;
- status = dnssdRegisterInstance(NULL, p, name, "_printer._tcp", NULL,
- printer_port, &printer_txt, 0);
+ status = dnssdRegisterInstance(NULL, p, name, "_printer._tcp", NULL, printer_port, &printer_txt, 0, from_callback);
# ifdef HAVE_SSL
if (status)
- dnssdRegisterInstance(NULL, p, name, "_ipps._tcp", DNSSDSubTypes,
- DNSSDPort, &ipp_txt, 0);
+ dnssdRegisterInstance(NULL, p, name, "_ipps._tcp", DNSSDSubTypes, DNSSDPort, &ipp_txt, 0, from_callback);
# endif /* HAVE_SSL */
if (status)
@@ -1263,11 +1228,9 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
*/
if (p->type & CUPS_PRINTER_FAX)
- status = dnssdRegisterInstance(NULL, p, name, "_fax-ipp._tcp",
- DNSSDSubTypes, DNSSDPort, &ipp_txt, 1);
+ status = dnssdRegisterInstance(NULL, p, name, "_fax-ipp._tcp", DNSSDSubTypes, DNSSDPort, &ipp_txt, 1, from_callback);
else
- status = dnssdRegisterInstance(NULL, p, name, "_ipp._tcp", DNSSDSubTypes,
- DNSSDPort, &ipp_txt, 1);
+ status = dnssdRegisterInstance(NULL, p, name, "_ipp._tcp", DNSSDSubTypes, DNSSDPort, &ipp_txt, 1, from_callback);
}
dnssdFreeTxtRecord(&ipp_txt);
@@ -1289,13 +1252,13 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
* Registration failed for this printer...
*/
- dnssdDeregisterInstance(&p->ipp_srv);
+ dnssdDeregisterInstance(&p->ipp_srv, from_callback);
# ifdef HAVE_DNSSD
# ifdef HAVE_SSL
- dnssdDeregisterInstance(&p->ipps_srv);
+ dnssdDeregisterInstance(&p->ipps_srv, from_callback);
# endif /* HAVE_SSL */
- dnssdDeregisterInstance(&p->printer_srv);
+ dnssdDeregisterInstance(&p->printer_srv, from_callback);
# endif /* HAVE_DNSSD */
}
}
@@ -1318,13 +1281,13 @@ dnssdStop(void)
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
- dnssdDeregisterPrinter(p, 1);
+ dnssdDeregisterPrinter(p, 1, 0);
/*
* Shutdown the rest of the service refs...
*/
- dnssdDeregisterInstance(&WebIFSrv);
+ dnssdDeregisterInstance(&WebIFSrv, 0);
# ifdef HAVE_DNSSD
cupsdRemoveSelect(DNSServiceRefSockFD(DNSSDMaster));
@@ -1333,11 +1296,20 @@ dnssdStop(void)
DNSSDMaster = NULL;
# else /* HAVE_AVAHI */
- avahi_client_free(DNSSDClient);
- DNSSDClient = NULL;
+ if (DNSSDMaster)
+ avahi_threaded_poll_stop(DNSSDMaster);
- avahi_threaded_poll_free(DNSSDMaster);
- DNSSDMaster = NULL;
+ if (DNSSDClient)
+ {
+ avahi_client_free(DNSSDClient);
+ DNSSDClient = NULL;
+ }
+
+ if (DNSSDMaster)
+ {
+ avahi_threaded_poll_free(DNSSDMaster);
+ DNSSDMaster = NULL;
+ }
# endif /* HAVE_DNSSD */
cupsArrayDelete(DNSSDPrinters);
@@ -1370,6 +1342,191 @@ dnssdUpdate(void)
/*
+ * 'dnssdUpdateDNSSDName()' - Update the listen port, computer name, and web interface registration.
+ */
+
+static void
+dnssdUpdateDNSSDName(int from_callback) /* I - Called from callback? */
+{
+ char webif[1024]; /* Web interface share name */
+# 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 /* __APPLE__ */
+
+
+ /*
+ * Only share the web interface and printers when non-local listening is
+ * enabled...
+ */
+
+ if (!DNSSDPort)
+ {
+ /*
+ * 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...
+ */
+
+ cupsd_listener_t *lis; /* Current listening socket */
+
+ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
+ lis;
+ lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
+ {
+ if (httpAddrLocalhost(&(lis->address)))
+ continue;
+
+ DNSSDPort = httpAddrPort(&(lis->address));
+ break;
+ }
+ }
+
+ if (!DNSSDPort)
+ return;
+
+ /*
+ * Get the computer name as a c-string...
+ */
+
+# ifdef __APPLE__
+ sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL);
+
+ if (sc)
+ {
+ /*
+ * Get the computer name from the dynamic store...
+ */
+
+ cupsdClearString(&DNSSDComputerName);
+
+ if ((nameRef = SCDynamicStoreCopyComputerName(sc, &nameEncoding)) != NULL)
+ {
+ if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
+ kCFStringEncodingUTF8))
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Dynamic store computer name is \"%s\".", nameBuffer);
+ cupsdSetString(&DNSSDComputerName, nameBuffer);
+ }
+
+ CFRelease(nameRef);
+ }
+
+ if (!DNSSDComputerName)
+ {
+ /*
+ * Use the ServerName instead...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Using ServerName \"%s\" as computer name.", ServerName);
+ cupsdSetString(&DNSSDComputerName, ServerName);
+ }
+
+ /*
+ * Get the local hostname from the dynamic store...
+ */
+
+ cupsdClearString(&DNSSDHostName);
+
+ if ((nameRef = SCDynamicStoreCopyLocalHostName(sc)) != NULL)
+ {
+ if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
+ kCFStringEncodingUTF8))
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Dynamic store host name is \"%s\".", nameBuffer);
+ cupsdSetString(&DNSSDHostName, nameBuffer);
+ }
+
+ CFRelease(nameRef);
+ }
+
+ if (!DNSSDHostName)
+ {
+ /*
+ * Use the ServerName instead...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Using ServerName \"%s\" as host name.", ServerName);
+ cupsdSetString(&DNSSDHostName, ServerName);
+ }
+
+ /*
+ * Get any Back-to-My-Mac domains and add them as aliases...
+ */
+
+ cupsdFreeAliases(DNSSDAlias);
+ DNSSDAlias = NULL;
+
+ btmm = SCDynamicStoreCopyValue(sc, CFSTR("Setup:/Network/BackToMyMac"));
+ if (btmm && CFGetTypeID(btmm) == CFDictionaryGetTypeID())
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "%d Back to My Mac aliases to add.",
+ (int)CFDictionaryGetCount(btmm));
+ CFDictionaryApplyFunction(btmm, dnssdAddAlias, NULL);
+ }
+ else if (btmm)
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Bad Back to My Mac data in dynamic store!");
+ else
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "No Back to My Mac aliases to add.");
+
+ if (btmm)
+ CFRelease(btmm);
+
+ CFRelease(sc);
+ }
+ else
+# endif /* __APPLE__ */
+# ifdef HAVE_AVAHI
+ if (DNSSDClient)
+ {
+ const char *host_name = avahi_client_get_host_name(DNSSDClient);
+ const char *host_fqdn = avahi_client_get_host_name_fqdn(DNSSDClient);
+
+ cupsdSetString(&DNSSDComputerName, host_name ? host_name : ServerName);
+
+ if (host_fqdn)
+ cupsdSetString(&DNSSDHostName, host_fqdn);
+ else if (strchr(ServerName, '.'))
+ cupsdSetString(&DNSSDHostName, ServerName);
+ else
+ cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
+ }
+ else
+# endif /* HAVE_AVAHI */
+ {
+ cupsdSetString(&DNSSDComputerName, ServerName);
+
+ if (strchr(ServerName, '.'))
+ cupsdSetString(&DNSSDHostName, ServerName);
+ else
+ cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
+ }
+
+ /*
+ * Then (re)register the web interface if enabled...
+ */
+
+ if (BrowseWebIF)
+ {
+ if (DNSSDComputerName)
+ snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDComputerName);
+ else
+ strlcpy(webif, "CUPS", sizeof(webif));
+
+ dnssdDeregisterInstance(&WebIFSrv, from_callback);
+ dnssdRegisterInstance(&WebIFSrv, NULL, webif, "_http._tcp", "_printer", DNSSDPort, NULL, 1, from_callback);
+ }
+}
+
+
+/*
* 'get_auth_info_required()' - Get the auth-info-required value to advertise.
*/
@@ -1400,7 +1557,7 @@ get_auth_info_required(
if (i)
*bufptr++ = ',';
- strlcpy(bufptr, p->auth_info_required[i], bufsize - (bufptr - buffer));
+ strlcpy(bufptr, p->auth_info_required[i], bufsize - (size_t)(bufptr - buffer));
bufptr += strlen(bufptr);
}
@@ -1666,5 +1823,5 @@ update_smb(int onoff) /* I - 1 = turn on, 0 = turn off */
/*
- * End of "$Id: dirsvc.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: dirsvc.c 12458 2015-01-30 16:15:53Z msweet $".
*/
diff --git a/scheduler/dirsvc.h b/scheduler/dirsvc.h
index edc5ad3..1326f8a 100644
--- a/scheduler/dirsvc.h
+++ b/scheduler/dirsvc.h
@@ -1,5 +1,5 @@
/*
- * "$Id: dirsvc.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: dirsvc.h 10996 2013-05-29 11:51:34Z msweet $"
*
* Directory services definitions for the CUPS scheduler.
*
@@ -80,5 +80,5 @@ extern void cupsdUpdateDNSSDName(void);
/*
- * End of "$Id: dirsvc.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: dirsvc.h 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/env.c b/scheduler/env.c
index ba11aad..59eab27 100644
--- a/scheduler/env.c
+++ b/scheduler/env.c
@@ -1,27 +1,16 @@
/*
- * "$Id: env.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: env.c 12700 2015-06-08 18:32:35Z msweet $"
*
- * Environment management routines for the CUPS scheduler.
+ * Environment management routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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:
- *
- * cupsdInitEnv() - Initialize the current environment with standard
- * variables.
- * cupsdLoadEnv() - Copy common environment variables into an array.
- * cupsdSetEnv() - Set a common environment variable.
- * cupsdSetEnvf() - Set a formatted common environment variable.
- * cupsdUpdateEnv() - Update the environment for the configured directories.
- * clear_env() - Clear common environment variables.
- * find_env() - Find a common environment variable.
+ * 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/".
*/
/*
@@ -131,6 +120,13 @@ cupsdSetEnv(const char *name, /* I - Name of variable */
return;
/*
+ * Do not allow dynamic linker variables when running as root...
+ */
+
+ if (!RunUser && (!strncmp(name, "DYLD_", 5) || !strncmp(name, "LD_", 3)))
+ return;
+
+ /*
* See if this variable has already been defined...
*/
@@ -269,5 +265,5 @@ find_env(const char *name) /* I - Variable name */
/*
- * End of "$Id: env.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: env.c 12700 2015-06-08 18:32:35Z msweet $".
*/
diff --git a/scheduler/file.c b/scheduler/file.c
index 84ceef1..ae91b9e 100644
--- a/scheduler/file.c
+++ b/scheduler/file.c
@@ -1,28 +1,16 @@
/*
- * "$Id: file.c 11221 2013-08-06 16:16:01Z msweet $"
+ * "$Id: file.c 11594 2014-02-14 20:09:01Z msweet $"
*
- * File functions for the CUPS scheduler.
+ * File functions for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * "LICENSE" which should have been included with this file. If this
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * cupsdCleanFiles() - Clean out old files.
- * cupsdCloseCreatedConfFile() - Close a created configuration file and move
- * into place.
- * cupsdClosePipe() - Close a pipe as necessary.
- * cupsdCreateConfFile() - Create a configuration file safely.
- * cupsdOpenConfFile() - Open a configuration file.
- * cupsdOpenPipe() - Create a pipe which is closed on exec.
- * cupsdRemoveFile() - Remove a file using the 7-pass US DoD method.
- * overwrite_data() - Overwrite the data in a file.
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*/
/*
@@ -43,7 +31,7 @@ static int overwrite_data(int fd, const char *buffer, int bufsize,
/*
* 'cupsdCleanFiles()' - Clean out old files.
*/
-
+
void
cupsdCleanFiles(const char *path, /* I - Directory to clean */
const char *pattern) /* I - Filename pattern or NULL */
@@ -65,7 +53,7 @@ cupsdCleanFiles(const char *path, /* I - Directory to clean */
return;
}
- cupsdLogMessage(CUPSD_LOG_INFO, "Cleaning out old files in \"%s\"...", path);
+ cupsdLogMessage(CUPSD_LOG_INFO, "Cleaning out old files in \"%s\".", path);
while ((dent = cupsDirRead(dir)) != NULL)
{
@@ -81,13 +69,11 @@ cupsdCleanFiles(const char *path, /* I - Directory to clean */
status = rmdir(filename);
}
else
- status = unlink(filename);
+ status = cupsdUnlinkOrRemoveFile(filename);
if (status)
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to remove \"%s\" - %s", filename,
strerror(errno));
- else
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Removed \"%s\"...", filename);
}
cupsDirClose(dir);
@@ -146,7 +132,7 @@ cupsdCloseCreatedConfFile(
snprintf(newfile, sizeof(newfile), "%s.N", filename);
snprintf(oldfile, sizeof(oldfile), "%s.O", filename);
- if ((cupsdRemoveFile(oldfile) && errno != ENOENT) ||
+ if ((cupsdUnlinkOrRemoveFile(oldfile) && errno != ENOENT) ||
(rename(filename, oldfile) && errno != ENOENT) ||
rename(newfile, filename))
{
@@ -308,14 +294,27 @@ cupsdOpenPipe(int *fds) /* O - Pipe file descriptors (2) */
/*
- * 'cupsdRemoveFile()' - Remove a file using the 7-pass US DoD method.
+ * 'cupsdRemoveFile()' - Remove a file securely.
*/
int /* O - 0 on success, -1 on error */
cupsdRemoveFile(const char *filename) /* I - File to remove */
{
#ifdef HAVE_REMOVEFILE
- return (removefile(filename, NULL, REMOVEFILE_SECURE_7_PASS));
+ /*
+ * See if the file exists...
+ */
+
+ if (access(filename, 0))
+ return (0);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Securely removing \"%s\".", filename);
+
+ /*
+ * Remove the file...
+ */
+
+ return (removefile(filename, NULL, REMOVEFILE_SECURE_1_PASS));
#else
int fd; /* File descriptor */
@@ -325,6 +324,15 @@ cupsdRemoveFile(const char *filename) /* I - File to remove */
/*
+ * See if the file exists...
+ */
+
+ if (access(filename, 0))
+ return (0);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Securely removing \"%s\".", filename);
+
+ /*
* First open the file for writing in exclusive mode.
*/
@@ -353,31 +361,9 @@ cupsdRemoveFile(const char *filename) /* I - File to remove */
}
/*
- * Overwrite the file 7 times with 0xF6, 0x00, 0xFF, random, 0x00, 0xFF,
- * and more random data.
+ * Overwrite the file with random data.
*/
- memset(buffer, 0xF6, sizeof(buffer));
- if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
- {
- close(fd);
- return (-1);
- }
-
- memset(buffer, 0x00, sizeof(buffer));
- if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
- {
- close(fd);
- return (-1);
- }
-
- memset(buffer, 0xFF, sizeof(buffer));
- if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
- {
- close(fd);
- return (-1);
- }
-
CUPS_SRAND(time(NULL));
for (i = 0; i < sizeof(buffer); i ++)
@@ -388,39 +374,31 @@ cupsdRemoveFile(const char *filename) /* I - File to remove */
return (-1);
}
- memset(buffer, 0x00, sizeof(buffer));
- if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
- {
- close(fd);
- return (-1);
- }
-
- memset(buffer, 0xFF, sizeof(buffer));
- if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
- {
- close(fd);
- return (-1);
- }
-
- for (i = 0; i < sizeof(buffer); i ++)
- buffer[i] = CUPS_RAND();
- if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
- {
- close(fd);
- return (-1);
- }
-
/*
- * Whew! Close the file (which will lead to the actual deletion) and
- * return success...
+ * Close the file, which will lead to the actual deletion, and return...
*/
- close(fd);
- return (0);
+ return (close(fd));
#endif /* HAVE_REMOVEFILE */
}
+/*
+ * 'cupsdUnlinkOrRemoveFile()' - Unlink or securely remove a file depending
+ * on the configuration.
+ */
+
+int /* O - 0 on success, -1 on error */
+cupsdUnlinkOrRemoveFile(
+ const char *filename) /* I - Filename */
+{
+ if (Classification)
+ return (cupsdRemoveFile(filename));
+ else
+ return (unlink(filename));
+}
+
+
#ifndef HAVE_REMOVEFILE
/*
* 'overwrite_data()' - Overwrite the data in a file.
@@ -453,7 +431,7 @@ overwrite_data(int fd, /* I - File descriptor */
else
bytes = filesize;
- if ((bytes = write(fd, buffer, bytes)) < 0)
+ if ((bytes = write(fd, buffer, (size_t)bytes)) < 0)
return (-1);
filesize -= bytes;
@@ -469,5 +447,5 @@ overwrite_data(int fd, /* I - File descriptor */
/*
- * End of "$Id: file.c 11221 2013-08-06 16:16:01Z msweet $".
+ * End of "$Id: file.c 11594 2014-02-14 20:09:01Z msweet $".
*/
diff --git a/scheduler/filter.c b/scheduler/filter.c
index 6979b5c..eec9611 100644
--- a/scheduler/filter.c
+++ b/scheduler/filter.c
@@ -1,5 +1,5 @@
/*
- * "$Id: filter.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: filter.c 10996 2013-05-29 11:51:34Z msweet $"
*
* File type conversion routines for CUPS.
*
@@ -500,5 +500,5 @@ mime_find_filters(
/*
- * End of "$Id: filter.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: filter.c 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index 6968cd5..763dc96 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -1,102 +1,19 @@
/*
- * "$Id: ipp.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: ipp.c 12978 2015-11-17 19:29:52Z msweet $"
*
- * IPP routines for the CUPS scheduler.
+ * IPP routines for the CUPS scheduler.
*
- * Copyright 2007-2013 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
- * This file contains Kerberos support code, copyright 2006 by
- * Jelmer Vernooij.
+ * This file contains Kerberos support code, copyright 2006 by
+ * Jelmer Vernooij.
*
- * 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:
- *
- * cupsdProcessIPPRequest() - Process an incoming IPP request.
- * cupsdTimeoutJob() - Timeout a job waiting on job files.
- * accept_jobs() - Accept print jobs to a printer.
- * 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_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.
- * add_printer_state_reasons() - Add the "printer-state-reasons" attribute
- * based upon the printer state...
- * add_queued_job_count() - Add the "queued-job-count" attribute for the
- * specified printer or class.
- * 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.
- * cancel_job() - Cancel a print job.
- * cancel_subscription() - Cancel a subscription.
- * check_rss_recipient() - Check that we do not have a duplicate RSS
- * feed URI.
- * check_quotas() - Check quotas for a printer and user.
- * close_job() - Close a multi-file job.
- * copy_attrs() - Copy attributes from one request to another.
- * copy_banner() - Copy a banner file to the requests directory
- * for the specified job.
- * copy_file() - Copy a PPD file or interface script...
- * copy_model() - Copy a PPD model file, substituting default
- * values as needed...
- * copy_job_attrs() - Copy job attributes.
- * copy_printer_attrs() - Copy printer attributes.
- * copy_subscription_attrs() - Copy subscription attributes.
- * create_job() - Print a file to a printer or class.
- * create_requested_array() - Create an array for the requested-attributes.
- * create_subscription() - Create a notification subscription.
- * delete_printer() - Remove a printer or class from the system.
- * get_default() - Get the default destination.
- * get_devices() - Get the list of available devices on the
- * local system.
- * get_document() - Get a copy of a job file.
- * get_job_attrs() - Get job attributes.
- * get_jobs() - Get a list of jobs for the specified printer.
- * get_notifications() - Get events for a subscription.
- * get_ppd() - Get a named PPD from the local system.
- * get_ppds() - Get the list of PPD files on the local
- * system.
- * get_printer_attrs() - Get printer attributes.
- * get_printer_supported() - Get printer supported values.
- * get_printers() - Get a list of printers or classes.
- * get_subscription_attrs() - Get subscription attributes.
- * get_subscriptions() - Get subscriptions.
- * get_username() - Get the username associated with a request.
- * hold_job() - Hold a print job.
- * hold_new_jobs() - Hold pending/new jobs on a printer or class.
- * move_job() - Move a job to a new destination.
- * ppd_parse_line() - Parse a PPD default line.
- * print_job() - Print a file to a printer or class.
- * read_job_ticket() - Read a job ticket embedded in a print file.
- * reject_jobs() - Reject print jobs to a printer.
- * release_held_new_jobs() - Release pending/new jobs on a printer or
- * class.
- * release_job() - Release a held print job.
- * renew_subscription() - Renew an existing subscription...
- * restart_job() - Restart an old print job.
- * save_auth_info() - Save authentication information for a job.
- * send_document() - Send a file to a printer or class.
- * send_http_error() - Send a HTTP error back to the IPP client.
- * send_ipp_status() - Send a status back to the IPP client.
- * set_default() - Set the default destination...
- * set_job_attrs() - Set job attributes.
- * set_printer_attrs() - Set printer attributes.
- * set_printer_defaults() - Set printer default options from a request.
- * start_printer() - Start a printer.
- * stop_printer() - Stop a printer.
- * url_encode_attr() - URL-encode a string attribute.
- * url_encode_string() - URL-encode a string.
- * user_allowed() - See if a user is allowed to print to a queue.
- * validate_job() - Validate printer options and destination.
- * validate_name() - Make sure the printer name only contains
- * valid chars.
- * validate_user() - Validate the user for the request.
+ * 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/".
*/
/*
@@ -153,7 +70,7 @@ static void copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra,
cups_array_t *exclude);
static int copy_banner(cupsd_client_t *con, cupsd_job_t *job,
const char *name);
-static int copy_file(const char *from, const char *to);
+static int copy_file(const char *from, const char *to, mode_t mode);
static int copy_model(cupsd_client_t *con, const char *from,
const char *to);
static void copy_job_attrs(cupsd_client_t *con,
@@ -168,7 +85,7 @@ static void copy_subscription_attrs(cupsd_client_t *con,
cups_array_t *exclude);
static void create_job(cupsd_client_t *con, ipp_attribute_t *uri);
static cups_array_t *create_requested_array(ipp_t *request);
-static void create_subscription(cupsd_client_t *con, ipp_attribute_t *uri);
+static void create_subscriptions(cupsd_client_t *con, ipp_attribute_t *uri);
static void delete_printer(cupsd_client_t *con, ipp_attribute_t *uri);
static void get_default(cupsd_client_t *con);
static void get_devices(cupsd_client_t *con);
@@ -212,15 +129,12 @@ static void set_printer_defaults(cupsd_client_t *con,
cupsd_printer_t *printer);
static void start_printer(cupsd_client_t *con, ipp_attribute_t *uri);
static void stop_printer(cupsd_client_t *con, ipp_attribute_t *uri);
-static void url_encode_attr(ipp_attribute_t *attr, char *buffer,
- int bufsize);
-static char *url_encode_string(const char *s, char *buffer, int bufsize);
+static void url_encode_attr(ipp_attribute_t *attr, char *buffer, size_t bufsize);
+static char *url_encode_string(const char *s, char *buffer, size_t bufsize);
static int user_allowed(cupsd_printer_t *p, const char *username);
static void validate_job(cupsd_client_t *con, ipp_attribute_t *uri);
static int validate_name(const char *name);
-static int validate_user(cupsd_job_t *job, cupsd_client_t *con,
- const char *owner, char *username,
- int userlen);
+static int validate_user(cupsd_job_t *job, cupsd_client_t *con, const char *owner, char *username, size_t userlen);
/*
@@ -242,7 +156,7 @@ cupsdProcessIPPRequest(
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"cupsdProcessIPPRequest(%p[%d]): operation_id = %04x",
- con, con->http.fd, con->request->request.op.operation_id);
+ con, con->number, con->request->request.op.operation_id);
/*
* First build an empty response message for this request...
@@ -270,7 +184,7 @@ cupsdProcessIPPRequest(
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Bad request version number %d.%d",
- IPP_VERSION_NOT_SUPPORTED, con->http.hostname,
+ IPP_VERSION_NOT_SUPPORTED, con->http->hostname,
con->request->request.any.version[0],
con->request->request.any.version[1]);
@@ -287,7 +201,7 @@ cupsdProcessIPPRequest(
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Bad request ID %d",
- IPP_BAD_REQUEST, con->http.hostname,
+ IPP_BAD_REQUEST, con->http->hostname,
con->request->request.any.request_id);
send_ipp_status(con, IPP_BAD_REQUEST, _("Bad request ID %d."),
@@ -297,7 +211,7 @@ cupsdProcessIPPRequest(
{
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s No attributes in request",
- IPP_BAD_REQUEST, con->http.hostname);
+ IPP_BAD_REQUEST, con->http->hostname);
send_ipp_status(con, IPP_BAD_REQUEST, _("No attributes in request."));
}
@@ -319,7 +233,7 @@ cupsdProcessIPPRequest(
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Attribute groups are out of order",
- IPP_BAD_REQUEST, con->http.hostname);
+ IPP_BAD_REQUEST, con->http->hostname);
send_ipp_status(con, IPP_BAD_REQUEST,
_("Attribute groups are out of order (%x < %x)."),
@@ -353,7 +267,20 @@ cupsdProcessIPPRequest(
if (attr && attr->name &&
!strcmp(attr->name, "attributes-natural-language") &&
(attr->value_tag & IPP_TAG_MASK) == IPP_TAG_LANGUAGE)
+ {
language = attr;
+
+ /*
+ * Reset language for this request if different from Accept-Language.
+ */
+
+ if (!con->language ||
+ strcmp(attr->values[0].string.text, con->language->language))
+ {
+ cupsLangFree(con->language);
+ con->language = cupsLangGet(attr->values[0].string.text);
+ }
+ }
else
language = NULL;
@@ -396,7 +323,7 @@ cupsdProcessIPPRequest(
charset->values[0].string.text);
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Unsupported attributes-charset value \"%s\"",
- IPP_CHARSET, con->http.hostname,
+ IPP_CHARSET, con->http->hostname,
charset->values[0].string.text);
send_ipp_status(con, IPP_BAD_REQUEST,
_("Unsupported character set \"%s\"."),
@@ -423,7 +350,7 @@ cupsdProcessIPPRequest(
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Missing attributes-charset attribute",
- IPP_BAD_REQUEST, con->http.hostname);
+ IPP_BAD_REQUEST, con->http->hostname);
}
if (!language)
@@ -433,7 +360,7 @@ cupsdProcessIPPRequest(
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Missing attributes-natural-language attribute",
- IPP_BAD_REQUEST, con->http.hostname);
+ IPP_BAD_REQUEST, con->http->hostname);
}
if (!uri)
@@ -444,7 +371,7 @@ cupsdProcessIPPRequest(
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Missing printer-uri, job-uri, or ppd-name "
- "attribute", IPP_BAD_REQUEST, con->http.hostname);
+ "attribute", IPP_BAD_REQUEST, con->http->hostname);
}
cupsdLogMessage(CUPSD_LOG_DEBUG, "Request attributes follow...");
@@ -475,15 +402,14 @@ cupsdProcessIPPRequest(
*/
if (!strcmp(username->values[0].string.text, "root") &&
- _cups_strcasecmp(con->http.hostname, "localhost") &&
+ _cups_strcasecmp(con->http->hostname, "localhost") &&
strcmp(con->username, "root"))
{
/*
* Remote unauthenticated user masquerading as local root...
*/
- _cupsStrFree(username->values[0].string.text);
- username->values[0].string.text = _cupsStrAlloc(RemoteRoot);
+ ippSetString(con->request, &username, 0, RemoteRoot);
}
}
@@ -507,183 +433,183 @@ cupsdProcessIPPRequest(
switch (con->request->request.op.operation_id)
{
- case IPP_PRINT_JOB :
+ case IPP_OP_PRINT_JOB :
print_job(con, uri);
break;
- case IPP_VALIDATE_JOB :
+ case IPP_OP_VALIDATE_JOB :
validate_job(con, uri);
break;
- case IPP_CREATE_JOB :
+ case IPP_OP_CREATE_JOB :
create_job(con, uri);
break;
- case IPP_SEND_DOCUMENT :
+ case IPP_OP_SEND_DOCUMENT :
send_document(con, uri);
break;
- case IPP_CANCEL_JOB :
+ case IPP_OP_CANCEL_JOB :
cancel_job(con, uri);
break;
- case IPP_GET_JOB_ATTRIBUTES :
+ case IPP_OP_GET_JOB_ATTRIBUTES :
get_job_attrs(con, uri);
break;
- case IPP_GET_JOBS :
+ case IPP_OP_GET_JOBS :
get_jobs(con, uri);
break;
- case IPP_GET_PRINTER_ATTRIBUTES :
+ case IPP_OP_GET_PRINTER_ATTRIBUTES :
get_printer_attrs(con, uri);
break;
- case IPP_GET_PRINTER_SUPPORTED_VALUES :
+ case IPP_OP_GET_PRINTER_SUPPORTED_VALUES :
get_printer_supported(con, uri);
break;
- case IPP_HOLD_JOB :
+ case IPP_OP_HOLD_JOB :
hold_job(con, uri);
break;
- case IPP_RELEASE_JOB :
+ case IPP_OP_RELEASE_JOB :
release_job(con, uri);
break;
- case IPP_RESTART_JOB :
+ case IPP_OP_RESTART_JOB :
restart_job(con, uri);
break;
- case IPP_PAUSE_PRINTER :
+ case IPP_OP_PAUSE_PRINTER :
stop_printer(con, uri);
break;
- case IPP_RESUME_PRINTER :
+ case IPP_OP_RESUME_PRINTER :
start_printer(con, uri);
break;
- case IPP_PURGE_JOBS :
- case IPP_CANCEL_JOBS :
- case IPP_CANCEL_MY_JOBS :
+ case IPP_OP_PURGE_JOBS :
+ case IPP_OP_CANCEL_JOBS :
+ case IPP_OP_CANCEL_MY_JOBS :
cancel_all_jobs(con, uri);
break;
- case IPP_SET_JOB_ATTRIBUTES :
+ case IPP_OP_SET_JOB_ATTRIBUTES :
set_job_attrs(con, uri);
break;
- case IPP_SET_PRINTER_ATTRIBUTES :
+ case IPP_OP_SET_PRINTER_ATTRIBUTES :
set_printer_attrs(con, uri);
break;
- case IPP_HOLD_NEW_JOBS :
+ case IPP_OP_HOLD_NEW_JOBS :
hold_new_jobs(con, uri);
break;
- case IPP_RELEASE_HELD_NEW_JOBS :
+ case IPP_OP_RELEASE_HELD_NEW_JOBS :
release_held_new_jobs(con, uri);
break;
- case IPP_CLOSE_JOB :
+ case IPP_OP_CLOSE_JOB :
close_job(con, uri);
break;
- case CUPS_GET_DEFAULT :
+ case IPP_OP_CUPS_GET_DEFAULT :
get_default(con);
break;
- case CUPS_GET_PRINTERS :
+ case IPP_OP_CUPS_GET_PRINTERS :
get_printers(con, 0);
break;
- case CUPS_GET_CLASSES :
+ case IPP_OP_CUPS_GET_CLASSES :
get_printers(con, CUPS_PRINTER_CLASS);
break;
- case CUPS_ADD_PRINTER :
+ case IPP_OP_CUPS_ADD_MODIFY_PRINTER :
add_printer(con, uri);
break;
- case CUPS_DELETE_PRINTER :
+ case IPP_OP_CUPS_DELETE_PRINTER :
delete_printer(con, uri);
break;
- case CUPS_ADD_CLASS :
+ case IPP_OP_CUPS_ADD_MODIFY_CLASS :
add_class(con, uri);
break;
- case CUPS_DELETE_CLASS :
+ case IPP_OP_CUPS_DELETE_CLASS :
delete_printer(con, uri);
break;
- case CUPS_ACCEPT_JOBS :
- case IPP_ENABLE_PRINTER :
+ case IPP_OP_CUPS_ACCEPT_JOBS :
+ case IPP_OP_ENABLE_PRINTER :
accept_jobs(con, uri);
break;
- case CUPS_REJECT_JOBS :
- case IPP_DISABLE_PRINTER :
+ case IPP_OP_CUPS_REJECT_JOBS :
+ case IPP_OP_DISABLE_PRINTER :
reject_jobs(con, uri);
break;
- case CUPS_SET_DEFAULT :
+ case IPP_OP_CUPS_SET_DEFAULT :
set_default(con, uri);
break;
- case CUPS_GET_DEVICES :
+ case IPP_OP_CUPS_GET_DEVICES :
get_devices(con);
break;
- case CUPS_GET_DOCUMENT :
+ case IPP_OP_CUPS_GET_DOCUMENT :
get_document(con, uri);
break;
- case CUPS_GET_PPD :
+ case IPP_OP_CUPS_GET_PPD :
get_ppd(con, uri);
break;
- case CUPS_GET_PPDS :
+ case IPP_OP_CUPS_GET_PPDS :
get_ppds(con);
break;
- case CUPS_MOVE_JOB :
+ case IPP_OP_CUPS_MOVE_JOB :
move_job(con, uri);
break;
- case CUPS_AUTHENTICATE_JOB :
+ case IPP_OP_CUPS_AUTHENTICATE_JOB :
authenticate_job(con, uri);
break;
- case IPP_CREATE_PRINTER_SUBSCRIPTION :
- case IPP_CREATE_JOB_SUBSCRIPTION :
- create_subscription(con, uri);
+ case IPP_OP_CREATE_PRINTER_SUBSCRIPTIONS :
+ case IPP_OP_CREATE_JOB_SUBSCRIPTIONS :
+ create_subscriptions(con, uri);
break;
- case IPP_GET_SUBSCRIPTION_ATTRIBUTES :
+ case IPP_OP_GET_SUBSCRIPTION_ATTRIBUTES :
get_subscription_attrs(con, sub_id);
break;
- case IPP_GET_SUBSCRIPTIONS :
+ case IPP_OP_GET_SUBSCRIPTIONS :
get_subscriptions(con, uri);
break;
- case IPP_RENEW_SUBSCRIPTION :
+ case IPP_OP_RENEW_SUBSCRIPTION :
renew_subscription(con, sub_id);
break;
- case IPP_CANCEL_SUBSCRIPTION :
+ case IPP_OP_CANCEL_SUBSCRIPTION :
cancel_subscription(con, sub_id);
break;
- case IPP_GET_NOTIFICATIONS :
+ case IPP_OP_GET_NOTIFICATIONS :
get_notifications(con);
break;
default :
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
"%04X %s Operation %04X (%s) not supported",
- IPP_OPERATION_NOT_SUPPORTED, con->http.hostname,
+ IPP_OPERATION_NOT_SUPPORTED, con->http->hostname,
con->request->request.op.operation_id,
ippOpString(con->request->request.op.operation_id));
@@ -707,78 +633,63 @@ cupsdProcessIPPRequest(
>= IPP_BAD_REQUEST &&
con->response->request.status.status_code
!= IPP_NOT_FOUND ? CUPSD_LOG_ERROR : CUPSD_LOG_DEBUG,
- "Returning IPP %s for %s (%s) from %s",
+ "[Client %d] Returning IPP %s for %s (%s) from %s",
+ con->number,
ippErrorString(con->response->request.status.status_code),
ippOpString(con->request->request.op.operation_id),
uri ? uri->values[0].string.text : "no URI",
- con->http.hostname);
+ con->http->hostname);
- if (LogLevel == CUPSD_LOG_DEBUG2)
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdProcessIPPRequest: ippLength(response)=%ld",
- (long)ippLength(con->response));
+ httpClearFields(con->http);
- if (cupsdSendHeader(con, HTTP_OK, "application/ipp", CUPSD_AUTH_NONE))
- {
#ifdef CUPSD_USE_CHUNKING
- /*
- * Because older versions of CUPS (1.1.17 and older) and some IPP
- * clients do not implement chunking properly, we cannot use
- * chunking by default. This may become the default in future
- * CUPS releases, or we might add a configuration directive for
- * it.
- */
-
- if (con->http.version == HTTP_1_1)
- {
- if (httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n\r\n") < 0)
- return (0);
+ /*
+ * Because older versions of CUPS (1.1.17 and older) and some IPP
+ * clients do not implement chunking properly, we cannot use
+ * chunking by default. This may become the default in future
+ * CUPS releases, or we might add a configuration directive for
+ * it.
+ */
- if (cupsdFlushHeader(con) < 0)
- return (0);
+ if (con->http->version == HTTP_1_1)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "[Client %d] Transfer-Encoding: chunked",
+ con->number);
- con->http.data_encoding = HTTP_ENCODE_CHUNKED;
- }
- else
+ cupsdSetLength(con->http, 0);
+ }
+ else
#endif /* CUPSD_USE_CHUNKING */
- {
- size_t length; /* Length of response */
-
-
- length = ippLength(con->response);
-
- if (con->file >= 0 && !con->pipe_pid)
- {
- struct stat fileinfo; /* File information */
-
-
- if (!fstat(con->file, &fileinfo))
- length += fileinfo.st_size;
- }
+ {
+ size_t length; /* Length of response */
- if (httpPrintf(HTTP(con), "Content-Length: " CUPS_LLFMT "\r\n\r\n",
- CUPS_LLCAST length) < 0)
- return (0);
- if (cupsdFlushHeader(con) < 0)
- return (0);
+ length = ippLength(con->response);
- con->http.data_encoding = HTTP_ENCODE_LENGTH;
- con->http.data_remaining = length;
+ if (con->file >= 0 && !con->pipe_pid)
+ {
+ struct stat fileinfo; /* File information */
- if (con->http.data_remaining <= INT_MAX)
- con->http._data_remaining = con->http.data_remaining;
- else
- con->http._data_remaining = INT_MAX;
+ if (!fstat(con->file, &fileinfo))
+ length += (size_t)fileinfo.st_size;
}
- cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient,
- (cupsd_selfunc_t)cupsdWriteClient, con);
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "[Client %d] Content-Length: " CUPS_LLFMT,
+ con->number, CUPS_LLCAST length);
+ httpSetLength(con->http, length);
+ }
+ if (cupsdSendHeader(con, HTTP_OK, "application/ipp", CUPSD_AUTH_NONE))
+ {
/*
* Tell the caller the response header was sent successfully...
*/
+ cupsdAddSelect(httpGetFd(con->http), (cupsd_selfunc_t)cupsdReadClient,
+ (cupsd_selfunc_t)cupsdWriteClient, con);
+
return (1);
}
else
@@ -860,7 +771,7 @@ accept_jobs(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "accept_jobs(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -945,7 +856,7 @@ add_class(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_class(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Do we have a valid URI?
@@ -1034,10 +945,18 @@ add_class(cupsd_client_t *con, /* I - Client connection */
need_restart_job = 0;
- if ((attr = ippFindAttribute(con->request, "printer-location",
- IPP_TAG_TEXT)) != NULL)
+ if ((attr = ippFindAttribute(con->request, "printer-location", IPP_TAG_TEXT)) != NULL)
cupsdSetString(&pclass->location, attr->values[0].string.text);
+ if ((attr = ippFindAttribute(con->request, "printer-geo-location", IPP_TAG_URI)) != NULL && !strncmp(attr->values[0].string.text, "geo:", 4))
+ cupsdSetString(&pclass->geo_location, attr->values[0].string.text);
+
+ if ((attr = ippFindAttribute(con->request, "printer-organization", IPP_TAG_TEXT)) != NULL)
+ cupsdSetString(&pclass->organization, attr->values[0].string.text);
+
+ if ((attr = ippFindAttribute(con->request, "printer-organizational-unit", IPP_TAG_TEXT)) != NULL)
+ cupsdSetString(&pclass->organizational_unit, attr->values[0].string.text);
+
if ((attr = ippFindAttribute(con->request, "printer-info",
IPP_TAG_TEXT)) != NULL)
cupsdSetString(&pclass->info, attr->values[0].string.text);
@@ -1059,6 +978,16 @@ add_class(cupsd_client_t *con, /* I - Client connection */
if ((attr = ippFindAttribute(con->request, "printer-is-shared",
IPP_TAG_BOOLEAN)) != NULL)
{
+ if (pclass->type & CUPS_PRINTER_REMOTE)
+ {
+ /*
+ * Cannot re-share remote printers.
+ */
+
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Cannot change printer-is-shared for remote queues."));
+ return;
+ }
+
if (pclass->shared && !attr->values[0].boolean)
cupsdDeregisterPrinter(pclass, 1);
@@ -1157,6 +1086,8 @@ add_class(cupsd_client_t *con, /* I - Client connection */
IPP_TAG_KEYWORD)) != NULL)
cupsdSetAuthInfoRequired(pclass, NULL, attr);
+ pclass->config_time = time(NULL);
+
/*
* Update the printer class attributes and return...
*/
@@ -1215,7 +1146,7 @@ add_file(cupsd_client_t *con, /* I - Connection to client */
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"add_file(con=%p[%d], job=%d, filetype=%s/%s, "
- "compression=%d)", con, con ? con->http.fd : -1, job->id,
+ "compression=%d)", con, con ? con->number : -1, job->id,
filetype->super, filetype->type, compression);
/*
@@ -1230,12 +1161,18 @@ add_file(cupsd_client_t *con, /* I - Connection to client */
else
{
compressions = (int *)realloc(job->compressions,
- (job->num_files + 1) * sizeof(int));
+ (size_t)(job->num_files + 1) * sizeof(int));
filetypes = (mime_type_t **)realloc(job->filetypes,
- (job->num_files + 1) *
+ (size_t)(job->num_files + 1) *
sizeof(mime_type_t *));
}
+ if (compressions)
+ job->compressions = compressions;
+
+ if (filetypes)
+ job->filetypes = filetypes;
+
if (!compressions || !filetypes)
{
cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_PURGE,
@@ -1248,9 +1185,7 @@ add_file(cupsd_client_t *con, /* I - Connection to client */
return (-1);
}
- job->compressions = compressions;
job->compressions[job->num_files] = compression;
- job->filetypes = filetypes;
job->filetypes[job->num_files] = filetype;
job->num_files ++;
@@ -1274,6 +1209,7 @@ add_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 */
+ const char *mandatory; /* Current mandatory job attribute */
const char *val; /* Default option value */
int priority; /* Job priority */
cupsd_job_t *job; /* Current job */
@@ -1287,15 +1223,25 @@ add_job(cupsd_client_t *con, /* I - Client connection */
ipp_t *unsup_col; /* media-col in unsupported response */
static const char * const readonly[] =/* List of read-only attributes */
{
+ "date-time-at-completed",
+ "date-time-at-creation",
+ "date-time-at-processing",
+ "job-detailed-status-messages",
+ "job-document-access-errors",
"job-id",
- "job-k-octets",
- /*"job-impressions",*/ /* For now we allow this since cupsd can't count */
"job-impressions-completed",
- "job-media-sheets",
+ "job-k-octets-completed",
"job-media-sheets-completed",
+ "job-pages-completed",
+ "job-printer-up-time",
+ "job-printer-uri",
"job-state",
"job-state-message",
"job-state-reasons",
+ "job-uri",
+ "number-of-documents",
+ "number-of-intervening-jobs",
+ "output-device-assigned",
"time-at-completed",
"time-at-creation",
"time-at-processing"
@@ -1303,7 +1249,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
- con, con->http.fd, printer, printer->name,
+ con, con->number, printer, printer->name,
filetype, filetype ? filetype->super : "none",
filetype ? filetype->type : "none");
@@ -1312,8 +1258,8 @@ add_job(cupsd_client_t *con, /* I - Client connection */
*/
if (!printer->shared &&
- _cups_strcasecmp(con->http.hostname, "localhost") &&
- _cups_strcasecmp(con->http.hostname, ServerName))
+ _cups_strcasecmp(con->http->hostname, "localhost") &&
+ _cups_strcasecmp(con->http->hostname, ServerName))
{
send_ipp_status(con, IPP_NOT_AUTHORIZED,
_("The printer or class is not shared."));
@@ -1339,8 +1285,8 @@ add_job(cupsd_client_t *con, /* I - Client connection */
return (NULL);
}
#ifdef HAVE_SSL
- else if (auth_info && !con->http.tls &&
- !httpAddrLocalhost(con->http.hostaddr))
+ else if (auth_info && !con->http->tls &&
+ !httpAddrLocalhost(con->http->hostaddr))
{
/*
* Require encryption of auth-info over non-local connections...
@@ -1365,27 +1311,43 @@ add_job(cupsd_client_t *con, /* I - Client connection */
/*
* Validate job template attributes; for now just document-format,
- * copies, number-up, and page-ranges...
+ * copies, job-sheets, number-up, page-ranges, mandatory attributes, and
+ * media...
*/
for (i = 0; i < (int)(sizeof(readonly) / sizeof(readonly[0])); i ++)
{
- if ((attr = ippFindAttribute(con->request, readonly[i],
- IPP_TAG_ZERO)) != NULL)
+ 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]);
+ send_ipp_status(con, IPP_BAD_REQUEST, _("The '%s' Job Status 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]);
+ cupsdLogMessage(CUPSD_LOG_INFO, "Unexpected '%s' Job Status attribute in a job creation request.", readonly[i]);
+ }
+ }
+
+ if (printer->pc)
+ {
+ for (mandatory = (char *)cupsArrayFirst(printer->pc->mandatory);
+ mandatory;
+ mandatory = (char *)cupsArrayNext(printer->pc->mandatory))
+ {
+ if (!ippFindAttribute(con->request, mandatory, IPP_TAG_ZERO))
+ {
+ /*
+ * Missing a required attribute...
+ */
+
+ send_ipp_status(con, IPP_CONFLICT,
+ _("The \"%s\" attribute is required for print jobs."),
+ mandatory);
+ return (NULL);
+ }
}
}
@@ -1575,8 +1537,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
}
if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_ZERO)) == NULL)
- ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL,
- "Untitled");
+ 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)
@@ -1587,57 +1548,13 @@ add_job(cupsd_client_t *con, /* I - Client connection */
attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
return (NULL);
}
- else
+ else if (!ippValidateAttribute(attr))
{
- 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);
- }
+ send_ipp_status(con, IPP_ATTRIBUTES, _("Bad job-name value: %s"),
+ cupsLastErrorString());
+ if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL)
+ attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
+ return (NULL);
}
if ((job = cupsdAddJob(priority, printer->name)) == NULL)
@@ -1665,7 +1582,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
cupsdSetString(&job->username, con->username);
if (attr)
- cupsdSetString(&attr->values[0].string.text, con->username);
+ ippSetString(job->attrs, &attr, 0, con->username);
}
else if (attr)
{
@@ -1683,9 +1600,8 @@ add_job(cupsd_client_t *con, /* I - Client connection */
"job-originating-user-name", NULL, job->username);
else
{
- attr->group_tag = IPP_TAG_JOB;
- _cupsStrFree(attr->name);
- attr->name = _cupsStrAlloc("job-originating-user-name");
+ ippSetGroupTag(job->attrs, &attr, IPP_TAG_JOB);
+ ippSetName(job->attrs, &attr, "job-originating-user-name");
}
if (con->username[0] || auth_info)
@@ -1700,6 +1616,9 @@ add_job(cupsd_client_t *con, /* I - Client connection */
ippDeleteAttribute(job->attrs, auth_info);
}
+ if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_NAME)) != NULL)
+ cupsdSetString(&(job->name), attr->values[0].string.text);
+
if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name",
IPP_TAG_ZERO)) != NULL)
{
@@ -1709,55 +1628,18 @@ add_job(cupsd_client_t *con, /* I - Client connection */
if (attr->value_tag != IPP_TAG_NAME ||
attr->num_values != 1 ||
- strcmp(con->http.hostname, "localhost"))
+ strcmp(con->http->hostname, "localhost"))
{
/*
* Can't override the value if we aren't connected via localhost.
* Also, we can only have 1 value and it must be a name value.
*/
- switch (attr->value_tag)
- {
- case IPP_TAG_STRING :
- case IPP_TAG_TEXTLANG :
- case IPP_TAG_NAMELANG :
- 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 :
- /*
- * Free old strings...
- */
-
- for (i = 0; i < attr->num_values; i ++)
- {
- _cupsStrFree(attr->values[i].string.text);
- attr->values[i].string.text = NULL;
- if (attr->values[i].string.language)
- {
- _cupsStrFree(attr->values[i].string.language);
- attr->values[i].string.language = NULL;
- }
- }
-
- default :
- break;
- }
-
- /*
- * Use the default connection hostname instead...
- */
-
- attr->value_tag = IPP_TAG_NAME;
- attr->num_values = 1;
- attr->values[0].string.text = _cupsStrAlloc(con->http.hostname);
+ ippDeleteAttribute(job->attrs, attr);
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-originating-host-name", NULL, con->http->hostname);
}
-
- attr->group_tag = IPP_TAG_JOB;
+ else
+ ippSetGroupTag(job->attrs, &attr, IPP_TAG_JOB);
}
else
{
@@ -1767,17 +1649,15 @@ add_job(cupsd_client_t *con, /* I - Client connection */
*/
ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME,
- "job-originating-host-name", NULL, con->http.hostname);
+ "job-originating-host-name", NULL, con->http->hostname);
}
- ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation",
- time(NULL));
- attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
- "time-at-processing", 0);
- attr->value_tag = IPP_TAG_NOVALUE;
- attr = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER,
- "time-at-completed", 0);
- attr->value_tag = IPP_TAG_NOVALUE;
+ ippAddOutOfBand(job->attrs, IPP_TAG_JOB, IPP_TAG_NOVALUE, "date-time-at-completed");
+ ippAddDate(job->attrs, IPP_TAG_JOB, "date-time-at-creation", ippTimeToDate(time(NULL)));
+ ippAddOutOfBand(job->attrs, IPP_TAG_JOB, IPP_TAG_NOVALUE, "date-time-at-processing");
+ ippAddOutOfBand(job->attrs, IPP_TAG_JOB, IPP_TAG_NOVALUE, "time-at-completed");
+ ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation", time(NULL));
+ ippAddOutOfBand(job->attrs, IPP_TAG_JOB, IPP_TAG_NOVALUE, "time-at-processing");
/*
* Add remaining job attributes...
@@ -1789,13 +1669,13 @@ add_job(cupsd_client_t *con, /* I - Client connection */
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->impressions = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-impressions-completed", 0);
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,
printer->uri);
- if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
- IPP_TAG_INTEGER)) != NULL)
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
attr->values[0].integer = 0;
else
ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-k-octets", 0);
@@ -1854,8 +1734,8 @@ add_job(cupsd_client_t *con, /* I - Client connection */
attr = ippAddStrings(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-sheets",
2, NULL, NULL);
- attr->values[0].string.text = _cupsStrRetain(printer->job_sheets[0]);
- attr->values[1].string.text = _cupsStrRetain(printer->job_sheets[1]);
+ ippSetString(job->attrs, &attr, 0, printer->job_sheets[0]);
+ ippSetString(job->attrs, &attr, 1, printer->job_sheets[1]);
}
job->job_sheets = attr;
@@ -1881,7 +1761,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
* Force the leading banner to have the classification on it...
*/
- cupsdSetString(&attr->values[0].string.text, Classification);
+ ippSetString(job->attrs, &attr, 0, Classification);
cupsdLogJob(job, CUPSD_LOG_NOTICE, "CLASSIFICATION FORCED "
"job-sheets=\"%s,none\", "
@@ -1898,7 +1778,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
* Can't put two different security markings on the same document!
*/
- cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text);
+ ippSetString(job->attrs, &attr, 1, attr->values[0].string.text);
cupsdLogJob(job, CUPSD_LOG_NOTICE, "CLASSIFICATION FORCED "
"job-sheets=\"%s,%s\", "
@@ -1938,18 +1818,18 @@ add_job(cupsd_client_t *con, /* I - Client connection */
if (attr->num_values > 1 &&
!strcmp(attr->values[0].string.text, attr->values[1].string.text))
{
- cupsdSetString(&(attr->values[0].string.text), Classification);
- cupsdSetString(&(attr->values[1].string.text), Classification);
+ ippSetString(job->attrs, &attr, 0, Classification);
+ ippSetString(job->attrs, &attr, 1, Classification);
}
else
{
if (attr->num_values == 1 ||
strcmp(attr->values[0].string.text, "none"))
- cupsdSetString(&(attr->values[0].string.text), Classification);
+ ippSetString(job->attrs, &attr, 0, Classification);
if (attr->num_values > 1 &&
strcmp(attr->values[1].string.text, "none"))
- cupsdSetString(&(attr->values[1].string.text), Classification);
+ ippSetString(job->attrs, &attr, 1, Classification);
}
if (attr->num_values > 1)
@@ -1997,7 +1877,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
*/
httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
- con->servername, con->serverport, "/jobs/%d", job->id);
+ con->clientname, con->clientport, "/jobs/%d", job->id);
ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL,
job_uri);
@@ -2005,6 +1885,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */
ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state",
job->state_value);
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_TEXT, "job-state-message", NULL, "");
ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons",
NULL, job->reasons->values[0].string.text);
@@ -2220,7 +2101,7 @@ add_job_subscriptions(
{
sub->user_data_len = user_data->values[0].unknown.length;
memcpy(sub->user_data, user_data->values[0].unknown.data,
- sub->user_data_len);
+ (size_t)sub->user_data_len);
}
ippAddSeparator(con->response);
@@ -2289,8 +2170,8 @@ add_job_uuid(cupsd_job_t *job) /* I - Job */
if (!ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI))
ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL,
- _httpAssembleUUID(ServerName, RemotePort, job->dest, job->id,
- uuid, sizeof(uuid)));
+ httpAssembleUUID(ServerName, RemotePort, job->dest, job->id,
+ uuid, sizeof(uuid)));
}
@@ -2323,7 +2204,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Do we have a valid URI?
@@ -2416,6 +2297,15 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
IPP_TAG_TEXT)) != NULL)
cupsdSetString(&printer->location, attr->values[0].string.text);
+ if ((attr = ippFindAttribute(con->request, "printer-geo-location", IPP_TAG_URI)) != NULL && !strncmp(attr->values[0].string.text, "geo:", 4))
+ cupsdSetString(&printer->geo_location, attr->values[0].string.text);
+
+ if ((attr = ippFindAttribute(con->request, "printer-organization", IPP_TAG_TEXT)) != NULL)
+ cupsdSetString(&printer->organization, attr->values[0].string.text);
+
+ if ((attr = ippFindAttribute(con->request, "printer-organizational-unit", IPP_TAG_TEXT)) != NULL)
+ cupsdSetString(&printer->organizational_unit, attr->values[0].string.text);
+
if ((attr = ippFindAttribute(con->request, "printer-info",
IPP_TAG_TEXT)) != NULL)
cupsdSetString(&printer->info, attr->values[0].string.text);
@@ -2460,7 +2350,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG,
"%s device-uri: %s", printer->name,
- uri_status_strings[uri_status - HTTP_URI_OVERFLOW]);
+ uri_status_strings[uri_status - HTTP_URI_STATUS_OVERFLOW]);
if (uri_status < HTTP_URI_OK)
{
@@ -2591,6 +2481,16 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
return;
}
+ if (printer->type & CUPS_PRINTER_REMOTE)
+ {
+ /*
+ * Cannot re-share remote printers.
+ */
+
+ send_ipp_status(con, IPP_BAD_REQUEST, _("Cannot change printer-is-shared for remote queues."));
+ return;
+ }
+
if (printer->shared && !attr->values[0].boolean)
cupsdDeregisterPrinter(printer, 1);
@@ -2735,7 +2635,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
* interfaces directory and make it executable...
*/
- if (copy_file(srcfile, dstfile))
+ if (copy_file(srcfile, dstfile, ConfigFilePerm | 0110))
{
send_ipp_status(con, IPP_INTERNAL_ERROR,
_("Unable to copy interface script - %s"),
@@ -2745,7 +2645,6 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG,
"Copied interface script successfully");
- chmod(dstfile, 0755);
}
snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
@@ -2758,7 +2657,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
* ppd directory and make it readable by all...
*/
- if (copy_file(srcfile, dstfile))
+ if (copy_file(srcfile, dstfile, ConfigFilePerm))
{
send_ipp_status(con, IPP_INTERNAL_ERROR,
_("Unable to copy PPD file - %s"),
@@ -2768,7 +2667,6 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG,
"Copied PPD file successfully");
- chmod(dstfile, 0644);
}
else
{
@@ -2822,7 +2720,6 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG,
"Copied PPD file successfully");
- chmod(dstfile, 0644);
}
}
@@ -2890,6 +2787,8 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
}
}
+ printer->config_time = time(NULL);
+
/*
* Update the printer attributes and return...
*/
@@ -2944,7 +2843,7 @@ add_printer_state_reasons(
{
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"add_printer_state_reasons(%p[%d], %p[%s])",
- con, con->http.fd, p, p->name);
+ con, con->number, p, p->name);
if (p->num_reasons == 0)
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
@@ -2970,7 +2869,7 @@ add_queued_job_count(
cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_queued_job_count(%p[%d], %p[%s])",
- con, con->http.fd, p, p->name);
+ con, con->number, p, p->name);
count = cupsdGetPrinterJobCount(p->name);
@@ -3042,7 +2941,7 @@ authenticate_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "authenticate_job(%p[%d], %s)",
- con, con->http.fd, uri->values[0].string.text);
+ con, con->number, uri->values[0].string.text);
/*
* Start with "everything is OK" status...
@@ -3177,8 +3076,8 @@ authenticate_job(cupsd_client_t *con, /* I - Client connection */
if (attr)
{
- attr->value_tag = IPP_TAG_KEYWORD;
- cupsdSetString(&(attr->values[0].string.text), "no-hold");
+ ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD);
+ ippSetString(job->attrs, &attr, 0, "no-hold");
}
/*
@@ -3221,7 +3120,7 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_all_jobs(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Get the jobs to cancel/purge...
@@ -3328,8 +3227,12 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */
{
for (i = 0; i < job_ids->num_values; i ++)
{
- if (!cupsdFindJob(job_ids->values[i].integer))
+ if ((job = cupsdFindJob(job_ids->values[i].integer)) == NULL)
break;
+
+ if (con->request->request.op.operation_id == IPP_CANCEL_MY_JOBS &&
+ _cups_strcasecmp(job->username, username))
+ break;
}
if (i < job_ids->num_values)
@@ -3385,6 +3288,10 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */
if ((job = cupsdFindJob(job_ids->values[i].integer)) == NULL ||
_cups_strcasecmp(job->dest, printer->name))
break;
+
+ if (con->request->request.op.operation_id == IPP_CANCEL_MY_JOBS &&
+ _cups_strcasecmp(job->username, username))
+ break;
}
if (i < job_ids->num_values)
@@ -3423,6 +3330,8 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */
}
con->response->request.status.status_code = IPP_OK;
+
+ cupsdCheckJobs();
}
@@ -3448,7 +3357,7 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_job(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* See if we have a job URI or a printer URI...
@@ -3648,7 +3557,7 @@ cancel_subscription(
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"cancel_subscription(con=%p[%d], sub_id=%d)",
- con, con->http.fd, sub_id);
+ con, con->number, sub_id);
/*
* Is the subscription ID valid?
@@ -3754,7 +3663,7 @@ check_quotas(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "check_quotas(%p[%d], %p[%s])",
- con, con->http.fd, p, p->name);
+ con, con->number, p, p->name);
/*
* Figure out who is printing...
@@ -3977,7 +3886,7 @@ close_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "close_job(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* See if we have a job URI or a printer URI...
@@ -4061,7 +3970,7 @@ close_job(cupsd_client_t *con, /* I - Client connection */
*/
httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
- con->servername, con->serverport, "/jobs/%d", job->id);
+ con->clientname, con->clientport, "/jobs/%d", job->id);
ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL,
job_uri);
@@ -4112,7 +4021,11 @@ copy_attrs(ipp_t *to, /* I - Destination request */
fromattr->group_tag != IPP_TAG_ZERO) || !fromattr->name)
continue;
- if (!strcmp(fromattr->name, "job-printer-uri"))
+ if (!strcmp(fromattr->name, "document-password") ||
+ !strcmp(fromattr->name, "job-authorization-uri") ||
+ !strcmp(fromattr->name, "job-password") ||
+ !strcmp(fromattr->name, "job-password-encryption") ||
+ !strcmp(fromattr->name, "job-printer-uri"))
continue;
if (exclude &&
@@ -4177,7 +4090,7 @@ copy_banner(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"copy_banner(con=%p[%d], job=%p[%d], name=\"%s\")",
- con, con ? con->http.fd : -1, job, job->id,
+ con, con ? con->number : -1, job, job->id,
name ? name : "(null)");
/*
@@ -4222,8 +4135,8 @@ copy_banner(cupsd_client_t *con, /* I - Client connection */
*/
attrname[2] = '_';
- attrname[3] = toupper(attrname[3] & 255);
- attrname[4] = toupper(attrname[4] & 255);
+ attrname[3] = (char)toupper(attrname[3] & 255);
+ attrname[4] = (char)toupper(attrname[4] & 255);
}
snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir,
@@ -4277,7 +4190,7 @@ copy_banner(cupsd_client_t *con, /* I - Client connection */
if (!isalpha(ch & 255) && ch != '-' && ch != '?')
break;
else if (s < (attrname + sizeof(attrname) - 1))
- *s++ = ch;
+ *s++ = (char)ch;
else
break;
@@ -4424,8 +4337,9 @@ copy_banner(cupsd_client_t *con, /* I - Client connection */
kbytes = (cupsFileTell(out) + 1023) / 1024;
- if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
- IPP_TAG_INTEGER)) != NULL)
+ job->koctets += kbytes;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
attr->values[0].integer += kbytes;
cupsFileClose(out);
@@ -4440,7 +4354,8 @@ copy_banner(cupsd_client_t *con, /* I - Client connection */
static int /* O - 0 = success, -1 = error */
copy_file(const char *from, /* I - Source file */
- const char *to) /* I - Destination file */
+ const char *to, /* I - Destination file */
+ mode_t mode) /* I - Permissions */
{
cups_file_t *src, /* Source file */
*dst; /* Destination file */
@@ -4457,7 +4372,7 @@ copy_file(const char *from, /* I - Source file */
if ((src = cupsFileOpen(from, "rb")) == NULL)
return (-1);
- if ((dst = cupsFileOpen(to, "wb")) == NULL)
+ if ((dst = cupsdCreateConfFile(to, mode)) == NULL)
{
cupsFileClose(src);
return (-1);
@@ -4468,7 +4383,7 @@ copy_file(const char *from, /* I - Source file */
*/
while ((bytes = cupsFileRead(src, buffer, sizeof(buffer))) > 0)
- if (cupsFileWrite(dst, buffer, bytes) < bytes)
+ if (cupsFileWrite(dst, buffer, (size_t)bytes) < bytes)
{
cupsFileClose(src);
cupsFileClose(dst);
@@ -4481,7 +4396,7 @@ copy_file(const char *from, /* I - Source file */
cupsFileClose(src);
- return (cupsFileClose(dst));
+ return (cupsdCloseCreatedConfFile(dst, to));
}
@@ -4536,7 +4451,7 @@ copy_model(cupsd_client_t *con, /* I - Client connection */
cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
snprintf(buffer, sizeof(buffer), "%s/daemon/cups-driverd", ServerBin);
- snprintf(tempfile, sizeof(tempfile), "%s/%d.ppd", TempDir, con->http.fd);
+ snprintf(tempfile, sizeof(tempfile), "%s/%d.ppd", TempDir, con->number);
tempfd = open(tempfile, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (tempfd < 0 || cupsdOpenPipe(temppipe))
return (-1);
@@ -4603,7 +4518,7 @@ copy_model(cupsd_client_t *con, /* I - Client connection */
if ((bytes = read(temppipe[0], buffer, sizeof(buffer))) > 0)
{
- if (write(tempfd, buffer, bytes) < bytes)
+ if (write(tempfd, buffer, (size_t)bytes) < bytes)
break;
total += bytes;
@@ -4717,7 +4632,7 @@ copy_model(cupsd_client_t *con, /* I - Client connection */
* Open the destination file for a copy...
*/
- if ((dst = cupsFileOpen(to, "wb")) == NULL)
+ if ((dst = cupsdCreateConfFile(to, ConfigFilePerm)) == NULL)
{
cupsFreeOptions(num_defaults, defaults);
cupsFileClose(src);
@@ -4772,7 +4687,7 @@ copy_model(cupsd_client_t *con, /* I - Client connection */
unlink(tempfile);
- return (cupsFileClose(dst));
+ return (cupsdCloseCreatedConfFile(dst, to));
}
@@ -4809,7 +4724,7 @@ copy_job_attrs(cupsd_client_t *con, /* I - Client connection */
(!ra || cupsArrayFind(ra, "job-more-info")))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "http",
- NULL, con->servername, con->serverport, "/jobs/%d",
+ NULL, con->clientname, con->clientport, "/jobs/%d",
job->id);
ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
"job-more-info", NULL, job_uri);
@@ -4830,7 +4745,7 @@ copy_job_attrs(cupsd_client_t *con, /* I - Client connection */
if (!ra || cupsArrayFind(ra, "job-printer-uri"))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
- con->servername, con->serverport,
+ con->clientname, con->clientport,
(job->dtype & CUPS_PRINTER_CLASS) ? "/classes/%s" :
"/printers/%s",
job->dest);
@@ -4841,13 +4756,67 @@ copy_job_attrs(cupsd_client_t *con, /* I - Client connection */
if (!ra || cupsArrayFind(ra, "job-uri"))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
- con->servername, con->serverport, "/jobs/%d",
+ con->clientname, con->clientport, "/jobs/%d",
job->id);
ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
"job-uri", NULL, job_uri);
}
- copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0, exclude);
+ if (job->attrs)
+ {
+ copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0, exclude);
+ }
+ else
+ {
+ /*
+ * Generate attributes from the job structure...
+ */
+
+ if (job->completed_time && (!ra || cupsArrayFind(ra, "date-time-at-completed")))
+ ippAddDate(con->response, IPP_TAG_JOB, "date-time-at-completed", ippTimeToDate(job->completed_time));
+
+ if (job->creation_time && (!ra || cupsArrayFind(ra, "date-time-at-creation")))
+ ippAddDate(con->response, IPP_TAG_JOB, "date-time-at-creation", ippTimeToDate(job->creation_time));
+
+ if (!ra || cupsArrayFind(ra, "job-id"))
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id);
+
+ if (!ra || cupsArrayFind(ra, "job-k-octets"))
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-k-octets", job->koctets);
+
+ if (job->name && (!ra || cupsArrayFind(ra, "job-name")))
+ ippAddString(con->response, IPP_TAG_JOB, IPP_CONST_TAG(IPP_TAG_NAME), "job-name", NULL, job->name);
+
+ if (job->username && (!ra || cupsArrayFind(ra, "job-originating-user-name")))
+ ippAddString(con->response, IPP_TAG_JOB, IPP_CONST_TAG(IPP_TAG_NAME), "job-originating-user-name", NULL, job->username);
+
+ if (!ra || cupsArrayFind(ra, "job-state"))
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state", (int)job->state_value);
+
+ if (!ra || cupsArrayFind(ra, "job-state-reasons"))
+ {
+ switch (job->state_value)
+ {
+ default : /* Should never get here for processing, pending, held, or stopped jobs since they don't get unloaded... */
+ break;
+ case IPP_JSTATE_ABORTED :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-aborted-by-system");
+ break;
+ case IPP_JSTATE_CANCELED :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-canceled-by-user");
+ break;
+ case IPP_JSTATE_COMPLETED :
+ ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-completed-successfully");
+ break;
+ }
+ }
+
+ if (job->completed_time && (!ra || cupsArrayFind(ra, "time-at-completed")))
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-completed", (int)job->completed_time);
+
+ if (job->creation_time && (!ra || cupsArrayFind(ra, "time-at-creation")))
+ ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation", (int)job->creation_time);
+ }
}
@@ -4904,8 +4873,8 @@ copy_printer_attrs(
else
{
httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri,
- sizeof(printer_uri), "ipp", NULL, con->servername,
- con->serverport,
+ sizeof(printer_uri), "ipp", NULL, con->clientname,
+ con->clientport,
(p2->type & CUPS_PRINTER_CLASS) ?
"/classes/%s" : "/printers/%s", p2->name);
member_uris->values[i].string.text = _cupsStrAlloc(printer_uri);
@@ -4924,6 +4893,13 @@ copy_printer_attrs(
"printer-alert-description", NULL,
printer->alert_description);
+ if (!ra || cupsArrayFind(ra, "printer-config-change-date-time"))
+ ippAddDate(con->response, IPP_TAG_PRINTER, "printer-config-change-date-time", ippTimeToDate(printer->config_time));
+
+ if (!ra || cupsArrayFind(ra, "printer-config-change-time"))
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "printer-config-change-time", printer->config_time);
+
if (!ra || cupsArrayFind(ra, "printer-current-time"))
ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
ippTimeToDate(curtime));
@@ -4966,7 +4942,7 @@ copy_printer_attrs(
if (!ra || cupsArrayFind(ra, "printer-icons"))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, printer_icons, sizeof(printer_icons),
- "http", NULL, con->servername, con->serverport,
+ "http", NULL, con->clientname, con->clientport,
"/icons/%s.png", printer->name);
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-icons",
NULL, printer_icons);
@@ -4974,17 +4950,15 @@ copy_printer_attrs(
}
if (!ra || cupsArrayFind(ra, "printer-is-accepting-jobs"))
- ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs",
- printer->accepting);
+ ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs", (char)printer->accepting);
if (!ra || cupsArrayFind(ra, "printer-is-shared"))
- ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared",
- printer->shared);
+ ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared", (char)printer->shared);
if (!ra || cupsArrayFind(ra, "printer-more-info"))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
- "http", NULL, con->servername, con->serverport,
+ "http", NULL, con->clientname, con->clientport,
(printer->type & CUPS_PRINTER_CLASS) ?
"/classes/%s" : "/printers/%s", printer->name);
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI,
@@ -4999,6 +4973,9 @@ copy_printer_attrs(
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
printer->state);
+ if (!ra || cupsArrayFind(ra, "printer-state-change-date-time"))
+ ippAddDate(con->response, IPP_TAG_PRINTER, "printer-state-change-date-time", ippTimeToDate(printer->state_time));
+
if (!ra || cupsArrayFind(ra, "printer-state-change-time"))
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"printer-state-change-time", printer->state_time);
@@ -5012,7 +4989,7 @@ copy_printer_attrs(
if (!ra || cupsArrayFind(ra, "printer-type"))
{
- int type; /* printer-type value */
+ cups_ptype_t type; /* printer-type value */
/*
* Add the CUPS-specific printer-type attribute...
@@ -5029,8 +5006,7 @@ copy_printer_attrs(
if (!printer->shared)
type |= CUPS_PRINTER_NOT_SHARED;
- ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type",
- type);
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type", (int)type);
}
if (!ra || cupsArrayFind(ra, "printer-up-time"))
@@ -5040,7 +5016,7 @@ copy_printer_attrs(
if (!ra || cupsArrayFind(ra, "printer-uri-supported"))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
- "ipp", NULL, con->servername, con->serverport,
+ "ipp", NULL, con->clientname, con->clientport,
(printer->type & CUPS_PRINTER_CLASS) ?
"/classes/%s" : "/printers/%s", printer->name);
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI,
@@ -5167,7 +5143,7 @@ copy_subscription_attrs(
if (sub->dest && (!ra || cupsArrayFind(ra, "notify-printer-uri")))
{
httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri),
- "ipp", NULL, con->servername, con->serverport,
+ "ipp", NULL, con->clientname, con->clientport,
"/printers/%s", sub->dest->name);
ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
"notify-printer-uri", NULL, printer_uri);
@@ -5200,7 +5176,7 @@ create_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -5265,251 +5241,34 @@ create_job(cupsd_client_t *con, /* I - Client connection */
static cups_array_t * /* O - Array of attributes or NULL */
create_requested_array(ipp_t *request) /* I - IPP request */
{
- int i; /* Looping var */
- ipp_attribute_t *requested; /* requested-attributes attribute */
cups_array_t *ra; /* Requested attributes array */
- char *value; /* Current value */
/*
- * Get the requested-attributes attribute, and return NULL if we don't
- * have one...
+ * Create the array for standard attributes...
*/
- if ((requested = ippFindAttribute(request, "requested-attributes",
- IPP_TAG_KEYWORD)) == NULL)
- return (NULL);
+ ra = ippCreateRequestedArray(request);
/*
- * If the attribute contains a single "all" keyword, return NULL...
+ * Add CUPS defaults as needed...
*/
- if (requested->num_values == 1 &&
- !strcmp(requested->values[0].string.text, "all"))
- return (NULL);
+ if (cupsArrayFind(ra, "printer-defaults"))
+ {
+ /*
+ * Include user-set defaults...
+ */
- /*
- * Create an array using "strcmp" as the comparison function...
- */
-
- ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
-
- for (i = 0; i < requested->num_values; i ++)
- {
- value = requested->values[i].string.text;
-
- 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");
- cupsArrayAdd(ra, "finishings");
- cupsArrayAdd(ra, "finishings-default");
- cupsArrayAdd(ra, "finishings-supported");
- cupsArrayAdd(ra, "job-hold-until");
- cupsArrayAdd(ra, "job-hold-until-default");
- cupsArrayAdd(ra, "job-hold-until-supported");
- cupsArrayAdd(ra, "job-priority");
- cupsArrayAdd(ra, "job-priority-default");
- cupsArrayAdd(ra, "job-priority-supported");
- cupsArrayAdd(ra, "job-sheets");
- 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");
- cupsArrayAdd(ra, "multiple-document-handling-default");
- 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, "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");
- cupsArrayAdd(ra, "job-detailed-status-message");
- cupsArrayAdd(ra, "job-document-access-errors");
- cupsArrayAdd(ra, "job-id");
- cupsArrayAdd(ra, "job-impressions");
- 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");
- cupsArrayAdd(ra, "job-message-from-operator");
- cupsArrayAdd(ra, "job-more-info");
- cupsArrayAdd(ra, "job-name");
- cupsArrayAdd(ra, "job-originating-user-name");
- cupsArrayAdd(ra, "job-printer-up-time");
- cupsArrayAdd(ra, "job-printer-uri");
- cupsArrayAdd(ra, "job-state");
- cupsArrayAdd(ra, "job-state-message");
- cupsArrayAdd(ra, "job-state-reasons");
- cupsArrayAdd(ra, "job-uri");
- cupsArrayAdd(ra, "number-of-documents");
- cupsArrayAdd(ra, "number-of-intervening-jobs");
- cupsArrayAdd(ra, "output-device-assigned");
- cupsArrayAdd(ra, "time-at-completed");
- cupsArrayAdd(ra, "time-at-creation");
- cupsArrayAdd(ra, "time-at-processing");
- }
- 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");
- cupsArrayAdd(ra, "compression-supported");
- cupsArrayAdd(ra, "document-format-default");
- 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-max-events-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-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-type");
- cupsArrayAdd(ra, "printer-up-time");
- cupsArrayAdd(ra, "printer-uri-supported");
- cupsArrayAdd(ra, "queued-job-count");
- 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"))
- {
- char *name; /* Option name */
-
-
- for (name = (char *)cupsArrayFirst(CommonDefaults);
- name;
- name = (char *)cupsArrayNext(CommonDefaults))
+ char *name; /* Option name */
+
+ cupsArrayRemove(ra, "printer-defaults");
+
+ for (name = (char *)cupsArrayFirst(CommonDefaults);
+ name;
+ name = (char *)cupsArrayNext(CommonDefaults))
+ if (!cupsArrayFind(ra, name))
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");
- }
- else
- cupsArrayAdd(ra, value);
}
return (ra);
@@ -5517,11 +5276,11 @@ create_requested_array(ipp_t *request) /* I - IPP request */
/*
- * 'create_subscription()' - Create a notification subscription.
+ * 'create_subscriptions()' - Create one or more notification subscriptions.
*/
static void
-create_subscription(
+create_subscriptions(
cupsd_client_t *con, /* I - Client connection */
ipp_attribute_t *uri) /* I - Printer URI */
{
@@ -5569,9 +5328,7 @@ create_subscription(
* Is the destination valid?
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "cupsdCreateSubscription(con=%p(%d), uri=\"%s\")",
- con, con->http.fd, uri->values[0].string.text);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "create_subscriptions(con=%p(%d), uri=\"%s\")", con, con->number, uri->values[0].string.text);
httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme,
sizeof(scheme), userpass, sizeof(userpass), host,
@@ -5822,7 +5579,7 @@ create_subscription(
if (MaxLeaseDuration && (lease == 0 || lease > MaxLeaseDuration))
{
cupsdLogMessage(CUPSD_LOG_INFO,
- "create_subscription: Limiting notify-lease-duration to "
+ "create_subscriptions: Limiting notify-lease-duration to "
"%d seconds.",
MaxLeaseDuration);
lease = MaxLeaseDuration;
@@ -5868,7 +5625,7 @@ create_subscription(
{
sub->user_data_len = user_data->values[0].unknown.length;
memcpy(sub->user_data, user_data->values[0].unknown.data,
- sub->user_data_len);
+ (size_t)sub->user_data_len);
}
ippAddSeparator(con->response);
@@ -5900,7 +5657,7 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "delete_printer(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Do we have a valid URI?
@@ -5951,10 +5708,16 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */
snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot,
printer->name);
unlink(filename);
+ snprintf(filename, sizeof(filename), "%s/interfaces/%s.O", ServerRoot,
+ printer->name);
+ unlink(filename);
snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
printer->name);
unlink(filename);
+ snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd.O", ServerRoot,
+ printer->name);
+ unlink(filename);
snprintf(filename, sizeof(filename), "%s/%s.png", CacheDir, printer->name);
unlink(filename);
@@ -6008,7 +5771,7 @@ get_default(cupsd_client_t *con) /* I - Client connection */
cups_array_t *ra; /* Requested attributes array */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_default(%p[%d])", con, con->http.fd);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_default(%p[%d])", con, con->number);
/*
* Check policy...
@@ -6058,7 +5821,7 @@ get_devices(cupsd_client_t *con) /* I - Client connection */
/* String for included schemes */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_devices(%p[%d])", con, con->http.fd);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_devices(%p[%d])", con, con->number);
/*
* Check policy...
@@ -6152,7 +5915,7 @@ get_document(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_document(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* See if we have a job URI or a printer URI...
@@ -6299,7 +6062,7 @@ get_job_attrs(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_job_attrs(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* See if we have a job URI or a printer URI...
@@ -6413,19 +6176,24 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
int port; /* Port portion of URI */
int job_comparison; /* Job comparison */
ipp_jstate_t job_state; /* job-state value */
- int first_job_id; /* First job ID */
- int limit; /* Maximum number of jobs to return */
+ int first_job_id = 1, /* First job ID */
+ first_index = 1, /* First index */
+ current_index = 0; /* Current index */
+ int limit = 0; /* Maximum number of jobs to return */
int count; /* Number of jobs that match */
+ int need_load_job = 0; /* Do we need to load the job? */
+ const char *job_attr; /* Job attribute requested */
ipp_attribute_t *job_ids; /* job-ids attribute */
cupsd_job_t *job; /* Current job pointer */
cupsd_printer_t *printer; /* Printer */
cups_array_t *list; /* Which job list... */
+ int delete_list = 0; /* Delete the list afterwards? */
cups_array_t *ra, /* Requested attributes array */
*exclude; /* Private attributes array */
cupsd_policy_t *policy; /* Current policy */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs(%p[%d], %s)", con, con->http.fd,
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs(%p[%d], %s)", con, con->number,
uri->values[0].string.text);
/*
@@ -6513,19 +6281,21 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
{
job_comparison = -1;
job_state = IPP_JOB_STOPPED;
- list = Jobs;
+ list = ActiveJobs;
}
else if (!strcmp(attr->values[0].string.text, "completed"))
{
job_comparison = 1;
job_state = IPP_JOB_CANCELED;
- list = Jobs;
+ list = cupsdGetCompletedJobs(printer);
+ delete_list = 1;
}
else if (!strcmp(attr->values[0].string.text, "aborted"))
{
job_comparison = 0;
job_state = IPP_JOB_ABORTED;
- list = Jobs;
+ list = cupsdGetCompletedJobs(printer);
+ delete_list = 1;
}
else if (!strcmp(attr->values[0].string.text, "all"))
{
@@ -6537,7 +6307,8 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
{
job_comparison = 0;
job_state = IPP_JOB_CANCELED;
- list = Jobs;
+ list = cupsdGetCompletedJobs(printer);
+ delete_list = 1;
}
else if (!strcmp(attr->values[0].string.text, "pending"))
{
@@ -6577,8 +6348,7 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
* See if they want to limit the number of jobs reported...
*/
- if ((attr = ippFindAttribute(con->request, "limit",
- IPP_TAG_INTEGER)) != NULL)
+ if ((attr = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER)) != NULL)
{
if (job_ids)
{
@@ -6590,11 +6360,20 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
limit = attr->values[0].integer;
}
- else
- limit = 0;
- if ((attr = ippFindAttribute(con->request, "first-job-id",
- IPP_TAG_INTEGER)) != NULL)
+ if ((attr = ippFindAttribute(con->request, "first-index", IPP_TAG_INTEGER)) != NULL)
+ {
+ if (job_ids)
+ {
+ send_ipp_status(con, IPP_CONFLICT,
+ _("The %s attribute cannot be provided with job-ids."),
+ "first-index");
+ return;
+ }
+
+ first_index = attr->values[0].integer;
+ }
+ else if ((attr = ippFindAttribute(con->request, "first-job-id", IPP_TAG_INTEGER)) != NULL)
{
if (job_ids)
{
@@ -6606,15 +6385,12 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
first_job_id = attr->values[0].integer;
}
- else
- first_job_id = 1;
/*
* See if we only want to see jobs for a specific user...
*/
- if ((attr = ippFindAttribute(con->request, "my-jobs",
- IPP_TAG_BOOLEAN)) != NULL && job_ids)
+ if ((attr = ippFindAttribute(con->request, "my-jobs", IPP_TAG_BOOLEAN)) != NULL && job_ids)
{
send_ipp_status(con, IPP_CONFLICT,
_("The %s attribute cannot be provided with job-ids."),
@@ -6626,17 +6402,42 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
else
username[0] = '\0';
- if ((ra = create_requested_array(con->request)) == NULL &&
- !ippFindAttribute(con->request, "requested-attributes", IPP_TAG_KEYWORD))
+ ra = create_requested_array(con->request);
+ for (job_attr = (char *)cupsArrayFirst(ra); job_attr; job_attr = (char *)cupsArrayNext(ra))
+ if (strcmp(job_attr, "job-id") &&
+ strcmp(job_attr, "job-k-octets") &&
+ strcmp(job_attr, "job-media-progress") &&
+ strcmp(job_attr, "job-more-info") &&
+ strcmp(job_attr, "job-name") &&
+ strcmp(job_attr, "job-originating-user-name") &&
+ strcmp(job_attr, "job-preserved") &&
+ strcmp(job_attr, "job-printer-up-time") &&
+ strcmp(job_attr, "job-printer-uri") &&
+ strcmp(job_attr, "job-state") &&
+ strcmp(job_attr, "job-state-reasons") &&
+ strcmp(job_attr, "job-uri") &&
+ strcmp(job_attr, "time-at-completed") &&
+ strcmp(job_attr, "time-at-creation") &&
+ strcmp(job_attr, "number-of-documents"))
+ {
+ need_load_job = 1;
+ break;
+ }
+
+ if (need_load_job && (limit == 0 || limit > 500) && (list == Jobs || delete_list))
{
/*
- * IPP conformance - Get-Jobs has a default requested-attributes value of
- * "job-id" and "job-uri".
+ * Limit expensive Get-Jobs for job history to 500 jobs...
*/
- ra = cupsArrayNew((cups_array_func_t)strcmp, NULL);
- cupsArrayAdd(ra, "job-id");
- cupsArrayAdd(ra, "job-uri");
+ ippAddInteger(con->response, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "limit", 500);
+
+ if (limit)
+ ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER, "limit", limit);
+
+ limit = 500;
+
+ cupsdLogClient(con, CUPSD_LOG_INFO, "Limiting Get-Jobs response to %d jobs.", limit);
}
/*
@@ -6664,13 +6465,15 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
{
job = cupsdFindJob(job_ids->values[i].integer);
- cupsdLoadJob(job);
-
- if (!job->attrs)
+ if (need_load_job && !job->attrs)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d",
- job->id);
- continue;
+ cupsdLoadJob(job);
+
+ if (!job->attrs)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d", job->id);
+ continue;
+ }
}
if (i > 0)
@@ -6720,13 +6523,19 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
if (job->id < first_job_id)
continue;
- cupsdLoadJob(job);
+ current_index ++;
+ if (current_index < first_index)
+ continue;
- if (!job->attrs)
+ if (need_load_job && !job->attrs)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d",
- job->id);
- continue;
+ cupsdLoadJob(job);
+
+ if (!job->attrs)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d", job->id);
+ continue;
+ }
}
if (username[0] && _cups_strcasecmp(username, job->username))
@@ -6750,6 +6559,9 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */
cupsArrayDelete(ra);
+ if (delete_list)
+ cupsArrayDelete(list);
+
con->response->request.status.status_code = IPP_OK;
}
@@ -6771,7 +6583,7 @@ get_notifications(cupsd_client_t *con) /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_notifications(con=%p[%d])",
- con, con->http.fd);
+ con, con->number);
/*
* Get subscription attributes...
@@ -6905,7 +6717,7 @@ get_ppd(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppd(%p[%d], %p[%s=%s])", con,
- con->http.fd, uri, uri->name, uri->values[0].string.text);
+ con->number, uri, uri->name, uri->values[0].string.text);
if (!strcmp(uri->name, "ppd-name"))
{
@@ -7078,7 +6890,7 @@ get_ppds(cupsd_client_t *con) /* I - Client connection */
/* String for included schemes */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->http.fd);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->number);
/*
* Check policy...
@@ -7223,7 +7035,7 @@ get_printer_attrs(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_attrs(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -7279,7 +7091,7 @@ get_printer_supported(
cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_supported(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -7311,9 +7123,15 @@ get_printer_supported(
*/
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ADMINDEFINE,
+ "printer-geo-location", 0);
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ADMINDEFINE,
"printer-info", 0);
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ADMINDEFINE,
"printer-location", 0);
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ADMINDEFINE,
+ "printer-organization", 0);
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ADMINDEFINE,
+ "printer-organizational-unit", 0);
con->response->request.status.status_code = IPP_OK;
}
@@ -7332,7 +7150,7 @@ get_printers(cupsd_client_t *con, /* I - Client connection */
int limit; /* Max number of printers to return */
int count; /* Number of printers that match */
cupsd_printer_t *printer; /* Current printer pointer */
- int printer_type, /* printer-type attribute */
+ cups_ptype_t printer_type, /* printer-type attribute */
printer_mask; /* printer-type-mask attribute */
char *location; /* Location string */
const char *username; /* Current user */
@@ -7342,7 +7160,7 @@ get_printers(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printers(%p[%d], %x)", con,
- con->http.fd, type);
+ con->number, type);
/*
* Check policy...
@@ -7386,15 +7204,15 @@ get_printers(cupsd_client_t *con, /* I - Client connection */
if ((attr = ippFindAttribute(con->request, "printer-type",
IPP_TAG_ENUM)) != NULL)
- printer_type = attr->values[0].integer;
+ printer_type = (cups_ptype_t)attr->values[0].integer;
else
- printer_type = 0;
+ printer_type = (cups_ptype_t)0;
if ((attr = ippFindAttribute(con->request, "printer-type-mask",
IPP_TAG_ENUM)) != NULL)
- printer_mask = attr->values[0].integer;
+ printer_mask = (cups_ptype_t)attr->values[0].integer;
else
- printer_mask = 0;
+ printer_mask = (cups_ptype_t)0;
local = httpAddrLocalhost(&(con->clientaddr));
@@ -7488,7 +7306,7 @@ get_subscription_attrs(
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"get_subscription_attrs(con=%p[%d], sub_id=%d)",
- con, con->http.fd, sub_id);
+ con, con->number, sub_id);
/*
* Is the subscription ID valid?
@@ -7569,7 +7387,7 @@ get_subscriptions(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"get_subscriptions(con=%p[%d], uri=%s)",
- con, con->http.fd, uri->values[0].string.text);
+ con, con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -7730,7 +7548,7 @@ hold_job(cupsd_client_t *con, /* I - Client connection */
cupsd_job_t *job; /* Job information */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_job(%p[%d], %s)", con, con->http.fd,
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_job(%p[%d], %s)", con, con->number,
uri->values[0].string.text);
/*
@@ -7859,7 +7677,7 @@ hold_new_jobs(cupsd_client_t *con, /* I - Connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_new_jobs(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -7935,7 +7753,7 @@ move_job(cupsd_client_t *con, /* I - Client connection */
*dprinter; /* Destination printer */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "move_job(%p[%d], %s)", con, con->http.fd,
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "move_job(%p[%d], %s)", con, con->number,
uri->values[0].string.text);
/*
@@ -8248,6 +8066,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */
ipp_attribute_t *uri) /* I - Printer URI */
{
ipp_attribute_t *attr; /* Current attribute */
+ ipp_attribute_t *doc_name; /* document-name attribute */
ipp_attribute_t *format; /* Document-format attribute */
const char *default_format; /* document-format-default value */
cupsd_job_t *job; /* New job */
@@ -8263,7 +8082,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */
int compression; /* Document compression */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "print_job(%p[%d], %s)", con, con->http.fd,
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "print_job(%p[%d], %s)", con, con->number,
uri->values[0].string.text);
/*
@@ -8325,6 +8144,10 @@ print_job(cupsd_client_t *con, /* I - Client connection */
* Is it a format we support?
*/
+ doc_name = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME);
+ if (doc_name)
+ ippSetName(con->request, &doc_name, "document-name-supplied");
+
if ((format = ippFindAttribute(con->request, "document-format",
IPP_TAG_MIMETYPE)) != NULL)
{
@@ -8340,6 +8163,8 @@ print_job(cupsd_client_t *con, /* I - Client connection */
format->values[0].string.text);
return;
}
+
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format-supplied", NULL, ippGetString(format, 0, NULL));
}
else if ((default_format = cupsGetOption("document-format",
printer->num_options,
@@ -8363,8 +8188,8 @@ print_job(cupsd_client_t *con, /* I - Client connection */
* Auto-type it!
*/
- strcpy(super, "application");
- strcpy(type, "octet-stream");
+ strlcpy(super, "application", sizeof(super));
+ strlcpy(type, "octet-stream", sizeof(type));
}
if (!strcmp(super, "application") && !strcmp(type, "octet-stream"))
@@ -8373,12 +8198,9 @@ print_job(cupsd_client_t *con, /* I - Client connection */
* Auto-type the file...
*/
- ipp_attribute_t *doc_name; /* document-name attribute */
-
-
cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job ???] Auto-typing file...");
- doc_name = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME);
+
filetype = mimeFileType(MimeDatabase, con->filename,
doc_name ? doc_name->values[0].string.text : NULL,
&compression);
@@ -8388,6 +8210,9 @@ print_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_INFO, "[Job ???] Request file type is %s/%s.",
filetype->super, filetype->type);
+
+ snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, filetype->type);
+ ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format-detected", NULL, mimetype);
}
else
filetype = mimeType(MimeDatabase, super, type);
@@ -8405,11 +8230,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */
filetype->type);
if (format)
- {
- _cupsStrFree(format->values[0].string.text);
-
- format->values[0].string.text = _cupsStrAlloc(mimetype);
- }
+ ippSetString(con->request, &format, 0, mimetype);
else
ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
"document-format", NULL, mimetype);
@@ -8457,8 +8278,9 @@ print_job(cupsd_client_t *con, /* I - Client connection */
cupsdUpdateQuota(printer, job->username, 0, kbytes);
- if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
- IPP_TAG_INTEGER)) != NULL)
+ job->koctets += kbytes;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
attr->values[0].integer += kbytes;
/*
@@ -8468,9 +8290,15 @@ print_job(cupsd_client_t *con, /* I - Client connection */
if (add_file(con, job, filetype, compression))
return;
- snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id,
- job->num_files);
- rename(con->filename, filename);
+ snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id, job->num_files);
+ if (rename(con->filename, filename))
+ {
+ cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to rename job document file \"%s\": %s", filename, strerror(errno));
+
+ send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to rename job document file."));
+ return;
+ }
+
cupsdClearString(&con->filename);
/*
@@ -8629,12 +8457,17 @@ read_job_ticket(cupsd_client_t *con) /* I - Client connection */
if (attr->group_tag != IPP_TAG_JOB || !attr->name)
continue;
- if (!strcmp(attr->name, "job-originating-host-name") ||
- !strcmp(attr->name, "job-originating-user-name") ||
+ if (!strncmp(attr->name, "date-time-at-", 13) ||
+ !strcmp(attr->name, "job-impressions-completed") ||
!strcmp(attr->name, "job-media-sheets-completed") ||
- !strcmp(attr->name, "job-k-octets") ||
+ !strncmp(attr->name, "job-k-octets", 12) ||
!strcmp(attr->name, "job-id") ||
+ !strcmp(attr->name, "job-originating-host-name") ||
+ !strcmp(attr->name, "job-originating-user-name") ||
+ !strcmp(attr->name, "job-pages-completed") ||
+ !strcmp(attr->name, "job-printer-uri") ||
!strncmp(attr->name, "job-state", 9) ||
+ !strcmp(attr->name, "job-uri") ||
!strncmp(attr->name, "time-at-", 8))
continue; /* Read-only attrs */
@@ -8697,7 +8530,7 @@ reject_jobs(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "reject_jobs(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -8732,7 +8565,8 @@ reject_jobs(cupsd_client_t *con, /* I - Client connection */
if ((attr = ippFindAttribute(con->request, "printer-state-message",
IPP_TAG_TEXT)) == NULL)
- strcpy(printer->state_message, "Rejecting Jobs");
+ strlcpy(printer->state_message, "Rejecting Jobs",
+ sizeof(printer->state_message));
else
strlcpy(printer->state_message, attr->values[0].string.text,
sizeof(printer->state_message));
@@ -8778,7 +8612,7 @@ release_held_new_jobs(
cupsdLogMessage(CUPSD_LOG_DEBUG2, "release_held_new_jobs(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -8849,7 +8683,7 @@ release_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "release_job(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* See if we have a job URI or a printer URI...
@@ -8944,10 +8778,8 @@ release_job(cupsd_client_t *con, /* I - Client connection */
if (attr)
{
- _cupsStrFree(attr->values[0].string.text);
-
- attr->value_tag = IPP_TAG_KEYWORD;
- attr->values[0].string.text = _cupsStrAlloc("no-hold");
+ ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD);
+ ippSetString(job->attrs, &attr, 0, "no-hold");
cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
"Job job-hold-until value changed by user.");
@@ -8987,7 +8819,7 @@ renew_subscription(
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"renew_subscription(con=%p[%d], sub_id=%d)",
- con, con->http.fd, sub_id);
+ con, con->number, sub_id);
/*
* Is the subscription ID valid?
@@ -9075,7 +8907,7 @@ restart_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "restart_job(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* See if we have a job URI or a printer URI...
@@ -9299,8 +9131,7 @@ save_auth_info(
{
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));
+ httpEncode64_2(line, sizeof(line), auth_info->values[i].string.text, (int)strlen(auth_info->values[i].string.text));
cupsFilePutConf(fp, dest->auth_info_required[i], line);
}
else
@@ -9331,15 +9162,13 @@ save_auth_info(
* Allow fallback to username+password for Kerberized queues...
*/
- httpEncode64_2(line, sizeof(line), auth_info->values[0].string.text,
- strlen(auth_info->values[0].string.text));
+ httpEncode64_2(line, sizeof(line), auth_info->values[0].string.text, (int)strlen(auth_info->values[0].string.text));
cupsFilePutConf(fp, "username", line);
cupsdSetStringf(job->auth_env + 0, "AUTH_USERNAME=%s",
auth_info->values[0].string.text);
- httpEncode64_2(line, sizeof(line), auth_info->values[1].string.text,
- strlen(auth_info->values[1].string.text));
+ httpEncode64_2(line, sizeof(line), auth_info->values[1].string.text, (int)strlen(auth_info->values[1].string.text));
cupsFilePutConf(fp, "password", line);
cupsdSetStringf(job->auth_env + 1, "AUTH_PASSWORD=%s",
@@ -9351,7 +9180,7 @@ save_auth_info(
* Write the authenticated username...
*/
- httpEncode64_2(line, sizeof(line), con->username, strlen(con->username));
+ httpEncode64_2(line, sizeof(line), con->username, (int)strlen(con->username));
cupsFilePutConf(fp, "username", line);
cupsdSetStringf(job->auth_env + 0, "AUTH_USERNAME=%s", con->username);
@@ -9360,7 +9189,7 @@ save_auth_info(
* Write the authenticated password...
*/
- httpEncode64_2(line, sizeof(line), con->password, strlen(con->password));
+ httpEncode64_2(line, sizeof(line), con->password, (int)strlen(con->password));
cupsFilePutConf(fp, "password", line);
cupsdSetStringf(job->auth_env + 1, "AUTH_PASSWORD=%s", con->password);
@@ -9430,7 +9259,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_document(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* See if we have a job URI or a printer URI...
@@ -9562,6 +9391,8 @@ send_document(cupsd_client_t *con, /* I - Client connection */
* Is it a format we support?
*/
+ cupsdLoadJob(job);
+
if ((format = ippFindAttribute(con->request, "document-format",
IPP_TAG_MIMETYPE)) != NULL)
{
@@ -9576,6 +9407,8 @@ send_document(cupsd_client_t *con, /* I - Client connection */
format->values[0].string.text);
return;
}
+
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format-supplied", NULL, ippGetString(format, 0, NULL));
}
else if ((default_format = cupsGetOption("document-format",
printer->num_options,
@@ -9598,8 +9431,8 @@ send_document(cupsd_client_t *con, /* I - Client connection */
* No document format attribute? Auto-type it!
*/
- strcpy(super, "application");
- strcpy(type, "octet-stream");
+ strlcpy(super, "application", sizeof(super));
+ strlcpy(type, "octet-stream", sizeof(type));
}
if (!strcmp(super, "application") && !strcmp(type, "octet-stream"))
@@ -9624,6 +9457,9 @@ send_document(cupsd_client_t *con, /* I - Client connection */
if (filetype)
cupsdLogJob(job, CUPSD_LOG_DEBUG, "Request file type is %s/%s.",
filetype->super, filetype->type);
+
+ snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, filetype->type);
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format-detected", NULL, mimetype);
}
else
filetype = mimeType(MimeDatabase, super, type);
@@ -9640,11 +9476,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */
if ((jformat = ippFindAttribute(job->attrs, "document-format",
IPP_TAG_MIMETYPE)) != NULL)
- {
- _cupsStrFree(jformat->values[0].string.text);
-
- jformat->values[0].string.text = _cupsStrAlloc(mimetype);
- }
+ ippSetString(job->attrs, &jformat, 0, mimetype);
else
ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
"document-format", NULL, mimetype);
@@ -9681,11 +9513,12 @@ send_document(cupsd_client_t *con, /* I - Client connection */
* Add the file to the job...
*/
- cupsdLoadJob(job);
-
if (add_file(con, job, filetype, compression))
return;
+ if ((attr = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME)) != NULL)
+ ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "document-name-supplied", NULL, ippGetString(attr, 0, NULL));
+
if (stat(con->filename, &fileinfo))
kbytes = 0;
else
@@ -9693,13 +9526,19 @@ send_document(cupsd_client_t *con, /* I - Client connection */
cupsdUpdateQuota(printer, job->username, 0, kbytes);
- if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
- IPP_TAG_INTEGER)) != NULL)
+ job->koctets += kbytes;
+
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
attr->values[0].integer += kbytes;
- snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id,
- job->num_files);
- rename(con->filename, filename);
+ snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id, job->num_files);
+ if (rename(con->filename, filename))
+ {
+ cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to rename job document file \"%s\": %s", filename, strerror(errno));
+
+ send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to rename job document file."));
+ return;
+ }
cupsdClearString(&con->filename);
@@ -9778,7 +9617,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */
*/
httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
- con->servername, con->serverport, "/jobs/%d", jobid);
+ con->clientname, con->clientport, "/jobs/%d", jobid);
ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL,
job_uri);
@@ -9818,13 +9657,13 @@ send_http_error(
uri = ippFindAttribute(con->request, "job-uri", IPP_TAG_URI);
cupsdLogMessage(status == HTTP_FORBIDDEN ? CUPSD_LOG_ERROR : CUPSD_LOG_DEBUG,
- "Returning HTTP %s for %s (%s) from %s",
- httpStatus(status),
+ "[Client %d] Returning HTTP %s for %s (%s) from %s",
+ con->number, httpStatus(status),
con->request ?
ippOpString(con->request->request.op.operation_id) :
"no operation-id",
uri ? uri->values[0].string.text : "no URI",
- con->http.hostname);
+ con->http->hostname);
if (printer)
{
@@ -9945,7 +9784,7 @@ set_default(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_default(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -10027,7 +9866,7 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_job_attrs(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Start with "everything is OK" status...
@@ -10135,15 +9974,18 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */
if (!strcmp(attr->name, "attributes-charset") ||
!strcmp(attr->name, "attributes-natural-language") ||
- !strcmp(attr->name, "document-compression") ||
- !strcmp(attr->name, "document-format") ||
+ !strncmp(attr->name, "date-time-at-", 13) ||
+ !strncmp(attr->name, "document-compression", 20) ||
+ !strncmp(attr->name, "document-format", 15) ||
!strcmp(attr->name, "job-detailed-status-messages") ||
!strcmp(attr->name, "job-document-access-errors") ||
!strcmp(attr->name, "job-id") ||
!strcmp(attr->name, "job-impressions-completed") ||
- !strcmp(attr->name, "job-k-octets") ||
+ !strcmp(attr->name, "job-k-octets-completed") ||
+ !strcmp(attr->name, "job-media-sheets-completed") ||
!strcmp(attr->name, "job-originating-host-name") ||
!strcmp(attr->name, "job-originating-user-name") ||
+ !strcmp(attr->name, "job-pages-completed") ||
!strcmp(attr->name, "job-printer-up-time") ||
!strcmp(attr->name, "job-printer-uri") ||
!strcmp(attr->name, "job-sheets") ||
@@ -10153,9 +9995,6 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */
!strcmp(attr->name, "number-of-documents") ||
!strcmp(attr->name, "number-of-intervening-jobs") ||
!strcmp(attr->name, "output-device-assigned") ||
- !strncmp(attr->name, "date-time-at-", 13) ||
- !strncmp(attr->name, "job-k-octets", 12) ||
- !strncmp(attr->name, "job-media-sheets", 16) ||
!strncmp(attr->name, "time-at-", 8))
{
/*
@@ -10229,9 +10068,7 @@ set_job_attrs(cupsd_client_t *con, /* I - Client connection */
{
cupsdLogJob(job, CUPSD_LOG_DEBUG, "Setting job-state to %d",
attr->values[0].integer);
- cupsdSetJobState(job, attr->values[0].integer,
- CUPSD_JOB_DEFAULT,
- "Job state changed by \"%s\"", username);
+ cupsdSetJobState(job, (ipp_jstate_t)attr->values[0].integer, CUPSD_JOB_DEFAULT, "Job state changed by \"%s\"", username);
check_jobs = 1;
}
break;
@@ -10399,7 +10236,7 @@ set_printer_attrs(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_printer_attrs(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -10437,6 +10274,24 @@ set_printer_attrs(cupsd_client_t *con, /* I - Client connection */
changed = 1;
}
+ if ((attr = ippFindAttribute(con->request, "printer-geo-location", IPP_TAG_URI)) != NULL && !strncmp(attr->values[0].string.text, "geo:", 4))
+ {
+ cupsdSetString(&printer->geo_location, attr->values[0].string.text);
+ changed = 1;
+ }
+
+ if ((attr = ippFindAttribute(con->request, "printer-organization", IPP_TAG_TEXT)) != NULL)
+ {
+ cupsdSetString(&printer->organization, attr->values[0].string.text);
+ changed = 1;
+ }
+
+ if ((attr = ippFindAttribute(con->request, "printer-organizational-unit", IPP_TAG_TEXT)) != NULL)
+ {
+ cupsdSetString(&printer->organizational_unit, attr->values[0].string.text);
+ changed = 1;
+ }
+
if ((attr = ippFindAttribute(con->request, "printer-info",
IPP_TAG_TEXT)) != NULL)
{
@@ -10450,6 +10305,8 @@ set_printer_attrs(cupsd_client_t *con, /* I - Client connection */
if (changed)
{
+ printer->config_time = time(NULL);
+
cupsdSetPrinterAttrs(printer);
cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
@@ -10477,7 +10334,7 @@ set_printer_defaults(
{
int i; /* Looping var */
ipp_attribute_t *attr; /* Current attribute */
- int namelen; /* Length of attribute name */
+ size_t namelen; /* Length of attribute name */
char name[256], /* New attribute name */
value[256]; /* String version of integer attrs */
@@ -10652,6 +10509,7 @@ set_printer_defaults(
break;
case IPP_TAG_NAME :
+ case IPP_TAG_TEXT :
case IPP_TAG_KEYWORD :
case IPP_TAG_URI :
printer->num_options = cupsAddOption(name,
@@ -10729,7 +10587,7 @@ start_printer(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_printer(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -10811,7 +10669,7 @@ stop_printer(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "stop_printer(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* Is the destination valid?
@@ -10844,7 +10702,7 @@ stop_printer(cupsd_client_t *con, /* I - Client connection */
if ((attr = ippFindAttribute(con->request, "printer-state-message",
IPP_TAG_TEXT)) == NULL)
- strcpy(printer->state_message, "Paused");
+ strlcpy(printer->state_message, "Paused", sizeof(printer->state_message));
else
{
strlcpy(printer->state_message, attr->values[0].string.text,
@@ -10875,7 +10733,7 @@ stop_printer(cupsd_client_t *con, /* I - Client connection */
static void
url_encode_attr(ipp_attribute_t *attr, /* I - Attribute */
char *buffer,/* I - String buffer */
- int bufsize)/* I - Size of buffer */
+ size_t bufsize)/* I - Size of buffer */
{
int i; /* Looping var */
char *bufptr, /* Pointer into buffer */
@@ -10901,8 +10759,7 @@ url_encode_attr(ipp_attribute_t *attr, /* I - Attribute */
*bufptr++ = '\'';
- bufptr = url_encode_string(attr->values[i].string.text,
- bufptr, bufend - bufptr + 1);
+ bufptr = url_encode_string(attr->values[i].string.text, bufptr, (size_t)(bufend - bufptr + 1));
if (bufptr >= bufend)
break;
@@ -10921,7 +10778,7 @@ url_encode_attr(ipp_attribute_t *attr, /* I - Attribute */
static char * /* O - End of string */
url_encode_string(const char *s, /* I - String */
char *buffer, /* I - String buffer */
- int bufsize) /* I - Size of buffer */
+ size_t bufsize) /* I - Size of buffer */
{
char *bufptr, /* Pointer into buffer */
*bufend; /* End of buffer */
@@ -11039,8 +10896,10 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
ipp_attribute_t *uri) /* I - Printer URI */
{
http_status_t status; /* Policy status */
- ipp_attribute_t *attr, /* Current attribute */
- *auth_info; /* auth-info attribute */
+ ipp_attribute_t *attr; /* Current attribute */
+#ifdef HAVE_SSL
+ ipp_attribute_t *auth_info; /* auth-info attribute */
+#endif /* HAVE_SSL */
ipp_attribute_t *format, /* Document-format attribute */
*name; /* Job-name attribute */
cups_ptype_t dtype; /* Destination type (printer/class) */
@@ -11052,7 +10911,7 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "validate_job(%p[%d], %s)", con,
- con->http.fd, uri->values[0].string.text);
+ con->number, uri->values[0].string.text);
/*
* OK, see if the client is sending the document compressed - CUPS
@@ -11206,7 +11065,9 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
* Check policy...
*/
+#ifdef HAVE_SSL
auth_info = ippFindAttribute(con->request, "auth-info", IPP_TAG_TEXT);
+#endif /* HAVE_SSL */
if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK)
{
@@ -11221,8 +11082,8 @@ validate_job(cupsd_client_t *con, /* I - Client connection */
return;
}
#ifdef HAVE_SSL
- else if (auth_info && !con->http.tls &&
- !httpAddrLocalhost(con->http.hostaddr))
+ else if (auth_info && !con->http->tls &&
+ !httpAddrLocalhost(con->http->hostaddr))
{
/*
* Require encryption of auth-info over non-local connections...
@@ -11276,16 +11137,12 @@ validate_user(cupsd_job_t *job, /* I - Job */
cupsd_client_t *con, /* I - Client connection */
const char *owner, /* I - Owner of job/resource */
char *username, /* O - Authenticated username */
- int userlen) /* I - Length of username */
+ size_t userlen) /* I - Length of username */
{
cupsd_printer_t *printer; /* Printer for job */
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "validate_user(job=%d, con=%d, owner=\"%s\", username=%p, "
- "userlen=%d)",
- job->id, con ? con->http.fd : 0,
- owner ? owner : "(null)", username, userlen);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "validate_user(job=%d, con=%d, owner=\"%s\", username=%p, userlen=" CUPS_LLFMT ")", job->id, con ? con->number : 0, owner ? owner : "(null)", username, CUPS_LLCAST userlen);
/*
* Validate input...
@@ -11312,5 +11169,5 @@ validate_user(cupsd_job_t *job, /* I - Job */
/*
- * End of "$Id: ipp.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: ipp.c 12978 2015-11-17 19:29:52Z msweet $".
*/
diff --git a/scheduler/job.c b/scheduler/job.c
index d8f56b5..54ee4ed 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -1,71 +1,16 @@
/*
- * "$Id: job.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: job.c 12856 2015-08-31 14:27:39Z msweet $"
*
- * Job management routines for the CUPS scheduler.
+ * Job management routines for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 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:
- *
- * 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.
- * 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.
+ * 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/".
*/
/*
@@ -174,6 +119,7 @@ static mime_filter_t gziptoany_filter =
*/
static int compare_active_jobs(void *first, void *second, void *data);
+static int compare_completed_jobs(void *first, void *second, void *data);
static int compare_jobs(void *first, void *second, void *data);
static void dump_job_history(cupsd_job_t *job);
static void finalize_job(cupsd_job_t *job, int set_job_state);
@@ -267,8 +213,6 @@ cupsdCancelJobs(const char *dest, /* I - Destination to cancel */
"Job canceled by user.");
}
}
-
- cupsdCheckJobs();
}
@@ -289,10 +233,7 @@ cupsdCheckJobs(void)
curtime = time(NULL);
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdCheckJobs: %d active jobs, sleeping=%d, reload=%d, "
- "curtime=%ld", cupsArrayCount(ActiveJobs), Sleeping,
- NeedReload, (long)curtime);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckJobs: %d active jobs, sleeping=%d, ac-power=%d, reload=%d, curtime=%ld", cupsArrayCount(ActiveJobs), Sleeping, ACPower, NeedReload, (long)curtime);
for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
job;
@@ -312,8 +253,8 @@ cupsdCheckJobs(void)
if (job->kill_time && job->kill_time <= curtime)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Stopping unresponsive job.",
- job->id);
+ if (!job->completed)
+ cupsdLogJob(job, CUPSD_LOG_ERROR, "Stopping unresponsive job.");
stop_job(job, CUPSD_JOB_FORCE);
continue;
@@ -325,8 +266,15 @@ cupsdCheckJobs(void)
if (job->cancel_time && job->cancel_time <= curtime)
{
- cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_DEFAULT,
- "Canceling stuck job after %d seconds.", MaxJobTime);
+ int cancel_after; /* job-cancel-after value */
+
+ attr = ippFindAttribute(job->attrs, "job-cancel-after", IPP_TAG_INTEGER);
+ cancel_after = attr ? ippGetInteger(attr, 0) : MaxJobTime;
+
+ if (job->completed)
+ cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_FORCE, "Marking stuck job as completed after %d seconds.", cancel_after);
+ else
+ cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_DEFAULT, "Canceling stuck job after %d seconds.", cancel_after);
continue;
}
@@ -379,10 +327,7 @@ cupsdCheckJobs(void)
*/
if (job->state_value == IPP_JOB_PENDING && !NeedReload &&
-#ifndef kIOPMAssertionTypeDenySystemSleep
- !Sleeping &&
-#endif /* !kIOPMAssertionTypeDenySystemSleep */
- !DoingShutdown && !job->printer)
+ (!Sleeping || ACPower) && !DoingShutdown && !job->printer)
{
printer = cupsdFindDest(job->dest);
pclass = NULL;
@@ -430,7 +375,7 @@ cupsdCheckJobs(void)
if ((attr = ippFindAttribute(job->attrs, "job-actual-printer-uri",
IPP_TAG_URI)) != NULL)
- cupsdSetString(&attr->values[0].string.text, printer->uri);
+ ippSetString(job->attrs, &attr, 0, printer->uri);
else
ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI,
"job-actual-printer-uri", NULL, printer->uri);
@@ -445,7 +390,9 @@ cupsdCheckJobs(void)
* Start the job...
*/
+ cupsArraySave(ActiveJobs);
start_job(job, printer);
+ cupsArrayRestore(ActiveJobs);
}
}
}
@@ -495,6 +442,8 @@ cupsdCleanJobs(void)
cupsdLogJob(job, CUPSD_LOG_DEBUG, "Removing document files.");
remove_job_files(job);
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+
if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate)
JobHistoryUpdate = job->history_time;
}
@@ -542,6 +491,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
/* Pipes used between filters */
int envc; /* Number of environment variables */
struct stat fileinfo; /* Job file information */
+ int argc = 0; /* Number of arguments */
char **argv = NULL, /* Filter command-line arguments */
filename[1024], /* Job filename */
command[1024], /* Full path to command */
@@ -598,7 +548,6 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
memset(job->filters, 0, sizeof(job->filters));
-
if (job->printer->raw)
{
/*
@@ -614,14 +563,37 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
* Local jobs get filtered...
*/
+ mime_type_t *dst = job->printer->filetype;
+ /* Destination file type */
+
snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
job->id, job->current_file + 1);
if (stat(filename, &fileinfo))
fileinfo.st_size = 0;
- filters = mimeFilter2(MimeDatabase, job->filetypes[job->current_file],
- fileinfo.st_size, job->printer->filetype,
- &(job->cost));
+ if (job->retry_as_raster)
+ {
+ /*
+ * Need to figure out whether the printer supports image/pwg-raster or
+ * image/urf, and use the corresponding type...
+ */
+
+ char type[MIME_MAX_TYPE]; /* MIME media type for printer */
+
+ snprintf(type, sizeof(type), "%s/image/urf", job->printer->name);
+ if ((dst = mimeType(MimeDatabase, "printer", type)) == NULL)
+ {
+ snprintf(type, sizeof(type), "%s/image/pwg-raster", job->printer->name);
+ dst = mimeType(MimeDatabase, "printer", type);
+ }
+
+ if (dst)
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "Retrying job as \"%s\".", strchr(dst->type, '/') + 1);
+ else
+ cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to retry job using a supported raster format.");
+ }
+
+ filters = mimeFilter2(MimeDatabase, job->filetypes[job->current_file], (size_t)fileinfo.st_size, dst, &(job->cost));
if (!filters)
{
@@ -672,6 +644,9 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
"FINAL_CONTENT_TYPE=%s/%s", filter->dst->super,
filter->dst->type);
}
+ else
+ snprintf(final_content_type, sizeof(final_content_type),
+ "FINAL_CONTENT_TYPE=printer/%s", job->printer->name);
}
/*
@@ -757,9 +732,8 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
* Add decompression/raw filter as needed...
*/
- if ((!job->printer->raw && job->compressions[job->current_file]) ||
- (!filters && !job->printer->remote &&
- (job->num_files > 1 || !strncmp(job->printer->device_uri, "file:", 5))))
+ if (job->compressions[job->current_file] &&
+ (!job->printer->remote || job->num_files == 1))
{
/*
* Add gziptoany filter to the front of the list...
@@ -891,11 +865,11 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
*/
if (job->printer->remote)
- argv = calloc(7 + job->num_files, sizeof(char *));
+ argc = 6 + job->num_files;
else
- argv = calloc(8, sizeof(char *));
+ argc = 7;
- if (!argv)
+ if ((argv = calloc((size_t)argc + 1, sizeof(char *))) == NULL)
{
cupsdLogMessage(CUPSD_LOG_DEBUG, "Unable to allocate argument array - %s",
strerror(errno));
@@ -927,7 +901,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
{
snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
job->id, job->current_file + 1);
- argv[6] = filename;
+ argv[6] = strdup(filename);
}
for (i = 0; argv[i]; i ++)
@@ -941,7 +915,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
IPP_TAG_LANGUAGE);
#ifdef __APPLE__
- strcpy(apple_language, "APPLE_LANGUAGE=");
+ strlcpy(apple_language, "APPLE_LANGUAGE=", sizeof(apple_language));
_cupsAppleLanguage(attr->values[0].string.text,
apple_language + 15, sizeof(apple_language) - 15);
#endif /* __APPLE__ */
@@ -954,7 +928,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
* the POSIX locale...
*/
- strcpy(lang, "LANG=C");
+ strlcpy(lang, "LANG=C", sizeof(lang));
break;
case 2 :
@@ -1012,14 +986,14 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
* All of these strcpy's are safe because we allocated the psr string...
*/
- strcpy(printer_state_reasons, "PRINTER_STATE_REASONS=");
+ strlcpy(printer_state_reasons, "PRINTER_STATE_REASONS=", psrlen);
for (psrptr = printer_state_reasons + 22, i = 0;
i < job->printer->num_reasons;
i ++)
{
if (i)
*psrptr++ = ',';
- strcpy(psrptr, job->printer->reasons[i]);
+ strlcpy(psrptr, job->printer->reasons[i], psrlen - (size_t)(psrptr - printer_state_reasons));
psrptr += strlen(psrptr);
}
}
@@ -1131,9 +1105,6 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
* Now create processes for all of the filters...
*/
- cupsdSetPrinterReasons(job->printer, "-cups-missing-filter-warning,"
- "cups-insecure-filter-warning");
-
for (i = 0, slot = 0, filter = (mime_filter_t *)cupsArrayFirst(filters);
filter;
i ++, filter = (mime_filter_t *)cupsArrayNext(filters))
@@ -1229,8 +1200,13 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
cupsdLogJob(job, CUPSD_LOG_INFO, "Started filter %s (PID %d)", command,
pid);
- argv[6] = NULL;
- slot = !slot;
+ if (argv[6])
+ {
+ free(argv[6]);
+ argv[6] = NULL;
+ }
+
+ slot = !slot;
}
cupsArrayDelete(filters);
@@ -1257,7 +1233,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
else if (stat(command, &backinfo))
backroot = 0;
else
- backroot = !(backinfo.st_mode & (S_IRWXG | S_IRWXO));
+ backroot = !(backinfo.st_mode & (S_IWGRP | S_IRWXO));
argv[0] = job->printer->sanitized_device_uri;
@@ -1267,7 +1243,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
pid = cupsdStartProcess(command, argv, envp, filterfds[!slot][0],
filterfds[slot][1], job->status_pipes[1],
job->back_pipes[1], job->side_pipes[1],
- backroot, job->profile, job, &(job->backend));
+ backroot, job->bprofile, job, &(job->backend));
if (pid == 0)
{
@@ -1314,13 +1290,12 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
cupsdClosePipe(filterfds[slot]);
- if (job->printer->remote && job->num_files > 1)
- {
- for (i = 0; i < job->num_files; i ++)
- free(argv[i + 6]);
- }
+ for (i = 6; i < argc; i ++)
+ if (argv[i])
+ free(argv[i]);
free(argv);
+
if (printer_state_reasons)
free(printer_state_reasons);
@@ -1350,13 +1325,9 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
if (argv)
{
- if (job->printer->remote && job->num_files > 1)
- {
- for (i = 0; i < job->num_files; i ++)
- free(argv[i + 6]);
- }
-
- free(argv);
+ for (i = 6; i < argc; i ++)
+ if (argv[i])
+ free(argv[i]);
}
if (printer_state_reasons)
@@ -1485,6 +1456,30 @@ cupsdFindJob(int id) /* I - Job ID */
/*
+ * 'cupsdGetCompletedJobs()'- Generate a completed jobs list.
+ */
+
+cups_array_t * /* O - Array of jobs */
+cupsdGetCompletedJobs(
+ cupsd_printer_t *p) /* I - Printer */
+{
+ cups_array_t *list; /* Array of jobs */
+ cupsd_job_t *job; /* Current job */
+
+
+ list = cupsArrayNew(compare_completed_jobs, NULL);
+
+ for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
+ job;
+ job = (cupsd_job_t *)cupsArrayNext(Jobs))
+ if ((!p || !_cups_strcasecmp(p->name, job->dest)) && job->state_value >= IPP_JOB_STOPPED && job->completed_time)
+ cupsArrayAdd(list, job);
+
+ return (list);
+}
+
+
+/*
* 'cupsdGetPrinterJobCount()' - Get the number of pending, processing,
* or held jobs in a printer or class.
*/
@@ -1538,9 +1533,10 @@ void
cupsdLoadAllJobs(void)
{
char filename[1024]; /* Full filename of job.cache file */
- struct stat fileinfo, /* Information on job.cache file */
- dirinfo; /* Information on RequestRoot dir */
-
+ struct stat fileinfo; /* Information on job.cache file */
+ cups_dir_t *dir; /* RequestRoot dir */
+ cups_dentry_t *dent; /* Entry in RequestRoot */
+ int load_cache = 1; /* Load the job.cache file? */
/*
@@ -1564,36 +1560,65 @@ cupsdLoadAllJobs(void)
if (stat(filename, &fileinfo))
{
- fileinfo.st_mtime = 0;
+ /*
+ * No job.cache file...
+ */
+
+ load_cache = 0;
if (errno != ENOENT)
cupsdLogMessage(CUPSD_LOG_ERROR,
"Unable to get file information for \"%s\" - %s",
filename, strerror(errno));
}
+ else if ((dir = cupsDirOpen(RequestRoot)) == NULL)
+ {
+ /*
+ * No spool directory...
+ */
- if (stat(RequestRoot, &dirinfo))
+ load_cache = 0;
+ }
+ else
{
- dirinfo.st_mtime = 0;
+ while ((dent = cupsDirRead(dir)) != NULL)
+ {
+ if (strlen(dent->filename) >= 6 && dent->filename[0] == 'c' && dent->fileinfo.st_mtime > fileinfo.st_mtime)
+ {
+ /*
+ * Job history file is newer than job.cache file...
+ */
- if (errno != ENOENT)
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to get directory information for \"%s\" - %s",
- RequestRoot, strerror(errno));
+ load_cache = 0;
+ break;
+ }
+ }
+
+ cupsDirClose(dir);
}
/*
* Load the most recent source for job data...
*/
- if (dirinfo.st_mtime > fileinfo.st_mtime)
+ if (load_cache)
{
+ /*
+ * Load the job.cache file...
+ */
+
+ load_job_cache(filename);
+ }
+ else
+ {
+ /*
+ * Load the job history files...
+ */
+
load_request_root();
load_next_job_id(filename);
}
- else
- load_job_cache(filename);
/*
* Clean out old jobs as needed...
@@ -1640,7 +1665,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
* Load job attributes...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Loading attributes...", job->id);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "Loading attributes...");
snprintf(jobfile, sizeof(jobfile), "%s/c%05d", RequestRoot, job->id);
if ((fp = cupsdOpenConfFile(jobfile)) == NULL)
@@ -1648,9 +1673,8 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, job->attrs) != IPP_DATA)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to read job control file \"%s\".", job->id,
- jobfile);
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "Unable to read job control file \"%s\".", jobfile);
cupsFileClose(fp);
goto error;
}
@@ -1663,18 +1687,16 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
if (!ippFindAttribute(job->attrs, "time-at-creation", IPP_TAG_INTEGER))
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Missing or bad time-at-creation attribute in "
- "control file.", job->id);
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "Missing or bad time-at-creation attribute in control file.");
goto error;
}
if ((job->state = ippFindAttribute(job->attrs, "job-state",
IPP_TAG_ENUM)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Missing or bad job-state attribute in control "
- "file.", job->id);
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "Missing or bad job-state attribute in control file.");
goto error;
}
@@ -1682,10 +1704,13 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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 ((attr = ippFindAttribute(job->attrs, "time-at-creation", IPP_TAG_INTEGER)) != NULL)
+ job->creation_time = attr->values[0].integer;
+
+ if (job->state_value >= IPP_JOB_CANCELED && (attr = ippFindAttribute(job->attrs, "time-at-completed", IPP_TAG_INTEGER)) != NULL)
{
+ job->completed_time = attr->values[0].integer;
+
if (JobHistory < INT_MAX)
job->history_time = attr->values[0].integer + JobHistory;
else
@@ -1714,18 +1739,17 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
if ((attr = ippFindAttribute(job->attrs, "job-printer-uri",
IPP_TAG_URI)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] No job-printer-uri attribute in control file.",
- job->id);
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "No job-printer-uri attribute in control file.");
goto error;
}
if ((dest = cupsdValidateDest(attr->values[0].string.text, &(job->dtype),
&destptr)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to queue job for destination \"%s\".",
- job->id, attr->values[0].string.text);
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "Unable to queue job for destination \"%s\".",
+ attr->values[0].string.text);
goto error;
}
@@ -1733,9 +1757,9 @@ 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->id, job->dest);
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "Unable to queue job for destination \"%s\".",
+ job->dest);
goto error;
}
@@ -1744,9 +1768,8 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
{
const char *reason; /* job-state-reason keyword */
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Job %d] Adding missing job-state-reasons attribute to "
- " control file.", job->id);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG,
+ "Adding missing job-state-reasons attribute to control file.");
switch (job->state_value)
{
@@ -1802,18 +1825,20 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
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);
+ job->impressions = ippFindAttribute(job->attrs, "job-impressions-completed", IPP_TAG_INTEGER);
+ job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed", IPP_TAG_INTEGER);
+ job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME);
+
+ if (!job->impressions)
+ job->impressions = ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-impressions-completed", 0);
if (!job->priority)
{
if ((attr = ippFindAttribute(job->attrs, "job-priority",
IPP_TAG_INTEGER)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Missing or bad job-priority attribute in "
- "control file.", job->id);
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "Missing or bad job-priority attribute in control file.");
goto error;
}
@@ -1825,15 +1850,21 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
if ((attr = ippFindAttribute(job->attrs, "job-originating-user-name",
IPP_TAG_NAME)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Missing or bad job-originating-user-name "
- "attribute in control file.", job->id);
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "Missing or bad job-originating-user-name "
+ "attribute in control file.");
goto error;
}
cupsdSetString(&job->username, attr->values[0].string.text);
}
+ if (!job->name)
+ {
+ if ((attr = ippFindAttribute(job->attrs, "job-name", IPP_TAG_NAME)) != NULL)
+ cupsdSetString(&job->name, attr->values[0].string.text);
+ }
+
/*
* Set the job hold-until time and state...
*/
@@ -1858,6 +1889,9 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
job->state_value = IPP_JOB_PENDING;
}
+ if ((attr = ippFindAttribute(job->attrs, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
+ job->koctets = attr->values[0].integer;
+
if (!job->num_files)
{
/*
@@ -1872,41 +1906,36 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
if (access(jobfile, 0))
break;
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "[Job %d] Auto-typing document file \"%s\"...", job->id,
- jobfile);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG,
+ "Auto-typing document file \"%s\"...", jobfile);
if (fileid > job->num_files)
{
if (job->num_files == 0)
{
- compressions = (int *)calloc(fileid, sizeof(int));
- filetypes = (mime_type_t **)calloc(fileid, sizeof(mime_type_t *));
+ compressions = (int *)calloc((size_t)fileid, sizeof(int));
+ filetypes = (mime_type_t **)calloc((size_t)fileid, sizeof(mime_type_t *));
}
else
{
- compressions = (int *)realloc(job->compressions,
- sizeof(int) * fileid);
- filetypes = (mime_type_t **)realloc(job->filetypes,
- sizeof(mime_type_t *) *
- fileid);
+ compressions = (int *)realloc(job->compressions, sizeof(int) * (size_t)fileid);
+ filetypes = (mime_type_t **)realloc(job->filetypes, sizeof(mime_type_t *) * (size_t)fileid);
}
+ if (compressions)
+ job->compressions = compressions;
+
+ if (filetypes)
+ job->filetypes = filetypes;
+
if (!compressions || !filetypes)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Ran out of memory for job file types.",
- job->id);
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "Ran out of memory for job file types.");
ippDelete(job->attrs);
job->attrs = NULL;
- if (compressions)
- free(compressions);
-
- if (filetypes)
- free(filetypes);
-
if (job->compressions)
{
free(job->compressions);
@@ -1923,9 +1952,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */
return (0);
}
- job->compressions = compressions;
- job->filetypes = filetypes;
- job->num_files = fileid;
+ job->num_files = fileid;
}
job->filetypes[fileid - 1] = mimeFileType(MimeDatabase, jobfile, NULL,
@@ -2074,7 +2101,7 @@ cupsdMoveJob(cupsd_job_t *job, /* I - Job */
if ((attr = ippFindAttribute(job->attrs, "job-printer-uri",
IPP_TAG_URI)) != NULL)
- cupsdSetString(&(attr->values[0].string.text), p->uri);
+ ippSetString(job->attrs, &attr, 0, p->uri);
cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, p, job,
"Job #%d moved from %s to %s.", job->id, olddest,
@@ -2170,11 +2197,18 @@ cupsdSaveAllJobs(void)
{
cupsFilePrintf(fp, "<Job %d>\n", job->id);
cupsFilePrintf(fp, "State %d\n", job->state_value);
+ cupsFilePrintf(fp, "Created %ld\n", (long)job->creation_time);
+ if (job->completed_time)
+ cupsFilePrintf(fp, "Completed %ld\n", (long)job->completed_time);
cupsFilePrintf(fp, "Priority %d\n", job->priority);
- cupsFilePrintf(fp, "HoldUntil %d\n", (int)job->hold_until);
+ if (job->hold_until)
+ cupsFilePrintf(fp, "HoldUntil %ld\n", (long)job->hold_until);
cupsFilePrintf(fp, "Username %s\n", job->username);
+ if (job->name)
+ cupsFilePutConf(fp, "Name", job->name);
cupsFilePrintf(fp, "Destination %s\n", job->dest);
cupsFilePrintf(fp, "DestType %d\n", job->dtype);
+ cupsFilePrintf(fp, "KOctets %d\n", job->koctets);
cupsFilePrintf(fp, "NumFiles %d\n", job->num_files);
for (i = 0; i < job->num_files; i ++)
cupsFilePrintf(fp, "File %d %s/%s %d\n", i + 1, job->filetypes[i]->super,
@@ -2212,8 +2246,7 @@ cupsdSaveJob(cupsd_job_t *job) /* I - Job */
if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL,
job->attrs) != IPP_DATA)
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unable to write job control file.", job->id);
+ cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to write job control file.");
cupsFileClose(fp);
return;
}
@@ -2265,7 +2298,7 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */
attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME);
if (attr)
- cupsdSetString(&(attr->values[0].string.text), when);
+ ippSetString(job->attrs, &attr, 0, when);
else
attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD,
"job-hold-until", NULL, when);
@@ -2281,9 +2314,10 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */
cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
- ippSetString(job->attrs, &job->reasons, 0, "job-hold-until-specified");
}
+ ippSetString(job->attrs, &job->reasons, 0, "job-hold-until-specified");
+
/*
* Update the hold time...
*/
@@ -2519,8 +2553,8 @@ cupsdSetJobState(
if (attr)
{
- attr->value_tag = IPP_TAG_KEYWORD;
- cupsdSetString(&(attr->values[0].string.text), "no-hold");
+ ippSetValueTag(job->attrs, &attr, IPP_TAG_KEYWORD);
+ ippSetString(job->attrs, &attr, 0, "no-hold");
}
default :
@@ -2715,10 +2749,17 @@ cupsdStopAllJobs(
job;
job = (cupsd_job_t *)cupsArrayNext(PrintingJobs))
{
- if (kill_delay)
- job->kill_time = time(NULL) + kill_delay;
+ if (job->completed)
+ {
+ cupsdSetJobState(job, IPP_JOB_COMPLETED, CUPSD_JOB_FORCE, NULL);
+ }
+ else
+ {
+ if (kill_delay)
+ job->kill_time = time(NULL) + kill_delay;
- cupsdSetJobState(job, IPP_JOB_PENDING, action, NULL);
+ cupsdSetJobState(job, IPP_JOB_PENDING, action, NULL);
+ }
}
}
@@ -2829,6 +2870,28 @@ compare_active_jobs(void *first, /* I - First job */
/*
+ * 'compare_completed_jobs()' - Compare the job IDs and completion times of two jobs.
+ */
+
+static int /* O - Difference */
+compare_completed_jobs(void *first, /* I - First job */
+ void *second, /* I - Second job */
+ void *data) /* I - App data (not used) */
+{
+ int diff; /* Difference */
+
+
+ (void)data;
+
+ if ((diff = ((cupsd_job_t *)second)->completed_time -
+ ((cupsd_job_t *)first)->completed_time) != 0)
+ return (diff);
+ else
+ return (((cupsd_job_t *)first)->id - ((cupsd_job_t *)second)->id);
+}
+
+
+/*
* 'compare_jobs()' - Compare the job IDs of two jobs.
*/
@@ -2923,7 +2986,7 @@ dump_job_history(cupsd_job_t *job) /* I - Job */
snprintf(temp, sizeof(temp), "[Job %d] printer-state-reasons=", job->id);
ptr = temp + strlen(temp);
if (printer->num_reasons == 0)
- strlcpy(ptr, "none", sizeof(temp) - (ptr - temp));
+ strlcpy(ptr, "none", sizeof(temp) - (size_t)(ptr - temp));
else
{
for (i = 0;
@@ -2933,7 +2996,7 @@ dump_job_history(cupsd_job_t *job) /* I - Job */
if (i)
*ptr++ = ',';
- strlcpy(ptr, printer->reasons[i], sizeof(temp) - (ptr - temp));
+ strlcpy(ptr, printer->reasons[i], sizeof(temp) - (size_t)(ptr - temp));
ptr += strlen(ptr);
}
}
@@ -2994,11 +3057,13 @@ finalize_job(cupsd_job_t *job, /* I - Job */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "finalize_job(job=%p(%d))", job, job->id);
/*
- * Clear the "connecting-to-device" reason, which is only valid when a printer
- * is processing, along with any remote printing job state...
+ * Clear the "connecting-to-device" and "cups-waiting-for-job-completed"
+ * reasons, which are only valid when a printer is processing, along with any
+ * remote printing job state...
*/
cupsdSetPrinterReasons(job->printer, "-connecting-to-device,"
+ "cups-waiting-for-job-completed,"
"cups-remote-pending,"
"cups-remote-pending-held,"
"cups-remote-processing,"
@@ -3022,6 +3087,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */
cupsdDestroyProfile(job->profile);
job->profile = NULL;
+ cupsdDestroyProfile(job->bprofile);
+ job->bprofile = NULL;
/*
* Clear the unresponsive job watchdog timers...
@@ -3068,8 +3135,9 @@ finalize_job(cupsd_job_t *job, /* I - Job */
job_state = IPP_JOB_COMPLETED;
message = "Job completed.";
- ippSetString(job->attrs, &job->reasons, 0,
- "job-completed-successfully");
+ if (!job->status)
+ ippSetString(job->attrs, &job->reasons, 0,
+ "job-completed-successfully");
break;
case IPP_JOB_STOPPED :
@@ -3255,13 +3323,48 @@ finalize_job(cupsd_job_t *job, /* I - Job */
* Hold the job...
*/
- cupsdSetJobHoldUntil(job, "indefinite", 1);
- ippSetString(job->attrs, &job->reasons, 0,
- "job-hold-until-specified");
+ const char *reason = ippGetString(job->reasons, 0, NULL);
- job_state = IPP_JOB_HELD;
- message = "Job held indefinitely due to backend errors; please "
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "job-state-reasons=\"%s\"",
+ reason);
+
+ if (!reason || strncmp(reason, "account-", 8))
+ {
+ cupsdSetJobHoldUntil(job, "indefinite", 1);
+
+ ippSetString(job->attrs, &job->reasons, 0,
+ "job-hold-until-specified");
+ message = "Job held indefinitely due to backend errors; please "
"consult the error_log file for details.";
+ }
+ else if (!strcmp(reason, "account-info-needed"))
+ {
+ cupsdSetJobHoldUntil(job, "indefinite", 0);
+
+ message = "Job held indefinitely - account information is "
+ "required.";
+ }
+ else if (!strcmp(reason, "account-closed"))
+ {
+ cupsdSetJobHoldUntil(job, "indefinite", 0);
+
+ message = "Job held indefinitely - account has been closed.";
+ }
+ else if (!strcmp(reason, "account-limit-reached"))
+ {
+ cupsdSetJobHoldUntil(job, "indefinite", 0);
+
+ message = "Job held indefinitely - account limit has been "
+ "reached.";
+ }
+ else
+ {
+ cupsdSetJobHoldUntil(job, "indefinite", 0);
+
+ message = "Job held indefinitely - account authorization failed.";
+ }
+
+ job_state = IPP_JOB_HELD;
}
break;
@@ -3295,8 +3398,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");
+ if (strncmp(job->reasons->values[0].string.text, "account-", 8))
+ ippSetString(job->attrs, &job->reasons, 0,
+ "cups-held-for-authentication");
}
break;
@@ -3422,13 +3526,6 @@ finalize_job(cupsd_job_t *job, /* I - Job */
job->printer->job = NULL;
job->printer = NULL;
-
- /*
- * Try printing another job...
- */
-
- if (printer_state != IPP_PRINTER_STOPPED)
- cupsdCheckJobs();
}
@@ -3480,19 +3577,16 @@ get_options(cupsd_job_t *job, /* I - Job */
"com.apple.print.DocumentTicket.PMSpoolFormat",
IPP_TAG_ZERO) &&
!ippFindAttribute(job->attrs, "APPrinterPreset", IPP_TAG_ZERO) &&
- (ippFindAttribute(job->attrs, "output-mode", IPP_TAG_ZERO) ||
- ippFindAttribute(job->attrs, "print-color-mode", IPP_TAG_ZERO) ||
+ (ippFindAttribute(job->attrs, "print-color-mode", IPP_TAG_ZERO) ||
ippFindAttribute(job->attrs, "print-quality", IPP_TAG_ZERO)))
{
/*
- * Map output-mode and print-quality to a preset...
+ * Map print-color-mode and print-quality to a preset...
*/
if ((attr = ippFindAttribute(job->attrs, "print-color-mode",
- IPP_TAG_KEYWORD)) == NULL)
- attr = ippFindAttribute(job->attrs, "output-mode", IPP_TAG_KEYWORD);
-
- if (attr && !strcmp(attr->values[0].string.text, "monochrome"))
+ IPP_TAG_KEYWORD)) != NULL &&
+ !strcmp(attr->values[0].string.text, "monochrome"))
print_color_mode = _PWG_PRINT_COLOR_MODE_MONOCHROME;
else
print_color_mode = _PWG_PRINT_COLOR_MODE_COLOR;
@@ -3679,7 +3773,8 @@ get_options(cupsd_job_t *job, /* I - Job */
attr->value_tag == IPP_TAG_MIMETYPE ||
attr->value_tag == IPP_TAG_NAMELANG ||
attr->value_tag == IPP_TAG_TEXTLANG ||
- (attr->value_tag == IPP_TAG_URI && strcmp(attr->name, "job-uuid")) ||
+ (attr->value_tag == IPP_TAG_URI && strcmp(attr->name, "job-uuid") &&
+ strcmp(attr->name, "job-authorization-uri")) ||
attr->value_tag == IPP_TAG_URISCHEME ||
attr->value_tag == IPP_TAG_BEGIN_COLLECTION) /* Not yet supported */
continue;
@@ -3694,9 +3789,14 @@ get_options(cupsd_job_t *job, /* I - Job */
continue;
if (!strncmp(attr->name, "job-", 4) &&
+ strcmp(attr->name, "job-account-id") &&
+ strcmp(attr->name, "job-accounting-user-id") &&
+ strcmp(attr->name, "job-authorization-uri") &&
strcmp(attr->name, "job-billing") &&
strcmp(attr->name, "job-impressions") &&
strcmp(attr->name, "job-originating-host-name") &&
+ strcmp(attr->name, "job-password") &&
+ strcmp(attr->name, "job-password-encryption") &&
strcmp(attr->name, "job-uuid") &&
!(job->printer->type & CUPS_PRINTER_REMOTE))
continue;
@@ -3721,18 +3821,18 @@ get_options(cupsd_job_t *job, /* I - Job */
*/
if (optptr > options)
- strlcat(optptr, " ", optlength - (optptr - options));
+ strlcat(optptr, " ", optlength - (size_t)(optptr - options));
if (attr->value_tag != IPP_TAG_BOOLEAN)
{
- strlcat(optptr, attr->name, optlength - (optptr - options));
- strlcat(optptr, "=", optlength - (optptr - options));
+ strlcat(optptr, attr->name, optlength - (size_t)(optptr - options));
+ strlcat(optptr, "=", optlength - (size_t)(optptr - options));
}
for (i = 0; i < attr->num_values; i ++)
{
if (i)
- strlcat(optptr, ",", optlength - (optptr - options));
+ strlcat(optptr, ",", optlength - (size_t)(optptr - options));
optptr += strlen(optptr);
@@ -3740,30 +3840,29 @@ get_options(cupsd_job_t *job, /* I - Job */
{
case IPP_TAG_INTEGER :
case IPP_TAG_ENUM :
- snprintf(optptr, optlength - (optptr - options),
+ snprintf(optptr, optlength - (size_t)(optptr - options),
"%d", attr->values[i].integer);
break;
case IPP_TAG_BOOLEAN :
if (!attr->values[i].boolean)
- strlcat(optptr, "no", optlength - (optptr - options));
+ strlcat(optptr, "no", optlength - (size_t)(optptr - options));
- strlcat(optptr, attr->name,
- optlength - (optptr - options));
+ strlcat(optptr, attr->name, optlength - (size_t)(optptr - options));
break;
case IPP_TAG_RANGE :
if (attr->values[i].range.lower == attr->values[i].range.upper)
- snprintf(optptr, optlength - (optptr - options) - 1,
+ snprintf(optptr, optlength - (size_t)(optptr - options) - 1,
"%d", attr->values[i].range.lower);
else
- snprintf(optptr, optlength - (optptr - options) - 1,
+ snprintf(optptr, optlength - (size_t)(optptr - options) - 1,
"%d-%d", attr->values[i].range.lower,
attr->values[i].range.upper);
break;
case IPP_TAG_RESOLUTION :
- snprintf(optptr, optlength - (optptr - options) - 1,
+ snprintf(optptr, optlength - (size_t)(optptr - options) - 1,
"%dx%d%s", attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
@@ -3803,10 +3902,10 @@ get_options(cupsd_job_t *job, /* I - Job */
for (i = num_pwgppds, pwgppd = pwgppds; i > 0; i --, pwgppd ++)
{
*optptr++ = ' ';
- strcpy(optptr, pwgppd->name);
+ strlcpy(optptr, pwgppd->name, optlength - (size_t)(optptr - options));
optptr += strlen(optptr);
*optptr++ = '=';
- strcpy(optptr, pwgppd->value);
+ strlcpy(optptr, pwgppd->value, optlength - (size_t)(optptr - options));
optptr += strlen(optptr);
}
@@ -3860,7 +3959,7 @@ ipp_length(ipp_t *ipp) /* I - IPP request */
*/
bytes ++; /* " " separator */
- bytes += attr->num_values; /* "," separators */
+ bytes += (size_t)attr->num_values; /* "," separators */
/*
* Boolean attributes appear as "foo,nofoo,foo,nofoo", while
@@ -3870,7 +3969,7 @@ ipp_length(ipp_t *ipp) /* I - IPP request */
if (attr->value_tag != IPP_TAG_BOOLEAN)
bytes += strlen(attr->name);
else
- bytes += attr->num_values * strlen(attr->name);
+ bytes += (size_t)attr->num_values * strlen(attr->name);
/*
* Now add the size required for each value in the attribute...
@@ -3884,7 +3983,7 @@ ipp_length(ipp_t *ipp) /* I - IPP request */
* Minimum value of a signed integer is -2147483647, or 11 digits.
*/
- bytes += attr->num_values * 11;
+ bytes += (size_t)attr->num_values * 11;
break;
case IPP_TAG_BOOLEAN :
@@ -3903,7 +4002,7 @@ ipp_length(ipp_t *ipp) /* I - IPP request */
* 23 characters max.
*/
- bytes += attr->num_values * 23;
+ bytes += (size_t)attr->num_values * 23;
break;
case IPP_TAG_RESOLUTION :
@@ -3912,7 +4011,7 @@ ipp_length(ipp_t *ipp) /* I - IPP request */
* suffixed by the units, or 26 characters max.
*/
- bytes += attr->num_values * 26;
+ bytes += (size_t)attr->num_values * 26;
break;
case IPP_TAG_STRING :
@@ -3988,14 +4087,13 @@ load_job_cache(const char *filename) /* I - job.cache filename */
{
if (job)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Missing </Job> directive on line %d.",
- linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Missing </Job> directive on line %d of %s.", linenum, filename);
continue;
}
if (!value)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Missing job ID on line %d.", linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Missing job ID on line %d of %s.", linenum, filename);
continue;
}
@@ -4003,8 +4101,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,
- linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad job ID %d on line %d of %s.", jobid, linenum, filename);
continue;
}
@@ -4038,13 +4135,12 @@ load_job_cache(const char *filename) /* I - job.cache filename */
job->status_pipes[0] = -1;
job->status_pipes[1] = -1;
- cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Loading from cache...",
- job->id);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "Loading from cache...");
}
else if (!job)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Missing <Job #> directive on line %d.", linenum);
+ "Missing <Job #> directive on line %d of %s.", linenum, filename);
continue;
}
else if (!_cups_strcasecmp(line, "</Job>"))
@@ -4053,12 +4149,20 @@ load_job_cache(const char *filename) /* I - job.cache filename */
if (job->state_value <= IPP_JOB_STOPPED && cupsdLoadJob(job))
cupsArrayAdd(ActiveJobs, job);
+ else if (job->state_value > IPP_JOB_STOPPED)
+ {
+ if (!job->completed_time || !job->creation_time || !job->name || !job->koctets)
+ {
+ cupsdLoadJob(job);
+ unload_job(job);
+ }
+ }
job = NULL;
}
else if (!value)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d.", linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d of %s.", linenum, filename);
continue;
}
else if (!_cups_strcasecmp(line, "State"))
@@ -4070,9 +4174,21 @@ load_job_cache(const char *filename) /* I - job.cache filename */
else if (job->state_value > IPP_JOB_COMPLETED)
job->state_value = IPP_JOB_COMPLETED;
}
+ else if (!_cups_strcasecmp(line, "Name"))
+ {
+ cupsdSetString(&(job->name), value);
+ }
+ else if (!_cups_strcasecmp(line, "Created"))
+ {
+ job->creation_time = strtol(value, NULL, 10);
+ }
+ else if (!_cups_strcasecmp(line, "Completed"))
+ {
+ job->completed_time = strtol(value, NULL, 10);
+ }
else if (!_cups_strcasecmp(line, "HoldUntil"))
{
- job->hold_until = atoi(value);
+ job->hold_until = strtol(value, NULL, 10);
}
else if (!_cups_strcasecmp(line, "Priority"))
{
@@ -4090,14 +4206,17 @@ load_job_cache(const char *filename) /* I - job.cache filename */
{
job->dtype = (cups_ptype_t)atoi(value);
}
+ else if (!_cups_strcasecmp(line, "KOctets"))
+ {
+ job->koctets = atoi(value);
+ }
else if (!_cups_strcasecmp(line, "NumFiles"))
{
job->num_files = atoi(value);
if (job->num_files < 0)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad NumFiles value %d on line %d.",
- job->num_files, linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad NumFiles value %d on line %d of %s.", job->num_files, linenum, filename);
job->num_files = 0;
continue;
}
@@ -4108,20 +4227,19 @@ 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.",
- job->id);
+ cupsdLogJob(job, CUPSD_LOG_INFO, "Data files have gone away.");
job->num_files = 0;
continue;
}
- job->filetypes = calloc(job->num_files, sizeof(mime_type_t *));
- job->compressions = calloc(job->num_files, sizeof(int));
+ job->filetypes = calloc((size_t)job->num_files, sizeof(mime_type_t *));
+ job->compressions = calloc((size_t)job->num_files, sizeof(int));
if (!job->filetypes || !job->compressions)
{
- cupsdLogMessage(CUPSD_LOG_EMERG,
- "[Job %d] Unable to allocate memory for %d files.",
- job->id, job->num_files);
+ cupsdLogJob(job, CUPSD_LOG_EMERG,
+ "Unable to allocate memory for %d files.",
+ job->num_files);
break;
}
}
@@ -4137,14 +4255,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 of %s.", linenum, filename);
continue;
}
if (number < 1 || number > job->num_files)
{
- cupsdLogMessage(CUPSD_LOG_ERROR, "Bad File number %d on line %d.",
- number, linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Bad File number %d on line %d of %s.", number, linenum, filename);
continue;
}
@@ -4159,9 +4276,9 @@ load_job_cache(const char *filename) /* I - job.cache filename */
* If the original MIME type is unknown, auto-type it!
*/
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "[Job %d] Unknown MIME type %s/%s for file %d.",
- job->id, super, type, number + 1);
+ cupsdLogJob(job, CUPSD_LOG_ERROR,
+ "Unknown MIME type %s/%s for file %d.",
+ super, type, number + 1);
snprintf(jobfile, sizeof(jobfile), "%s/d%05d-%03d", RequestRoot,
job->id, number + 1);
@@ -4178,8 +4295,14 @@ load_job_cache(const char *filename) /* I - job.cache filename */
}
}
else
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown %s directive on line %d.",
- line, linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown %s directive on line %d of %s.", line, linenum, filename);
+ }
+
+ if (job)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Missing </Job> directive on line %d of %s.", linenum, filename);
+ cupsdDeleteJob(job, CUPSD_JOB_PURGE);
}
cupsFileClose(fp);
@@ -4343,10 +4466,7 @@ remove_job_files(cupsd_job_t *job) /* I - Job */
{
snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot,
job->id, i);
- if (Classification)
- cupsdRemoveFile(filename);
- else
- unlink(filename);
+ cupsdUnlinkOrRemoveFile(filename);
}
free(job->filetypes);
@@ -4377,10 +4497,7 @@ remove_job_history(cupsd_job_t *job) /* I - Job */
snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot,
job->id);
- if (Classification)
- cupsdRemoveFile(filename);
- else
- unlink(filename);
+ cupsdUnlinkOrRemoveFile(filename);
LastEvent |= CUPSD_EVENT_PRINTER_STATE_CHANGED;
}
@@ -4394,6 +4511,7 @@ static void
set_time(cupsd_job_t *job, /* I - Job to update */
const char *name) /* I - Name of attribute */
{
+ char date_name[128]; /* date-time-at-xxx */
ipp_attribute_t *attr; /* Time attribute */
time_t curtime; /* Current time */
@@ -4408,8 +4526,18 @@ set_time(cupsd_job_t *job, /* I - Job to update */
attr->values[0].integer = curtime;
}
+ snprintf(date_name, sizeof(date_name), "date-%s", name);
+
+ if ((attr = ippFindAttribute(job->attrs, date_name, IPP_TAG_ZERO)) != NULL)
+ {
+ attr->value_tag = IPP_TAG_DATE;
+ ippSetDate(job->attrs, &attr, 0, ippTimeToDate(curtime));
+ }
+
if (!strcmp(name, "time-at-completed"))
{
+ job->completed_time = curtime;
+
if (JobHistory < INT_MAX && attr)
job->history_time = attr->values[0].integer + JobHistory;
else
@@ -4440,6 +4568,13 @@ static void
start_job(cupsd_job_t *job, /* I - Job ID */
cupsd_printer_t *printer) /* I - Printer to print job */
{
+ const char *filename; /* Support filename */
+ ipp_attribute_t *cancel_after = ippFindAttribute(job->attrs,
+ "job-cancel-after",
+ IPP_TAG_INTEGER);
+ /* job-cancel-after attribute */
+
+
cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job(job=%p(%d), printer=%p(%s))",
job, job->id, printer, printer->name);
@@ -4467,7 +4602,7 @@ start_job(cupsd_job_t *job, /* I - Job ID */
"job-printer-state-message",
IPP_TAG_TEXT);
if (job->printer_message)
- cupsdSetString(&(job->printer_message->values[0].string.text), "");
+ ippSetString(job->attrs, &job->printer_message, 0, "");
ippSetString(job->attrs, &job->reasons, 0, "job-printing");
cupsdSetJobState(job, IPP_JOB_PROCESSING, CUPSD_JOB_DEFAULT, NULL);
@@ -4488,17 +4623,39 @@ start_job(cupsd_job_t *job, /* I - Job ID */
job->printer = printer;
printer->job = job;
- if (MaxJobTime > 0)
+ if (cancel_after)
+ job->cancel_time = time(NULL) + ippGetInteger(cancel_after, 0);
+ else if (MaxJobTime > 0)
job->cancel_time = time(NULL) + MaxJobTime;
else
job->cancel_time = 0;
/*
+ * Check for support files...
+ */
+
+ cupsdSetPrinterReasons(job->printer, "-cups-missing-filter-warning,"
+ "cups-insecure-filter-warning");
+
+ if (printer->pc)
+ {
+ for (filename = (const char *)cupsArrayFirst(printer->pc->support_files);
+ filename;
+ filename = (const char *)cupsArrayNext(printer->pc->support_files))
+ {
+ if (_cupsFileCheck(filename, _CUPS_FILE_CHECK_FILE, !RunUser,
+ cupsdLogFCMessage, printer))
+ break;
+ }
+ }
+
+ /*
* Setup the last exit status and security profiles...
*/
- job->status = 0;
- job->profile = cupsdCreateProfile(job->id);
+ job->status = 0;
+ job->profile = cupsdCreateProfile(job->id, 0);
+ job->bprofile = cupsdCreateProfile(job->id, 1);
/*
* Create the status pipes and buffer...
@@ -4515,6 +4672,8 @@ start_job(cupsd_job_t *job, /* I - Job ID */
cupsdDestroyProfile(job->profile);
job->profile = NULL;
+ cupsdDestroyProfile(job->bprofile);
+ job->bprofile = NULL;
return;
}
@@ -4540,6 +4699,8 @@ start_job(cupsd_job_t *job, /* I - Job ID */
cupsdDestroyProfile(job->profile);
job->profile = NULL;
+ cupsdDestroyProfile(job->bprofile);
+ job->bprofile = NULL;
return;
}
@@ -4569,6 +4730,8 @@ start_job(cupsd_job_t *job, /* I - Job ID */
cupsdDestroyProfile(job->profile);
job->profile = NULL;
+ cupsdDestroyProfile(job->bprofile);
+ job->bprofile = NULL;
return;
}
@@ -4607,7 +4770,7 @@ stop_job(cupsd_job_t *job, /* I - Job */
FilterLevel -= job->cost;
job->cost = 0;
- if (action == CUPSD_JOB_DEFAULT && !job->kill_time)
+ if (action == CUPSD_JOB_DEFAULT && !job->kill_time && job->backend > 0)
job->kill_time = time(NULL) + JobKillDelay;
else if (action >= CUPSD_JOB_FORCE)
job->kill_time = 0;
@@ -4650,13 +4813,14 @@ unload_job(cupsd_job_t *job) /* I - Job */
if (!job->attrs)
return;
- cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Unloading...", job->id);
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "Unloading...");
ippDelete(job->attrs);
job->attrs = NULL;
job->state = NULL;
job->reasons = NULL;
+ job->impressions = NULL;
job->sheets = NULL;
job->job_sheets = NULL;
job->printer_message = NULL;
@@ -4678,6 +4842,8 @@ update_job(cupsd_job_t *job) /* I - Job to check */
*ptr; /* Pointer update... */
int loglevel, /* Log level for message */
event = 0; /* Events? */
+ cupsd_printer_t *printer = job->printer;
+ /* Printer */
static const char * const levels[] = /* Log levels */
{
"NONE",
@@ -4715,6 +4881,25 @@ update_job(cupsd_job_t *job) /* I - Job to check */
cupsdLogJob(job, CUPSD_LOG_DEBUG, "PAGE: %s", message);
+ if (job->impressions)
+ {
+ if (!_cups_strncasecmp(message, "total ", 6))
+ {
+ /*
+ * Got a total count of pages from a backend or filter...
+ */
+
+ copies = atoi(message + 6);
+ copies -= ippGetInteger(job->impressions, 0); /* Just track the delta */
+ }
+ else if (!sscanf(message, "%*d%d", &copies))
+ copies = 1;
+
+ ippSetInteger(job->attrs, &job->impressions, 0, ippGetInteger(job->impressions, 0) + copies);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+ }
+
if (job->sheets)
{
if (!_cups_strncasecmp(message, "total ", 6))
@@ -4724,12 +4909,14 @@ update_job(cupsd_job_t *job) /* I - Job to check */
*/
copies = atoi(message + 6);
- copies -= job->sheets->values[0].integer; /* Just track the delta */
+ copies -= ippGetInteger(job->sheets, 0); /* Just track the delta */
}
else if (!sscanf(message, "%*d%d", &copies))
copies = 1;
- job->sheets->values[0].integer += copies;
+ ippSetInteger(job->attrs, &job->sheets, 0, ippGetInteger(job->sheets, 0) + copies);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
if (job->printer->page_limit)
cupsdUpdateQuota(job->printer, job->username, copies, 0);
@@ -4738,8 +4925,21 @@ update_job(cupsd_job_t *job) /* I - Job to check */
cupsdLogPage(job, message);
if (job->sheets)
- cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job,
- "Printed %d page(s).", job->sheets->values[0].integer);
+ cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job, "Printed %d page(s).", ippGetInteger(job->sheets, 0));
+ }
+ else if (loglevel == CUPSD_LOG_JOBSTATE)
+ {
+ /*
+ * Support "keyword" to set job-state-reasons to the specified keyword.
+ * This is sufficient for the current paid printing stuff.
+ */
+
+ cupsdLogJob(job, CUPSD_LOG_DEBUG, "JOBSTATE: %s", message);
+
+ if (!strcmp(message, "cups-retry-as-raster"))
+ job->retry_as_raster = 1;
+ else
+ ippSetString(job->attrs, &job->reasons, 0, message);
}
else if (loglevel == CUPSD_LOG_STATE)
{
@@ -4754,7 +4954,7 @@ update_job(cupsd_job_t *job) /* I - Job to check */
{
event |= CUPSD_EVENT_PRINTER_STATE;
- if (MaxJobTime > 0 && strstr(message, "connecting-to-device") != NULL)
+ if (MaxJobTime > 0)
{
/*
* Reset cancel time after connecting to the device...
@@ -4765,7 +4965,17 @@ update_job(cupsd_job_t *job) /* I - Job to check */
break;
if (i >= job->printer->num_reasons)
- job->cancel_time = time(NULL) + MaxJobTime;
+ {
+ ipp_attribute_t *cancel_after = ippFindAttribute(job->attrs,
+ "job-cancel-after",
+ IPP_TAG_INTEGER);
+ /* job-cancel-after attribute */
+
+ if (cancel_after)
+ job->cancel_time = time(NULL) + ippGetInteger(cancel_after, 0);
+ else
+ job->cancel_time = time(NULL) + MaxJobTime;
+ }
}
}
@@ -4781,11 +4991,21 @@ update_job(cupsd_job_t *job) /* I - Job to check */
cups_option_t *attrs; /* Attributes */
const char *attr; /* Attribute */
-
cupsdLogJob(job, CUPSD_LOG_DEBUG, "ATTR: %s", message);
num_attrs = cupsParseOptions(message, 0, &attrs);
+ if ((attr = cupsGetOption("auth-info-default", num_attrs,
+ attrs)) != NULL)
+ {
+ job->printer->num_options = cupsAddOption("auth-info", attr,
+ job->printer->num_options,
+ &(job->printer->options));
+ cupsdSetPrinterAttrs(job->printer);
+
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
+ }
+
if ((attr = cupsGetOption("auth-info-required", num_attrs,
attrs)) != NULL)
{
@@ -4997,10 +5217,11 @@ update_job(cupsd_job_t *job) /* I - Job to check */
finalize_job(job, 1);
/*
- * Check for new jobs...
+ * Try printing another job...
*/
- cupsdCheckJobs();
+ if (printer->state != IPP_PRINTER_STOPPED)
+ cupsdCheckJobs();
}
}
@@ -5045,15 +5266,14 @@ 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), "");
+ ippSetString(job->attrs, &job->printer_message, 0, "");
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);
+ ippSetString(job->attrs, &job->printer_message, 0, job->printer->state_message);
job->dirty = 1;
cupsdMarkDirty(CUPSD_DIRTY_JOBS);
@@ -5121,5 +5341,5 @@ update_job_attrs(cupsd_job_t *job, /* I - Job to update */
/*
- * End of "$Id: job.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: job.c 12856 2015-08-31 14:27:39Z msweet $".
*/
diff --git a/scheduler/job.h b/scheduler/job.h
index 6fb5ab8..2e3edc8 100644
--- a/scheduler/job.h
+++ b/scheduler/job.h
@@ -1,16 +1,16 @@
/*
- * "$Id: job.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: job.h 12668 2015-05-27 19:30:32Z msweet $"
*
- * Print job definitions for the CUPS scheduler.
+ * Print job definitions for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 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/".
+ * 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/".
*/
/*
@@ -39,14 +39,19 @@ struct cupsd_job_s /**** Job request ****/
* waiting on files */
char *username; /* Printing user */
char *dest; /* Destination printer or class */
+ char *name; /* Job name/title */
+ int koctets; /* job-k-octets */
cups_ptype_t dtype; /* Destination type */
cupsd_printer_t *printer; /* Printer this job is assigned to */
int num_files; /* Number of files in job */
mime_type_t **filetypes; /* File types */
int *compressions; /* Compression status of each file */
- ipp_attribute_t *sheets; /* job-media-sheets-completed */
+ ipp_attribute_t *impressions, /* job-impressions-completed */
+ *sheets; /* job-media-sheets-completed */
time_t access_time, /* Last access time */
cancel_time, /* When to cancel/send SIGTERM */
+ creation_time, /* When job was created */
+ completed_time, /* When job was completed (0 if not) */
file_time, /* Job file retain time */
history_time, /* Job history retain time */
hold_until, /* Hold expiration date/time */
@@ -74,10 +79,13 @@ struct cupsd_job_s /**** Job request ****/
int backend; /* Backend process ID */
int status; /* Status code from filters */
int tries; /* Number of tries for this job */
+ int completed; /* cups-waiting-for-job-completed seen */
+ int retry_as_raster;/* Need to retry the job as raster */
char *auth_env[3], /* AUTH_xxx environment variables,
* if any */
*auth_uid; /* AUTH_UID environment variable */
- void *profile; /* Security profile */
+ void *profile, /* Security profile for filters */
+ *bprofile; /* Security profile for backend */
cups_array_t *history; /* Debug log history */
int progress; /* Printing progress */
int num_keywords; /* Number of PPD keywords */
@@ -145,6 +153,7 @@ extern void cupsdDeleteJob(cupsd_job_t *job,
cupsd_jobaction_t action);
extern cupsd_job_t *cupsdFindJob(int id);
extern void cupsdFreeAllJobs(void);
+extern cups_array_t *cupsdGetCompletedJobs(cupsd_printer_t *p);
extern int cupsdGetPrinterJobCount(const char *dest);
extern int cupsdGetUserJobCount(const char *username);
extern void cupsdLoadAllJobs(void);
@@ -171,5 +180,5 @@ extern void cupsdUpdateJobs(void);
/*
- * End of "$Id: job.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: job.h 12668 2015-05-27 19:30:32Z msweet $".
*/
diff --git a/scheduler/listen.c b/scheduler/listen.c
index a4c19c0..9fcc631 100644
--- a/scheduler/listen.c
+++ b/scheduler/listen.c
@@ -1,24 +1,16 @@
/*
- * "$Id: listen.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: listen.c 12178 2014-09-30 18:56:48Z msweet $"
*
- * Server listening routines for the CUPS scheduler.
+ * Server listening routines for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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:
- *
- * cupsdDeleteAllListeners() - Delete all listeners.
- * cupsdPauseListening() - Clear input polling on all listening sockets...
- * cupsdResumeListening() - Set input polling on all listening sockets...
- * cupsdStartListening() - Create all listening sockets...
- * cupsdStopListening() - Close all listening sockets...
+ * 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/".
*/
/*
@@ -51,10 +43,19 @@ cupsdDeleteAllListeners(void)
for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
lis;
lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
- free(lis);
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ if (!lis->on_demand)
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
+ {
+ cupsArrayRemove(Listeners, lis);
+ free(lis);
+ }
- cupsArrayDelete(Listeners);
- Listeners = NULL;
+ if (cupsArrayCount(Listeners) == 0)
+ {
+ cupsArrayDelete(Listeners);
+ Listeners = NULL;
+ }
}
@@ -123,9 +124,7 @@ cupsdResumeListening(void)
void
cupsdStartListening(void)
{
- int status; /* Bind result */
- int p, /* Port number */
- val; /* Parameter value */
+ int p; /* Port number */
cupsd_listener_t *lis; /* Current listening socket */
char s[256]; /* String addresss */
const char *have_domain; /* Have a domain socket? */
@@ -151,7 +150,7 @@ cupsdStartListening(void)
lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
{
httpAddrString(&(lis->address), s, sizeof(s));
- p = _httpAddrPort(&(lis->address));
+ p = httpAddrPort(&(lis->address));
/*
* If needed, create a socket for listening...
@@ -163,7 +162,7 @@ cupsdStartListening(void)
* Create a socket for listening...
*/
- lis->fd = socket(lis->address.addr.sa_family, SOCK_STREAM, 0);
+ lis->fd = httpAddrListen(&(lis->address), p);
if (lis->fd == -1)
{
@@ -186,132 +185,15 @@ cupsdStartListening(void)
continue;
}
-
- /*
- * Set things up to reuse the local address for this port.
- */
-
- val = 1;
-#ifdef __sun
- setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
-#else
- setsockopt(lis->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
-#endif /* __sun */
-
- /*
- * Bind to the port we found...
- */
-
-#ifdef AF_INET6
- if (lis->address.addr.sa_family == AF_INET6)
- {
-# ifdef IPV6_V6ONLY
- /*
- * Accept only IPv6 connections on this socket, to avoid
- * potential security issues and to make all platforms behave
- * the same.
- */
-
- val = 1;
-# ifdef __sun
- setsockopt(lis->fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&val, sizeof(val));
-# else
- setsockopt(lis->fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val));
-# endif /* __sun */
-# endif /* IPV6_V6ONLY */
-
- status = bind(lis->fd, (struct sockaddr *)&(lis->address),
- httpAddrLength(&(lis->address)));
- }
- else
-#endif /* AF_INET6 */
-#ifdef AF_LOCAL
- if (lis->address.addr.sa_family == AF_LOCAL)
- {
- mode_t mask; /* Umask setting */
-
-
- /*
- * Remove any existing domain socket file...
- */
-
- unlink(lis->address.un.sun_path);
-
- /*
- * Save the current umask and set it to 0 so that all users can access
- * the domain socket...
- */
-
- mask = umask(0);
-
- /*
- * Bind the domain socket...
- */
-
- status = bind(lis->fd, (struct sockaddr *)&(lis->address),
- httpAddrLength(&(lis->address)));
-
- /*
- * Restore the umask...
- */
-
- umask(mask);
- }
- else
-#endif /* AF_LOCAL */
- status = bind(lis->fd, (struct sockaddr *)&(lis->address),
- sizeof(lis->address.ipv4));
-
- if (status < 0)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to bind socket for address %s:%d - %s.",
- s, p, strerror(errno));
- close(lis->fd);
- lis->fd = -1;
-
- if (FatalErrors & CUPSD_FATAL_LISTEN)
- cupsdEndProcess(getpid(), 0);
-
- continue;
- }
-
- /*
- * Listen for new clients.
- */
-
- if (listen(lis->fd, ListenBackLog) < 0)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to listen for clients on address %s:%d - %s.",
- s, p, strerror(errno));
-
- close(lis->fd);
- lis->fd = -1;
-
- if (FatalErrors & CUPSD_FATAL_LISTEN)
- cupsdEndProcess(getpid(), 0);
-
- continue;
- }
}
- fcntl(lis->fd, F_SETFD, fcntl(lis->fd, F_GETFD) | FD_CLOEXEC);
-
if (p)
cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d on fd %d...",
s, p, lis->fd);
else
- {
cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s on fd %d...",
s, lis->fd);
- if (chmod(s, 0140777))
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to change permisssions on domain socket "
- "\"%s\" - %s", s, strerror(errno));
- }
-
/*
* Save the first port that is bound to the local loopback or
* "any" address...
@@ -339,7 +221,7 @@ cupsdStartListening(void)
{
cupsdLogMessage(CUPSD_LOG_EMERG,
"No Listen or Port lines were found to allow access via "
- "localhost!");
+ "localhost.");
if (FatalErrors & (CUPSD_FATAL_CONFIG | CUPSD_FATAL_LISTEN))
cupsdEndProcess(getpid(), 0);
@@ -401,31 +283,24 @@ cupsdStopListening(void)
lis;
lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
{
- if (lis->fd != -1)
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ if (!lis->on_demand && lis->fd != -1)
{
-#ifdef WIN32
- closesocket(lis->fd);
-#else
- close(lis->fd);
-#endif /* WIN32 */
-
-#ifdef AF_LOCAL
- /*
- * Remove domain sockets...
- */
+ httpAddrClose(&(lis->address), lis->fd);
+ lis->fd = -1;
+ }
-# ifdef HAVE_LAUNCH_H
- if (lis->address.addr.sa_family == AF_LOCAL && !Launchd)
-# else
- if (lis->address.addr.sa_family == AF_LOCAL)
-# endif /* HAVE_LAUNCH_H */
- unlink(lis->address.un.sun_path);
-#endif /* AF_LOCAL */
+#else
+ if (lis->fd != -1)
+ {
+ httpAddrClose(&(lis->address), lis->fd);
+ lis->fd = -1;
}
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
}
}
/*
- * End of "$Id: listen.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: listen.c 12178 2014-09-30 18:56:48Z msweet $".
*/
diff --git a/scheduler/log.c b/scheduler/log.c
index d739b58..55e8036 100644
--- a/scheduler/log.c
+++ b/scheduler/log.c
@@ -1,28 +1,16 @@
/*
- * "$Id: log.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: log.c 12928 2015-10-23 21:31:58Z msweet $"
*
- * Log file routines for the CUPS scheduler.
+ * Log file routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 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:
- *
- * cupsdCheckLogFile() - Open/rotate a log file if it needs it.
- * cupsdGetDateTime() - Returns a pointer to a date/time string.
- * cupsdLogGSSMessage() - Log a GSSAPI error...
- * cupsdLogJob() - Log a job message.
- * cupsdLogMessage() - Log a message to the error log file.
- * cupsdLogPage() - Log a page to the page log file.
- * cupsdLogRequest() - Log an HTTP request in Common Log Format.
- * cupsdWriteErrorLog() - Write a line to the ErrorLog.
- * format_log_line() - Format a line for a log file.
+ * 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/".
*/
/*
@@ -31,18 +19,68 @@
#include "cupsd.h"
#include <stdarg.h>
+#ifdef HAVE_ASL_H
+# include <asl.h>
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+# define SD_JOURNAL_SUPPRESS_LOCATION
+# include <systemd/sd-journal.h>
+#endif /* HAVE_ASL_H */
#include <syslog.h>
/*
+ * Constants for log keys from PWG 5110.3 (PWG Common Log Format)...
+ */
+
+#define PWG_DeviceUUID "DUU"
+#define PWG_Event "E"
+#define PWG_LogNaturalLanguage "NL"
+#define PWG_Status "S"
+#define PWG_ServiceURI "URI"
+#define PWG_UserHost "UH"
+#define PWG_UserName "UN"
+#define PWG_UserURI "UU"
+#define PWG_ServiceIsAcceptingJobs "IAJ"
+#define PWG_ServiceState "ST"
+#define PWG_ServiceStateReasons "SR"
+#define PWG_ServiceUUID "SUU"
+#define PWG_JobID "JID"
+#define PWG_JobUUID "JUU"
+#define PWG_JobImagesCompleted "JIM"
+#define PWG_JobImpressionsCompleted "JIC"
+#define PWG_JobDestinationURI "JD"
+#define PWG_JobState "JS"
+#define PWG_JobStateReasons "JR"
+#define PWG_JobAccountingID "JA"
+#define PWG_JobAcountingUserName "JAUN"
+#define PWG_JobAccountingUserURI "JAUU"
+
+
+/*
* Local globals...
*/
-static int log_linesize = 0; /* Size of line for output file */
+static _cups_mutex_t log_mutex = _CUPS_MUTEX_INITIALIZER;
+ /* Mutex for logging */
+static size_t 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... */
+#ifdef HAVE_ASL_H
+static const int log_levels[] = /* ASL levels... */
+ {
+ ASL_LEVEL_EMERG,
+ ASL_LEVEL_EMERG,
+ ASL_LEVEL_ALERT,
+ ASL_LEVEL_CRIT,
+ ASL_LEVEL_ERR,
+ ASL_LEVEL_WARNING,
+ ASL_LEVEL_NOTICE,
+ ASL_LEVEL_INFO,
+ ASL_LEVEL_DEBUG,
+ ASL_LEVEL_DEBUG
+ };
+#elif defined(HAVE_VSYSLOG) || defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+static const int log_levels[] = /* SYSLOG levels... */
{
0,
LOG_EMERG,
@@ -55,7 +93,7 @@ static const int syslevels[] = /* SYSLOG levels... */
LOG_DEBUG,
LOG_DEBUG
};
-#endif /* HAVE_VSYSLOG */
+#endif /* HAVE_ASL_H */
/*
@@ -87,6 +125,16 @@ cupsdCheckLogFile(cups_file_t **lf, /* IO - Log file */
return (1);
/*
+ * Handle logging to stderr...
+ */
+
+ if (!strcmp(logname, "stderr"))
+ {
+ *lf = LogStderr;
+ return (1);
+ }
+
+ /*
* Format the filename as needed...
*/
@@ -124,7 +172,7 @@ cupsdCheckLogFile(cups_file_t **lf, /* IO - Log file */
* Insert the server name...
*/
- strlcpy(ptr, ServerName, sizeof(filename) - (ptr - filename));
+ strlcpy(ptr, ServerName, sizeof(filename) - (size_t)(ptr - filename));
ptr += strlen(ptr);
}
else
@@ -165,23 +213,34 @@ cupsdCheckLogFile(cups_file_t **lf, /* IO - Log file */
* the log file permissions as a basis...
*/
- int log_dir_perm = 0300 | LogFilePerm;
+ mode_t log_dir_perm = (mode_t)(0300 | LogFilePerm);
/* LogFilePerm + owner write/search */
if (log_dir_perm & 0040)
log_dir_perm |= 0010; /* Add group search */
if (log_dir_perm & 0004)
log_dir_perm |= 0001; /* Add other search */
- cupsdCheckPermissions(CUPS_LOGDIR, NULL, log_dir_perm, RunUser, Group,
- 1, -1);
+ cupsdCheckPermissions(CUPS_LOGDIR, NULL, log_dir_perm, RunUser, Group, 1, -1);
*lf = cupsFileOpen(filename, "a");
}
if (*lf == NULL)
{
- syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename,
- strerror(errno));
+#ifdef HAVE_ASL_H
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to open log file \"%s\" - %s", filename, strerror(errno));
+ asl_release(m);
+
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, strerror(errno));
+
+#else
+ syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, strerror(errno));
+#endif /* HAVE_ASL_H */
if (FatalErrors & CUPSD_FATAL_LOG)
cupsdEndProcess(getpid(), 0);
@@ -214,7 +273,7 @@ cupsdCheckLogFile(cups_file_t **lf, /* IO - Log file */
cupsFileClose(*lf);
- strcpy(backname, filename);
+ strlcpy(backname, filename, sizeof(backname));
strlcat(backname, ".O", sizeof(backname));
unlink(backname);
@@ -222,8 +281,20 @@ cupsdCheckLogFile(cups_file_t **lf, /* IO - Log file */
if ((*lf = cupsFileOpen(filename, "a")) == NULL)
{
- syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename,
- strerror(errno));
+#ifdef HAVE_ASL_H
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to open log file \"%s\" - %s", filename, strerror(errno));
+ asl_release(m);
+
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, strerror(errno));
+
+#else
+ syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, strerror(errno));
+#endif /* HAVE_ASL_H */
if (FatalErrors & CUPSD_FATAL_LOG)
cupsdEndProcess(getpid(), 0);
@@ -382,8 +453,8 @@ cupsdLogFCMessage(
int /* O - 1 on success, 0 on error */
cupsdLogGSSMessage(
int level, /* I - Log level */
- int major_status, /* I - Major GSSAPI status */
- int minor_status, /* I - Minor GSSAPI status */
+ OM_uint32 major_status, /* I - Major GSSAPI status */
+ OM_uint32 minor_status, /* I - Minor GSSAPI status */
const char *message, /* I - printf-style message string */
...) /* I - Additional args as needed */
{
@@ -437,6 +508,61 @@ cupsdLogGSSMessage(
/*
+ * 'cupsdLogClient()' - Log a client message.
+ */
+
+int /* O - 1 on success, 0 on error */
+cupsdLogClient(cupsd_client_t *con, /* I - Client connection */
+ int level, /* I - Log level */
+ const char *message, /* I - Printf-style message string */
+ ...) /* I - Additional arguments as needed */
+{
+ va_list ap, ap2; /* Argument pointers */
+ char clientmsg[1024];/* Format string for client message */
+ int status; /* Formatting status */
+
+
+ /*
+ * See if we want to log this message...
+ */
+
+ if (TestConfigFile || !ErrorLog)
+ return (1);
+
+ if (level > LogLevel)
+ return (1);
+
+ /*
+ * Format and write the log message...
+ */
+
+ if (con)
+ snprintf(clientmsg, sizeof(clientmsg), "[Client %d] %s", con->number,
+ message);
+ else
+ strlcpy(clientmsg, message, sizeof(clientmsg));
+
+ va_start(ap, message);
+
+ do
+ {
+ va_copy(ap2, ap);
+ status = format_log_line(clientmsg, ap2);
+ va_end(ap2);
+ }
+ while (status == 0);
+
+ va_end(ap);
+
+ if (status > 0)
+ return (cupsdWriteErrorLog(level, log_line));
+ else
+ return (cupsdWriteErrorLog(CUPSD_LOG_ERROR,
+ "Unable to allocate memory for log line."));
+}
+
+
+/*
* 'cupsdLogJob()' - Log a job message.
*/
@@ -463,6 +589,96 @@ cupsdLogJob(cupsd_job_t *job, /* I - Job */
LogDebugHistory <= 0)
return (1);
+#ifdef HAVE_ASL_H
+ if (!strcmp(ErrorLog, "syslog"))
+ {
+ asl_object_t m; /* Log message */
+ char job_id[32], /* job-id string */
+ completed[32]; /* job-impressions-completed string */
+ cupsd_printer_t *printer = job ? (job->printer ? job->printer : (job->dest ? cupsdFindDest(job->dest) : NULL)) : NULL;
+ static const char * const job_states[] =
+ { /* job-state strings */
+ "Pending",
+ "PendingHeld",
+ "Processing",
+ "ProcessingStopped",
+ "Canceled",
+ "Aborted",
+ "Completed"
+ };
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ if (printer)
+ asl_set(m, PWG_ServiceURI, printer->uri);
+ if (job)
+ {
+ snprintf(job_id, sizeof(job_id), "%d", job->id);
+
+ asl_set(m, PWG_Event, "JobStateChanged");
+ asl_set(m, PWG_JobID, job_id);
+ asl_set(m, PWG_JobState, job->state_value < IPP_JSTATE_PENDING ? "" : job_states[job->state_value - IPP_JSTATE_PENDING]);
+
+ if (job->impressions)
+ {
+ snprintf(completed, sizeof(completed), "%d", ippGetInteger(job->impressions, 0));
+ asl_set(m, PWG_JobImpressionsCompleted, completed);
+ }
+ }
+
+ va_start(ap, message);
+ asl_vlog(NULL, m, log_levels[level], message, ap);
+ va_end(ap);
+
+ asl_release(m);
+ return (1);
+ }
+
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ if (!strcmp(ErrorLog, "syslog"))
+ {
+ cupsd_printer_t *printer = job ? (job->printer ? job->printer : (job->dest ? cupsdFindDest(job->dest) : NULL)) : NULL;
+ static const char * const job_states[] =
+ { /* job-state strings */
+ "Pending",
+ "PendingHeld",
+ "Processing",
+ "ProcessingStopped",
+ "Canceled",
+ "Aborted",
+ "Completed"
+ };
+
+ va_start(ap, message);
+
+ do
+ {
+ va_copy(ap2, ap);
+ status = format_log_line(message, ap2);
+ va_end(ap2);
+ }
+ while (status == 0);
+
+ va_end(ap);
+
+ if (job)
+ sd_journal_send("MESSAGE=%s", log_line,
+ "PRIORITY=%i", log_levels[level],
+ PWG_Event"=JobStateChanged",
+ PWG_ServiceURI"=%s", printer ? printer->uri : "",
+ PWG_JobID"=%d", job->id,
+ PWG_JobState"=%s", job->state_value < IPP_JSTATE_PENDING ? "" : job_states[job->state_value - IPP_JSTATE_PENDING],
+ PWG_JobImpressionsCompleted"=%d", ippGetInteger(job->impressions, 0),
+ NULL);
+ else
+ sd_journal_send("MESSAGE=%s", log_line,
+ "PRIORITY=%i", log_levels[level],
+ NULL);
+
+ return (1);
+ }
+#endif /* HAVE_ASL_H */
+
/*
* Format and write the log message...
*/
@@ -496,12 +712,13 @@ cupsdLogJob(cupsd_job_t *job, /* I - Job */
*/
cupsd_joblog_t *temp; /* Copy of log message */
+ size_t log_len = strlen(log_line);
+ /* Length of log message */
-
- if ((temp = malloc(sizeof(cupsd_joblog_t) + strlen(log_line))) != NULL)
+ if ((temp = malloc(sizeof(cupsd_joblog_t) + log_len)) != NULL)
{
temp->time = time(NULL);
- strcpy(temp->message, log_line);
+ memcpy(temp->message, log_line, log_len + 1);
}
if (!job->history)
@@ -535,7 +752,7 @@ cupsdLogJob(cupsd_job_t *job, /* I - Job */
}
else
return (cupsdWriteErrorLog(CUPSD_LOG_ERROR,
- "Unable to allocate memory for log line!"));
+ "Unable to allocate memory for log line."));
}
@@ -559,12 +776,26 @@ 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);
+
+#ifdef HAVE_ASL_H
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_vlog(NULL, m, log_levels[level], message, ap);
+ asl_release(m);
+
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_printv(log_levels[level], message, ap);
+
+#elif defined(HAVE_VSYSLOG)
+ vsyslog(LOG_LPR | log_levels[level], message, ap);
+
#else
vfprintf(stderr, message, ap);
putc('\n', stderr);
#endif /* HAVE_VSYSLOG */
+
va_end(ap);
return (1);
@@ -573,6 +804,32 @@ cupsdLogMessage(int level, /* I - Log level */
if (level > LogLevel || !ErrorLog)
return (1);
+#ifdef HAVE_ASL_H
+ if (!strcmp(ErrorLog, "syslog"))
+ {
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+
+ va_start(ap, message);
+ asl_vlog(NULL, m, log_levels[level], message, ap);
+ va_end(ap);
+
+ asl_release(m);
+ return (1);
+ }
+
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ if (!strcmp(ErrorLog, "syslog"))
+ {
+ va_start(ap, message);
+ sd_journal_printv(log_levels[level], message, ap);
+ va_end(ap);
+ return (1);
+ }
+#endif /* HAVE_ASL_H */
+
/*
* Format and write the log message...
*/
@@ -623,7 +880,7 @@ cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */
if (!PageLogFormat)
return (1);
- strcpy(number, "1");
+ strlcpy(number, "1", sizeof(number));
copies = 1;
sscanf(page, "%255s%d", number, &copies);
@@ -641,53 +898,68 @@ cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */
break;
case 'p' : /* Printer name */
- strlcpy(bufptr, job->printer->name,
- sizeof(buffer) - (bufptr - buffer));
+ strlcpy(bufptr, job->dest, sizeof(buffer) - (size_t)(bufptr - buffer));
bufptr += strlen(bufptr);
break;
case 'j' : /* Job ID */
- snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), "%d", job->id);
+ snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer), "%d", job->id);
bufptr += strlen(bufptr);
break;
case 'u' : /* Username */
- strlcpy(bufptr, job->username ? job->username : "-",
- sizeof(buffer) - (bufptr - buffer));
+ strlcpy(bufptr, job->username ? job->username : "-", sizeof(buffer) - (size_t)(bufptr - buffer));
bufptr += strlen(bufptr);
break;
case 'T' : /* Date and time */
- strlcpy(bufptr, cupsdGetDateTime(NULL, LogTimeFormat),
- sizeof(buffer) - (bufptr - buffer));
+ strlcpy(bufptr, cupsdGetDateTime(NULL, LogTimeFormat), sizeof(buffer) - (size_t)(bufptr - buffer));
bufptr += strlen(bufptr);
break;
case 'P' : /* Page number */
- strlcpy(bufptr, number, sizeof(buffer) - (bufptr - buffer));
+ strlcpy(bufptr, number, sizeof(buffer) - (size_t)(bufptr - buffer));
bufptr += strlen(bufptr);
break;
case 'C' : /* Number of copies */
- snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), "%d", copies);
+ snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer), "%d", copies);
bufptr += strlen(bufptr);
break;
case '{' : /* {attribute} */
- if ((nameend = strchr(format, '}')) != NULL &&
- (nameend - format - 2) < (sizeof(name) - 1))
+ if ((nameend = strchr(format, '}')) != NULL && (size_t)(nameend - format - 2) < (sizeof(name) - 1))
{
/*
* Pull the name from inside the brackets...
*/
- memcpy(name, format + 1, nameend - format - 1);
+ memcpy(name, format + 1, (size_t)(nameend - format - 1));
name[nameend - format - 1] = '\0';
format = nameend;
- if ((attr = ippFindAttribute(job->attrs, name,
- IPP_TAG_ZERO)) != NULL)
+ attr = ippFindAttribute(job->attrs, name, IPP_TAG_ZERO);
+ if (!attr && !strcmp(name, "job-billing"))
+ {
+ /*
+ * Handle alias "job-account-id" (which was standardized after
+ * "job-billing" was defined for CUPS...
+ */
+
+ attr = ippFindAttribute(job->attrs, "job-account-id", IPP_TAG_ZERO);
+ }
+ else if (!attr && !strcmp(name, "media"))
+ {
+ /*
+ * Handle alias "media-col" which uses dimensions instead of
+ * names...
+ */
+
+ attr = ippFindAttribute(job->attrs, "media-col/media-size", IPP_TAG_BEGIN_COLLECTION);
+ }
+
+ if (attr)
{
/*
* Add the attribute value...
@@ -705,14 +977,12 @@ cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */
{
case IPP_TAG_INTEGER :
case IPP_TAG_ENUM :
- snprintf(bufptr, sizeof(buffer) - (bufptr - buffer),
- "%d", attr->values[i].integer);
+ snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer), "%d", attr->values[i].integer);
bufptr += strlen(bufptr);
break;
case IPP_TAG_BOOLEAN :
- snprintf(bufptr, sizeof(buffer) - (bufptr - buffer),
- "%d", attr->values[i].boolean);
+ snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer), "%d", attr->values[i].boolean);
bufptr += strlen(bufptr);
break;
@@ -726,14 +996,28 @@ cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */
case IPP_TAG_CHARSET :
case IPP_TAG_LANGUAGE :
case IPP_TAG_MIMETYPE :
- strlcpy(bufptr, attr->values[i].string.text,
- sizeof(buffer) - (bufptr - buffer));
+ strlcpy(bufptr, attr->values[i].string.text, sizeof(buffer) - (size_t)(bufptr - buffer));
bufptr += strlen(bufptr);
break;
+ case IPP_TAG_BEGIN_COLLECTION :
+ if (!strcmp(attr->name, "media-size"))
+ {
+ ipp_attribute_t *x_dimension = ippFindAttribute(ippGetCollection(attr, 0), "x-dimension", IPP_TAG_INTEGER);
+ ipp_attribute_t *y_dimension = ippFindAttribute(ippGetCollection(attr, 0), "y-dimension", IPP_TAG_INTEGER);
+ /* Media dimensions */
+
+ if (x_dimension && y_dimension)
+ {
+ pwg_media_t *pwg = pwgMediaForSize(ippGetInteger(x_dimension, 0), ippGetInteger(y_dimension, 0));
+ /* PWG media name */
+ strlcpy(bufptr, pwg->pwg, sizeof(buffer) - (size_t)(bufptr - buffer));
+ break;
+ }
+ }
+
default :
- strlcpy(bufptr, "???",
- sizeof(buffer) - (bufptr - buffer));
+ strlcpy(bufptr, "???", sizeof(buffer) - (size_t)(bufptr - buffer));
bufptr += strlen(bufptr);
break;
}
@@ -759,7 +1043,70 @@ cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */
*bufptr = '\0';
-#ifdef HAVE_VSYSLOG
+#ifdef HAVE_ASL_H
+ if (!strcmp(ErrorLog, "syslog"))
+ {
+ asl_object_t m; /* Log message */
+ char job_id[32], /* job-id string */
+ completed[32]; /* job-impressions-completed string */
+ static const char * const job_states[] =
+ { /* job-state strings */
+ "Pending",
+ "PendingHeld",
+ "Processing",
+ "ProcessingStopped",
+ "Canceled",
+ "Aborted",
+ "Completed"
+ };
+
+ snprintf(job_id, sizeof(job_id), "%d", job->id);
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_set(m, PWG_Event, "JobStateChanged");
+ asl_set(m, PWG_ServiceURI, job->printer->uri);
+ asl_set(m, PWG_JobID, job_id);
+ asl_set(m, PWG_JobState, job_states[job->state_value - IPP_JSTATE_PENDING]);
+
+ if (job->impressions)
+ {
+ snprintf(completed, sizeof(completed), "%d", ippGetInteger(job->impressions, 0));
+ asl_set(m, PWG_JobImpressionsCompleted, completed);
+ }
+
+ asl_log(NULL, m, ASL_LEVEL_INFO, "%s", buffer);
+
+ asl_release(m);
+ return (1);
+ }
+
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ if (!strcmp(ErrorLog, "syslog"))
+ {
+ static const char * const job_states[] =
+ { /* job-state strings */
+ "Pending",
+ "PendingHeld",
+ "Processing",
+ "ProcessingStopped",
+ "Canceled",
+ "Aborted",
+ "Completed"
+ };
+
+ sd_journal_send("MESSAGE=%s", buffer,
+ "PRIORITY=%i", LOG_INFO,
+ PWG_Event"=JobStateChanged",
+ PWG_ServiceURI"=%s", job->printer->uri,
+ PWG_JobID"=%d", job->id,
+ PWG_JobState"=%s", job_states[job->state_value - IPP_JSTATE_PENDING],
+ PWG_JobImpressionsCompleted"=%d", ippGetInteger(job->impressions, 0),
+ NULL);
+ return (1);
+ }
+
+#elif defined(HAVE_VSYSLOG)
/*
* See if we are logging pages via syslog...
*/
@@ -770,7 +1117,7 @@ cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */
return (1);
}
-#endif /* HAVE_VSYSLOG */
+#endif /* HAVE_ASL_H */
/*
* Not using syslog; check the log file...
@@ -825,7 +1172,9 @@ cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */
* Filter requests as needed...
*/
- if (AccessLogLevel < CUPSD_ACCESSLOG_ALL)
+ if (AccessLogLevel == CUPSD_ACCESSLOG_NONE)
+ return (1);
+ else if (AccessLogLevel < CUPSD_ACCESSLOG_ALL)
{
/*
* Eliminate simple GET, POST, and PUT requests...
@@ -929,7 +1278,36 @@ cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */
}
}
-#ifdef HAVE_VSYSLOG
+#ifdef HAVE_ASL_H
+ if (!strcmp(ErrorLog, "syslog"))
+ {
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+
+ asl_log(NULL, m, ASL_LEVEL_INFO, "REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n",
+ con->http->hostname, con->username[0] != '\0' ? con->username : "-",
+ states[con->operation], _httpEncodeURI(temp, con->uri, sizeof(temp)),
+ con->http->version / 100, con->http->version % 100,
+ code, CUPS_LLCAST con->bytes,
+ con->request ?
+ ippOpString(con->request->request.op.operation_id) : "-",
+ con->response ?
+ ippErrorString(con->response->request.status.status_code) : "-");
+
+ asl_release(m);
+ return (1);
+ }
+
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ if (!strcmp(ErrorLog, "syslog"))
+ {
+ sd_journal_print(LOG_INFO, "REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s", con->http->hostname, con->username[0] != '\0' ? con->username : "-", states[con->operation], _httpEncodeURI(temp, con->uri, sizeof(temp)), con->http->version / 100, con->http->version % 100, code, CUPS_LLCAST con->bytes, con->request ? ippOpString(con->request->request.op.operation_id) : "-", con->response ? ippErrorString(con->response->request.status.status_code) : "-");
+ return (1);
+ }
+
+#elif defined(HAVE_VSYSLOG)
/*
* See if we are logging accesses via syslog...
*/
@@ -938,9 +1316,9 @@ cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */
{
syslog(LOG_INFO,
"REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n",
- con->http.hostname, con->username[0] != '\0' ? con->username : "-",
+ con->http->hostname, con->username[0] != '\0' ? con->username : "-",
states[con->operation], _httpEncodeURI(temp, con->uri, sizeof(temp)),
- con->http.version / 100, con->http.version % 100,
+ con->http->version / 100, con->http->version % 100,
code, CUPS_LLCAST con->bytes,
con->request ?
ippOpString(con->request->request.op.operation_id) : "-",
@@ -949,7 +1327,7 @@ cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */
return (1);
}
-#endif /* HAVE_VSYSLOG */
+#endif /* HAVE_ASL_H */
/*
* Not using syslog; check the log file...
@@ -964,12 +1342,12 @@ cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */
cupsFilePrintf(AccessFile,
"%s - %s %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n",
- con->http.hostname,
+ con->http->hostname,
con->username[0] != '\0' ? con->username : "-",
cupsdGetDateTime(&(con->start), LogTimeFormat),
states[con->operation],
_httpEncodeURI(temp, con->uri, sizeof(temp)),
- con->http.version / 100, con->http.version % 100,
+ con->http->version / 100, con->http->version % 100,
code, CUPS_LLCAST con->bytes,
con->request ?
ippOpString(con->request->request.op.operation_id) : "-",
@@ -991,6 +1369,7 @@ int /* O - 1 on success, 0 on failure */
cupsdWriteErrorLog(int level, /* I - Log level */
const char *message) /* I - Message string */
{
+ int ret = 1; /* Return value */
static const char levels[] = /* Log levels... */
{
' ',
@@ -1006,34 +1385,62 @@ cupsdWriteErrorLog(int level, /* I - Log level */
};
-#ifdef HAVE_VSYSLOG
+#ifdef HAVE_ASL_H
+ if (!strcmp(ErrorLog, "syslog"))
+ {
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_INFO, "%s", message);
+
+ asl_release(m);
+ return (1);
+ }
+
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ if (!strcmp(ErrorLog, "syslog"))
+ {
+ sd_journal_print(log_levels[level], "%s", message);
+ return (1);
+ }
+
+#elif defined(HAVE_VSYSLOG)
/*
* See if we are logging errors via syslog...
*/
if (!strcmp(ErrorLog, "syslog"))
{
- syslog(syslevels[level], "%s", message);
+ syslog(log_levels[level], "%s", message);
return (1);
}
-#endif /* HAVE_VSYSLOG */
+#endif /* HAVE_ASL_H */
/*
* Not using syslog; check the log file...
*/
+ _cupsMutexLock(&log_mutex);
+
if (!cupsdCheckLogFile(&ErrorFile, ErrorLog))
- return (0);
+ {
+ ret = 0;
+ }
+ else
+ {
+ /*
+ * Write the log message...
+ */
- /*
- * Write the log message...
- */
+ cupsFilePrintf(ErrorFile, "%c %s %s\n", levels[level],
+ cupsdGetDateTime(NULL, LogTimeFormat), message);
+ cupsFileFlush(ErrorFile);
+ }
- cupsFilePrintf(ErrorFile, "%c %s %s\n", levels[level],
- cupsdGetDateTime(NULL, LogTimeFormat), message);
- cupsFileFlush(ErrorFile);
+ _cupsMutexUnlock(&log_mutex);
- return (1);
+ return (ret);
}
@@ -1049,7 +1456,7 @@ static int /* O - -1 for fatal, 0 for retry, 1 for success */
format_log_line(const char *message, /* I - Printf-style format string */
va_list ap) /* I - Argument list */
{
- int len; /* Length of formatted line */
+ ssize_t len; /* Length of formatted line */
/*
@@ -1069,17 +1476,16 @@ format_log_line(const char *message, /* I - Printf-style format string */
* Format the log message...
*/
- len = vsnprintf(log_line, log_linesize, message, ap);
+ len = _cups_safe_vsnprintf(log_line, log_linesize, message, ap);
/*
* Resize the buffer as needed...
*/
- if (len >= log_linesize && log_linesize < 65536)
+ if ((size_t)len >= log_linesize && log_linesize < 65536)
{
char *temp; /* Temporary string pointer */
-
len ++;
if (len < 8192)
@@ -1087,12 +1493,12 @@ format_log_line(const char *message, /* I - Printf-style format string */
else if (len > 65536)
len = 65536;
- temp = realloc(log_line, len);
+ temp = realloc(log_line, (size_t)len);
if (temp)
{
log_line = temp;
- log_linesize = len;
+ log_linesize = (size_t)len;
return (0);
}
@@ -1103,5 +1509,5 @@ format_log_line(const char *message, /* I - Printf-style format string */
/*
- * End of "$Id: log.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: log.c 12928 2015-10-23 21:31:58Z msweet $".
*/
diff --git a/scheduler/main.c b/scheduler/main.c
index 11eae52..b1aa503 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -1,39 +1,16 @@
/*
- * "$Id: main.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: main.c 12700 2015-06-08 18:32:35Z msweet $"
*
- * Main loop for the CUPS scheduler.
+ * Main loop for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * "LICENSE" which should have been included with this file. If this
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * main() - Main entry for the CUPS scheduler.
- * cupsdAddString() - Copy and add a string to an array.
- * cupsdCheckProcess() - Tell the main loop to check for dead children.
- * cupsdClearString() - Clear a string.
- * cupsdFreeStrings() - Free an array of strings.
- * cupsdHoldSignals() - Hold child and termination signals.
- * cupsdReleaseSignals() - Release signals for delivery.
- * cupsdSetString() - Set a string value.
- * cupsdSetStringf() - Set a formatted string value.
- * launchd_checkin() - Check-in with launchd and collect the listening
- * fds.
- * launchd_checkout() - Update the launchd KeepAlive file as needed.
- * parent_handler() - Catch USR1/CHLD signals...
- * process_children() - Process all dead children...
- * select_timeout() - Calculate the select timeout value.
- * sigchld_handler() - Handle 'child' signals from old processes.
- * sighup_handler() - Handle 'hangup' signals to reconfigure the
- * scheduler.
- * sigterm_handler() - Handle 'terminate' signals that stop the scheduler.
- * usage() - Show scheduler usage.
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*/
/*
@@ -43,6 +20,12 @@
#define _MAIN_C_
#include "cupsd.h"
#include <sys/resource.h>
+#ifdef HAVE_ASL_H
+# include <asl.h>
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+# define SD_JOURNAL_SUPPRESS_LOCATION
+# include <systemd/sd-journal.h>
+#endif /* HAVE_ASL_H */
#include <syslog.h>
#include <grp.h>
@@ -51,17 +34,18 @@
# include <libgen.h>
# define CUPS_KEEPALIVE CUPS_CACHEDIR "/org.cups.cupsd"
/* Name of the launchd KeepAlive file */
-# ifndef LAUNCH_JOBKEY_KEEPALIVE
-# define LAUNCH_JOBKEY_KEEPALIVE "KeepAlive"
-# endif /* !LAUNCH_JOBKEY_KEEPALIVE */
-# ifndef LAUNCH_JOBKEY_PATHSTATE
-# define LAUNCH_JOBKEY_PATHSTATE "PathState"
-# endif /* !LAUNCH_JOBKEY_PATHSTATE */
-# ifndef LAUNCH_JOBKEY_SERVICEIPC
-# define LAUNCH_JOBKEY_SERVICEIPC "ServiceIPC"
-# endif /* !LAUNCH_JOBKEY_SERVICEIPC */
+# ifdef HAVE_LAUNCH_ACTIVATE_SOCKET
+/* Update when we have a public header we can include */
+extern int launch_activate_socket(const char *name, int **fds, size_t *cnt);
+# endif /* HAVE_LAUNCH_ACTIVATE_SOCKET */
#endif /* HAVE_LAUNCH_H */
+#ifdef HAVE_SYSTEMD
+# include <systemd/sd-daemon.h>
+# define CUPS_KEEPALIVE CUPS_CACHEDIR "/org.cups.cupsd"
+ /* Name of the systemd path file */
+#endif /* HAVE_SYSTEMD */
+
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
# include <malloc.h>
#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
@@ -70,6 +54,10 @@
# include <notify.h>
#endif /* HAVE_NOTIFY_H */
+#ifdef HAVE_DBUS
+# include <dbus/dbus.h>
+#endif /* HAVE_DBUS */
+
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif /* HAVE_SYS_PARAM_H */
@@ -79,16 +67,16 @@
* Local functions...
*/
-#ifdef HAVE_LAUNCHD
-static void launchd_checkin(void);
-static void launchd_checkout(void);
-#endif /* HAVE_LAUNCHD */
static void parent_handler(int sig);
static void process_children(void);
static void sigchld_handler(int sig);
static void sighup_handler(int sig);
static void sigterm_handler(int sig);
static long select_timeout(int fds);
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+static void service_checkin(void);
+static void service_checkout(void);
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
static void usage(int status) __attribute__((noreturn));
@@ -118,7 +106,11 @@ main(int argc, /* I - Number of command-line args */
{
int i; /* Looping var */
char *opt; /* Option character */
- int fg; /* Run in the foreground */
+ int close_all = 1, /* Close all file descriptors? */
+ disconnect = 1, /* Disconnect from controlling terminal? */
+ fg = 0, /* Run in foreground? */
+ run_as_child = 0;
+ /* Running as child process? */
int fds; /* Number of ready descriptors */
cupsd_client_t *con; /* Current client */
cupsd_job_t *job; /* Current job */
@@ -134,22 +126,15 @@ main(int argc, /* I - Number of command-line args */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action; /* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
-#ifdef __sgi
- cups_file_t *fp; /* Fake lpsched lock file */
- struct stat statbuf; /* Needed for checking lpsched FIFO */
-#endif /* __sgi */
- int run_as_child = 0;
- /* Needed for background fork/exec */
#ifdef __APPLE__
- int use_sysman = !getuid();
- /* Use system management functions? */
+ int use_sysman = 1; /* Use system management functions? */
#else
time_t netif_time = 0; /* Time since last network update */
#endif /* __APPLE__ */
-#if HAVE_LAUNCHD
- int launchd_idle_exit;
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ int service_idle_exit;
/* Idle exit on select timeout? */
-#endif /* HAVE_LAUNCHD */
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
#ifdef HAVE_GETEUID
@@ -159,7 +144,7 @@ main(int argc, /* I - Number of command-line args */
if (getuid() != geteuid())
{
- fputs("cupsd: Cannot run as a setuid program\n", stderr);
+ fputs("cupsd: Cannot run as a setuid program.\n", stderr);
return (1);
}
#endif /* HAVE_GETEUID */
@@ -173,8 +158,10 @@ main(int argc, /* I - Number of command-line args */
#ifdef HAVE_LAUNCHD
if (getenv("CUPSD_LAUNCHD"))
{
- Launchd = 1;
- fg = 1;
+ OnDemand = 1;
+ fg = 1;
+ close_all = 0;
+ disconnect = 0;
}
#endif /* HAVE_LAUNCHD */
@@ -185,7 +172,8 @@ main(int argc, /* I - Number of command-line args */
{
case 'C' : /* Run as child with config file */
run_as_child = 1;
- fg = -1;
+ fg = 1;
+ close_all = 0;
case 'c' : /* Configuration file */
i ++;
@@ -240,26 +228,33 @@ main(int argc, /* I - Number of command-line args */
break;
case 'f' : /* Run in foreground... */
- fg = 1;
+ fg = 1;
+ disconnect = 0;
+ close_all = 0;
break;
case 'F' : /* Run in foreground, but disconnect from terminal... */
- fg = -1;
+ fg = 1;
+ close_all = 0;
break;
case 'h' : /* Show usage/help */
usage(0);
break;
- case 'l' : /* Started by launchd... */
-#ifdef HAVE_LAUNCHD
- Launchd = 1;
- fg = 1;
+ case 'l' : /* Started by launchd/systemd... */
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ OnDemand = 1;
+ fg = 1;
+ close_all = 0;
+ disconnect = 0;
#else
- _cupsLangPuts(stderr, _("cupsd: launchd(8) support not compiled "
+ _cupsLangPuts(stderr, _("cupsd: On-demand support not compiled "
"in, running in normal mode."));
- fg = 0;
-#endif /* HAVE_LAUNCHD */
+ fg = 0;
+ disconnect = 1;
+ close_all = 1;
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
break;
case 'p' : /* Stop immediately for profiling */
@@ -267,12 +262,13 @@ main(int argc, /* I - Number of command-line args */
"use only!\n", stderr);
stop_scheduler = 1;
fg = 1;
+ disconnect = 0;
+ close_all = 0;
break;
case 'P' : /* Disable security profiles */
- fputs("cupsd: -P (disable security profiles) is for internal "
- "testing use only!\n", stderr);
- UseProfiles = 0;
+ fputs("cupsd: -P (disable sandboxing) is for internal testing use only.\n", stderr);
+ UseSandboxing = 0;
break;
case 's' : /* Set cups-files.conf location */
@@ -309,6 +305,8 @@ main(int argc, /* I - Number of command-line args */
case 't' : /* Test the cupsd.conf file... */
TestConfigFile = 1;
fg = 1;
+ disconnect = 0;
+ close_all = 0;
break;
default : /* Unknown option */
@@ -325,10 +323,7 @@ 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)
{
@@ -354,13 +349,64 @@ main(int argc, /* I - Number of command-line args */
return (1);
}
- strlcpy(slash, "/cups-files.conf", len - (slash - filename));
+ strlcpy(slash, "/cups-files.conf", len - (size_t)(slash - filename));
cupsdSetString(&CupsFilesFile, filename);
free(filename);
}
+ if (disconnect)
+ {
+ /*
+ * Make sure we aren't tying up any filesystems...
+ */
+
+ chdir("/");
+
+ /*
+ * Disconnect from the controlling terminal...
+ */
+
+ setsid();
+ }
+
+ if (close_all)
+ {
+ /*
+ * Close all open files...
+ */
+
+ getrlimit(RLIMIT_NOFILE, &limit);
+
+ for (i = 0; i < (int)limit.rlim_cur && i < 1024; i ++)
+ close(i);
+
+ /*
+ * Redirect stdin/out/err to /dev/null...
+ */
+
+ if ((i = open("/dev/null", O_RDONLY)) != 0)
+ {
+ dup2(i, 0);
+ close(i);
+ }
+
+ if ((i = open("/dev/null", O_WRONLY)) != 1)
+ {
+ dup2(i, 1);
+ close(i);
+ }
+
+ if ((i = open("/dev/null", O_WRONLY)) != 2)
+ {
+ dup2(i, 2);
+ close(i);
+ }
+ }
+ else
+ LogStderr = cupsFileStderr();
+
/*
- * If the user hasn't specified "-f", run in the background...
+ * Run in the background as needed...
*/
if (!fg)
@@ -435,74 +481,17 @@ main(int argc, /* I - Number of command-line args */
#endif /* __OpenBSD__ && OpenBSD < 201211 */
/*
- * Since CoreFoundation and DBUS both create fork-unsafe data on execution of
- * a program, and since this kind of really unfriendly behavior seems to be
- * more common these days in system libraries, we need to re-execute the
- * background cupsd with the "-C" option to avoid problems. Unfortunately,
- * we also have to assume that argv[0] contains the name of the cupsd
- * executable - there is no portable way to get the real pathname...
+ * Since many system libraries create fork-unsafe data on execution of a
+ * program, we need to re-execute the background cupsd with the "-C" and "-s"
+ * options to avoid problems. Unfortunately, we also have to assume that
+ * argv[0] contains the name of the cupsd executable - there is no portable
+ * way to get the real pathname...
*/
- execlp(argv[0], argv[0], "-C", ConfigurationFile, (char *)0);
+ execlp(argv[0], argv[0], "-C", ConfigurationFile, "-s", CupsFilesFile, (char *)0);
exit(errno);
}
- if (fg < 1)
- {
- /*
- * Make sure we aren't tying up any filesystems...
- */
-
- chdir("/");
-
-#ifndef DEBUG
- /*
- * Disable core dumps...
- */
-
- getrlimit(RLIMIT_CORE, &limit);
- limit.rlim_cur = 0;
- setrlimit(RLIMIT_CORE, &limit);
-
- /*
- * Disconnect from the controlling terminal...
- */
-
- setsid();
-
- /*
- * Close all open files...
- */
-
- getrlimit(RLIMIT_NOFILE, &limit);
-
- for (i = 0; i < limit.rlim_cur && i < 1024; i ++)
- close(i);
-
- /*
- * Redirect stdin/out/err to /dev/null...
- */
-
- if ((i = open("/dev/null", O_RDONLY)) != 0)
- {
- dup2(i, 0);
- close(i);
- }
-
- if ((i = open("/dev/null", O_WRONLY)) != 1)
- {
- dup2(i, 1);
- close(i);
- }
-
- if ((i = open("/dev/null", O_WRONLY)) != 2)
- {
- dup2(i, 2);
- close(i);
- }
-#endif /* DEBUG */
- }
-
/*
* Set the timezone info...
*/
@@ -513,6 +502,14 @@ main(int argc, /* I - Number of command-line args */
setlocale(LC_TIME, "");
#endif /* LC_TIME */
+#ifdef HAVE_DBUS_THREADS_INIT
+ /*
+ * Enable threading support for D-BUS...
+ */
+
+ dbus_threads_init_default();
+#endif /* HAVE_DBUS_THREADS_INIT */
+
/*
* Set the maximum number of files...
*/
@@ -531,7 +528,7 @@ main(int argc, /* I - Number of command-line args */
#endif /* RLIM_INFINITY */
MaxFDs = limit.rlim_max;
- limit.rlim_cur = MaxFDs;
+ limit.rlim_cur = (rlim_t)MaxFDs;
setrlimit(RLIMIT_NOFILE, &limit);
@@ -559,17 +556,18 @@ main(int argc, /* I - Number of command-line args */
cupsdCleanFiles(CacheDir, "*.ipp");
-#if HAVE_LAUNCHD
- if (Launchd)
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ if (OnDemand)
{
/*
- * If we were started by launchd get the listen sockets file descriptors...
+ * If we were started on demand by launchd or systemd get the listen sockets
+ * file descriptors...
*/
- launchd_checkin();
- launchd_checkout();
+ service_checkin();
+ service_checkout();
}
-#endif /* HAVE_LAUNCHD */
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
/*
* Startup the server...
@@ -618,28 +616,6 @@ main(int argc, /* I - Number of command-line args */
signal(SIGTERM, sigterm_handler);
#endif /* HAVE_SIGSET */
-#ifdef __sgi
- /*
- * Try to create a fake lpsched lock file if one is not already there.
- * Some Adobe applications need it under IRIX in order to enable
- * printing...
- */
-
- if ((fp = cupsFileOpen("/var/spool/lp/SCHEDLOCK", "w")) == NULL)
- {
- syslog(LOG_LPR, "Unable to create fake lpsched lock file "
- "\"/var/spool/lp/SCHEDLOCK\"\' - %s!",
- strerror(errno));
- }
- else
- {
- fchmod(cupsFileNumber(fp), 0644);
- fchown(cupsFileNumber(fp), User, Group);
-
- cupsFileClose(fp);
- }
-#endif /* __sgi */
-
/*
* Initialize authentication certificates...
*/
@@ -678,18 +654,15 @@ main(int argc, /* I - Number of command-line args */
* Send server-started event...
*/
-#ifdef HAVE_LAUNCHD
- if (Launchd)
- cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
- "Scheduler started via launchd.");
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+ if (OnDemand)
+ cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started on demand.");
else
-#endif /* HAVE_LAUNCHD */
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
if (fg)
- cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
- "Scheduler started in foreground.");
+ cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started in foreground.");
else
- cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL,
- "Scheduler started in background.");
+ cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started in background.");
/*
* Start any pending print jobs...
@@ -732,10 +705,10 @@ main(int argc, /* I - Number of command-line args */
for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
con;
con = (cupsd_client_t *)cupsArrayNext(Clients))
- if (con->http.state == HTTP_WAITING)
+ if (httpGetState(con->http) == HTTP_WAITING)
cupsdCloseClient(con);
else
- con->http.keep_alive = HTTP_KEEPALIVE_OFF;
+ con->http->keep_alive = HTTP_KEEPALIVE_OFF;
cupsdPauseListening();
}
@@ -763,23 +736,21 @@ main(int argc, /* I - Number of command-line args */
if (!cupsdReadConfiguration())
{
- syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!",
- ConfigurationFile);
- break;
- }
-
-#if HAVE_LAUNCHD
- if (Launchd)
- {
- /*
- * If we were started by launchd, get the listen socket file
- * descriptors...
- */
+#ifdef HAVE_ASL_H
+ asl_object_t m; /* Log message */
+
+ m = asl_new(ASL_TYPE_MSG);
+ asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
+ asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to read configuration file \"%s\" - exiting.", ConfigurationFile);
+ asl_release(m);
+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
+ sd_journal_print(LOG_ERR, "Unable to read configuration file \"%s\" - exiting.", ConfigurationFile);
+#else
+ syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting.", ConfigurationFile);
+#endif /* HAVE_ASL_H */
- launchd_checkin();
- launchd_checkout();
+ break;
}
-#endif /* HAVE_LAUNCHD */
/*
* Startup the server...
@@ -810,23 +781,26 @@ main(int argc, /* I - Number of command-line args */
if ((timeout = select_timeout(fds)) > 1 && LastEvent)
timeout = 1;
-#if HAVE_LAUNCHD
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
/*
* If no other work is scheduled and we're being controlled by
* launchd then timeout after 'LaunchdTimeout' seconds of
* inactivity...
*/
- if (timeout == 86400 && Launchd && LaunchdTimeout &&
+ if (timeout == 86400 && OnDemand && IdleExitTimeout &&
!cupsArrayCount(ActiveJobs) &&
+# ifdef HAVE_SYSTEMD
+ !WebInterface &&
+# endif /* HAVE_SYSTEMD */
(!Browsing || !BrowseLocalProtocols || !cupsArrayCount(Printers)))
{
- timeout = LaunchdTimeout;
- launchd_idle_exit = 1;
+ timeout = IdleExitTimeout;
+ service_idle_exit = 1;
}
else
- launchd_idle_exit = 0;
-#endif /* HAVE_LAUNCHD */
+ service_idle_exit = 0;
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
if ((fds = cupsdDoSelect(timeout)) < 0)
{
@@ -854,7 +828,7 @@ main(int argc, /* I - Number of command-line args */
i ++, con = (cupsd_client_t *)cupsArrayNext(Clients))
cupsdLogMessage(CUPSD_LOG_EMERG,
"Clients[%d] = %d, file = %d, state = %d",
- i, con->http.fd, con->file, con->http.state);
+ i, con->number, con->file, httpGetState(con->http));
for (i = 0, lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
lis;
@@ -923,13 +897,13 @@ main(int argc, /* I - Number of command-line args */
}
#endif /* !__APPLE__ */
-#if HAVE_LAUNCHD
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
/*
* If no other work was scheduled and we're being controlled by launchd
* then timeout after 'LaunchdTimeout' seconds of inactivity...
*/
- if (!fds && launchd_idle_exit)
+ if (!fds && service_idle_exit)
{
cupsdLogMessage(CUPSD_LOG_INFO,
"Printer sharing is off and there are no jobs pending, "
@@ -937,7 +911,7 @@ main(int argc, /* I - Number of command-line args */
stop_scheduler = 1;
break;
}
-#endif /* HAVE_LAUNCHD */
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
/*
* Resume listening for new connections as needed...
@@ -991,7 +965,7 @@ main(int argc, /* I - Number of command-line args */
* Process pending data in the input buffer...
*/
- if (con->http.used)
+ if (httpGetReady(con->http))
{
cupsdReadClient(con);
continue;
@@ -1002,11 +976,9 @@ main(int argc, /* I - Number of command-line args */
*/
activity = current_time - Timeout;
- if (con->http.activity < activity && !con->pipe_pid)
+ if (httpGetActivity(con->http) < activity && !con->pipe_pid)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Closing client %d after %d seconds of inactivity...",
- con->http.fd, Timeout);
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Closing client %d after %d seconds of inactivity.", con->number, Timeout);
cupsdCloseClient(con);
continue;
@@ -1143,14 +1115,14 @@ main(int argc, /* I - Number of command-line args */
cupsdStopServer();
-#ifdef HAVE_LAUNCHD
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
/*
- * Update the launchd KeepAlive file as needed...
+ * Update the keep-alive file as needed...
*/
- if (Launchd)
- launchd_checkout();
-#endif /* HAVE_LAUNCHD */
+ if (OnDemand)
+ service_checkout();
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
/*
* Stop all jobs...
@@ -1167,18 +1139,6 @@ main(int argc, /* I - Number of command-line args */
cupsdStopSystemMonitor();
#endif /* __APPLE__ */
-#ifdef __sgi
- /*
- * Remove the fake IRIX lpsched lock file, but only if the existing
- * file is not a FIFO which indicates that the real IRIX lpsched is
- * running...
- */
-
- if (!stat("/var/spool/lp/FIFO", &statbuf))
- if (!S_ISFIFO(statbuf.st_mode))
- unlink("/var/spool/lp/SCHEDLOCK");
-#endif /* __sgi */
-
cupsdStopSelect();
return (!stop_scheduler);
@@ -1196,8 +1156,8 @@ cupsdAddString(cups_array_t **a, /* IO - String array */
if (!*a)
*a = cupsArrayNew3((cups_array_func_t)strcmp, NULL,
(cups_ahash_func_t)NULL, 0,
- (cups_acopy_func_t)_cupsStrAlloc,
- (cups_afree_func_t)_cupsStrFree);
+ (cups_acopy_func_t)strdup,
+ (cups_afree_func_t)free);
return (cupsArrayAdd(*a, (char *)s));
}
@@ -1227,7 +1187,7 @@ cupsdClearString(char **s) /* O - String value */
{
if (s && *s)
{
- _cupsStrFree(*s);
+ free(*s);
*s = NULL;
}
}
@@ -1308,10 +1268,10 @@ cupsdSetString(char **s, /* O - New string */
return;
if (*s)
- _cupsStrFree(*s);
+ free(*s);
if (v)
- *s = _cupsStrAlloc(v);
+ *s = strdup(v);
else
*s = NULL;
}
@@ -1342,207 +1302,16 @@ cupsdSetStringf(char **s, /* O - New string */
vsnprintf(v, sizeof(v), f, ap);
va_end(ap);
- *s = _cupsStrAlloc(v);
+ *s = strdup(v);
}
else
*s = NULL;
if (olds)
- _cupsStrFree(olds);
+ free(olds);
}
-#ifdef HAVE_LAUNCHD
-/*
- * 'launchd_checkin()' - Check-in with launchd and collect the listening fds.
- */
-
-static void
-launchd_checkin(void)
-{
- size_t i, /* Looping var */
- count; /* Number of listeners */
- launch_data_t ld_msg, /* Launch data message */
- ld_resp, /* Launch data response */
- ld_array, /* Launch data array */
- ld_sockets, /* Launch data sockets dictionary */
- tmp; /* Launch data */
- cupsd_listener_t *lis; /* Listeners array */
- http_addr_t addr; /* Address variable */
- socklen_t addrlen; /* Length of address */
- int fd; /* File descriptor */
- char s[256]; /* String addresss */
-
-
- cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: pid=%d", (int)getpid());
-
- /*
- * Check-in with launchd...
- */
-
- ld_msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
- if ((ld_resp = launch_msg(ld_msg)) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "launchd_checkin: launch_msg(\"" LAUNCH_KEY_CHECKIN
- "\") IPC failure");
- exit(EXIT_FAILURE);
- return; /* anti-compiler-warning */
- }
-
- if (launch_data_get_type(ld_resp) == LAUNCH_DATA_ERRNO)
- {
- errno = launch_data_get_errno(ld_resp);
- cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Check-in failed: %s",
- strerror(errno));
- exit(EXIT_FAILURE);
- return; /* anti-compiler-warning */
- }
-
- /*
- * Get the sockets dictionary...
- */
-
- if ((ld_sockets = launch_data_dict_lookup(ld_resp, LAUNCH_JOBKEY_SOCKETS))
- == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "launchd_checkin: No sockets found to answer requests on!");
- exit(EXIT_FAILURE);
- return; /* anti-compiler-warning */
- }
-
- /*
- * Get the array of listener sockets...
- */
-
- if ((ld_array = launch_data_dict_lookup(ld_sockets, "Listeners")) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "launchd_checkin: No sockets found to answer requests on!");
- exit(EXIT_FAILURE);
- return; /* anti-compiler-warning */
- }
-
- /*
- * Add listening fd(s) to the Listener array...
- */
-
- if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY)
- {
- count = launch_data_array_get_count(ld_array);
-
- for (i = 0; i < count; i ++)
- {
- /*
- * Get the launchd file descriptor and address...
- */
-
- if ((tmp = launch_data_array_get_index(ld_array, i)) != NULL)
- {
- fd = launch_data_get_fd(tmp);
- addrlen = sizeof(addr);
-
- if (getsockname(fd, (struct sockaddr *)&addr, &addrlen))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "launchd_checkin: Unable to get local address - %s",
- strerror(errno));
- continue;
- }
-
- /*
- * Try to match the launchd socket address to one of the listeners...
- */
-
- for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
- lis;
- lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
- if (httpAddrEqual(&lis->address, &addr))
- break;
-
- /*
- * Add a new listener If there's no match...
- */
-
- if (lis)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "launchd_checkin: Matched existing listener %s with fd %d...",
- httpAddrString(&(lis->address), s, sizeof(s)), fd);
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "launchd_checkin: Adding new listener %s with fd %d...",
- httpAddrString(&addr, s, sizeof(s)), fd);
-
- if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "launchd_checkin: Unable to allocate listener - "
- "%s.", strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- cupsArrayAdd(Listeners, lis);
-
- memcpy(&lis->address, &addr, sizeof(lis->address));
- }
-
- lis->fd = fd;
-
-# ifdef HAVE_SSL
- if (_httpAddrPort(&(lis->address)) == 443)
- lis->encryption = HTTP_ENCRYPT_ALWAYS;
-# endif /* HAVE_SSL */
- }
- }
- }
-
- launch_data_free(ld_msg);
- launch_data_free(ld_resp);
-}
-
-
-/*
- * 'launchd_checkout()' - Update the launchd KeepAlive file as needed.
- */
-
-static void
-launchd_checkout(void)
-{
- int fd; /* File descriptor */
-
-
- /*
- * Create or remove the launchd KeepAlive file based on whether
- * there are active jobs, polling, browsing for remote printers or
- * shared printers to advertise...
- */
-
- if (cupsArrayCount(ActiveJobs) ||
- (Browsing && BrowseLocalProtocols && cupsArrayCount(Printers)))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Creating launchd keepalive file \"" CUPS_KEEPALIVE
- "\"...");
-
- if ((fd = open(CUPS_KEEPALIVE, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR)) >= 0)
- close(fd);
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Removing launchd keepalive file \"" CUPS_KEEPALIVE
- "\"...");
-
- unlink(CUPS_KEEPALIVE);
- }
-}
-#endif /* HAVE_LAUNCHD */
-
-
/*
* 'parent_handler()' - Catch USR1/CHLD signals...
*/
@@ -1699,8 +1468,7 @@ process_children(void)
}
if (job->printer_message)
- cupsdSetString(&(job->printer_message->values[0].string.text),
- message);
+ ippSetString(job->attrs, &job->printer_message, 0, message);
}
}
@@ -1820,7 +1588,7 @@ select_timeout(int fds) /* I - Number of descriptors returned */
for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
con;
con = (cupsd_client_t *)cupsArrayNext(Clients))
- if (con->http.used > 0)
+ if (httpGetReady(con->http))
return (0);
/*
@@ -1874,9 +1642,9 @@ select_timeout(int fds) /* I - Number of descriptors returned */
for (con = (cupsd_client_t *)cupsArrayFirst(Clients);
con;
con = (cupsd_client_t *)cupsArrayNext(Clients))
- if ((con->http.activity + Timeout) < timeout)
+ if ((httpGetActivity(con->http) + Timeout) < timeout)
{
- timeout = con->http.activity + Timeout;
+ timeout = httpGetActivity(con->http) + Timeout;
why = "timeout a client connection";
}
@@ -2040,6 +1808,361 @@ sigterm_handler(int sig) /* I - Signal number */
}
+#if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD)
+/*
+ * 'service_checkin()' - Check-in with launchd and collect the listening fds.
+ */
+
+static void
+service_checkin(void)
+{
+# ifdef HAVE_LAUNCH_ACTIVATE_SOCKET
+ int error; /* Check-in error, if any */
+ size_t i, /* Looping var */
+ count; /* Number of listeners */
+ int *ld_sockets; /* Listener sockets */
+ cupsd_listener_t *lis; /* Listeners array */
+ http_addr_t addr; /* Address variable */
+ socklen_t addrlen; /* Length of address */
+ char s[256]; /* String addresss */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: pid=%d", (int)getpid());
+
+ /*
+ * Check-in with launchd...
+ */
+
+ if ((error = launch_activate_socket("Listeners", &ld_sockets, &count)) != 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to get listener sockets: %s", strerror(error));
+ exit(EXIT_FAILURE);
+ return; /* anti-compiler-warning */
+ }
+
+ /*
+ * Try to match the launchd sockets to the cupsd listeners...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: %d listeners.", (int)count);
+
+ for (i = 0; i < count; i ++)
+ {
+ /*
+ * Get the launchd socket address...
+ */
+
+ addrlen = sizeof(addr);
+
+ if (getsockname(ld_sockets[i], (struct sockaddr *)&addr, &addrlen))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to get local address for listener #%d: %s", (int)i + 1, strerror(errno));
+ continue;
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Listener #%d at fd %d, \"%s\".", (int)i + 1, ld_sockets[i], httpAddrString(&addr, s, sizeof(s)));
+
+ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
+ lis;
+ lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
+ if (httpAddrEqual(&lis->address, &addr))
+ break;
+
+ /*
+ * Add a new listener if there's no match...
+ */
+
+ if (lis)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Matched existing listener #%d to %s.", (int)i + 1, httpAddrString(&(lis->address), s, sizeof(s)));
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Adding new listener #%d for %s.", (int)i + 1, httpAddrString(&addr, s, sizeof(s)));
+
+ if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to allocate listener: %s", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ cupsArrayAdd(Listeners, lis);
+
+ memcpy(&lis->address, &addr, sizeof(lis->address));
+ }
+
+ lis->fd = ld_sockets[i];
+ lis->on_demand = 1;
+
+# ifdef HAVE_SSL
+ if (httpAddrPort(&(lis->address)) == 443)
+ lis->encryption = HTTP_ENCRYPT_ALWAYS;
+# endif /* HAVE_SSL */
+ }
+
+ free(ld_sockets);
+
+# elif defined(HAVE_LAUNCHD)
+ size_t i, /* Looping var */
+ count; /* Number of listeners */
+ launch_data_t ld_msg, /* Launch data message */
+ ld_resp, /* Launch data response */
+ ld_array, /* Launch data array */
+ ld_sockets, /* Launch data sockets dictionary */
+ tmp; /* Launch data */
+ cupsd_listener_t *lis; /* Listeners array */
+ http_addr_t addr; /* Address variable */
+ socklen_t addrlen; /* Length of address */
+ int fd; /* File descriptor */
+ char s[256]; /* String addresss */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: pid=%d", (int)getpid());
+
+ /*
+ * Check-in with launchd...
+ */
+
+ ld_msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
+ if ((ld_resp = launch_msg(ld_msg)) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "service_checkin: launch_msg(\"" LAUNCH_KEY_CHECKIN
+ "\") IPC failure");
+ exit(EXIT_FAILURE);
+ return; /* anti-compiler-warning */
+ }
+
+ if (launch_data_get_type(ld_resp) == LAUNCH_DATA_ERRNO)
+ {
+ errno = launch_data_get_errno(ld_resp);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Check-in failed: %s",
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ return; /* anti-compiler-warning */
+ }
+
+ /*
+ * Get the sockets dictionary...
+ */
+
+ if ((ld_sockets = launch_data_dict_lookup(ld_resp, LAUNCH_JOBKEY_SOCKETS))
+ == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "service_checkin: No sockets found to answer requests on.");
+ exit(EXIT_FAILURE);
+ return; /* anti-compiler-warning */
+ }
+
+ /*
+ * Get the array of listener sockets...
+ */
+
+ if ((ld_array = launch_data_dict_lookup(ld_sockets, "Listeners")) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "service_checkin: No sockets found to answer requests on.");
+ exit(EXIT_FAILURE);
+ return; /* anti-compiler-warning */
+ }
+
+ /*
+ * Add listening fd(s) to the Listener array...
+ */
+
+ if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY)
+ {
+ count = launch_data_array_get_count(ld_array);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: %d listeners.", (int)count);
+
+ for (i = 0; i < count; i ++)
+ {
+ /*
+ * Get the launchd file descriptor and address...
+ */
+
+ if ((tmp = launch_data_array_get_index(ld_array, i)) != NULL)
+ {
+ fd = launch_data_get_fd(tmp);
+ addrlen = sizeof(addr);
+
+ if (getsockname(fd, (struct sockaddr *)&addr, &addrlen))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to get local address for listener #%d: %s", (int)i + 1, strerror(errno));
+ continue;
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Listener #%d at fd %d, \"%s\".", (int)i + 1, fd, httpAddrString(&addr, s, sizeof(s)));
+
+ /*
+ * Try to match the launchd socket address to one of the listeners...
+ */
+
+ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
+ lis;
+ lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
+ if (httpAddrEqual(&lis->address, &addr))
+ break;
+
+ /*
+ * Add a new listener If there's no match...
+ */
+
+ if (lis)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Matched existing listener #%d to %s.", (int)i + 1, httpAddrString(&(lis->address), s, sizeof(s)));
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Adding new listener #%d for %s.", (int)i + 1, httpAddrString(&addr, s, sizeof(s)));
+
+ if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to allocate listener: %s.", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ cupsArrayAdd(Listeners, lis);
+
+ memcpy(&lis->address, &addr, sizeof(lis->address));
+ }
+
+ lis->fd = fd;
+ lis->on_demand = 1;
+
+# ifdef HAVE_SSL
+ if (httpAddrPort(&(lis->address)) == 443)
+ lis->encryption = HTTP_ENCRYPT_ALWAYS;
+# endif /* HAVE_SSL */
+ }
+ }
+ }
+
+ launch_data_free(ld_msg);
+ launch_data_free(ld_resp);
+
+# else /* HAVE_SYSTEMD */
+ int i, /* Looping var */
+ count; /* Number of listeners */
+ cupsd_listener_t *lis; /* Listeners array */
+ http_addr_t addr; /* Address variable */
+ socklen_t addrlen; /* Length of address */
+ char s[256]; /* String addresss */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: pid=%d", (int)getpid());
+
+ /*
+ * Check-in with systemd...
+ */
+
+ if ((count = sd_listen_fds(0)) < 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to get listener sockets: %s", strerror(-count));
+ exit(EXIT_FAILURE);
+ return; /* anti-compiler-warning */
+ }
+
+ /*
+ * Try to match the systemd sockets to the cupsd listeners...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: %d listeners.", count);
+
+ for (i = 0; i < count; i ++)
+ {
+ /*
+ * Get the launchd socket address...
+ */
+
+ addrlen = sizeof(addr);
+
+ if (getsockname(SD_LISTEN_FDS_START + i, (struct sockaddr *)&addr, &addrlen))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to get local address for listener #%d: %s", (int)i + 1, strerror(errno));
+ continue;
+ }
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Listener #%d at fd %d, \"%s\".", (int)i + 1, SD_LISTEN_FDS_START + i, httpAddrString(&addr, s, sizeof(s)));
+
+ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
+ lis;
+ lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
+ if (httpAddrEqual(&lis->address, &addr))
+ break;
+
+ /*
+ * Add a new listener if there's no match...
+ */
+
+ if (lis)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Matched existing listener #%d to %s.", (int)i + 1, httpAddrString(&(lis->address), s, sizeof(s)));
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "service_checkin: Adding new listener #%d for %s.", (int)i + 1, httpAddrString(&addr, s, sizeof(s)));
+
+ if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "service_checkin: Unable to allocate listener: %s", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ cupsArrayAdd(Listeners, lis);
+
+ memcpy(&lis->address, &addr, sizeof(lis->address));
+ }
+
+ lis->fd = SD_LISTEN_FDS_START + i;
+ lis->on_demand = 1;
+
+# ifdef HAVE_SSL
+ if (httpAddrPort(&(lis->address)) == 443)
+ lis->encryption = HTTP_ENCRYPT_ALWAYS;
+# endif /* HAVE_SSL */
+ }
+# endif /* HAVE_LAUNCH_ACTIVATE_SOCKET */
+}
+
+
+/*
+ * 'service_checkout()' - Update the CUPS_KEEPALIVE file as needed.
+ */
+
+static void
+service_checkout(void)
+{
+ int fd; /* File descriptor */
+
+
+ /*
+ * Create or remove the "keep-alive" file based on whether there are active
+ * jobs or shared printers to advertise...
+ */
+
+ if (cupsArrayCount(ActiveJobs) || /* Active jobs */
+ WebInterface || /* Web interface enabled */
+ (Browsing && BrowseLocalProtocols && cupsArrayCount(Printers)))
+ /* Printers being shared */
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Creating keep-alive file \"" CUPS_KEEPALIVE "\".");
+
+ if ((fd = open(CUPS_KEEPALIVE, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR)) >= 0)
+ close(fd);
+ }
+ else
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Removing keep-alive file \"" CUPS_KEEPALIVE "\".");
+
+ unlink(CUPS_KEEPALIVE);
+ }
+}
+#endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */
+
+
/*
* 'usage()' - Show scheduler usage.
*/
@@ -2057,7 +2180,7 @@ usage(int status) /* O - Exit status */
_cupsLangPuts(fp, _(" -F Run in the foreground but "
"detach from console."));
_cupsLangPuts(fp, _(" -h Show this usage message."));
- _cupsLangPuts(fp, _(" -l Run cupsd from launchd(8)."));
+ _cupsLangPuts(fp, _(" -l Run cupsd on demand."));
_cupsLangPuts(fp, _(" -t Test the configuration "
"file."));
@@ -2066,5 +2189,5 @@ usage(int status) /* O - Exit status */
/*
- * End of "$Id: main.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: main.c 12700 2015-06-08 18:32:35Z msweet $".
*/
diff --git a/scheduler/mime-private.h b/scheduler/mime-private.h
index f984548..078953d 100644
--- a/scheduler/mime-private.h
+++ b/scheduler/mime-private.h
@@ -1,5 +1,5 @@
/*
- * "$Id: mime-private.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: mime-private.h 3411 2011-09-07 22:31:27Z msweet $"
*
* Private MIME type/conversion database definitions for CUPS.
*
@@ -41,5 +41,5 @@ extern void _mimeError(mime_t *mime, const char *format, ...)
#endif /* !_CUPS_MIME_PRIVATE_H_ */
/*
- * End of "$Id: mime-private.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: mime-private.h 3411 2011-09-07 22:31:27Z msweet $".
*/
diff --git a/scheduler/mime.c b/scheduler/mime.c
index 412c9e0..29d3ebc 100644
--- a/scheduler/mime.c
+++ b/scheduler/mime.c
@@ -1,40 +1,16 @@
/*
- * "$Id: mime.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: mime.c 11558 2014-02-06 18:33:34Z msweet $"
*
- * MIME database file routines for CUPS.
+ * MIME database file routines for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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:
- *
- * mimeDelete() - Delete (free) a MIME database.
- * mimeDeleteFilter() - Delete a filter from the MIME database.
- * mimeDeleteType() - Delete a type from the MIME database.
- * _mimeError() - Show an error message.
- * mimeFirstFilter() - Get the first filter in the MIME database.
- * mimeFirstType() - Get the first type in the MIME database.
- * mimeLoad() - Create a new MIME database from disk.
- * mimeLoadFilters() - Load filter definitions from disk.
- * mimeLoadTypes() - Load type definitions from disk.
- * mimeNew() - Create a new, empty MIME database.
- * mimeNextFilter() - Get the next filter in the MIME database.
- * mimeNextType() - Get the next type in the MIME database.
- * mimeNumFilters() - Get the number of filters in a MIME database.
- * mimeNumTypes() - Get the number of types in a MIME database.
- * mimeSetErrorCallback() - Set the callback for error messages.
- * mime_add_fcache() - Add a filter to the filter cache.
- * mime_compare_fcache() - Compare two filter cache entries.
- * mime_delete_fcache() - Free all memory used by the filter cache.
- * mime_delete_rules() - Free all memory for the given rule tree.
- * mime_load_convs() - Load a xyz.convs file.
- * mime_load_types() - Load a xyz.types file.
+ * 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/".
*/
/*
@@ -134,7 +110,7 @@ mimeDeleteFilter(mime_t *mime, /* I - MIME database */
filter ? filter->dst->super : "???",
filter ? filter->cost : -1,
filter ? CUPS_LLCAST filter->maxsize : CUPS_LLCAST -1));
-
+
if (!mime || !filter)
return;
@@ -659,6 +635,9 @@ mime_delete_rules(mime_magic_t *rules) /* I - Rules to free */
if (rules->child != NULL)
mime_delete_rules(rules->child);
+ if (rules->op == MIME_MAGIC_REGEX)
+ regfree(&(rules->value.rev));
+
free(rules);
rules = next;
}
@@ -741,7 +720,7 @@ mime_load_convs(
while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
(temp - super + 1) < MIME_MAX_SUPER)
- *temp++ = tolower(*lineptr++ & 255);
+ *temp++ = (char)tolower(*lineptr++ & 255);
*temp = '\0';
@@ -753,7 +732,7 @@ mime_load_convs(
while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
*lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
- *temp++ = tolower(*lineptr++ & 255);
+ *temp++ = (char)tolower(*lineptr++ & 255);
*temp = '\0';
@@ -798,7 +777,7 @@ mime_load_convs(
if (!mime_add_fcache(filtercache, filter, filterpath))
{
DEBUG_printf(("mime_load_convs: Filter %s not found in %s.", filter,
- filterpath));
+ filterpath));
_mimeError(mime, "Filter \"%s\" not found.", filter);
continue;
}
@@ -814,7 +793,7 @@ mime_load_convs(
while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
(temp - super + 1) < MIME_MAX_SUPER)
- *temp++ = tolower(*lineptr++ & 255);
+ *temp++ = (char)tolower(*lineptr++ & 255);
*temp = '\0';
@@ -826,7 +805,7 @@ mime_load_convs(
while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
*lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
- *temp++ = tolower(*lineptr++ & 255);
+ *temp++ = (char)tolower(*lineptr++ & 255);
*temp = '\0';
@@ -836,8 +815,8 @@ mime_load_convs(
* Force * / * to be "application/octet-stream"...
*/
- strcpy(super, "application");
- strcpy(type, "octet-stream");
+ strlcpy(super, "application", sizeof(super));
+ strlcpy(type, "octet-stream", sizeof(type));
}
/*
@@ -865,7 +844,7 @@ mime_load_types(mime_t *mime, /* I - MIME database */
const char *filename) /* I - Types file to load */
{
cups_file_t *fp; /* Types file */
- int linelen; /* Length of line */
+ size_t linelen; /* Length of line */
char line[32768], /* Input line from file */
*lineptr, /* Current position in line */
super[MIME_MAX_SUPER], /* Super-type name */
@@ -927,7 +906,7 @@ mime_load_types(mime_t *mime, /* I - MIME database */
while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
(temp - super + 1) < MIME_MAX_SUPER)
- *temp++ = tolower(*lineptr++ & 255);
+ *temp++ = (char)tolower(*lineptr++ & 255);
*temp = '\0';
@@ -939,7 +918,7 @@ mime_load_types(mime_t *mime, /* I - MIME database */
while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
*lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
- *temp++ = tolower(*lineptr++ & 255);
+ *temp++ = (char)tolower(*lineptr++ & 255);
*temp = '\0';
@@ -956,5 +935,5 @@ mime_load_types(mime_t *mime, /* I - MIME database */
/*
- * End of "$Id: mime.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: mime.c 11558 2014-02-06 18:33:34Z msweet $".
*/
diff --git a/scheduler/mime.h b/scheduler/mime.h
index 51d7a29..ddd3283 100644
--- a/scheduler/mime.h
+++ b/scheduler/mime.h
@@ -1,9 +1,9 @@
/*
- * "$Id: mime.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: mime.h 11272 2013-09-10 19:15:36Z msweet $"
*
* MIME type/conversion database definitions for CUPS.
*
- * 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
@@ -19,6 +19,7 @@
# include <cups/array.h>
# include <cups/ipp.h>
# include <cups/file.h>
+# include <regex.h>
/*
@@ -58,7 +59,8 @@ typedef enum
MIME_MAGIC_INT, /* Integer/32-bit word matches */
MIME_MAGIC_LOCALE, /* Current locale matches string */
MIME_MAGIC_CONTAINS, /* File contains a string */
- MIME_MAGIC_ISTRING /* Case-insensitive string matches */
+ MIME_MAGIC_ISTRING, /* Case-insensitive string matches */
+ MIME_MAGIC_REGEX /* Regular expression matches */
} mime_op_t;
typedef struct _mime_magic_s /**** MIME Magic Data ****/
@@ -80,6 +82,7 @@ typedef struct _mime_magic_s /**** MIME Magic Data ****/
unsigned char charv; /* Byte value */
unsigned short shortv; /* Short value */
unsigned intv; /* Integer value */
+ regex_t rev; /* Regular expression value */
} value;
} mime_magic_t;
@@ -158,5 +161,5 @@ extern void mimeSetErrorCallback(mime_t *mime, mime_error_cb_t cb,
#endif /* !_CUPS_MIME_H_ */
/*
- * End of "$Id: mime.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: mime.h 11272 2013-09-10 19:15:36Z msweet $".
*/
diff --git a/scheduler/network.c b/scheduler/network.c
index 07b5265..18f9b7c 100644
--- a/scheduler/network.c
+++ b/scheduler/network.c
@@ -1,23 +1,16 @@
/*
- * "$Id: network.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: network.c 11497 2014-01-06 21:59:35Z msweet $"
*
- * Network interface functions for the CUPS scheduler.
+ * Network interface functions for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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"
- * "LICENSE" which should have been included with this file. If this
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * cupsdNetIFFind() - Find a network interface.
- * cupsdNetIFFree() - Free the current network interface list.
- * cupsdNetIFUpdate() - Update the network interface list as needed...
- * compare_netif() - Compare two network interfaces.
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * "LICENSE" which should have been included with this file. If this
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*/
/*
@@ -133,7 +126,10 @@ cupsdNetIFUpdate(void)
*/
if (getifaddrs(&addrs) < 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdNetIFUpdate: Unable to get interface list - %s", strerror(errno));
return;
+ }
for (addr = addrs; addr != NULL; addr = addr->ifa_next)
{
@@ -148,7 +144,10 @@ cupsdNetIFUpdate(void)
#endif
) ||
addr->ifa_netmask == NULL || addr->ifa_name == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdNetIFUpdate: Ignoring \"%s\".", addr->ifa_name);
continue;
+ }
/*
* Try looking up the hostname for the address as needed...
@@ -178,7 +177,10 @@ cupsdNetIFUpdate(void)
hostlen = strlen(hostname);
if ((temp = calloc(1, sizeof(cupsd_netif_t) + hostlen)) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdNetIFUpdate: Unable to allocate memory for interface.");
break;
+ }
/*
* Copy all of the information...
@@ -264,7 +266,7 @@ cupsdNetIFUpdate(void)
if (match)
{
- temp->port = _httpAddrPort(&(lis->address));
+ temp->port = httpAddrPort(&(lis->address));
break;
}
}
@@ -296,5 +298,5 @@ compare_netif(cupsd_netif_t *a, /* I - First network interface */
/*
- * End of "$Id: network.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: network.c 11497 2014-01-06 21:59:35Z msweet $".
*/
diff --git a/scheduler/network.h b/scheduler/network.h
index 0570975..411a6d2 100644
--- a/scheduler/network.h
+++ b/scheduler/network.h
@@ -1,5 +1,5 @@
/*
- * "$Id: network.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: network.h 10996 2013-05-29 11:51:34Z msweet $"
*
* Network interface definitions for the CUPS scheduler.
*
@@ -48,5 +48,5 @@ extern void cupsdNetIFUpdate(void);
/*
- * End of "$Id: network.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: network.h 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/org.cups.cups-lpd.plist.in b/scheduler/org.cups.cups-lpd.plist.in
index 32067ef..76eb2ee 100644
--- a/scheduler/org.cups.cups-lpd.plist.in
+++ b/scheduler/org.cups.cups-lpd.plist.in
@@ -6,6 +6,12 @@
<true/>
<key>Label</key>
<string>org.cups.cups-lpd</string>
+ <key>ProcessType</key>
+ <string>Background</string>
+ <key>EnableTransactions</key>
+ <true/>
+ <key>EnablePressuredExit</key>
+ <true/>
<key>ProgramArguments</key>
<array>
<string>/usr/libexec/cups/daemon/cups-lpd</string>
diff --git a/scheduler/org.cups.cups-lpd.socket b/scheduler/org.cups.cups-lpd.socket
new file mode 100644
index 0000000..dd5288c
--- /dev/null
+++ b/scheduler/org.cups.cups-lpd.socket
@@ -0,0 +1,9 @@
+[Unit]
+Description=CUPS LPD Server Socket
+
+[Socket]
+ListenStream=515
+Accept=yes
+
+[Install]
+WantedBy=sockets.target
diff --git a/scheduler/org.cups.cups-lpdAT.service.in b/scheduler/org.cups.cups-lpdAT.service.in
new file mode 100644
index 0000000..5c78273
--- /dev/null
+++ b/scheduler/org.cups.cups-lpdAT.service.in
@@ -0,0 +1,9 @@
+[Unit]
+Description=CUPS LPD server
+Documentation=man:cups-lpd(8)
+
+[Service]
+ExecStart=-@CUPS_SERVERBIN@/daemon/cups-lpd
+StandardInput=socket
+User=@CUPS_USER@
+
diff --git a/scheduler/org.cups.cupsd.path.in b/scheduler/org.cups.cupsd.path.in
new file mode 100644
index 0000000..1bccc6f
--- /dev/null
+++ b/scheduler/org.cups.cupsd.path.in
@@ -0,0 +1,8 @@
+[Unit]
+Description=CUPS Scheduler
+
+[Path]
+PathExists=@CUPS_CACHEDIR@/org.cups.cupsd
+
+[Install]
+WantedBy=multi-user.target
diff --git a/scheduler/org.cups.cupsd.plist b/scheduler/org.cups.cupsd.plist
index ccc861d..c0755c4 100644
--- a/scheduler/org.cups.cupsd.plist
+++ b/scheduler/org.cups.cupsd.plist
@@ -4,8 +4,12 @@
<dict>
<key>Label</key>
<string>org.cups.cupsd</string>
+ <key>ProcessType</key>
+ <string>Background</string>
<key>EnableTransactions</key>
<true/>
+ <key>EnablePressuredExit</key>
+ <true/>
<key>ExitTimeOut</key>
<integer>60</integer>
<key>KeepAlive</key>
@@ -21,8 +25,7 @@
<string>/usr/sbin/cupsd</string>
<string>-l</string>
</array>
- <!-- These environment variables are only used when CUPS is compiled
- with --enable-debug-printfs -->
+ <!-- These environment variables are only used when CUPS is compiled with debug-printfs support -->
<key>EnvironmentVariables</key>
<dict>
<key>CUPS_DEBUG_LOG</key>
@@ -30,27 +33,13 @@
<key>CUPS_DEBUG_LEVEL</key>
<string>3</string>
<key>CUPS_DEBUG_FILTER</key>
- <string>^(http|_http|ipp|_ipp|mime).*</string>
+ <string>^(cupsDo|cupsGet|cupsMake|cupsSet|http|_http|ipp|_ipp|mime).*</string>
</dict>
- <key>ServiceIPC</key>
- <true/>
<key>Sockets</key>
<dict>
<key>Listeners</key>
<array>
<dict>
- <key>SockNodeName</key>
- <string>::1</string>
- <key>SockServiceName</key>
- <string>ipp</string>
- </dict>
- <dict>
- <key>SockNodeName</key>
- <string>127.0.0.1</string>
- <key>SockServiceName</key>
- <string>ipp</string>
- </dict>
- <dict>
<key>SockPathMode</key>
<integer>49663</integer>
<key>SockPathName</key>
diff --git a/scheduler/org.cups.cupsd.service.in b/scheduler/org.cups.cupsd.service.in
new file mode 100644
index 0000000..0a27c76
--- /dev/null
+++ b/scheduler/org.cups.cupsd.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=CUPS Scheduler
+Documentation=man:cupsd(8)
+
+[Service]
+ExecStart=@sbindir@/cupsd -l
+Type=simple
+
+[Install]
+Also=org.cups.cupsd.socket org.cups.cupsd.path
+WantedBy=printer.target
diff --git a/scheduler/org.cups.cupsd.socket.in b/scheduler/org.cups.cupsd.socket.in
new file mode 100644
index 0000000..b0928c5
--- /dev/null
+++ b/scheduler/org.cups.cupsd.socket.in
@@ -0,0 +1,8 @@
+[Unit]
+Description=CUPS Scheduler
+
+[Socket]
+ListenStream=@CUPS_DEFAULT_DOMAINSOCKET@
+
+[Install]
+WantedBy=sockets.target
diff --git a/scheduler/policy.c b/scheduler/policy.c
index 75b5983..b9883d4 100644
--- a/scheduler/policy.c
+++ b/scheduler/policy.c
@@ -1,32 +1,16 @@
/*
- * "$Id: policy.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: policy.c 11681 2014-03-05 19:07:24Z msweet $"
*
- * Policy routines for the CUPS scheduler.
+ * Policy routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2011, 2014 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:
- *
- * AddPolicy() - Add a policy to the system.
- * cupsdAddPolicyOp() - Add an operation to a policy.
- * cupsdCheckPolicy() - Check the IPP operation and username against a
- * policy.
- * cupsdDeleteAllPolicies() - Delete all policies in memory.
- * cupsdFindPolicy() - Find a named policy.
- * cupsdFindPolicyOp() - Find a policy operation.
- * cupsdGetPrivateAttrs() - Get the private attributes for the current
- * request.
- * compare_ops() - Compare two operations.
- * compare_policies() - Compare two policies.
- * free_policy() - Free the memory used by a policy.
- * hash_op() - Generate a lookup hash for the operation.
+ * 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/".
*/
/*
@@ -48,7 +32,7 @@ static int hash_op(cupsd_location_t *op);
/*
- * 'AddPolicy()' - Add a policy to the system.
+ * 'cupsdAddPolicy()' - Add a policy to the system.
*/
cupsd_policy_t * /* O - Policy */
@@ -136,7 +120,7 @@ cupsdCheckPolicy(cupsd_policy_t *p, /* I - Policy */
if (!p || !con)
{
- cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdCheckPolicy: p=%p, con=%p!", p, con);
+ cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdCheckPolicy: p=%p, con=%p.", p, con);
return ((http_status_t)0);
}
@@ -147,7 +131,7 @@ cupsdCheckPolicy(cupsd_policy_t *p, /* I - Policy */
if ((po = cupsdFindPolicyOp(p, con->request->request.op.operation_id)) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckPolicy: No matching operation, returning 0!");
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckPolicy: No matching operation, returning 0.");
return ((http_status_t)0);
}
@@ -263,7 +247,7 @@ cupsdFindPolicyOp(cupsd_policy_t *p, /* I - Policy */
return (po);
}
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: No match found!");
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: No match found.");
return (NULL);
}
@@ -293,9 +277,15 @@ cupsdGetPrivateAttrs(
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"cupsdGetPrivateAttrs(policy=%p(%s), con=%p(%d), "
"printer=%p(%s), owner=\"%s\")", policy, policy->name, con,
- con->http.fd, printer, printer ? printer->name : "", owner);
+ con->number, printer, printer ? printer->name : "", owner);
#endif /* DEBUG */
+ if (!policy)
+ {
+ cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdGetPrivateAttrs: policy=%p, con=%p, printer=%p, owner=\"%s\", DefaultPolicyPtr=%p: This should never happen, please report a bug.", policy, con, printer, owner, DefaultPolicyPtr);
+ policy = DefaultPolicyPtr;
+ }
+
/*
* Get the access and attributes lists that correspond to the request...
*/
@@ -513,5 +503,5 @@ hash_op(cupsd_location_t *op) /* I - Operation */
/*
- * End of "$Id: policy.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: policy.c 11681 2014-03-05 19:07:24Z msweet $".
*/
diff --git a/scheduler/policy.h b/scheduler/policy.h
index df17a11..8af88f5 100644
--- a/scheduler/policy.h
+++ b/scheduler/policy.h
@@ -1,5 +1,5 @@
/*
- * "$Id: policy.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: policy.h 10996 2013-05-29 11:51: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 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: policy.h 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/printers.c b/scheduler/printers.c
index 48c4a82..61956b7 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -1,59 +1,16 @@
/*
- * "$Id: printers.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: printers.c 12733 2015-06-12 01:21:05Z msweet $"
*
- * Printer routines for the CUPS scheduler.
+ * Printer routines for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 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:
- *
- * cupsdAddPrinter() - Add a printer to the system.
- * cupsdCreateCommonData() - Create the common printer data.
- * cupsdDeleteAllPrinters() - Delete all printers from the system.
- * cupsdDeletePrinter() - Delete a printer from the system.
- * cupsdFindDest() - Find a destination in the list.
- * cupsdFindPrinter() - Find a printer in the list.
- * cupsdLoadAllPrinters() - Load printers from the printers.conf file.
- * cupsdRenamePrinter() - Rename a printer.
- * cupsdSaveAllPrinters() - Save all printer definitions to the
- * printers.conf file.
- * cupsdSetAuthInfoRequired() - Set the required authentication info.
- * cupsdSetDeviceURI() - Set the device URI for a printer.
- * cupsdSetPrinterAttr() - Set a printer attribute.
- * cupsdSetPrinterAttrs() - Set printer attributes based upon the PPD
- * file.
- * cupsdSetPrinterReasons() - Set/update the reasons strings.
- * cupsdSetPrinterState() - Update the current state of a printer.
- * cupsdStopPrinter() - Stop a printer from printing any jobs...
- * cupsdUpdatePrinterPPD() - Update keywords in a printer's PPD file.
- * cupsdUpdatePrinters() - Update printers after a partial reload.
- * cupsdValidateDest() - Validate a printer/class destination.
- * cupsdWritePrintcap() - Write a pseudo-printcap file for older
- * applications that need it...
- * add_printer_defaults() - Add name-default attributes to the printer
- * attributes.
- * add_printer_filter() - Add a MIME filter for a printer.
- * add_printer_formats() - Add document-format-supported values for a
- * printer.
- * compare_printers() - Compare two printers.
- * delete_printer_filters() - Delete all MIME filters for a printer.
- * dirty_printer() - Mark config and state files dirty for the
- * specified printer.
- * load_ppd() - Load a cached PPD file, updating the cache as
- * needed.
- * new_media_col() - Create a media-col collection value.
- * write_irix_config() - Update the config files used by the IRIX
- * desktop tools.
- * write_irix_state() - Update the status files used by IRIX printing
- * desktop tools.
- * write_xml_string() - Write a string with XML escaping.
+ * 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/".
*/
/*
@@ -93,13 +50,8 @@ static int compare_printers(void *first, void *second, void *data);
static void delete_printer_filters(cupsd_printer_t *p);
static void dirty_printer(cupsd_printer_t *p);
static void load_ppd(cupsd_printer_t *p);
-static void log_ipp_conformance(cupsd_printer_t *p, const char *reason);
static ipp_t *new_media_col(_pwg_size_t *size, const char *source,
const char *type);
-#ifdef __sgi
-static void write_irix_config(cupsd_printer_t *p);
-static void write_irix_state(cupsd_printer_t *p);
-#endif /* __sgi */
static void write_xml_string(cups_file_t *fp, const char *s);
@@ -139,15 +91,16 @@ cupsdAddPrinter(const char *name) /* I - Name of printer */
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
ServerName, RemotePort, "/printers/%s", name);
cupsdSetString(&p->uri, uri);
- cupsdSetString(&p->uuid, _httpAssembleUUID(ServerName, RemotePort, name, 0,
- uuid, sizeof(uuid)));
+ cupsdSetString(&p->uuid, httpAssembleUUID(ServerName, RemotePort, name, 0,
+ uuid, sizeof(uuid)));
cupsdSetDeviceURI(p, "file:///dev/null");
- p->state = IPP_PRINTER_STOPPED;
- p->state_time = time(NULL);
- p->accepting = 0;
- p->shared = DefaultShared;
- p->filetype = mimeAddType(MimeDatabase, "printer", name);
+ p->config_time = time(NULL);
+ p->state = IPP_PRINTER_STOPPED;
+ p->state_time = time(NULL);
+ p->accepting = 0;
+ p->shared = DefaultShared;
+ p->filetype = mimeAddType(MimeDatabase, "printer", name);
cupsdSetString(&p->job_sheets[0], "none");
cupsdSetString(&p->job_sheets[1], "none");
@@ -219,6 +172,10 @@ cupsdCreateCommonData(void)
"third-shift",
"weekend"
};
+ static const char * const features[] =/* ipp-features-supported values */
+ {
+ "subscription-object"
+ };
static const char * const versions[] =/* ipp-versions-supported values */
{
"1.0",
@@ -228,54 +185,53 @@ cupsdCreateCommonData(void)
};
static const int ops[] = /* operations-supported values */
{
- IPP_PRINT_JOB,
- IPP_VALIDATE_JOB,
- IPP_CREATE_JOB,
- IPP_SEND_DOCUMENT,
- IPP_CANCEL_JOB,
- IPP_GET_JOB_ATTRIBUTES,
- IPP_GET_JOBS,
- IPP_GET_PRINTER_ATTRIBUTES,
- IPP_HOLD_JOB,
- IPP_RELEASE_JOB,
- IPP_RESTART_JOB,
- IPP_PAUSE_PRINTER,
- IPP_RESUME_PRINTER,
- IPP_PURGE_JOBS,
- IPP_SET_PRINTER_ATTRIBUTES,
- IPP_SET_JOB_ATTRIBUTES,
- IPP_GET_PRINTER_SUPPORTED_VALUES,
- IPP_CREATE_PRINTER_SUBSCRIPTION,
- IPP_CREATE_JOB_SUBSCRIPTION,
- IPP_GET_SUBSCRIPTION_ATTRIBUTES,
- IPP_GET_SUBSCRIPTIONS,
- IPP_RENEW_SUBSCRIPTION,
- IPP_CANCEL_SUBSCRIPTION,
- IPP_GET_NOTIFICATIONS,
- IPP_ENABLE_PRINTER,
- IPP_DISABLE_PRINTER,
- IPP_HOLD_NEW_JOBS,
- IPP_RELEASE_HELD_NEW_JOBS,
- IPP_CANCEL_JOBS,
- IPP_CANCEL_MY_JOBS,
- IPP_CLOSE_JOB,
- CUPS_GET_DEFAULT,
- CUPS_GET_PRINTERS,
- CUPS_ADD_PRINTER,
- CUPS_DELETE_PRINTER,
- CUPS_GET_CLASSES,
- CUPS_ADD_CLASS,
- CUPS_DELETE_CLASS,
- CUPS_ACCEPT_JOBS,
- CUPS_REJECT_JOBS,
- CUPS_SET_DEFAULT,
- CUPS_GET_DEVICES,
- CUPS_GET_PPDS,
- CUPS_MOVE_JOB,
- CUPS_AUTHENTICATE_JOB,
- CUPS_GET_PPD,
- CUPS_GET_DOCUMENT,
- IPP_RESTART_JOB
+ IPP_OP_PRINT_JOB,
+ IPP_OP_VALIDATE_JOB,
+ IPP_OP_CREATE_JOB,
+ IPP_OP_SEND_DOCUMENT,
+ IPP_OP_CANCEL_JOB,
+ IPP_OP_GET_JOB_ATTRIBUTES,
+ IPP_OP_GET_JOBS,
+ IPP_OP_GET_PRINTER_ATTRIBUTES,
+ IPP_OP_HOLD_JOB,
+ IPP_OP_RELEASE_JOB,
+ IPP_OP_PAUSE_PRINTER,
+ IPP_OP_RESUME_PRINTER,
+ IPP_OP_PURGE_JOBS,
+ IPP_OP_SET_PRINTER_ATTRIBUTES,
+ IPP_OP_SET_JOB_ATTRIBUTES,
+ IPP_OP_GET_PRINTER_SUPPORTED_VALUES,
+ IPP_OP_CREATE_PRINTER_SUBSCRIPTIONS,
+ IPP_OP_CREATE_JOB_SUBSCRIPTIONS,
+ IPP_OP_GET_SUBSCRIPTION_ATTRIBUTES,
+ IPP_OP_GET_SUBSCRIPTIONS,
+ IPP_OP_RENEW_SUBSCRIPTION,
+ IPP_OP_CANCEL_SUBSCRIPTION,
+ IPP_OP_GET_NOTIFICATIONS,
+ IPP_OP_ENABLE_PRINTER,
+ IPP_OP_DISABLE_PRINTER,
+ IPP_OP_HOLD_NEW_JOBS,
+ IPP_OP_RELEASE_HELD_NEW_JOBS,
+ IPP_OP_CANCEL_JOBS,
+ IPP_OP_CANCEL_MY_JOBS,
+ IPP_OP_CLOSE_JOB,
+ IPP_OP_CUPS_GET_DEFAULT,
+ IPP_OP_CUPS_GET_PRINTERS,
+ IPP_OP_CUPS_ADD_MODIFY_PRINTER,
+ IPP_OP_CUPS_DELETE_PRINTER,
+ IPP_OP_CUPS_GET_CLASSES,
+ IPP_OP_CUPS_ADD_MODIFY_CLASS,
+ IPP_OP_CUPS_DELETE_CLASS,
+ IPP_OP_CUPS_ACCEPT_JOBS,
+ IPP_OP_CUPS_REJECT_JOBS,
+ IPP_OP_CUPS_SET_DEFAULT,
+ IPP_OP_CUPS_GET_DEVICES,
+ IPP_OP_CUPS_GET_PPDS,
+ IPP_OP_CUPS_MOVE_JOB,
+ IPP_OP_CUPS_AUTHENTICATE_JOB,
+ IPP_OP_CUPS_GET_PPD,
+ IPP_OP_CUPS_GET_DOCUMENT,
+ IPP_OP_RESTART_JOB
};
static const char * const charsets[] =/* charset-supported values */
{
@@ -348,9 +304,9 @@ cupsdCreateCommonData(void)
"multiple-document-handling",
"number-up",
"output-bin",
- "output-mode",
"orientation-requested",
"page-ranges",
+ "print-color-mode",
"print-quality",
"printer-resolution",
"sides"
@@ -367,9 +323,9 @@ cupsdCreateCommonData(void)
"multiple-document-handling",
"number-up",
"output-bin",
- "output-mode",
"orientation-requested",
"page-ranges",
+ "print-color-mode",
"print-quality",
"printer-resolution",
"sides"
@@ -388,8 +344,11 @@ cupsdCreateCommonData(void)
};
static const char * const printer_settable[] =
{ /* printer-settable-attributes-supported */
+ "printer-geo-location",
"printer-info",
- "printer-location"
+ "printer-location",
+ "printer-organization",
+ "printer-organizational-unit"
};
static const char * const which_jobs[] =
{ /* which-jobs-supported values */
@@ -469,6 +428,9 @@ cupsdCreateCommonData(void)
ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
"generated-natural-language-supported", NULL, DefaultLanguage);
+ /* ipp-features-supported */
+ ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "ipp-features-supported", sizeof(features) / sizeof(features[0]), NULL, features);
+
/* ipp-versions-supported */
ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
"ipp-versions-supported", sizeof(versions) / sizeof(versions[0]),
@@ -478,6 +440,10 @@ cupsdCreateCommonData(void)
ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"ippget-event-life", 15);
+ /* job-cancel-after-supported */
+ ippAddRange(CommonData, IPP_TAG_PRINTER, "job-cancel-after-supported",
+ 0, INT_MAX);
+
/* job-creation-attributes-supported */
ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
"job-creation-attributes-supported",
@@ -578,6 +544,9 @@ cupsdCreateCommonData(void)
ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
"multiple-operation-time-out", MultipleOperationTimeout);
+ /* multiple-operation-time-out-action */
+ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "multiple-operation-time-out-action", NULL, "process-job");
+
/* natural-language-configured (no IPP_TAG_COPY) */
ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
"natural-language-configured", NULL, DefaultLanguage);
@@ -663,6 +632,9 @@ cupsdCreateCommonData(void)
ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
"pdl-override-supported", NULL, "attempted");
+ /* printer-get-attributes-supported */
+ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "printer-get-attributes-supported", NULL, "document-format");
+
/* printer-op-policy-supported */
attr = ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY,
"printer-op-policy-supported", cupsArrayCount(Policies),
@@ -720,9 +692,6 @@ cupsdDeletePrinter(
{
int i, /* Looping var */
changed = 0; /* Class changed? */
-#ifdef __sgi
- char filename[1024]; /* Interface script filename */
-#endif /* __sgi */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDeletePrinter(p=%p(%s), update=%d)",
@@ -756,31 +725,6 @@ cupsdDeletePrinter(
cupsArrayRemove(Printers, p);
/*
- * Remove the dummy interface/icon/option files under IRIX...
- */
-
-#ifdef __sgi
- snprintf(filename, sizeof(filename), "/var/spool/lp/interface/%s", p->name);
- unlink(filename);
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/gui_interface/ELF/%s.gui",
- p->name);
- unlink(filename);
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/activeicons/%s", p->name);
- unlink(filename);
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.config", p->name);
- unlink(filename);
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.status", p->name);
- unlink(filename);
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/member/%s", p->name);
- unlink(filename);
-#endif /* __sgi */
-
- /*
* If p is the default printer, assign a different one...
*/
@@ -824,6 +768,7 @@ cupsdDeletePrinter(
cupsdClearString(&p->hostname);
cupsdClearString(&p->name);
cupsdClearString(&p->location);
+ cupsdClearString(&p->geo_location);
cupsdClearString(&p->make_model);
cupsdClearString(&p->info);
cupsdClearString(&p->job_sheets[0]);
@@ -957,7 +902,7 @@ cupsdLoadAllPrinters(void)
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
}
- else if (!_cups_strcasecmp(line, "</Printer>"))
+ else if (!_cups_strcasecmp(line, "</Printer>") || !_cups_strcasecmp(line, "</DefaultPrinter>"))
{
if (p != NULL)
{
@@ -1033,6 +978,21 @@ cupsdLoadAllPrinters(void)
if (value)
cupsdSetString(&p->location, value);
}
+ else if (!_cups_strcasecmp(line, "GeoLocation"))
+ {
+ if (value)
+ cupsdSetString(&p->geo_location, value);
+ }
+ else if (!_cups_strcasecmp(line, "Organization"))
+ {
+ if (value)
+ cupsdSetString(&p->organization, value);
+ }
+ else if (!_cups_strcasecmp(line, "OrganizationalUnit"))
+ {
+ if (value)
+ cupsdSetString(&p->organizational_unit, value);
+ }
else if (!_cups_strcasecmp(line, "DeviceURI"))
{
if (value)
@@ -1137,6 +1097,15 @@ cupsdLoadAllPrinters(void)
if (value)
p->state_time = atoi(value);
}
+ else if (!_cups_strcasecmp(line, "ConfigTime"))
+ {
+ /*
+ * Set the config time...
+ */
+
+ if (value)
+ p->config_time = atoi(value);
+ }
else if (!_cups_strcasecmp(line, "Accepting"))
{
/*
@@ -1160,7 +1129,7 @@ cupsdLoadAllPrinters(void)
else if (!_cups_strcasecmp(line, "Type"))
{
if (value)
- p->type = atoi(value);
+ p->type = (cups_ptype_t)atoi(value);
else
cupsdLogMessage(CUPSD_LOG_ERROR,
"Syntax error on line %d of printers.conf.", linenum);
@@ -1287,10 +1256,17 @@ cupsdLoadAllPrinters(void)
else if (!_cups_strcasecmp(line, "ErrorPolicy"))
{
if (value)
- cupsdSetString(&p->error_policy, value);
+ {
+ if (strcmp(value, "retry-current-job") &&
+ strcmp(value, "abort-job") &&
+ strcmp(value, "retry-job") &&
+ strcmp(value, "stop-printer"))
+ cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid ErrorPolicy \"%s\" on line %d or printers.conf.", ErrorPolicy, linenum);
+ else
+ cupsdSetString(&p->error_policy, value);
+ }
else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Syntax error on line %d of printers.conf.", linenum);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of printers.conf.", linenum);
}
else if (!_cups_strcasecmp(line, "Attribute") && value)
{
@@ -1486,9 +1462,18 @@ cupsdSaveAllPrinters(void)
if (printer->location)
cupsFilePutConf(fp, "Location", printer->location);
+ if (printer->geo_location)
+ cupsFilePutConf(fp, "GeoLocation", printer->geo_location);
+
if (printer->make_model)
cupsFilePutConf(fp, "MakeModel", printer->make_model);
+ if (printer->organization)
+ cupsFilePutConf(fp, "Organization", printer->organization);
+
+ if (printer->organizational_unit)
+ cupsFilePutConf(fp, "OrganizationalUnit", printer->organizational_unit);
+
cupsFilePutConf(fp, "DeviceURI", printer->device_uri);
if (printer->port_monitor)
@@ -1498,13 +1483,14 @@ cupsdSaveAllPrinters(void)
{
cupsFilePuts(fp, "State Stopped\n");
- if (printer->state_message)
+ if (printer->state_message[0])
cupsFilePutConf(fp, "StateMessage", printer->state_message);
}
else
cupsFilePuts(fp, "State Idle\n");
cupsFilePrintf(fp, "StateTime %d\n", (int)printer->state_time);
+ cupsFilePrintf(fp, "ConfigTime %d\n", (int)printer->config_time);
for (i = 0; i < printer->num_reasons; i ++)
if (strcmp(printer->reasons[i], "connecting-to-device") &&
@@ -1562,8 +1548,7 @@ cupsdSaveAllPrinters(void)
if (i)
*ptr++ = ',';
- strlcpy(ptr, marker->values[i].string.text,
- value + sizeof(value) - ptr);
+ strlcpy(ptr, marker->values[i].string.text, (size_t)(value + sizeof(value) - ptr));
ptr += strlen(ptr);
}
@@ -1622,8 +1607,7 @@ cupsdSaveAllPrinters(void)
if (i)
*ptr++ = ',';
- strlcpy(ptr, marker->values[i].string.text,
- value + sizeof(value) - ptr);
+ strlcpy(ptr, marker->values[i].string.text, (size_t)(value + sizeof(value) - ptr));
ptr += strlen(ptr);
}
@@ -1643,8 +1627,7 @@ cupsdSaveAllPrinters(void)
if (i)
*ptr++ = ',';
- strlcpy(ptr, marker->values[i].string.text,
- value + sizeof(value) - ptr);
+ strlcpy(ptr, marker->values[i].string.text, (size_t)(value + sizeof(value) - ptr));
ptr += strlen(ptr);
}
@@ -1656,15 +1639,10 @@ cupsdSaveAllPrinters(void)
cupsFilePrintf(fp, "Attribute marker-change-time %ld\n",
(long)printer->marker_time);
- cupsFilePuts(fp, "</Printer>\n");
-
-#ifdef __sgi
- /*
- * Make IRIX desktop & printer status happy
- */
-
- write_irix_state(printer);
-#endif /* __sgi */
+ if (printer == DefaultPrinter)
+ cupsFilePuts(fp, "</DefaultPrinter>\n");
+ else
+ cupsFilePuts(fp, "</Printer>\n");
}
cupsdCloseCreatedConfFile(fp, filename);
@@ -1767,7 +1745,7 @@ cupsdSetAuthInfoRequired(
strcmp(p->auth_info_required[0], "none"))
p->type |= CUPS_PRINTER_AUTHENTICATED;
else
- p->type &= ~CUPS_PRINTER_AUTHENTICATED;
+ p->type &= (cups_ptype_t)~CUPS_PRINTER_AUTHENTICATED;
return (1);
}
@@ -1910,12 +1888,13 @@ void
cupsdSetPrinterAttr(
cupsd_printer_t *p, /* I - Printer */
const char *name, /* I - Attribute name */
- char *value) /* I - Attribute value string */
+ const char *value) /* I - Attribute value string */
{
ipp_attribute_t *attr; /* Attribute */
int i, /* Looping var */
count; /* Number of values */
- char *ptr, /* Pointer into value */
+ char *temp, /* Temporary copy of value string */
+ *ptr, /* Pointer into value */
*start, /* Start of value */
quote; /* Quote character */
ipp_tag_t value_tag; /* Value tag for this attribute */
@@ -1932,10 +1911,21 @@ cupsdSetPrinterAttr(
}
/*
+ * Copy the value string so we can do what we want with it...
+ */
+
+ if ((temp = strdup(value)) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to duplicate value for \"%s\" attribute.", name);
+ return;
+ }
+
+ /*
* Count the number of values...
*/
- for (count = 1, quote = '\0', ptr = value;
+ for (count = 1, quote = '\0', ptr = temp;
*ptr;
ptr ++)
{
@@ -1977,21 +1967,22 @@ cupsdSetPrinterAttr(
if (!attr)
{
+ free(temp);
cupsdLogMessage(CUPSD_LOG_ERROR,
"Unable to allocate memory for printer attribute "
"(%d values)", count);
return;
}
- for (i = 0; i < count; i ++)
+ for (i = 0, start = temp; i < count; i ++)
{
- if ((ptr = strchr(value, ',')) != NULL)
+ if ((ptr = strchr(start, ',')) != NULL)
*ptr++ = '\0';
- attr->values[i].integer = strtol(value, NULL, 10);
+ attr->values[i].integer = strtol(start, NULL, 10);
if (ptr)
- value = ptr;
+ start = ptr;
}
}
else
@@ -2027,13 +2018,14 @@ cupsdSetPrinterAttr(
if (!attr)
{
+ free(temp);
cupsdLogMessage(CUPSD_LOG_ERROR,
"Unable to allocate memory for printer attribute "
"(%d values)", count);
return;
}
- for (i = 0, quote = '\0', ptr = value; i < count; i ++)
+ for (i = 0, quote = '\0', ptr = temp; i < count; i ++)
{
for (start = ptr; *ptr; ptr ++)
{
@@ -2062,6 +2054,79 @@ cupsdSetPrinterAttr(
attr->values[i].string.text = _cupsStrAlloc(start);
}
}
+
+ free(temp);
+
+ /*
+ * Update the printer-supply and printer-supply-description, as needed...
+ */
+
+ if (!strcmp(name, "marker-names"))
+ {
+ ipp_attribute_t *supply_desc = ippFindAttribute(p->attrs, "printer-supply-description", IPP_TAG_TEXT);
+ /* printer-supply-description attribute */
+
+ if (supply_desc != NULL)
+ ippDeleteAttribute(p->attrs, supply_desc);
+
+ supply_desc = ippCopyAttribute(p->attrs, attr, 0);
+ ippSetName(p->attrs, &supply_desc, "printer-supply-description");
+ ippSetValueTag(p->attrs, &supply_desc, IPP_TAG_TEXT);
+ }
+ else if (!strcmp(name, "marker-colors") || !strcmp(name, "marker-levels") || !strcmp(name, "marker-types"))
+ {
+ char buffer[256], /* printer-supply values */
+ pstype[64], /* printer-supply type value */
+ *psptr; /* Pointer into type */
+ const char *color, /* marker-colors value */
+ *type; /* marker-types value */
+ int level; /* marker-levels value */
+ ipp_attribute_t *colors = ippFindAttribute(p->attrs, "marker-colors", IPP_TAG_NAME);
+ /* marker-colors attribute */
+ ipp_attribute_t *levels = ippFindAttribute(p->attrs, "marker-levels", IPP_TAG_INTEGER);
+ /* marker-levels attribute */
+ ipp_attribute_t *types = ippFindAttribute(p->attrs, "marker-types", IPP_TAG_KEYWORD);
+ /* marker-types attribute */
+ ipp_attribute_t *supply = ippFindAttribute(p->attrs, "printer-supply", IPP_TAG_STRING);
+ /* printer-supply attribute */
+
+ if (supply != NULL)
+ {
+ ippDeleteAttribute(p->attrs, supply);
+ supply = NULL;
+ }
+
+ if (!colors || !levels || !types)
+ return;
+
+ count = ippGetCount(colors);
+ if (count != ippGetCount(levels) || count != ippGetCount(types))
+ return;
+
+ for (i = 0; i < count; i ++)
+ {
+ color = ippGetString(colors, i, NULL);
+ level = ippGetInteger(levels, i);
+ type = ippGetString(types, i, NULL);
+
+ for (psptr = pstype; *type && psptr < (pstype + sizeof(pstype) - 1); type ++)
+ if (*type == '-')
+ {
+ type ++;
+ *psptr++ = (char)toupper(*type & 255);
+ }
+ else
+ *psptr++ = *type;
+ *psptr = '\0';
+
+ snprintf(buffer, sizeof(buffer), "index=%d;class=%s;type=%s;unit=percent;maxcapacity=100;level=%d;colorantname=%s;", i + 1, strncmp(pstype, "waste", 5) ? "supplyThatIsConsumed" : "receptacleThatIsFilled", pstype, level, color);
+
+ if (!i)
+ supply = ippAddOctetString(p->attrs, IPP_TAG_PRINTER, "printer-supply", buffer, (int)strlen(buffer));
+ else
+ ippSetOctetString(p->attrs, &supply, i, buffer, (int)strlen(buffer));
+ }
+ }
}
@@ -2121,10 +2186,8 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT)
auth_type = cupsdDefaultAuthType();
- if (auth_type == CUPSD_AUTH_BASIC || auth_type == CUPSD_AUTH_BASICDIGEST)
+ if (auth_type == CUPSD_AUTH_BASIC)
auth_supported = "basic";
- else if (auth_type == CUPSD_AUTH_DIGEST)
- auth_supported = "digest";
#ifdef HAVE_GSSAPI
else if (auth_type == CUPSD_AUTH_NEGOTIATE)
auth_supported = "negotiate";
@@ -2133,10 +2196,10 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
if (auth_type != CUPSD_AUTH_NONE)
p->type |= CUPS_PRINTER_AUTHENTICATED;
else
- p->type &= ~CUPS_PRINTER_AUTHENTICATED;
+ p->type &= (cups_ptype_t)~CUPS_PRINTER_AUTHENTICATED;
}
else
- p->type &= ~CUPS_PRINTER_AUTHENTICATED;
+ p->type &= (cups_ptype_t)~CUPS_PRINTER_AUTHENTICATED;
/*
* Create the required IPP attributes for a printer...
@@ -2153,10 +2216,15 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
p->name);
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
NULL, p->location ? p->location : "");
+ if (p->geo_location)
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-geo-location", NULL, p->geo_location);
+ else
+ ippAddOutOfBand(p->attrs, IPP_TAG_PRINTER, IPP_TAG_UNKNOWN, "printer-geo-location");
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
NULL, p->info ? p->info : "");
- ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uuid", NULL,
- p->uuid);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-organization", NULL, p->organization ? p->organization : "");
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-organizational-unit", NULL, p->organizational_unit ? p->organizational_unit : "");
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uuid", NULL, p->uuid);
if (cupsArrayCount(p->users) > 0)
{
@@ -2172,7 +2240,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
for (i = 0, name = (char *)cupsArrayFirst(p->users);
name;
i ++, name = (char *)cupsArrayNext(p->users))
- attr->values[i].string.text = _cupsStrRetain(name);
+ attr->values[i].string.text = _cupsStrAlloc(name);
}
ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
@@ -2215,7 +2283,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
if (p->type & CUPS_PRINTER_CLASS)
{
p->raw = 1;
- p->type &= ~CUPS_PRINTER_OPTIONS;
+ p->type &= (cups_ptype_t)~CUPS_PRINTER_OPTIONS;
/*
* Add class-specific attributes...
@@ -2239,9 +2307,9 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
for (i = 0; i < p->num_printers; i ++)
{
if (attr != NULL)
- attr->values[i].string.text = _cupsStrRetain(p->printers[i]->name);
+ attr->values[i].string.text = _cupsStrAlloc(p->printers[i]->name);
- p->type &= ~CUPS_PRINTER_OPTIONS | p->printers[i]->type;
+ p->type &= (cups_ptype_t)~CUPS_PRINTER_OPTIONS | p->printers[i]->type;
}
}
}
@@ -2339,7 +2407,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
{
for (i = 0; i < oldattr->num_values; i ++)
attr->values[i].string.text =
- _cupsStrRetain(oldattr->values[i].string.text);
+ _cupsStrAlloc(oldattr->values[i].string.text);
}
}
@@ -2393,7 +2461,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
{
for (i = 0; i < oldattr->num_values; i ++)
attr->values[i].string.text =
- _cupsStrRetain(oldattr->values[i].string.text);
+ _cupsStrAlloc(oldattr->values[i].string.text);
}
}
@@ -2406,7 +2474,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
{
for (i = 0; i < oldattr->num_values; i ++)
attr->values[i].string.text =
- _cupsStrRetain(oldattr->values[i].string.text);
+ _cupsStrAlloc(oldattr->values[i].string.text);
}
}
@@ -2435,15 +2503,6 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
add_printer_defaults(p);
-#ifdef __sgi
- /*
- * Write the IRIX printer config and status files...
- */
-
- write_irix_config(p);
- write_irix_state(p);
-#endif /* __sgi */
-
/*
* Let the browse protocols reflect the change
*/
@@ -2539,14 +2598,17 @@ cupsdSetPrinterReasons(
_cupsStrFree(p->reasons[i]);
if (i < p->num_reasons)
- memmove(p->reasons + i, p->reasons + i + 1,
- (p->num_reasons - i) * sizeof(char *));
+ memmove(p->reasons + i, p->reasons + i + 1, (size_t)(p->num_reasons - i) * sizeof(char *));
if (!strcmp(reason, "paused") && p->state == IPP_PRINTER_STOPPED)
cupsdSetPrinterState(p, IPP_PRINTER_IDLE, 1);
+ if (!strcmp(reason, "cups-waiting-for-job-completed") && p->job)
+ p->job->completed = 0;
+
if (strcmp(reason, "connecting-to-device"))
dirty_printer(p);
+
break;
}
}
@@ -2562,10 +2624,6 @@ cupsdSetPrinterReasons(
if (i >= p->num_reasons)
{
- if (!strncmp(reason, "cups-ipp-missing-", 17) ||
- !strncmp(reason, "cups-ipp-wrong-", 15))
- log_ipp_conformance(p, reason);
-
if (i >= (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
{
cupsdLogMessage(CUPSD_LOG_ALERT,
@@ -2581,6 +2639,9 @@ cupsdSetPrinterReasons(
if (!strcmp(reason, "paused") && p->state != IPP_PRINTER_STOPPED)
cupsdSetPrinterState(p, IPP_PRINTER_STOPPED, 1);
+ if (!strcmp(reason, "cups-waiting-for-job-completed") && p->job)
+ p->job->completed = 1;
+
if (strcmp(reason, "connecting-to-device"))
dirty_printer(p);
}
@@ -2631,10 +2692,6 @@ cupsdSetPrinterState(
*/
p->state_time = time(NULL);
-
-#ifdef __sgi
- write_irix_state(p);
-#endif /* __sgi */
}
/*
@@ -3023,16 +3080,6 @@ cupsdWritePrintcap(void)
cupsd_printer_t *p; /* Current printer */
-#ifdef __sgi
- /*
- * Update the IRIX printer state for the default printer; if
- * no printers remain, then the default printer file will be
- * removed...
- */
-
- write_irix_state(DefaultPrinter);
-#endif /* __sgi */
-
/*
* See if we have a printcap file; if not, don't bother writing it.
*/
@@ -3226,6 +3273,10 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */
cupsArrayAdd(CommonDefaults, _cupsStrAlloc("copies-default"));
cupsArrayAdd(CommonDefaults, _cupsStrAlloc("document-format-default"));
cupsArrayAdd(CommonDefaults, _cupsStrAlloc("finishings-default"));
+ cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-account-id-default"));
+ cupsArrayAdd(CommonDefaults,
+ _cupsStrAlloc("job-accounting-user-id-default"));
+ cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-cancel-after-default"));
cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-hold-until-default"));
cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-priority-default"));
cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-sheets-default"));
@@ -3274,6 +3325,10 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
"document-format-default", NULL, "application/octet-stream");
+ if (!cupsGetOption("job-cancel-after", p->num_options, p->options))
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-cancel-after-default", MaxJobTime);
+
if (!cupsGetOption("job-hold-until", p->num_options, p->options))
ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
"job-hold-until-default", NULL, "no-hold");
@@ -3377,7 +3432,7 @@ add_printer_filter(
{
char *ptr; /* Pointer into maxsize(nnnn) program */
- maxsize = strtoll(program + 8, &ptr, 10);
+ maxsize = (size_t)strtoll(program + 8, &ptr, 10);
if (*ptr != ')')
{
@@ -3565,8 +3620,7 @@ add_printer_formats(cupsd_printer_t *p) /* I - Printer */
filter;
filter = (mime_filter_t *)cupsArrayNext(MimeDatabase->filters))
{
- if (filter->dst == p->filetype && filter->filter &&
- strstr(filter->filter, "PrintJobMgr"))
+ if (filter->dst == p->filetype && strstr(filter->filter, "PrintJobMgr"))
break;
}
@@ -3731,7 +3785,8 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
qualities[3]; /* print-quality values */
int num_margins, /* Number of media-*-margin-supported values */
margins[16]; /* media-*-margin-supported values */
- const char *filter; /* Current filter */
+ const char *filter, /* Current filter */
+ *mandatory; /* Current mandatory attribute */
static const char * const sides[3] = /* sides-supported values */
{
"one-sided",
@@ -3787,7 +3842,9 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
cupsdLogMessage(CUPSD_LOG_DEBUG, "load_ppd: Loading %s...", ppd_name);
- p->type &= ~CUPS_PRINTER_OPTIONS;
+ cupsdClearString(&(p->make_model));
+
+ p->type &= (cups_ptype_t)~CUPS_PRINTER_OPTIONS;
p->type |= CUPS_PRINTER_BW;
finishings[0] = IPP_FINISHINGS_NONE;
@@ -3803,6 +3860,10 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
p->pc = _ppdCacheCreateWithPPD(ppd);
+ if (!p->pc)
+ cupsdLogMessage(CUPSD_LOG_WARN, "Unable to create cache of \"%s\": %s",
+ ppd_name, cupsLastErrorString());
+
ppdMarkDefaults(ppd);
if (ppd->color_device)
@@ -3815,8 +3876,28 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
if (ppd_attr->value && !_cups_strcasecmp(ppd_attr->value, "true"))
p->type |= CUPS_PRINTER_FAX;
- ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER, "color-supported",
- ppd->color_device);
+ ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER, "color-supported", (char)ppd->color_device);
+
+ if (p->pc && p->pc->charge_info_uri)
+ ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_URI,
+ "printer-charge-info-uri", NULL, p->pc->charge_info_uri);
+
+ if (p->pc && p->pc->account_id)
+ ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER, "job-account-id-supported",
+ 1);
+
+ if (p->pc && p->pc->accounting_user_id)
+ ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER,
+ "job-accounting-user-id-supported", 1);
+
+ if (p->pc && p->pc->password)
+ {
+ ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "job-password-encryption-supported", NULL, "none");
+ ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-password-supported", (int)strlen(p->pc->password));
+ }
+
if (ppd->throughput)
{
ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
@@ -3838,6 +3919,9 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
"pages-per-minute-color", 1);
}
+ if ((ppd_attr = ppdFindAttr(ppd, "1284DeviceId", NULL)) != NULL)
+ ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-device-id", NULL, ppd_attr->value);
+
num_qualities = 0;
if ((output_mode = ppdFindOption(ppd, "OutputMode")) != NULL)
@@ -3906,10 +3990,10 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
if (ppd->num_sizes == 0 || !p->pc)
{
- if (!ppdFindAttr(ppd, "APScannerOnly", NULL))
+ if (!ppdFindAttr(ppd, "APScannerOnly", NULL) && !ppdFindAttr(ppd, "cups3D", NULL))
cupsdLogMessage(CUPSD_LOG_CRIT,
"The PPD file for printer %s contains no media "
- "options and is therefore invalid!", p->name);
+ "options and is therefore invalid.", p->name);
ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
"media-default", NULL, "unknown");
@@ -3973,13 +4057,13 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
for (i = p->pc->num_sizes, pwgsize = p->pc->sizes;
i > 0;
i --, pwgsize ++, val ++)
- val->string.text = _cupsStrRetain(pwgsize->map.pwg);
+ val->string.text = _cupsStrAlloc(pwgsize->map.pwg);
if (p->pc->custom_min_keyword)
{
- val->string.text = _cupsStrRetain(p->pc->custom_min_keyword);
+ val->string.text = _cupsStrAlloc(p->pc->custom_min_keyword);
val ++;
- val->string.text = _cupsStrRetain(p->pc->custom_max_keyword);
+ val->string.text = _cupsStrAlloc(p->pc->custom_max_keyword);
}
}
@@ -4031,7 +4115,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
val = attr->values;
i > 0;
i --, pwgsource ++, val ++)
- val->string.text = _cupsStrRetain(pwgsource->pwg);
+ val->string.text = _cupsStrAlloc(pwgsource->pwg);
}
/*
@@ -4047,7 +4131,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
val = attr->values;
i > 0;
i --, pwgtype ++, val ++)
- val->string.text = _cupsStrRetain(pwgtype->pwg);
+ val->string.text = _cupsStrAlloc(pwgtype->pwg);
}
/*
@@ -4292,41 +4376,51 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
}
/*
- * output-mode and print-color-mode...
+ * print-color-mode...
*/
if (ppd->color_device)
{
- static const char * const output_modes[] =
+ static const char * const color_modes[] =
{
"monochrome",
"color"
};
ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "output-mode-supported", 2, NULL, output_modes);
- ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "output-mode-default", NULL, "color");
-
- ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "print-color-mode-supported", 2, NULL, output_modes);
+ "print-color-mode-supported", 2, NULL, color_modes);
ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
"print-color-mode-default", NULL, "color");
}
else
{
ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "output-mode-supported", NULL, "monochrome");
- ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
- "output-mode-default", NULL, "monochrome");
-
- ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
"print-color-mode-supported", NULL, "monochrome");
ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
"print-color-mode-default", NULL, "monochrome");
}
/*
+ * Mandatory job attributes, if any...
+ */
+
+ if (p->pc && cupsArrayCount(p->pc->mandatory) > 0)
+ {
+ int count = cupsArrayCount(p->pc->mandatory);
+ /* Number of mandatory attributes */
+
+ attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "printer-mandatory-job-attributes", count, NULL,
+ NULL);
+
+ for (val = attr->values,
+ mandatory = (char *)cupsArrayFirst(p->pc->mandatory);
+ mandatory;
+ val ++, mandatory = (char *)cupsArrayNext(p->pc->mandatory))
+ val->string.text = _cupsStrAlloc(mandatory);
+ }
+
+ /*
* Printer resolutions...
*/
@@ -4589,6 +4683,13 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
}
/*
+ * 3D printer support...
+ */
+
+ if (ppdFindAttr(ppd, "cups3D", NULL))
+ p->type |= CUPS_PRINTER_3D;
+
+ /*
* Show current and available port monitors for this printer...
*/
@@ -4654,22 +4755,16 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
CGContextRef context; /* The CG context used for resizing */
snprintf(outPath, sizeof(outPath), "%s/%s.png", CacheDir, p->name);
- outUrl = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
- (UInt8 *)outPath,
- strlen(outPath),
- FALSE);
- icnsFileUrl = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
- (UInt8 *)ppd_attr->value,
- strlen(ppd_attr->value),
- FALSE);
+ outUrl = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)outPath, (CFIndex)strlen(outPath), FALSE);
+ icnsFileUrl = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)ppd_attr->value, (CFIndex)strlen(ppd_attr->value), FALSE);
if (outUrl && icnsFileUrl)
{
sourceRef = CGImageSourceCreateWithURL(icnsFileUrl, NULL);
if (sourceRef)
{
- for (i = 0; i < CGImageSourceGetCount(sourceRef); i ++)
+ for (i = 0; i < (int)CGImageSourceGetCount(sourceRef); i ++)
{
- imageRef = CGImageSourceCreateImageAtIndex(sourceRef, i, NULL);
+ imageRef = CGImageSourceCreateImageAtIndex(sourceRef, (size_t)i, NULL);
if (!imageRef)
continue;
@@ -4773,14 +4868,12 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
pstatus = ppdLastError(&pline);
- cupsdLogMessage(CUPSD_LOG_ERROR, "PPD file for %s cannot be loaded!",
- p->name);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "PPD file for %s cannot be loaded.", p->name);
if (pstatus <= PPD_ALLOC_ERROR)
- cupsdLogMessage(CUPSD_LOG_ERROR, "%s", strerror(errno));
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s: %s", ppd_name, strerror(errno));
else
- cupsdLogMessage(CUPSD_LOG_ERROR, "%s on line %d.",
- ppdErrorString(pstatus), pline);
+ cupsdLogMessage(CUPSD_LOG_ERROR, "%s on line %d of %s.", ppdErrorString(pstatus), pline, ppd_name);
cupsdLogMessage(CUPSD_LOG_INFO,
"Hint: Run \"cupstestppd %s\" and fix any errors.",
@@ -4902,83 +4995,6 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
/*
- * 'log_ipp_conformance()' - Log an IPP conformance issue with a printer.
- */
-
-static void
-log_ipp_conformance(
- cupsd_printer_t *p, /* I - Printer */
- const char *reason) /* I - Printer state reason */
-{
- const char *message; /* Message to log */
-#ifdef __APPLE__
- aslmsg aslm; /* Apple System Log message */
-#endif /* __APPLE__ */
-
-
- /*
- * Strip the leading "cups-ipp-" from the reason and create a log message for
- * it...
- */
-
- reason += 9;
- if (!strcmp(reason, "missing-cancel-job"))
- message = "Printer does not support REQUIRED Cancel-Job operation.";
- else if (!strcmp(reason, "missing-get-job-attributes"))
- message = "Printer does not support REQUIRED Get-Job-Attributes operation.";
- else if (!strcmp(reason, "missing-print-job"))
- message = "Printer does not support REQUIRED Print-Job operation.";
- else if (!strcmp(reason, "missing-validate-job"))
- 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"))
- message = "Printer does not provide REQUIRED job-id attribute.";
- else if (!strcmp(reason, "missing-job-state"))
- message = "Printer does not provide REQUIRED job-state attribute.";
- else if (!strcmp(reason, "missing-operations-supported"))
- message = "Printer does not provide REQUIRED operations-supported "
- "attribute.";
- else if (!strcmp(reason, "missing-printer-is-accepting-jobs"))
- message = "Printer does not provide REQUIRED printer-is-accepting-jobs "
- "attribute.";
- else if (!strcmp(reason, "missing-printer-state-reasons"))
- message = "Printer does not provide REQUIRED printer-state-reasons "
- "attribute.";
- else if (!strcmp(reason, "wrong-http-version"))
- message = "Printer does not use REQUIRED HTTP/1.1 transport.";
- else
- message = "Unknown IPP conformance failure.";
-
- cupsdLogMessage(CUPSD_LOG_WARN, "%s: %s", p->name, message);
-
-#ifdef __APPLE__
- /*
- * Report the failure information to Apple if the user opts into providing
- * feedback to Apple...
- */
-
- aslm = asl_new(ASL_TYPE_MSG);
- if (aslm)
- {
- asl_set(aslm, "com.apple.message.domain", "com.apple.printing.ipp.conformance");
- asl_set(aslm, "com.apple.message.domain_scope", "com.apple.printing.ipp.conformance");
- asl_set(aslm, "com.apple.message.signature", reason);
- asl_set(aslm, "com.apple.message.signature2",
- p->make_model ? p->make_model : "Unknown");
- asl_log(NULL, aslm, ASL_LEVEL_NOTICE, "%s: %s",
- p->make_model ? p->make_model : "Unknown", message);
- asl_free(aslm);
- }
-#endif /* __APPLE__ */
-}
-
-
-/*
* 'new_media_col()' - Create a media-col collection value.
*/
@@ -5022,261 +5038,6 @@ new_media_col(_pwg_size_t *size, /* I - media-size/margin values */
}
-#ifdef __sgi
-/*
- * 'write_irix_config()' - Update the config files used by the IRIX
- * desktop tools.
- */
-
-static void
-write_irix_config(cupsd_printer_t *p) /* I - Printer to update */
-{
- char filename[1024]; /* Interface script filename */
- cups_file_t *fp; /* Interface script file */
- ipp_attribute_t *attr; /* Attribute data */
-
-
- /*
- * Add dummy interface and GUI scripts to fool SGI's "challenged" printing
- * tools. First the interface script that tells the tools what kind of
- * printer we have...
- */
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/interface/%s", p->name);
-
- if (p->type & CUPS_PRINTER_CLASS)
- unlink(filename);
- else if ((fp = cupsFileOpen(filename, "w")) != NULL)
- {
- cupsFilePuts(fp, "#!/bin/sh\n");
-
- if ((attr = ippFindAttribute(p->attrs, "printer-make-and-model",
- IPP_TAG_TEXT)) != NULL)
- cupsFilePrintf(fp, "NAME=\"%s\"\n", attr->values[0].string.text);
- else if (p->type & CUPS_PRINTER_CLASS)
- cupsFilePuts(fp, "NAME=\"Printer Class\"\n");
- else
- cupsFilePuts(fp, "NAME=\"Remote Destination\"\n");
-
- if (p->type & CUPS_PRINTER_COLOR)
- cupsFilePuts(fp, "TYPE=ColorPostScript\n");
- else
- cupsFilePuts(fp, "TYPE=MonoPostScript\n");
-
- cupsFilePrintf(fp, "HOSTNAME=%s\n", ServerName);
- cupsFilePrintf(fp, "HOSTPRINTER=%s\n", p->name);
-
- cupsFileClose(fp);
-
- chmod(filename, 0755);
- chown(filename, User, Group);
- }
-
- /*
- * Then the member file that tells which device file the queue is connected
- * to... Networked printers use "/dev/null" in this file, so that's what
- * we use (the actual device URI can confuse some apps...)
- */
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/member/%s", p->name);
-
- if (p->type & CUPS_PRINTER_CLASS)
- unlink(filename);
- else if ((fp = cupsFileOpen(filename, "w")) != NULL)
- {
- cupsFilePuts(fp, "/dev/null\n");
-
- cupsFileClose(fp);
-
- chmod(filename, 0644);
- chown(filename, User, Group);
- }
-
- /*
- * The gui_interface file is a script or program that launches a GUI
- * option panel for the printer, using options specified on the
- * command-line in the third argument. The option panel must send
- * any printing options to stdout on a single line when the user
- * accepts them, or nothing if the user cancels the dialog.
- *
- * The default options panel program is /usr/bin/glpoptions, from
- * the ESP Print Pro software. You can select another using the
- * PrintcapGUI option.
- */
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/gui_interface/ELF/%s.gui", p->name);
-
- if (p->type & CUPS_PRINTER_CLASS)
- unlink(filename);
- else if ((fp = cupsFileOpen(filename, "w")) != NULL)
- {
- cupsFilePuts(fp, "#!/bin/sh\n");
- cupsFilePrintf(fp, "%s -d %s -o \"$3\"\n", PrintcapGUI, p->name);
-
- cupsFileClose(fp);
-
- chmod(filename, 0755);
- chown(filename, User, Group);
- }
-
- /*
- * The POD config file is needed by the printstatus command to show
- * the printer location and device.
- */
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.config", p->name);
-
- if (p->type & CUPS_PRINTER_CLASS)
- unlink(filename);
- else if ((fp = cupsFileOpen(filename, "w")) != NULL)
- {
- cupsFilePrintf(fp, "Printer Class | %s\n",
- (p->type & CUPS_PRINTER_COLOR) ? "ColorPostScript" : "MonoPostScript");
- cupsFilePrintf(fp, "Printer Model | %s\n", p->make_model ? p->make_model : "");
- cupsFilePrintf(fp, "Location Code | %s\n", p->location ? p->location : "");
- cupsFilePrintf(fp, "Physical Location | %s\n", p->info ? p->info : "");
- cupsFilePrintf(fp, "Port Path | %s\n", p->device_uri);
- cupsFilePrintf(fp, "Config Path | /var/spool/lp/pod/%s.config\n", p->name);
- cupsFilePrintf(fp, "Active Status Path | /var/spool/lp/pod/%s.status\n", p->name);
- cupsFilePuts(fp, "Status Update Wait | 10 seconds\n");
-
- cupsFileClose(fp);
-
- chmod(filename, 0664);
- chown(filename, User, Group);
- }
-}
-
-
-/*
- * 'write_irix_state()' - Update the status files used by IRIX printing
- * desktop tools.
- */
-
-static void
-write_irix_state(cupsd_printer_t *p) /* I - Printer to update */
-{
- char filename[1024]; /* Interface script filename */
- cups_file_t *fp; /* Interface script file */
- int tag; /* Status tag value */
-
-
- if (p)
- {
- /*
- * The POD status file is needed for the printstatus window to
- * provide the current status of the printer.
- */
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/pod/%s.status", p->name);
-
- if (p->type & CUPS_PRINTER_CLASS)
- unlink(filename);
- else if ((fp = cupsFileOpen(filename, "w")) != NULL)
- {
- cupsFilePrintf(fp, "Operational Status | %s\n",
- (p->state == IPP_PRINTER_IDLE) ? "Idle" :
- (p->state == IPP_PRINTER_PROCESSING) ? "Busy" :
- "Faulted");
- cupsFilePrintf(fp, "Information | 01 00 00 | %s\n", CUPS_SVERSION);
- cupsFilePrintf(fp, "Information | 02 00 00 | Device URI: %s\n",
- p->device_uri);
- cupsFilePrintf(fp, "Information | 03 00 00 | %s jobs\n",
- p->accepting ? "Accepting" : "Not accepting");
- cupsFilePrintf(fp, "Information | 04 00 00 | %s\n", p->state_message);
-
- cupsFileClose(fp);
-
- chmod(filename, 0664);
- chown(filename, User, Group);
- }
-
- /*
- * The activeicons file is needed to provide desktop icons for printers:
- *
- * [ quoted from /usr/lib/print/tagit ]
- *
- * --- Type of printer tags (base values)
- *
- * Dumb=66048 # 0x10200
- * DumbColor=66080 # 0x10220
- * Raster=66112 # 0x10240
- * ColorRaster=66144 # 0x10260
- * Plotter=66176 # 0x10280
- * PostScript=66208 # 0x102A0
- * ColorPostScript=66240 # 0x102C0
- * MonoPostScript=66272 # 0x102E0
- *
- * --- Printer state modifiers for local printers
- *
- * Idle=0 # 0x0
- * Busy=1 # 0x1
- * Faulted=2 # 0x2
- * Unknown=3 # 0x3 (Faulted due to unknown reason)
- *
- * --- Printer state modifiers for network printers
- *
- * NetIdle=8 # 0x8
- * NetBusy=9 # 0x9
- * NetFaulted=10 # 0xA
- * NetUnknown=11 # 0xB (Faulted due to unknown reason)
- */
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/activeicons/%s", p->name);
-
- if (p->type & CUPS_PRINTER_CLASS)
- unlink(filename);
- else if ((fp = cupsFileOpen(filename, "w")) != NULL)
- {
- if (p->type & CUPS_PRINTER_COLOR)
- tag = 66240;
- else
- tag = 66272;
-
- if (p->type & CUPS_PRINTER_REMOTE)
- tag |= 8;
-
- if (p->state == IPP_PRINTER_PROCESSING)
- tag |= 1;
-
- else if (p->state == IPP_PRINTER_STOPPED)
- tag |= 2;
-
- cupsFilePuts(fp, "#!/bin/sh\n");
- cupsFilePrintf(fp, "#Tag %d\n", tag);
-
- cupsFileClose(fp);
-
- chmod(filename, 0755);
- chown(filename, User, Group);
- }
- }
-
- /*
- * The default file is needed by the printers window to show
- * the default printer.
- */
-
- snprintf(filename, sizeof(filename), "/var/spool/lp/default");
-
- if (DefaultPrinter != NULL)
- {
- if ((fp = cupsFileOpen(filename, "w")) != NULL)
- {
- cupsFilePrintf(fp, "%s\n", DefaultPrinter->name);
-
- cupsFileClose(fp);
-
- chmod(filename, 0644);
- chown(filename, User, Group);
- }
- }
- else
- unlink(filename);
-}
-#endif /* __sgi */
-
-
/*
* 'write_xml_string()' - Write a string with XML escaping.
*/
@@ -5296,7 +5057,7 @@ write_xml_string(cups_file_t *fp, /* I - File to write to */
if (*s == '&')
{
if (s > start)
- cupsFileWrite(fp, start, s - start);
+ cupsFileWrite(fp, start, (size_t)(s - start));
cupsFilePuts(fp, "&amp;");
start = s + 1;
@@ -5304,7 +5065,7 @@ write_xml_string(cups_file_t *fp, /* I - File to write to */
else if (*s == '<')
{
if (s > start)
- cupsFileWrite(fp, start, s - start);
+ cupsFileWrite(fp, start, (size_t)(s - start));
cupsFilePuts(fp, "&lt;");
start = s + 1;
@@ -5317,5 +5078,5 @@ write_xml_string(cups_file_t *fp, /* I - File to write to */
/*
- * End of "$Id: printers.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: printers.c 12733 2015-06-12 01:21:05Z msweet $".
*/
diff --git a/scheduler/printers.h b/scheduler/printers.h
index ad89d70..27db750 100644
--- a/scheduler/printers.h
+++ b/scheduler/printers.h
@@ -1,16 +1,16 @@
/*
- * "$Id: printers.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: printers.h 12666 2015-05-25 19:38:09Z msweet $"
*
- * Printer definitions for the CUPS scheduler.
+ * Printer definitions for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * 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/".
+ * 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/".
*/
#ifdef HAVE_DNSSD
@@ -63,9 +63,12 @@ struct cupsd_printer_s
*uuid, /* Printer UUID */
*hostname, /* Host printer resides on */
*name, /* Printer name */
- *location, /* Location code */
+ *location, /* Location string */
+ *geo_location, /* Geographic location URI */
*make_model, /* Make and model */
*info, /* Description */
+ *organization, /* Organization name */
+ *organizational_unit, /* Organizational unit (department, etc.) */
*op_policy, /* Operation policy name */
*error_policy; /* Error policy */
cupsd_policy_t *op_policy_ptr; /* Pointer to operation policy */
@@ -77,7 +80,8 @@ struct cupsd_printer_s
char state_message[1024]; /* Printer state message */
int num_reasons; /* Number of printer-state-reasons */
char *reasons[64]; /* printer-state-reasons strings */
- time_t state_time; /* Time at this state */
+ time_t config_time, /* Time at this configuration */
+ state_time; /* Time at this state */
char *job_sheets[2]; /* Banners/job sheets */
cups_ptype_t type; /* Printer type (color, small, etc.) */
char *device_uri; /* Device URI */
@@ -166,7 +170,8 @@ extern int cupsdSetAuthInfoRequired(cupsd_printer_t *p,
ipp_attribute_t *attr);
extern void cupsdSetDeviceURI(cupsd_printer_t *p, const char *uri);
extern void cupsdSetPrinterAttr(cupsd_printer_t *p,
- const char *name, char *value);
+ const char *name,
+ const char *value);
extern void cupsdSetPrinterAttrs(cupsd_printer_t *p);
extern int cupsdSetPrinterReasons(cupsd_printer_t *p,
const char *s);
@@ -189,5 +194,5 @@ extern void cupsdWritePrintcap(void);
/*
- * End of "$Id: printers.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: printers.h 12666 2015-05-25 19:38:09Z msweet $".
*/
diff --git a/scheduler/process.c b/scheduler/process.c
index a706ac2..19c7472 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -1,26 +1,16 @@
/*
- * "$Id: process.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: process.c 12521 2015-02-17 20:00:17Z msweet $"
*
- * Process management routines for the CUPS scheduler.
+ * Process management routines for the CUPS scheduler.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 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:
- *
- * cupsdCreateProfile() - Create an execution profile for a subprocess.
- * cupsdDestroyProfile() - Delete an execution profile.
- * cupsdEndProcess() - End a process.
- * cupsdFinishProcess() - Finish a process and get its name.
- * cupsdStartProcess() - Start a process.
- * compare_procs() - Compare two processes.
- * cupsd_requote() - Make a regular-expression version of a string.
+ * 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/".
*/
/*
@@ -32,6 +22,19 @@
#ifdef __APPLE__
# include <libgen.h>
#endif /* __APPLE__ */
+#ifdef HAVE_POSIX_SPAWN
+# include <spawn.h>
+extern char **environ;
+#endif /* HAVE_POSIX_SPAWN */
+#ifdef HAVE_POSIX_SPAWN
+# if !defined(__OpenBSD__) || OpenBSD >= 201505
+# define USE_POSIX_SPAWN 1
+# else
+# define USE_POSIX_SPAWN 0
+# endif /* !__OpenBSD__ || */
+#else
+# define USE_POSIX_SPAWN 0
+#endif /* HAVE_POSIX_SPAWN */
/*
@@ -68,34 +71,37 @@ static char *cupsd_requote(char *dst, const char *src, size_t dstsize);
*/
void * /* O - Profile or NULL on error */
-cupsdCreateProfile(int job_id) /* I - Job ID or 0 for none */
+cupsdCreateProfile(int job_id, /* I - Job ID or 0 for none */
+ int allow_networking)/* I - Allow networking off machine? */
{
#ifdef HAVE_SANDBOX_H
- cups_file_t *fp; /* File pointer */
- char profile[1024], /* File containing the profile */
- cache[1024], /* Quoted CacheDir */
- request[1024], /* Quoted RequestRoot */
- root[1024], /* Quoted ServerRoot */
- temp[1024]; /* Quoted TempDir */
- const char *nodebug; /* " (with no-log)" for no debug */
-
-
- if (!UseProfiles)
+ cups_file_t *fp; /* File pointer */
+ char profile[1024], /* File containing the profile */
+ bin[1024], /* Quoted ServerBin */
+ cache[1024], /* Quoted CacheDir */
+ domain[1024], /* Domain socket, if any */
+ request[1024], /* Quoted RequestRoot */
+ root[1024], /* Quoted ServerRoot */
+ state[1024], /* Quoted StateDir */
+ temp[1024]; /* Quoted TempDir */
+ const char *nodebug; /* " (with no-log)" for no debug */
+ cupsd_listener_t *lis; /* Current listening socket */
+
+
+ if (!UseSandboxing || Sandboxing == CUPSD_SANDBOXING_OFF)
{
/*
* Only use sandbox profiles as root...
*/
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL",
- job_id);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
return (NULL);
}
if ((fp = cupsTempFile2(profile, sizeof(profile))) == NULL)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL",
- job_id);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create security profile: %s",
strerror(errno));
return (NULL);
@@ -104,22 +110,29 @@ cupsdCreateProfile(int job_id) /* I - Job ID or 0 for none */
fchown(cupsFileNumber(fp), RunUser, Group);
fchmod(cupsFileNumber(fp), 0640);
+ cupsd_requote(bin, ServerBin, sizeof(bin));
cupsd_requote(cache, CacheDir, sizeof(cache));
cupsd_requote(request, RequestRoot, sizeof(request));
cupsd_requote(root, ServerRoot, sizeof(root));
+ cupsd_requote(state, StateDir, sizeof(state));
cupsd_requote(temp, TempDir, sizeof(temp));
nodebug = LogLevel < CUPSD_LOG_DEBUG ? " (with no-log)" : "";
cupsFilePuts(fp, "(version 1)\n");
- cupsFilePuts(fp, "(allow default)\n");
- cupsFilePrintf(fp,
- "(deny file-write* file-read-data file-read-metadata\n"
- " (regex"
- " #\"^%s$\"" /* RequestRoot */
- " #\"^%s/\"" /* RequestRoot/... */
- ")%s)\n",
- request, request, nodebug);
+ if (Sandboxing == CUPSD_SANDBOXING_STRICT)
+ cupsFilePuts(fp, "(deny default)\n");
+ else
+ cupsFilePuts(fp, "(allow default)\n");
+ if (LogLevel >= CUPSD_LOG_DEBUG)
+ cupsFilePuts(fp, "(debug deny)\n");
+ cupsFilePuts(fp, "(import \"system.sb\")\n");
+ cupsFilePuts(fp, "(system-network)\n");
+ cupsFilePuts(fp, "(allow mach-per-user-lookup)\n");
+ cupsFilePuts(fp, "(allow ipc-posix-sem)\n");
+ cupsFilePuts(fp, "(allow ipc-posix-shm)\n");
+ cupsFilePuts(fp, "(allow ipc-sysv-shm)\n");
+ cupsFilePuts(fp, "(allow mach-lookup)\n");
if (!RunUser)
cupsFilePrintf(fp,
"(deny file-write* file-read-data file-read-metadata\n"
@@ -142,13 +155,43 @@ cupsdCreateProfile(int job_id) /* I - Job ID or 0 for none */
" #\"^/System/\""
")%s)\n",
root, root, nodebug);
- /* Specifically allow applications to stat RequestRoot */
+ /* Specifically allow applications to stat RequestRoot and some other system folders */
cupsFilePrintf(fp,
"(allow file-read-metadata\n"
" (regex"
+ " #\"^/$\"" /* / */
+ " #\"^/usr$\"" /* /usr */
+ " #\"^/Library$\"" /* /Library */
+ " #\"^/Library/Printers$\"" /* /Library/Printers */
" #\"^%s$\"" /* RequestRoot */
"))\n",
request);
+ /* Read and write TempDir, CacheDir, and other common folders */
+ cupsFilePuts(fp,
+ "(allow file-write* file-read-data file-read-metadata\n"
+ " (regex"
+ " #\"^/private/var/db/\""
+ " #\"^/private/var/folders/\""
+ " #\"^/private/var/lib/\""
+ " #\"^/private/var/log/\""
+ " #\"^/private/var/mysql/\""
+ " #\"^/private/var/run/\""
+ " #\"^/private/var/spool/\""
+ " #\"^/Library/Application Support/\""
+ " #\"^/Library/Caches/\""
+ " #\"^/Library/Logs/\""
+ " #\"^/Library/Preferences/\""
+ " #\"^/Library/WebServer/\""
+ " #\"^/Users/Shared/\""
+ "))\n");
+ cupsFilePrintf(fp,
+ "(deny file-write*\n"
+ " (regex #\"^%s$\")%s)\n",
+ request, nodebug);
+ cupsFilePrintf(fp,
+ "(deny file-write* file-read-data file-read-metadata\n"
+ " (regex #\"^%s/\")%s)\n",
+ request, nodebug);
cupsFilePrintf(fp,
"(allow file-write* file-read-data file-read-metadata\n"
" (regex"
@@ -156,56 +199,160 @@ cupsdCreateProfile(int job_id) /* I - Job ID or 0 for none */
" #\"^%s/\"" /* TempDir/... */
" #\"^%s$\"" /* CacheDir */
" #\"^%s/\"" /* CacheDir/... */
+ " #\"^%s$\"" /* StateDir */
+ " #\"^%s/\"" /* StateDir/... */
+ "))\n",
+ temp, temp, cache, cache, state, state);
+ /* Read common folders */
+ cupsFilePrintf(fp,
+ "(allow file-read-data file-read-metadata\n"
+ " (regex"
+ " #\"^/AppleInternal$\""
+ " #\"^/AppleInternal/\""
+ " #\"^/bin$\"" /* /bin */
+ " #\"^/bin/\"" /* /bin/... */
+ " #\"^/private$\""
+ " #\"^/private/etc$\""
+ " #\"^/private/etc/\""
+ " #\"^/private/tmp$\""
+ " #\"^/private/tmp/\""
+ " #\"^/private/var$\""
+ " #\"^/private/var/db$\""
+ " #\"^/private/var/folders$\""
+ " #\"^/private/var/lib$\""
+ " #\"^/private/var/log$\""
+ " #\"^/private/var/mysql$\""
+ " #\"^/private/var/run$\""
+ " #\"^/private/var/spool$\""
+ " #\"^/private/var/tmp$\""
+ " #\"^/private/var/tmp/\""
+ " #\"^/usr/bin$\"" /* /usr/bin */
+ " #\"^/usr/bin/\"" /* /usr/bin/... */
+ " #\"^/usr/libexec/cups$\"" /* /usr/libexec/cups */
+ " #\"^/usr/libexec/cups/\"" /* /usr/libexec/cups/... */
+ " #\"^/usr/libexec/fax$\"" /* /usr/libexec/fax */
+ " #\"^/usr/libexec/fax/\"" /* /usr/libexec/fax/... */
+ " #\"^/usr/sbin$\"" /* /usr/sbin */
+ " #\"^/usr/sbin/\"" /* /usr/sbin/... */
+ " #\"^/Library$\"" /* /Library */
+ " #\"^/Library/\"" /* /Library/... */
+ " #\"^/System$\"" /* /System */
+ " #\"^/System/\"" /* /System/... */
" #\"^%s/Library$\"" /* RequestRoot/Library */
" #\"^%s/Library/\"" /* RequestRoot/Library/... */
- " #\"^/Library/Application Support/\""
- " #\"^/Library/Caches/\""
- " #\"^/Library/Preferences/\""
- " #\"^/Library/Printers/.*/\""
- " #\"^/Users/Shared/\""
+ " #\"^%s$\"" /* ServerBin */
+ " #\"^%s/\"" /* ServerBin/... */
+ " #\"^%s$\"" /* ServerRoot */
+ " #\"^%s/\"" /* ServerRoot/... */
"))\n",
- temp, temp, cache, cache, request, request);
- cupsFilePrintf(fp,
- "(deny file-write*\n"
+ request, request, bin, bin, root, root);
+ if (Sandboxing == CUPSD_SANDBOXING_RELAXED)
+ {
+ /* Limited write access to /Library/Printers/... */
+ cupsFilePuts(fp,
+ "(allow file-write*\n"
" (regex"
- " #\"^/Library/Printers/PPDs$\""
- " #\"^/Library/Printers/PPDs/\""
- " #\"^/Library/Printers/PPD Plugins$\""
- " #\"^/Library/Printers/PPD Plugins/\""
- ")%s)\n", nodebug);
- if (job_id)
+ " #\"^/Library/Printers/.*/\""
+ "))\n");
+ cupsFilePrintf(fp,
+ "(deny file-write*\n"
+ " (regex"
+ " #\"^/Library/Printers/PPDs$\""
+ " #\"^/Library/Printers/PPDs/\""
+ " #\"^/Library/Printers/PPD Plugins$\""
+ " #\"^/Library/Printers/PPD Plugins/\""
+ ")%s)\n", nodebug);
+ }
+ /* Allow execution of child processes as long as the programs are not in a user directory */
+ cupsFilePuts(fp, "(allow process*)\n");
+ cupsFilePuts(fp, "(deny process-exec (regex #\"^/Users/\"))\n");
+ if (RunUser && getenv("CUPS_TESTROOT"))
{
- /*
- * Allow job filters to read the spool file(s)...
- */
+ /* Allow source directory access in "make test" environment */
+ char testroot[1024]; /* Root directory of test files */
+
+ cupsd_requote(testroot, getenv("CUPS_TESTROOT"), sizeof(testroot));
cupsFilePrintf(fp,
+ "(allow file-write* file-read-data file-read-metadata\n"
+ " (regex"
+ " #\"^%s$\"" /* CUPS_TESTROOT */
+ " #\"^%s/\"" /* CUPS_TESTROOT/... */
+ "))\n",
+ testroot, testroot);
+ cupsFilePrintf(fp,
+ "(allow process-exec\n"
+ " (regex"
+ " #\"^%s/\"" /* CUPS_TESTROOT/... */
+ "))\n",
+ testroot);
+ cupsFilePrintf(fp, "(allow sysctl*)\n");
+ }
+ if (job_id)
+ {
+ /* Allow job filters to read the current job files... */
+ cupsFilePrintf(fp,
"(allow file-read-data file-read-metadata\n"
- " (regex #\"^%s/([ac]%05d|d%05d-[0-9][0-9][0-9])$\"))\n",
+ " (regex #\"^%s/([ac]%05d|d%05d-[0-9][0-9][0-9])$\"))\n",
request, job_id, job_id);
}
else
{
- /*
- * Allow email notifications from notifiers...
- */
-
+ /* Allow email notifications from notifiers... */
cupsFilePuts(fp,
"(allow process-exec\n"
" (literal \"/usr/sbin/sendmail\")\n"
- " (with no-sandbox)\n"
- ")\n");
+ " (with no-sandbox))\n");
+ }
+ /* Allow access to Bluetooth, USB, and notify_post. */
+ cupsFilePuts(fp, "(allow iokit*)\n");
+ cupsFilePuts(fp, "(allow distributed-notification-post)\n");
+ /* Allow outbound networking to local services */
+ cupsFilePuts(fp, "(allow network-outbound"
+ "\n (regex #\"^/private/var/run/\" #\"^/private/tmp/\" #\"^/private/var/tmp/\")");
+ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
+ lis;
+ lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
+ {
+ if (httpAddrFamily(&(lis->address)) == AF_LOCAL)
+ {
+ httpAddrString(&(lis->address), domain, sizeof(domain));
+ cupsFilePrintf(fp, "\n (literal \"%s\")", domain);
+ }
+ }
+ if (allow_networking)
+ {
+ /* Allow TCP and UDP networking off the machine... */
+ cupsFilePuts(fp, "\n (remote tcp))\n");
+ cupsFilePuts(fp, "(allow network-bind)\n"); /* for LPD resvport */
+ cupsFilePuts(fp, "(allow network*\n"
+ " (local udp \"*:*\")\n"
+ " (remote udp \"*:*\"))\n");
+
+ /* Also allow access to device files... */
+ cupsFilePuts(fp, "(allow file-write* file-read-data file-read-metadata file-ioctl\n"
+ " (regex #\"^/dev/\"))\n");
+
+ /* And allow kernel extensions to be loaded, e.g., SMB */
+ cupsFilePuts(fp, "(allow system-kext-load)\n");
+ }
+ else
+ {
+ /* Only allow SNMP (UDP) and LPD (TCP) off the machine... */
+ cupsFilePuts(fp, ")\n");
+ cupsFilePuts(fp, "(allow network-outbound\n"
+ " (remote udp \"*:161\")"
+ " (remote tcp \"*:515\"))\n");
+ cupsFilePuts(fp, "(allow network-inbound\n"
+ " (local udp \"localhost:*\"))\n");
}
-
cupsFileClose(fp);
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = \"%s\"",
- job_id, profile);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d,allow_networking=%d) = \"%s\"", job_id, allow_networking, profile);
return ((void *)strdup(profile));
#else
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL",
- job_id);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
return (NULL);
#endif /* HAVE_SANDBOX_H */
@@ -268,10 +415,10 @@ cupsdEndProcess(int pid, /* I - Process ID */
*/
const char * /* O - Process name */
-cupsdFinishProcess(int pid, /* I - Process ID */
- char *name, /* I - Name buffer */
- int namelen, /* I - Size of name buffer */
- int *job_id) /* O - Job ID pointer or NULL */
+cupsdFinishProcess(int pid, /* I - Process ID */
+ char *name, /* I - Name buffer */
+ size_t namelen, /* I - Size of name buffer */
+ int *job_id) /* O - Job ID pointer or NULL */
{
cupsd_proc_t key, /* Search key */
*proc; /* Matching process */
@@ -296,10 +443,7 @@ cupsdFinishProcess(int pid, /* I - Process ID */
strlcpy(name, "unknown", namelen);
}
- cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdFinishProcess(pid=%d, name=%p, namelen=%d, "
- "job_id=%p(%d)) = \"%s\"", pid, name, namelen, job_id,
- job_id ? *job_id : 0, name);
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFinishProcess(pid=%d, name=%p, namelen=" CUPS_LLFMT ", job_id=%p(%d)) = \"%s\"", pid, name, CUPS_LLCAST namelen, job_id, job_id ? *job_id : 0, name);
return (name);
}
@@ -326,13 +470,20 @@ cupsdStartProcess(
{
int i; /* Looping var */
const char *exec_path = command; /* Command to be exec'd */
- char *real_argv[103], /* Real command-line arguments */
- cups_exec[1024]; /* Path to "cups-exec" program */
- int user; /* Command UID */
+ char *real_argv[110], /* Real command-line arguments */
+ cups_exec[1024], /* Path to "cups-exec" program */
+ user_str[16], /* User string */
+ group_str[16], /* Group string */
+ nice_str[16]; /* FilterNice string */
+ uid_t user; /* Command UID */
cupsd_proc_t *proc; /* New process record */
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+#if USE_POSIX_SPAWN
+ posix_spawn_file_actions_t actions; /* Spawn file actions */
+ posix_spawnattr_t attrs; /* Spawn attributes */
+ sigset_t defsignals; /* Default signals */
+#elif defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action; /* POSIX signal handler */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+#endif /* USE_POSIX_SPAWN */
#if defined(__APPLE__)
char processPath[1024], /* CFProcessPath environment variable */
linkpath[1024]; /* Link path for symlinks... */
@@ -396,25 +547,107 @@ cupsdStartProcess(
* Use helper program when we have a sandbox profile...
*/
+#if !USE_POSIX_SPAWN
if (profile)
+#endif /* !USE_POSIX_SPAWN */
{
snprintf(cups_exec, sizeof(cups_exec), "%s/daemon/cups-exec", ServerBin);
+ snprintf(user_str, sizeof(user_str), "%d", user);
+ snprintf(group_str, sizeof(group_str), "%d", Group);
+ snprintf(nice_str, sizeof(nice_str), "%d", FilterNice);
real_argv[0] = cups_exec;
- real_argv[1] = profile;
- real_argv[2] = (char *)command;
+ real_argv[1] = (char *)"-g";
+ real_argv[2] = group_str;
+ real_argv[3] = (char *)"-n";
+ real_argv[4] = nice_str;
+ real_argv[5] = (char *)"-u";
+ real_argv[6] = user_str;
+ real_argv[7] = profile ? profile : "none";
+ real_argv[8] = (char *)command;
for (i = 0;
- i < (int)(sizeof(real_argv) / sizeof(real_argv[0]) - 4) && argv[i];
+ i < (int)(sizeof(real_argv) / sizeof(real_argv[0]) - 10) && argv[i];
i ++)
- real_argv[i + 3] = argv[i];
+ real_argv[i + 9] = argv[i];
- real_argv[i + 3] = NULL;
+ real_argv[i + 9] = NULL;
argv = real_argv;
exec_path = cups_exec;
}
+ if (LogLevel == CUPSD_LOG_DEBUG2)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: Preparing to start \"%s\", arguments:", command);
+
+ for (i = 0; argv[i]; i ++)
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: argv[%d] = \"%s\"", i, argv[i]);
+ }
+
+#if USE_POSIX_SPAWN
+ /*
+ * Setup attributes and file actions for the spawn...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: Setting spawn attributes.");
+ sigemptyset(&defsignals);
+ sigaddset(&defsignals, SIGTERM);
+ sigaddset(&defsignals, SIGCHLD);
+ sigaddset(&defsignals, SIGPIPE);
+
+ posix_spawnattr_init(&attrs);
+ posix_spawnattr_setflags(&attrs, POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGDEF);
+ posix_spawnattr_setpgroup(&attrs, 0);
+ posix_spawnattr_setsigdefault(&attrs, &defsignals);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: Setting file actions.");
+ posix_spawn_file_actions_init(&actions);
+ if (infd != 0)
+ {
+ if (infd < 0)
+ posix_spawn_file_actions_addopen(&actions, 0, "/dev/null", O_RDONLY, 0);
+ else
+ posix_spawn_file_actions_adddup2(&actions, infd, 0);
+ }
+
+ if (outfd != 1)
+ {
+ if (outfd < 0)
+ posix_spawn_file_actions_addopen(&actions, 1, "/dev/null", O_WRONLY, 0);
+ else
+ posix_spawn_file_actions_adddup2(&actions, outfd, 1);
+ }
+
+ if (errfd != 2)
+ {
+ if (errfd < 0)
+ posix_spawn_file_actions_addopen(&actions, 2, "/dev/null", O_WRONLY, 0);
+ else
+ posix_spawn_file_actions_adddup2(&actions, errfd, 2);
+ }
+
+ if (backfd != 3 && backfd >= 0)
+ posix_spawn_file_actions_adddup2(&actions, backfd, 3);
+
+ if (sidefd != 4 && sidefd >= 0)
+ posix_spawn_file_actions_adddup2(&actions, sidefd, 4);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: Calling posix_spawn.");
+
+ if (posix_spawn(pid, exec_path, &actions, &attrs, argv, envp ? envp : environ))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to fork %s - %s.", command, strerror(errno));
+
+ *pid = 0;
+ }
+ else
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartProcess: pid=%d", (int)*pid);
+
+ posix_spawn_file_actions_destroy(&actions);
+ posix_spawnattr_destroy(&attrs);
+
+#else
/*
* Block signals before forking...
*/
@@ -444,13 +677,13 @@ cupsdStartProcess(
* processes it creates.
*/
-#ifdef HAVE_SETPGID
+# ifdef HAVE_SETPGID
if (!RunUser && setpgid(0, 0))
exit(errno + 100);
-#else
+# else
if (!RunUser && setpgrp())
exit(errno + 100);
-#endif /* HAVE_SETPGID */
+# endif /* HAVE_SETPGID */
/*
* Update the remaining file descriptors as needed...
@@ -529,11 +762,11 @@ cupsdStartProcess(
* Unblock signals before doing the exec...
*/
-#ifdef HAVE_SIGSET
+# ifdef HAVE_SIGSET
sigset(SIGTERM, SIG_DFL);
sigset(SIGCHLD, SIG_DFL);
sigset(SIGPIPE, SIG_DFL);
-#elif defined(HAVE_SIGACTION)
+# elif defined(HAVE_SIGACTION)
memset(&action, 0, sizeof(action));
sigemptyset(&action.sa_mask);
@@ -542,11 +775,11 @@ cupsdStartProcess(
sigaction(SIGTERM, &action, NULL);
sigaction(SIGCHLD, &action, NULL);
sigaction(SIGPIPE, &action, NULL);
-#else
+# else
signal(SIGTERM, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
-#endif /* HAVE_SIGSET */
+# endif /* HAVE_SIGSET */
cupsdReleaseSignals();
@@ -573,7 +806,11 @@ cupsdStartProcess(
*pid = 0;
}
- else
+
+ cupsdReleaseSignals();
+#endif /* USE_POSIX_SPAWN */
+
+ if (*pid)
{
if (!process_array)
process_array = cupsArrayNew((cups_array_func_t)compare_procs, NULL);
@@ -591,8 +828,6 @@ cupsdStartProcess(
}
}
- cupsdReleaseSignals();
-
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, "
"infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, "
@@ -638,10 +873,13 @@ cupsd_requote(char *dst, /* I - Destination buffer */
{
ch = *src++;
+ if (ch == '/' && !*src)
+ break; /* Don't add trailing slash */
+
if (strchr(".?*()[]^$\\", ch))
*dstptr++ = '\\';
- *dstptr++ = ch;
+ *dstptr++ = (char)ch;
}
*dstptr = '\0';
@@ -652,5 +890,5 @@ cupsd_requote(char *dst, /* I - Destination buffer */
/*
- * End of "$Id: process.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: process.c 12521 2015-02-17 20:00:17Z msweet $".
*/
diff --git a/scheduler/quotas.c b/scheduler/quotas.c
index 3ebfd8d..ae8b88f 100644
--- a/scheduler/quotas.c
+++ b/scheduler/quotas.c
@@ -1,5 +1,5 @@
/*
- * "$Id: quotas.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: quotas.c 10996 2013-05-29 11:51: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 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: quotas.c 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/select.c b/scheduler/select.c
index e2f40d8..357cc40 100644
--- a/scheduler/select.c
+++ b/scheduler/select.c
@@ -1,28 +1,16 @@
/*
- * "$Id: select.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: select.c 11594 2014-02-14 20:09:01Z msweet $"
*
- * Select abstraction functions for the CUPS scheduler.
+ * Select abstraction functions for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
- * Copyright 2006-2007 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2006-2007 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * cupsdAddSelect() - Add a file descriptor to the list.
- * cupsdDoSelect() - Do a select-like operation.
- * cupsdIsSelecting() - Determine whether we are monitoring a file
- * descriptor.
- * cupsdRemoveSelect() - Remove a file descriptor from the list.
- * cupsdStartSelect() - Initialize the file polling engine.
- * cupsdStopSelect() - Shutdown the file polling engine.
- * compare_fds() - Compare file descriptors.
- * find_fd() - Find an existing file descriptor record.
+ * 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/".
*/
/*
@@ -39,8 +27,6 @@
# include <sys/time.h>
#elif defined(HAVE_POLL)
# include <poll.h>
-#elif defined(__hpux)
-# include <sys/time.h>
#else
# include <sys/select.h>
#endif /* HAVE_EPOLL */
@@ -49,15 +35,14 @@
/*
* Design Notes for Poll/Select API in CUPSD
* -----------------------------------------
- *
+ *
* SUPPORTED APIS
- *
+ *
* OS select poll epoll kqueue /dev/poll
* -------------- ------ ------ ------ ------ ---------
* AIX YES YES NO NO NO
* FreeBSD YES YES NO YES NO
* HP-UX YES YES NO NO NO
- * IRIX YES YES NO NO NO
* Linux YES YES YES NO NO
* MacOS X YES YES NO YES NO
* NetBSD YES YES NO YES NO
@@ -65,22 +50,22 @@
* Solaris YES YES NO NO YES
* Tru64 YES YES NO NO NO
* Windows YES NO NO NO NO
- *
- *
+ *
+ *
* HIGH-LEVEL API
- *
+ *
* typedef void (*cupsd_selfunc_t)(void *data);
- *
+ *
* void cupsdStartSelect(void);
* void cupsdStopSelect(void);
* void cupsdAddSelect(int fd, cupsd_selfunc_t read_cb,
* cupsd_selfunc_t write_cb, void *data);
* void cupsdRemoveSelect(int fd);
* int cupsdDoSelect(int timeout);
- *
- *
+ *
+ *
* IMPLEMENTATION STRATEGY
- *
+ *
* 0. Common Stuff
* a. CUPS array of file descriptor to callback functions
* and data + temporary array of removed fd's.
@@ -103,7 +88,7 @@
* working sets.
* d. cupsdStopSelect() frees all of the memory used by the
* CUPS array and fd_set's.
- *
+ *
* 2. poll() - O(n log n)
* a. Regular array of pollfd, sorted the same as the CUPS
* array.
@@ -117,7 +102,7 @@
* e. cupsdRemoveSelect() flags the pollfd array as invalid.
* f. cupsdStopSelect() frees all of the memory used by the
* CUPS array and pollfd array.
- *
+ *
* 3. epoll() - O(n)
* a. cupsdStartSelect() creates epoll file descriptor using
* epoll_create() with the maximum fd count, and
@@ -133,7 +118,7 @@
* the callback record.
* d. cupsdStopSelect() closes the epoll file descriptor and
* frees all of the memory used by the event buffer.
- *
+ *
* 4. kqueue() - O(n)
* b. cupsdStartSelect() creates kqueue file descriptor
* using kqueue() function and allocates a global event
@@ -146,7 +131,7 @@
* find the callback record.
* e. cupsdStopSelect() closes the kqueue() file descriptor
* and frees all of the memory used by the event buffer.
- *
+ *
* 5. /dev/poll - O(n log n) - NOT YET IMPLEMENTED
* a. cupsdStartSelect() opens /dev/poll and allocates an
* array of pollfd structs; on failure to open /dev/poll,
@@ -533,15 +518,13 @@ cupsdDoSelect(long timeout) /* I - Timeout in seconds */
if (cupsd_pollfds)
- pfd = realloc(cupsd_pollfds, allocfds * sizeof(struct pollfd));
+ pfd = realloc(cupsd_pollfds, (size_t)allocfds * sizeof(struct pollfd));
else
- pfd = malloc(allocfds * sizeof(struct pollfd));
+ pfd = malloc((size_t)allocfds * sizeof(struct pollfd));
if (!pfd)
{
- cupsdLogMessage(CUPSD_LOG_EMERG,
- "Unable to allocate %d bytes for polling!",
- (int)(allocfds * sizeof(struct pollfd)));
+ cupsdLogMessage(CUPSD_LOG_EMERG, "Unable to allocate %d bytes for polling.", (int)((size_t)allocfds * sizeof(struct pollfd)));
return (-1);
}
@@ -570,9 +553,9 @@ cupsdDoSelect(long timeout) /* I - Timeout in seconds */
}
if (timeout >= 0 && timeout < 86400)
- nfds = poll(cupsd_pollfds, count, timeout * 1000);
+ nfds = poll(cupsd_pollfds, (nfds_t)count, timeout * 1000);
else
- nfds = poll(cupsd_pollfds, count, -1);
+ nfds = poll(cupsd_pollfds, (nfds_t)count, -1);
if (nfds > 0)
{
@@ -813,7 +796,7 @@ cupsdRemoveSelect(int fd) /* I - File descriptor */
void
cupsdStartSelect(void)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartSelect()");
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdStartSelect()");
cupsd_fds = cupsArrayNew((cups_array_func_t)compare_fds, NULL);
@@ -823,13 +806,13 @@ cupsdStartSelect(void)
#ifdef HAVE_EPOLL
cupsd_epoll_fd = epoll_create(MaxFDs);
- cupsd_epoll_events = calloc(MaxFDs, sizeof(struct epoll_event));
+ cupsd_epoll_events = calloc((size_t)MaxFDs, sizeof(struct epoll_event));
cupsd_update_pollfds = 0;
#elif defined(HAVE_KQUEUE)
cupsd_kqueue_fd = kqueue();
cupsd_kqueue_changes = 0;
- cupsd_kqueue_events = calloc(MaxFDs, sizeof(struct kevent));
+ cupsd_kqueue_events = calloc((size_t)MaxFDs, sizeof(struct kevent));
#elif defined(HAVE_POLL)
cupsd_update_pollfds = 0;
@@ -851,7 +834,7 @@ cupsdStopSelect(void)
_cupsd_fd_t *fdptr; /* Current file descriptor */
- cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStopSelect()");
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdStopSelect()");
for (fdptr = (_cupsd_fd_t *)cupsArrayFirst(cupsd_fds);
fdptr;
@@ -947,5 +930,5 @@ find_fd(int fd) /* I - File descriptor */
/*
- * End of "$Id: select.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: select.c 11594 2014-02-14 20:09:01Z msweet $".
*/
diff --git a/scheduler/server.c b/scheduler/server.c
index 7e511c4..37001de 100644
--- a/scheduler/server.c
+++ b/scheduler/server.c
@@ -1,5 +1,5 @@
/*
- * "$Id: server.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: server.c 12689 2015-06-03 19:49:54Z msweet $"
*
* Server start/stop routines for the CUPS scheduler.
*
@@ -54,7 +54,7 @@ cupsdStartServer(void)
* Create the default security profile...
*/
- DefaultProfile = cupsdCreateProfile(0);
+ DefaultProfile = cupsdCreateProfile(0, 1);
/*
* Startup all the networking stuff...
@@ -142,21 +142,24 @@ cupsdStopServer(void)
if (AccessFile != NULL)
{
- cupsFileClose(AccessFile);
+ if (AccessFile != LogStderr)
+ cupsFileClose(AccessFile);
AccessFile = NULL;
}
if (ErrorFile != NULL)
{
- cupsFileClose(ErrorFile);
+ if (ErrorFile != LogStderr)
+ cupsFileClose(ErrorFile);
ErrorFile = NULL;
}
if (PageFile != NULL)
{
- cupsFileClose(PageFile);
+ if (PageFile != LogStderr)
+ cupsFileClose(PageFile);
PageFile = NULL;
}
@@ -180,5 +183,5 @@ cupsdStopServer(void)
/*
- * End of "$Id: server.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: server.c 12689 2015-06-03 19:49:54Z msweet $".
*/
diff --git a/scheduler/statbuf.c b/scheduler/statbuf.c
index 7f99149..b608b15 100644
--- a/scheduler/statbuf.c
+++ b/scheduler/statbuf.c
@@ -1,22 +1,16 @@
/*
- * "$Id: statbuf.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: statbuf.c 11594 2014-02-14 20:09:01Z msweet $"
*
- * Status buffer routines for the CUPS scheduler.
+ * Status buffer routines for the CUPS scheduler.
*
- * Copyright 2007-2010 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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:
- *
- * cupsdStatBufDelete() - Destroy a status buffer.
- * cupsdStatBufNew() - Create a new status buffer.
- * cupsdStatBufUpdate() - Update the status buffer.
+ * 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/".
*/
/*
@@ -119,7 +113,7 @@ cupsdStatBufNew(int fd, /* I - File descriptor of pipe */
char * /* O - Line from buffer, "", or NULL */
cupsdStatBufUpdate(
cupsd_statbuf_t *sb, /* I - Status buffer */
- int *loglevel, /* O - Log level */
+ int *loglevel, /* O - Log level */
char *line, /* I - Line buffer */
int linelen) /* I - Size of line buffer */
{
@@ -138,8 +132,7 @@ cupsdStatBufUpdate(
* No, read more data...
*/
- if ((bytes = read(sb->fd, sb->buffer + sb->bufused,
- CUPSD_SB_BUFFER_SIZE - sb->bufused - 1)) > 0)
+ if ((bytes = read(sb->fd, sb->buffer + sb->bufused, (size_t)(CUPSD_SB_BUFFER_SIZE - sb->bufused - 1))) > 0)
{
sb->bufused += bytes;
sb->buffer[sb->bufused] = '\0';
@@ -258,6 +251,11 @@ cupsdStatBufUpdate(
*loglevel = CUPSD_LOG_STATE;
message = sb->buffer + 6;
}
+ else if (!strncmp(sb->buffer, "JOBSTATE:", 9))
+ {
+ *loglevel = CUPSD_LOG_JOBSTATE;
+ message = sb->buffer + 9;
+ }
else if (!strncmp(sb->buffer, "ATTR:", 5))
{
*loglevel = CUPSD_LOG_ATTR;
@@ -307,7 +305,7 @@ cupsdStatBufUpdate(
* Copy the message to the line buffer...
*/
- strlcpy(line, message, linelen);
+ strlcpy(line, message, (size_t)linelen);
/*
* Copy over the buffer data we've used up...
@@ -326,5 +324,5 @@ cupsdStatBufUpdate(
/*
- * End of "$Id: statbuf.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: statbuf.c 11594 2014-02-14 20:09:01Z msweet $".
*/
diff --git a/scheduler/statbuf.h b/scheduler/statbuf.h
index 91564d0..68bf206 100644
--- a/scheduler/statbuf.h
+++ b/scheduler/statbuf.h
@@ -1,5 +1,5 @@
/*
- * "$Id: statbuf.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: statbuf.h 10996 2013-05-29 11:51: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 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: statbuf.h 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/subscriptions.c b/scheduler/subscriptions.c
index 0b9c452..5d0e822 100644
--- a/scheduler/subscriptions.c
+++ b/scheduler/subscriptions.c
@@ -1,37 +1,16 @@
/*
- * "$Id: subscriptions.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: subscriptions.c 12978 2015-11-17 19:29:52Z msweet $"
*
- * Subscription routines for the CUPS scheduler.
+ * Subscription routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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:
- *
- * cupsdAddEvent() - Add an event to the global event cache.
- * cupsdAddSubscription() - Add a new subscription object.
- * cupsdDeleteAllSubscriptions() - Delete all subscriptions.
- * cupsdDeleteSubscription() - Delete a subscription object.
- * cupsdEventName() - Return a single event name.
- * cupsdEventValue() - Return the event mask value for a name.
- * cupsdExpireSubscriptions() - Expire old subscription objects.
- * cupsdFindSubscription() - Find a subscription by ID.
- * cupsdLoadAllSubscriptions() - Load all subscriptions from the .conf file.
- * cupsdSaveAllSubscriptions() - Save all subscriptions to the .conf file.
- * cupsdStopAllNotifiers() - Stop all notifier processes.
- * cupsd_compare_subscriptions() - Compare two subscriptions.
- * cupsd_delete_event() - Delete a single event...
- * cupsd_send_dbus() - Send a DBUS notification...
- * cupsd_send_notification() - Send a notification for the specified
- * event.
- * cupsd_start_notifier() - Start a notifier subprocess...
- * cupsd_update_notifier() - Read messages from notifiers.
+ * 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/".
*/
/*
@@ -126,9 +105,7 @@ cupsdAddEvent(
* Check if this subscription requires this event...
*/
- if ((sub->mask & event) != 0 &&
- (sub->dest == dest || !sub->dest) &&
- (sub->job == job || !sub->job))
+ if ((sub->mask & event) != 0 && (sub->dest == dest || !sub->dest || sub->job == job))
{
/*
* Need this event, so create a new event record...
@@ -212,7 +189,7 @@ cupsdAddEvent(
(const char * const *)dest->reasons);
ippAddBoolean(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
- "printer-is-accepting-jobs", dest->accepting);
+ "printer-is-accepting-jobs", (char)dest->accepting);
}
if (job)
@@ -945,9 +922,9 @@ cupsdLoadAllSubscriptions(void)
if (isxdigit(valueptr[0]) && isxdigit(valueptr[1]))
{
if (isdigit(valueptr[0]))
- sub->user_data[i] = (valueptr[0] - '0') << 4;
+ sub->user_data[i] = (unsigned char)((valueptr[0] - '0') << 4);
else
- sub->user_data[i] = (tolower(valueptr[0]) - 'a' + 10) << 4;
+ sub->user_data[i] = (unsigned char)((tolower(valueptr[0]) - 'a' + 10) << 4);
if (isdigit(valueptr[1]))
sub->user_data[i] |= valueptr[1] - '0';
@@ -966,7 +943,7 @@ cupsdLoadAllSubscriptions(void)
break;
}
else
- sub->user_data[i] = *valueptr++;
+ sub->user_data[i] = (unsigned char)*valueptr++;
}
if (*valueptr)
@@ -1638,5 +1615,5 @@ cupsd_update_notifier(void)
/*
- * End of "$Id: subscriptions.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: subscriptions.c 12978 2015-11-17 19:29:52Z msweet $".
*/
diff --git a/scheduler/subscriptions.h b/scheduler/subscriptions.h
index 1a786ae..867a1c6 100644
--- a/scheduler/subscriptions.h
+++ b/scheduler/subscriptions.h
@@ -1,5 +1,5 @@
/*
- * "$Id: subscriptions.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: subscriptions.h 10996 2013-05-29 11:51:34Z msweet $"
*
* Subscription definitions for the CUPS scheduler.
*
@@ -162,5 +162,5 @@ extern void cupsdStopAllNotifiers(void);
/*
- * End of "$Id: subscriptions.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: subscriptions.h 10996 2013-05-29 11:51:34Z msweet $".
*/
diff --git a/scheduler/sysman.c b/scheduler/sysman.c
index d5f82c1..63b51a9 100644
--- a/scheduler/sysman.c
+++ b/scheduler/sysman.c
@@ -1,34 +1,16 @@
/*
- * "$Id: sysman.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: sysman.c 12236 2014-11-03 04:08:41Z msweet $"
*
- * System management functions for the CUPS scheduler.
+ * System management functions for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 2006 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2006 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * cupsdCleanDirty() - Write dirty config and state files.
- * cupsdMarkDirty() - Mark config or state files as needing a
- * write.
- * cupsdSetBusyState() - Let the system know when we are busy
- * doing something.
- * cupsdAllowSleep() - Tell the OS it is now OK to sleep.
- * cupsdStartSystemMonitor() - Start monitoring for system change.
- * cupsdStopSystemMonitor() - Stop monitoring for system change.
- * sysEventThreadEntry() - A thread to receive power and computer
- * name change notifications.
- * sysEventPowerNotifier() - Handle power notification events.
- * sysEventConfigurationNotifier() - Computer name changed notification
- * callback.
- * sysEventTimerNotifier() - Handle delayed event notifications.
- * sysUpdate() - Update the current system state.
+ * 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/".
*/
@@ -37,42 +19,28 @@
*/
#include "cupsd.h"
-#ifdef HAVE_VPROC_TRANSACTION_BEGIN
-# include <vproc.h>
-#endif /* HAVE_VPROC_TRANSACTION_BEGIN */
#ifdef __APPLE__
+# include <vproc.h>
# include <IOKit/pwr_mgt/IOPMLib.h>
-# ifdef HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H
-# include <IOKit/pwr_mgt/IOPMLibPrivate.h>
-# endif /* HAVE_IOKIT_PWR_MGT_IOPMLIBPRIVATE_H */
#endif /* __APPLE__ */
/*
* The system management functions cover disk and power management which
- * are primarily used on portable computers.
+ * are primarily used for portable computers.
*
* Disk management involves delaying the write of certain configuration
* and state files to minimize the number of times the disk has to spin
- * up.
+ * up or flash to be written to.
*
- * Power management support is currently only implemented on MacOS X, but
+ * Power management support is currently only implemented on OS X, but
* essentially we use four functions to let the OS know when it is OK to
* put the system to sleep, typically when we are not in the middle of
- * printing a job.
- *
- * Once put to sleep, we invalidate all remote printers since it is common
- * to wake up in a new location/on a new wireless network.
+ * printing a job. And on OS X we can also "sleep print" - basically the
+ * system only wakes up long enough to service network requests and process
+ * print jobs.
*/
-/*
- * Local globals...
- */
-
-#ifdef kIOPMAssertionTypeDenySystemSleep
-static IOPMAssertionID dark_wake = 0; /* "Dark wake" assertion for sharing */
-#endif /* kIOPMAssertionTypeDenySystemSleep */
-
/*
* 'cupsdCleanDirty()' - Write dirty config and state files.
@@ -162,9 +130,10 @@ cupsdSetBusyState(void)
"Active clients and printing jobs",
"Active clients, printing jobs, and dirty files"
};
-#ifdef HAVE_VPROC_TRANSACTION_BEGIN
+#ifdef __APPLE__
static vproc_transaction_t vtran = 0; /* Current busy transaction */
-#endif /* HAVE_VPROC_TRANSACTION_BEGIN */
+ static IOPMAssertionID keep_awake = 0;/* Keep the system awake while printing */
+#endif /* __APPLE__ */
/*
@@ -204,7 +173,7 @@ cupsdSetBusyState(void)
{
busy = newbusy;
-#ifdef HAVE_VPROC_TRANSACTION_BEGIN
+#ifdef __APPLE__
if (busy && !vtran)
vtran = vproc_transaction_begin(NULL);
else if (!busy && vtran)
@@ -212,24 +181,25 @@ cupsdSetBusyState(void)
vproc_transaction_end(NULL, vtran);
vtran = 0;
}
-#endif /* HAVE_VPROC_TRANSACTION_BEGIN */
+#endif /* __APPLE__ */
}
-#ifdef kIOPMAssertionTypeDenySystemSleep
- if (cupsArrayCount(PrintingJobs) > 0 && !dark_wake)
+#ifdef __APPLE__
+ if (cupsArrayCount(PrintingJobs) > 0 && !keep_awake)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Asserting dark wake.");
- IOPMAssertionCreateWithName(kIOPMAssertionTypeDenySystemSleep,
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Asserting NetworkClientActive.");
+
+ IOPMAssertionCreateWithName(kIOPMAssertNetworkClientActive,
kIOPMAssertionLevelOn,
- CFSTR("org.cups.cupsd"), &dark_wake);
+ CFSTR("org.cups.cupsd"), &keep_awake);
}
- else if (cupsArrayCount(PrintingJobs) == 0 && dark_wake)
+ else if (cupsArrayCount(PrintingJobs) == 0 && keep_awake)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Releasing dark wake assertion.");
- IOPMAssertionRelease(dark_wake);
- dark_wake = 0;
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Releasing power assertion.");
+ IOPMAssertionRelease(keep_awake);
+ keep_awake = 0;
}
-#endif /* kIOPMAssertionTypeDenySystemSleep */
+#endif /* __APPLE__ */
}
@@ -244,8 +214,10 @@ cupsdSetBusyState(void)
* Include MacOS-specific headers...
*/
+# include <notify.h>
# include <IOKit/IOKitLib.h>
# include <IOKit/IOMessage.h>
+# include <IOKit/ps/IOPowerSources.h>
# include <IOKit/pwr_mgt/IOPMLib.h>
# include <SystemConfiguration/SystemConfiguration.h>
# include <pthread.h>
@@ -310,6 +282,8 @@ static CFStringRef ComputerNameKey = NULL,
NetworkInterfaceKeyIPv6 = NULL;
/* Netowrk interface key */
static cupsd_sysevent_t LastSysEvent; /* Last system event (for delayed sleep) */
+static int NameChanged = 0;/* Did we get a 'name changed' event during sleep? */
+static int PSToken = 0; /* Power source notifications */
/*
@@ -325,6 +299,7 @@ static void sysEventConfigurationNotifier(SCDynamicStoreRef store,
void *context);
static void sysEventTimerNotifier(CFRunLoopTimerRef timer, void *context);
static void sysUpdate(void);
+static void sysUpdateNames(void);
/*
@@ -336,6 +311,7 @@ cupsdAllowSleep(void)
{
cupsdCleanDirty();
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Allowing system sleep.");
IOAllowPowerChange(LastSysEvent.powerKernelPort,
LastSysEvent.powerNotificationID);
}
@@ -351,6 +327,8 @@ cupsdStartSystemMonitor(void)
int flags; /* fcntl flags on pipe */
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartSystemMonitor()");
+
if (cupsdOpenPipe(SysEventPipes))
{
cupsdLogMessage(CUPSD_LOG_ERROR, "System event monitor pipe() failed - %s!",
@@ -375,6 +353,15 @@ cupsdStartSystemMonitor(void)
pthread_mutex_init(&SysEventThreadMutex, NULL);
pthread_cond_init(&SysEventThreadCond, NULL);
pthread_create(&SysEventThread, NULL, (void *(*)())sysEventThreadEntry, NULL);
+
+ /*
+ * Monitor for power source changes via dispatch queue...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartSystemMonitor: IOPSGetTimeRemainingEstimate=%f", IOPSGetTimeRemainingEstimate());
+ ACPower = IOPSGetTimeRemainingEstimate() == kIOPSTimeRemainingUnlimited;
+ notify_register_dispatch(kIOPSNotifyPowerSource, &PSToken, dispatch_get_main_queue(), ^(int t) { (void)t;
+ ACPower = IOPSGetTimeRemainingEstimate() == kIOPSTimeRemainingUnlimited; });
}
@@ -388,6 +375,8 @@ cupsdStopSystemMonitor(void)
CFRunLoopRef rl; /* The event handler runloop */
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStopSystemMonitor()");
+
if (SysEventThread)
{
/*
@@ -418,6 +407,12 @@ cupsdStopSystemMonitor(void)
cupsdRemoveSelect(SysEventPipes[0]);
cupsdClosePipe(SysEventPipes);
}
+
+ if (PSToken != 0)
+ {
+ notify_cancel(PSToken);
+ PSToken = 0;
+ }
}
@@ -658,18 +653,19 @@ sysEventPowerNotifier(
switch (messageType)
{
- case kIOMessageCanSystemPowerOff:
- case kIOMessageCanSystemSleep:
+ case kIOMessageCanSystemPowerOff :
+ case kIOMessageCanSystemSleep :
threadData->sysevent.event |= SYSEVENT_CANSLEEP;
break;
- case kIOMessageSystemWillRestart:
- case kIOMessageSystemWillPowerOff:
- case kIOMessageSystemWillSleep:
+ case kIOMessageSystemWillRestart :
+ case kIOMessageSystemWillPowerOff :
+ case kIOMessageSystemWillSleep :
threadData->sysevent.event |= SYSEVENT_WILLSLEEP;
+ threadData->sysevent.event &= ~SYSEVENT_WOKE;
break;
- case kIOMessageSystemHasPoweredOn:
+ case kIOMessageSystemHasPoweredOn :
/*
* Because powered on is followed by a net-changed event, delay
* before sending it.
@@ -679,16 +675,62 @@ sysEventPowerNotifier(
threadData->sysevent.event |= SYSEVENT_WOKE;
break;
- case kIOMessageSystemWillNotPowerOff:
- case kIOMessageSystemWillNotSleep:
+ case kIOMessageSystemWillNotPowerOff :
+ case kIOMessageSystemWillNotSleep :
# ifdef kIOMessageSystemWillPowerOn
- case kIOMessageSystemWillPowerOn:
+ case kIOMessageSystemWillPowerOn :
# endif /* kIOMessageSystemWillPowerOn */
default:
sendit = 0;
break;
}
+ switch (messageType)
+ {
+ case kIOMessageCanSystemPowerOff :
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Got kIOMessageCanSystemPowerOff message.");
+ break;
+ case kIOMessageCanSystemSleep :
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Got kIOMessageCannSystemSleep message.");
+ break;
+ case kIOMessageSystemWillRestart :
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Got kIOMessageSystemWillRestart message.");
+ break;
+ case kIOMessageSystemWillPowerOff :
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Got kIOMessageSystemWillPowerOff message.");
+ break;
+ case kIOMessageSystemWillSleep :
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Got kIOMessageSystemWillSleep message.");
+ break;
+ case kIOMessageSystemHasPoweredOn :
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Got kIOMessageSystemHasPoweredOn message.");
+ break;
+ case kIOMessageSystemWillNotPowerOff :
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Got kIOMessageSystemWillNotPowerOff message.");
+ break;
+ case kIOMessageSystemWillNotSleep :
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Got kIOMessageSystemWillNotSleep message.");
+ break;
+# ifdef kIOMessageSystemWillPowerOn
+ case kIOMessageSystemWillPowerOn :
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Got kIOMessageSystemWillPowerOn message.");
+ break;
+# endif /* kIOMessageSystemWillPowerOn */
+ default:
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Got unknown power message %d.",
+ (int)messageType);
+ break;
+ }
+
if (sendit == 0)
IOAllowPowerChange(threadData->sysevent.powerKernelPort,
(long)messageArgument);
@@ -816,8 +858,9 @@ sysUpdate(void)
{
/*
* If there are active printers that don't have the connecting-to-device
- * printer-state-reason then cancel the sleep request (i.e. this reason
- * indicates a job that is not yet connected to the printer)...
+ * or cups-waiting-for-job-completed printer-state-reason then cancel the
+ * sleep request, i.e., these reasons indicate a job that is not actively
+ * doing anything...
*/
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
@@ -827,7 +870,8 @@ sysUpdate(void)
if (p->job)
{
for (i = 0; i < p->num_reasons; i ++)
- if (!strcmp(p->reasons[i], "connecting-to-device"))
+ if (!strcmp(p->reasons[i], "connecting-to-device") ||
+ !strcmp(p->reasons[i], "cups-waiting-for-job-completed"))
break;
if (!p->num_reasons || i >= p->num_reasons)
@@ -838,14 +882,14 @@ sysUpdate(void)
if (p)
{
cupsdLogMessage(CUPSD_LOG_INFO,
- "System sleep canceled because printer %s is active",
+ "System sleep canceled because printer %s is active.",
p->name);
IOCancelPowerChange(sysevent.powerKernelPort,
sysevent.powerNotificationID);
}
else
{
- cupsdLogMessage(CUPSD_LOG_DEBUG, "System wants to sleep");
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "System wants to sleep.");
IOAllowPowerChange(sysevent.powerKernelPort,
sysevent.powerNotificationID);
}
@@ -853,50 +897,30 @@ sysUpdate(void)
if (sysevent.event & SYSEVENT_WILLSLEEP)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG, "System going to sleep");
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "System going to sleep.");
Sleeping = 1;
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Deregistering local printer \"%s\"", p->name);
- cupsdDeregisterPrinter(p, 0);
- }
-
cupsdCleanDirty();
-#ifdef kIOPMAssertionTypeDenySystemSleep
- /*
- * Remove our assertion as needed since the user wants the system to
- * sleep (different than idle sleep)...
- */
-
- if (dark_wake)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Releasing dark wake assertion.");
- IOPMAssertionRelease(dark_wake);
- dark_wake = 0;
- }
-#endif /* kIOPMAssertionTypeDenySystemSleep */
-
/*
* If we have no printing jobs, allow the power change immediately.
- * Otherwise set the SleepJobs time to 15 seconds in the future when
+ * Otherwise set the SleepJobs time to 10 seconds in the future when
* we'll take more drastic measures...
*/
if (cupsArrayCount(PrintingJobs) == 0)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Allowing system sleep.");
IOAllowPowerChange(sysevent.powerKernelPort,
sysevent.powerNotificationID);
+ }
else
{
/*
* If there are active printers that don't have the connecting-to-device
- * printer-state-reason then delay the sleep request (i.e. this reason
- * indicates a job that is not yet connected to the printer)...
+ * or cups-waiting-for-job-completed printer-state-reasons then delay the
+ * sleep request, i.e., these reasons indicate a job is active...
*/
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
@@ -906,7 +930,8 @@ sysUpdate(void)
if (p->job)
{
for (i = 0; i < p->num_reasons; i ++)
- if (!strcmp(p->reasons[i], "connecting-to-device"))
+ if (!strcmp(p->reasons[i], "connecting-to-device") ||
+ !strcmp(p->reasons[i], "cups-waiting-for-job-completed"))
break;
if (!p->num_reasons || i >= p->num_reasons)
@@ -916,11 +941,16 @@ sysUpdate(void)
if (p)
{
+ cupsdLogMessage(CUPSD_LOG_INFO,
+ "System sleep delayed because printer %s is active.",
+ p->name);
+
LastSysEvent = sysevent;
SleepJobs = time(NULL) + 10;
}
else
{
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Allowing system sleep.");
IOAllowPowerChange(sysevent.powerKernelPort,
sysevent.powerNotificationID);
}
@@ -929,78 +959,118 @@ sysUpdate(void)
if (sysevent.event & SYSEVENT_WOKE)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG, "System woke from sleep");
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "System woke from sleep.");
IOAllowPowerChange(sysevent.powerKernelPort,
sysevent.powerNotificationID);
Sleeping = 0;
-#ifdef kIOPMAssertionTypeDenySystemSleep
- if (cupsArrayCount(PrintingJobs) > 0 && !dark_wake)
+ /*
+ * Make sure jobs that were queued prior to the system going to sleep don't
+ * get canceled right away...
+ */
+
+ if (MaxJobTime > 0)
{
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Asserting dark wake.");
- IOPMAssertionCreateWithName(kIOPMAssertionTypeDenySystemSleep,
- kIOPMAssertionLevelOn,
- CFSTR("org.cups.cupsd"), &dark_wake);
+ cupsd_job_t *job; /* Current job */
+
+ for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
+ job;
+ job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
+ {
+ if (job->cancel_time)
+ {
+ ipp_attribute_t *cancel_after = ippFindAttribute(job->attrs,
+ "job-cancel-after",
+ IPP_TAG_INTEGER);
+
+ if (cancel_after)
+ job->cancel_time = time(NULL) + ippGetInteger(cancel_after, 0);
+ else
+ job->cancel_time = time(NULL) + MaxJobTime;
+ }
+ }
}
-#endif /* kIOPMAssertionTypeDenySystemSleep */
+
+ if (NameChanged)
+ sysUpdateNames();
cupsdCheckJobs();
}
if (sysevent.event & SYSEVENT_NETCHANGED)
{
- if (!Sleeping)
+ if (Sleeping)
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "System network configuration changed");
+ "System network configuration changed - "
+ "ignored while sleeping.");
else
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "System network configuration changed; "
- "ignored while sleeping");
+ "System network configuration changed.");
}
if (sysevent.event & SYSEVENT_NAMECHANGED)
{
- if (!Sleeping)
+ if (Sleeping)
+ {
+ NameChanged = 1;
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "Computer name or BTMM domains changed - ignored while "
+ "sleeping.");
+ }
+ else
{
cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Computer name or BTMM domains changed");
+ "Computer name or BTMM domains changed.");
- /*
- * De-register the individual printers...
- */
+ sysUpdateNames();
+ }
+ }
+ }
+}
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- cupsdDeregisterPrinter(p, 1);
+
+/*
+ * 'sysUpdateNames()' - Update computer and/or BTMM domains.
+ */
+
+static void
+sysUpdateNames(void)
+{
+ cupsd_printer_t *p; /* Current printer */
+
+
+ NameChanged = 0;
+
+ /*
+ * De-register the individual printers...
+ */
+
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
+ p;
+ p = (cupsd_printer_t *)cupsArrayNext(Printers))
+ cupsdDeregisterPrinter(p, 1);
# if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
- /*
- * Update the computer name and BTMM domain list...
- */
+ /*
+ * Update the computer name and BTMM domain list...
+ */
- cupsdUpdateDNSSDName();
+ cupsdUpdateDNSSDName();
# endif /* HAVE_DNSSD || HAVE_AVAHI */
- /*
- * Now re-register them...
- */
+ /*
+ * Now re-register them...
+ */
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
- p;
- p = (cupsd_printer_t *)cupsArrayNext(Printers))
- cupsdRegisterPrinter(p);
- }
- else
- cupsdLogMessage(CUPSD_LOG_DEBUG,
- "Computer name or BTMM domains changed; ignored while "
- "sleeping");
- }
- }
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
+ p;
+ p = (cupsd_printer_t *)cupsArrayNext(Printers))
+ cupsdRegisterPrinter(p);
}
#endif /* __APPLE__ */
/*
- * End of "$Id: sysman.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: sysman.c 12236 2014-11-03 04:08:41Z msweet $".
*/
diff --git a/scheduler/sysman.h b/scheduler/sysman.h
index d603178..9da386d 100644
--- a/scheduler/sysman.h
+++ b/scheduler/sysman.h
@@ -1,16 +1,16 @@
/*
- * "$Id: sysman.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: sysman.h 12140 2014-08-30 01:51:22Z msweet $"
*
- * System management definitions for the CUPS scheduler.
+ * System management definitions for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 2006 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2006 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * 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/".
*/
/*
@@ -35,7 +35,9 @@ VAR int DirtyFiles VALUE(CUPSD_DIRTY_NONE),
/* How often do we write dirty files? */
VAR time_t DirtyCleanTime VALUE(0);
/* When to clean dirty files next */
-VAR int Sleeping VALUE(0);
+VAR int ACPower VALUE(-1),
+ /* Is the system on AC power? */
+ Sleeping VALUE(0);
/* Non-zero if machine is entering or *
* in a sleep state... */
VAR time_t SleepJobs VALUE(0);
@@ -60,5 +62,5 @@ extern void cupsdStopSystemMonitor(void);
/*
- * End of "$Id: sysman.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: sysman.h 12140 2014-08-30 01:51:22Z msweet $".
*/
diff --git a/scheduler/testlpd.c b/scheduler/testlpd.c
index 3ff483e..a614ec4 100644
--- a/scheduler/testlpd.c
+++ b/scheduler/testlpd.c
@@ -1,27 +1,16 @@
/*
- * "$Id: testlpd.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: testlpd.c 12644 2015-05-19 21:22:35Z msweet $"
*
- * cups-lpd test program for CUPS.
+ * cups-lpd test program for CUPS.
*
- * Copyright 2007-2010 by Apple Inc.
- * Copyright 2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 by Apple Inc.
+ * Copyright 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() - Simulate an LPD client.
- * do_command() - Send the LPD command and wait for a response.
- * print_job() - Submit a file for printing.
- * print_waiting() - Print waiting jobs.
- * remove_job() - Cancel a print job.
- * status_long() - Show the long printer status.
- * status_short() - Show the short printer status.
- * usage() - Show program usage...
+ * 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/".
*/
/*
@@ -42,11 +31,11 @@
*/
static int do_command(int outfd, int infd, const char *command);
-static int print_job(int outfd, int infd, char *dest, char **args);
+static int print_job(int outfd, int infd, char *dest, char **args) __attribute__((nonnull(4)));
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 int remove_job(int outfd, int infd, char *dest, char **args) __attribute__((nonnull(4)));
+static int status_long(int outfd, int infd, char *dest, char **args) __attribute__((nonnull(4)));
+static int status_short(int outfd, int infd, char *dest, char **args) __attribute__((nonnull(4)));
static void usage(void) __attribute__((noreturn));
@@ -76,7 +65,7 @@ main(int argc, /* I - Number of command-line arguments */
*/
op = NULL;
- opargs = NULL;
+ opargs = argv + argc;
dest = NULL;
cupslpd_argc = 1;
cupslpd_argv[0] = (char *)"cups-lpd";
@@ -210,15 +199,15 @@ do_command(int outfd, /* I - Command file descriptor */
int infd, /* I - Response file descriptor */
const char *command) /* I - Command line to send */
{
- int len; /* Length of command line */
- char status; /* Status byte */
+ size_t len; /* Length of command line */
+ char status; /* Status byte */
printf("COMMAND: %02X %s", command[0], command + 1);
len = strlen(command);
- if (write(outfd, command, len) < len)
+ if ((size_t)write(outfd, command, len) < len)
{
puts(" Write failed!");
return (-1);
@@ -251,7 +240,7 @@ print_job(int outfd, /* I - Command file descriptor */
struct stat fileinfo; /* File information */
char *jobname; /* Job name */
int sequence; /* Sequence number */
- int bytes; /* Bytes read/written */
+ ssize_t bytes; /* Bytes read/written */
/*
@@ -305,10 +294,10 @@ print_job(int outfd, /* I - Command file descriptor */
* Send the control file...
*/
- bytes = strlen(control);
+ bytes = (ssize_t)strlen(control);
snprintf(command, sizeof(command), "\002%d cfA%03dlocalhost\n",
- bytes, sequence);
+ (int)bytes, sequence);
if ((status = do_command(outfd, infd, command)) != 0)
{
@@ -318,14 +307,14 @@ print_job(int outfd, /* I - Command file descriptor */
bytes ++;
- if (write(outfd, control, bytes) < bytes)
+ if (write(outfd, control, (size_t)bytes) < bytes)
{
- printf("CONTROL: Unable to write %d bytes!\n", bytes);
+ printf("CONTROL: Unable to write %d bytes!\n", (int)bytes);
close(fd);
return (-1);
}
- printf("CONTROL: Wrote %d bytes.\n", bytes);
+ printf("CONTROL: Wrote %d bytes.\n", (int)bytes);
if (read(infd, command, 1) < 1)
{
@@ -355,9 +344,9 @@ print_job(int outfd, /* I - Command file descriptor */
while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
{
- if (write(outfd, buffer, bytes) < bytes)
+ if (write(outfd, buffer, (size_t)bytes) < bytes)
{
- printf("DATA: Unable to write %d bytes!\n", bytes);
+ printf("DATA: Unable to write %d bytes!\n", (int)bytes);
close(fd);
return (-1);
}
@@ -451,21 +440,21 @@ status_long(int outfd, /* I - Command file descriptor */
{
char command[1024], /* Command buffer */
buffer[8192]; /* Status buffer */
- int bytes; /* Bytes read/written */
+ ssize_t bytes; /* Bytes read/written */
/*
* Send the "send short status" command...
*/
- if (args)
+ if (args[0])
snprintf(command, sizeof(command), "\004%s %s\n", dest, args[0]);
else
snprintf(command, sizeof(command), "\004%s\n", dest);
- bytes = strlen(command);
+ bytes = (ssize_t)strlen(command);
- if (write(outfd, command, bytes) < bytes)
+ if (write(outfd, command, (size_t)bytes) < bytes)
return (-1);
/*
@@ -474,7 +463,7 @@ status_long(int outfd, /* I - Command file descriptor */
while ((bytes = read(infd, buffer, sizeof(buffer))) > 0)
{
- fwrite(buffer, 1, bytes, stdout);
+ fwrite(buffer, 1, (size_t)bytes, stdout);
fflush(stdout);
}
@@ -494,21 +483,21 @@ status_short(int outfd, /* I - Command file descriptor */
{
char command[1024], /* Command buffer */
buffer[8192]; /* Status buffer */
- int bytes; /* Bytes read/written */
+ ssize_t bytes; /* Bytes read/written */
/*
* Send the "send short status" command...
*/
- if (args)
+ if (args[0])
snprintf(command, sizeof(command), "\003%s %s\n", dest, args[0]);
else
snprintf(command, sizeof(command), "\003%s\n", dest);
- bytes = strlen(command);
+ bytes = (ssize_t)strlen(command);
- if (write(outfd, command, bytes) < bytes)
+ if (write(outfd, command, (size_t)bytes) < bytes)
return (-1);
/*
@@ -517,7 +506,7 @@ status_short(int outfd, /* I - Command file descriptor */
while ((bytes = read(infd, buffer, sizeof(buffer))) > 0)
{
- fwrite(buffer, 1, bytes, stdout);
+ fwrite(buffer, 1, (size_t)bytes, stdout);
fflush(stdout);
}
@@ -546,5 +535,5 @@ usage(void)
/*
- * End of "$Id: testlpd.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: testlpd.c 12644 2015-05-19 21:22:35Z msweet $".
*/
diff --git a/scheduler/testmime.c b/scheduler/testmime.c
index 5a71ea9..0271309 100644
--- a/scheduler/testmime.c
+++ b/scheduler/testmime.c
@@ -1,24 +1,16 @@
/*
- * "$Id: testmime.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: testmime.c 11558 2014-02-06 18:33:34Z msweet $"
*
- * MIME test program for CUPS.
+ * MIME test program for CUPS.
*
- * Copyright 2007-2013 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2014 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() - Main entry for the test program.
- * add_ppd_filter() - Add a printer filter from a PPD.
- * add_ppd_filters() - Add all filters from a PPD.
- * print_rules() - Print the rules for a file type...
- * type_dir() - Show the MIME types for a given directory.
+ * 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/".
*/
/*
@@ -135,7 +127,7 @@ main(int argc, /* I - Number of command-line args */
sscanf(argv[i], "%15[^/]/%255s", super, type);
dst = mimeType(mime, super, type);
- filters = mimeFilter2(mime, src, srcinfo.st_size, dst, &cost);
+ filters = mimeFilter2(mime, src, (size_t)srcinfo.st_size, dst, &cost);
if (!filters)
{
@@ -264,7 +256,7 @@ add_ppd_filter(mime_t *mime, /* I - MIME database */
{
char *ptr; /* Pointer into maxsize(nnnn) program */
- maxsize = strtoll(program + 8, &ptr, 10);
+ maxsize = (size_t)strtoll(program + 8, &ptr, 10);
if (*ptr != ')')
{
@@ -527,5 +519,5 @@ type_dir(mime_t *mime, /* I - MIME database */
/*
- * End of "$Id: testmime.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: testmime.c 11558 2014-02-06 18:33:34Z msweet $".
*/
diff --git a/scheduler/testspeed.c b/scheduler/testspeed.c
index 425f471..9b443cb 100644
--- a/scheduler/testspeed.c
+++ b/scheduler/testspeed.c
@@ -1,23 +1,16 @@
/*
- * "$Id: testspeed.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: testspeed.c 11558 2014-02-06 18:33:34Z msweet $"
*
- * Scheduler speed test for CUPS.
+ * Scheduler speed test for CUPS.
*
- * Copyright 2007-2010 by Apple Inc.
- * Copyright 1997-2005 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2005 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * main() - Send multiple IPP requests and report on the average response
- * time.
- * do_test() - Run a test on a specific host...
- * usage() - Show program usage...
+ * 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/".
*/
/*
@@ -39,7 +32,7 @@
static int do_test(const char *server, int port,
http_encryption_t encryption, int requests,
- int verbose);
+ const char *opstring, int verbose);
static void usage(void) __attribute__((noreturn));
@@ -66,6 +59,7 @@ main(int argc, /* I - Number of command-line arguments */
end; /* End time */
double elapsed; /* Elapsed time */
int verbose; /* Verbosity */
+ const char *opstring; /* Operation name */
/*
@@ -78,6 +72,7 @@ main(int argc, /* I - Number of command-line arguments */
port = ippPort();
encryption = HTTP_ENCRYPT_IF_REQUESTED;
verbose = 0;
+ opstring = NULL;
for (i = 1; i < argc; i ++)
if (argv[i][0] == '-')
@@ -85,6 +80,10 @@ main(int argc, /* I - Number of command-line arguments */
for (ptr = argv[i] + 1; *ptr; ptr ++)
switch (*ptr)
{
+ case 'E' : /* Enable encryption */
+ encryption = HTTP_ENCRYPT_REQUIRED;
+ break;
+
case 'c' : /* Number of children */
i ++;
if (i >= argc)
@@ -93,16 +92,20 @@ main(int argc, /* I - Number of command-line arguments */
children = atoi(argv[i]);
break;
- case 'r' : /* Number of requests */
+ case 'o' : /* Operation */
i ++;
if (i >= argc)
usage();
- requests = atoi(argv[i]);
+ opstring = argv[i];
break;
- case 'E' : /* Enable encryption */
- encryption = HTTP_ENCRYPT_REQUIRED;
+ case 'r' : /* Number of requests */
+ i ++;
+ if (i >= argc)
+ usage();
+
+ requests = atoi(argv[i]);
break;
case 'v' : /* Verbose logging */
@@ -139,9 +142,10 @@ main(int argc, /* I - Number of command-line arguments */
start = time(NULL);
if (children < 1)
- return (do_test(server, port, encryption, requests, verbose));
+ return (do_test(server, port, encryption, requests, opstring, verbose));
else if (children == 1)
- good_children = do_test(server, port, encryption, requests, verbose) ? 0 : 1;
+ good_children = do_test(server, port, encryption, requests, opstring,
+ verbose) ? 0 : 1;
else
{
char options[255], /* Command-line options for child */
@@ -174,7 +178,12 @@ main(int argc, /* I - Number of command-line arguments */
* Child goes here...
*/
- execlp(argv[0], argv[0], options, "0", reqstr, serverstr, (char *)NULL);
+ if (opstring)
+ execlp(argv[0], argv[0], options, "0", reqstr, "-o", opstring,
+ serverstr, (char *)NULL);
+ else
+ execlp(argv[0], argv[0], options, "0", reqstr, serverstr, (char *)NULL);
+
exit(errno);
}
else if (pid < 0)
@@ -237,6 +246,7 @@ do_test(const char *server, /* I - Server to use */
int port, /* I - Port number to use */
http_encryption_t encryption, /* I - Encryption to use */
int requests, /* I - Number of requests to send */
+ const char *opstring, /* I - Operation string */
int verbose) /* I - Verbose output? */
{
int i; /* Looping var */
@@ -247,9 +257,10 @@ do_test(const char *server, /* I - Server to use */
double reqtime, /* Time for this request */
elapsed; /* Elapsed time */
int op; /* Current operation */
- static ipp_op_t ops[4] = /* Operations to test... */
+ static ipp_op_t ops[5] = /* Operations to test... */
{
IPP_PRINT_JOB,
+ CUPS_GET_DEFAULT,
CUPS_GET_PRINTERS,
CUPS_GET_CLASSES,
IPP_GET_JOBS
@@ -282,7 +293,11 @@ do_test(const char *server, /* I - Server to use */
* In addition, IPP_GET_JOBS needs a printer-uri attribute.
*/
- op = ops[i & 3];
+ if (opstring)
+ op = ippOpValue(opstring);
+ else
+ op = ops[i % (int)(sizeof(ops) / sizeof(ops[0]))];
+
request = ippNewRequest(op);
gettimeofday(&start, NULL);
@@ -353,13 +368,13 @@ do_test(const char *server, /* I - Server to use */
static void
usage(void)
{
- puts("Usage: testspeed [-c children] [-h] [-r requests] [-v] [-E] "
- "hostname[:port]");
+ puts("Usage: testspeed [-c children] [-h] [-o operation] [-r requests] [-v] "
+ "[-E] hostname[:port]");
exit(0);
}
/*
- * End of "$Id: testspeed.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: testspeed.c 11558 2014-02-06 18:33:34Z msweet $".
*/
diff --git a/scheduler/testsub.c b/scheduler/testsub.c
index 66801af..97a3a83 100644
--- a/scheduler/testsub.c
+++ b/scheduler/testsub.c
@@ -1,23 +1,16 @@
/*
- * "$Id: testsub.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: testsub.c 11889 2014-05-22 13:54:15Z msweet $"
*
- * Scheduler notification tester for CUPS.
+ * Scheduler notification tester for CUPS.
*
- * Copyright 2007-2012 by Apple Inc.
- * Copyright 2006-2007 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2006-2007 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * main() - Subscribe to the .
- * print_attributes() - Print the attributes in a request...
- * sigterm_handler() - Flag when the user hits CTRL-C...
- * usage() - Show program usage...
+ * 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/".
*/
/*
@@ -251,7 +244,7 @@ main(int argc, /* I - Number of command-line arguments */
interval = 5;
ippDelete(response);
- sleep(interval);
+ sleep((unsigned)interval);
}
/*
@@ -435,17 +428,10 @@ print_attributes(ipp_t *ipp, /* I - IPP request */
case IPP_TAG_DATE :
{
- time_t vtime; /* Date/Time value */
- struct tm *vdate; /* Date info */
char vstring[256]; /* Formatted time */
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
- {
- vtime = ippDateToTime(val->date);
- vdate = localtime(&vtime);
- strftime(vstring, sizeof(vstring), "%c", vdate);
- printf(" (%s)", vstring);
- }
+ printf(" (%s)", _cupsStrDate(vstring, sizeof(vstring), ippDateToTime(val->date)));
}
putchar('\n');
break;
@@ -519,5 +505,5 @@ usage(void)
/*
- * End of "$Id: testsub.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: testsub.c 11889 2014-05-22 13:54:15Z msweet $".
*/
diff --git a/scheduler/tls-darwin.c b/scheduler/tls-darwin.c
deleted file mode 100644
index bb6998b..0000000
--- a/scheduler/tls-darwin.c
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * "$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
deleted file mode 100644
index c2d7032..0000000
--- a/scheduler/tls-gnutls.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * "$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
deleted file mode 100644
index f123d28..0000000
--- a/scheduler/tls-openssl.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * "$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
deleted file mode 100644
index bd18263..0000000
--- a/scheduler/tls.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * "$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 bf014be..68ed07e 100644
--- a/scheduler/type.c
+++ b/scheduler/type.c
@@ -1,26 +1,16 @@
/*
- * "$Id: type.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: type.c 12577 2015-03-30 19:07:17Z msweet $"
*
- * MIME typing routines for CUPS.
+ * MIME typing routines for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2015 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:
- *
- * mimeAddType() - Add a MIME type to a database.
- * mimeAddTypeRule() - Add a detection rule for a file type.
- * mimeFileType() - Determine the type of a file.
- * mimeType() - Lookup a file type.
- * mime_compare_types() - Compare two MIME super/type names.
- * mime_check_rules() - Check each rule in a list.
- * mime_patmatch() - Pattern matching.
+ * 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/".
*/
/*
@@ -319,7 +309,7 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
*/
ptr = name;
- while (isalnum(*rule & 255) && (ptr - name) < (sizeof(name) - 1))
+ while (isalnum(*rule & 255) && (size_t)(ptr - name) < (sizeof(name) - 1))
*ptr++ = *rule++;
*ptr = '\0';
@@ -332,12 +322,12 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
rule ++;
for (num_values = 0;
- num_values < (sizeof(value) / sizeof(value[0]));
+ num_values < (int)(sizeof(value) / sizeof(value[0]));
num_values ++)
{
ptr = value[num_values];
- while ((ptr - value[num_values]) < (sizeof(value[0]) - 1) &&
+ while ((size_t)(ptr - value[num_values]) < (sizeof(value[0]) - 1) &&
*rule != '\0' && *rule != ',' && *rule != ')')
{
if (isspace(*rule & 255))
@@ -358,7 +348,7 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
quote = *rule++;
while (*rule != '\0' && *rule != quote &&
- (ptr - value[num_values]) < (sizeof(value[0]) - 1))
+ (size_t)(ptr - value[num_values]) < (sizeof(value[0]) - 1))
*ptr++ = *rule++;
if (*rule == quote)
@@ -371,14 +361,14 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
rule ++;
while (*rule != '>' && *rule != '\0' &&
- (ptr - value[num_values]) < (sizeof(value[0]) - 1))
+ (size_t)(ptr - value[num_values]) < (sizeof(value[0]) - 1))
{
if (isxdigit(rule[0] & 255) && isxdigit(rule[1] & 255))
{
if (isdigit(*rule))
- *ptr = (*rule++ - '0') << 4;
+ *ptr = (char)((*rule++ - '0') << 4);
else
- *ptr = (tolower(*rule++) - 'a' + 10) << 4;
+ *ptr = (char)((tolower(*rule++) - 'a' + 10) << 4);
if (isdigit(*rule))
*ptr++ |= *rule++ - '0';
@@ -425,6 +415,8 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
op = MIME_MAGIC_ASCII;
else if (!strcmp(name, "printable"))
op = MIME_MAGIC_PRINTABLE;
+ else if (!strcmp(name, "regex"))
+ op = MIME_MAGIC_REGEX;
else if (!strcmp(name, "string"))
op = MIME_MAGIC_STRING;
else if (!strcmp(name, "istring"))
@@ -454,7 +446,7 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
*/
snprintf(value[0], sizeof(value[0]), "*.%s", name);
- length[0] = strlen(value[0]);
+ length[0] = (int)strlen(value[0]);
op = MIME_MAGIC_MATCH;
}
@@ -465,7 +457,7 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
if ((temp = calloc(1, sizeof(mime_magic_t))) == NULL)
return (-1);
- temp->invert = invert;
+ temp->invert = (short)invert;
if (current != NULL)
{
temp->parent = current->parent;
@@ -507,15 +499,15 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
*/
current = temp;
- temp->op = op;
+ temp->op = (short)op;
invert = 0;
switch (op)
{
case MIME_MAGIC_MATCH :
- if (length[0] > (sizeof(temp->value.matchv) - 1))
+ if ((size_t)length[0] > (sizeof(temp->value.matchv) - 1))
return (-1);
- strcpy(temp->value.matchv, value[0]);
+ strlcpy(temp->value.matchv, value[0], sizeof(temp->value.matchv));
break;
case MIME_MAGIC_ASCII :
case MIME_MAGIC_PRINTABLE :
@@ -524,18 +516,24 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
if (temp->length > MIME_MAX_BUFFER)
temp->length = MIME_MAX_BUFFER;
break;
+ case MIME_MAGIC_REGEX :
+ temp->offset = strtol(value[0], NULL, 0);
+ temp->length = MIME_MAX_BUFFER;
+ if (regcomp(&(temp->value.rev), value[1], REG_NOSUB | REG_EXTENDED))
+ return (-1);
+ break;
case MIME_MAGIC_STRING :
case MIME_MAGIC_ISTRING :
temp->offset = strtol(value[0], NULL, 0);
- if (length[1] > sizeof(temp->value.stringv))
+ if ((size_t)length[1] > sizeof(temp->value.stringv))
return (-1);
temp->length = length[1];
- memcpy(temp->value.stringv, value[1], length[1]);
+ memcpy(temp->value.stringv, value[1], (size_t)length[1]);
break;
case MIME_MAGIC_CHAR :
temp->offset = strtol(value[0], NULL, 0);
if (length[1] == 1)
- temp->value.charv = value[1][0];
+ temp->value.charv = (unsigned char)value[1][0];
else
temp->value.charv = (unsigned char)strtol(value[1], NULL, 0);
@@ -551,18 +549,18 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */
temp->value.intv = (unsigned)strtol(value[1], NULL, 0);
break;
case MIME_MAGIC_LOCALE :
- if (length[0] > (sizeof(temp->value.localev) - 1))
+ if ((size_t)length[0] > (sizeof(temp->value.localev) - 1))
return (-1);
- strcpy(temp->value.localev, value[0]);
+ strlcpy(temp->value.localev, value[0], sizeof(temp->value.localev));
break;
case MIME_MAGIC_CONTAINS :
temp->offset = strtol(value[0], NULL, 0);
temp->region = strtol(value[1], NULL, 0);
- if (length[2] > sizeof(temp->value.stringv))
+ if ((size_t)length[2] > sizeof(temp->value.stringv))
return (-1);
temp->length = length[2];
- memcpy(temp->value.stringv, value[2], length[2]);
+ memcpy(temp->value.stringv, value[2], (size_t)length[2]);
break;
}
}
@@ -615,8 +613,23 @@ mimeFileType(mime_t *mime, /* I - MIME database */
return (NULL);
}
- fb.offset = -1;
- fb.length = 0;
+ /*
+ * Then preload the first MIME_MAX_BUFFER bytes of the file into the file
+ * buffer, returning an error if we can't read anything...
+ */
+
+ fb.offset = 0;
+ fb.length = (int)cupsFileRead(fb.fp, (char *)fb.buffer, MIME_MAX_BUFFER);
+
+ if (fb.length <= 0)
+ {
+ DEBUG_printf(("1mimeFileType: Unable to read from \"%s\": %s", pathname, strerror(errno)));
+ DEBUG_puts("1mimeFileType: Returning NULL.");
+
+ cupsFileClose(fb.fp);
+
+ return (NULL);
+ }
/*
* Figure out the base filename (without directory portion)...
@@ -735,8 +748,8 @@ mime_check_rules(
int n; /* Looping var */
int region; /* Region to look at */
int logic, /* Logic to apply */
- result, /* Result of test */
- intv; /* Integer value */
+ result; /* Result of test */
+ unsigned intv; /* Integer value */
short shortv; /* Short value */
unsigned char *bufptr; /* Pointer into buffer */
@@ -782,6 +795,8 @@ mime_check_rules(
fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
sizeof(fb->buffer));
fb->offset = rules->offset;
+
+ DEBUG_printf(("4mime_check_rules: MIME_MAGIC_ASCII fb->length=%d", fb->length));
}
/*
@@ -824,6 +839,8 @@ mime_check_rules(
fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
sizeof(fb->buffer));
fb->offset = rules->offset;
+
+ DEBUG_printf(("4mime_check_rules: MIME_MAGIC_PRINTABLE fb->length=%d", fb->length));
}
/*
@@ -852,6 +869,52 @@ mime_check_rules(
result = (n == 0);
break;
+ case MIME_MAGIC_REGEX :
+ DEBUG_printf(("5mime_check_rules: regex(%d, \"%s\")", rules->offset,
+ rules->value.stringv));
+
+ /*
+ * Load the buffer if necessary...
+ */
+
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->length) > (fb->offset + fb->length))
+ {
+ /*
+ * Reload file buffer...
+ */
+
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
+
+ DEBUG_printf(("4mime_check_rules: MIME_MAGIC_REGEX fb->length=%d", fb->length));
+
+ DEBUG_printf(("5mime_check_rules: loaded %d byte fb->buffer at %d, starts "
+ "with \"%c%c%c%c\".",
+ fb->length, fb->offset, fb->buffer[0], fb->buffer[1],
+ fb->buffer[2], fb->buffer[3]));
+ }
+
+ /*
+ * Compare the buffer against the string. If the file is too
+ * short then don't compare - it can't match...
+ */
+
+ if (fb->length > 0)
+ {
+ char temp[MIME_MAX_BUFFER + 1];
+ /* Temporary buffer */
+
+ memcpy(temp, fb->buffer, (size_t)fb->length);
+ temp[fb->length] = '\0';
+ result = !regexec(&(rules->value.rev), temp, 0, NULL, 0);
+ }
+
+ DEBUG_printf(("5mime_check_rules: result=%d", result));
+ break;
+
case MIME_MAGIC_STRING :
DEBUG_printf(("5mime_check_rules: string(%d, \"%s\")", rules->offset,
rules->value.stringv));
@@ -872,6 +935,8 @@ mime_check_rules(
sizeof(fb->buffer));
fb->offset = rules->offset;
+ DEBUG_printf(("4mime_check_rules: MIME_MAGIC_STRING fb->length=%d", fb->length));
+
DEBUG_printf(("5mime_check_rules: loaded %d byte fb->buffer at %d, starts "
"with \"%c%c%c%c\".",
fb->length, fb->offset, fb->buffer[0], fb->buffer[1],
@@ -886,8 +951,7 @@ mime_check_rules(
if ((rules->offset + rules->length) > (fb->offset + fb->length))
result = 0;
else
- result = (memcmp(fb->buffer + rules->offset - fb->offset,
- rules->value.stringv, rules->length) == 0);
+ result = !memcmp(fb->buffer + rules->offset - fb->offset, rules->value.stringv, (size_t)rules->length);
DEBUG_printf(("5mime_check_rules: result=%d", result));
break;
@@ -907,6 +971,8 @@ mime_check_rules(
fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
sizeof(fb->buffer));
fb->offset = rules->offset;
+
+ DEBUG_printf(("4mime_check_rules: MIME_MAGIC_ISTRING fb->length=%d", fb->length));
}
/*
@@ -917,9 +983,7 @@ mime_check_rules(
if ((rules->offset + rules->length) > (fb->offset + fb->length))
result = 0;
else
- result = (_cups_strncasecmp((char *)fb->buffer + rules->offset -
- fb->offset,
- rules->value.stringv, rules->length) == 0);
+ result = !_cups_strncasecmp((char *)fb->buffer + rules->offset - fb->offset, rules->value.stringv, (size_t)rules->length);
break;
case MIME_MAGIC_CHAR :
@@ -937,6 +1001,8 @@ mime_check_rules(
fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
sizeof(fb->buffer));
fb->offset = rules->offset;
+
+ DEBUG_printf(("4mime_check_rules: MIME_MAGIC_CHAR fb->length=%d", fb->length));
}
/*
@@ -967,6 +1033,8 @@ mime_check_rules(
fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
sizeof(fb->buffer));
fb->offset = rules->offset;
+
+ DEBUG_printf(("4mime_check_rules: MIME_MAGIC_SHORT fb->length=%d", fb->length));
}
/*
@@ -979,7 +1047,7 @@ mime_check_rules(
else
{
bufptr = fb->buffer + rules->offset - fb->offset;
- shortv = (bufptr[0] << 8) | bufptr[1];
+ shortv = (short)((bufptr[0] << 8) | bufptr[1]);
result = (shortv == rules->value.shortv);
}
break;
@@ -1000,6 +1068,8 @@ mime_check_rules(
fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
sizeof(fb->buffer));
fb->offset = rules->offset;
+
+ DEBUG_printf(("4mime_check_rules: MIME_MAGIC_INT fb->length=%d", fb->length));
}
/*
@@ -1012,19 +1082,16 @@ mime_check_rules(
else
{
bufptr = fb->buffer + rules->offset - fb->offset;
- intv = (((((bufptr[0] << 8) | bufptr[1]) << 8) |
- bufptr[2]) << 8) | bufptr[3];
+ intv = (unsigned)((((((bufptr[0] << 8) | bufptr[1]) << 8) | bufptr[2]) << 8) | bufptr[3]);
result = (intv == rules->value.intv);
}
break;
case MIME_MAGIC_LOCALE :
#if defined(WIN32) || defined(__EMX__) || defined(__APPLE__)
- result = (strcmp(rules->value.localev,
- setlocale(LC_ALL, "")) == 0);
+ result = !strcmp(rules->value.localev, setlocale(LC_ALL, ""));
#else
- result = (strcmp(rules->value.localev,
- setlocale(LC_MESSAGES, "")) == 0);
+ result = !strcmp(rules->value.localev, setlocale(LC_MESSAGES, ""));
#endif /* __APPLE__ */
break;
@@ -1044,6 +1111,8 @@ mime_check_rules(
fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
sizeof(fb->buffer));
fb->offset = rules->offset;
+
+ DEBUG_printf(("4mime_check_rules: MIME_MAGIC_CONTAINS fb->length=%d", fb->length));
}
/*
@@ -1061,9 +1130,7 @@ mime_check_rules(
region = fb->length - rules->length;
for (n = 0; n < region; n ++)
- if ((result = (memcmp(fb->buffer + rules->offset - fb->offset + n,
- rules->value.stringv,
- rules->length) == 0)) != 0)
+ if ((result = (memcmp(fb->buffer + rules->offset - fb->offset + n, rules->value.stringv, (size_t)rules->length) == 0)) != 0)
break;
}
break;
@@ -1212,5 +1279,5 @@ mime_patmatch(const char *s, /* I - String to match against */
/*
- * End of "$Id: type.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: type.c 12577 2015-03-30 19:07:17Z msweet $".
*/
diff --git a/scheduler/util.c b/scheduler/util.c
index 74dd9ff..a31be2e 100644
--- a/scheduler/util.c
+++ b/scheduler/util.c
@@ -1,28 +1,16 @@
/*
- * "$Id: util.c 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: util.c 11558 2014-02-06 18:33:34Z msweet $"
*
- * Mini-daemon utility functions for CUPS.
+ * Mini-daemon utility functions for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2005 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2005 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * cupsdCompareNames() - Compare two names.
- * cupsdCreateStringsArray() - Create a CUPS array of strings.
- * cupsdExec() - Run a program with the correct environment.
- * cupsdPipeCommand() - Read output from a command.
- * cupsdSendIPPGroup() - Send a group tag.
- * cupsdSendIPPHeader() - Send the IPP response header.
- * cupsdSendIPPInteger() - Send an integer attribute.
- * cupsdSendIPPString() - Send a string attribute.
- * cupsdSendIPPTrailer() - Send the end-of-message tag.
+ * 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/".
*/
/*
@@ -163,7 +151,7 @@ cupsdCreateStringsArray(const char *s) /* I - Comma-delimited strings */
if (!s || !*s)
return (NULL);
else
- return (_cupsArrayNewStrings(s));
+ return (_cupsArrayNewStrings(s, ','));
}
@@ -251,7 +239,7 @@ cups_file_t * /* O - CUPS file or NULL on error */
cupsdPipeCommand(int *pid, /* O - Process ID or 0 on error */
const char *command, /* I - Command to run */
char **argv, /* I - Arguments to pass to command */
- int user) /* I - User to run as or 0 for current */
+ uid_t user) /* I - User to run as or 0 for current */
{
int fd, /* Temporary file descriptor */
fds[2]; /* Pipe file descriptors */
@@ -404,8 +392,8 @@ cupsdSendIPPInteger(
putchar(value_tag);
len = strlen(name);
- putchar(len >> 8);
- putchar(len);
+ putchar((int)(len >> 8));
+ putchar((int)len);
fputs(name, stdout);
@@ -441,14 +429,14 @@ cupsdSendIPPString(
putchar(value_tag);
len = strlen(name);
- putchar(len >> 8);
- putchar(len);
+ putchar((int)(len >> 8));
+ putchar((int)len);
fputs(name, stdout);
len = strlen(value);
- putchar(len >> 8);
- putchar(len);
+ putchar((int)(len >> 8));
+ putchar((int)len);
fputs(value, stdout);
}
@@ -467,5 +455,5 @@ cupsdSendIPPTrailer(void)
/*
- * End of "$Id: util.c 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: util.c 11558 2014-02-06 18:33:34Z msweet $".
*/
diff --git a/scheduler/util.h b/scheduler/util.h
index cf5ae0d..08b495c 100644
--- a/scheduler/util.h
+++ b/scheduler/util.h
@@ -1,16 +1,16 @@
/*
- * "$Id: util.h 11173 2013-07-23 12:31:34Z msweet $"
+ * "$Id: util.h 11558 2014-02-06 18:33:34Z msweet $"
*
- * Mini-daemon utility definitions for CUPS.
+ * Mini-daemon utility definitions for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2005 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2005 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * 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/".
*/
#ifndef _CUPSD_UTIL_H_
@@ -49,7 +49,7 @@ extern int cupsdCompareNames(const char *s, const char *t);
extern cups_array_t *cupsdCreateStringsArray(const char *s);
extern int cupsdExec(const char *command, char **argv);
extern cups_file_t *cupsdPipeCommand(int *pid, const char *command,
- char **argv, int user);
+ char **argv, uid_t user);
extern void cupsdSendIPPGroup(ipp_tag_t group_tag);
extern void cupsdSendIPPHeader(ipp_status_t status_code,
int request_id);
@@ -67,5 +67,5 @@ extern void cupsdSendIPPTrailer(void);
#endif /* !_CUPSD_UTIL_H_ */
/*
- * End of "$Id: util.h 11173 2013-07-23 12:31:34Z msweet $".
+ * End of "$Id: util.h 11558 2014-02-06 18:33:34Z msweet $".
*/