diff options
author | jlovell <jlovell@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2006-06-22 20:01:18 +0000 |
---|---|---|
committer | jlovell <jlovell@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2006-06-22 20:01:18 +0000 |
commit | ed4869111296da3b8514751fab9dffaa3146cb87 (patch) | |
tree | 2c70846273867a43b55920695412df4069c77efa /scheduler | |
parent | 9e22304f017970e9ba10cd593a1b07df4aafdabb (diff) |
Load cups into easysw/current.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@181 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'scheduler')
-rw-r--r-- | scheduler/Dependencies | 154 | ||||
-rw-r--r-- | scheduler/auth.c | 5 | ||||
-rw-r--r-- | scheduler/client.c | 38 | ||||
-rw-r--r-- | scheduler/conf.c | 150 | ||||
-rw-r--r-- | scheduler/dirsvc.c | 63 | ||||
-rw-r--r-- | scheduler/filter.c | 4 | ||||
-rw-r--r-- | scheduler/ipp.c | 553 | ||||
-rw-r--r-- | scheduler/job.c | 129 | ||||
-rw-r--r-- | scheduler/mime.c | 15 | ||||
-rw-r--r-- | scheduler/newselect.txt | 115 | ||||
-rw-r--r-- | scheduler/printers.c | 101 | ||||
-rw-r--r-- | scheduler/printers.h | 3 | ||||
-rw-r--r-- | scheduler/subscriptions.c | 374 | ||||
-rw-r--r-- | scheduler/subscriptions.h | 6 | ||||
-rw-r--r-- | scheduler/testmime.c | 2 |
15 files changed, 900 insertions, 812 deletions
diff --git a/scheduler/Dependencies b/scheduler/Dependencies index 7ca0a4300..f6e2042a2 100644 --- a/scheduler/Dependencies +++ b/scheduler/Dependencies @@ -4,169 +4,177 @@ auth.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h auth.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h auth.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h auth.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h -auth.o: ../cups/http.h ../cups/i18n.h ../cups/debug.h sysman.h statbuf.h -auth.o: cert.h auth.h client.h policy.h printers.h classes.h job.h conf.h -auth.o: banners.h dirsvc.h network.h subscriptions.h +auth.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h +auth.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h +auth.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h banners.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h banners.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h banners.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h banners.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -banners.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -banners.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -banners.o: classes.h job.h conf.h banners.h dirsvc.h network.h +banners.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +banners.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +banners.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h banners.o: subscriptions.h ../cups/dir.h cert.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h cert.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h cert.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h cert.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h -cert.o: ../cups/http.h ../cups/i18n.h ../cups/debug.h sysman.h statbuf.h -cert.o: cert.h auth.h client.h policy.h printers.h classes.h job.h conf.h -cert.o: banners.h dirsvc.h network.h subscriptions.h +cert.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h +cert.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h +cert.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h classes.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h classes.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h classes.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h classes.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -classes.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -classes.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -classes.o: classes.h job.h conf.h banners.h dirsvc.h network.h +classes.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +classes.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +classes.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h classes.o: subscriptions.h client.o: ../cups/http-private.h ../config.h ../cups/http.h ../cups/md5.h client.o: ../cups/ipp-private.h ../cups/ipp.h cupsd.h ../cups/string.h client.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h client.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -client.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -client.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -client.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h +client.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +client.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +client.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h +client.o: subscriptions.h conf.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h conf.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h conf.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h conf.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h -conf.o: ../cups/http.h ../cups/i18n.h ../cups/debug.h sysman.h statbuf.h -conf.o: cert.h auth.h client.h policy.h printers.h classes.h job.h conf.h -conf.o: banners.h dirsvc.h network.h subscriptions.h ../cups/dir.h +conf.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h +conf.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h +conf.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h +conf.o: ../cups/dir.h dirsvc.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h dirsvc.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h dirsvc.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h dirsvc.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -dirsvc.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -dirsvc.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -dirsvc.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h +dirsvc.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +dirsvc.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +dirsvc.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h +dirsvc.o: subscriptions.h env.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h env.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h env.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h env.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h -env.o: ../cups/http.h ../cups/i18n.h ../cups/debug.h sysman.h statbuf.h -env.o: cert.h auth.h client.h policy.h printers.h classes.h job.h conf.h -env.o: banners.h dirsvc.h network.h subscriptions.h +env.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h +env.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h +env.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h main.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h main.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h main.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h main.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h -main.o: ../cups/http.h ../cups/i18n.h ../cups/debug.h sysman.h statbuf.h -main.o: cert.h auth.h client.h policy.h printers.h classes.h job.h conf.h -main.o: banners.h dirsvc.h network.h subscriptions.h +main.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h +main.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h +main.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h ipp.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h ipp.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h ipp.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h ipp.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h -ipp.o: ../cups/http.h ../cups/i18n.h ../cups/debug.h sysman.h statbuf.h -ipp.o: cert.h auth.h client.h policy.h printers.h classes.h job.h conf.h -ipp.o: banners.h dirsvc.h network.h subscriptions.h +ipp.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h +ipp.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h +ipp.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h listen.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h listen.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h listen.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h listen.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -listen.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -listen.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -listen.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h +listen.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +listen.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +listen.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h +listen.o: subscriptions.h job.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h job.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h job.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h job.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h -job.o: ../cups/http.h ../cups/i18n.h ../cups/debug.h sysman.h statbuf.h -job.o: cert.h auth.h client.h policy.h printers.h classes.h job.h conf.h -job.o: banners.h dirsvc.h network.h subscriptions.h ../cups/backend.h -job.o: ../cups/dir.h +job.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h +job.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h +job.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h +job.o: ../cups/backend.h ../cups/dir.h log.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h log.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h log.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h log.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h -log.o: ../cups/http.h ../cups/i18n.h ../cups/debug.h sysman.h statbuf.h -log.o: cert.h auth.h client.h policy.h printers.h classes.h job.h conf.h -log.o: banners.h dirsvc.h network.h subscriptions.h -network.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h -network.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h +log.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h +log.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h +log.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h +network.o: ../cups/http-private.h ../config.h ../cups/http.h ../cups/md5.h +network.o: ../cups/ipp-private.h ../cups/ipp.h cupsd.h ../cups/string.h network.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h network.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -network.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -network.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -network.o: classes.h job.h conf.h banners.h dirsvc.h network.h +network.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +network.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +network.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h network.o: subscriptions.h policy.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h policy.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h policy.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h policy.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -policy.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -policy.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -policy.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h +policy.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +policy.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +policy.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h +policy.o: subscriptions.h printers.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h printers.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h printers.o: ../cups/string.h ../cups/array.h ../cups/cups.h ../cups/ppd.h printers.o: ../cups/array.h ../cups/file.h ../cups/language.h mime.h printers.o: ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h -printers.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h -printers.o: policy.h printers.h classes.h job.h conf.h banners.h dirsvc.h -printers.o: network.h subscriptions.h ../cups/transcode.h +printers.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +printers.o: auth.h client.h policy.h printers.h classes.h job.h conf.h +printers.o: banners.h dirsvc.h network.h subscriptions.h process.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h process.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h process.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h process.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -process.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -process.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -process.o: classes.h job.h conf.h banners.h dirsvc.h network.h +process.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +process.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +process.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h process.o: subscriptions.h quotas.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h quotas.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h quotas.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h quotas.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -quotas.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -quotas.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -quotas.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h +quotas.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +quotas.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +quotas.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h +quotas.o: subscriptions.h server.o: ../cups/http-private.h ../config.h ../cups/http.h ../cups/md5.h server.o: ../cups/ipp-private.h ../cups/ipp.h cupsd.h ../cups/string.h server.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h server.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -server.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -server.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -server.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h +server.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +server.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +server.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h +server.o: subscriptions.h statbuf.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h statbuf.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h statbuf.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h statbuf.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -statbuf.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -statbuf.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -statbuf.o: classes.h job.h conf.h banners.h dirsvc.h network.h +statbuf.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +statbuf.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +statbuf.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h statbuf.o: subscriptions.h subscriptions.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h subscriptions.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h subscriptions.o: ../cups/string.h ../cups/array.h ../cups/cups.h subscriptions.o: ../cups/ppd.h ../cups/array.h ../cups/file.h subscriptions.o: ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h -subscriptions.o: ../cups/http.h ../cups/i18n.h ../cups/debug.h sysman.h -subscriptions.o: statbuf.h cert.h auth.h client.h policy.h printers.h -subscriptions.o: classes.h job.h conf.h banners.h dirsvc.h network.h -subscriptions.o: subscriptions.h +subscriptions.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h +subscriptions.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h +subscriptions.o: policy.h printers.h classes.h job.h conf.h banners.h +subscriptions.o: dirsvc.h network.h subscriptions.h sysman.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h sysman.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h ../cups/string.h sysman.o: ../cups/array.h ../cups/cups.h ../cups/ppd.h ../cups/array.h sysman.o: ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h -sysman.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/debug.h -sysman.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h -sysman.o: classes.h job.h conf.h banners.h dirsvc.h network.h subscriptions.h +sysman.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +sysman.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +sysman.o: printers.h classes.h job.h conf.h banners.h dirsvc.h network.h +sysman.o: subscriptions.h filter.o: ../cups/debug.h ../cups/string.h ../config.h mime.h ../cups/array.h filter.o: ../cups/ipp.h ../cups/file.h -mime.o: ../cups/dir.h ../cups/string.h ../config.h mime.h ../cups/array.h -mime.o: ../cups/ipp.h ../cups/file.h +mime.o: ../cups/debug.h ../cups/dir.h ../cups/string.h ../config.h mime.h +mime.o: ../cups/array.h ../cups/ipp.h ../cups/file.h type.o: ../cups/string.h ../config.h mime.h ../cups/array.h ../cups/ipp.h type.o: ../cups/file.h ../cups/debug.h cups-deviced.o: util.h ../cups/cups.h ../cups/ipp.h ../cups/http.h @@ -176,7 +184,7 @@ cups-deviced.o: ../config.h ../cups/array.h ../cups/dir.h cups-driverd.o: util.h ../cups/cups.h ../cups/ipp.h ../cups/http.h cups-driverd.o: ../cups/md5.h ../cups/ppd.h ../cups/array.h ../cups/file.h cups-driverd.o: ../cups/language.h ../cups/file.h ../cups/string.h -cups-driverd.o: ../config.h ../cups/dir.h +cups-driverd.o: ../config.h ../cups/dir.h ../cups/transcode.h cups-lpd.o: ../cups/http-private.h ../config.h ../cups/http.h ../cups/md5.h cups-lpd.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h ../cups/ppd.h cups-lpd.o: ../cups/array.h ../cups/file.h ../cups/language.h diff --git a/scheduler/auth.c b/scheduler/auth.c index ee781150c..c203ed5db 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -869,9 +869,12 @@ cupsdCheckAuth( */ for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList); - iface && !strcmp(masks->mask.name.name, iface->name); + iface; iface = (cupsd_netif_t *)cupsArrayNext(NetIFList)) { + if (strcmp(masks->mask.name.name, iface->name)) + continue; + if (iface->address.addr.sa_family == AF_INET) { /* diff --git a/scheduler/client.c b/scheduler/client.c index 526e55bcc..ceb0591ae 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -54,6 +54,11 @@ #ifdef HAVE_CDSASSL # include <Security/Security.h> +# ifdef HAVE_SECBASEPRIV_H +# include <Security/SecBasePriv.h> +# else + extern const char *cssmErrorString(int error); +# endif /* HAVE_SECBASEPRIV_H */ #endif /* HAVE_CDSASSL */ #ifdef HAVE_GNUTLS # include <gnutls/x509.h> @@ -1882,24 +1887,27 @@ cupsdSendCommand( if (con->filename) + { fd = open(con->filename, O_RDONLY); - else - fd = open("/dev/null", O_RDONLY); - if (fd < 0) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "cupsdSendCommand: %d Unable to open \"%s\" for reading: %s", - con->http.fd, con->filename ? con->filename : "/dev/null", - strerror(errno)); - return (0); - } + if (fd < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdSendCommand: %d Unable to open \"%s\" for reading: %s", + con->http.fd, con->filename ? con->filename : "/dev/null", + strerror(errno)); + return (0); + } - fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + } + else + fd = -1; con->pipe_pid = pipe_command(con, fd, &(con->file), command, options, root); - close(fd); + if (fd >= 0) + close(fd); cupsdLogMessage(CUPSD_LOG_INFO, "Started \"%s\" (pid=%d)", command, con->pipe_pid); @@ -2659,7 +2667,7 @@ encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */ error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA); if (!error) - error = SSLSetProtocolVersion(conn->session, kSSLProtocol3); + error = SSLSetProtocolVersionEnabled(conn->session, kSSLProtocol2, false); if (!error) { @@ -2697,8 +2705,8 @@ encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */ "encrypt_client: Unable to encrypt connection from %s!", con->http.hostname); - cupsdLogMessage(CUPSD_LOG_ERROR, - "encrypt_client: CDSA error code is %d", (int)error); + cupsdLogMessage(CUPSD_LOG_ERROR, "encrypt_client: %s (%d)", + cssmErrorString(error), (int)error); con->http.error = error; con->http.status = HTTP_ERROR; diff --git a/scheduler/conf.c b/scheduler/conf.c index 10677426f..458a9ba87 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -289,6 +289,11 @@ cupsdReadConfiguration(void) cupsdSetString(&ServerHeader, "CUPS/1.2"); cupsdSetString(&StateDir, CUPS_STATEDIR); + if (!strcmp(CUPS_DEFAULT_PRINTCAP, "/etc/printers.conf")) + PrintcapFormat = PRINTCAP_SOLARIS; + else + PrintcapFormat = PRINTCAP_BSD; + strlcpy(temp, ConfigurationFile, sizeof(temp)); if ((slash = strrchr(temp, '/')) != NULL) *slash = '\0'; @@ -1277,33 +1282,14 @@ get_addr_and_mask(const char *value, /* I - String from config file */ const char *maskval, /* Pointer to start of mask value */ *ptr, /* Pointer into value */ *ptr2; /* ... */ - static unsigned netmasks[4][4] = /* Standard IPv4 netmasks... */ - { - { 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000 }, - { 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000 }, - { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00 }, - { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff } - }; -#ifdef AF_INET6 - static unsigned netmasks6[8][4] = /* Standard IPv6 netmasks... */ - { - { 0xffff0000, 0x00000000, 0x00000000, 0x00000000 }, - { 0xffffffff, 0x00000000, 0x00000000, 0x00000000 }, - { 0xffffffff, 0xffff0000, 0x00000000, 0x00000000 }, - { 0xffffffff, 0xffffffff, 0x00000000, 0x00000000 }, - { 0xffffffff, 0xffffffff, 0xffff0000, 0x00000000 }, - { 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000 }, - { 0xffffffff, 0xffffffff, 0xffffffff, 0xffff0000 }, - { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff } - }; -#endif /* AF_INET6 */ /* * Get the address... */ - memset(ip, 0, sizeof(unsigned) * 4); + ip[0] = ip[1] = ip[2] = ip[2] = 0x00000000; + mask[0] = mask[1] = mask[2] = mask[3] = 0xffffffff; if ((maskval = strchr(value, '/')) != NULL) maskval ++; @@ -1334,6 +1320,7 @@ get_addr_and_mask(const char *value, /* I - String from config file */ ptr2 = strchr(ptr2 + 1, ':'), j ++); i = 7 - j; + ptr ++; } else if (isxdigit(*ptr & 255)) { @@ -1343,9 +1330,9 @@ get_addr_and_mask(const char *value, /* I - String from config file */ return (0); if (i & 1) - ip[i] |= ipval; + ip[i / 2] |= ipval; else - ip[i] |= ipval << 16; + ip[i / 2] |= ipval << 16; } else return (0); @@ -1354,7 +1341,10 @@ get_addr_and_mask(const char *value, /* I - String from config file */ ptr ++; } - ipcount = i; + if (*ptr != ']') + return (0); + + ptr ++; if (*ptr && *ptr != '/') return (0); @@ -1366,70 +1356,55 @@ get_addr_and_mask(const char *value, /* I - String from config file */ * Parse dotted-decimal IPv4 address... */ - family = AF_INET; - ipcount = sscanf(value, "%u.%u.%u.%u", ip + 0, ip + 1, ip + 2, ip + 3); + unsigned val[4]; /* IPv4 address values */ - ip[3] |= ((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8; - ip[0] = ip[1] = ip[2] = 0; - } - if (*maskval) - { + family = AF_INET; + ipcount = sscanf(value, "%u.%u.%u.%u", val + 0, val + 1, val + 2, val + 3); + /* - * Get the netmask value(s)... + * Range check the IP numbers... */ - memset(mask, 0, sizeof(unsigned) * 4); + for (i = 0; i < ipcount; i ++) + if (val[i] > 255) + return (0); -#ifdef AF_INET6 - if (*maskval == '[') - { - /* - * Get hexadecimal mask value... - */ + /* + * Make sure the trailing values are zeroed, as some C libraries like + * glibc apparently like to fill the unused arguments with garbage... + */ - for (i = 0, ptr = maskval + 1; *ptr && i < 8; i ++) - { - if (*ptr == ']') - break; - else if (!strncmp(ptr, "::", 2)) - { - for (ptr2 = strchr(ptr + 2, ':'), j = 0; - ptr2; - ptr2 = strchr(ptr2 + 1, ':'), j ++); + for (i = ipcount; i < 4; i ++) + val[i] = 0; - i = 7 - j; - } - else if (isxdigit(*ptr & 255)) - { - ipval = strtoul(ptr, (char **)&ptr, 16); + /* + * Merge everything into a 32-bit IPv4 address in ip[3]... + */ - if (ipval > 0xffff) - return (0); + ip[3] = (((((val[0] << 8) | val[1]) << 8) | val[2]) << 8) | val[3]; - if (i & 1) - mask[i] |= ipval; - else - mask[i] |= ipval << 16; - } - else - return (0); + if (ipcount < 4) + mask[3] = (0xffffffff << (32 - 8 * ipcount)) & 0xffffffff; + } - while (*ptr == ':') - ptr ++; - } + if (*maskval) + { + /* + * Get the netmask value(s)... + */ + + memset(mask, 0, sizeof(unsigned) * 4); - if (*ptr) - return (0); - } - else -#endif /* AF_INET6 */ if (strchr(maskval, '.')) { /* * Get dotted-decimal mask... */ + if (family != AF_INET) + return (0); + if (sscanf(maskval, "%u.%u.%u.%u", mask + 0, mask + 1, mask + 2, mask + 3) != 4) return (0); @@ -1447,6 +1422,9 @@ get_addr_and_mask(const char *value, /* I - String from config file */ #ifdef AF_INET6 if (family == AF_INET6) { + if (i > 128) + return (0); + i = 128 - i; if (i <= 96) @@ -1478,25 +1456,20 @@ get_addr_and_mask(const char *value, /* I - String from config file */ else #endif /* AF_INET6 */ { - i = 32 - i; + if (i > 32) + return (0); mask[0] = 0xffffffff; mask[1] = 0xffffffff; mask[2] = 0xffffffff; - if (i > 0) - mask[3] = (0xffffffff << i) & 0xffffffff; + if (i < 32) + mask[3] = (0xffffffff << (32 - i)) & 0xffffffff; else mask[3] = 0xffffffff; } } } -#ifdef AF_INET6 - else if (family == AF_INET6) - memcpy(mask, netmasks6[ipcount - 1], sizeof(unsigned) * 4); -#endif /* AF_INET6 */ - else - memcpy(mask, netmasks[ipcount - 1], sizeof(unsigned) * 4); cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_addr_and_mask(value=\"%s\", " @@ -1634,7 +1607,12 @@ parse_aaa(cupsd_location_t *loc, /* I - Location */ else cupsdDenyIP(loc, ones, zeros); } +#ifdef AF_INET6 + else if (value[0] == '*' || value[0] == '.' || + (!isdigit(value[0] & 255) && value[0] != '[')) +#else else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255)) +#endif /* AF_INET6 */ { /* * Host or domain name... @@ -2406,7 +2384,12 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ else cupsdDenyIP(location, ones, zeros); } - else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0])) +#ifdef AF_INET6 + else if (value[0] == '*' || value[0] == '.' || + (!isdigit(value[0] & 255) && value[0] != '[')) +#else + else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255)) +#endif /* AF_INET6 */ { /* * Host or domain name... @@ -2490,7 +2473,12 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ * nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm */ - if (value[0] == '*' || value[0] == '.' || !isdigit(value[0])) +#ifdef AF_INET6 + if (value[0] == '*' || value[0] == '.' || + (!isdigit(value[0] & 255) && value[0] != '[')) +#else + if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255)) +#endif /* AF_INET6 */ { /* * Host or domain name... diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c index ddc99b259..900f13538 100644 --- a/scheduler/dirsvc.c +++ b/scheduler/dirsvc.c @@ -36,6 +36,7 @@ * cupsdStopPolling() - Stop polling servers as needed. * cupsdUpdateCUPSBrowse() - Update the browse lists using the CUPS * protocol. + * cupsdUpdateLDAPBrowse() - Scan for new printers via LDAP... * cupsdUpdatePolling() - Read status messages from the poll daemons. * cupsdUpdateSLPBrowse() - Get browsing information via SLP. * dequote() - Remote quotes from a string. @@ -1526,39 +1527,57 @@ cupsdUpdateLDAPBrowse(void) * Loop through the available printers... */ - if ((e = ldap_first_entry(BrowseLDAPHandle, res)) == NULL) + for (e = ldap_first_entry(BrowseLDAPHandle, res); + e; + e = ldap_next_entry(BrowseLDAPHandle, e)) { - cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get LDAP printer entry!"); - return; - } + /* + * Get the required values from this entry... + */ + + if ((value = ldap_get_values(BrowseLDAPHandle, e, + "printerDescription")) == NULL) + continue; - while (e) - { - value = ldap_get_values(BrowseLDAPHandle, e, "printerDescription"); strlcpy(info, *value, sizeof(info)); ldap_value_free(value); - value = ldap_get_values(BrowseLDAPHandle, e, "printerLocation"); + if ((value = ldap_get_values(BrowseLDAPHandle, e, + "printerLocation")) == NULL) + continue; + strlcpy(location, *value, sizeof(location)); ldap_value_free(value); - value = ldap_get_values(BrowseLDAPHandle, e, "printerMakeAndModel"); + if ((value = ldap_get_values(BrowseLDAPHandle, e, + "printerMakeAndModel")) == NULL) + continue; + strlcpy(make_model, *value, sizeof(make_model)); ldap_value_free(value); - value = ldap_get_values(BrowseLDAPHandle, e, "printerType"); + if ((value = ldap_get_values(BrowseLDAPHandle, e, + "printerType")) == NULL) + continue; + type = atoi(*value); ldap_value_free(value); - value = ldap_get_values(BrowseLDAPHandle, e, "printerURI"); + if ((value = ldap_get_values(BrowseLDAPHandle, e, + "printerURI")) == NULL) + continue; + strlcpy(uri, *value, sizeof(uri)); ldap_value_free(value); + /* + * Process the entry as browse data... + */ + if (!is_local_queue(uri, host, sizeof(host), resource, sizeof(resource))) process_browse_data(uri, host, resource, type, IPP_PRINTER_IDLE, location, info, make_model, 0, NULL); - e = ldap_next_entry(BrowseLDAPHandle, e); } } #endif /* HAVE_OPENLDAP */ @@ -2521,7 +2540,7 @@ send_cups_browse(cupsd_printer_t *p) /* I - Printer to send */ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, iface->hostname, iface->port, - (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s%s" : + (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s" : "/printers/%s", p->name); snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n", @@ -2660,13 +2679,13 @@ send_ldap_browse(cupsd_printer_t *p) /* I - Printer to register */ sprintf(typestring, "%u", p->type); - cn_value[0] = p->info; + cn_value[0] = p->name; cn_value[1] = NULL; - info[0] = p->info; + info[0] = p->info ? p->info : "Unknown"; info[1] = NULL; - location[0] = p->location; + location[0] = p->location ? p->location : "Unknown"; location[1] = NULL; - make_model[0] = p->make_model; + make_model[0] = p->make_model ? p->make_model : "Unknown"; make_model[1] = NULL; type[0] = typestring; type[1] = NULL; @@ -2674,7 +2693,7 @@ send_ldap_browse(cupsd_printer_t *p) /* I - Printer to register */ uri[1] = NULL; snprintf(filter, sizeof(filter), - "(&(objectclass=cupsPrinter)(printerDescription~=%s))", p->info); + "(&(objectclass=cupsPrinter)(printerURI=%s))", p->uri); ldap_search_s(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE, filter, (char **)ldap_attrs, 0, &res); @@ -2696,7 +2715,7 @@ send_ldap_browse(cupsd_printer_t *p) /* I - Printer to register */ mods[6].mod_type = "objectClass"; mods[6].mod_values = (char **)objectClass_values; - snprintf(dn, sizeof(dn), "cn=%s,ou=printers,%s", p->info, BrowseLDAPDN); + snprintf(dn, sizeof(dn), "cn=%s,ou=printers,%s", p->name, BrowseLDAPDN); cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_browse: dn=\"%s\"", dn); if (ldap_count_entries(BrowseLDAPHandle, res) > 0) @@ -2724,7 +2743,7 @@ send_ldap_browse(cupsd_printer_t *p) /* I - Printer to register */ else { /* - * Printer has already been registered, modify the current + * Printer has never been registered, add the current * registration... */ @@ -2734,11 +2753,11 @@ send_ldap_browse(cupsd_printer_t *p) /* I - Printer to register */ for (i = 0; i < 7; i ++) { pmods[i] = mods + i; - pmods[i]->mod_op = LDAP_MOD_REPLACE; + pmods[i]->mod_op = LDAP_MOD_ADD; } pmods[i] = NULL; - if ((rc = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) + if ((rc = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) cupsdLogMessage(CUPSD_LOG_ERROR, "LDAP add for %s failed with status %d: %s", p->name, rc, ldap_err2string(rc)); diff --git a/scheduler/filter.c b/scheduler/filter.c index e97e2541b..d3dd6230d 100644 --- a/scheduler/filter.c +++ b/scheduler/filter.c @@ -346,6 +346,8 @@ find_filters(mime_t *mime, /* I - MIME database */ * any...) */ + tempcost += current->cost; + if (tempcost < mincost) { cupsArrayDelete(mintemp); @@ -356,7 +358,7 @@ find_filters(mime_t *mime, /* I - MIME database */ */ mintemp = temp; - mincost = tempcost + current->cost; + mincost = tempcost; cupsArrayInsert(mintemp, current); } else diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 929654951..2d09ea1bf 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -126,8 +126,7 @@ static void accept_jobs(cupsd_client_t *con, ipp_attribute_t *uri); static void add_class(cupsd_client_t *con, ipp_attribute_t *uri); static int add_file(cupsd_client_t *con, cupsd_job_t *job, mime_type_t *filetype, int compression); -static cupsd_job_t *add_job(cupsd_client_t *con, ipp_attribute_t *uri, - cupsd_printer_t **dprinter, +static cupsd_job_t *add_job(cupsd_client_t *con, cupsd_printer_t *printer, mime_type_t *filetype); static void add_job_state_reasons(cupsd_client_t *con, cupsd_job_t *job); static void add_job_subscriptions(cupsd_client_t *con, cupsd_job_t *job); @@ -700,12 +699,6 @@ accept_jobs(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - const char *name; /* Printer name */ cupsd_printer_t *printer; /* Printer data */ @@ -716,11 +709,7 @@ accept_jobs(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((name = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -751,12 +740,19 @@ accept_jobs(cupsd_client_t *con, /* I - Client connection */ cupsdAddPrinterHistory(printer); if (dtype & CUPS_PRINTER_CLASS) + { cupsdSaveAllClasses(); + + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" now accepting jobs (\"%s\").", + printer->name, get_username(con)); + } else + { cupsdSaveAllPrinters(); - cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" now accepting jobs (\"%s\").", name, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" now accepting jobs (\"%s\").", + printer->name, get_username(con)); + } /* * Everything was ok, so return OK status... @@ -784,7 +780,6 @@ add_class(cupsd_client_t *con, /* I - Client connection */ cupsd_printer_t *pclass, /* Class */ *member; /* Member printer/class */ cups_ptype_t dtype; /* Destination type */ - const char *dest; /* Printer or class name */ ipp_attribute_t *attr; /* Printer attribute */ int modify; /* Non-zero if we just modified */ char newname[IPP_MAX_NAME]; /* New class name */ @@ -1003,11 +998,7 @@ add_class(cupsd_client_t *con, /* I - Client connection */ * Search for the printer or class URI... */ - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &member)) == NULL) + if (!cupsdValidateDest(attr->values[i].string.text, &dtype, &member)) { /* * Bad URI... @@ -1144,54 +1135,24 @@ add_file(cupsd_client_t *con, /* I - Connection to client */ static cupsd_job_t * /* O - Job object */ add_job(cupsd_client_t *con, /* I - Client connection */ - ipp_attribute_t *uri, /* I - printer-uri */ - cupsd_printer_t **dprinter, /* I - Destination printer */ + cupsd_printer_t *printer, /* I - Destination printer */ mime_type_t *filetype) /* I - First print file type, if any */ { http_status_t status; /* Policy status */ ipp_attribute_t *attr; /* Current attribute */ - const char *dest; /* Destination */ - cups_ptype_t dtype; /* Destination type (printer or class) */ const char *val; /* Default option value */ int priority; /* Job priority */ char *title; /* Job name/title */ cupsd_job_t *job; /* Current job */ - char job_uri[HTTP_MAX_URI], /* Job URI */ - method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - cupsd_printer_t *printer; /* Printer data */ + char job_uri[HTTP_MAX_URI]; /* Job URI */ int kbytes; /* Size of print file */ int i; /* Looping var */ int lowerpagerange; /* Page range bound */ - cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %s)", con, - con->http.fd, uri->values[0].string.text); - - /* - * Is the destination valid? - */ - - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) - { - /* - * Bad URI... - */ - - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer or class was not found.")); - return (NULL); - } - - if (dprinter) - *dprinter = printer; + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))", + con, con->http.fd, printer, printer->name, + filetype, filetype->super, filetype->type); /* * Check remote printing to non-shared printer... @@ -1229,7 +1190,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */ { send_ipp_status(con, IPP_NOT_ACCEPTING, _("Destination \"%s\" is not accepting jobs."), - dest); + printer->name); return (NULL); } @@ -1296,7 +1257,7 @@ add_job(cupsd_client_t *con, /* I - Client connection */ if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs) cupsdCleanJobs(); - if (cupsArrayCount(Jobs) >= MaxJobs && MaxJobs) + if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs) { send_ipp_status(con, IPP_NOT_POSSIBLE, _("Too many active jobs.")); @@ -1338,11 +1299,13 @@ add_job(cupsd_client_t *con, /* I - Client connection */ if ((job = cupsdAddJob(priority, printer->name)) == NULL) { send_ipp_status(con, IPP_INTERNAL_ERROR, - _("Unable to add job for destination \"%s\"!"), dest); + _("Unable to add job for destination \"%s\"!"), + printer->name); return (NULL); } - job->dtype = dtype; + job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_REMOTE); job->attrs = con->request; con->request = NULL; @@ -2767,11 +2730,10 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *uri) /* I - Job or Printer URI */ { http_status_t status; /* Policy status */ - const char *dest; /* Destination */ cups_ptype_t dtype; /* Destination type */ - char method[HTTP_MAX_URI], /* Method portion of URI */ + char scheme[HTTP_MAX_URI], /* Scheme portion of URI */ userpass[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ + hostname[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ int port; /* Port portion of URI */ ipp_attribute_t *attr; /* Attribute in request */ @@ -2830,16 +2792,17 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ * And if the destination is valid... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), userpass, sizeof(userpass), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI? */ + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, + scheme, sizeof(scheme), userpass, sizeof(userpass), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + if ((!strncmp(resource, "/printers/", 10) && resource[10]) || (!strncmp(resource, "/classes/", 9) && resource[9])) { @@ -2847,13 +2810,6 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ _("The printer or class was not found.")); return; } - else if (strcmp(resource, "/printers/")) - { - send_ipp_status(con, IPP_NOT_FOUND, - _("The printer-uri \"%s\" is not valid."), - uri->values[0].string.text); - return; - } /* * Check policy... @@ -2880,7 +2836,8 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ * Check policy... */ - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) { send_http_error(con, status); return; @@ -2890,10 +2847,11 @@ cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ * Cancel all of the jobs on the named printer... */ - cupsdCancelJobs(dest, username, purge); + cupsdCancelJobs(printer->name, username, purge); cupsdLogMessage(CUPSD_LOG_INFO, "All jobs on \"%s\" were %s by \"%s\".", - dest, purge ? "purged" : "cancelled", get_username(con)); + printer->name, purge ? "purged" : "cancelled", + get_username(con)); } con->response->request.status.status_code = IPP_OK; @@ -2910,13 +2868,12 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */ { ipp_attribute_t *attr; /* Current attribute */ int jobid; /* Job ID */ - char method[HTTP_MAX_URI], /* Method portion of URI */ + char scheme[HTTP_MAX_URI], /* Scheme portion of URI */ username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ int port; /* Port portion of URI */ cupsd_job_t *job; /* Job information */ - const char *dest; /* Destination */ cups_ptype_t dtype; /* Destination type (printer or class) */ cupsd_printer_t *printer; /* Printer data */ @@ -2948,11 +2905,7 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */ * Find the current job on the specified printer... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -2979,7 +2932,7 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */ job; job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) if (job->state_value <= IPP_JOB_PROCESSING && - !strcasecmp(job->dest, dest)) + !strcasecmp(job->dest, printer->name)) break; if (job) @@ -2987,7 +2940,7 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */ else { send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s!"), - dest); + printer->name); return; } } @@ -2999,8 +2952,8 @@ cancel_job(cupsd_client_t *con, /* I - Client connection */ * Got a job URI; parse it to get the job ID... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, sizeof(host), &port, resource, sizeof(resource)); if (strncmp(resource, "/jobs/", 6)) @@ -4459,17 +4412,33 @@ static void create_job(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *uri) /* I - Printer URI */ { - cupsd_job_t *job; /* New job */ + cupsd_printer_t *printer; /* Printer */ + cupsd_job_t *job; /* New job */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", con, con->http.fd, uri->values[0].string.text); /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, NULL, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* * Create the job object... */ - if ((job = add_job(con, uri, NULL, NULL)) == NULL) + if ((job = add_job(con, printer, NULL)) == NULL) return; /* @@ -4677,8 +4646,8 @@ create_subscription( ipp_attribute_t *attr; /* Current attribute */ const char *dest; /* Destination */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ + char scheme[HTTP_MAX_URI], + /* Scheme portion of URI */ userpass[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], @@ -4718,8 +4687,8 @@ create_subscription( "cupsdCreateSubscription(con=%p(%d), uri=\"%s\")", con, con->http.fd, uri->values[0].string.text); - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), userpass, sizeof(userpass), host, + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)); if (!strcmp(resource, "/")) @@ -4740,7 +4709,8 @@ create_subscription( dtype = CUPS_PRINTER_CLASS; printer = NULL; } - else if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + else if ((dest = cupsdValidateDest(uri->values[0].string.text, &dtype, + &printer)) == NULL) { /* * Bad URI... @@ -4757,7 +4727,8 @@ create_subscription( if (printer) { - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) { send_http_error(con, status); return; @@ -4811,10 +4782,54 @@ create_subscription( { if (!strcmp(attr->name, "notify-recipient") && attr->value_tag == IPP_TAG_URI) + { + /* + * Validate the recipient scheme against the ServerBin/notifier + * directory... + */ + + char notifier[1024]; /* Notifier filename */ + + recipient = attr->values[0].string.text; + + if (httpSeparateURI(HTTP_URI_CODING_ALL, recipient, scheme, + sizeof(scheme), userpass, sizeof(userpass), host, + sizeof(host), &port, resource, sizeof(resource))) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Bad notify-recipient URI \"%s\"!"), recipient); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_URI_SCHEME); + return; + } + + snprintf(notifier, sizeof(notifier), "%s/notifier/%s", ServerBin, + scheme); + if (access(notifier, X_OK)) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("notify-recipient URI \"%s\" uses unknown scheme!"), + recipient); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_URI_SCHEME); + return; + } + } else if (!strcmp(attr->name, "notify-pull-method") && attr->value_tag == IPP_TAG_KEYWORD) + { pullmethod = attr->values[0].string.text; + + if (strcmp(pullmethod, "ippget")) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Bad notify-pull-method \"%s\"!"), pullmethod); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_ATTRIBUTES); + return; + } + } else if (!strcmp(attr->name, "notify-charset") && attr->value_tag == IPP_TAG_CHARSET && strcmp(attr->values[0].string.text, "us-ascii") && @@ -4961,13 +4976,7 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *uri) /* I - URI of printer or class */ { http_status_t status; /* Policy status */ - const char *dest; /* Destination */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ cupsd_printer_t *printer; /* Printer/class */ char filename[1024]; /* Script/PPD filename */ @@ -4979,11 +4988,7 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */ * Do we have a valid URI? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -5008,7 +5013,7 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */ * Remove old jobs... */ - cupsdCancelJobs(dest, NULL, 1); + cupsdCancelJobs(printer->name, NULL, 1); /* * Remove old subscriptions and send a "deleted printer" event... @@ -5017,7 +5022,7 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */ cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, printer, NULL, "%s \"%s\" deleted by \"%s\".", (dtype & CUPS_PRINTER_CLASS) ? "Class" : "Printer", - dest, get_username(con)); + printer->name, get_username(con)); cupsdExpireSubscriptions(printer, NULL); @@ -5025,24 +5030,26 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */ * Remove any old PPD or script files... */ - snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot, dest); + snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot, + printer->name); unlink(filename); - snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, dest); + snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, + printer->name); unlink(filename); if (dtype & CUPS_PRINTER_CLASS) { - cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" deleted by \"%s\".", dest, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" deleted by \"%s\".", + printer->name, get_username(con)); cupsdDeletePrinter(printer, 0); cupsdSaveAllClasses(); } else { - cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" deleted by \"%s\".", dest, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" deleted by \"%s\".", + printer->name, get_username(con)); cupsdDeletePrinter(printer, 0); cupsdSaveAllPrinters(); @@ -5285,7 +5292,7 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ const char *dest; /* Destination */ cups_ptype_t dtype; /* Destination type (printer or class) */ cups_ptype_t dmask; /* Destination type mask */ - char method[HTTP_MAX_URI], /* Method portion of URI */ + char scheme[HTTP_MAX_URI], /* Scheme portion of URI */ username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ @@ -5307,8 +5314,8 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, sizeof(host), &port, resource, sizeof(resource)); if (!strcmp(resource, "/") || @@ -5333,7 +5340,8 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ dmask = CUPS_PRINTER_CLASS; printer = NULL; } - else if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + else if ((dest = cupsdValidateDest(uri->values[0].string.text, &dtype, + &printer)) == NULL) { /* * Bad URI... @@ -5352,7 +5360,8 @@ get_jobs(cupsd_client_t *con, /* I - Client connection */ if (printer) { - if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) { send_http_error(con, status); return; @@ -5688,17 +5697,7 @@ get_printer_attrs(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *uri) /* I - Printer URI */ { http_status_t status; /* Policy status */ - const char *dest; /* Destination */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ cupsd_printer_t *printer; /* Printer/class */ cups_array_t *ra; /* Requested attributes array */ @@ -5710,11 +5709,7 @@ get_printer_attrs(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -5977,8 +5972,8 @@ get_subscriptions(cupsd_client_t *con, /* I - Client connection */ cups_array_t *ra; /* Requested attributes array */ ipp_attribute_t *attr; /* Attribute */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ + char scheme[HTTP_MAX_URI], + /* Scheme portion of URI */ username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], @@ -5998,8 +5993,8 @@ get_subscriptions(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, sizeof(host), &port, resource, sizeof(resource)); if (!strcmp(resource, "/") || @@ -6022,7 +6017,7 @@ get_subscriptions(cupsd_client_t *con, /* I - Client connection */ return; } } - else if (!cupsdValidateDest(host, resource, &dtype, &printer)) + else if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -6281,7 +6276,7 @@ move_job(cupsd_client_t *con, /* I - Client connection */ *dest; /* Destination */ cups_ptype_t stype, /* Source type (printer or class) */ dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], /* Method portion of URI */ + char scheme[HTTP_MAX_URI], /* Scheme portion of URI */ username[HTTP_MAX_URI], /* Username portion of URI */ host[HTTP_MAX_URI], /* Host portion of URI */ resource[HTTP_MAX_URI]; /* Resource portion of URI */ @@ -6309,11 +6304,8 @@ move_job(cupsd_client_t *con, /* I - Client connection */ return; } - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &dtype, &dprinter)) == NULL) + if ((dest = cupsdValidateDest(attr->values[0].string.text, &dtype, + &dprinter)) == NULL) { /* * Bad URI... @@ -6328,7 +6320,8 @@ move_job(cupsd_client_t *con, /* I - Client connection */ * Check policy... */ - if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con, NULL)) != HTTP_OK) + if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con, + NULL)) != HTTP_OK) { send_http_error(con, status); return; @@ -6338,8 +6331,8 @@ move_job(cupsd_client_t *con, /* I - Client connection */ * See if we have a job URI or a printer URI... */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, sizeof(host), &port, resource, sizeof(resource)); if (!strcmp(uri->name, "printer-uri")) @@ -6355,7 +6348,8 @@ move_job(cupsd_client_t *con, /* I - Client connection */ * Move all jobs... */ - if ((src = cupsdValidateDest(host, resource, &stype, &sprinter)) == NULL) + if ((src = cupsdValidateDest(uri->values[0].string.text, &stype, + &sprinter)) == NULL) { /* * Bad URI... @@ -6653,6 +6647,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */ { ipp_attribute_t *attr; /* Current attribute */ ipp_attribute_t *format; /* Document-format attribute */ + const char *default_format; /* document-format-default value */ cupsd_job_t *job; /* New job */ char filename[1024]; /* Job filename */ mime_type_t *filetype; /* Type of file */ @@ -6710,6 +6705,21 @@ print_job(cupsd_client_t *con, /* I - Client connection */ } /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, NULL, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* * Is it a format we support? */ @@ -6720,7 +6730,8 @@ print_job(cupsd_client_t *con, /* I - Client connection */ * Grab format from client... */ - if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, type) != 2) + if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, + type) != 2) { send_ipp_status(con, IPP_BAD_REQUEST, _("Could not scan type \"%s\"!"), @@ -6728,10 +6739,26 @@ print_job(cupsd_client_t *con, /* I - Client connection */ return; } } + else if ((default_format = cupsGetOption("document-format", + printer->num_options, + printer->options)) != NULL) + { + /* + * Use default document format... + */ + + if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Could not scan type \"%s\"!"), + default_format); + return; + } + } else { /* - * No document format attribute? Auto-type it! + * Auto-type it! */ strcpy(super, "application"); @@ -6754,32 +6781,35 @@ print_job(cupsd_client_t *con, /* I - Client connection */ doc_name ? doc_name->values[0].string.text : NULL, &compression); - if (filetype) - { - /* - * Replace the document-format attribute value with the auto-typed one. - */ + if (!filetype) + filetype = mimeType(MimeDatabase, super, type); + } + else + filetype = mimeType(MimeDatabase, super, type); - snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, - filetype->type); + if (filetype && + (!format || + (!strcmp(super, "application") && !strcmp(type, "octet-stream")))) + { + /* + * Replace the document-format attribute value with the auto-typed or + * default one. + */ - if (format) - { - _cupsStrFree(format->values[0].string.text); + snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, + filetype->type); - format->values[0].string.text = _cupsStrAlloc(mimetype); - } - else - ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, - "document-format", NULL, mimetype); + if (format) + { + _cupsStrFree(format->values[0].string.text); + + format->values[0].string.text = _cupsStrAlloc(mimetype); } else - filetype = mimeType(MimeDatabase, super, type); + ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, + "document-format", NULL, mimetype); } - else - filetype = mimeType(MimeDatabase, super, type); - - if (!filetype) + else if (!filetype) { send_ipp_status(con, IPP_DOCUMENT_FORMAT, _("Unsupported format \'%s/%s\'!"), super, type); @@ -6808,7 +6838,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */ * Create the job object... */ - if ((job = add_job(con, uri, &printer, filetype)) == NULL) + if ((job = add_job(con, printer, filetype)) == NULL) return; /* @@ -7073,12 +7103,6 @@ reject_jobs(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], /* Method portion of URI */ - username[HTTP_MAX_URI], /* Username portion of URI */ - host[HTTP_MAX_URI], /* Host portion of URI */ - resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int port; /* Port portion of URI */ - const char *name; /* Printer name */ cupsd_printer_t *printer; /* Printer data */ ipp_attribute_t *attr; /* printer-state-message text */ @@ -7090,11 +7114,7 @@ reject_jobs(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((name = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -7135,14 +7155,14 @@ reject_jobs(cupsd_client_t *con, /* I - Client connection */ cupsdSaveAllClasses(); cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" rejecting jobs (\"%s\").", - name, get_username(con)); + printer->name, get_username(con)); } else { cupsdSaveAllPrinters(); cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" rejecting jobs (\"%s\").", - name, get_username(con)); + printer->name, get_username(con)); } /* @@ -7598,6 +7618,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */ { ipp_attribute_t *attr; /* Current attribute */ ipp_attribute_t *format; /* Document-format attribute */ + const char *default_format;/* document-format-default value */ int jobid; /* Job ID number */ cupsd_job_t *job; /* Current job */ char job_uri[HTTP_MAX_URI], @@ -7756,6 +7777,22 @@ send_document(cupsd_client_t *con, /* I - Client connection */ return; } } + else if ((default_format = cupsGetOption("document-format", + printer->num_options, + printer->options)) != NULL) + { + /* + * Use default document format... + */ + + if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Could not scan type \"%s\"!"), + default_format); + return; + } + } else { /* @@ -7782,31 +7819,35 @@ send_document(cupsd_client_t *con, /* I - Client connection */ doc_name ? doc_name->values[0].string.text : NULL, &compression); - if (filetype) - { - /* - * Replace the document-format attribute value with the auto-typed one. - */ - - snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, - filetype->type); - - if (format) - { - _cupsStrFree(format->values[0].string.text); - format->values[0].string.text = _cupsStrAlloc(mimetype); - } - else - ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, - "document-format", NULL, mimetype); - } - else + if (!filetype) filetype = mimeType(MimeDatabase, super, type); } else filetype = mimeType(MimeDatabase, super, type); - if (!filetype) + if (filetype && + (!format || + (!strcmp(super, "application") && !strcmp(type, "octet-stream")))) + { + /* + * Replace the document-format attribute value with the auto-typed or + * default one. + */ + + snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, + filetype->type); + + if (format) + { + _cupsStrFree(format->values[0].string.text); + + format->values[0].string.text = _cupsStrAlloc(mimetype); + } + else + ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, + "document-format", NULL, mimetype); + } + else if (!filetype) { send_ipp_status(con, IPP_DOCUMENT_FORMAT, _("Unsupported format \'%s/%s\'!"), super, type); @@ -8046,16 +8087,6 @@ set_default(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ - const char *name; /* Printer name */ cupsd_printer_t *printer; /* Printer */ @@ -8066,11 +8097,7 @@ set_default(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((name = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -8103,8 +8130,8 @@ set_default(cupsd_client_t *con, /* I - Client connection */ cupsdWritePrintcap(); cupsdLogMessage(CUPSD_LOG_INFO, - "Default destination set to \"%s\" by \"%s\".", name, - get_username(con)); + "Default destination set to \"%s\" by \"%s\".", + printer->name, get_username(con)); /* * Everything was ok, so return OK status... @@ -8606,8 +8633,7 @@ set_printer_defaults( attr->values[0].string.text); cupsdSetString(&printer->error_policy, attr->values[0].string.text); } - else if (!strcmp(attr->name, "document-format-default") || - !strcmp(attr->name, "notify-lease-duration-default") || + else if (!strcmp(attr->name, "notify-lease-duration-default") || !strcmp(attr->name, "notify-events-default")) continue; @@ -8710,16 +8736,6 @@ start_printer(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ - const char *name; /* Printer name */ cupsd_printer_t *printer; /* Printer data */ @@ -8730,11 +8746,7 @@ start_printer(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((name = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -8765,17 +8777,19 @@ start_printer(cupsd_client_t *con, /* I - Client connection */ if (dtype & CUPS_PRINTER_CLASS) { - cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" started by \"%s\".", name, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" started by \"%s\".", + printer->name, get_username(con)); cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, printer, NULL, - "Class \"%s\" started by \"%s\".", name, get_username(con)); + "Class \"%s\" started by \"%s\".", printer->name, + get_username(con)); } else { - cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" started by \"%s\".", name, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" started by \"%s\".", + printer->name, get_username(con)); cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, printer, NULL, - "Printer \"%s\" started by \"%s\".", name, get_username(con)); + "Printer \"%s\" started by \"%s\".", printer->name, + get_username(con)); } cupsdCheckJobs(); @@ -8798,16 +8812,6 @@ stop_printer(cupsd_client_t *con, /* I - Client connection */ { http_status_t status; /* Policy status */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ - const char *name; /* Printer name */ cupsd_printer_t *printer; /* Printer data */ ipp_attribute_t *attr; /* printer-state-message attribute */ @@ -8819,11 +8823,7 @@ stop_printer(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((name = cupsdValidateDest(host, resource, &dtype, &printer)) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... @@ -8861,17 +8861,19 @@ stop_printer(cupsd_client_t *con, /* I - Client connection */ if (dtype & CUPS_PRINTER_CLASS) { - cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" stopped by \"%s\".", name, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" stopped by \"%s\".", + printer->name, get_username(con)); cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, printer, NULL, - "Class \"%s\" stopped by \"%s\".", name, get_username(con)); + "Class \"%s\" stopped by \"%s\".", printer->name, + get_username(con)); } else { - cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" stopped by \"%s\".", name, - get_username(con)); + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" stopped by \"%s\".", + printer->name, get_username(con)); cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, printer, NULL, - "Printer \"%s\" stopped by \"%s\".", name, get_username(con)); + "Printer \"%s\" stopped by \"%s\".", printer->name, + get_username(con)); } /* @@ -8998,15 +9000,6 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *attr; /* Current attribute */ ipp_attribute_t *format; /* Document-format attribute */ cups_ptype_t dtype; /* Destination type (printer or class) */ - char method[HTTP_MAX_URI], - /* Method portion of URI */ - username[HTTP_MAX_URI], - /* Username portion of URI */ - host[HTTP_MAX_URI], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ char super[MIME_MAX_SUPER], /* Supertype of file */ type[MIME_MAX_TYPE]; @@ -9066,11 +9059,7 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ * Is the destination valid? */ - httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, method, - sizeof(method), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if (cupsdValidateDest(host, resource, &dtype, &printer) == NULL) + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) { /* * Bad URI... diff --git a/scheduler/job.c b/scheduler/job.c index 9c04db161..102905119 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -506,8 +506,19 @@ cupsdFinishJob(cupsd_job_t *job) /* I - Job */ */ cupsdStopJob(job, 0); - job->state->values[0].integer = IPP_JOB_PENDING; - job->state_value = IPP_JOB_PENDING; + + if (!(printer->type & CUPS_PRINTER_REMOTE) || + (printer->type & CUPS_PRINTER_IMPLICIT)) + { + /* + * Mark the job as pending again - we'll retry on another + * printer... + */ + + job->state->values[0].integer = IPP_JOB_PENDING; + job->state_value = IPP_JOB_PENDING; + } + cupsdSaveJob(job); /* @@ -865,13 +876,6 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ cups_file_t *fp; /* Job file */ int fileid; /* Current file ID */ ipp_attribute_t *attr; /* Job attribute */ - char scheme[32], /* Scheme portion of URI */ - username[64], /* Username portion of URI */ - host[HTTP_MAX_HOST], - /* Host portion of URI */ - resource[HTTP_MAX_URI]; - /* Resource portion of URI */ - int port; /* Port portion of URI */ const char *dest; /* Destination */ mime_type_t **filetypes; /* New filetypes array */ int *compressions; /* New compressions array */ @@ -955,11 +959,7 @@ cupsdLoadJob(cupsd_job_t *job) /* I - Job */ return; } - httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, scheme, - sizeof(scheme), username, sizeof(username), host, - sizeof(host), &port, resource, sizeof(resource)); - - if ((dest = cupsdValidateDest(host, resource, &(job->dtype), + if ((dest = cupsdValidateDest(attr->values[0].string.text, &(job->dtype), NULL)) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, @@ -3090,28 +3090,6 @@ start_job(cupsd_job_t *job, /* I - Job ID */ job->status = 0; memset(job->filters, 0, sizeof(job->filters)); - filterfds[1][0] = open("/dev/null", O_RDONLY); - - if (filterfds[1][0] < 0) - { - cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"/dev/null\" - %s.", - strerror(errno)); - snprintf(printer->state_message, sizeof(printer->state_message), - "Unable to open \"/dev/null\" - %s.", strerror(errno)); - - cupsdAddPrinterHistory(printer); - - cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, - "Job canceled because the server could not open /dev/null."); - - goto abort_job; - } - - fcntl(filterfds[1][0], F_SETFD, fcntl(filterfds[1][0], F_GETFD) | FD_CLOEXEC); - - cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job: filterfds[%d] = [ %d %d ]", - 1, filterfds[1][0], filterfds[1][1]); - for (i = 0, slot = 0, filter = (mime_filter_t *)cupsArrayFirst(filters); filter; i ++, filter = (mime_filter_t *)cupsArrayNext(filters)) @@ -3165,36 +3143,43 @@ start_job(cupsd_job_t *job, /* I - Job ID */ else { job->print_pipes[0] = -1; - if (!strncmp(printer->device_uri, "file:/dev/", 10) && - strcmp(printer->device_uri, "file:/dev/null")) - job->print_pipes[1] = open(printer->device_uri + 5, - O_WRONLY | O_EXCL); - else if (!strncmp(printer->device_uri, "file:///dev/", 12) && - strcmp(printer->device_uri, "file:///dev/null")) - job->print_pipes[1] = open(printer->device_uri + 7, - O_WRONLY | O_EXCL); + if (!strcmp(printer->device_uri, "file:/dev/null") || + !strcmp(printer->device_uri, "file:///dev/null")) + job->print_pipes[1] = -1; else - job->print_pipes[1] = open(printer->device_uri + 5, - O_WRONLY | O_CREAT | O_TRUNC, 0600); - - if (job->print_pipes[1] < 0) { - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unable to open output file \"%s\" - %s.", - printer->device_uri, strerror(errno)); - snprintf(printer->state_message, sizeof(printer->state_message), - "Unable to open output file \"%s\" - %s.", - printer->device_uri, strerror(errno)); - - cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, - "Job canceled because the server could not open the " - "output file."); + if (!strncmp(printer->device_uri, "file:/dev/", 10)) + job->print_pipes[1] = open(printer->device_uri + 5, + O_WRONLY | O_EXCL); + else if (!strncmp(printer->device_uri, "file:///dev/", 12)) + job->print_pipes[1] = open(printer->device_uri + 7, + O_WRONLY | O_EXCL); + else if (!strncmp(printer->device_uri, "file:///", 8)) + job->print_pipes[1] = open(printer->device_uri + 7, + O_WRONLY | O_CREAT | O_TRUNC, 0600); + else + job->print_pipes[1] = open(printer->device_uri + 5, + O_WRONLY | O_CREAT | O_TRUNC, 0600); - goto abort_job; - } + if (job->print_pipes[1] < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to open output file \"%s\" - %s.", + printer->device_uri, strerror(errno)); + snprintf(printer->state_message, sizeof(printer->state_message), + "Unable to open output file \"%s\" - %s.", + printer->device_uri, strerror(errno)); + + cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, + "Job canceled because the server could not open the " + "output file."); + + goto abort_job; + } - fcntl(job->print_pipes[1], F_SETFD, - fcntl(job->print_pipes[1], F_GETFD) | FD_CLOEXEC); + fcntl(job->print_pipes[1], F_SETFD, + fcntl(job->print_pipes[1], F_GETFD) | FD_CLOEXEC); + } } cupsdLogMessage(CUPSD_LOG_DEBUG2, @@ -3274,25 +3259,7 @@ start_job(cupsd_job_t *job, /* I - Job ID */ argv[0] = sani_uri; filterfds[slot][0] = -1; - filterfds[slot][1] = open("/dev/null", O_WRONLY); - - if (filterfds[slot][1] < 0) - { - cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"/dev/null\" - %s.", - strerror(errno)); - snprintf(printer->state_message, sizeof(printer->state_message), - "Unable to open \"/dev/null\" - %s.", strerror(errno)); - - cupsdAddPrinterHistory(printer); - - cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, - "Job canceled because the server could not open a file."); - - goto abort_job; - } - - fcntl(filterfds[slot][1], F_SETFD, - fcntl(filterfds[slot][1], F_GETFD) | FD_CLOEXEC); + filterfds[slot][1] = -1; cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job: backend=\"%s\"", command); diff --git a/scheduler/mime.c b/scheduler/mime.c index 0aa3d92e1..da82e4390 100644 --- a/scheduler/mime.c +++ b/scheduler/mime.c @@ -51,6 +51,7 @@ #include <stdlib.h> #include <ctype.h> +#include <cups/debug.h> #include <cups/dir.h> #include <cups/string.h> #include "mime.h" @@ -486,6 +487,8 @@ load_convs(mime_t *mime, /* I - MIME database */ if ((fp = cupsFileOpen(filename, "r")) == NULL) return; + DEBUG_printf(("\"%s\":\n", filename)); + /* * Then read each line from the file, skipping any comments in the file... */ @@ -496,6 +499,8 @@ load_convs(mime_t *mime, /* I - MIME database */ * Skip blank lines and lines starting with a #... */ + DEBUG_puts(line); + if (!line[0] || line[0] == '#') continue; @@ -544,7 +549,10 @@ load_convs(mime_t *mime, /* I - MIME database */ continue; if ((dsttype = mimeType(mime, super, type)) == NULL) + { + DEBUG_printf((" Destination type %s/%s not found!\n", super, type)); continue; + } /* * Then get the cost and filter program... @@ -575,7 +583,10 @@ load_convs(mime_t *mime, /* I - MIME database */ */ if (!add_fcache(filtercache, filter, filterpath)) + { + DEBUG_printf((" Filter %s not found in %s!\n", filter, filterpath)); continue; + } } /* @@ -655,6 +666,8 @@ load_types(mime_t *mime, /* I - MIME database */ if ((fp = cupsFileOpen(filename, "r")) == NULL) return; + DEBUG_printf(("\"%s\":\n", filename)); + /* * Then read each line from the file, skipping any comments in the file... */ @@ -665,6 +678,8 @@ load_types(mime_t *mime, /* I - MIME database */ * Skip blank lines and lines starting with a #... */ + DEBUG_puts(line); + if (!line[0] || line[0] == '#') continue; diff --git a/scheduler/newselect.txt b/scheduler/newselect.txt new file mode 100644 index 000000000..5cb9ab4ba --- /dev/null +++ b/scheduler/newselect.txt @@ -0,0 +1,115 @@ +Design Notes for New Poll/Select API in CUPSD - 2006-06-06 +---------------------------------------------------------- + +SUPPORTED APIS + + OS select poll epoll kqueue /dev/poll + -------------- ------ ------ ------ ------ --------- + AIX YES YES NO NO NO + FreeBSD YES YES NO YES NO + HP-UX YES YES NO NO NO + IRIX YES YES NO NO NO + Linux YES YES YES NO NO + MacOS X YES YES NO YES NO + NetBSD YES YES NO YES NO + OpenBSD YES YES NO YES NO + Solaris YES YES NO NO YES + Tru64 YES YES NO NO NO + Windows YES NO NO NO NO + + +HIGH-LEVEL API + + typedef void (*cupsd_selfunc_t)(void *data); + + void cupsdStartSelect(void); + void cupsdStopSelect(void); + void cupsdAddSelect(int fd, cupsd_selfunc_t read_cb, + cupsd_selfunc_t write_cb, void *data); + void cupsdRemoveSelect(int fd); + int cupsdDoSelect(int timeout); + + +IMPLEMENTATION STRATEGY + + 0. Common Stuff + a. CUPS array of file descriptor to callback functions + and data. + b. cupsdStartSelect() creates the array + c. cupsdStopSelect() destroys the array and all elements. + d. cupsdAddSelect() adds to the array and allocates a + new callback element. + e. cupsdRemoveSelect() removes from the array and frees + the callback element. + + 1. select() + a. Input/Output fd_set variables, copied to working + copies and then used with select(). + b. Loop through CUPS array, using FD_ISSET and calling + the read/ write callbacks as needed. + c. cupsdRemoveSelect() clears fd_set bit from main and + working sets. + d. cupsdStopSelect() frees all of the memory used by the + CUPS array and fd_set's. + + 2. poll() + a. Regular array of pollfd, sorted the same as the CUPS + array. + b. Loop through pollfd array, call the corresponding + read/write callbacks as needed. + c. cupsdAddSelect() adds first to CUPS array, then uses + current index to determine insertion point for pollfd + array. + d. cupsdRemoveSelect() needs to update cupsdDoSelect() + loop counter if <= current index. + e. cupsdStopSelect() frees all of the memory used by the + CUPS array and pollfd array. + + 3. epoll() + a. cupsdStartSelect() creates epoll file descriptor using + epoll_create() with the maximum fd count, and + allocates an events buffer for the maximum fd count. + b. cupsdAdd/RemoveSelect() uses epoll_ctl() to add + (EPOLL_CTL_ADD) or remove (EPOLL_CTL_DEL) a single + event using the level-triggered semantics. The event + user data field is a pointer to the new callback array + element. + c. cupsdDoSelect() uses epoll_wait() with the global event + buffer allocated in cupsdStartSelect() and then loops + through the events, using the user data field to find + the callback record. + d. cupsdStopSelect() closes the epoll file descriptor and + frees all of the memory used by the event buffer. + + 4. kqueue() + b. cupsdStartSelect() creates kqueue file descriptor + using kqyeue() function and allocates a global event + buffer. + c. cupsdAdd/RemoveSelect() uses EV_SET and kevent() to + register the changes. The event user data field is a + pointer to the new callback array element. + d. cupsdDoSelect() uses kevent() to poll for events and + loops through the events, using the user data field to + find the callback record. + e. cupsdStopSelect() closes the kqyeye() file descriptor + and frees all of the memory used by the event buffer. + + 5. /dev/poll + a. cupsdStartSelect() opens /dev/poll and allocates an + array of pollfd structs; on failure to open /dev/poll, + revert to poll() system call. + b. cupsdAddSelect() writes a single pollfd struct to + /dev/poll with the new file descriptor and the + POLLIN/POLLOUT flags. + c. cupsdRemoveSelect() writes a single pollfd struct to + /dev/poll with the file descriptor and the POLLREMOVE + flag. + d. cupsdDoSelect() uses the DP_POLL ioctl to retrieve + events from /dev/poll and then loops through the + returned pollfd array, looking up the file descriptors + as needed. + e. cupsdStopSelect() closes /dev/poll and frees the + pollfd array. + f. Need to benchmark to see if it is more efficient than + using poll() - this is the only mechanism that is O(n + log n), all of the others are O(n)... diff --git a/scheduler/printers.c b/scheduler/printers.c index f6d939a41..4c373658c 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -62,6 +62,7 @@ */ #include "cupsd.h" +#include <cups/dir.h> /* @@ -257,6 +258,11 @@ cupsdCreateCommonData(void) { int i; /* Looping var */ ipp_attribute_t *attr; /* Attribute data */ + cups_dir_t *dir; /* Notifier directory */ + cups_dentry_t *dent; /* Notifier directory entry */ + cups_array_t *notifiers; /* Notifier array */ + char filename[1024], /* Filename */ + *notifier; /* Current notifier */ static const int nups[] = /* number-up-supported values */ { 1, 2, 4, 6, 9, 16 }; static const ipp_orient_t orients[4] =/* orientation-requested-supported values */ @@ -406,10 +412,6 @@ cupsdCreateCommonData(void) /* copies-supported */ ippAddRange(CommonData, IPP_TAG_PRINTER, "copies-supported", 1, MaxCopies); - /* document-format-default */ - ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE, - "document-format-default", NULL, "application/octet-stream"); - /* generated-natural-language-supported */ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE, "generated-natural-language-supported", NULL, DefaultLanguage); @@ -502,11 +504,11 @@ cupsdCreateCommonData(void) ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "notify-max-events-supported", MaxEvents); - /* notify-notify-events-default */ + /* notify-events-default */ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "notify-events-default", NULL, "job-completed"); - /* notify-notify-events-supported */ + /* notify-events-supported */ ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "notify-events-supported", (int)(sizeof(notify_events) / sizeof(notify_events[0])), @@ -516,10 +518,31 @@ cupsdCreateCommonData(void) ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "notify-pull-method-supported", NULL, "ippget"); - /* TODO: scan notifier directory */ /* notify-schemes-supported */ - ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, - "notify-schemes-supported", NULL, "mailto"); + snprintf(filename, sizeof(filename), "%s/notifier", ServerBin); + if ((dir = cupsDirOpen(filename)) != NULL) + { + notifiers = cupsArrayNew((cups_array_func_t)strcmp, NULL); + + while ((dent = cupsDirRead(dir)) != NULL) + if (S_ISREG(dent->fileinfo.st_mode) && + (dent->fileinfo.st_mode & S_IXOTH) != 0) + cupsArrayAdd(notifiers, _cupsStrAlloc(dent->filename)); + + if (cupsArrayCount(notifiers) > 0) + { + attr = ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "notify-schemes-supported", + cupsArrayCount(notifiers), NULL, NULL); + + for (i = 0, notifier = (char *)cupsArrayFirst(notifiers); + notifier; + i ++, notifier = (char *)cupsArrayNext(notifiers)) + attr->values[i].string.text = notifier; + } + + cupsArrayDelete(notifiers); + } /* number-up-supported */ ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, @@ -665,7 +688,7 @@ cupsdDeletePrinter( dp = (cupsd_printer_t *)cupsArrayNext(Printers)) if (dp != p && (dp->type & CUPS_PRINTER_DEFAULT)) { - DefaultPrinter = p; + DefaultPrinter = dp; break; } } @@ -2404,18 +2427,25 @@ cupsdUpdatePrinters(void) const char * /* O - Printer or class name */ cupsdValidateDest( - const char *hostname, /* I - Host name */ - const char *resource, /* I - Resource name */ + const char *uri, /* I - Printer URI */ cups_ptype_t *dtype, /* O - Type (printer or class) */ cupsd_printer_t **printer) /* O - Printer pointer */ { cupsd_printer_t *p; /* Current printer */ char localname[1024],/* Localized hostname */ *lptr, /* Pointer into localized hostname */ - *sptr; /* Pointer into server name */ - - - DEBUG_printf(("cupsdValidateDest(\"%s\", \"%s\", %p, %p)\n", hostname, resource, + *sptr, /* Pointer into server name */ + *rptr, /* Pointer into resource */ + scheme[32], /* Scheme portion of URI */ + username[64], /* Username portion of URI */ + hostname[HTTP_MAX_HOST], + /* Host portion of URI */ + resource[HTTP_MAX_URI]; + /* Resource portion of URI */ + int port; /* Port portion of URI */ + + + DEBUG_printf(("cupsdValidateDest(uri=\"%s\", dtype=%p, printer=%p)\n", uri, dtype, printer)); /* @@ -2425,7 +2455,16 @@ cupsdValidateDest( if (printer) *printer = NULL; - *dtype = (cups_ptype_t)0; + if (dtype) + *dtype = (cups_ptype_t)0; + + /* + * Pull the hostname and resource from the URI... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), + username, sizeof(username), hostname, sizeof(hostname), + &port, resource, sizeof(resource)); /* * See if the resource is a class or printer... @@ -2437,7 +2476,7 @@ cupsdValidateDest( * Class... */ - resource += 9; + rptr = resource + 9; } else if (!strncmp(resource, "/printers/", 10)) { @@ -2445,7 +2484,7 @@ cupsdValidateDest( * Printer... */ - resource += 10; + rptr = resource + 10; } else { @@ -2460,17 +2499,19 @@ cupsdValidateDest( * See if the printer or class name exists... */ - p = cupsdFindDest(resource); + p = cupsdFindDest(rptr); - if (p == NULL && strchr(resource, '@') == NULL) + if (p == NULL && strchr(rptr, '@') == NULL) return (NULL); else if (p != NULL) { if (printer) *printer = p; - *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | - CUPS_PRINTER_REMOTE); + if (dtype) + *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_REMOTE); + return (p->name); } @@ -2479,7 +2520,7 @@ cupsdValidateDest( */ if (!strcasecmp(hostname, "localhost")) - hostname = ServerName; + strlcpy(hostname, ServerName, sizeof(hostname)); strlcpy(localname, hostname, sizeof(localname)); @@ -2521,13 +2562,15 @@ cupsdValidateDest( p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) if (!strcasecmp(p->hostname, localname) && - !strcasecmp(p->name, resource)) + !strcasecmp(p->name, rptr)) { if (printer) *printer = p; - *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | - CUPS_PRINTER_REMOTE); + if (dtype) + *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_REMOTE); + return (p->name); } @@ -2776,6 +2819,10 @@ add_printer_defaults(cupsd_printer_t *p)/* I - Printer */ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "copies-default", 1); + if (!cupsGetOption("document-format", p->num_options, p->options)) + ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE, + "document-format-default", NULL, "application/octet-stream"); + if (!cupsGetOption("job-hold-until", p->num_options, p->options)) ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "job-hold-until-default", NULL, "no-hold"); diff --git a/scheduler/printers.h b/scheduler/printers.h index 4b1629098..b25af075f 100644 --- a/scheduler/printers.h +++ b/scheduler/printers.h @@ -135,8 +135,7 @@ extern void cupsdStopPrinter(cupsd_printer_t *p, int update); extern void cupsdUpdatePrinters(void); extern cupsd_quota_t *cupsdUpdateQuota(cupsd_printer_t *p, const char *username, int pages, int k); -extern const char *cupsdValidateDest(const char *hostname, - const char *resource, +extern const char *cupsdValidateDest(const char *uri, cups_ptype_t *dtype, cupsd_printer_t **printer); extern void cupsdWritePrintcap(void); diff --git a/scheduler/subscriptions.c b/scheduler/subscriptions.c index 56f21d1d6..81dd255ac 100644 --- a/scheduler/subscriptions.c +++ b/scheduler/subscriptions.c @@ -36,7 +36,6 @@ * cupsdStopAllNotifiers() - Stop all notifier processes. * cupsdUpdateNotifierStatus() - Read messages from notifiers. * cupsd_compare_subscriptions() - Compare two subscriptions. - * cupsd_delete_all_events() - Delete all cached events. * cupsd_delete_event() - Delete a single event... * cupsd_send_dbus() - Send a DBUS notification... * cupsd_send_notification() - Send a notification for the specified @@ -61,7 +60,6 @@ static int cupsd_compare_subscriptions(cupsd_subscription_t *first, cupsd_subscription_t *second, void *unused); -static void cupsd_delete_all_events(void); static void cupsd_delete_event(cupsd_event_t *event); #ifdef HAVE_DBUS static void cupsd_send_dbus(cupsd_eventmask_t event, cupsd_printer_t *dest, @@ -114,29 +112,11 @@ cupsdAddEvent( } /* - * Allocate memory for the event cache as needed... - */ - - if (!Events) - { - Events = calloc(MaxEvents, sizeof(cupsd_event_t *)); - NumEvents = 0; - - if (!Events) - { - cupsdLogMessage(CUPSD_LOG_CRIT, - "Unable to allocate memory for event cache - %s", - strerror(errno)); - return; - } - } - - /* * Then loop through the subscriptions and add the event to the corresponding * caches... */ - for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), temp = NULL; + for (temp = NULL, sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); sub; sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) { @@ -149,185 +129,168 @@ cupsdAddEvent( (sub->job == job || !sub->job)) { /* - * Need this event... + * Need this event, so create a new event record... */ - if (!temp) + if ((temp = (cupsd_event_t *)calloc(1, sizeof(cupsd_event_t))) == NULL) { - /* - * Create the new event record... - */ + cupsdLogMessage(CUPSD_LOG_CRIT, + "Unable to allocate memory for event - %s", + strerror(errno)); + return; + } - if ((temp = (cupsd_event_t *)calloc(1, sizeof(cupsd_event_t))) == NULL) - { - cupsdLogMessage(CUPSD_LOG_CRIT, - "Unable to allocate memory for event - %s", - strerror(errno)); - return; - } + temp->event = event; + temp->time = time(NULL); + temp->attrs = ippNew(); + temp->job = job; + temp->dest = dest; - temp->event = event; - temp->time = time(NULL); - temp->attrs = ippNew(); - temp->job = job; - temp->dest = dest; + /* + * Add common event notification attributes... + */ - /* - * Add common event notification attributes... - */ + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_CHARSET, + "notify-charset", NULL, "utf-8"); - ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, - "notify-subscription-id", sub->id); + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_LANGUAGE, + "notify-natural-langugage", NULL, "en-US"); - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, - "notify-subscribed-event", NULL, cupsdEventName(event)); + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, + "notify-subscription-id", sub->id); - ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, - "printer-up-time", time(NULL)); + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, + "notify-sequence-number", sub->next_event_id); - va_start(ap, text); - vsnprintf(ftext, sizeof(ftext), text, ap); - va_end(ap); + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, + "notify-subscribed-event", NULL, cupsdEventName(event)); - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_TEXT, - "notify-text", NULL, ftext); + if (sub->user_data_len > 0) + ippAddOctetString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + "notify-user-data", sub->user_data, + sub->user_data_len); - if (dest) - { - /* - * Add printer attributes... - */ + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, + "printer-up-time", time(NULL)); - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_URI, - "notify-printer-uri", NULL, dest->uri); + va_start(ap, text); + vsnprintf(ftext, sizeof(ftext), text, ap); + va_end(ap); - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_NAME, - "printer-name", NULL, dest->name); + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_TEXT, + "notify-text", NULL, ftext); - ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_ENUM, - "printer-state", dest->state); + if (dest) + { + /* + * Add printer attributes... + */ - if (dest->num_reasons == 0) - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, - IPP_TAG_KEYWORD, "printer-state-reasons", NULL, - dest->state == IPP_PRINTER_STOPPED ? "paused" : "none"); - else - ippAddStrings(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, - IPP_TAG_KEYWORD, "printer-state-reasons", - dest->num_reasons, NULL, - (const char * const *)dest->reasons); + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_URI, + "notify-printer-uri", NULL, dest->uri); - ippAddBoolean(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, - "printer-is-accepting-jobs", dest->accepting); - } + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_NAME, + "printer-name", NULL, dest->name); - if (job) - { - /* - * Add job attributes... - */ + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_ENUM, + "printer-state", dest->state); - ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, - "notify-job-id", job->id); - ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_ENUM, - "job-state", job->state_value); + if (dest->num_reasons == 0) + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "printer-state-reasons", NULL, + dest->state == IPP_PRINTER_STOPPED ? "paused" : "none"); + else + ippAddStrings(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "printer-state-reasons", + dest->num_reasons, NULL, + (const char * const *)dest->reasons); - if ((attr = ippFindAttribute(job->attrs, "job-name", - IPP_TAG_NAME)) != NULL) - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_NAME, - "job-name", NULL, attr->values[0].string.text); + ippAddBoolean(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + "printer-is-accepting-jobs", dest->accepting); + } - switch (job->state_value) - { - case IPP_JOB_PENDING : - if (dest && dest->state == IPP_PRINTER_STOPPED) - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, - IPP_TAG_KEYWORD, "job-state-reasons", NULL, - "printer-stopped"); - else - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, - IPP_TAG_KEYWORD, "job-state-reasons", NULL, - "none"); - break; - - case IPP_JOB_HELD : - if (ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD) != NULL || - ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME) != NULL) - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, - IPP_TAG_KEYWORD, "job-state-reasons", NULL, - "job-hold-until-specified"); - else - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, - IPP_TAG_KEYWORD, "job-state-reasons", NULL, - "job-incoming"); - break; - - case IPP_JOB_PROCESSING : - ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, - IPP_TAG_KEYWORD, "job-state-reasons", NULL, - "job-printing"); - break; + if (job) + { + /* + * Add job attributes... + */ - case IPP_JOB_STOPPED : + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, + "notify-job-id", job->id); + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_ENUM, + "job-state", job->state_value); + + if ((attr = ippFindAttribute(job->attrs, "job-name", + IPP_TAG_NAME)) != NULL) + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_NAME, + "job-name", NULL, attr->values[0].string.text); + + switch (job->state_value) + { + case IPP_JOB_PENDING : + if (dest && dest->state == IPP_PRINTER_STOPPED) ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, - "job-stopped"); - break; - - case IPP_JOB_CANCELLED : + "printer-stopped"); + else ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, - "job-canceled-by-user"); - break; + "none"); + break; - case IPP_JOB_ABORTED : + case IPP_JOB_HELD : + if (ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD) != NULL || + ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME) != NULL) ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, - "aborted-by-system"); - break; - - case IPP_JOB_COMPLETED : + "job-hold-until-specified"); + else ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, - "job-completed-successfully"); - break; - } - - ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, - "job-impressions-completed", - job->sheets ? job->sheets->values[0].integer : 0); + "job-incoming"); + break; + + case IPP_JOB_PROCESSING : + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "job-printing"); + break; + + case IPP_JOB_STOPPED : + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "job-stopped"); + break; + + case IPP_JOB_CANCELLED : + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "job-canceled-by-user"); + break; + + case IPP_JOB_ABORTED : + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "aborted-by-system"); + break; + + case IPP_JOB_COMPLETED : + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "job-completed-successfully"); + break; } - /* - * Purge an old event as needed... - */ - - if (NumEvents >= MaxEvents) - { - /* - * Purge the oldest event in the cache... - */ - - cupsd_delete_event(Events[0]); - - NumEvents --; - - memmove(Events, Events + 1, NumEvents * sizeof(cupsd_event_t *)); - } + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, + "job-impressions-completed", + job->sheets ? job->sheets->values[0].integer : 0); /* - * Add the new event to the main cache... + * Send the notification for this subscription... */ - Events[NumEvents] = temp; - NumEvents ++; + cupsd_send_notification(sub, temp); } - - /* - * Send the notification for this subscription... - */ - - cupsd_send_notification(sub, temp); } } @@ -438,8 +401,6 @@ cupsdDeleteAllSubscriptions(void) cupsd_subscription_t *sub; /* Subscription */ - cupsd_delete_all_events(); - if (!Subscriptions) return; @@ -462,6 +423,9 @@ cupsdDeleteSubscription( cupsd_subscription_t *sub, /* I - Subscription object */ int update) /* I - 1 = update subscriptions.conf */ { + int i; /* Looping var */ + + /* * Close the pipe to the notifier as needed... */ @@ -483,7 +447,12 @@ cupsdDeleteSubscription( cupsdClearString(&(sub->recipient)); if (sub->events) + { + for (i = 0; i < sub->num_events; i ++) + cupsd_delete_event(sub->events[i]); + free(sub->events); + } free(sub); @@ -1300,27 +1269,6 @@ cupsd_compare_subscriptions( /* - * 'cupsd_delete_all_events()' - Delete all cached events. - */ - -static void -cupsd_delete_all_events(void) -{ - int i; /* Looping var */ - - - if (MaxEvents <= 0 || !Events) - return; - - for (i = 0; i < NumEvents; i ++) - cupsd_delete_event(Events[i]); - - free(Events); - Events = NULL; -} - - -/* * 'cupsd_delete_event()' - Delete a single event... * * Oldest events must be deleted first, otherwise the subscription cache @@ -1330,43 +1278,6 @@ cupsd_delete_all_events(void) static void cupsd_delete_event(cupsd_event_t *event)/* I - Event to delete */ { - cupsd_subscription_t *sub; /* Current subscription */ - - - /* - * Loop through the subscriptions and look for the event in the cache... - */ - - for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); - sub; - sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) - { - /* - * Only check the first event in the subscription cache, since the - * caller will only delete the oldest event in the cache... - */ - - if (sub->num_events > 0 && sub->events[0] == event) - { - /* - * Remove this event... - */ - - sub->num_events --; - sub->first_event_id ++; - - if (sub->num_events > 0) - { - /* - * Shift other events upward in cache... - */ - - memmove(sub->events, sub->events + 1, - sub->num_events * sizeof(cupsd_event_t *)); - } - } - } - /* * Free memory... */ @@ -1490,6 +1401,25 @@ cupsd_send_notification( } /* + * Purge an old event as needed... + */ + + if (sub->num_events >= MaxEvents) + { + /* + * Purge the oldest event in the cache... + */ + + cupsd_delete_event(sub->events[0]); + + sub->num_events --; + sub->first_event_id ++; + + memmove(sub->events, sub->events + 1, + sub->num_events * sizeof(cupsd_event_t *)); + } + + /* * Add the event to the subscription. Since the events array is * always MaxEvents in length, and since we will have already * removed an event from the subscription cache if we hit the diff --git a/scheduler/subscriptions.h b/scheduler/subscriptions.h index 8f98199ca..f9243f16e 100644 --- a/scheduler/subscriptions.h +++ b/scheduler/subscriptions.h @@ -131,11 +131,9 @@ VAR int MaxSubscriptions VALUE(100), VAR cups_array_t *Subscriptions VALUE(NULL); /* Active subscriptions */ -VAR int MaxEvents VALUE(100), /* Maximum number of events */ - NumEvents VALUE(0); /* Number of active events */ -VAR cupsd_event_t **Events VALUE(NULL); /* Active events */ +VAR int MaxEvents VALUE(100); /* Maximum number of events */ -VAR unsigned LastEvent VALUE(0); /* Last events processed */ +VAR unsigned LastEvent VALUE(0); /* Last event(s) processed */ VAR int NotifierPipes[2] VALUE2(-1, -1); /* Pipes for notifier error/debug output */ VAR cupsd_statbuf_t *NotifierStatusBuffer VALUE(NULL); diff --git a/scheduler/testmime.c b/scheduler/testmime.c index 196d1211f..ccba4d59c 100644 --- a/scheduler/testmime.c +++ b/scheduler/testmime.c @@ -71,7 +71,7 @@ main(int argc, /* I - Number of command-line args */ mime = NULL; src = NULL; dst = NULL; - filter_path = "../filter:../pdftops"; + filter_path = "../filter:../pdftops:" CUPS_SERVERBIN "/filter"; for (i = 1; i < argc; i ++) if (!strcmp(argv[i], "-d")) |