summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjacobs <none@none>2006-06-22 13:28:31 -0700
committerjacobs <none@none>2006-06-22 13:28:31 -0700
commit355b4669e025ff377602b6fc7caaf30dbc218371 (patch)
tree29a740456e8d09f935e18068ce72814285fafeec
parent5d0bc3ededb82d77f7c33d8f58e517a837ba5140 (diff)
downloadillumos-joyent-355b4669e025ff377602b6fc7caaf30dbc218371.tar.gz
LSARC/2003/547 PAPI Print Commands
LSARC/2006/172 PAPI Print Commands Packaging Breakout 4144591 lpstat -d reports *process* default printer as *system* default printer 4299193 lp -cd <queue> <file> causes multiple -d options errors 4327963 RFE cancel on local queue should not require in.lpd 4331220 lpmove doesn't work on remote print queues 4470602 Customer wants to increase print limit of 52 files to 300 4949866 lpstat shows FAILED printers due to expanded status message 4994469 lpadmin doesn't add filter definitions for printers 6302778 RUNPATH & RPATH errors in SUNWipplu package 6314007 lpstat should report paper type list supported by a printer 6317991 lprm -Pprintername - command results in aSegmentation fault 6338002 lpsched support for PAPI is incomplete 6346505 print commands should use PAPI for service interaction (LSARC/2003/547) 6364267 psm-lpsched has replicated code 6389273 RUNPATH and RPATH failures in SUNWippcore --HG-- rename : usr/src/cmd/lp/cmd/cancel.c => deleted_files/usr/src/cmd/lp/cmd/cancel.c rename : usr/src/cmd/lp/cmd/comb.c => deleted_files/usr/src/cmd/lp/cmd/comb.c rename : usr/src/cmd/lp/cmd/lp.c => deleted_files/usr/src/cmd/lp/cmd/lp.c rename : usr/src/cmd/lp/cmd/lpc/Makefile => deleted_files/usr/src/cmd/lp/cmd/lpc/Makefile rename : usr/src/cmd/lp/cmd/lpc/cmds.c => deleted_files/usr/src/cmd/lp/cmd/lpc/cmds.c rename : usr/src/cmd/lp/cmd/lpc/cmdtab.c => deleted_files/usr/src/cmd/lp/cmd/lpc/cmdtab.c rename : usr/src/cmd/lp/cmd/lpc/fatalmsg.c => deleted_files/usr/src/cmd/lp/cmd/lpc/fatalmsg.c rename : usr/src/cmd/lp/cmd/lpc/global.c => deleted_files/usr/src/cmd/lp/cmd/lpc/global.c rename : usr/src/cmd/lp/cmd/lpc/lpc.c => deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.c rename : usr/src/cmd/lp/cmd/lpc/lpc.h => deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.h rename : usr/src/cmd/lp/cmd/lpc/process.c => deleted_files/usr/src/cmd/lp/cmd/lpc/process.c rename : usr/src/cmd/lp/cmd/lpc/sndrcv.c => deleted_files/usr/src/cmd/lp/cmd/lpc/sndrcv.c rename : usr/src/cmd/lp/cmd/lpc/topq.c => deleted_files/usr/src/cmd/lp/cmd/lpc/topq.c rename : usr/src/cmd/lp/cmd/lpmove.c => deleted_files/usr/src/cmd/lp/cmd/lpmove.c rename : usr/src/cmd/lp/cmd/lpstat/Makefile => deleted_files/usr/src/cmd/lp/cmd/lpstat/Makefile rename : usr/src/cmd/lp/cmd/lpstat/accept.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/accept.c rename : usr/src/cmd/lp/cmd/lpstat/add_mounted.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/add_mounted.c rename : usr/src/cmd/lp/cmd/lpstat/charset.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/charset.c rename : usr/src/cmd/lp/cmd/lpstat/class.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/class.c rename : usr/src/cmd/lp/cmd/lpstat/device.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/device.c rename : usr/src/cmd/lp/cmd/lpstat/done.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/done.c rename : usr/src/cmd/lp/cmd/lpstat/form.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/form.c rename : usr/src/cmd/lp/cmd/lpstat/lpstat.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.c rename : usr/src/cmd/lp/cmd/lpstat/lpstat.h => deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.h rename : usr/src/cmd/lp/cmd/lpstat/output.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/output.c rename : usr/src/cmd/lp/cmd/lpstat/parse.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/parse.c rename : usr/src/cmd/lp/cmd/lpstat/printer.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/printer.c rename : usr/src/cmd/lp/cmd/lpstat/request.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/request.c rename : usr/src/cmd/lp/cmd/lpstat/send_message.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/send_message.c rename : usr/src/cmd/lp/lib/papi/attribute.c => deleted_files/usr/src/cmd/lp/lib/papi/attribute.c rename : usr/src/cmd/lp/lib/papi/list.c => deleted_files/usr/src/cmd/lp/lib/papi/list.c rename : usr/src/cmd/lp/lib/papi/papi.h => deleted_files/usr/src/cmd/lp/lib/papi/papi.h rename : usr/src/cmd/lp/lib/papi/status.c => deleted_files/usr/src/cmd/lp/lib/papi/status.c rename : usr/src/cmd/print/cancel/Makefile => deleted_files/usr/src/cmd/print/cancel/Makefile rename : usr/src/cmd/print/cancel/cancel.c => deleted_files/usr/src/cmd/print/cancel/cancel.c rename : usr/src/cmd/print/cancel/cancel_list.c => deleted_files/usr/src/cmd/print/cancel/cancel_list.c rename : usr/src/cmd/print/cancel/cancel_list.h => deleted_files/usr/src/cmd/print/cancel/cancel_list.h rename : usr/src/cmd/print/lp/Makefile => deleted_files/usr/src/cmd/print/lp/Makefile rename : usr/src/cmd/print/lpmove/Makefile => deleted_files/usr/src/cmd/print/lpmove/Makefile rename : usr/src/cmd/print/lpmove/lpmove.c => deleted_files/usr/src/cmd/print/lpmove/lpmove.c rename : usr/src/cmd/print/lpstat/Makefile => deleted_files/usr/src/cmd/print/lpstat/Makefile rename : usr/src/cmd/print/lpstat/bsd-functions.c => deleted_files/usr/src/cmd/print/lpstat/bsd-functions.c rename : usr/src/cmd/print/lpstat/bsd-functions.h => deleted_files/usr/src/cmd/print/lpstat/bsd-functions.h rename : usr/src/cmd/print/lpstat/lpstat.c => deleted_files/usr/src/cmd/print/lpstat/lpstat.c rename : usr/src/cmd/print/lpstat/parse.h => deleted_files/usr/src/cmd/print/lpstat/parse.h rename : usr/src/cmd/print/lpstat/parse_bsd.c => deleted_files/usr/src/cmd/print/lpstat/parse_bsd.c rename : usr/src/cmd/print/lpstat/sysv-functions.c => deleted_files/usr/src/cmd/print/lpstat/sysv-functions.c rename : usr/src/cmd/print/lpstat/sysv-functions.h => deleted_files/usr/src/cmd/print/lpstat/sysv-functions.h rename : usr/src/cmd/print/scripts/accept => deleted_files/usr/src/cmd/print/scripts/accept rename : usr/src/cmd/lp/lib/papi/mapfile-vers => usr/src/cmd/lp/lib/papi/mapfile rename : usr/src/cmd/print/lp/cleanup.xml => usr/src/cmd/print/gateway/cleanup.xml rename : usr/src/cmd/print/lp/print-cleanup => usr/src/cmd/print/gateway/print-cleanup rename : usr/src/cmd/print/lp/lp.c => usr/src/cmd/print/gateway/printd.c rename : usr/src/lib/print/job.c => usr/src/lib/print/libprint/common/job.c rename : usr/src/lib/print/job.h => usr/src/lib/print/libprint/common/job.h rename : usr/src/lib/print/list.c => usr/src/lib/print/libprint/common/list.c rename : usr/src/lib/print/list.h => usr/src/lib/print/libprint/common/list.h rename : usr/src/lib/print/llib-lprint => usr/src/lib/print/libprint/common/llib-lprint rename : usr/src/lib/print/mapfile-vers => usr/src/lib/print/libprint/common/mapfile-vers rename : usr/src/lib/print/misc.c => usr/src/lib/print/libprint/common/misc.c rename : usr/src/lib/print/misc.h => usr/src/lib/print/libprint/common/misc.h rename : usr/src/lib/print/network.c => usr/src/lib/print/libprint/common/network.c rename : usr/src/lib/print/network.h => usr/src/lib/print/libprint/common/network.h rename : usr/src/lib/print/ns.c => usr/src/lib/print/libprint/common/ns.c rename : usr/src/lib/print/ns.h => usr/src/lib/print/libprint/common/ns.h rename : usr/src/lib/print/ns_bsd_addr.c => usr/src/lib/print/libprint/common/ns_bsd_addr.c rename : usr/src/lib/print/ns_cmn_kvp.c => usr/src/lib/print/libprint/common/ns_cmn_kvp.c rename : usr/src/lib/print/ns_cmn_printer.c => usr/src/lib/print/libprint/common/ns_cmn_printer.c rename : usr/src/lib/print/nss_convert.c => usr/src/lib/print/libprint/common/nss_convert.c rename : usr/src/lib/print/nss_ldap.c => usr/src/lib/print/libprint/common/nss_ldap.c rename : usr/src/lib/print/nss_printer.c => usr/src/lib/print/libprint/common/nss_printer.c rename : usr/src/lib/print/nss_write.c => usr/src/lib/print/libprint/common/nss_write.c rename : usr/src/lib/print/sunPrinter.at.conf.txt => usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt rename : usr/src/lib/print/sunPrinter.oc.conf.txt => usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/cancel.c (renamed from usr/src/cmd/lp/cmd/cancel.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/comb.c (renamed from usr/src/cmd/lp/cmd/comb.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lp.c (renamed from usr/src/cmd/lp/cmd/lp.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpc/Makefile (renamed from usr/src/cmd/lp/cmd/lpc/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpc/cmds.c (renamed from usr/src/cmd/lp/cmd/lpc/cmds.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpc/cmdtab.c (renamed from usr/src/cmd/lp/cmd/lpc/cmdtab.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpc/fatalmsg.c (renamed from usr/src/cmd/lp/cmd/lpc/fatalmsg.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpc/global.c (renamed from usr/src/cmd/lp/cmd/lpc/global.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.c (renamed from usr/src/cmd/lp/cmd/lpc/lpc.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.h (renamed from usr/src/cmd/lp/cmd/lpc/lpc.h)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpc/process.c (renamed from usr/src/cmd/lp/cmd/lpc/process.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpc/sndrcv.c (renamed from usr/src/cmd/lp/cmd/lpc/sndrcv.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpc/topq.c (renamed from usr/src/cmd/lp/cmd/lpc/topq.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpmove.c (renamed from usr/src/cmd/lp/cmd/lpmove.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/Makefile (renamed from usr/src/cmd/lp/cmd/lpstat/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/accept.c (renamed from usr/src/cmd/lp/cmd/lpstat/accept.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/add_mounted.c (renamed from usr/src/cmd/lp/cmd/lpstat/add_mounted.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/charset.c (renamed from usr/src/cmd/lp/cmd/lpstat/charset.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/class.c (renamed from usr/src/cmd/lp/cmd/lpstat/class.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/device.c (renamed from usr/src/cmd/lp/cmd/lpstat/device.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/done.c (renamed from usr/src/cmd/lp/cmd/lpstat/done.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/form.c (renamed from usr/src/cmd/lp/cmd/lpstat/form.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.c (renamed from usr/src/cmd/lp/cmd/lpstat/lpstat.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.h (renamed from usr/src/cmd/lp/cmd/lpstat/lpstat.h)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/output.c (renamed from usr/src/cmd/lp/cmd/lpstat/output.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/parse.c (renamed from usr/src/cmd/lp/cmd/lpstat/parse.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/printer.c (renamed from usr/src/cmd/lp/cmd/lpstat/printer.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/request.c (renamed from usr/src/cmd/lp/cmd/lpstat/request.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/cmd/lpstat/send_message.c (renamed from usr/src/cmd/lp/cmd/lpstat/send_message.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/lib/papi/attribute.c (renamed from usr/src/cmd/lp/lib/papi/attribute.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/lib/papi/list.c (renamed from usr/src/cmd/lp/lib/papi/list.c)0
-rw-r--r--deleted_files/usr/src/cmd/lp/lib/papi/papi.h (renamed from usr/src/cmd/lp/lib/papi/papi.h)0
-rw-r--r--deleted_files/usr/src/cmd/lp/lib/papi/status.c (renamed from usr/src/cmd/lp/lib/papi/status.c)0
-rw-r--r--deleted_files/usr/src/cmd/print/cancel/Makefile (renamed from usr/src/cmd/print/cancel/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/print/cancel/cancel.c (renamed from usr/src/cmd/print/cancel/cancel.c)0
-rw-r--r--deleted_files/usr/src/cmd/print/cancel/cancel_list.c (renamed from usr/src/cmd/print/cancel/cancel_list.c)0
-rw-r--r--deleted_files/usr/src/cmd/print/cancel/cancel_list.h (renamed from usr/src/cmd/print/cancel/cancel_list.h)0
-rw-r--r--deleted_files/usr/src/cmd/print/lp/Makefile (renamed from usr/src/cmd/print/lp/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/print/lpmove/Makefile (renamed from usr/src/cmd/print/lpmove/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/print/lpmove/lpmove.c (renamed from usr/src/cmd/print/lpmove/lpmove.c)0
-rw-r--r--deleted_files/usr/src/cmd/print/lpstat/Makefile (renamed from usr/src/cmd/print/lpstat/Makefile)0
-rw-r--r--deleted_files/usr/src/cmd/print/lpstat/bsd-functions.c (renamed from usr/src/cmd/print/lpstat/bsd-functions.c)0
-rw-r--r--deleted_files/usr/src/cmd/print/lpstat/bsd-functions.h (renamed from usr/src/cmd/print/lpstat/bsd-functions.h)0
-rw-r--r--deleted_files/usr/src/cmd/print/lpstat/lpstat.c (renamed from usr/src/cmd/print/lpstat/lpstat.c)0
-rw-r--r--deleted_files/usr/src/cmd/print/lpstat/parse.h (renamed from usr/src/cmd/print/lpstat/parse.h)0
-rw-r--r--deleted_files/usr/src/cmd/print/lpstat/parse_bsd.c (renamed from usr/src/cmd/print/lpstat/parse_bsd.c)0
-rw-r--r--deleted_files/usr/src/cmd/print/lpstat/sysv-functions.c (renamed from usr/src/cmd/print/lpstat/sysv-functions.c)0
-rw-r--r--deleted_files/usr/src/cmd/print/lpstat/sysv-functions.h (renamed from usr/src/cmd/print/lpstat/sysv-functions.h)0
-rw-r--r--deleted_files/usr/src/cmd/print/scripts/accept (renamed from usr/src/cmd/print/scripts/accept)0
-rw-r--r--usr/src/cmd/lp/cmd/Makefile35
-rw-r--r--usr/src/cmd/lp/cmd/adaptor/Makefile2
-rw-r--r--usr/src/cmd/lp/cmd/adaptor/cancel_job.c2
-rw-r--r--usr/src/cmd/lp/lib/access/Makefile10
-rw-r--r--usr/src/cmd/lp/lib/papi/Makefile13
-rw-r--r--usr/src/cmd/lp/lib/papi/job.c256
-rw-r--r--usr/src/cmd/lp/lib/papi/library.c98
-rw-r--r--usr/src/cmd/lp/lib/papi/lpsched-jobs.c254
-rw-r--r--usr/src/cmd/lp/lib/papi/lpsched-misc.c51
-rw-r--r--usr/src/cmd/lp/lib/papi/lpsched-msgs.c288
-rw-r--r--usr/src/cmd/lp/lib/papi/lpsched-printers.c237
-rw-r--r--usr/src/cmd/lp/lib/papi/lpsched-service.c13
-rw-r--r--usr/src/cmd/lp/lib/papi/mapfile151
-rw-r--r--usr/src/cmd/lp/lib/papi/mapfile-vers125
-rw-r--r--usr/src/cmd/lp/lib/papi/papi_impl.h40
-rw-r--r--usr/src/cmd/lp/lib/papi/ppd.c164
-rw-r--r--usr/src/cmd/lp/lib/papi/printer.c171
-rw-r--r--usr/src/cmd/lp/lib/papi/service.c34
-rw-r--r--usr/src/cmd/print/Makefile14
-rw-r--r--usr/src/cmd/print/Makefile.sp10
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/Makefile84
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/accept.c104
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/cancel.c127
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/common.c491
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/common.h66
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/disable.c149
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/enable.c104
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/in.lpd.c242
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/lp.c328
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/lpc.c540
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/lpmove.c165
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/lpq.c134
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/lpr.c270
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/lprm.c101
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/lpstat.c1015
-rw-r--r--usr/src/cmd/print/bsd-sysv-commands/reject.c108
-rw-r--r--usr/src/cmd/print/gateway/Makefile70
-rw-r--r--usr/src/cmd/print/gateway/adaptor.c2
-rw-r--r--usr/src/cmd/print/gateway/cleanup.xml (renamed from usr/src/cmd/print/lp/cleanup.xml)0
-rw-r--r--usr/src/cmd/print/gateway/print-cleanup (renamed from usr/src/cmd/print/lp/print-cleanup)0
-rw-r--r--usr/src/cmd/print/gateway/printd.c336
-rw-r--r--usr/src/cmd/print/gateway/translators/cascade/cascade.c17
-rw-r--r--usr/src/cmd/print/gateway/translators/test/test.c11
-rw-r--r--usr/src/cmd/print/lp/lp.c1281
-rw-r--r--usr/src/cmd/print/lpget/lpget.c15
-rw-r--r--usr/src/cmd/print/lpset/lpset.c13
-rw-r--r--usr/src/cmd/print/scripts/Makefile24
-rw-r--r--usr/src/cmd/print/scripts/lpadmin74
-rw-r--r--usr/src/lib/print/Makefile108
-rw-r--r--usr/src/lib/print/job.h145
-rw-r--r--usr/src/lib/print/libhttp-core/Makefile56
-rw-r--r--usr/src/lib/print/libhttp-core/Makefile.com64
-rw-r--r--usr/src/lib/print/libhttp-core/common/debug.h70
-rw-r--r--usr/src/lib/print/libhttp-core/common/http-addr.c371
-rw-r--r--usr/src/lib/print/libhttp-core/common/http-private.h115
-rw-r--r--usr/src/lib/print/libhttp-core/common/http-support.c379
-rw-r--r--usr/src/lib/print/libhttp-core/common/http.c2569
-rw-r--r--usr/src/lib/print/libhttp-core/common/http.h436
-rw-r--r--usr/src/lib/print/libhttp-core/common/mapfile58
-rw-r--r--usr/src/lib/print/libhttp-core/i386/Makefile30
-rw-r--r--usr/src/lib/print/libhttp-core/sparc/Makefile30
-rw-r--r--usr/src/lib/print/libipp-core/Makefile56
-rw-r--r--usr/src/lib/print/libipp-core/Makefile.com58
-rw-r--r--usr/src/lib/print/libipp-core/common/ipp.c136
-rw-r--r--usr/src/lib/print/libipp-core/common/ipp.h348
-rw-r--r--usr/src/lib/print/libipp-core/common/ipp_types.c303
-rw-r--r--usr/src/lib/print/libipp-core/common/mapfile48
-rw-r--r--usr/src/lib/print/libipp-core/common/read.c666
-rw-r--r--usr/src/lib/print/libipp-core/common/strings.c411
-rw-r--r--usr/src/lib/print/libipp-core/common/write.c415
-rw-r--r--usr/src/lib/print/libipp-core/i386/Makefile30
-rw-r--r--usr/src/lib/print/libipp-core/sparc/Makefile30
-rw-r--r--usr/src/lib/print/libipp-listener/Makefile56
-rw-r--r--usr/src/lib/print/libipp-listener/Makefile.com67
-rw-r--r--usr/src/lib/print/libipp-listener/common/cancel-job.c96
-rw-r--r--usr/src/lib/print/libipp-listener/common/common.c313
-rw-r--r--usr/src/lib/print/libipp-listener/common/create-job.c108
-rw-r--r--usr/src/lib/print/libipp-listener/common/cups-accept-jobs.c68
-rw-r--r--usr/src/lib/print/libipp-listener/common/cups-get-classes.c90
-rw-r--r--usr/src/lib/print/libipp-listener/common/cups-get-default.c81
-rw-r--r--usr/src/lib/print/libipp-listener/common/cups-get-printers.c91
-rw-r--r--usr/src/lib/print/libipp-listener/common/cups-move-job.c103
-rw-r--r--usr/src/lib/print/libipp-listener/common/cups-reject-jobs.c68
-rw-r--r--usr/src/lib/print/libipp-listener/common/disable-printer.c77
-rw-r--r--usr/src/lib/print/libipp-listener/common/enable-printer.c68
-rw-r--r--usr/src/lib/print/libipp-listener/common/get-job-attributes.c89
-rw-r--r--usr/src/lib/print/libipp-listener/common/get-jobs.c99
-rw-r--r--usr/src/lib/print/libipp-listener/common/get-printer-attributes.c92
-rw-r--r--usr/src/lib/print/libipp-listener/common/hold-job.c96
-rw-r--r--usr/src/lib/print/libipp-listener/common/ipp-listener.c455
-rw-r--r--usr/src/lib/print/libipp-listener/common/ipp-listener.h70
-rw-r--r--usr/src/lib/print/libipp-listener/common/mapfile39
-rw-r--r--usr/src/lib/print/libipp-listener/common/pause-printer.c68
-rw-r--r--usr/src/lib/print/libipp-listener/common/print-job.c123
-rw-r--r--usr/src/lib/print/libipp-listener/common/purge-jobs.c71
-rw-r--r--usr/src/lib/print/libipp-listener/common/release-job.c95
-rw-r--r--usr/src/lib/print/libipp-listener/common/restart-job.c106
-rw-r--r--usr/src/lib/print/libipp-listener/common/resume-printer.c68
-rw-r--r--usr/src/lib/print/libipp-listener/common/send-document.c143
-rw-r--r--usr/src/lib/print/libipp-listener/common/set-job-attributes.c90
-rw-r--r--usr/src/lib/print/libipp-listener/common/set-printer-attributes.c83
-rw-r--r--usr/src/lib/print/libipp-listener/common/validate-job.c107
-rw-r--r--usr/src/lib/print/libipp-listener/i386/Makefile30
-rw-r--r--usr/src/lib/print/libipp-listener/sparc/Makefile30
-rw-r--r--usr/src/lib/print/libpapi-common/Makefile57
-rw-r--r--usr/src/lib/print/libpapi-common/Makefile.com57
-rw-r--r--usr/src/lib/print/libpapi-common/common/attribute.c1181
-rw-r--r--usr/src/lib/print/libpapi-common/common/common.c132
-rw-r--r--usr/src/lib/print/libpapi-common/common/config-site.h60
-rw-r--r--usr/src/lib/print/libpapi-common/common/config.h159
-rw-r--r--usr/src/lib/print/libpapi-common/common/library.c105
-rw-r--r--usr/src/lib/print/libpapi-common/common/list.c161
-rw-r--r--usr/src/lib/print/libpapi-common/common/mapfile151
-rw-r--r--usr/src/lib/print/libpapi-common/common/misc.c87
-rw-r--r--usr/src/lib/print/libpapi-common/common/papi.h448
-rw-r--r--usr/src/lib/print/libpapi-common/common/status.c133
-rw-r--r--usr/src/lib/print/libpapi-common/common/uri.c303
-rw-r--r--usr/src/lib/print/libpapi-common/common/uri.h66
-rw-r--r--usr/src/lib/print/libpapi-common/i386/Makefile30
-rw-r--r--usr/src/lib/print/libpapi-common/sparc/Makefile30
-rw-r--r--usr/src/lib/print/libpapi-dynamic/Makefile56
-rw-r--r--usr/src/lib/print/libpapi-dynamic/Makefile.com59
-rw-r--r--usr/src/lib/print/libpapi-dynamic/common/job.c457
-rw-r--r--usr/src/lib/print/libpapi-dynamic/common/mapfile150
-rw-r--r--usr/src/lib/print/libpapi-dynamic/common/nss.c497
-rw-r--r--usr/src/lib/print/libpapi-dynamic/common/papi_impl.h97
-rw-r--r--usr/src/lib/print/libpapi-dynamic/common/printer.c512
-rw-r--r--usr/src/lib/print/libpapi-dynamic/common/psm.c100
-rw-r--r--usr/src/lib/print/libpapi-dynamic/common/service.c564
-rw-r--r--usr/src/lib/print/libpapi-dynamic/i386/Makefile30
-rw-r--r--usr/src/lib/print/libpapi-dynamic/sparc/Makefile30
-rw-r--r--usr/src/lib/print/libpapi-ipp/Makefile56
-rw-r--r--usr/src/lib/print/libpapi-ipp/Makefile.com71
-rw-r--r--usr/src/lib/print/libpapi-ipp/common/ipp-support.c612
-rw-r--r--usr/src/lib/print/libpapi-ipp/common/job.c627
-rw-r--r--usr/src/lib/print/libpapi-ipp/common/mapfile150
-rw-r--r--usr/src/lib/print/libpapi-ipp/common/papi_impl.h114
-rw-r--r--usr/src/lib/print/libpapi-ipp/common/printer.c435
-rw-r--r--usr/src/lib/print/libpapi-ipp/common/service.c394
-rw-r--r--usr/src/lib/print/libpapi-ipp/i386/Makefile30
-rw-r--r--usr/src/lib/print/libpapi-ipp/sparc/Makefile30
-rw-r--r--usr/src/lib/print/libpapi-lpd/Makefile56
-rw-r--r--usr/src/lib/print/libpapi-lpd/Makefile.com99
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/job.c298
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/library.c90
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/lpd-cancel.c122
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/lpd-job.c551
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/lpd-misc.c192
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/lpd-port.c768
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/lpd-query.c292
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/mapfile150
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/papi_impl.h111
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/printer.c156
-rw-r--r--usr/src/lib/print/libpapi-lpd/common/service.c299
-rw-r--r--usr/src/lib/print/libpapi-lpd/i386/Makefile31
-rw-r--r--usr/src/lib/print/libpapi-lpd/sparc/Makefile31
-rw-r--r--usr/src/lib/print/libprint/Makefile54
-rw-r--r--usr/src/lib/print/libprint/Makefile.com61
-rw-r--r--usr/src/lib/print/libprint/common/job.c (renamed from usr/src/lib/print/job.c)513
-rw-r--r--usr/src/lib/print/libprint/common/job.h138
-rw-r--r--usr/src/lib/print/libprint/common/list.c (renamed from usr/src/lib/print/list.c)11
-rw-r--r--usr/src/lib/print/libprint/common/list.h (renamed from usr/src/lib/print/list.h)11
-rw-r--r--usr/src/lib/print/libprint/common/llib-lprint (renamed from usr/src/lib/print/llib-lprint)14
-rw-r--r--usr/src/lib/print/libprint/common/mapfile-vers (renamed from usr/src/lib/print/mapfile-vers)28
-rw-r--r--usr/src/lib/print/libprint/common/misc.c (renamed from usr/src/lib/print/misc.c)39
-rw-r--r--usr/src/lib/print/libprint/common/misc.h (renamed from usr/src/lib/print/misc.h)39
-rw-r--r--usr/src/lib/print/libprint/common/network.c (renamed from usr/src/lib/print/network.c)4
-rw-r--r--usr/src/lib/print/libprint/common/network.h (renamed from usr/src/lib/print/network.h)11
-rw-r--r--usr/src/lib/print/libprint/common/ns.c (renamed from usr/src/lib/print/ns.c)13
-rw-r--r--usr/src/lib/print/libprint/common/ns.h (renamed from usr/src/lib/print/ns.h)0
-rw-r--r--usr/src/lib/print/libprint/common/ns_bsd_addr.c (renamed from usr/src/lib/print/ns_bsd_addr.c)13
-rw-r--r--usr/src/lib/print/libprint/common/ns_cmn_kvp.c (renamed from usr/src/lib/print/ns_cmn_kvp.c)11
-rw-r--r--usr/src/lib/print/libprint/common/ns_cmn_printer.c (renamed from usr/src/lib/print/ns_cmn_printer.c)11
-rw-r--r--usr/src/lib/print/libprint/common/nss_convert.c (renamed from usr/src/lib/print/nss_convert.c)6
-rw-r--r--usr/src/lib/print/libprint/common/nss_ldap.c (renamed from usr/src/lib/print/nss_ldap.c)6
-rw-r--r--usr/src/lib/print/libprint/common/nss_printer.c (renamed from usr/src/lib/print/nss_printer.c)9
-rw-r--r--usr/src/lib/print/libprint/common/nss_write.c (renamed from usr/src/lib/print/nss_write.c)6
-rw-r--r--usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt (renamed from usr/src/lib/print/sunPrinter.at.conf.txt)0
-rw-r--r--usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt (renamed from usr/src/lib/print/sunPrinter.oc.conf.txt)0
-rw-r--r--usr/src/lib/print/libprint/i386/Makefile30
-rw-r--r--usr/src/lib/print/libprint/sparc/Makefile30
-rw-r--r--usr/src/lib/print/mod_ipp/Makefile100
-rw-r--r--usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf341
-rw-r--r--usr/src/lib/print/mod_ipp/index.html44
-rw-r--r--usr/src/lib/print/mod_ipp/ipp-listener.xml73
-rw-r--r--usr/src/lib/print/mod_ipp/mapfile39
-rw-r--r--usr/src/lib/print/mod_ipp/mod_ipp.c552
-rw-r--r--usr/src/pkgdefs/Makefile8
-rw-r--r--usr/src/pkgdefs/SUNWippcore/Makefile49
-rw-r--r--usr/src/pkgdefs/SUNWippcore/pkginfo.tmpl57
-rw-r--r--usr/src/pkgdefs/SUNWippcore/prototype_com52
-rw-r--r--usr/src/pkgdefs/SUNWippcore/prototype_i38650
-rw-r--r--usr/src/pkgdefs/SUNWippcore/prototype_sparc50
-rw-r--r--usr/src/pkgdefs/SUNWipplr/Makefile51
-rw-r--r--usr/src/pkgdefs/SUNWipplr/pkginfo.tmpl57
-rw-r--r--usr/src/pkgdefs/SUNWipplr/preremove.tmpl41
-rw-r--r--usr/src/pkgdefs/SUNWipplr/prototype_com60
-rw-r--r--usr/src/pkgdefs/SUNWipplr/prototype_i38650
-rw-r--r--usr/src/pkgdefs/SUNWipplr/prototype_sparc50
-rw-r--r--usr/src/pkgdefs/SUNWipplu/Makefile50
-rw-r--r--usr/src/pkgdefs/SUNWipplu/pkginfo.tmpl57
-rw-r--r--usr/src/pkgdefs/SUNWipplu/prototype_com48
-rw-r--r--usr/src/pkgdefs/SUNWipplu/prototype_i38650
-rw-r--r--usr/src/pkgdefs/SUNWipplu/prototype_sparc50
-rw-r--r--usr/src/pkgdefs/SUNWlp-cmds/Makefile49
-rw-r--r--usr/src/pkgdefs/SUNWlp-cmds/pkginfo.tmpl59
-rw-r--r--usr/src/pkgdefs/SUNWlp-cmds/prototype_com64
-rw-r--r--usr/src/pkgdefs/SUNWlp-cmds/prototype_i38652
-rw-r--r--usr/src/pkgdefs/SUNWlp-cmds/prototype_sparc53
-rw-r--r--usr/src/pkgdefs/SUNWlpr-cmds/Makefile49
-rw-r--r--usr/src/pkgdefs/SUNWlpr-cmds/pkginfo.tmpl58
-rw-r--r--usr/src/pkgdefs/SUNWlpr-cmds/prototype_com53
-rw-r--r--usr/src/pkgdefs/SUNWlpr-cmds/prototype_i38652
-rw-r--r--usr/src/pkgdefs/SUNWlpr-cmds/prototype_sparc52
-rw-r--r--usr/src/pkgdefs/SUNWpapi/Makefile39
-rw-r--r--usr/src/pkgdefs/SUNWpapi/pkginfo.tmpl56
-rw-r--r--usr/src/pkgdefs/SUNWpapi/prototype_com53
-rw-r--r--usr/src/pkgdefs/SUNWpapi/prototype_i38650
-rw-r--r--usr/src/pkgdefs/SUNWpapi/prototype_sparc50
-rw-r--r--usr/src/pkgdefs/SUNWpcr/pkginfo.tmpl1
-rw-r--r--usr/src/pkgdefs/SUNWpcu/Makefile11
-rw-r--r--usr/src/pkgdefs/SUNWpcu/pkginfo.tmpl1
-rw-r--r--usr/src/pkgdefs/SUNWpcu/prototype_com24
-rw-r--r--usr/src/pkgdefs/SUNWpsf/pkginfo.tmpl1
-rw-r--r--usr/src/pkgdefs/SUNWpsm-ipp/Makefile50
-rw-r--r--usr/src/pkgdefs/SUNWpsm-ipp/pkginfo.tmpl56
-rw-r--r--usr/src/pkgdefs/SUNWpsm-ipp/prototype_com53
-rw-r--r--usr/src/pkgdefs/SUNWpsm-ipp/prototype_i38650
-rw-r--r--usr/src/pkgdefs/SUNWpsm-ipp/prototype_sparc50
-rw-r--r--usr/src/pkgdefs/SUNWpsm-lpd/Makefile49
-rw-r--r--usr/src/pkgdefs/SUNWpsm-lpd/pkginfo.tmpl56
-rw-r--r--usr/src/pkgdefs/SUNWpsm-lpd/prototype_com52
-rw-r--r--usr/src/pkgdefs/SUNWpsm-lpd/prototype_i38650
-rw-r--r--usr/src/pkgdefs/SUNWpsm-lpd/prototype_sparc50
-rw-r--r--usr/src/pkgdefs/SUNWpsr/pkginfo.tmpl1
-rw-r--r--usr/src/pkgdefs/SUNWpsu/pkginfo.tmpl1
-rw-r--r--usr/src/pkgdefs/SUNWpsu/prototype_com14
-rw-r--r--usr/src/pkgdefs/SUNWscplp/pkginfo.tmpl1
287 files changed, 31008 insertions, 2877 deletions
diff --git a/usr/src/cmd/lp/cmd/cancel.c b/deleted_files/usr/src/cmd/lp/cmd/cancel.c
index 9acdbe805b..9acdbe805b 100644
--- a/usr/src/cmd/lp/cmd/cancel.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/cancel.c
diff --git a/usr/src/cmd/lp/cmd/comb.c b/deleted_files/usr/src/cmd/lp/cmd/comb.c
index 595fed9651..595fed9651 100644
--- a/usr/src/cmd/lp/cmd/comb.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/comb.c
diff --git a/usr/src/cmd/lp/cmd/lp.c b/deleted_files/usr/src/cmd/lp/cmd/lp.c
index d24d6791a8..d24d6791a8 100644
--- a/usr/src/cmd/lp/cmd/lp.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lp.c
diff --git a/usr/src/cmd/lp/cmd/lpc/Makefile b/deleted_files/usr/src/cmd/lp/cmd/lpc/Makefile
index d4704db6ba..d4704db6ba 100644
--- a/usr/src/cmd/lp/cmd/lpc/Makefile
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpc/Makefile
diff --git a/usr/src/cmd/lp/cmd/lpc/cmds.c b/deleted_files/usr/src/cmd/lp/cmd/lpc/cmds.c
index e877fb71e4..e877fb71e4 100644
--- a/usr/src/cmd/lp/cmd/lpc/cmds.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpc/cmds.c
diff --git a/usr/src/cmd/lp/cmd/lpc/cmdtab.c b/deleted_files/usr/src/cmd/lp/cmd/lpc/cmdtab.c
index 602f06d3df..602f06d3df 100644
--- a/usr/src/cmd/lp/cmd/lpc/cmdtab.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpc/cmdtab.c
diff --git a/usr/src/cmd/lp/cmd/lpc/fatalmsg.c b/deleted_files/usr/src/cmd/lp/cmd/lpc/fatalmsg.c
index 521061e152..521061e152 100644
--- a/usr/src/cmd/lp/cmd/lpc/fatalmsg.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpc/fatalmsg.c
diff --git a/usr/src/cmd/lp/cmd/lpc/global.c b/deleted_files/usr/src/cmd/lp/cmd/lpc/global.c
index 83fa12c222..83fa12c222 100644
--- a/usr/src/cmd/lp/cmd/lpc/global.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpc/global.c
diff --git a/usr/src/cmd/lp/cmd/lpc/lpc.c b/deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.c
index 09c4641f96..09c4641f96 100644
--- a/usr/src/cmd/lp/cmd/lpc/lpc.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.c
diff --git a/usr/src/cmd/lp/cmd/lpc/lpc.h b/deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.h
index a9af649549..a9af649549 100644
--- a/usr/src/cmd/lp/cmd/lpc/lpc.h
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.h
diff --git a/usr/src/cmd/lp/cmd/lpc/process.c b/deleted_files/usr/src/cmd/lp/cmd/lpc/process.c
index ddeda2c430..ddeda2c430 100644
--- a/usr/src/cmd/lp/cmd/lpc/process.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpc/process.c
diff --git a/usr/src/cmd/lp/cmd/lpc/sndrcv.c b/deleted_files/usr/src/cmd/lp/cmd/lpc/sndrcv.c
index b989ba5a86..b989ba5a86 100644
--- a/usr/src/cmd/lp/cmd/lpc/sndrcv.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpc/sndrcv.c
diff --git a/usr/src/cmd/lp/cmd/lpc/topq.c b/deleted_files/usr/src/cmd/lp/cmd/lpc/topq.c
index 4a5b0fccff..4a5b0fccff 100644
--- a/usr/src/cmd/lp/cmd/lpc/topq.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpc/topq.c
diff --git a/usr/src/cmd/lp/cmd/lpmove.c b/deleted_files/usr/src/cmd/lp/cmd/lpmove.c
index 56d52e38b1..56d52e38b1 100644
--- a/usr/src/cmd/lp/cmd/lpmove.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpmove.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/Makefile b/deleted_files/usr/src/cmd/lp/cmd/lpstat/Makefile
index 9e9b661703..9e9b661703 100644
--- a/usr/src/cmd/lp/cmd/lpstat/Makefile
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/Makefile
diff --git a/usr/src/cmd/lp/cmd/lpstat/accept.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/accept.c
index 987682cde8..987682cde8 100644
--- a/usr/src/cmd/lp/cmd/lpstat/accept.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/accept.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/add_mounted.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/add_mounted.c
index f89f633caf..f89f633caf 100644
--- a/usr/src/cmd/lp/cmd/lpstat/add_mounted.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/add_mounted.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/charset.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/charset.c
index 6d6f504e9c..6d6f504e9c 100644
--- a/usr/src/cmd/lp/cmd/lpstat/charset.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/charset.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/class.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/class.c
index c567d86971..c567d86971 100644
--- a/usr/src/cmd/lp/cmd/lpstat/class.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/class.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/device.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/device.c
index afc21c56a8..afc21c56a8 100644
--- a/usr/src/cmd/lp/cmd/lpstat/device.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/device.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/done.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/done.c
index edbaffc42d..edbaffc42d 100644
--- a/usr/src/cmd/lp/cmd/lpstat/done.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/done.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/form.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/form.c
index 60feda5eb5..60feda5eb5 100644
--- a/usr/src/cmd/lp/cmd/lpstat/form.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/form.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/lpstat.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.c
index 5a264904cb..5a264904cb 100644
--- a/usr/src/cmd/lp/cmd/lpstat/lpstat.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/lpstat.h b/deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.h
index b1d9a6d76f..b1d9a6d76f 100644
--- a/usr/src/cmd/lp/cmd/lpstat/lpstat.h
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.h
diff --git a/usr/src/cmd/lp/cmd/lpstat/output.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/output.c
index 1cf20519a3..1cf20519a3 100644
--- a/usr/src/cmd/lp/cmd/lpstat/output.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/output.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/parse.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/parse.c
index c408d844a9..c408d844a9 100644
--- a/usr/src/cmd/lp/cmd/lpstat/parse.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/parse.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/printer.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/printer.c
index 5e83017193..5e83017193 100644
--- a/usr/src/cmd/lp/cmd/lpstat/printer.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/printer.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/request.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/request.c
index 6ced71d4e1..6ced71d4e1 100644
--- a/usr/src/cmd/lp/cmd/lpstat/request.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/request.c
diff --git a/usr/src/cmd/lp/cmd/lpstat/send_message.c b/deleted_files/usr/src/cmd/lp/cmd/lpstat/send_message.c
index e241825717..e241825717 100644
--- a/usr/src/cmd/lp/cmd/lpstat/send_message.c
+++ b/deleted_files/usr/src/cmd/lp/cmd/lpstat/send_message.c
diff --git a/usr/src/cmd/lp/lib/papi/attribute.c b/deleted_files/usr/src/cmd/lp/lib/papi/attribute.c
index 02f5db2fc4..02f5db2fc4 100644
--- a/usr/src/cmd/lp/lib/papi/attribute.c
+++ b/deleted_files/usr/src/cmd/lp/lib/papi/attribute.c
diff --git a/usr/src/cmd/lp/lib/papi/list.c b/deleted_files/usr/src/cmd/lp/lib/papi/list.c
index fb5451232f..fb5451232f 100644
--- a/usr/src/cmd/lp/lib/papi/list.c
+++ b/deleted_files/usr/src/cmd/lp/lib/papi/list.c
diff --git a/usr/src/cmd/lp/lib/papi/papi.h b/deleted_files/usr/src/cmd/lp/lib/papi/papi.h
index 1ba622aa2a..1ba622aa2a 100644
--- a/usr/src/cmd/lp/lib/papi/papi.h
+++ b/deleted_files/usr/src/cmd/lp/lib/papi/papi.h
diff --git a/usr/src/cmd/lp/lib/papi/status.c b/deleted_files/usr/src/cmd/lp/lib/papi/status.c
index 61f6d20739..61f6d20739 100644
--- a/usr/src/cmd/lp/lib/papi/status.c
+++ b/deleted_files/usr/src/cmd/lp/lib/papi/status.c
diff --git a/usr/src/cmd/print/cancel/Makefile b/deleted_files/usr/src/cmd/print/cancel/Makefile
index f7d257fd90..f7d257fd90 100644
--- a/usr/src/cmd/print/cancel/Makefile
+++ b/deleted_files/usr/src/cmd/print/cancel/Makefile
diff --git a/usr/src/cmd/print/cancel/cancel.c b/deleted_files/usr/src/cmd/print/cancel/cancel.c
index acfc529344..acfc529344 100644
--- a/usr/src/cmd/print/cancel/cancel.c
+++ b/deleted_files/usr/src/cmd/print/cancel/cancel.c
diff --git a/usr/src/cmd/print/cancel/cancel_list.c b/deleted_files/usr/src/cmd/print/cancel/cancel_list.c
index d9ad68ebab..d9ad68ebab 100644
--- a/usr/src/cmd/print/cancel/cancel_list.c
+++ b/deleted_files/usr/src/cmd/print/cancel/cancel_list.c
diff --git a/usr/src/cmd/print/cancel/cancel_list.h b/deleted_files/usr/src/cmd/print/cancel/cancel_list.h
index d535e0f3ff..d535e0f3ff 100644
--- a/usr/src/cmd/print/cancel/cancel_list.h
+++ b/deleted_files/usr/src/cmd/print/cancel/cancel_list.h
diff --git a/usr/src/cmd/print/lp/Makefile b/deleted_files/usr/src/cmd/print/lp/Makefile
index 3e813bb0a2..3e813bb0a2 100644
--- a/usr/src/cmd/print/lp/Makefile
+++ b/deleted_files/usr/src/cmd/print/lp/Makefile
diff --git a/usr/src/cmd/print/lpmove/Makefile b/deleted_files/usr/src/cmd/print/lpmove/Makefile
index 7892c91c36..7892c91c36 100644
--- a/usr/src/cmd/print/lpmove/Makefile
+++ b/deleted_files/usr/src/cmd/print/lpmove/Makefile
diff --git a/usr/src/cmd/print/lpmove/lpmove.c b/deleted_files/usr/src/cmd/print/lpmove/lpmove.c
index e3d32afee2..e3d32afee2 100644
--- a/usr/src/cmd/print/lpmove/lpmove.c
+++ b/deleted_files/usr/src/cmd/print/lpmove/lpmove.c
diff --git a/usr/src/cmd/print/lpstat/Makefile b/deleted_files/usr/src/cmd/print/lpstat/Makefile
index 0e77ee879b..0e77ee879b 100644
--- a/usr/src/cmd/print/lpstat/Makefile
+++ b/deleted_files/usr/src/cmd/print/lpstat/Makefile
diff --git a/usr/src/cmd/print/lpstat/bsd-functions.c b/deleted_files/usr/src/cmd/print/lpstat/bsd-functions.c
index 8b5b42fe46..8b5b42fe46 100644
--- a/usr/src/cmd/print/lpstat/bsd-functions.c
+++ b/deleted_files/usr/src/cmd/print/lpstat/bsd-functions.c
diff --git a/usr/src/cmd/print/lpstat/bsd-functions.h b/deleted_files/usr/src/cmd/print/lpstat/bsd-functions.h
index b12adedc84..b12adedc84 100644
--- a/usr/src/cmd/print/lpstat/bsd-functions.h
+++ b/deleted_files/usr/src/cmd/print/lpstat/bsd-functions.h
diff --git a/usr/src/cmd/print/lpstat/lpstat.c b/deleted_files/usr/src/cmd/print/lpstat/lpstat.c
index 0902aa51fa..0902aa51fa 100644
--- a/usr/src/cmd/print/lpstat/lpstat.c
+++ b/deleted_files/usr/src/cmd/print/lpstat/lpstat.c
diff --git a/usr/src/cmd/print/lpstat/parse.h b/deleted_files/usr/src/cmd/print/lpstat/parse.h
index fb4abd3d9f..fb4abd3d9f 100644
--- a/usr/src/cmd/print/lpstat/parse.h
+++ b/deleted_files/usr/src/cmd/print/lpstat/parse.h
diff --git a/usr/src/cmd/print/lpstat/parse_bsd.c b/deleted_files/usr/src/cmd/print/lpstat/parse_bsd.c
index 963ea8f048..963ea8f048 100644
--- a/usr/src/cmd/print/lpstat/parse_bsd.c
+++ b/deleted_files/usr/src/cmd/print/lpstat/parse_bsd.c
diff --git a/usr/src/cmd/print/lpstat/sysv-functions.c b/deleted_files/usr/src/cmd/print/lpstat/sysv-functions.c
index 35520fddd3..35520fddd3 100644
--- a/usr/src/cmd/print/lpstat/sysv-functions.c
+++ b/deleted_files/usr/src/cmd/print/lpstat/sysv-functions.c
diff --git a/usr/src/cmd/print/lpstat/sysv-functions.h b/deleted_files/usr/src/cmd/print/lpstat/sysv-functions.h
index eea04ecc4b..eea04ecc4b 100644
--- a/usr/src/cmd/print/lpstat/sysv-functions.h
+++ b/deleted_files/usr/src/cmd/print/lpstat/sysv-functions.h
diff --git a/usr/src/cmd/print/scripts/accept b/deleted_files/usr/src/cmd/print/scripts/accept
index 8d2fb4a995..8d2fb4a995 100644
--- a/usr/src/cmd/print/scripts/accept
+++ b/deleted_files/usr/src/cmd/print/scripts/accept
diff --git a/usr/src/cmd/lp/cmd/Makefile b/usr/src/cmd/lp/cmd/Makefile
index 2a50a58144..28a60c9026 100644
--- a/usr/src/cmd/lp/cmd/Makefile
+++ b/usr/src/cmd/lp/cmd/Makefile
@@ -33,12 +33,9 @@ include ../Makefile.lp
OWNER = root
-SUBDIRS = lpc lptest lpadmin lpsched lpstat adaptor scripts
+SUBDIRS = lptest lpadmin lpsched adaptor scripts
-LOCALPROG1 = lp lpsystem lpmove lpshut
-LOCALPROG2 = accept
-LOCALPROG = $(LOCALPROG1) $(LOCALPROG2)
-LOCALLINKS = disable enable reject
+LOCALPROG = lpsystem lpshut
SBINPROG = lpfilter lpforms lpusers
@@ -46,35 +43,27 @@ LIBLINKS = $(SBINPROG)
PROG = $(LOCALPROG) $(SBINPROG)
-COMMONOBJ= comb.o
-OTHEROBJS= cancel.o lp.o $(SBINPROG:=.o)
-
-OBJS= $(COMMONOBJ) $(OTHEROBJS)
+OBJS= $(SBINPROG:=.o)
SRCS= $(OBJS:.o=.c)
POFILE= lp_cmd.po
-POFILES= $(SRCS:%.c=%.po) lpsystem.po lpmove.po lpschedlpshut.po
+POFILES= $(SRCS:%.c=%.po) lpsystem.po lpschedlpshut.po
ROOTLIBLPLOCLPROG= $(LOCALPROG:%=$(ROOTLIBLPLOCL)/%)
ROOTSBINPROG= $(SBINPROG:%=$(ROOTUSRSBIN)/%)
ROOTSYMLINKS= $(LIBLINKS:%=$(ROOTLIB)/%)
-ROOTSYMLINKS2= $(LOCALLINKS:%=$(ROOTLIBLPLOCL)/%)
CPPFLAGS = -I$(LPINC) $(CPPFLAGS.master)
# conditional assignments
#
-accept:= LDLIBS += $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP)
-cancel:= LDLIBS += $(LIBREQ) $(LIBMSG) $(LIBOAM) $(LIBLP)
-lp:= LDLIBS += $(LIBPRT) $(LIBREQ) $(LIBMSG) $(LIBOAM) $(LIBLP)
lpfilter:= LDLIBS += $(LIBFLT) $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP) \
-lgen -z lazyload -lsecdb -z nolazyload
lpforms:= LDLIBS += $(LIBFRM) $(LIBMSG) $(LIBREQ) $(LIBOAM) \
$(LIBACC) $(LIBLP) \
-z lazyload -lsecdb -z nolazyload
-lpmove:= LDLIBS += $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP)
lpshut:= LDLIBS += $(LIBMSG) $(LIBOAM) $(LIBLP)
lpsystem:= LDLIBS += $(LIBSYS) $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP) \
-lnsl -z lazyload -lsecdb -z nolazyload
@@ -84,13 +73,8 @@ lpusers:= LDLIBS += $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBUSR) $(LIBLP)
all: $(PROG) $(SUBDIRS)
-accept: $(COMMONOBJ)
- $(LINK.c) -o $@ $(COMMONOBJ) $(LDFLAGS) $(LDLIBS)
- $(POST_PROCESS)
-
-
install: $(PROG) $(ROOTLIBLPLOCLPROG) $(ROOTSBINPROG) \
- $(ROOTSYMLINKS) $(ROOTSYMLINKS2) $(SUBDIRS)
+ $(ROOTSYMLINKS) $(SUBDIRS)
catalog: $(SUBDIRS) $(POFILE)
$(CP) $(POFILE) ..
@@ -101,7 +85,7 @@ clean: $(SUBDIRS)
clobber: $(SUBDIRS) local_clobber
local_clobber:
- $(RM) $(OBJS) $(PROG) lpmove.o lpsystem.o $(CLOBBERFILES)
+ $(RM) $(OBJS) $(PROG) lpsystem.o $(CLOBBERFILES)
strip: $(SUBDIRS)
$(STRIP) $(PROG)
@@ -109,16 +93,9 @@ strip: $(SUBDIRS)
lint:
$(LINT.c) $(SRCS) $(LDLIBS)
-$(LOCALPROG1) $(SBINPROG): $$@.o
- $(LINK.c) -o $@ $@.o $(LDFLAGS) $(LDLIBS)
- $(POST_PROCESS)
-
$(ROOTSYMLINKS):
$(RM) $@; $(SYMLINK) ../sbin/$(@F) $@
-$(ROOTSYMLINKS2):
- $(RM) $@; $(SYMLINK) ./accept $@
-
$(SUBDIRS): FRC
@cd $@; pwd; $(MAKE) $(TARGET)
diff --git a/usr/src/cmd/lp/cmd/adaptor/Makefile b/usr/src/cmd/lp/cmd/adaptor/Makefile
index f7d7d7508b..04aaa4547b 100644
--- a/usr/src/cmd/lp/cmd/adaptor/Makefile
+++ b/usr/src/cmd/lp/cmd/adaptor/Makefile
@@ -38,7 +38,7 @@ include ../../Makefile.lp
ROOTLIBDIR= $(ROOT)/usr/lib/print/bsd-adaptor
CPPFLAGS += -I$(LPINC)
-CPPFLAGS += -I$(SRC)/lib
+CPPFLAGS += -I$(SRC)/lib/print/libprint/common
LDLIBS += -lprint -z lazyload -ltsol -z nolazyload -lc
LDLIBS += -L$(SRC)/cmd/lp/lib/msgs -llpmsg
LDLIBS += -L$(SRC)/cmd/lp/lib/class -llpcls
diff --git a/usr/src/cmd/lp/cmd/adaptor/cancel_job.c b/usr/src/cmd/lp/cmd/adaptor/cancel_job.c
index 7ffa9af79b..4ae65e5dcc 100644
--- a/usr/src/cmd/lp/cmd/adaptor/cancel_job.c
+++ b/usr/src/cmd/lp/cmd/adaptor/cancel_job.c
@@ -44,7 +44,7 @@
#include "misc.h"
/* print NS include */
-#include <print/ns.h>
+#include <ns.h>
static char *
diff --git a/usr/src/cmd/lp/lib/access/Makefile b/usr/src/cmd/lp/lib/access/Makefile
index 97c6801b34..7734b7a65f 100644
--- a/usr/src/cmd/lp/lib/access/Makefile
+++ b/usr/src/cmd/lp/lib/access/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
#
# CDDL HEADER END
#
+
#
-# Copyright 1990-2003 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -44,7 +44,7 @@ include ../../Makefile.lp
# This library is not installed in the proto area.
LIBS = $(LIBRARY)
-CPPFLAGS = -I../../include $(CPPFLAGS.master)
+CPPFLAGS = -I../../include $(CPPFLAGS.master) $(C_PICFLAGS) -D_TS_ERRNO
POFILE = lp_lib_access.po
diff --git a/usr/src/cmd/lp/lib/papi/Makefile b/usr/src/cmd/lp/lib/papi/Makefile
index 72c7ff60a5..2f3d18a668 100644
--- a/usr/src/cmd/lp/lib/papi/Makefile
+++ b/usr/src/cmd/lp/lib/papi/Makefile
@@ -17,8 +17,6 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
-
-
#
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
@@ -34,8 +32,8 @@ VERS=.1
LPSCHED_OBJS = lpsched-msgs.o lpsched-service.o lpsched-printers.o \
lpsched-jobs.o lpsched-misc.o
-OBJECTS = $(LPSCHED_OBJS) \
- list.o attribute.o status.o service.o printer.o job.o
+OBJECTS = $(LPSCHED_OBJS) service.o printer.o job.o ppd.o library.o
+
include ../../../../lib/Makefile.lib
include ../../Makefile.lp
@@ -44,7 +42,7 @@ ROOTLIBDIR= $(ROOT)/usr/lib/print
CPPFLAGS = -I.
CPPFLAGS += -I$(LPINC)
-CPPFLAGS += -I$(SRC)/lib
+CPPFLAGS += -I$(SRC)/lib/print/libpapi-common/common
CPPFLAGS += -D_REENTRANT
CPPFLAGS += $(ENVCPPFLAGS1)
CPPFLAGS += $(ENVCPPFLAGS2)
@@ -55,11 +53,12 @@ LDLIBS += -L$(SRC)/cmd/lp/lib/class -llpcls
LDLIBS += -L$(SRC)/cmd/lp/lib/requests -llpreq
LDLIBS += -L$(SRC)/cmd/lp/lib/secure -llpsec
LDLIBS += -L$(SRC)/cmd/lp/lib/forms -llpfrm
+LDLIBS += -L$(SRC)/cmd/lp/lib/access -llpacc
LDLIBS += -L$(SRC)/cmd/lp/lib/lp -llp
-MAPFILES= mapfile-vers
+MAPFILES= mapfile
MAPOPTS= $(MAPFILES:%=-M%)
-DYNFLAGS += $(MAPOPTS)
+DYNFLAGS += $(BDIRECT) $(MAPOPTS)
LIBS = $(DYNLIB)
diff --git a/usr/src/cmd/lp/lib/papi/job.c b/usr/src/cmd/lp/lib/papi/job.c
index ff8aea70b7..776e6dee1c 100644
--- a/usr/src/cmd/lp/lib/papi/job.c
+++ b/usr/src/cmd/lp/lib/papi/job.c
@@ -35,11 +35,22 @@
#include <sys/stat.h>
#include <papi_impl.h>
+
+/*
+ * for an older application that may have been linked with a pre-v1.0
+ * PAPI implementation.
+ */
+papi_status_t
+papiAttributeListAdd(papi_attribute_t ***attrs, int flags, char *name,
+ papi_attribute_value_type_t type, papi_attribute_value_t *value)
+{
+ return (papiAttributeListAddValue(attrs, flags, name, type, value));
+}
+
#ifdef LP_USE_PAPI_ATTR
-static papi_status_t psm_modifyAttrsFile(const papi_attribute_t **attrs,
- char *file);
-static papi_status_t psm_modifyAttrsList(char *file,
- const papi_attribute_t **attrs, papi_attribute_t ***newAttrs);
+static papi_status_t psm_modifyAttrsFile(papi_attribute_t **attrs, char *file);
+static papi_status_t psm_modifyAttrsList(char *file, papi_attribute_t **attrs,
+ papi_attribute_t ***newAttrs);
#endif
@@ -104,12 +115,6 @@ papiJobGetId(papi_job_t job)
return (result);
}
-papi_job_ticket_t *
-papiJobGetJobTicket(papi_job_t job)
-{
- return (NULL); /* NOT SUPPORTED */
-}
-
static REQUEST *
create_request(papi_service_t svc, char *printer, papi_attribute_t **attributes)
{
@@ -158,7 +163,7 @@ authorized(service_t *svc, int32_t id)
}
static papi_status_t
-copy_file(const char *from, char *to)
+copy_file(char *from, char *to)
{
int ifd, ofd;
char buf[BUFSIZ];
@@ -199,23 +204,18 @@ copy_file(const char *from, char *to)
*/
static papi_status_t
-psm_copy_attrsToFile(const papi_attribute_t **attrs, char *file)
+psm_copy_attrsToFile(papi_attribute_t **attrs, char *file)
{
papi_status_t result = PAPI_OK;
- FILE *out = NULL;
-
- if ((attrs != NULL) && (*attrs != NULL))
- {
- out = fopen(file, "w");
- if (out != NULL)
- {
- papiAttributeListPrint(
- out, "", (papi_attribute_t **)attrs);
+
+ if ((attrs != NULL) && (*attrs != NULL)) {
+ FILE *out = NULL;
+
+ if ((out = fopen(file, "w")) != NULL) {
+ papiAttributeListPrint(out, attrs, "");
fclose(out);
- }
- else
- {
+ } else {
result = PAPI_NOT_POSSIBLE;
}
}
@@ -238,7 +238,7 @@ psm_copy_attrsToFile(const papi_attribute_t **attrs, char *file)
*/
static papi_status_t
-psm_modifyAttrsFile(const papi_attribute_t **attrs, char *file)
+psm_modifyAttrsFile(papi_attribute_t **attrs, char *file)
{
papi_status_t result = PAPI_OK;
@@ -246,61 +246,46 @@ psm_modifyAttrsFile(const papi_attribute_t **attrs, char *file)
struct stat tmpBuf;
FILE *fd = NULL;
- if ((attrs != NULL) && (*attrs != NULL) && (file != NULL))
- {
+ if ((attrs != NULL) && (*attrs != NULL) && (file != NULL)) {
/*
* check file exist before try to modify it, if it doesn't
* exist assume there is an error
*/
- if (stat(file, &tmpBuf) == 0)
- {
+ if (stat(file, &tmpBuf) == 0) {
/*
* if file is currently empty just write the given
* attributes to the file otherwise exact the attributes
* from the file and modify them accordingly before
* writing them back to the file
*/
- if (tmpBuf.st_size == 0)
- {
-printf("psm_modifyAttrsFile() @1 - empty attribute file\n");
+ if (tmpBuf.st_size == 0) {
newAttrs = (papi_attribute_t **)attrs;
fd = fopen(file, "w");
- if (fd != NULL)
- {
+ if (fd != NULL) {
papiAttributeListPrint(fd,
- "", newAttrs);
+ newAttrs, "");
fclose(fd);
- }
- else
- {
+ } else {
result = PAPI_NOT_POSSIBLE;
}
- }
- else
- {
-printf("psm_modifyAttrsFile() @2 - modify file\n");
+ } else {
result =
psm_modifyAttrsList(file, attrs, &newAttrs);
fd = fopen(file, "w");
- if (fd != NULL)
- {
+ if (fd != NULL) {
papiAttributeListPrint(fd,
- "", newAttrs);
+ newAttrs, "");
fclose(fd);
- }
- else
- {
+ } else {
result = PAPI_NOT_POSSIBLE;
}
papiAttributeListFree(newAttrs);
}
- }
- else
- {
+ } else {
result = PAPI_NOT_POSSIBLE;
}
}
@@ -324,7 +309,7 @@ printf("psm_modifyAttrsFile() @2 - modify file\n");
*/
static papi_status_t
-psm_modifyAttrsList(char *file, const papi_attribute_t **attrs,
+psm_modifyAttrsList(char *file, papi_attribute_t **attrs,
papi_attribute_t ***newAttrs)
{
@@ -341,39 +326,30 @@ psm_modifyAttrsList(char *file, const papi_attribute_t **attrs,
int n = 0;
fd = fopen(file, "r");
- if (fd != NULL)
- {
+ if (fd != NULL) {
fD = fileno(fd);
a = &aBuff[0];
p = &aBuff[0];
count = read(fD, &aBuff[0], sizeof (aBuff) - 1);
- while ((result == PAPI_OK) && (count > 0))
- {
+ while ((result == PAPI_OK) && (count > 0)) {
aBuff[count+n] = '\0';
- if (count == sizeof (aBuff) - n - 1)
- {
+ if (count == sizeof (aBuff) - n - 1) {
p = strrchr(aBuff, '\n');
- if (p != NULL)
- {
+ if (p != NULL) {
/* terminate at last complete line */
*p = '\0';
}
}
-printf("psm_modifyAttrsList() @3 - aBuff=\n");
-printf("%s\n", aBuff);
result = papiAttributeListFromString(
newAttrs, PAPI_ATTR_EXCL, aBuff);
-printf("psm_modifyAttrsList() @4 - result=%d\n", result);
- if (result == PAPI_OK)
- {
+ if (result == PAPI_OK) {
/*
* handle any part lines and then read the next
* buffer from the file
*/
n = 0;
- if (p != a)
- {
+ if (p != a) {
p++; /* skip NL */
n = sizeof (aBuff) - 1 - (p - a);
strncpy(aBuff, p, n);
@@ -389,13 +365,11 @@ printf("psm_modifyAttrsList() @4 - result=%d\n", result);
/* now modify the attribute list with the new attributes in 'attrs' */
nextAttr = papiAttributeListGetNext((papi_attribute_t **)attrs, &iter);
- while ((result == PAPI_OK) && (nextAttr != NULL))
- {
+ while ((result == PAPI_OK) && (nextAttr != NULL)) {
values = nextAttr->values;
- if ((values != NULL) && (*values != NULL))
- {
- result = papiAttributeListAdd(newAttrs,
+ if ((values != NULL) && (*values != NULL)) {
+ result = papiAttributeListAddValue(newAttrs,
PAPI_ATTR_REPLACE,
nextAttr->name,
nextAttr->type, *values);
@@ -403,9 +377,8 @@ printf("psm_modifyAttrsList() @4 - result=%d\n", result);
}
while ((result == PAPI_OK) &&
- (values != NULL) && (*values != NULL))
- {
- result = papiAttributeListAdd(newAttrs,
+ (values != NULL) && (*values != NULL)) {
+ result = papiAttributeListAddValue(newAttrs,
PAPI_ATTR_APPEND,
nextAttr->name,
nextAttr->type, *values);
@@ -421,10 +394,10 @@ printf("psm_modifyAttrsList() @4 - result=%d\n", result);
papi_status_t
-papiJobSubmit(papi_service_t handle, const char *printer,
- const papi_attribute_t **job_attributes,
- const papi_job_ticket_t *job_ticket,
- const char **files, papi_job_t *job)
+papiJobSubmit(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket,
+ char **files, papi_job_t *job)
{
papi_status_t status;
service_t *svc = handle;
@@ -526,10 +499,10 @@ papiJobSubmit(papi_service_t handle, const char *printer,
}
papi_status_t
-papiJobSubmitByReference(papi_service_t handle, const char *printer,
- const papi_attribute_t **job_attributes,
- const papi_job_ticket_t *job_ticket,
- const char **files, papi_job_t *job)
+papiJobSubmitByReference(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket,
+ char **files, papi_job_t *job)
{
service_t *svc = handle;
job_t *j;
@@ -620,10 +593,10 @@ papiJobSubmitByReference(papi_service_t handle, const char *printer,
}
papi_status_t
-papiJobValidate(papi_service_t handle, const char *printer,
- const papi_attribute_t **job_attributes,
- const papi_job_ticket_t *job_ticket,
- const char **files, papi_job_t *job)
+papiJobValidate(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket,
+ char **files, papi_job_t *job)
{
papi_status_t status;
papi_attribute_t **attributes = NULL;
@@ -635,7 +608,7 @@ papiJobValidate(papi_service_t handle, const char *printer,
list_append(&attributes, job_attributes[i]);
status = papiJobSubmitByReference(handle, printer,
- (const papi_attribute_t **)attributes,
+ (papi_attribute_t **)attributes,
job_ticket, files, job);
if (status == PAPI_OK) {
int id = papiJobGetId(*job);
@@ -651,9 +624,9 @@ papiJobValidate(papi_service_t handle, const char *printer,
}
papi_status_t
-papiJobStreamOpen(papi_service_t handle, const char *printer,
- const papi_attribute_t **job_attributes,
- const papi_job_ticket_t *job_ticket, papi_stream_t *stream)
+papiJobStreamOpen(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, papi_stream_t *stream)
{
papi_status_t status;
service_t *svc = handle;
@@ -716,7 +689,7 @@ papiJobStreamOpen(papi_service_t handle, const char *printer,
papi_status_t
papiJobStreamWrite(papi_service_t handle,
- papi_stream_t stream, const void *buffer, const size_t buflen)
+ papi_stream_t stream, void *buffer, size_t buflen)
{
service_t *svc = handle;
job_stream_t *s = stream;
@@ -769,8 +742,8 @@ papiJobStreamClose(papi_service_t handle,
}
papi_status_t
-papiJobQuery(papi_service_t handle, const char *printer, const int32_t job_id,
- const char **requested_attrs,
+papiJobQuery(papi_service_t handle, char *printer, int32_t job_id,
+ char **requested_attrs,
papi_job_t *job)
{
service_t *svc = handle;
@@ -824,7 +797,51 @@ papiJobQuery(papi_service_t handle, const char *printer, const int32_t job_id,
}
papi_status_t
-papiJobCancel(papi_service_t handle, const char *printer, const int32_t job_id)
+papiJobMove(papi_service_t handle, char *printer, int32_t job_id,
+ char *destination)
+{
+ papi_status_t result = PAPI_OK;
+ service_t *svc = handle;
+ char req_id[64];
+ char *queue;
+ char *user = NULL;
+
+ if ((svc == NULL) || (printer == NULL) || (job_id < 0) ||
+ (destination == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ queue = printer_name_from_uri_id(printer, job_id);
+ snprintf(req_id, sizeof (req_id), "%s-%d", queue, job_id);
+ free(queue);
+
+ if (papiAttributeListGetString(svc->attributes, NULL, "user-name",
+ &user) == PAPI_OK) {
+ REQUEST *r = getrequest(req_id);
+
+ if ((r != NULL) && (r->user != NULL) &&
+ (strcmp(r->user, user) != 0))
+ result = PAPI_NOT_AUTHORIZED;
+ freerequest(r);
+ }
+
+ if (result == PAPI_OK) {
+ short status = MOK;
+ char *dest = printer_name_from_uri_id(destination, -1);
+
+ if ((snd_msg(svc, S_MOVE_REQUEST, req_id, dest) < 0) ||
+ (rcv_msg(svc, R_MOVE_REQUEST, &status) < 0))
+ status = MTRANSMITERR;
+
+ free(dest);
+
+ result = lpsched_status_to_papi_status(status);
+ }
+
+ return (result);
+}
+
+papi_status_t
+papiJobCancel(papi_service_t handle, char *printer, int32_t job_id)
{
papi_status_t result = PAPI_OK;
service_t *svc = handle;
@@ -843,7 +860,8 @@ papiJobCancel(papi_service_t handle, const char *printer, const int32_t job_id)
&user) == PAPI_OK) {
REQUEST *r = getrequest(req_id);
- if ((r != NULL) && (strcmp(r->user, user) != 0))
+ if ((r != NULL) && (r->user != NULL) &&
+ (strcmp(r->user, user) != 0))
result = PAPI_NOT_AUTHORIZED;
freerequest(r);
}
@@ -862,8 +880,8 @@ papiJobCancel(papi_service_t handle, const char *printer, const int32_t job_id)
}
papi_status_t
-hold_release_job(papi_service_t handle, const char *printer,
- const int32_t job_id, int flag)
+hold_release_job(papi_service_t handle, char *printer,
+ int32_t job_id, int flag)
{
papi_status_t status;
service_t *svc = handle;
@@ -884,16 +902,25 @@ hold_release_job(papi_service_t handle, const char *printer,
if ((r = getrequest(file)) != NULL) {
r->actions &= ~ACT_RESUME;
- if (flag == 0)
+ switch (flag) {
+ case 0:
r->actions |= ACT_HOLD;
- else
+ break;
+ case 1:
r->actions |= ACT_RESUME;
+ break;
+ case 2:
+ r->actions |= ACT_IMMEDIATE;
+ break;
+ }
if (putrequest(file, r) < 0) {
detailed_error(svc,
gettext("failed to write job: %s: %s"),
file, strerror(errno));
+ freerequest(r);
return (PAPI_DEVICE_ERROR);
}
+ freerequest(r);
} else {
detailed_error(svc, gettext("failed to read job: %s: %s"),
file, strerror(errno));
@@ -901,34 +928,31 @@ hold_release_job(papi_service_t handle, const char *printer,
}
status = lpsched_end_change(svc, dest, job_id);
- freerequest(r);
- free(dest);
return (status);
}
papi_status_t
-papiJobHold(papi_service_t handle, const char *printer, const int32_t job_id,
- const char *hold_until, const time_t *hold_until_time)
+papiJobHold(papi_service_t handle, char *printer, int32_t job_id)
{
return (hold_release_job(handle, printer, job_id, 0));
}
papi_status_t
-papiJobRelease(papi_service_t handle, const char *printer, const int32_t job_id)
+papiJobRelease(papi_service_t handle, char *printer, int32_t job_id)
{
return (hold_release_job(handle, printer, job_id, 1));
}
papi_status_t
-papiJobRestart(papi_service_t handle, const char *printer, const int32_t job_id)
+papiJobPromote(papi_service_t handle, char *printer, int32_t job_id)
{
- return (PAPI_OPERATION_NOT_SUPPORTED);
+ return (hold_release_job(handle, printer, job_id, 2));
}
papi_status_t
-papiJobModify(papi_service_t handle, const char *printer, const int32_t job_id,
- const papi_attribute_t **attributes, papi_job_t *job)
+papiJobModify(papi_service_t handle, char *printer, int32_t job_id,
+ papi_attribute_t **attributes, papi_job_t *job)
{
papi_status_t status;
job_t *j = NULL;
@@ -989,7 +1013,6 @@ papiJobModify(papi_service_t handle, const char *printer, const int32_t job_id,
status = lpsched_end_change(svc, dest, job_id);
lpsched_request_to_job_attributes(r, j);
freerequest(r);
- free(dest);
return (status);
}
@@ -1000,9 +1023,9 @@ papiJobModify(papi_service_t handle, const char *printer, const int32_t job_id,
#define DUMMY_FILE "/var/spool/lp/fifos/FIFO"
papi_status_t
-papiJobCreate(papi_service_t handle, const char *printer,
- const papi_attribute_t **job_attributes,
- const papi_job_ticket_t *job_ticket, papi_job_t *job)
+papiJobCreate(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, papi_job_t *job)
{
papi_status_t status;
service_t *svc = handle;
@@ -1030,6 +1053,8 @@ papiJobCreate(papi_service_t handle, const char *printer,
/* convert the attributes to an lpsched REQUEST structure */
request = create_request(svc, (char *)printer,
(papi_attribute_t **)job_attributes);
+ if (request == NULL)
+ return (PAPI_TEMPORARY_ERROR);
addlist(&request->file_list, DUMMY_FILE); /* add a dummy file */
request->actions |= ACT_HOLD; /* hold the job */
@@ -1046,12 +1071,14 @@ papiJobCreate(papi_service_t handle, const char *printer,
if (status != PAPI_OK) {
detailed_error(svc, "unable to copy attributes to file: %s: %s",
metadata_file, strerror(errno));
+ free(request_id);
return (PAPI_DEVICE_ERROR);
}
#endif
/* store the REQUEST on disk */
snprintf(metadata_file, sizeof (metadata_file), "%s-0", request_id);
+ free(request_id);
if (putrequest(metadata_file, request) < 0) {
detailed_error(svc, gettext("unable to save request: %s: %s"),
metadata_file, strerror(errno));
@@ -1103,6 +1130,7 @@ papiJobCommit(papi_service_t handle, char *printer, int32_t id)
detailed_error(svc,
gettext("failed to write job: %s: %s"),
metadata_file, strerror(errno));
+ freerequest(r);
return (PAPI_DEVICE_ERROR);
}
} else {
@@ -1113,7 +1141,6 @@ papiJobCommit(papi_service_t handle, char *printer, int32_t id)
status = lpsched_end_change(svc, dest, id);
freerequest(r);
- free(dest);
return (status);
}
@@ -1173,7 +1200,6 @@ papiJobStreamAdd(papi_service_t handle, char *printer, int32_t id,
}
status = lpsched_end_change(svc, dest, id);
- free(dest);
if (status != PAPI_OK)
return (status);
diff --git a/usr/src/cmd/lp/lib/papi/library.c b/usr/src/cmd/lp/lib/papi/library.c
new file mode 100644
index 0000000000..53c3a956a6
--- /dev/null
+++ b/usr/src/cmd/lp/lib/papi/library.c
@@ -0,0 +1,98 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdio.h>
+#include <string.h>
+#include <papi.h>
+
+static char *calls[] = {
+ /* Attribute Calls */
+ "papiAttributeListAddValue",
+ "papiAttributeListAddBoolean", "papiAttributeListAddCollection",
+ "papiAttributeListAddDatetime", "papiAttributeListAddInteger",
+ "papiAttributeListAddMetadata", "papiAttributeListAddRange",
+ "papiAttributeListAddResolution", "papiAttributeListAddString",
+ "papiAttributeListDelete",
+ "papiAttributeListGetValue", "papiAttributeListGetNext",
+ "papiAttributeListFind",
+ "papiAttributeListGetBoolean", "papiAttributeListGetCollection",
+ "papiAttributeListGetDatetime", "papiAttributeListGetInteger",
+ "papiAttributeListGetMetadata", "papiAttributeListGetRange",
+ "papiAttributeListGetResolution", "papiAttributeListGetString",
+ "papiAttributeListFromString", "papiAttributeListToString",
+ "papiAttributeListFree",
+ /* Job Calls */
+ "papiJobSubmit", "papiJobSubmitByReference", "papiJobValidate",
+ "papiJobStreamOpen", "papiJobStreamWrite", "papiJobStreamClose",
+ "papiJobQuery", "papiJobModify", "papiJobCancel", "papiJobPromote",
+ "papiJobGetAttributeList", "papiJobGetId", "papiJobGetPrinterName",
+ "papiJobFree", "papiJobListFree",
+ "papiJobHold", "papiJobRelease",
+ /* Printer Calls */
+ "papiPrintersList", "papiPrinterQuery", "papiPrinterModify",
+ "papiPrinterAdd", "papiPrinterRemove",
+ "papiPrinterPause", "papiPrinterResume",
+ "papiPrinterDisable", "papiPrinterEnable",
+ "papiPrinterPurgeJobs", "papiPrinterListJobs",
+ "papiPrinterGetAttributeList",
+ "papiPrinterFree", "papiPrinterListFree",
+ /* Service Calls */
+ "papiServiceCreate", "papiServiceDestroy",
+ "papiServiceGetAppData",
+ "papiServiceGetEncryption", "papiServiceGetPassword",
+ "papiServiceGetServiceName", "papiServiceGetUserName",
+ "papiServiceSetAppData", "papiServiceSetAuthCB",
+ "papiServiceSetEncryption", "papiServiceSetPassword",
+ "papiServiceSetUserName",
+ "papiServiceGetAttributeList", "papiServiceGetStatusMessage",
+ /* Misc Calls */
+ "papiStatusString",
+ "papiLibrarySupportedCall", "papiLibrarySupportedCalls",
+ NULL
+};
+
+char **
+papiLibrarySupportedCalls()
+{
+ return (calls);
+}
+
+char
+papiLibrarySupportedCall(const char *name)
+{
+ int i;
+
+ for (i = 0; calls[i] != NULL; i++)
+ if (strcmp(name, calls[i]) == 0)
+ return (PAPI_TRUE);
+
+ return (PAPI_FALSE);
+}
diff --git a/usr/src/cmd/lp/lib/papi/lpsched-jobs.c b/usr/src/cmd/lp/lib/papi/lpsched-jobs.c
index 225cc08dcf..a4fea773a5 100644
--- a/usr/src/cmd/lp/lib/papi/lpsched-jobs.c
+++ b/usr/src/cmd/lp/lib/papi/lpsched-jobs.c
@@ -44,14 +44,14 @@ papi_status_t
job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
papi_attribute_t **attributes)
{
+ papi_status_t status = PAPI_OK;
papi_attribute_t *attr;
+ papi_attribute_t **unmapped = NULL;
int i;
char *s;
char **options = NULL;
char **modes = NULL;
- char *class = NULL;
- char *job_name = NULL;
char pr_filter = 0;
char *pr_title = NULL;
@@ -59,26 +59,36 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
int pr_indent = -1;
int numberUp = 0;
int orientation = 0;
- int lowerPage = 0;
- int upperPage = 0;
- papi_status_t getResult = 0;
+ int lower = 0;
+ int upper = 0;
char buf[256];
void *iterator = NULL;
-
- char banner = 0;
+ char *mapped_keys[] = { "copies", "document-format", "form",
+ "job-class", "job-hold-until", "job-host", "job-name",
+ "job-originating-user-name", "job-printer",
+ "job-sheets", "lp-charset", "lp-modes", "number-up",
+ "orienttation-requested", "page-ranges", "pr-filter",
+ "pr-indent", "pr-title", "pr-width", "priority",
+ "requesting-user-name", NULL };
if (attributes == NULL)
return (PAPI_BAD_ARGUMENT);
- papiAttributeListGetString(attributes, NULL, "job-printer",
- &r->destination);
+ /* replace the current destination */
+ papiAttributeListGetLPString(attributes,
+ "job-printer", &r->destination);
+ /* set the copies. We need at least 1 */
i = r->copies;
papiAttributeListGetInteger(attributes, NULL, "copies", &i);
if (i <= 0)
i = 1;
r->copies = i;
+ /*
+ * set the priority. PAPI/IPP uses 1-100, lpsched use 0-39, so we
+ * have to convert it.
+ */
if (papiAttributeListGetInteger(attributes, NULL, "priority", &i)
== PAPI_OK) {
if ((i < 1) || (i > 100))
@@ -86,56 +96,41 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
i = (i + 1) / 2.5;
r->priority = i;
}
-
if ((r->priority < 0) || (r->priority > 39))
r->priority = 20;
- /*
- * 'media' size should be processed both in the lpsched filter and
- * the foomatic filter (if present) so that we ensure the result of
- * other options like 'page-ranges' are consistent.
- */
-/*
- * TODO - I thing we should really have this but I can't get it to filter
- * so its commented out for now (paulcun)
- * papiAttributeListGetString(attributes, NULL, "media", &r->form);
- */
+ /* set the requested form to print on */
+ papiAttributeListGetLPString(attributes, "form", &r->form);
+ /* set the page range */
#ifndef LP_USE_PAPI_ATTR
- papiAttributeListGetString(attributes, NULL, "page-ranges", &r->pages);
+ papiAttributeListGetLPString(attributes, "page-ranges", &r->pages);
#else
- getResult =
- papiAttributeListGetRange(attributes, &iterator,
- "page-ranges", &lowerPage, &upperPage);
- while (getResult == PAPI_OK) {
- if (r->pages == NULL) {
- snprintf(buf, sizeof (buf),
- "%d-%d", lowerPage, upperPage);
- r->pages = (char *)strdup(buf);
- }
- else
- {
+ for (status = papiAttributeListGetRange(attributes, &iterator,
+ "page-ranges", &lower, &upper);
+ status == PAPI_OK;
+ status = papiAttributeListGetRange(attributes, &iterator,
+ "page-ranges", &lower, &upper)) {
+ if (r->pages != NULL) {
snprintf(buf, sizeof (buf), "%s,%d-%d",
- r->pages, lowerPage, upperPage);
+ r->pages, lower, upper);
free(r->pages);
- r->pages = (char *)strdup(buf);
- }
- /*
- * get the next value; note the attribute 'name' is set to
- * NULL to do this.
- */
- getResult =
- papiAttributeListGetRange(attributes, &iterator,
- "page-ranges", &lowerPage, &upperPage);
+ } else
+ snprintf(buf, sizeof (buf), "%d-%d", lower, upper);
+ r->pages = (char *)strdup(buf);
}
#endif
-
+ /*
+ * set the document format, converting to old format names as
+ * as needed.
+ */
s = NULL;
papiAttributeListGetString(attributes, NULL, "document-format", &s);
if (s != NULL)
r->input_type = strdup(mime_type_to_lp_type(s));
+
/*
* If we don't have an owner, set one.
*/
@@ -165,6 +160,7 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
r->user = strdup(user);
}
+ /* set any held state */
s = NULL;
papiAttributeListGetString(attributes, NULL, "job-hold-until", &s);
if (s != NULL) {
@@ -178,7 +174,8 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
r->actions |= ACT_HOLD;
}
- papiAttributeListGetString(attributes, NULL, "lp-charset", &r->charset);
+ /* set lp charset/printwheel */
+ papiAttributeListGetLPString(attributes, "lp-charset", &r->charset);
/* legacy pr(1) filter related garbage "lpr -p" */
papiAttributeListGetBoolean(attributes, NULL, "pr-filter", &pr_filter);
@@ -208,12 +205,16 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
"pr(1) filter options specified without enabling pr(1) filter"));
/* add burst page information */
- papiAttributeListGetBoolean(attributes, NULL, "job-sheets", &banner);
- papiAttributeListGetString(attributes, NULL, "job-class", &class);
- papiAttributeListGetString(attributes, NULL, "job-name", &job_name);
-
- {
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "job-sheets", &s);
+ if ((s != NULL) && (strcasecmp(s, "none") == 0)) {
char buf[128];
+ char *class = NULL;
+ char *job_name = NULL;
+
+ papiAttributeListGetLPString(attributes, "job-class", &class);
+ papiAttributeListGetLPString(attributes, "job-name", &job_name);
+
/* burst page is enabled by default, add the title */
snprintf(buf, sizeof (buf), "%s%s%s",
(job_name ? job_name : ""),
@@ -224,27 +225,9 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
free(r->title);
r->title = strdup(buf);
}
- }
- if (banner == 0) /* burst page is disabled via lp "option" */
+ } else /* burst page is disabled via lp "option" */
appendlist(&options, "nobanner");
- /* add "lp -o" options */
- attr = papiAttributeListFind(attributes, "lp-options");
- if ((attr != NULL) && (attr->type == PAPI_STRING) &&
- (attr->values != NULL)) {
- int i;
-
- for (i = 0; attr->values[i] != NULL; i++)
- appendlist(&options, attr->values[i]->string);
- }
-
- if (options != NULL) {
- if (r->options != NULL)
- free(r->options);
- r->options = sprintlist(options);
- freelist(options);
- }
-
/* Convert attribute "number-up" to mode group=n */
papiAttributeListGetInteger(attributes, NULL, "number-up", &numberUp);
if ((numberUp >= 2) && ((numberUp % 2) == 0)) {
@@ -260,45 +243,15 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
"orientation-requested", &orientation);
if ((orientation >= 3) && (orientation <= 6)) {
switch (orientation) {
- case 3:
- {
- /* 3 = portrait */
- appendlist(&modes, "portrait");
- break;
- }
-
- case 4:
- {
- /* 4 = landscape */
- appendlist(&modes, "landscape");
- break;
- }
-
- case 5:
- {
- /*
- * 5 = reverse-landscape - not supported in
- * lpsched so just use 'landscape' for now
- */
- appendlist(&modes, "landscape");
- break;
- }
-
- case 6:
- {
- /*
- * 6 = reverse-portrait not supported in
- * lpsched so just use 'portrait' for now
- */
- appendlist(&modes, "portrait");
- break;
- }
-
- default:
- {
- appendlist(&modes, "portrait");
- break;
- }
+ case 4: /* landscape */
+ case 5: /* reverse-landscape, use landscape instead */
+ appendlist(&modes, "landscape");
+ break;
+ case 3: /* portrait */
+ case 6: /* reverse-portrait, use portrait instead */
+ default:
+ appendlist(&modes, "portrait");
+ break;
}
}
@@ -319,6 +272,29 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r,
freelist(modes);
}
+ /* add any unconsumed attributes to the "options" list */
+ split_and_copy_attributes(mapped_keys, attributes, NULL, &unmapped);
+ if (unmapped != NULL) { /* convert them to lp options */
+ char *buf = malloc(1024);
+ ssize_t size = 1024;
+
+ while (papiAttributeListToString(unmapped, ", ", buf, size)
+ != PAPI_OK) {
+ size += 1024;
+ buf = realloc(buf, size);
+ }
+ appendlist(&options, buf);
+ free(buf);
+ papiAttributeListFree(unmapped);
+ }
+
+ if (options != NULL) {
+ if (r->options != NULL)
+ free(r->options);
+ r->options = sprintlist(options);
+ freelist(options);
+ }
+
return (PAPI_OK);
}
@@ -388,26 +364,16 @@ lpsched_request_to_job_attributes(REQUEST *r, job_t *j)
"copies", r->copies);
/* destination */
- addLPString(&j->attributes, PAPI_ATTR_REPLACE, "printer-name",
- r->destination);
-
- /* file_list */
- addLPStrings(&j->attributes, PAPI_ATTR_REPLACE,
- "lpsched-files", r->file_list);
+ papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
+ "printer-name", r->destination);
/* form */
- addLPString(&j->attributes, PAPI_ATTR_REPLACE, "media", r->form);
-
- /* actions */
- papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
- "lpsched-actions", r->actions);
-
- /* alert */
- addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-alert", r->alert);
+ papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
+ "form", r->form);
/* options */
- addLPString(&j->attributes, PAPI_ATTR_REPLACE,
- "lp-options", r->options);
+ papiAttributeListFromString(&j->attributes, PAPI_ATTR_APPEND,
+ r->options);
tmp = (((r->options != NULL) && (strstr(r->options, "nobanner")
!= NULL)) ? "none" : "standard");
@@ -429,33 +395,30 @@ lpsched_request_to_job_attributes(REQUEST *r, job_t *j)
"job-priority", (int)((r->priority + 1) * 2.5));
/* pages */
- addLPString(&j->attributes, PAPI_ATTR_REPLACE, "page-ranges", r->pages);
+ papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
+ "page-ranges", r->pages);
/* charset */
- addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-charset",
- r->charset);
+ papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
+ "lp-charset", r->charset);
/* modes */
- addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-modes", r->modes);
+ papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
+ "lp-modes", r->modes);
/* title */
- addLPString(&j->attributes, PAPI_ATTR_REPLACE, "job-name", r->title);
+ papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
+ "job-name", r->title);
/* input_type */
/* user */
- addLPString(&j->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE,
"job-originating-user-name", r->user);
/* outcome */
- papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
- "lpsched-outcome", r->outcome);
lpsched_request_outcome_to_attributes(&j->attributes, r->outcome);
- /* version */
- papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
- "lpsched-version", r->version);
-
/* constants, (should be derived from options) */
papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE,
"number-up", 1);
@@ -476,7 +439,7 @@ job_status_to_attributes(job_t *job, char *req_id, char *user, char *slabel,
char buf[BUFSIZ];
char *p;
- addLPString(&job->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE,
"job-originating-user-name", user);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"job-k-octets", size/1024);
@@ -486,10 +449,12 @@ job_status_to_attributes(job_t *job, char *req_id, char *user, char *slabel,
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"job-id", atoi(++p));
}
- snprintf(buf, sizeof (buf), "lpsched://%s/%d", destination, atoi(p));
+ snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s/%d",
+ destination, atoi(p));
papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
"job-uri", buf);
- snprintf(buf, sizeof (buf), "lpsched://%s", destination);
+ snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s",
+ destination);
papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
"job-printer-uri", buf);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
@@ -498,25 +463,26 @@ job_status_to_attributes(job_t *job, char *req_id, char *user, char *slabel,
"output-device-assigned", destination);
papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE,
"printer-name", destination);
- addLPString(&job->attributes, PAPI_ATTR_REPLACE, "media", form);
+ papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE,
+ "form", form);
lpsched_request_outcome_to_attributes(&job->attributes, state);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"time-at-creation", date);
- addLPString(&job->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE,
"lpsched-request-id", req_id);
- addLPString(&job->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE,
"lp-charset", charset);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"lpsched-job-state", state);
papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE,
"number-of-intervening-jobs", rank - 1);
- addLPString(&job->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE,
"lpsched-file", file);
- addLPString(&job->attributes, PAPI_ATTR_EXCL,
+ papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_EXCL,
"job-name", file);
- addLPString(&job->attributes, PAPI_ATTR_EXCL,
+ papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_EXCL,
"tsol-sensitivity-label", slabel);
}
diff --git a/usr/src/cmd/lp/lib/papi/lpsched-misc.c b/usr/src/cmd/lp/lib/papi/lpsched-misc.c
index 0ed7895fbb..97047a8357 100644
--- a/usr/src/cmd/lp/lib/papi/lpsched-misc.c
+++ b/usr/src/cmd/lp/lib/papi/lpsched-misc.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,7 +35,8 @@
papi_status_t
-addLPString(papi_attribute_t ***list, int flags, char *name, char *value)
+papiAttributeListAddLPString(papi_attribute_t ***list, int flags, char *name,
+ char *value)
{
papi_status_t result = PAPI_BAD_ARGUMENT;
@@ -47,7 +47,7 @@ addLPString(papi_attribute_t ***list, int flags, char *name, char *value)
}
papi_status_t
-addLPStrings(papi_attribute_t ***list, int flags, char *name,
+papiAttributeListAddLPStrings(papi_attribute_t ***list, int flags, char *name,
char **values)
{
papi_status_t result = PAPI_OK;
@@ -64,8 +64,45 @@ addLPStrings(papi_attribute_t ***list, int flags, char *name,
return (result);
}
+void
+papiAttributeListGetLPString(papi_attribute_t **attributes, char *key,
+ char **string)
+{
+ char *value = NULL;
+
+ papiAttributeListGetString(attributes, NULL, key, &value);
+ if (value != NULL) {
+ if (*string != NULL)
+ free(*string);
+ *string = strdup(value);
+ }
+}
+
+void
+papiAttributeListGetLPStrings(papi_attribute_t **attributes, char *key,
+ char ***strings)
+{
+ papi_status_t status;
+ char **values = NULL;
+ char *value = NULL;
+ void *iter = NULL;
+
+ for (status = papiAttributeListGetString(attributes, &iter,
+ key, &value);
+ status == PAPI_OK;
+ status = papiAttributeListGetString(attributes, &iter,
+ NULL, &value))
+ addlist(&values, value);
+
+ if (values != NULL) {
+ if (*strings != NULL)
+ freelist(*strings);
+ *strings = values;
+ }
+}
+
char *
-printer_name_from_uri_id(const char *uri, int32_t id)
+printer_name_from_uri_id(char *uri, int32_t id)
{
REQUEST *request = NULL;
char *result = "";
diff --git a/usr/src/cmd/lp/lib/papi/lpsched-msgs.c b/usr/src/cmd/lp/lib/papi/lpsched-msgs.c
index 7da01787da..5f5806276b 100644
--- a/usr/src/cmd/lp/lib/papi/lpsched-msgs.c
+++ b/usr/src/cmd/lp/lib/papi/lpsched-msgs.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,12 +32,14 @@
#include <libintl.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
/* lpsched include files */
#include "lp.h"
#include "msgs.h"
#include "printers.h"
+#include "class.h"
#include <papi_impl.h>
@@ -139,6 +140,8 @@ lpsched_status_to_papi_status(int status)
return (PAPI_SERVICE_UNAVAILABLE);
case M2LATE:
return (PAPI_GONE);
+ case MBUSY:
+ return (PAPI_PRINTER_BUSY);
case MOK:
case MOKMORE:
return (PAPI_OK);
@@ -233,7 +236,7 @@ lpsched_commit_job(papi_service_t svc, char *job, char **tmp)
}
papi_status_t
-lpsched_start_change(papi_service_t svc, const char *printer, int32_t job_id,
+lpsched_start_change(papi_service_t svc, char *printer, int32_t job_id,
char **tmp)
{
papi_status_t result = PAPI_OK;
@@ -264,7 +267,7 @@ lpsched_start_change(papi_service_t svc, const char *printer, int32_t job_id,
}
papi_status_t
-lpsched_end_change(papi_service_t svc, const char *printer, int32_t job_id)
+lpsched_end_change(papi_service_t svc, char *printer, int32_t job_id)
{
papi_status_t result = PAPI_OK;
short status = MOK;
@@ -294,7 +297,62 @@ lpsched_end_change(papi_service_t svc, const char *printer, int32_t job_id)
}
papi_status_t
-lpsched_enable_printer(papi_service_t svc, const char *printer)
+lpsched_accept_printer(papi_service_t svc, char *printer)
+{
+ papi_status_t result = PAPI_OK;
+ short status;
+ char *req_id;
+ char *dest;
+
+ if ((svc == NULL) || (printer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ dest = printer_name_from_uri_id(printer, -1);
+ if ((snd_msg(svc, S_ACCEPT_DEST, dest) < 0) ||
+ (rcv_msg(svc, R_ACCEPT_DEST, &status, &req_id) < 0))
+ status = MTRANSMITERR;
+ free(dest);
+
+ if ((status != MOK) && (status != MERRDEST)) {
+ detailed_error(svc, "%s: %s", printer,
+ lpsched_status_string(status));
+ result = lpsched_status_to_papi_status(status);
+ }
+
+ return (result);
+}
+
+papi_status_t
+lpsched_reject_printer(papi_service_t svc, char *printer, char *message)
+{
+ papi_status_t result = PAPI_OK;
+ short status;
+ char *req_id;
+ char *dest;
+
+ if ((svc == NULL) || (printer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if (message == NULL)
+ message = "stopped by user";
+
+ dest = printer_name_from_uri_id(printer, -1);
+ if ((snd_msg(svc, S_REJECT_DEST, dest, message, 0) < 0) ||
+ (rcv_msg(svc, R_REJECT_DEST, &status, &req_id) < 0))
+ status = MTRANSMITERR;
+ free(dest);
+
+ if ((status != MOK) && (status != MERRDEST)) {
+ detailed_error(svc, "%s: %s", printer,
+ lpsched_status_string(status));
+ result = lpsched_status_to_papi_status(status);
+ }
+
+ return (result);
+}
+
+papi_status_t
+lpsched_enable_printer(papi_service_t svc, char *printer)
{
papi_status_t result = PAPI_OK;
short status;
@@ -320,8 +378,7 @@ lpsched_enable_printer(papi_service_t svc, const char *printer)
}
papi_status_t
-lpsched_disable_printer(papi_service_t svc, const char *printer,
- const char *message)
+lpsched_disable_printer(papi_service_t svc, char *printer, char *message)
{
papi_status_t result = PAPI_OK;
short status;
@@ -348,3 +405,216 @@ lpsched_disable_printer(papi_service_t svc, const char *printer,
return (result);
}
+
+papi_status_t
+lpsched_load_unload_dest(papi_service_t handle, char *dest, int type)
+{
+ service_t *svc = handle;
+ papi_status_t result;
+ short status = MOK;
+
+ /* tell the scheduler it's going */
+ if (snd_msg(svc, type, dest, "", "") < 0)
+ return (PAPI_SERVICE_UNAVAILABLE);
+
+ switch (type) {
+ case S_LOAD_PRINTER:
+ type = R_LOAD_PRINTER;
+ break;
+ case S_UNLOAD_PRINTER:
+ type = R_UNLOAD_PRINTER;
+ break;
+ case S_LOAD_CLASS:
+ type = R_LOAD_CLASS;
+ break;
+ case S_UNLOAD_CLASS:
+ type = R_UNLOAD_CLASS;
+ }
+
+ if (rcv_msg(svc, type, &status) < 0)
+ return (PAPI_SERVICE_UNAVAILABLE);
+
+ result = lpsched_status_to_papi_status(status);
+
+ return (result);
+}
+
+papi_status_t
+lpsched_remove_class(papi_service_t handle, char *dest)
+{
+ papi_status_t result;
+
+ /* tell the scheduler it's going */
+ result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_CLASS);
+
+ if (result == PAPI_OK) {
+ /* remove the scheduler config files */
+ if (delclass(dest) == -1)
+ result = PAPI_SERVICE_UNAVAILABLE;
+ }
+
+ return (result);
+}
+
+static void
+remove_from_class(papi_service_t handle, char *dest, CLASS *cls)
+{
+ if (dellist(&cls->members, dest) == 0) {
+ if (cls->members != NULL) {
+ if (putclass(cls->name, cls) == 0)
+ (void) lpsched_load_unload_dest(handle,
+ cls->name, S_LOAD_CLASS);
+ } else
+ (void) lpsched_remove_class(handle, cls->name);
+ }
+}
+
+papi_status_t
+lpsched_remove_printer(papi_service_t handle, char *dest)
+{
+
+ papi_status_t result;
+
+ /* tell the scheduler it's going */
+ result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_PRINTER);
+
+ if (result == PAPI_OK) {
+ CLASS *cls;
+ char *dflt;
+
+ /* remove the scheduler config files */
+ if (delprinter(dest) == -1)
+ return (PAPI_SERVICE_UNAVAILABLE);
+
+ /* remove from any classes */
+ while ((cls = getclass(NAME_ALL)) != NULL)
+ if (searchlist(dest, cls->members) != 0)
+ remove_from_class(handle, dest, cls);
+
+ /* reset the default if it needs to be done */
+ if (((dflt = getdefault()) != NULL) &&
+ (strcmp(dflt, dest) == 0))
+ putdefault(NAME_NONE);
+ }
+
+ return (result);
+}
+
+papi_status_t
+lpsched_add_modify_class(papi_service_t handle, char *dest,
+ papi_attribute_t **attributes)
+{
+ papi_status_t result;
+ void *iter = NULL;
+ char **members = NULL;
+ char *member;
+
+ /*
+ * The only attribute that we can modify for a class is the set of
+ * members. Anything else will be ignored.
+ */
+ for (result = papiAttributeListGetString(attributes, &iter,
+ "member-names", &member);
+ result == PAPI_OK;
+ result = papiAttributeListGetString(attributes, &iter,
+ NULL, &member))
+ addlist(&members, member);
+
+ if (members != NULL) {
+ /* modify the configuration file */
+ CLASS class;
+
+ memset(&class, 0, sizeof (class));
+ class.name = dest;
+ class.members = members;
+
+ if (putclass(dest, &class) == -1) {
+ if ((errno == EPERM) || (errno == EACCES))
+ result = PAPI_NOT_AUTHORIZED;
+ else
+ result = PAPI_NOT_POSSIBLE;
+ } else
+ result = PAPI_OK;
+
+ freelist(members);
+ } else
+ result = PAPI_ATTRIBUTES;
+
+ /* tell the scheduler about the changes */
+ if (result == PAPI_OK)
+ result = lpsched_load_unload_dest(handle, dest, S_LOAD_CLASS);
+
+ return (result);
+}
+
+papi_status_t
+lpsched_add_printer(papi_service_t handle, char *dest,
+ papi_attribute_t **attributes)
+{
+ PRINTER *p;
+ papi_status_t result = PAPI_TEMPORARY_ERROR;
+
+ if ((p = calloc(1, sizeof (*p))) != NULL) {
+ p->name = strdup(dest);
+ p->banner = BAN_ALWAYS;
+ p->interface = strdup("/usr/lib/lp/model/uri");
+ p->fault_alert.shcmd = strdup("mail");
+
+ attributes_to_printer(attributes, p);
+
+ if (putprinter(dest, p) == -1) {
+ if ((errno == EPERM) || (errno == EACCES))
+ result = PAPI_NOT_AUTHORIZED;
+ else
+ result = PAPI_NOT_POSSIBLE;
+ } else
+ result = PAPI_OK;
+
+ freeprinter(p);
+ }
+
+ /* tell the scheduler about the changes */
+ if (result == PAPI_OK)
+ result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER);
+
+ return (result);
+}
+
+papi_status_t
+lpsched_add_modify_printer(papi_service_t handle, char *dest,
+ papi_attribute_t **attributes, int type)
+{
+ PRINTER *p;
+ papi_status_t result;
+
+ if (type == 0) {
+ if ((p = calloc(1, sizeof (*p))) != NULL) {
+ p->name = strdup(dest);
+ p->banner = BAN_ALWAYS;
+ p->interface = strdup("/usr/lib/lp/model/uri");
+ p->fault_alert.shcmd = strdup("mail");
+ }
+ } else
+ p = getprinter(dest);
+
+ if (p != NULL) {
+ attributes_to_printer(attributes, p);
+
+ if (putprinter(dest, p) == -1) {
+ if ((errno == EPERM) || (errno == EACCES))
+ result = PAPI_NOT_AUTHORIZED;
+ else
+ result = PAPI_NOT_POSSIBLE;
+ } else
+ result = PAPI_OK;
+
+ freeprinter(p);
+ } else
+ result = PAPI_NOT_POSSIBLE;
+
+ /* tell the scheduler about the changes */
+ if (result == PAPI_OK)
+ result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER);
+
+ return (result);
+}
diff --git a/usr/src/cmd/lp/lib/papi/lpsched-printers.c b/usr/src/cmd/lp/lib/papi/lpsched-printers.c
index d425c1bef7..408af31962 100644
--- a/usr/src/cmd/lp/lib/papi/lpsched-printers.c
+++ b/usr/src/cmd/lp/lib/papi/lpsched-printers.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,12 +30,12 @@
#include <stdlib.h>
#include <libintl.h>
#include <unistd.h>
+#include <string.h>
#include <sys/utsname.h>
#include <papi_impl.h>
#include "class.h"
-
void
lpsched_printer_status_to_attributes(papi_attribute_t ***attrs,
unsigned short status)
@@ -73,25 +72,9 @@ lpsched_printer_status_to_attributes(papi_attribute_t ***attrs,
papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
"printer-is-accepting-jobs",
((status & PS_REJECTED) != PS_REJECTED));
- papiAttributeListAddInteger(attrs, PAPI_ATTR_REPLACE,
- "lpsched-status", status);
papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
"printer-is-processing-jobs",
((status & PS_DISABLED) != PS_DISABLED));
- papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
- "lpsched-faulted", (status & PS_FAULTED));
- papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
- "lpsched-busy", (status & PS_BUSY));
- papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
- "lpsched-later", (status & PS_LATER));
- papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
- "lpsched-remote", (status & PS_REMOTE));
- papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
- "lpsched-show-fault", (status & PS_SHOW_FAULT));
- papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
- "lpsched-use-as-key", (status & PS_USE_AS_KEY));
- papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE,
- "lpsched-form-fault", (status & PS_FORM_FAULT));
}
void
@@ -113,12 +96,23 @@ lpsched_printer_defaults(papi_attribute_t ***attributes)
"job-priority-default", 20);
papiAttributeListAddRange(attributes, PAPI_ATTR_REPLACE,
"copies-supported", 1, 65535);
+ papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
+ "copies-default", 1);
papiAttributeListAddBoolean(attributes, PAPI_ATTR_REPLACE,
"page-ranges-supported", PAPI_TRUE);
papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
"number-up-supported", 1);
papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
"number-up-default", 1);
+ papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
+ "job-hold-until-supported", "no-hold");
+ papiAttributeListAddString(attributes, PAPI_ATTR_APPEND,
+ "job-hold-until-supported", "indefinite");
+ papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
+ "job-hold-until-default", "no-hold");
+ papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
+ "document-format-default", "application/octet-stream");
+
}
papi_status_t
@@ -128,6 +122,7 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p,
PRINTER *tmp;
char buf[BUFSIZ+1];
struct utsname sysname;
+ char **allowed = NULL, **denied = NULL;
if ((svc == NULL) || (p == NULL) || (dest == NULL))
return (PAPI_BAD_ARGUMENT);
@@ -140,12 +135,13 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p,
}
/* name */
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"printer-name", tmp->name);
if (tmp->name != NULL) {
char uri[BUFSIZ];
- snprintf(uri, sizeof (uri), "lpsched://%s", tmp->name);
+ snprintf(uri, sizeof (uri), "lpsched://localhost/printers/%s",
+ tmp->name);
papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE,
"printer-uri-supported", uri);
}
@@ -166,53 +162,53 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p,
int i;
for (i = 0; tmp->input_types[i] != NULL; i++)
- addLPString(&p->attributes,
+ papiAttributeListAddLPString(&p->attributes,
PAPI_ATTR_APPEND, "document-format-supported",
lp_type_to_mime_type(tmp->input_types[i]));
}
/* description */
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"printer-info", tmp->description);
/* add lpsched specific attributes */
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"device-uri", tmp->device);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-dial-info", tmp->dial_info);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-fault-recovery", tmp->fault_rec);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-interface-script", tmp->interface);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-data-rate", tmp->speed);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-stty", tmp->stty);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
- "lpsched-remote", tmp->remote);
papiAttributeListAddBoolean(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-login-term", tmp->login);
papiAttributeListAddBoolean(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-daisy", tmp->daisy);
- addLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-charsets", tmp->char_sets);
#ifdef CAN_DO_MODULES
- addLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-modules", tmp->modules);
#endif /* CAN_DO_MODULES */
- addLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-options", tmp->options);
- addLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-printer-type", tmp->printer_types);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ if (tmp->fault_alert.shcmd != NULL) {
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-fault-alert-command",
tmp->fault_alert.shcmd);
- papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-fault-alert-threshold",
tmp->fault_alert.Q);
- papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-fault-alert-interval",
tmp->fault_alert.W);
+ }
papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-cpi-value", tmp->cpi.val);
papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
@@ -229,6 +225,14 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p,
"lpsched-pwid-value", tmp->pwid.val);
papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-pwid-unit", tmp->pwid.sc);
+
+ /* allow/deny list */
+ load_userprinter_access(dest, &allowed, &denied);
+ papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
+ "requesting-user-name-allowed", allowed);
+ papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE,
+ "requesting-user-name-denied", denied);
+
#ifdef LP_USE_PAPI_ATTR
if (tmp->ppd != NULL) {
int fd;
@@ -242,12 +246,14 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p,
snprintf(buf, sizeof (buf), "file://%s%s/ppd/%s.ppd",
sysname.nodename, ETCDIR, tmp->name);
papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE,
- "lpsched-printer-ppd-uri", buf);
+ "ppd-file-uri", buf);
snprintf(buf, sizeof (buf), "file://%s%s",
sysname.nodename, tmp->ppd);
papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-printer-configure-ppd-uri", buf);
+ papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE,
+ "lpsched-ppd-source-path", tmp->ppd);
snprintf(buf, sizeof (buf), "%s/ppd/%s.ppd", ETCDIR, tmp->name);
@@ -255,56 +261,7 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p,
* We don't return error on any of the error conditions, we just
* silently return without adding the attribute.
*/
- if (((fd = open(buf, O_RDONLY)) >= 0) &&
- (fstat(fd, &sbuf) == 0)) {
- char *contents;
-
- if ((contents = malloc(sbuf.st_size + 1)) != NULL) {
- int pos = 0, rd, rdsize;
-
- rdsize = sbuf.st_blksize;
-
- while (rd = read(fd, contents + pos, rdsize)) {
- if (rd < 0) {
- if (errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
- pos += rd;
-
- /*
- * Don't write past the end of our
- * buffer. This is paranoid, in case
- * the file increased size while we were
- * reading it.
- */
- if (pos + rdsize > sbuf.st_size) {
- rdsize = sbuf.st_size - pos;
- }
- }
-
- /* File didn't change size while reading. */
- if (pos + rd == sbuf.st_size) {
- /*
- * Terminate the buffer and set
- * attribute. This assume that there
- * are no null bytes in the ppd file.
- */
- contents[pos + rd] = '\0';
-
- papiAttributeListAddString(
- &p->attributes,
- PAPI_ATTR_REPLACE,
- "lpsched-printer-ppd-contents",
- contents);
- }
-
- free(contents);
- }
- }
- close(fd);
+ PPDFileToAttributesList(&p->attributes, buf);
}
#endif
@@ -315,25 +272,25 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p,
papi_status_t
printer_status_to_attributes(printer_t *p, char *printer, char *form,
- char *character_set, char *reject_reason, char *disable_reason,
+ char *character_set, char *disable_reason, char *reject_reason,
short status, char *request_id,
- long enable_date, long reject_date)
+ long disable_date, long reject_date)
{
if (p == NULL)
return (PAPI_BAD_ARGUMENT);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
- "media-ready", form);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ "form-ready", form);
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-active-job", request_id);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-mounted-char-set", character_set);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
- "printer-reject-reason", reject_reason);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
- "printer-disable-reason", disable_reason);
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ "lpsched-disable-reason", disable_reason);
papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE,
- "lpsched-enable-date", enable_date);
+ "lpsched-disable-date", disable_date);
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ "lpsched-reject-reason", reject_reason);
papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-reject-date", reject_date);
@@ -378,12 +335,13 @@ lpsched_class_configuration_to_attributes(service_t *svc, printer_t *p,
}
/* name */
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
"printer-name", tmp->name);
if (tmp->name != NULL) {
char uri[BUFSIZ];
- snprintf(uri, sizeof (uri), "lpsched://%s", tmp->name);
+ snprintf(uri, sizeof (uri), "lpsched://localhost/printers/%s",
+ tmp->name);
papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE,
"printer-uri-supported", uri);
}
@@ -410,8 +368,8 @@ class_status_to_attributes(printer_t *p, char *printer, short status,
if (p == NULL)
return (PAPI_BAD_ARGUMENT);
- addLPString(&p->attributes, PAPI_ATTR_REPLACE,
- "printer-reject-reason", reject_reason);
+ papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE,
+ "lpsched-reject-reason", reject_reason);
papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE,
"lpsched-reject-date", reject_date);
@@ -432,3 +390,70 @@ class_status_to_attributes(printer_t *p, char *printer, short status,
return (PAPI_OK);
}
+
+papi_status_t
+attributes_to_printer(papi_attribute_t **attributes, PRINTER *tmp)
+{
+ papi_status_t status;
+ void *iter = NULL;
+ char *string = NULL;
+ int flags;
+ char **list = NULL;
+
+ /* banner needs some conversion to the bitfield */
+ iter = NULL, string = NULL; flags = 0;
+ for (status = papiAttributeListGetString(attributes, &iter,
+ "job-sheets-supported", &string);
+ status == PAPI_OK;
+ status = papiAttributeListGetString(attributes, &iter,
+ NULL, &string))
+ if (strcasecmp(string, "none") == 0)
+ flags |= BAN_NEVER;
+ else if (strcasecmp(string, "standard") == 0)
+ flags |= BAN_ALWAYS;
+ if (flags != 0)
+ tmp->banner = flags;
+
+ /* input_types needs mime-type conversion */
+ iter = NULL, string = NULL; list = NULL;
+ for (status = papiAttributeListGetString(attributes, &iter,
+ "document-format-supported", &string);
+ status == PAPI_OK;
+ status = papiAttributeListGetString(attributes, &iter,
+ NULL, &string))
+ addlist(&list, mime_type_to_lp_type(string));
+ if (list != NULL) {
+ if (tmp->input_types != NULL)
+ freelist(tmp->input_types);
+ tmp->input_types = list;
+ }
+
+ papiAttributeListGetLPString(attributes,
+ "device-uri", &tmp->device);
+ papiAttributeListGetLPString(attributes,
+ "printer-info", &tmp->description);
+ papiAttributeListGetLPString(attributes,
+ "lpsched-dial-info", &tmp->dial_info);
+ papiAttributeListGetLPString(attributes,
+ "lpsched-fault-recovery", &tmp->fault_rec);
+ papiAttributeListGetLPString(attributes,
+ "lpsched-interface-script", &tmp->interface);
+ papiAttributeListGetLPString(attributes,
+ "lpsched-data-rate", &tmp->speed);
+ papiAttributeListGetLPString(attributes,
+ "lpsched-stty", &tmp->stty);
+ papiAttributeListGetLPStrings(attributes,
+ "lpsched-charsets", &tmp->char_sets);
+ papiAttributeListGetLPStrings(attributes,
+ "lpsched-printer-types", &tmp->printer_types);
+ papiAttributeListGetLPStrings(attributes,
+ "lpsched-options", &tmp->options);
+ papiAttributeListGetLPStrings(attributes,
+ "lpsched-modules", &tmp->modules);
+#ifdef LP_USE_PAPI_ATTR
+ papiAttributeListGetLPString(attributes,
+ "lpsched-printer-ppd-uri", &tmp->ppd);
+#endif
+
+ return (PAPI_OK);
+}
diff --git a/usr/src/cmd/lp/lib/papi/lpsched-service.c b/usr/src/cmd/lp/lib/papi/lpsched-service.c
index 8b6d6b944b..33f0082944 100644
--- a/usr/src/cmd/lp/lib/papi/lpsched-service.c
+++ b/usr/src/cmd/lp/lib/papi/lpsched-service.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,13 +35,13 @@
void
-lpsched_service_information(printer_t *p)
+lpsched_service_information(papi_attribute_t ***attrs)
{
FORM form;
while (getform(NAME_ALL, &form, (FALERT *)0, (FILE **)0) != -1) {
- papiAttributeListAddString(&p->attributes, PAPI_ATTR_APPEND,
- "media-supported", form.name);
+ papiAttributeListAddString(attrs, PAPI_ATTR_APPEND,
+ "form-supported", form.name);
freeform(&form);
}
}
diff --git a/usr/src/cmd/lp/lib/papi/mapfile b/usr/src/cmd/lp/lib/papi/mapfile
new file mode 100644
index 0000000000..a10fae2acf
--- /dev/null
+++ b/usr/src/cmd/lp/lib/papi/mapfile
@@ -0,0 +1,151 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Generic interface definition for usr/src/cmd/lp/lib/papi
+#
+# For information regarding the establishment of versioned definitions see:
+# The Linker and Libraries Manual (version 2.5 or greater)
+# This is part of the Developers Guide in the Answerbook. Specifically refer
+# to Chapter 2 under section "Defining Additional Symbols" through section
+# "Reducing Symbol Scope", and Chapter 5 "Versioning".
+#
+# For specific OSNET rules for the modification (evolution) of these version
+# definitions see:
+# Policy for Shared Library Version Names and Interface Definitions
+
+SUNW_1.0 {
+ global:
+ # PAPI Attribute Calls
+ papiAttributeListAdd;
+ papiAttributeListAddValue = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddBoolean = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddCollection = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddDatetime = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddInteger = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddMetadata = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddRange = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddResolution = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListDelete = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetValue = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetNext = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFind = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetBoolean = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetCollection = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetDatetime = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetInteger = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetMetadata = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetRange = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetResolution = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFromString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListToString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFree = FUNCTION FILTER libpapi-common.so ;
+
+ # PAPI Service Calls
+ papiServiceCreate;
+ papiServiceDestroy;
+ papiServiceSetUserName;
+ papiServiceSetPassword;
+ papiServiceSetEncryption;
+ papiServiceSetAuthCB;
+ papiServiceSetAppData;
+ papiServiceGetUserName;
+ papiServiceGetPassword;
+ papiServiceGetEncryption;
+ papiServiceGetAppData;
+ papiServiceGetServiceName;
+ papiServiceGetAttributeList;
+ papiServiceGetStatusMessage;
+
+ # PAPI Printer Calls
+ papiPrintersList;
+ papiPrinterQuery;
+ papiPrinterAdd;
+ papiPrinterModify;
+ papiPrinterRemove;
+ papiPrinterDisable;
+ papiPrinterEnable;
+ papiPrinterPause;
+ papiPrinterResume;
+ papiPrinterPurgeJobs;
+ papiPrinterListJobs;
+ papiPrinterGetAttributeList;
+ papiPrinterFree;
+ papiPrinterListFree;
+
+ # PAPI Job Calls
+ papiJobSubmit;
+ papiJobSubmitByReference;
+ papiJobValidate;
+ papiJobStreamOpen;
+ papiJobStreamWrite;
+ papiJobStreamClose;
+ papiJobQuery;
+ papiJobModify;
+ papiJobMove;
+ papiJobCancel;
+ papiJobHold;
+ papiJobRelease;
+ papiJobRestart = FUNCTION FILTER libpapi-common.so ;
+ papiJobPromote;
+ papiJobGetAttributeList;
+ papiJobGetPrinterName;
+ papiJobGetId;
+ papiJobGetJobTicket = FUNCTION FILTER libpapi-common.so ;
+ papiJobFree;
+ papiJobListFree;
+
+ # Misc. PAPI Calls
+ papiStatusString = FUNCTION FILTER libpapi-common.so ;
+ papiLibrarySupportedCall;
+ papiLibrarySupportedCalls;
+};
+
+SUNWprivate_1.0 {
+ global:
+ papiServiceSetPeer; # used by to pass peer connection
+ papiJobCreate;
+ papiJobStreamAdd;
+ papiJobCommit;
+
+ # Misc. supporting calls
+ # URI
+ uri_from_string = FUNCTION FILTER libpapi-common.so ;
+ uri_to_string = FUNCTION FILTER libpapi-common.so ;
+ uri_free = FUNCTION FILTER libpapi-common.so ;
+ # list
+ list_remove = FUNCTION FILTER libpapi-common.so ;
+ list_append = FUNCTION FILTER libpapi-common.so ;
+ list_concatenate = FUNCTION FILTER libpapi-common.so ;
+
+ # extra Attribute Calls
+ copy_attributes = FUNCTION FILTER libpapi-common.so ;
+ split_and_copy_attributes = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListPrint = FUNCTION FILTER libpapi-common.so ;
+
+ local:
+ *;
+};
diff --git a/usr/src/cmd/lp/lib/papi/mapfile-vers b/usr/src/cmd/lp/lib/papi/mapfile-vers
deleted file mode 100644
index 2bddef28d0..0000000000
--- a/usr/src/cmd/lp/lib/papi/mapfile-vers
+++ /dev/null
@@ -1,125 +0,0 @@
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-#
-# Generic interface definition for usr/src/cmd/lp/lib/papi
-#
-# For information regarding the establishment of versioned definitions see:
-# The Linker and Libraries Manual (version 2.5 or greater)
-# This is part of the Developers Guide in the Answerbook. Specifically refer
-# to Chapter 2 under section "Defining Additional Symbols" through section
-# "Reducing Symbol Scope", and Chapter 5 "Versioning".
-#
-# For specific OSNET rules for the modification (evolution) of these version
-# definitions see:
-# Policy for Shared Library Version Names and Interface Definitions
-
-
-SUNWprivate_1.1 {
- global:
-
- papiAttributeListAdd;
- papiAttributeListAddString;
- papiAttributeListAddInteger;
- papiAttributeListAddBoolean;
- papiAttributeListAddRange;
- papiAttributeListAddResolution;
- papiAttributeListAddDatetime;
- papiAttributeListAddCollection;
- papiAttributeListDelete;
- papiAttributeListGetValue;
- papiAttributeListGetString;
- papiAttributeListGetInteger;
- papiAttributeListGetBoolean;
- papiAttributeListGetRange;
- papiAttributeListGetResolution;
- papiAttributeListGetDatetime;
- papiAttributeListGetCollection;
- papiAttributeListFree;
- papiAttributeListFind;
- papiAttributeListGetNext;
- papiAttributeListFromString;
- papiAttributeListToString;
-
- papiServiceCreate;
- papiServiceDestroy;
- papiServiceSetPeer; # used by to pass peer connection
- papiServiceSetUserName;
- papiServiceSetPassword;
- papiServiceSetEncryption;
- papiServiceSetAuthCB;
- papiServiceSetAppData;
- papiServiceGetUserName;
- papiServiceGetPassword;
- papiServiceGetEncryption;
- papiServiceGetAppData;
- papiServiceGetServiceName;
- papiServiceGetStatusMessage;
-
- papiPrintersList;
- papiPrinterQuery;
- papiPrinterModify;
- papiPrinterPause;
- papiPrinterResume;
- papiPrinterPurgeJobs;
- papiPrinterListJobs;
- papiPrinterGetAttributeList;
- papiPrinterFree;
- papiPrinterListFree;
-
- papiJobSubmit;
- papiJobSubmitByReference;
- papiJobValidate;
- papiJobStreamOpen;
- papiJobStreamWrite;
- papiJobStreamClose;
- papiJobQuery;
- papiJobModify;
- papiJobCancel;
- papiJobHold;
- papiJobRelease;
- papiJobRestart;
- papiJobGetAttributeList;
- papiJobGetPrinterName;
- papiJobGetId;
- papiJobGetJobTicket;
- papiJobFree;
- papiJobListFree;
-
- papiStatusString;
- #papiLibrarySupportedCalls;
- #papiLibrarySupportedCall;
-
- papiAttributeListPrint;
- list_append;
-
- papiJobCreate;
- papiJobStreamAdd;
- papiJobCommit;
-
- local:
- *;
-};
-
diff --git a/usr/src/cmd/lp/lib/papi/papi_impl.h b/usr/src/cmd/lp/lib/papi/papi_impl.h
index d2359f4e73..5d13df73ee 100644
--- a/usr/src/cmd/lp/lib/papi/papi_impl.h
+++ b/usr/src/cmd/lp/lib/papi/papi_impl.h
@@ -54,7 +54,7 @@ extern "C" {
typedef struct {
papi_attribute_t **attributes;
- int (*authCB)(papi_service_t svc);
+ int (*authCB)(papi_service_t svc, void *app_data);
void *app_data;
MESG *md;
char *msgbuf;
@@ -86,18 +86,27 @@ extern void job_status_to_attributes(job_t *job, char *req_id, char *user,
char *charset, short rank, char *file);
extern papi_status_t addLPString(papi_attribute_t ***list,
int flags, char *name, char *value);
-extern papi_status_t addLPStrings(papi_attribute_t ***list,
+extern papi_status_t papiAttributeListAddLPStrings(papi_attribute_t ***list,
int flags, char *name, char **values);
+extern void papiAttributeListGetLPString(papi_attribute_t **attributes,
+ char *key, char **string);
+extern void papiAttributeListGetLPStrings(papi_attribute_t **attributes,
+ char *key, char ***string);
+
extern papi_status_t lpsched_printer_configuration_to_attributes(
service_t *svc, printer_t *p, char *dest);
extern papi_status_t lpsched_class_configuration_to_attributes(service_t *svc,
printer_t *p, char *dest);
extern papi_status_t class_status_to_attributes(printer_t *p, char *printer,
short status, char *reject_reason, long reject_date);
+extern papi_status_t lpsched_reject_printer(papi_service_t svc,
+ char *printer, char *message);
+extern papi_status_t lpsched_accept_printer(papi_service_t svc,
+ char *printer);
extern papi_status_t lpsched_disable_printer(papi_service_t svc,
- const char *printer, const char *message);
+ char *printer, char *message);
extern papi_status_t lpsched_enable_printer(papi_service_t svc,
- const char *printer);
+ char *printer);
extern papi_status_t lpsched_status_to_papi_status(int status);
extern papi_status_t job_attributes_to_lpsched_request(papi_service_t svc,
REQUEST *r, papi_attribute_t **attributes);
@@ -106,31 +115,32 @@ extern papi_status_t lpsched_alloc_files(papi_service_t svc, int number,
extern papi_status_t lpsched_commit_job(papi_service_t svc, char *job,
char **tmp);
extern papi_status_t lpsched_start_change(papi_service_t svc,
- const char *printer, int32_t job_id, char **tmp);
+ char *printer, int32_t job_id, char **tmp);
extern papi_status_t lpsched_end_change(papi_service_t svc,
- const char *printer, int32_t job_id);
+ char *printer, int32_t job_id);
extern papi_status_t printer_status_to_attributes(printer_t *p, char *printer,
char *form, char *character_set, char *reject_reason,
char *disable_reason, short status, char *request_id, long enable_date,
long reject_date);
-
-extern void lpsched_service_information(printer_t *p);
+extern papi_status_t lpsched_remove_printer(papi_service_t svc, char *dest);
+extern papi_status_t lpsched_remove_class(papi_service_t svc, char *dest);
+extern papi_status_t lpsched_add_modify_printer(papi_service_t svc, char *dest,
+ papi_attribute_t **attributes, int type);
+extern papi_status_t lpsched_add_modify_class(papi_service_t svc, char *dest,
+ papi_attribute_t **attributes);
+
+extern void lpsched_service_information(papi_attribute_t ***attrs);
extern void lpsched_request_to_job_attributes(REQUEST *r, job_t *j);
extern void detailed_error(service_t *svc, char *fmt, ...);
extern char *banner_type(unsigned short banner);
extern char *mime_type_to_lp_type(char *mime_type);
extern char *lp_type_to_mime_type(char *lp_type);
-extern char *fifo_name_from_uri(const char *uri);
-extern char *printer_name_from_uri_id(const char *uri, int32_t id);
+extern char *fifo_name_from_uri(char *uri);
+extern char *printer_name_from_uri_id(char *uri, int32_t id);
extern int snd_msg(service_t *svc, int type, ...);
extern int rcv_msg(service_t *svc, int type, ...);
-extern int list_append();
-extern void list_remove();
-
-
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/lp/lib/papi/ppd.c b/usr/src/cmd/lp/lib/papi/ppd.c
new file mode 100644
index 0000000000..5facf902be
--- /dev/null
+++ b/usr/src/cmd/lp/lib/papi/ppd.c
@@ -0,0 +1,164 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * This file contains an extremely rudimentary implementation of PPD file
+ * parsing support. The parsing done here converts the contents of a PPD
+ * file into a set of PAPI attributes that applications can use to build
+ * print panels.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <papi.h>
+
+static void
+process_line(char *line, char **key, char **value, char **comment)
+{
+ char *ptr, *ptr2;
+
+ *key = &line[1];
+ *value = NULL;
+ *comment = NULL;
+
+ if ((ptr = strchr(line, ':')) == NULL)
+ return;
+
+ /*
+ * line is in the form:
+ * *key: value/comment
+ * or
+ * *key value/comment: data
+ */
+ *ptr++ = NULL;
+ while (isspace(*ptr) != 0)
+ ptr++;
+
+ if ((ptr2 = strchr(line, ' ')) != NULL) {
+ ptr = ptr2;
+ /*
+ * line is in the form:
+ * *key value/comment: data
+ */
+ *ptr++ = NULL;
+ while (*ptr == ' ')
+ ptr++;
+ }
+
+ if (*ptr == '*')
+ ptr++;
+
+ *value = ptr;
+
+ if ((ptr = strchr(ptr, '/')) != NULL) {
+ *ptr++ = NULL;
+ *comment = ptr;
+ }
+}
+
+papi_status_t
+PPDFileToAttributesList(papi_attribute_t ***attributes, char *filename)
+{
+ papi_status_t status = PAPI_OK;
+ FILE *fp;
+ char line[256];
+ char capability[256];
+ char def[256];
+ char supported[256];
+ char *current_group_name = NULL;
+
+ int ui = 0;
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ return (PAPI_NOT_POSSIBLE);
+
+ while ((status == PAPI_OK) &&
+ (fgets(line, sizeof (line), fp) != NULL)) {
+ char *key = NULL, *value = NULL, *text = NULL;
+
+ /* we want *key...: "value" */
+ if (line[0] != '*')
+ continue;
+
+ if (strchr(line, ':') == NULL)
+ continue;
+
+ if ((text = strrchr(line, '\n')) != NULL)
+ *text = NULL;
+
+ process_line(line, &key, &value, &text);
+
+ if ((strcasecmp(key, "PageSize") == 0) ||
+ (strcasecmp(key, "InputSlot") == 0))
+ key = "media";
+
+ if (strcasecmp(key, "OpenGroup") == 0) {
+ if (value == NULL)
+ value = "unknown";
+ current_group_name = strdup(value);
+ } else if (strcasecmp(key, "OpenUI") == 0) {
+ if ((strcasecmp(value, "PageSize") == 0) ||
+ (strcasecmp(value, "InputSlot") == 0))
+ value = "media";
+ snprintf(capability, sizeof (capability), "%s", value);
+ snprintf(def, sizeof (def),
+ "%s-default", value);
+ snprintf(supported, sizeof (supported),
+ "%s-supported", value);
+ ui = 1;
+ } else if (strcasecmp(key, "CloseGroup") == 0) {
+ /* do nothing */
+ } else if (strcasecmp(key, "CloseUI") == 0) {
+ ui = 0;
+ /* do nothing */
+ } else if (strcasecmp(key, "Manufacturer") == 0) {
+ status = papiAttributeListAddString(attributes,
+ PAPI_ATTR_EXCL,
+ "printer-make", value);
+ } else if (strcasecmp(key, "ModelName") == 0) {
+ status = papiAttributeListAddString(attributes,
+ PAPI_ATTR_EXCL,
+ "printer-model", value);
+ } else if (strcasecmp(key, "ShortNickName") == 0) {
+ status = papiAttributeListAddString(attributes,
+ PAPI_ATTR_EXCL,
+ "printer-make-and-model", value);
+ } else if ((strncasecmp(key, "Default", 7) == 0) && ui) {
+ status = papiAttributeListAddString(attributes,
+ PAPI_ATTR_EXCL,
+ def, value);
+ } else if ((strcasecmp(key, capability) == 0) && ui) {
+ status = papiAttributeListAddString(attributes,
+ PAPI_ATTR_APPEND,
+ supported, value);
+ }
+ }
+ fclose(fp);
+
+ return (status);
+}
diff --git a/usr/src/cmd/lp/lib/papi/printer.c b/usr/src/cmd/lp/lib/papi/printer.c
index 2bfc1eabc8..8d1c6f6459 100644
--- a/usr/src/cmd/lp/lib/papi/printer.c
+++ b/usr/src/cmd/lp/lib/papi/printer.c
@@ -59,8 +59,8 @@ papiPrinterListFree(papi_printer_t *printers)
}
papi_status_t
-papiPrintersList(papi_service_t handle, const char **requested_attrs,
- const papi_filter_t *filter, papi_printer_t **printers)
+papiPrintersList(papi_service_t handle, char **requested_attrs,
+ papi_filter_t *filter, papi_printer_t **printers)
{
service_t *svc = handle;
printer_t *p = NULL;
@@ -139,9 +139,9 @@ papiPrintersList(papi_service_t handle, const char **requested_attrs,
}
papi_status_t
-papiPrinterQuery(papi_service_t handle, const char *name,
- const char **requested_attrs,
- const papi_attribute_t **job_attrs,
+papiPrinterQuery(papi_service_t handle, char *name,
+ char **requested_attrs,
+ papi_attribute_t **job_attrs,
papi_printer_t *printer)
{
papi_status_t pst;
@@ -166,6 +166,22 @@ papiPrinterQuery(papi_service_t handle, const char *name,
dest = printer_name_from_uri_id(name, -1);
+ if (strcmp(dest, "_default") == 0) {
+ static char *_default;
+
+ if (_default == NULL) {
+ int fd;
+ static char buf[128];
+
+ if ((fd = open("/etc/lp/default", O_RDONLY)) >= 0) {
+ read(fd, buf, sizeof (buf));
+ close(fd);
+ _default = strtok(buf, " \t\n");
+ }
+ }
+ dest = _default;
+ }
+
if (isprinter(dest) != 0) {
pst = lpsched_printer_configuration_to_attributes(svc, p, dest);
if (pst != PAPI_OK)
@@ -202,7 +218,7 @@ papiPrinterQuery(papi_service_t handle, const char *name,
reject_reason, reject_date);
} else if (strcmp(dest, "PrintService") == 0) {
/* fill the printer object with service information */
- lpsched_service_information(p);
+ lpsched_service_information(&p->attributes);
} else
return (PAPI_NOT_FOUND);
@@ -212,19 +228,108 @@ papiPrinterQuery(papi_service_t handle, const char *name,
}
papi_status_t
-papiPrinterModify(papi_service_t handle, const char *name,
- const papi_attribute_t **attributes, papi_printer_t *result)
+papiPrinterAdd(papi_service_t handle, char *name,
+ papi_attribute_t **attributes, papi_printer_t *result)
{
- service_t *svc = handle;
+ papi_status_t status;
+ printer_t *p = NULL;
+ char *dest;
+
+ if ((handle == NULL) || (name == NULL) || (attributes == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ dest = printer_name_from_uri_id(name, -1);
+
+ if (isprinter(dest) != 0) {
+ status = lpsched_add_modify_printer(handle, dest,
+ attributes, 0);
+
+ if ((*result = p = calloc(1, sizeof (*p))) != NULL)
+ lpsched_printer_configuration_to_attributes(handle, p,
+ dest);
+ else
+ status = PAPI_TEMPORARY_ERROR;
+
+ } else if (isclass(dest) != 0) {
+ status = lpsched_add_modify_class(handle, dest, attributes);
+
+ if ((*result = p = calloc(1, sizeof (*p))) != NULL)
+ lpsched_class_configuration_to_attributes(handle, p,
+ dest);
+ else
+ status = PAPI_TEMPORARY_ERROR;
+
+ } else
+ status = PAPI_NOT_FOUND;
+
+ free(dest);
+
+ return (status);
+}
+
+papi_status_t
+papiPrinterModify(papi_service_t handle, char *name,
+ papi_attribute_t **attributes, papi_printer_t *result)
+{
+ papi_status_t status;
+ printer_t *p = NULL;
+ char *dest;
+
+ if ((handle == NULL) || (name == NULL) || (attributes == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ dest = printer_name_from_uri_id(name, -1);
+
+ if (isprinter(dest) != 0) {
+ status = lpsched_add_modify_printer(handle, dest,
+ attributes, 1);
+
+ if ((*result = p = calloc(1, sizeof (*p))) != NULL)
+ lpsched_printer_configuration_to_attributes(handle, p,
+ dest);
+ else
+ status = PAPI_TEMPORARY_ERROR;
+ } else if (isclass(dest) != 0) {
+ status = lpsched_add_modify_class(handle, dest, attributes);
+
+ if ((*result = p = calloc(1, sizeof (*p))) != NULL)
+ lpsched_class_configuration_to_attributes(handle, p,
+ dest);
+ else
+ status = PAPI_TEMPORARY_ERROR;
+ } else
+ status = PAPI_NOT_FOUND;
+
+ free(dest);
+
+ return (status);
+}
+
+papi_status_t
+papiPrinterRemove(papi_service_t handle, char *name)
+{
+ papi_status_t result;
+ char *dest;
- if ((svc == NULL) || (name == NULL) || (attributes == NULL))
+ if ((handle == NULL) || (name == NULL))
return (PAPI_BAD_ARGUMENT);
- return (PAPI_OPERATION_NOT_SUPPORTED);
+ dest = printer_name_from_uri_id(name, -1);
+
+ if (isprinter(dest) != 0) {
+ result = lpsched_remove_printer(handle, dest);
+ } else if (isclass(dest) != 0) {
+ result = lpsched_remove_class(handle, dest);
+ } else
+ result = PAPI_NOT_FOUND;
+
+ free(dest);
+
+ return (result);
}
papi_status_t
-papiPrinterPause(papi_service_t handle, const char *name, const char *message)
+papiPrinterDisable(papi_service_t handle, char *name, char *message)
{
papi_status_t result;
@@ -237,7 +342,7 @@ papiPrinterPause(papi_service_t handle, const char *name, const char *message)
}
papi_status_t
-papiPrinterResume(papi_service_t handle, const char *name)
+papiPrinterEnable(papi_service_t handle, char *name)
{
papi_status_t result;
@@ -250,7 +355,33 @@ papiPrinterResume(papi_service_t handle, const char *name)
}
papi_status_t
-papiPrinterPurgeJobs(papi_service_t handle, const char *name, papi_job_t **jobs)
+papiPrinterPause(papi_service_t handle, char *name, char *message)
+{
+ papi_status_t result;
+
+ if ((handle == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ result = lpsched_reject_printer(handle, name, message);
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterResume(papi_service_t handle, char *name)
+{
+ papi_status_t result;
+
+ if ((handle == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ result = lpsched_accept_printer(handle, name);
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs)
{
service_t *svc = handle;
papi_status_t result = PAPI_OK_SUBST;
@@ -263,10 +394,10 @@ papiPrinterPurgeJobs(papi_service_t handle, const char *name, papi_job_t **jobs)
return (PAPI_BAD_ARGUMENT);
dest = printer_name_from_uri_id(name, -1);
- if (snd_msg(svc, S_CANCEL, dest, "", "") < 0)
- return (PAPI_SERVICE_UNAVAILABLE);
-
+ more = snd_msg(svc, S_CANCEL, dest, "", "");
free(dest);
+ if (more < 0)
+ return (PAPI_SERVICE_UNAVAILABLE);
do {
if (rcv_msg(svc, R_CANCEL, &more, &status, &req_id) < 0)
@@ -300,9 +431,9 @@ papiPrinterPurgeJobs(papi_service_t handle, const char *name, papi_job_t **jobs)
}
papi_status_t
-papiPrinterListJobs(papi_service_t handle, const char *name,
- const char **requested_attrs, const int type_mask,
- const int max_num_jobs, papi_job_t **jobs)
+papiPrinterListJobs(papi_service_t handle, char *name,
+ char **requested_attrs, int type_mask,
+ int max_num_jobs, papi_job_t **jobs)
{
service_t *svc = handle;
char *dest;
diff --git a/usr/src/cmd/lp/lib/papi/service.c b/usr/src/cmd/lp/lib/papi/service.c
index f9c9162406..a15434fcfb 100644
--- a/usr/src/cmd/lp/lib/papi/service.c
+++ b/usr/src/cmd/lp/lib/papi/service.c
@@ -38,10 +38,10 @@
#include <tsol/label.h>
papi_status_t
-papiServiceCreate(papi_service_t *handle, const char *service_name,
- const char *user_name, const char *password,
- const int (*authCB)(papi_service_t svc),
- const papi_encryption_t encryption, void *app_data)
+papiServiceCreate(papi_service_t *handle, char *service_name,
+ char *user_name, char *password,
+ int (*authCB)(papi_service_t svc, void *app_data),
+ papi_encryption_t encryption, void *app_data)
{
service_t *svc = NULL;
char *path = Lp_FIFO;
@@ -125,7 +125,7 @@ papiServiceSetPeer(papi_service_t handle, int peerfd)
}
papi_status_t
-papiServiceSetUserName(papi_service_t handle, const char *user_name)
+papiServiceSetUserName(papi_service_t handle, char *user_name)
{
service_t *svc = handle;
@@ -137,7 +137,7 @@ papiServiceSetUserName(papi_service_t handle, const char *user_name)
}
papi_status_t
-papiServiceSetPassword(papi_service_t handle, const char *password)
+papiServiceSetPassword(papi_service_t handle, char *password)
{
service_t *svc = handle;
@@ -150,7 +150,7 @@ papiServiceSetPassword(papi_service_t handle, const char *password)
papi_status_t
papiServiceSetEncryption(papi_service_t handle,
- const papi_encryption_t encryption)
+ papi_encryption_t encryption)
{
service_t *svc = handle;
@@ -163,20 +163,20 @@ papiServiceSetEncryption(papi_service_t handle,
papi_status_t
papiServiceSetAuthCB(papi_service_t handle,
- const int (*authCB)(papi_service_t svc))
+ int (*authCB)(papi_service_t svc, void *app_data))
{
service_t *svc = handle;
if (svc == NULL)
return (PAPI_BAD_ARGUMENT);
- svc->authCB = (int (*)(papi_service_t svc))authCB;
+ svc->authCB = (int (*)(papi_service_t svc, void *app_data))authCB;
return (PAPI_OK);
}
papi_status_t
-papiServiceSetAppData(papi_service_t handle, const void *app_data)
+papiServiceSetAppData(papi_service_t handle, void *app_data)
{
service_t *svc = handle;
@@ -252,6 +252,20 @@ papiServiceGetAppData(papi_service_t handle)
return (result);
}
+papi_attribute_t **
+papiServiceGetAttributeList(papi_service_t handle)
+{
+ service_t *svc = handle;
+ papi_attribute_t **result = NULL;
+
+ if (svc != NULL) {
+ lpsched_service_information(&svc->attributes);
+ result = svc->attributes;
+ }
+
+ return (result);
+}
+
char *
papiServiceGetStatusMessage(papi_service_t handle)
{
diff --git a/usr/src/cmd/print/Makefile b/usr/src/cmd/print/Makefile
index ff02c70dbf..27ccdf43ad 100644
--- a/usr/src/cmd/print/Makefile
+++ b/usr/src/cmd/print/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -36,13 +35,10 @@ PRINT_SUBDIRS = \
scripts \
lpget \
lpset \
- lp \
- lpstat \
- cancel \
- lpmove \
conv_fix \
printer-info \
- gateway
+ gateway \
+ bsd-sysv-commands
SUBDIRS = $(PRINT_SUBDIRS) $(JAVA_SUBDIRS)
diff --git a/usr/src/cmd/print/Makefile.sp b/usr/src/cmd/print/Makefile.sp
index f4510a84a8..af1d87d236 100644
--- a/usr/src/cmd/print/Makefile.sp
+++ b/usr/src/cmd/print/Makefile.sp
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
#
# CDDL HEADER END
#
+
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -87,7 +87,7 @@ INCSYS = $(INC)/sys
LPINC = $(SRC)/include
#NPRTINC = $(NPRTROOT)/include
-NPRTINC = $(SRC)/lib
+NPRTINC = $(SRC)/lib/print/libprint/common
LPLIB = $(SRC)/lib
LDLIBS += -L$(LPLIB)
diff --git a/usr/src/cmd/print/bsd-sysv-commands/Makefile b/usr/src/cmd/print/bsd-sysv-commands/Makefile
new file mode 100644
index 0000000000..ee16f07879
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/Makefile
@@ -0,0 +1,84 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+UCBPROGS = lpr lpq lprm lpc
+BINPROGS = lp lpstat cancel enable disable $(UCBPROGS)
+
+SBINPROGS = accept reject lpmove
+
+
+OBJS = $(BINPROGS:=.o) $(SBINPROGS:=.o) common.o
+
+ROOTBINPROGS = $(BINPROGS:%=$(ROOTBIN)/%)
+ROOTUSRSBINPROGS = $(SBINPROGS:%=$(ROOTUSRSBIN)/%)
+
+
+FILEMODE = 0555
+OWNER = root
+
+include ../../Makefile.cmd
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -I.
+CPPFLAGS += -I../../../lib/print/libpapi-common/common
+LDLIBS += -lpapi -lc
+
+# each program needs common.o as well
+$(BINPROGS) $(SBINPROGS): $(BINPROGS:%=%.c) $(SBINPROGS:%=%.c) common.o
+ $(LINK.c) -o $@ $@.c common.o $(LDLIBS)
+ $(POST_PROCESS)
+
+# ucb links (lptest is handled in usr/src/cmd/lp/cmd/Makefile)
+ROOTUSRUCB = $(ROOT)/usr/ucb
+ROOTUCBSYMLINKS = $(UCBPROGS:%=$(ROOTUSRUCB)/%)
+$(ROOTUSRUCB)/%: $(ROOTUSRUCB) %
+
+$(ROOTUCBSYMLINKS):
+ $(RM) $@; $(SYMLINK) ../bin/$(@F) $@
+
+# usr/lib links
+ROOTUSRLIBSYMLINKS = $(SBINPROGS:%=$(ROOTLIB)/%)
+$(ROOTLIB)/%: $(ROOTLIB) %
+
+$(ROOTUSRLIBSYMLINKS):
+ $(RM) $@; $(SYMLINK) ../sbin/$(@F) $@
+
+.KEEP_STATE:
+
+all: $(BINPROGS) $(SBINPROGS)
+
+install: $(BINPROGS) $(SBINPROGS) $(ROOTBINPROGS) $(ROOTUSRSBINPROGS) \
+ $(ROOTUCBSYMLINKS) $(ROOTUSRLIBSYMLINKS)
+
+clean:
+ $(RM) $(OBJS)
+
+CLOBBERFILES += $(BINPROGS) $(SBINPROGS)
+
+lint:
+
+include ../../Makefile.targ
diff --git a/usr/src/cmd/print/bsd-sysv-commands/accept.c b/usr/src/cmd/print/bsd-sysv-commands/accept.c
new file mode 100644
index 0000000000..c20f9344de
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/accept.c
@@ -0,0 +1,104 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: accept.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout,
+ gettext("Usage: %s destination ...\n"),
+ name);
+ exit(1);
+}
+
+int
+main(int ac, char *av[])
+{
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ int exit_status = 0;
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av, "E")) != EOF)
+ switch (c) {
+ case 'E':
+ encryption = PAPI_ENCRYPT_ALWAYS;
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ if (ac == optind)
+ usage(av[0]);
+
+ for (c = optind; c < ac; c++) {
+ char *printer = av[c];
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL,
+ cli_auth_callback, encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"),
+ printer, verbose_papi_message(svc, status));
+ exit_status = 1;
+ }
+
+ status = papiPrinterResume(svc, printer);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("accept: %s: %s\n"), printer,
+ verbose_papi_message(svc, status));
+ exit_status = 1;
+ }
+
+ papiServiceDestroy(svc);
+ }
+
+ return (exit_status);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/cancel.c b/usr/src/cmd/print/bsd-sysv-commands/cancel.c
new file mode 100644
index 0000000000..c95279ad5e
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/cancel.c
@@ -0,0 +1,127 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: cancel.c 147 2006-04-25 16:51:06Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout, "Usage: %s [-u user] (printer|request-id ...)\n", name);
+ exit(1);
+}
+
+int
+main(int ac, char *av[])
+{
+ int exit_code = 0;
+ char *user = NULL;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av, "Eu:")) != EOF)
+ switch (c) {
+ case 'E':
+ encryption = PAPI_ENCRYPT_REQUIRED;
+ break;
+ case 'u':
+ user = optarg;
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ for (c = optind; c < ac; c++) {
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_job_t *jobs = NULL;
+ char *printer = NULL;
+ int32_t id = -1;
+
+ (void) get_printer_id(av[c], &printer, &id);
+
+ status = papiServiceCreate(&svc, printer, user, NULL,
+ cli_auth_callback, encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"),
+ printer, verbose_papi_message(svc, status));
+ exit(1);
+ }
+
+#define OUT ((status == PAPI_OK) ? stdout : stderr)
+
+ if (id != -1) { /* it's a job */
+ char *mesg = "cancelled";
+
+ status = papiJobCancel(svc, printer, id);
+ if (status != PAPI_OK) {
+ mesg = verbose_papi_message(svc, status);
+ exit_code = 1;
+ }
+ fprintf(OUT, "%s-%d: %s\n", printer, id, mesg);
+ } else { /* it's a printer */
+ status = papiPrinterPurgeJobs(svc, printer, &jobs);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("PurgeJobs %s: %s\n"),
+ printer,
+ verbose_papi_message(svc, status));
+ exit_code = 1;
+ }
+
+ while ((jobs != NULL) && (*jobs != NULL))
+ fprintf(OUT, "%s-%d: %s\n", printer,
+ papiJobGetId(*jobs++), "cancelled");
+
+ papiJobListFree(jobs);
+ }
+
+ papiServiceDestroy(svc);
+ }
+
+ return (exit_code);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/common.c b/usr/src/cmd/print/bsd-sysv-commands/common.c
new file mode 100644
index 0000000000..5d70752563
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/common.c
@@ -0,0 +1,491 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: common.c 162 2006-05-08 14:17:44Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <alloca.h>
+#include <string.h>
+#include <libintl.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <papi.h>
+#include "common.h"
+
+#ifndef HAVE_GETPASSPHRASE /* some systems don't have getpassphrase() */
+#define getpassphrase getpass
+#endif
+
+/* give the most verbose error message to the caller */
+char *
+verbose_papi_message(papi_service_t svc, papi_status_t status)
+{
+ char *mesg;
+
+ mesg = papiServiceGetStatusMessage(svc);
+
+ if (mesg == NULL)
+ mesg = papiStatusString(status);
+
+ return (mesg);
+}
+
+static int
+match_job(int id, char *user, int ac, char *av[])
+{
+ int i;
+
+ for (i = 0; i < ac; i++)
+ if (strcmp("-", av[i]) == 0)
+ return (0); /* "current" user match */
+ else if ((isdigit(av[i][0]) != 0) && (id == atoi(av[i])))
+ return (0); /* job-id match */
+ else if (strcmp(user, av[i]) == 0)
+ return (0); /* user match */
+
+ return (-1);
+}
+
+/*
+ * to support job/printer status
+ */
+static char *
+state_string(int state)
+{
+ switch (state) {
+ case 3:
+ return (gettext("idle"));
+ case 4:
+ return (gettext("processing"));
+ case 5:
+ return (gettext("stopped"));
+ default:
+ return (gettext("unknown"));
+ }
+}
+
+static char *_rank_suffixes[] = {
+ "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th"
+};
+
+static char *
+rank_string(const int rank)
+{
+ static char buf[12];
+
+ if (rank < 0)
+ snprintf(buf, sizeof (buf), gettext("invalid"));
+ else if (rank == 0)
+ snprintf(buf, sizeof (buf), gettext("active"));
+ else if ((rank > 10) && (rank < 14))
+ sprintf(buf, "%dth", rank);
+ else
+ sprintf(buf, "%d%s", rank, _rank_suffixes[rank % 10]);
+
+ return (buf);
+}
+
+static void
+printer_state_line(FILE *fp, papi_printer_t p, int num_jobs, char *name)
+{
+ papi_attribute_t **list = papiPrinterGetAttributeList(p);
+ int state = 0;
+ char *reason = "";
+
+ (void) papiAttributeListGetInteger(list, NULL,
+ "printer-state", &state);
+ (void) papiAttributeListGetString(list, NULL,
+ "printer-state-reasons", &reason);
+ (void) papiAttributeListGetString(list, NULL,
+ "printer-name", &name);
+
+ if ((state != 0x03) || (num_jobs != 0)) {
+ fprintf(fp, "%s: %s", name, state_string(state));
+ if (state == 0x05) /* stopped */
+ fprintf(fp, ": %s\n", reason);
+ else
+ fprintf(fp, "\n");
+ } else
+ fprintf(fp, "no entries\n");
+}
+
+static void
+print_header(FILE *fp)
+{
+ fprintf(fp, gettext("Rank\tOwner\t Job\tFile(s)\t\t\t\tTotal Size\n"));
+}
+
+static void
+print_job_line(FILE *fp, int count, papi_job_t job, int fmt, int ac, char *av[])
+{
+ papi_attribute_t **list = papiJobGetAttributeList(job);
+ int copies = 1, id = 0, rank = count, size = 0;
+ char *name = "print job";
+ char *user = "nobody";
+ char *host = "localhost";
+ char *suffix = "k";
+
+ (void) papiAttributeListGetInteger(list, NULL,
+ "job-id", &id);
+ (void) papiAttributeListGetString(list, NULL,
+ "job-originating-user-name", &user);
+
+ /* if we are looking and it doesn't match, return early */
+ if ((ac > 0) && (match_job(id, user, ac, av) < 0))
+ return;
+
+ (void) papiAttributeListGetInteger(list, NULL,
+ "copies", &copies);
+ (void) papiAttributeListGetInteger(list, NULL,
+ "number-of-intervening-jobs", &rank);
+
+ if (papiAttributeListGetInteger(list, NULL, "job-octets", &size)
+ == PAPI_OK)
+ suffix = "bytes";
+ else
+ (void) papiAttributeListGetInteger(list, NULL,
+ "job-k-octets", &size);
+ (void) papiAttributeListGetString(list, NULL,
+ "job-name", &name);
+
+ size *= copies;
+
+ if (fmt == 3) {
+ fprintf(fp, gettext("%s\t%-8.8s %d\t%-32.32s%d %s\n"),
+ rank_string(++rank), user, id, name, size, suffix);
+ } else
+ fprintf(fp, gettext(
+ "\n%s: %s\t\t\t\t[job %d %s]\n\t%-32.32s\t%d %s\n"),
+ user, rank_string(++rank), id, host, name, size,
+ suffix);
+}
+
+/*
+ * to support job cancelation
+ */
+static void
+cancel_job(papi_service_t svc, FILE *fp, char *printer, papi_job_t job,
+ int ac, char *av[])
+{
+ papi_status_t status;
+ papi_attribute_t **list = papiJobGetAttributeList(job);
+ int id = 0;
+ char *user = "";
+ char *mesg = gettext("cancelled");
+
+ papiAttributeListGetInteger(list, NULL,
+ "job-id", &id);
+ papiAttributeListGetString(list, NULL,
+ "job-originating-user-name", &user);
+
+ /* if we are looking and it doesn't match, return early */
+ if ((ac > 0) && (match_job(id, user, ac, av) < 0))
+ return;
+
+ status = papiJobCancel(svc, printer, id);
+ if (status != PAPI_OK)
+ mesg = papiStatusString(status);
+
+ fprintf(fp, "%s-%d: %s\n", printer, id, mesg);
+}
+
+int
+berkeley_queue_report(papi_service_t svc, FILE *fp, char *dest, int fmt,
+ int ac, char *av[])
+{
+ papi_status_t status;
+ papi_printer_t p = NULL;
+ papi_job_t *jobs = NULL;
+ char *pattrs[] = { "printer-name", "printer-state",
+ "printer-state-reasons", NULL };
+ char *jattrs[] = {
+ "job-name", "job-octets", "job-k-octets",
+ "job-originating-user-name", "job-id",
+ "number-of-intervening-jobs", NULL };
+ int num_jobs = 0;
+
+ status = papiPrinterQuery(svc, dest, pattrs, NULL, &p);
+ if (status != PAPI_OK) {
+ fprintf(fp, gettext(
+ "Failed to query service for state of %s: %s\n"),
+ dest, verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ status = papiPrinterListJobs(svc, dest, jattrs, PAPI_LIST_JOBS_ALL,
+ 0, &jobs);
+ if (status != PAPI_OK) {
+ fprintf(fp, gettext(
+ "Failed to query service for jobs on %s: %s\n"),
+ dest, verbose_papi_message(svc, status));
+ return (-1);
+ }
+ if (jobs != NULL) {
+ while (jobs[num_jobs] != NULL)
+ num_jobs++;
+ }
+
+ printer_state_line(fp, p, num_jobs, dest);
+ if (num_jobs > 0) {
+ int i;
+
+ if (fmt == 3)
+ print_header(fp);
+ for (i = 0; jobs[i] != NULL; i++)
+ print_job_line(fp, i, jobs[i], fmt, ac, av);
+ }
+
+ papiPrinterFree(p);
+ papiJobListFree(jobs);
+
+ return (num_jobs);
+}
+
+int
+berkeley_cancel_request(papi_service_t svc, FILE *fp, char *dest,
+ int ac, char *av[])
+{
+ papi_status_t status;
+ papi_job_t *jobs = NULL;
+ char *jattrs[] = { "job-originating-user-name", "job-id", NULL };
+
+ status = papiPrinterListJobs(svc, dest, jattrs, PAPI_LIST_JOBS_ALL,
+ 0, &jobs);
+
+ if (status != PAPI_OK) {
+ fprintf(fp, gettext("Failed to query service for %s: %s\n"),
+ dest, verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ /* cancel the job(s) */
+ if (jobs != NULL) {
+ int i;
+
+ for (i = 0; jobs[i] != NULL; i++)
+ cancel_job(svc, fp, dest, jobs[i], ac, av);
+ }
+
+ papiJobListFree(jobs);
+
+ return (0);
+}
+
+int
+get_printer_id(char *name, char **printer, int *id)
+{
+ int result = -1;
+
+ if (name != NULL) {
+ char *p = strrchr(name, '-');
+
+ *printer = name;
+ if (p != NULL) {
+ char *s = NULL;
+
+ *id = strtol(p + 1, &s, 10);
+ if (s[0] != '\0')
+ *id = -1;
+ else
+ *p = '\0';
+ result = 0;
+ } else
+ *id = -1;
+ }
+
+ return (result);
+}
+
+/*
+ * strsplit() splits a string into a NULL terminated array of substrings
+ * determined by a seperator. The original string is modified, and newly
+ * allocated space is only returned for the array itself. If more than
+ * 1024 substrings exist, they will be ignored.
+ */
+char **
+strsplit(char *string, const char *seperators)
+{
+ char *list[BUFSIZ],
+ **result;
+ int length = 0;
+
+ if ((string == NULL) || (seperators == NULL))
+ return (NULL);
+
+ (void) memset(list, 0, sizeof (list));
+ for (list[length] = strtok(string, seperators);
+ (list[length] != NULL) && (length < (BUFSIZ - 2));
+ list[length] = strtok(NULL, seperators))
+ length++;
+
+ if ((result = (char **)calloc(length+1, sizeof (char *))) != NULL)
+ (void) memcpy(result, list, length * sizeof (char *));
+
+ return (result);
+}
+
+papi_status_t
+jobSubmitSTDIN(papi_service_t svc, char *printer, papi_attribute_t **list,
+ papi_job_t *job)
+{
+ papi_status_t status;
+ papi_stream_t stream = NULL;
+ int rc;
+ char buf[BUFSIZ];
+
+ status = papiJobStreamOpen(svc, printer, list, NULL, &stream);
+ while ((status == PAPI_OK) && ((rc = read(0, buf, sizeof (buf))) > 0))
+ status = papiJobStreamWrite(svc, stream, buf, rc);
+
+ if (status == PAPI_OK)
+ status = papiJobStreamClose(svc, stream, job);
+
+ return (status);
+}
+
+static char **
+all_list(papi_service_t svc)
+{
+ papi_status_t status;
+ papi_printer_t printer = NULL;
+ char *list[] = { "member-names", NULL };
+ char **result = NULL;
+
+ status = papiPrinterQuery(svc, "_all", list, NULL, &printer);
+ if ((status == PAPI_OK) && (printer != NULL)) {
+ papi_attribute_t **attributes =
+ papiPrinterGetAttributeList(printer);
+ if (attributes != NULL) {
+ void *iter = NULL;
+ char *value = NULL;
+
+ for (status = papiAttributeListGetString(attributes,
+ &iter, "member-names", &value);
+ status == PAPI_OK;
+ status = papiAttributeListGetString(attributes,
+ &iter, NULL, &value))
+ list_append(&result, strdup(value));
+ }
+ papiPrinterFree(printer);
+ }
+
+ return (result);
+}
+
+static char **
+printers_list(papi_service_t svc)
+{
+ papi_status_t status;
+ papi_printer_t *printers = NULL;
+ char *keys[] = { "printer-name", NULL };
+ char **result = NULL;
+
+ status = papiPrintersList(svc, keys, NULL, &printers);
+ if ((status == PAPI_OK) && (printers != NULL)) {
+ int i;
+
+ for (i = 0; printers[i] != NULL; i++) {
+ papi_attribute_t **attributes =
+ papiPrinterGetAttributeList(printers[i]);
+ char *name = NULL;
+
+ (void) papiAttributeListGetString(attributes, NULL,
+ "printer-name", &name);
+ if ((name != NULL) && (strcmp(name, "_default") != 0))
+ list_append(&result, strdup(name));
+ }
+ papiPrinterListFree(printers);
+ }
+
+ return (result);
+}
+
+char **
+interest_list(papi_service_t svc)
+{
+ static char been_here;
+ static char **result;
+
+ if (been_here == 0) { /* only do this once */
+ been_here = 1;
+
+ if ((result = all_list(svc)) == NULL)
+ result = printers_list(svc);
+ }
+
+ return (result);
+}
+
+char *
+localhostname()
+{
+ static char *result;
+
+ if (result == NULL) {
+ static char buf[256];
+
+ if (gethostname(buf, sizeof (buf)) == 0)
+ result = buf;
+ }
+
+ return (result);
+}
+
+int
+cli_auth_callback(papi_service_t svc, void *app_data)
+{
+ char prompt[BUFSIZ];
+ char *user, *svc_name, *passphrase;
+
+ /* get the name of the service we are contacting */
+ if ((svc_name = papiServiceGetServiceName(svc)) == NULL)
+ return (-1);
+
+ /* find our who we are supposed to be */
+ if ((user = papiServiceGetUserName(svc)) == NULL) {
+ struct passwd *pw;
+
+ if ((pw = getpwuid(getuid())) != NULL)
+ user = pw->pw_name;
+ else
+ user = "nobody";
+ }
+
+ /* build the prompt string */
+ snprintf(prompt, sizeof (prompt),
+ gettext("passphrase for %s to access %s: "), user, svc_name);
+
+ /* ask for the passphrase */
+ if ((passphrase = getpassphrase(prompt)) != NULL)
+ papiServiceSetPassword(svc, passphrase);
+
+ return (0);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/common.h b/usr/src/cmd/print/bsd-sysv-commands/common.h
new file mode 100644
index 0000000000..92a2b5b66c
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/common.h
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#ifndef _BSD_SYSV_COMMON_H
+#define _BSD_SYSV_COMMON_H
+
+/* $Id: common.h 162 2006-05-08 14:17:44Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <papi.h>
+
+#include <config-site.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char **strsplit(char *string, const char *seperators);
+extern char *verbose_papi_message(papi_service_t svc, papi_status_t status);
+
+extern int berkeley_cancel_request(papi_service_t svc, FILE *fp, char *dest,
+ int ac, char *av[]);
+
+extern int get_printer_id(char *name, char **printer, int *id);
+
+extern int berkeley_queue_report(papi_service_t svc, FILE *fp, char *dest,
+ int fmt, int ac, char *av[]);
+
+extern papi_status_t jobSubmitSTDIN(papi_service_t svc, char *printer,
+ papi_attribute_t **list, papi_job_t *job);
+
+extern char **interest_list(papi_service_t svc);
+extern char *localhostname();
+
+extern int cli_auth_callback(papi_service_t svc, void *app_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BSD_SYSV_COMMON_H */
diff --git a/usr/src/cmd/print/bsd-sysv-commands/disable.c b/usr/src/cmd/print/bsd-sysv-commands/disable.c
new file mode 100644
index 0000000000..8b813b6d56
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/disable.c
@@ -0,0 +1,149 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: disable.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout,
+ gettext("Usage: %s [-c] [-W] [-r reason] destination ...\n"),
+ name);
+ exit(1);
+}
+
+static void
+cancel_active_job(papi_service_t svc, char *dest)
+{
+ papi_status_t status;
+ papi_job_t *j = NULL;
+ char *req_attrs[] = { "job-state", "job-id", NULL };
+
+ status = papiPrinterListJobs(svc, dest, req_attrs, 0, 0, &j);
+ if ((status == PAPI_OK) && (j != NULL)) {
+ int i;
+
+ for (i = 0; j[i] != NULL; j++) {
+ papi_attribute_t **a = papiJobGetAttributeList(j[i]);
+ int state = 0;
+
+ if (a == NULL)
+ continue;
+
+ (void) papiAttributeListGetInteger(a, NULL,
+ "job-state", &state);
+ if (state == 0x05) { /* processing */
+ int32_t id = papiJobGetId(j[i]);
+
+ (void) papiJobCancel(svc, dest, id);
+ }
+ }
+ papiJobListFree(j);
+ }
+}
+
+int
+main(int ac, char *av[])
+{
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ int exit_status = 0;
+ int cancel = 0;
+ int pending = 0; /* not implemented */
+ char *reason = NULL;
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av, "EcWr:")) != EOF)
+ switch (c) {
+ case 'c': /* cancel active job first */
+ cancel = 1;
+ break;
+ case 'W': /* wait for active request, not implemented */
+ pending = 1;
+ break;
+ case 'r': /* reason */
+ reason = optarg;
+ break;
+ case 'E':
+ encryption = PAPI_ENCRYPT_NEVER;
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ if (ac <= optind)
+ usage(av[0]);
+
+ while (optind < ac) {
+ char *printer = av[optind++];
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL,
+ cli_auth_callback, encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"),
+ printer, verbose_papi_message(svc, status));
+ exit_status = 1;
+ }
+
+ status = papiPrinterDisable(svc, printer, reason);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("disable: %s: %s\n"), printer,
+ verbose_papi_message(svc, status));
+ exit_status = 1;
+ }
+
+ if (cancel != 0)
+ cancel_active_job(svc, printer);
+
+ papiServiceDestroy(svc);
+ }
+
+ return (exit_status);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/enable.c b/usr/src/cmd/print/bsd-sysv-commands/enable.c
new file mode 100644
index 0000000000..1bf7a0ccce
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/enable.c
@@ -0,0 +1,104 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: enable.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout,
+ gettext("Usage: %s destination ...\n"),
+ name);
+ exit(1);
+}
+
+int
+main(int ac, char *av[])
+{
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ int exit_status = 0;
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av, "E")) != EOF)
+ switch (c) {
+ case 'E':
+ encryption = PAPI_ENCRYPT_ALWAYS;
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ if (ac == optind)
+ usage(av[0]);
+
+ for (c = optind; c < ac; c++) {
+ char *printer = av[c];
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL,
+ cli_auth_callback, encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"),
+ printer, verbose_papi_message(svc, status));
+ exit_status = 1;
+ }
+
+ status = papiPrinterEnable(svc, printer);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("enable: %s: %s\n"), printer,
+ verbose_papi_message(svc, status));
+ exit_status = 1;
+ }
+
+ papiServiceDestroy(svc);
+ }
+
+ return (exit_status);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/in.lpd.c b/usr/src/cmd/print/bsd-sysv-commands/in.lpd.c
new file mode 100644
index 0000000000..465189daf1
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/in.lpd.c
@@ -0,0 +1,242 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: in.lpd.c 170 2006-05-20 05:58:49Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+#include <libintl.h>
+
+#include <papi.h>
+#include "common.h"
+
+#define ACK(fp) { (void) fputc('\0', fp); (void) fflush(fp); }
+#define NACK(fp) { (void) fputc('\1', fp); (void) fflush(fp); }
+
+/*
+ * This file contains the front-end of the BSD Print Protocol adaptor. This
+ * code assumes a BSD Socket interface to the networking side.
+ */
+
+void
+fatal(FILE *fp, char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsyslog(LOG_DEBUG, fmt, ap);
+ vfprintf(fp, fmt, ap);
+ va_end(ap);
+}
+
+static void
+cleanup(char **files)
+{
+ if (files != NULL) {
+ int i;
+
+ for (i = 0; files[i] != NULL; i++)
+ unlink(files[i]);
+ }
+}
+
+static void
+berkeley_receive_files(papi_service_t svc, FILE *ifp, FILE *ofp)
+{
+ char line[BUFSIZ];
+ char **files = NULL; /* the job data files */
+
+ /* This should actually implement transfer job from RFC-1179 */
+ ACK(ofp);
+
+ while (fgets(line, sizeof (line), ifp) != NULL) {
+ switch (line[0]) {
+ case 0x01: /* Abort */
+ cleanup(files);
+ break;
+ case 0x02: /* Receive control file */
+
+ break;
+ case 0x03: { /* Receive data file */
+ char file[] = "lpdXXXXXX";
+ int fd;
+
+ fd = mkstemp(file);
+
+ list_append(&files, strdup(file));
+ }
+ break;
+ default:
+ fatal(ofp, "protocol screwup");
+ cleanup(files);
+ break;
+ }
+ }
+
+ cleanup(files);
+}
+
+static void
+berkeley_transfer_files(papi_service_t svc, FILE *ifp, FILE *ofp,
+ char *printer)
+{
+ papi_status_t status;
+ papi_printer_t p = NULL;
+ char *keys[] = { "printer-is-accepting", NULL };
+
+ status = papiPrinterQuery(svc, printer, keys, NULL, &p);
+ if ((status == PAPI_OK) && (p != NULL)) {
+ papi_attribute_t **attrs = papiPrinterGetAttributeList(p);
+ char accepting = PAPI_FALSE;
+
+ papiAttributeListGetBoolean(attrs, NULL,
+ "printer-is-accepting", &accepting);
+
+ if (accepting == PAPI_TRUE)
+ berkeley_receive_files(svc, ifp, ofp);
+ else
+ NACK(ofp);
+
+ papiPrinterFree(p);
+ } else
+ NACK(ofp);
+}
+
+/*
+ * This is the entry point for this program. The program takes the
+ * following options:
+ * (none)
+ */
+int
+main(int ac, char *av[])
+{
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ FILE *ifp = stdin,
+ *ofp = stdout;
+ int c;
+ char buf[BUFSIZ],
+ **args,
+ *printer;
+
+ openlog("bsd-gw", LOG_PID, LOG_LPR);
+
+ while ((c = getopt(ac, av, "d")) != EOF)
+ switch (c) {
+ case 'E':
+ encryption = PAPI_ENCRYPT_ALWAYS;
+ break;
+ case 'd':
+ default:
+ ;
+ }
+
+ if (fgets(buf, sizeof (buf), ifp) == NULL) {
+ if (feof(ifp) == 0)
+ syslog(LOG_ERR, "Error reading from connection: %s",
+ strerror(errno));
+ exit(1);
+ }
+
+ if ((buf[0] < 1) || (buf[0] > 5)) {
+ fatal(ofp, "Invalid protocol request (%d): %c%s\n",
+ buf[0], buf[0], buf);
+ exit(1);
+ }
+
+ args = strsplit(&buf[1], "\t\n ");
+ printer = *args++;
+
+ if (printer == NULL) {
+ fatal(ofp, "Can't determine requested printer");
+ exit(1);
+ }
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL, NULL,
+ encryption, NULL);
+ if (status != PAPI_OK) {
+ fatal(ofp, "Failed to contact service for %s: %s\n", printer,
+ verbose_papi_message(svc, status));
+ exit(1);
+ }
+
+#ifdef HAVE_IS_SYSTEM_LABELED
+ if (is_system_labeled()) {
+ int fd = fileno(ifp);
+
+ (void) papiServiceSetPeer(svc, fd);
+ }
+#endif
+
+ switch (buf[0]) {
+ case '\1': /* restart printer */
+ ACK(ofp); /* there is no equivalent */
+ break;
+ case '\2': /* transfer job(s) */
+ berkeley_transfer_files(svc, ifp, ofp, printer);
+ break;
+ case '\3': /* show queue (short) */
+ case '\4': { /* show queue (long) */
+ int count;
+
+ for (count = 0; args[count] != 0; count++);
+
+ berkeley_queue_report(svc, ofp, printer, buf[0], count, args);
+ }
+ break;
+ case '\5': { /* cancel job(s) */
+ char *requestor = *args++;
+ int count;
+
+ status = papiServiceSetUserName(svc, requestor);
+ for (count = 0; args[count] != 0; count++);
+
+ berkeley_cancel_request(svc, ofp, printer, count, args);
+ }
+ break;
+ default:
+ fatal(ofp, "unsupported protocol request (%c), %s",
+ buf[0], &buf[1]);
+ }
+
+ (void) fflush(ofp);
+
+ syslog(LOG_DEBUG, "protocol request(%d) for %s completed: %s",
+ buf[0], printer, papiStatusString(status));
+ syslog(LOG_DEBUG, "detail: %s", verbose_papi_message(svc, status));
+
+ papiServiceDestroy(svc);
+
+ return (0);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/lp.c b/usr/src/cmd/print/bsd-sysv-commands/lp.c
new file mode 100644
index 0000000000..702f1b8d00
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/lp.c
@@ -0,0 +1,328 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lp.c 169 2006-05-20 05:58:14Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+#ifdef HAVE_LIBMAGIC /* for mimetype auto-detection */
+#include <magic.h>
+#endif /* HAVE_LIBMAGIC */
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout,
+ gettext("Usage: %s [-c] [-m] [-p] [-s] [-w] [-d destination] "
+ "[-f form-name] [-H special-handling] [-n number] "
+ "[-o option] [-P page-list] [-q priority-level] "
+ "[-S character-set | print-wheel] [-t title] [-v] "
+ "[-T content-type [-r]] [-y mode-list] [file...]\n"),
+ name);
+ exit(1);
+}
+
+static struct {
+ char *mime_type;
+ char *lp_type;
+} type_map[] = {
+ { "text/plain", "simple" },
+ { "application/octet-stream", "raw" },
+ { "application/octet-stream", "any" },
+ { "application/postscript", "postscript" },
+ { "application/postscript", "ps" },
+ { "application/x-cif", "cif" },
+ { "application/x-dvi", "dvi" },
+ { "application/x-plot", "plot" },
+ { "application/x-ditroff", "troff" },
+ { "application/x-troff", "otroff" },
+ { "application/x-pr", "pr" },
+ { "application/x-fortran", "fortran" },
+ { "application/x-raster", "raster" },
+ { NULL, NULL}
+};
+
+static char *
+lp_type_to_mime_type(char *lp_type)
+{
+ int i;
+
+ if (lp_type == NULL)
+ return ("application/octet-stream");
+
+ for (i = 0; type_map[i].lp_type != NULL; i++)
+ if (strcasecmp(type_map[i].lp_type, lp_type) == 0)
+ return (type_map[i].mime_type);
+
+ return (lp_type);
+}
+
+int
+main(int ac, char *av[])
+{
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_attribute_t **list = NULL;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ papi_job_t job = NULL;
+ char *printer = NULL;
+ char b = PAPI_TRUE;
+ int copy = 0;
+ int silent = 0;
+ int dump = 0;
+ int validate = 0;
+ int modify = -1;
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av, "DEH:P:S:T:cd:f:i:mn:o:pq:rst:Vwy:")) != EOF)
+ switch (c) {
+ case 'H': /* handling */
+ if (strcasecmp(optarg, "hold") == 0)
+ papiAttributeListAddString(&list,
+ PAPI_ATTR_EXCL,
+ "job-hold-until", "indefinite");
+ else if (strcasecmp(optarg, "release") == 0)
+ papiAttributeListAddString(&list,
+ PAPI_ATTR_EXCL,
+ "job-hold-until", "no-hold");
+ else if (strcasecmp(optarg, "immediate") == 0)
+ papiAttributeListAddInteger(&list,
+ PAPI_ATTR_EXCL,
+ "job-priority", 100);
+ else
+ papiAttributeListAddString(&list,
+ PAPI_ATTR_EXCL,
+ "job-hold-until", optarg);
+ break;
+ case 'P': /* page list */
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "page-ranges", optarg);
+ break;
+ case 'S': /* charset */
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "lp-charset", optarg);
+ break;
+ case 'T': /* type */
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format",
+ lp_type_to_mime_type(optarg));
+ break;
+ case 'D': /* dump */
+ dump = 1;
+ break;
+ case 'c': /* copy */
+ copy = 1;
+ break;
+ case 'd': /* destination */
+ printer = optarg;
+ break;
+ case 'f': /* form */
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "media", optarg);
+ break;
+ case 'i': /* modify job */
+ if ((get_printer_id(optarg, &printer, &modify) < 0) ||
+ (modify < 0)) {
+ fprintf(stderr,
+ gettext("invalid request id: %s\n"),
+ optarg);
+ exit(1);
+ }
+ break;
+ case 'm': /* mail when complete */
+ papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
+ "rfc-1179-mail", 1);
+ break;
+ case 'n': /* copies */
+ papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
+ "copies", atoi(optarg));
+ break;
+ case 'o': /* lp "options" */
+ papiAttributeListFromString(&list,
+ PAPI_ATTR_REPLACE, optarg);
+ break;
+ case 'p': /* Solaris - notification */
+ papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
+ "rfc-1179-mail", 1);
+ break;
+ case 'q': { /* priority */
+ int i = atoi(optarg);
+
+ i = 99 * (39 - i) / 39 + 1;
+ if ((i < 1) || (i > 100)) {
+ fprintf(stderr, gettext(
+ "priority must be between 0 and 39.\n"));
+ exit(1);
+ }
+ papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
+ "priority", i);
+ }
+ break;
+ case 'r': /* "raw" mode */
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format",
+ "application/octet-stream");
+ papiAttributeListAddString(&list, PAPI_ATTR_APPEND,
+ "stty", "raw");
+ break;
+ case 's': /* suppress message */
+ silent = 1;
+ break;
+ case 't': /* title */
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "job-name", optarg);
+ break;
+ case 'V': /* validate */
+ validate = 1;
+ break;
+ case 'w':
+ papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
+ "rfc-1179-mail", 1);
+ break;
+ case 'y': /* lp "modes" */
+ papiAttributeListAddString(&list, PAPI_ATTR_APPEND,
+ "lp-modes", optarg);
+ break;
+ case 'E':
+ encryption = PAPI_ENCRYPT_REQUIRED;
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ /* convert "banner", "nobanner" to "job-sheet" */
+ if (papiAttributeListGetBoolean(list, NULL, "banner", &b) == PAPI_OK) {
+ (void) papiAttributeListDelete(&list, "banner");
+ if (b == PAPI_FALSE)
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "job-sheets", "none");
+ }
+
+ if ((printer == NULL) &&
+ ((printer = getenv("PRINTER")) == NULL) &&
+ ((printer = getenv("LPDEST")) == NULL))
+ printer = DEFAULT_DEST;
+
+ if (modify == -1) {
+ char *document_format = "application/octet-stream";
+
+#ifdef MAGIC_MIME
+ if (optind != ac) {
+ /* get the mime type of the file data */
+ magic_t ms = NULL;
+
+ if ((ms = magic_open(MAGIC_MIME)) != NULL) {
+ document_format = magic_file(ms, av[optind]);
+ magic_close(ms);
+ }
+ }
+#endif
+
+ papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, "copies", 1);
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", document_format);
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "job-sheets", "standard");
+ }
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback,
+ encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"), printer,
+ verbose_papi_message(svc, status));
+ exit(1);
+ }
+
+ if (modify != -1)
+ status = papiJobModify(svc, printer, modify, list, &job);
+ else if (optind == ac) /* no file list, use stdin */
+ status = jobSubmitSTDIN(svc, printer, list, &job);
+ else if (validate == 1) /* validate the request can be processed */
+ status = papiJobValidate(svc, printer, list,
+ NULL, &av[optind], &job);
+ else if (copy == 0) /* reference the files in the job, default */
+ status = papiJobSubmitByReference(svc, printer, list,
+ NULL, &av[optind], &job);
+ else /* copy the files before return, -c */
+ status = papiJobSubmit(svc, printer, list,
+ NULL, &av[optind], &job);
+
+ papiAttributeListFree(list);
+
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("%s: %s\n"), printer,
+ verbose_papi_message(svc, status));
+ papiJobFree(job);
+ papiServiceDestroy(svc);
+ exit(1);
+ }
+
+ if (((silent == 0) || (dump != 0)) &&
+ ((list = papiJobGetAttributeList(job)) != NULL)) {
+ char *dest = "unknown";
+ int32_t id = 0;
+
+ papiAttributeListGetString(list, NULL, "printer-name", &dest);
+ papiAttributeListGetInteger(list, NULL, "job-id", &id);
+ printf(gettext("request id is %s-%d "), dest, id);
+ if (ac != optind)
+ printf("(%d file(s))\n", ac - optind);
+ else
+ printf("(standard input)\n");
+
+ if (dump != 0) {
+ printf("job attributes:\n");
+ papiAttributeListPrint(stdout, list, "\t");
+ printf("\n");
+ }
+ }
+
+ papiJobFree(job);
+ papiServiceDestroy(svc);
+
+ return (0);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/lpc.c b/usr/src/cmd/print/bsd-sysv-commands/lpc.c
new file mode 100644
index 0000000000..6d0aa6135d
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/lpc.c
@@ -0,0 +1,540 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lpc.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+typedef int (cmd_handler_t)(papi_service_t, char **);
+
+static papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+
+/* ARGSUSED0 */
+static int
+lpc_exit(papi_service_t svc, char **args)
+{
+ exit(0);
+ /* NOTREACHED */
+ return (0);
+}
+
+static int
+lpc_status(papi_service_t svc, char **args)
+{
+ papi_status_t status;
+ papi_printer_t p = NULL;
+ char *pattrs[] = { "printer-state", "printer-state-reasons",
+ "printer-is-accepting-jobs", NULL };
+ char *destination = args[1];
+
+ status = papiPrinterQuery(svc, destination, pattrs, NULL, &p);
+ if (status == PAPI_OK) {
+ papi_attribute_t **list = papiPrinterGetAttributeList(p);
+ char accepting = 0;
+ int32_t state = 0;
+
+ printf("%s:\n", destination);
+
+ (void) papiAttributeListGetBoolean(list, NULL,
+ "printer-is-accepting-jobs", &accepting);
+ printf(gettext("\tqueueing is %s\n"),
+ (accepting ? gettext("enabled") : gettext("disabled")));
+
+ (void) papiAttributeListGetInteger(list, NULL,
+ "printer-state", &state);
+ printf("\tprinting is %s\n",
+ ((state != 0x05) ? gettext("enabled") :
+ gettext("disabled")));
+
+ if (state != 0x03) { /* !idle */
+ papi_job_t *jobs = NULL;
+ int i = 0;
+
+ (void) papiPrinterListJobs(svc, destination, NULL,
+ PAPI_LIST_JOBS_ALL, 0, &jobs);
+ if (jobs != NULL) {
+ for (i = 0; jobs[i] != NULL; i++);
+ papiJobListFree(jobs);
+ }
+ printf(gettext("\t%d entries in spool area\n"), i);
+ } else
+ printf(gettext("\tno entries\n"));
+
+ if (state == 0x04)
+ printf(gettext("\tdaemon present\n"));
+
+ } else {
+ fprintf(stderr, "%s: %s\n", destination,
+ verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ papiPrinterFree(p);
+
+ return (0);
+}
+
+static int
+lpc_abort(papi_service_t svc, char **args)
+{
+ papi_status_t status;
+ char *destination = args[1];
+
+ if (destination == NULL) {
+ fprintf(stderr, gettext("Usage: abort (destination)\n"));
+ return (-1);
+ }
+
+ status = papiPrinterPause(svc, destination, "paused via lpc abort");
+ if (status == PAPI_OK) {
+ printf(gettext("%s: processing disabled after current job\n"),
+ destination);
+ } else {
+ fprintf(stderr, "%s: %s\n", destination,
+ verbose_papi_message(svc, status));
+ }
+
+ return (0);
+}
+
+static int
+lpc_clean(papi_service_t svc, char **args)
+{
+ papi_status_t status;
+ papi_job_t *jobs = NULL;
+ char *destination = args[1];
+
+ if (destination == NULL) {
+ fprintf(stderr, gettext("Usage: clean (destination)\n"));
+ return (-1);
+ }
+
+ status = papiPrinterPurgeJobs(svc, destination, &jobs);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("clean: %s: %s\n"), destination,
+ verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ if (jobs != NULL) {
+ int i;
+
+ for (i = 0; jobs[i] != NULL; i++)
+ printf(gettext("\t%s-%d: cancelled\n"), destination,
+ papiJobGetId(jobs[i]));
+
+ papiJobListFree(jobs);
+ }
+
+ return (0);
+}
+
+static int
+lpc_disable(papi_service_t svc, char **args)
+{
+ papi_status_t status;
+ char *destination = args[1];
+
+ if (destination == NULL) {
+ fprintf(stderr, gettext("Usage: disable: (destination)\n"));
+ return (-1);
+ }
+
+ status = papiPrinterDisable(svc, destination, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("disable: %s: %s\n"), destination,
+ verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+lpc_enable(papi_service_t svc, char **args)
+{
+ papi_status_t status;
+ char *destination = args[1];
+
+ if (destination == NULL) {
+ fprintf(stderr, gettext("Usage: enable: (destination)\n"));
+ return (-1);
+ }
+
+ status = papiPrinterEnable(svc, destination);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("enable: %s: %s\n"), destination,
+ verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+lpc_restart(papi_service_t svc, char **args)
+{
+ int rc = 0;
+
+ rc += lpc_disable(svc, args);
+ rc += lpc_enable(svc, args);
+
+ return (rc);
+}
+
+static int
+lpc_start(papi_service_t svc, char **args)
+{
+ papi_status_t status;
+ char *destination = args[1];
+
+ if (destination == NULL) {
+ fprintf(stderr, gettext("Usage: start (destination)\n"));
+ return (-1);
+ }
+
+ status = papiPrinterResume(svc, destination);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("start: %s: %s\n"), destination,
+ verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+lpc_stop(papi_service_t svc, char **args)
+{
+ papi_status_t status;
+ char *destination = args[1];
+
+ if (destination == NULL) {
+ fprintf(stderr, gettext("Usage: stop (destination)\n"));
+ return (-1);
+ }
+
+ status = papiPrinterPause(svc, destination, "paused via lpc");
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("stop: %s: %s\n"), destination,
+ verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+lpc_topq(papi_service_t svc, char **args)
+{
+ papi_status_t status;
+ char *destination = args[1];
+ int32_t id = atoi(args[2]);
+
+ if (destination == NULL) {
+ fprintf(stderr, gettext("Usage: topq (destination) (id)\n"));
+ return (-1);
+ }
+
+ status = papiJobPromote(svc, destination, id);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("topq: %s %d: %s\n"), destination, id,
+ verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+lpc_up(papi_service_t svc, char **args)
+{
+ int rc = 0;
+
+ rc += lpc_enable(svc, args);
+ rc += lpc_start(svc, args);
+
+ return (rc);
+}
+
+static int
+lpc_down(papi_service_t svc, char **args)
+{
+ int rc = 0;
+
+ rc += lpc_disable(svc, args);
+ rc += lpc_stop(svc, args);
+
+ return (rc);
+}
+
+static int lpc_help(papi_service_t svc, char **args); /* forward reference */
+
+static char help_help[] = "get help on commands";
+static char help_exit[] = "exit lpc";
+static char help_status[] = "show status of daemon and queue";
+static char help_abort[] =
+ "disable print queue terminating any active job processing";
+static char help_clean[] = "remove all jobs from a queue";
+static char help_disable[] = "turn off spooling to a queue";
+static char help_down[] =
+ "turn off queueing and printing for a queue and set a reason";
+static char help_enable[] = "turn on spooling to a queue";
+static char help_restart[] = "restart job processing for a queue";
+static char help_start[] = "turn on printing from a queue";
+static char help_stop[] = "turn off printing from a queue";
+static char help_up[] = "turn on queueing and printing for a queue";
+static char help_topq[] = "put a job at the top of the queue";
+
+static struct {
+ char *cmd;
+ int (*handler)(papi_service_t svc, char **args);
+ char *help_string;
+ int num_args;
+} cmd_tab[] = {
+ { "?", lpc_help, help_help, 0 },
+ { "help", lpc_help, help_help, 0 },
+ { "exit", lpc_exit, help_exit, 0 },
+ { "quit", lpc_exit, help_exit, 0 },
+ { "status", lpc_status, help_status, 1 },
+ { "abort", lpc_abort, help_abort, 1 },
+ { "clean", lpc_clean, help_clean, 1 },
+ { "disable", lpc_disable, help_disable, 1 },
+ { "down", lpc_down, help_down, 2 },
+ { "enable", lpc_enable, help_enable, 1 },
+ { "restart", lpc_restart, help_restart, 1 },
+ { "start", lpc_start, help_start, 1 },
+ { "stop", lpc_stop, help_stop, 1 },
+ { "up", lpc_up, help_up, 1 },
+ { "topq", lpc_topq, help_topq, 2 },
+ { NULL, NULL, NULL, 0 }
+};
+
+static int
+lpc_handler(char *cmd, cmd_handler_t **handler)
+{
+ int i;
+
+ for (i = 0; cmd_tab[i].cmd != NULL; i++)
+ if (strcmp(cmd, cmd_tab[i].cmd) == 0) {
+ *handler = cmd_tab[i].handler;
+ return (cmd_tab[i].num_args);
+ }
+ return (-1);
+}
+
+static char *
+lpc_helptext(char *cmd)
+{
+ int i;
+
+ for (i = 0; cmd_tab[i].cmd != NULL; i++)
+ if (strcmp(cmd, cmd_tab[i].cmd) == 0)
+ return (gettext(cmd_tab[i].help_string));
+ return (NULL);
+}
+
+/* ARGSUSED0 */
+static int
+lpc_help(papi_service_t svc, char **args)
+{
+ if (args[1] == NULL) {
+ int i;
+
+ printf(gettext("Commands are:\n\n"));
+ for (i = 0; cmd_tab[i].cmd != NULL; i++) {
+ printf("\t%s", cmd_tab[i].cmd);
+ if ((i % 7) == 6)
+ printf("\n");
+ }
+ if ((i % 7) != 6)
+ printf("\n");
+ } else {
+ char *helptext = lpc_helptext(args[1]);
+
+ if (helptext == NULL)
+ helptext = gettext("no such command");
+
+ printf("%s: %s\n", args[1], helptext);
+ }
+
+ return (0);
+}
+
+static int
+process_one(int (*handler)(papi_service_t, char **), char **av, int expected)
+{
+ int rc = -1;
+ papi_status_t status = PAPI_OK;
+ papi_service_t svc = NULL;
+ char *printer = av[1];
+
+ if ((printer != NULL) && (expected != 0)) {
+ status = papiServiceCreate(&svc, printer, NULL, NULL,
+ cli_auth_callback, encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"),
+ printer, verbose_papi_message(svc, status));
+ }
+ }
+
+ if (status == PAPI_OK)
+ rc = handler(svc, av);
+
+ if (svc != NULL)
+ papiServiceDestroy(svc);
+
+ return (rc);
+}
+
+static int
+process_all(int (*handler)(papi_service_t, char **), char **av, int expected)
+{
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ char **printers;
+ int rc = 0;
+
+ status = papiServiceCreate(&svc, NULL, NULL, NULL, NULL,
+ encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("Failed to contact service: %s\n"),
+ verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ if ((printers = interest_list(svc)) != NULL) {
+ int i;
+
+ for (i = 0; printers[i] != NULL; i++) {
+ av[1] = printers[i];
+ rc += process_one(handler, av, expected);
+ }
+ }
+
+ papiServiceDestroy(svc);
+
+ return (rc);
+}
+
+static int
+process(int ac, char **av)
+{
+ int (*handler)(papi_service_t, char **) = NULL;
+ int num_args = -1;
+
+ char *printer = av[1];
+ int rc = -1;
+
+ if ((num_args = lpc_handler(av[0], &handler)) < 0) {
+ printf(gettext("%s: invalid command\n"), av[0]);
+ return (-1);
+ }
+
+ if (((printer != NULL) && (strcmp(printer, "all") != 0)) ||
+ (num_args <= ac))
+ rc = process_one(handler, av, num_args);
+ else
+ rc = process_all(handler, av, num_args);
+
+ return (rc);
+}
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout,
+ gettext("Usage: %s [ command [ parameter...]]\n"),
+ name);
+ exit(1);
+}
+
+static void
+lpc_shell()
+{
+ for (;;) {
+ char line[256];
+ char **av = NULL;
+ int ac = 0;
+
+ /* prompt */
+ fprintf(stdout, "lpc> ");
+ fflush(stdout);
+
+ /* get command */
+ if (fgets(line, sizeof (line), stdin) == NULL)
+ exit(1);
+ if ((av = strsplit(line, " \t\n")) != NULL)
+ for (ac = 0; av[ac] != NULL; ac++);
+
+ (void) process(ac, av);
+ free(av);
+ }
+}
+
+int
+main(int ac, char *av[])
+{
+ int result = 0;
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av, "E")) != EOF)
+ switch (c) {
+ case 'E':
+ encryption = PAPI_ENCRYPT_ALWAYS;
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ if (optind == ac)
+ lpc_shell();
+ else
+ result = process(optind - 2, &av[optind]);
+
+ return (result);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/lpmove.c b/usr/src/cmd/print/bsd-sysv-commands/lpmove.c
new file mode 100644
index 0000000000..cca6c3fcb1
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/lpmove.c
@@ -0,0 +1,165 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lpmove.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout,
+ gettext("Usage: %s [request-id] (destination)\n"
+ " %s (source) (destination)\n"), name);
+ exit(1);
+}
+
+static int
+move_job(papi_service_t svc, char *src, int32_t id, char *dest)
+{
+ int result = 0;
+ papi_status_t status;
+ char *mesg = gettext("moved");
+
+ status = papiJobMove(svc, src, id, dest);
+ if (status != PAPI_OK) {
+ mesg = (char *)verbose_papi_message(svc, status);
+ result = -1;
+ }
+ fprintf(stderr, gettext("%s-%d to %s: %s\n"), src, id, dest, mesg);
+
+ return (result);
+}
+
+int
+main(int ac, char *av[])
+{
+ int exit_code = 0;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ char *destination = NULL;
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av, "E:")) != EOF)
+ switch (c) {
+ case 'E':
+ encryption = PAPI_ENCRYPT_REQUIRED;
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ if (optind >= ac - 1)
+ usage(av[0]);
+
+ destination = av[--ac];
+
+ for (c = optind; c < ac; c++) {
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_job_t *jobs = NULL;
+ char *printer = NULL;
+ int32_t id = -1;
+
+ (void) get_printer_id(av[c], &printer, &id);
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL,
+ cli_auth_callback, encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"),
+ printer, verbose_papi_message(svc, status));
+ exit(1);
+ }
+
+ if (id != -1) { /* it's a job */
+ if (move_job(svc, printer, id, destination) < 0)
+ exit_code = 1;
+ } else { /* it's a printer */
+ char message[128];
+ int count = 0;
+
+ snprintf(message, sizeof (message), "moved jobs to %s",
+ destination);
+ status = papiPrinterDisable(svc, printer, message);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("Disable %s: %s\n"),
+ printer,
+ verbose_papi_message(svc, status));
+ exit_code = 1;
+ } else
+ printf(gettext(
+ "destination %s is not accepting requests\n"),
+ printer);
+
+ status = papiPrinterListJobs(svc, printer, NULL,
+ 0, 0, &jobs);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("Jobs %s: %s\n"),
+ printer,
+ verbose_papi_message(svc, status));
+ exit_code = 1;
+ }
+
+ printf(gettext("move in progress ...\n"));
+ while ((jobs != NULL) && (*jobs != NULL)) {
+ id = papiJobGetId(*jobs++);
+ if (move_job(svc, printer, id, destination) < 0)
+ exit_code = 1;
+ else
+ count++;
+ }
+ printf(gettext(
+ "total of %d requests moved from %s to %s\n"),
+ count, printer, destination);
+
+ papiJobListFree(jobs);
+ }
+
+ papiServiceDestroy(svc);
+ }
+
+ return (exit_code);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/lpq.c b/usr/src/cmd/print/bsd-sysv-commands/lpq.c
new file mode 100644
index 0000000000..188a5669d6
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/lpq.c
@@ -0,0 +1,134 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lpq.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout, gettext("Usage: %s [-P printer] (user|id ...)\n"),
+ name);
+ exit(1);
+}
+
+static void
+clear_screen()
+{
+ static char buf[32];
+
+ /* quick and dirty for now, this should be fixed real soon */
+ if (buf[0] == '\0') {
+ FILE *fp = popen("/bin/tput clear", "r");
+ if (fp != NULL) {
+ fgets(buf, sizeof (buf), fp);
+ fclose(fp);
+ }
+ }
+ printf("%s", buf);
+}
+
+int
+main(int ac, char *av[])
+{
+ char *printer = NULL;
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ int format = 3; /* lpq short format */
+ int interval = 0;
+ int num_jobs;
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av, "EP:l")) != EOF)
+ switch (c) {
+ case 'E':
+ encryption = PAPI_ENCRYPT_REQUIRED;
+ break;
+ case 'P':
+ printer = optarg;
+ break;
+ case 'l':
+ format = 4; /* lpq long format */
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ if ((optind < ac) && (av[optind][0] == '+'))
+ interval = atoi(av[optind++]);
+
+ if ((printer == NULL) &&
+ ((printer = getenv("PRINTER")) == NULL) &&
+ ((printer = getenv("LPDEST")) == NULL))
+ printer = DEFAULT_DEST;
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback,
+ encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"), printer,
+ verbose_papi_message(svc, status));
+ papiServiceDestroy(svc);
+ exit(1);
+ }
+
+ do {
+ if (interval != 0)
+ clear_screen();
+
+ num_jobs = berkeley_queue_report(svc, stdout, printer, format,
+ ac - optind, &av[optind]);
+
+ if ((interval != 0) && (num_jobs > 0))
+ sleep(interval);
+ } while ((interval > 0) && (num_jobs > 0));
+
+ papiServiceDestroy(svc);
+
+ return (0);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/lpr.c b/usr/src/cmd/print/bsd-sysv-commands/lpr.c
new file mode 100644
index 0000000000..b273cfe6c0
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/lpr.c
@@ -0,0 +1,270 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lpr.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+#ifdef HAVE_LIBMAGIC /* for mimetype auto-detection */
+#include <magic.h>
+#endif /* HAVE_LIBMAGIC */
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout,
+ gettext("Usage: %s [-P printer] [-# copies] [-C class] "
+ "[-J job] [-T title] "
+ "[-p [-i indent] [-w width]] "
+ "[-1|-2|-3|-4 font] [-m] [-h] [-s] "
+ "[-filter_option] [file ..]\n"), name);
+ exit(1);
+}
+
+int
+main(int ac, char *av[])
+{
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_attribute_t **list = NULL;
+ papi_job_t job = NULL;
+ int exit_code = 0;
+ char *printer = NULL;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ int dump = 0;
+ int validate = 0;
+ int remove = 0;
+ int copy = 1; /* default is to copy the data */
+ char *document_format = "application/octet-stream";
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av,
+ "EP:#:C:DVJ:T:w:i:hplrstdgvcfmn1:2:3:4:")) != EOF)
+ switch (c) {
+ case 'E':
+ encryption = PAPI_ENCRYPT_REQUIRED;
+ break;
+ case 'P':
+ printer = optarg;
+ break;
+ case '#':
+ papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
+ "copies", atoi(optarg));
+ break;
+ case 'C':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "rfc-1179-class", optarg);
+ break;
+ case 'D':
+ dump = 1;
+ break;
+ case 'J':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "job-name", optarg);
+ break;
+ case 'T':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "pr-title", optarg);
+ break;
+ case 'p':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", "application/x-pr");
+ papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
+ "pr-filter", 1);
+ break;
+ case 'i':
+ papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
+ "pr-indent", atoi(optarg));
+ break;
+ case 'w':
+ papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL,
+ "pr-width", atoi(optarg));
+ break;
+ case 'h':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "job-sheets", "none");
+ break;
+ case 'l':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", "application/octet-stream");
+ break;
+ case 'o':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", "application/postscript");
+ break;
+ case 'c':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", "application/x-cif");
+ break;
+ case 'd':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", "application/x-dvi");
+ break;
+ case 'f':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", "application/x-fortran");
+ break;
+ case 'g':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", "application/x-plot");
+ break;
+ case 'n':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", "application/x-ditroff");
+ break;
+ case 't':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", "application/x-troff");
+ break;
+ case 'v':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", "application/x-raster");
+ break;
+ case 'm':
+ papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL,
+ "rfc-1179-mail", 1);
+ break;
+ case 'r':
+ remove = 1;
+ break;
+ case 's':
+ copy = 0;
+ break;
+ case 'V': /* validate */
+ validate = 1;
+ break;
+ case '1':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "rfc-1179-font-r", optarg);
+ break;
+ case '2':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "rfc-1179-font-i", optarg);
+ break;
+ case '3':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "rfc-1179-font-b", optarg);
+ break;
+ case '4':
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "rfc-1179-font-s", optarg);
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ if ((remove != 0) && (copy == 0)) {
+ fprintf(stderr, gettext(
+ "-r and -s may not be used together\n"));
+ exit(1);
+ }
+
+ if ((printer == NULL) &&
+ ((printer = getenv("PRINTER")) == NULL) &&
+ ((printer = getenv("LPDEST")) == NULL))
+ printer = DEFAULT_DEST;
+
+#ifdef MAGIC_MIME
+ if (optind != ac) {
+ /* get the mime type of the file data */
+ magic_t ms;
+
+ if ((ms = magic_open(MAGIC_MIME)) != NULL) {
+ document_format = magic_file(ms, av[optind]);
+ magic_close(ms);
+ }
+ }
+#endif
+
+ papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, "copies", 1);
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "document-format", document_format);
+ papiAttributeListAddString(&list, PAPI_ATTR_EXCL,
+ "job-sheets", "standard");
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback,
+ encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"), printer,
+ verbose_papi_message(svc, status));
+ exit(1);
+ }
+
+ if (validate == 1) /* validate the request can be processed */
+ status = papiJobValidate(svc, printer, list,
+ NULL, &av[optind], &job);
+ else if (optind == ac) /* no file list, use stdin */
+ status = jobSubmitSTDIN(svc, printer, list, &job);
+ else if (copy == 0) /* reference the files in the job, default */
+ status = papiJobSubmitByReference(svc, printer, list,
+ NULL, &av[optind], &job);
+ else /* copy the files before return, -c */
+ status = papiJobSubmit(svc, printer, list,
+ NULL, &av[optind], &job);
+
+ papiAttributeListFree(list);
+
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("%s: %s\n"), printer,
+ verbose_papi_message(svc, status));
+ papiJobFree(job);
+ papiServiceDestroy(svc);
+ exit(1);
+ }
+
+ if (dump != 0) {
+ list = papiJobGetAttributeList(job);
+ printf("job attributes:\n");
+ papiAttributeListPrint(stdout, list, "\t");
+ printf("\n");
+ }
+
+ papiJobFree(job);
+ papiServiceDestroy(svc);
+
+ return (exit_code);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/lprm.c b/usr/src/cmd/print/bsd-sysv-commands/lprm.c
new file mode 100644
index 0000000000..841a5da811
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/lprm.c
@@ -0,0 +1,101 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lprm.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout, gettext("Usage: %s [-P printer] (user|id ...)\n"),
+ name);
+ exit(1);
+}
+
+int
+main(int ac, char *av[])
+{
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ char *printer = NULL;
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av, "EP:")) != EOF)
+ switch (c) {
+ case 'E':
+ encryption = PAPI_ENCRYPT_REQUIRED;
+ break;
+ case 'P':
+ printer = optarg;
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ if ((printer == NULL) &&
+ ((printer = getenv("PRINTER")) == NULL) &&
+ ((printer = getenv("LPDEST")) == NULL))
+ printer = DEFAULT_DEST;
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback,
+ encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"),
+ printer, verbose_papi_message(svc, status));
+ papiServiceDestroy(svc);
+ return (1);
+ }
+
+ berkeley_cancel_request(svc, stdout, printer,
+ ac - optind, &av[optind]);
+
+ papiServiceDestroy(svc);
+
+ return (0);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/lpstat.c b/usr/src/cmd/print/bsd-sysv-commands/lpstat.c
new file mode 100644
index 0000000000..466025da9a
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/lpstat.c
@@ -0,0 +1,1015 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lpstat.c 173 2006-05-25 04:52:06Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <pwd.h>
+#include <papi.h>
+#include <uri.h>
+#include "common.h"
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout, gettext("Usage: %s [-d] [-r] [-s] [-t] [-a [list]] "
+ "[-c [list]] [-o [list] [-l]] [-R [list] [-l]] "
+ "[-p [list] [-D] [-l]] [-v [list]] [-S [list] [-l]] "
+ "[-f [list] [-l]] [-u list]\n"),
+ name);
+ exit(1);
+}
+
+static char *
+nctime(time_t *t)
+{
+ static char buf[64];
+ struct tm *tm = localtime(t);
+
+ (void) strftime(buf, sizeof (buf), "%c", tm);
+
+ return (buf);
+}
+
+static char *
+printer_name(papi_printer_t printer)
+{
+ papi_attribute_t **attributes = papiPrinterGetAttributeList(printer);
+ char *result = NULL;
+
+ if (attributes != NULL)
+ papiAttributeListGetString(attributes, NULL,
+ "printer-name", &result);
+
+ return (result);
+}
+
+static int
+lpstat_default_printer(papi_encryption_t encryption)
+{
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_printer_t p = NULL;
+ char *name = NULL;
+
+ status = papiServiceCreate(&svc, NULL, NULL, NULL, cli_auth_callback,
+ encryption, NULL);
+ if (status == PAPI_OK) {
+ char *req[] = { "printer-name", NULL };
+
+ status = papiPrinterQuery(svc, DEFAULT_DEST, req, NULL, &p);
+ if (p != NULL)
+ name = printer_name(p);
+ }
+ if (name != NULL)
+ printf(gettext("system default printer: %s\n"), name);
+ else
+ printf(gettext("no system default destination\n"));
+ papiPrinterFree(p);
+ papiServiceDestroy(svc);
+
+ return (0);
+}
+
+static int
+lpstat_service_status(papi_encryption_t encryption)
+{
+ int result = 0;
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ char *name = NULL;
+
+ if (((name = getenv("PAPI_SERVICE_URI")) == NULL) &&
+ ((name = getenv("IPP_SERVER")) == NULL) &&
+ ((name = getenv("CUPS_SERVER")) == NULL))
+ name = DEFAULT_SERVICE_URI;
+
+ status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback,
+ encryption, NULL);
+ if (status != PAPI_OK) {
+ printf(gettext("scheduler is not running\n"));
+ result = -1;
+ } else
+ printf(gettext("scheduler is running\n"));
+ papiServiceDestroy(svc);
+
+ return (result);
+}
+
+static char *
+get_device_uri(papi_service_t svc, char *name)
+{
+ papi_status_t status;
+ papi_printer_t p = NULL;
+ char *keys[] = { "device-uri", NULL };
+ char *result = NULL;
+
+ status = papiPrinterQuery(svc, name, keys, NULL, &p);
+ if ((status == PAPI_OK) && (p != NULL)) {
+ papi_attribute_t **attrs = papiPrinterGetAttributeList(p);
+
+ (void) papiAttributeListGetString(attrs, NULL,
+ "device-uri", &result);
+ if (result != NULL)
+ result = strdup(result);
+
+ papiPrinterFree(p);
+ }
+
+ return (result);
+}
+
+static char *report_device_keys[] = { "printer-name", "printer-uri-supported",
+ NULL };
+/* ARGSUSED2 */
+static int
+report_device(papi_service_t svc, char *name, papi_printer_t printer,
+ int verbose, int description)
+{
+ papi_status_t status;
+ papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
+ char *uri = NULL;
+ char *device = NULL;
+ uri_t *u = NULL;
+
+ if (name == NULL) {
+ status = papiAttributeListGetString(attrs, NULL,
+ "printer-name", &name);
+ if (status != PAPI_OK)
+ status = papiAttributeListGetString(attrs, NULL,
+ "printer-uri-supported", &name);
+ }
+
+ if (name == NULL)
+ return (-1);
+
+ (void) papiAttributeListGetString(attrs, NULL,
+ "printer-uri-supported", &uri);
+
+ if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) {
+ char *nodename = localhostname();
+
+ if ((u->host == NULL) ||
+ (strcasecmp(u->host, "localhost") == 0) ||
+ (strcasecmp(u->host, nodename) == 0))
+ device = get_device_uri(svc, name);
+
+ if (device != NULL) {
+ printf(gettext("device for %s: %s\n"), name, device);
+ return (0);
+ } else if (uri != NULL) {
+ printf(gettext("system for %s: %s (as %s)\n"), name,
+ u->host, uri);
+ return (0);
+ }
+
+ uri_free(u);
+ }
+
+ return (0);
+}
+
+static char *report_accepting_keys[] = { "printer-name",
+ "printer-uri-supported", "printer-is-accepting-jobs",
+ "printer-up-time", "printer-state-time",
+ "lpsched-reject-date", "lpsched-reject-reason", NULL };
+/* ARGSUSED2 */
+static int
+report_accepting(papi_service_t svc, char *name, papi_printer_t printer,
+ int verbose, int description)
+{
+ papi_status_t status;
+ papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
+ time_t curr;
+ char boolean = PAPI_FALSE;
+
+ if (name == NULL) {
+ status = papiAttributeListGetString(attrs, NULL,
+ "printer-name", &name);
+ if (status != PAPI_OK)
+ status = papiAttributeListGetString(attrs, NULL,
+ "printer-uri-supported", &name);
+ }
+ if (name == NULL)
+ return (-1);
+
+ (void) papiAttributeListGetBoolean(attrs, NULL,
+ "printer-is-accepting-jobs", &boolean);
+ (void) time(&curr);
+ (void) papiAttributeListGetDatetime(attrs, NULL,
+ "printer-up-time", &curr);
+ (void) papiAttributeListGetDatetime(attrs, NULL,
+ "printer-state-time", &curr);
+ (void) papiAttributeListGetDatetime(attrs, NULL,
+ "lpsched-reject-date", &curr);
+
+ if (boolean == PAPI_TRUE) {
+ printf(gettext("%s accepting requests since %s\n"),
+ name, nctime(&curr));
+ } else {
+ char *reason = "unknown reason";
+
+ (void) papiAttributeListGetString(attrs, NULL,
+ "lpsched-reject-reason", &reason);
+
+ printf(gettext("%s not accepting requests since %s\n\t%s\n"),
+ name, nctime(&curr), reason);
+ }
+
+ return (0);
+}
+
+static char *report_class_keys[] = { "printer-name", "printer-uri-supported",
+ "member-names", NULL };
+/* ARGSUSED2 */
+static int
+report_class(papi_service_t svc, char *name, papi_printer_t printer,
+ int verbose, int description)
+{
+ papi_status_t status;
+ papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
+ char *member = NULL;
+ void *iter = NULL;
+
+ status = papiAttributeListGetString(attrs, &iter,
+ "member-names", &member);
+ if (status == PAPI_NOT_FOUND) /* it's not a class */
+ return (0);
+
+ if (name == NULL) {
+ status = papiAttributeListGetString(attrs, NULL,
+ "printer-name", &name);
+ if (status != PAPI_OK)
+ status = papiAttributeListGetString(attrs, NULL,
+ "printer-uri-supported", &name);
+ }
+ if (name == NULL)
+ return (-1);
+
+ printf(gettext("members of class %s:\n\t%s\n"), name, member);
+ while (papiAttributeListGetString(attrs, &iter, NULL, &member)
+ == PAPI_OK)
+ printf("\t%s\n", member);
+
+ return (0);
+}
+
+static char *report_printer_keys[] = { "printer-name",
+ "printer-uri-supported", "printer-state",
+ "printer-up-time", "printer-state-time",
+ "lpsched-disable-date", "printer-state-reasons",
+ "lpsched-disable-reason", NULL };
+/* ARGSUSED2 */
+static int
+report_printer(papi_service_t svc, char *name, papi_printer_t printer,
+ int verbose, int description)
+{
+ papi_status_t status;
+ papi_attribute_t **attrs = papiPrinterGetAttributeList(printer);
+ time_t curr;
+ int32_t pstat = 0;
+ char *member = NULL;
+
+ status = papiAttributeListGetString(attrs, NULL,
+ "member-names", &member);
+ if (status == PAPI_OK) /* it's a class */
+ return (0);
+
+ if (name == NULL) {
+ status = papiAttributeListGetString(attrs, NULL,
+ "printer-name", &name);
+ if (status != PAPI_OK)
+ status = papiAttributeListGetString(attrs, NULL,
+ "printer-uri-supported", &name);
+ }
+ if (name == NULL)
+ return (-1);
+
+ printf(gettext("printer %s "), name);
+
+ status = papiAttributeListGetInteger(attrs, NULL,
+ "printer-state", &pstat);
+
+ switch (pstat) {
+ case 0x03: /* idle */
+ printf(gettext("idle. enabled"));
+ break;
+ case 0x04: { /* processing */
+ char *requested[] = { "job-id", NULL };
+ papi_job_t *j = NULL;
+ int32_t jobid = 0;
+
+ (void) papiPrinterListJobs(svc, name, requested, 0, 1, &j);
+ if ((j != NULL) && (j[0] != NULL))
+ jobid = papiJobGetId(j[0]);
+ papiJobListFree(j);
+
+ printf(gettext("now printing %s-%d. enabled"), name, jobid);
+ }
+ break;
+ case 0x05: /* stopped */
+ printf(gettext("disabled"));
+ break;
+ default:
+ printf(gettext("unknown state(0x%x)."), pstat);
+ break;
+ }
+
+ (void) time(&curr);
+ (void) papiAttributeListGetDatetime(attrs, NULL,
+ "printer-up-time", &curr);
+ (void) papiAttributeListGetDatetime(attrs, NULL,
+ "printer-state-time", &curr);
+ (void) papiAttributeListGetDatetime(attrs, NULL,
+ "lpsched-disable-date", &curr);
+ printf(gettext(" since %s. available.\n"), nctime(&curr));
+
+ if (pstat == 0x05) {
+ char *reason = "unknown reason";
+
+ (void) papiAttributeListGetString(attrs, NULL,
+ "printer-state-reasons", &reason);
+ (void) papiAttributeListGetString(attrs, NULL,
+ "lpsched-disable-reason", &reason);
+ printf(gettext("\t%s\n"), reason);
+ }
+
+ if (verbose == 1) {
+ void *iter;
+ char *str;
+
+ str = "";
+ (void) papiAttributeListGetString(attrs, NULL,
+ "form-ready", &str);
+ printf(gettext("\tForm mounted: %s\n"), str);
+
+ str = "";
+ iter = NULL;
+ (void) papiAttributeListGetString(attrs, &iter,
+ "document-format-supported", &str);
+ printf(gettext("\tContent types: %s"), str);
+ while (papiAttributeListGetString(attrs, &iter, NULL, &str)
+ == PAPI_OK)
+ printf(", %s", str);
+ printf("\n");
+
+ str = "";
+ (void) papiAttributeListGetString(attrs, NULL,
+ "printer-info", &str);
+ printf(gettext("\tDescription: %s\n"), str);
+
+ str = "";
+ (void) papiAttributeListGetString(attrs, NULL,
+ "lpsched-dial-info", &str);
+ printf(gettext("\tConnection: %s\n"),
+ ((str[0] != '\0') ? gettext("direct") : str));
+
+ str = "";
+ (void) papiAttributeListGetString(attrs, NULL,
+ "lpsched-interface-script", &str);
+ printf(gettext("\tInterface: %s\n"), str);
+
+ str = NULL;
+ (void) papiAttributeListGetString(attrs, NULL,
+ "ppd-file-uri", &str);
+ (void) papiAttributeListGetString(attrs, NULL,
+ "lpsched-ppd-source-path", &str);
+ if (str != NULL)
+ printf(gettext("\tPPD: %s\n"), str);
+
+ str = NULL;
+ (void) papiAttributeListGetString(attrs, NULL,
+ "lpsched-fault-alert-command", &str);
+ if (str != NULL)
+ printf(gettext("\tOn fault: %s\n"), str);
+
+ str = "";
+ (void) papiAttributeListGetString(attrs, NULL,
+ "lpsched-fault-recovery", &str);
+ printf(gettext("\tAfter fault: %s\n"),
+ ((str[0] == '\0') ? gettext("continue") : str));
+
+ str = "(all)";
+ iter = NULL;
+ (void) papiAttributeListGetString(attrs, &iter,
+ "requesting-user-name-allowed", &str);
+ printf(gettext("\tUsers allowed:\n\t\t%s\n"),
+ ((str[0] == '\0') ? gettext("(none)") : str));
+ if ((str != NULL) && (str[0] != '\0'))
+ while (papiAttributeListGetString(attrs, &iter, NULL,
+ &str) == PAPI_OK)
+ printf("\t\t%s\n", str);
+
+ str = NULL;
+ iter = NULL;
+ (void) papiAttributeListGetString(attrs, &iter,
+ "requesting-user-name-denied", &str);
+ if (str != NULL) {
+ printf(gettext("\tUsers denied:\n\t\t%s\n"),
+ ((str[0] == '\0') ? gettext("(none)") : str));
+ if ((str != NULL) && (str[0] != '\0'))
+ while (papiAttributeListGetString(attrs, &iter,
+ NULL, &str) == PAPI_OK)
+ printf("\t\t%s\n", str);
+ }
+
+ str = "(none)";
+ iter = NULL;
+ (void) papiAttributeListGetString(attrs, &iter,
+ "form-supported", &str);
+ printf(gettext("\tForms allowed:\n\t\t%s\n"),
+ ((str[0] == '\0') ? gettext("(none)") : str));
+ if ((str != NULL) && (str[0] != '\0'))
+ while (papiAttributeListGetString(attrs, &iter, NULL,
+ &str) == PAPI_OK)
+ printf("\t\t%s\n", str);
+
+ str = "";
+ iter = NULL;
+ (void) papiAttributeListGetString(attrs, &iter,
+ "media-supported", &str);
+ printf(gettext("\tMedia supported:\n\t\t%s\n"),
+ ((str[0] == '\0') ? gettext("(none)") : str));
+ if ((str != NULL) && (str[0] != '\0'))
+ while (papiAttributeListGetString(attrs, &iter, NULL,
+ &str) == PAPI_OK)
+ printf("\t\t%s\n", str);
+
+ str = "";
+ (void) papiAttributeListGetString(attrs, NULL,
+ "job-sheets-supported", &str);
+ printf(gettext("\tBanner %s\n"),
+ (strcasecmp(str, "none") == 0 ?
+ gettext("not required") : gettext("required")));
+
+ str = "";
+ iter = NULL;
+ (void) papiAttributeListGetString(attrs, &iter,
+ "lpsched-print-wheels", &str);
+ printf(gettext("\tCharacter sets:\n\t\t%s\n"),
+ ((str[0] == '\0') ? gettext("(none)") : str));
+ if ((str != NULL) && (str[0] != '\0'))
+ while (papiAttributeListGetString(attrs, &iter, NULL,
+ &str) == PAPI_OK)
+ printf("\t\t%s\n", str);
+
+ printf(gettext("\tDefault pitch:\n"));
+ printf(gettext("\tDefault page size:\n"));
+ printf(gettext("\tDefault port setting:\n"));
+
+ str = "";
+ iter = NULL;
+ (void) papiAttributeListGetString(attrs, &iter,
+ "lpsched-options", &str);
+ if (str != NULL) {
+ printf(gettext("\tOptions: %s"), str);
+ while (papiAttributeListGetString(attrs, &iter, NULL,
+ &str) == PAPI_OK)
+ printf(", %s", str);
+ printf("\n");
+ }
+
+ } else if (description == 1) {
+ char *str = "";
+ (void) papiAttributeListGetString(attrs, NULL,
+ "printer-description", &str);
+ printf(gettext("\tDescription: %s\n"), str);
+ } else if (verbose > 1)
+ papiAttributeListPrint(stdout, attrs, "\t");
+
+ if (verbose > 0)
+ printf("\n");
+
+ return (0);
+}
+
+static int
+printer_query(char *name, int (*report)(papi_service_t, char *, papi_printer_t,
+ int, int), papi_encryption_t encryption,
+ int verbose, int description)
+{
+ int result = 0;
+ papi_status_t status;
+ papi_service_t svc = NULL;
+
+ status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback,
+ encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"),
+ name ? name : "(NULL)",
+ verbose_papi_message(svc, status));
+ papiServiceDestroy(svc);
+ return (-1);
+ }
+
+ if (name == NULL) { /* all */
+ char **interest = interest_list(svc);
+
+ if (interest != NULL) {
+ int i;
+
+ for (i = 0; interest[i] != NULL; i++)
+ result += printer_query(interest[i], report,
+ encryption, verbose,
+ description);
+ }
+ } else {
+ papi_printer_t printer = NULL;
+ char **keys = NULL;
+
+ /*
+ * Limit the query to only required data to reduce the need
+ * to go remote for information.
+ */
+ if (report == report_device)
+ keys = report_device_keys;
+ else if (report == report_class)
+ keys = report_class_keys;
+ else if (report == report_accepting)
+ keys = report_accepting_keys;
+ else if ((report == report_printer) && (verbose == 0))
+ keys = report_printer_keys;
+
+ status = papiPrinterQuery(svc, name, keys, NULL, &printer);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to get printer info for %s: %s\n"),
+ name, verbose_papi_message(svc, status));
+ papiServiceDestroy(svc);
+ return (-1);
+ }
+
+ if (printer != NULL)
+ result = report(svc, name, printer, verbose,
+ description);
+
+ papiPrinterFree(printer);
+ }
+
+ papiServiceDestroy(svc);
+
+ return (result);
+}
+
+static int
+match_user(char *user, char **list)
+{
+ int i;
+
+ for (i = 0; list[i] != NULL; i++) {
+ if (strcmp(user, list[i]) == 0)
+ return (0);
+ }
+
+ return (-1);
+}
+
+static char **users = NULL;
+
+static int
+report_job(papi_job_t job, int show_rank, int verbose)
+{
+ papi_attribute_t **attrs = papiJobGetAttributeList(job);
+ time_t clock = 0;
+ char date[24];
+ char request[26];
+ char *user = "unknown";
+ int32_t size = 0;
+ int32_t jstate = 0;
+
+ char *destination = "unknown";
+ int32_t id = -1;
+
+ (void) papiAttributeListGetString(attrs, NULL,
+ "job-originating-user-name", &user);
+
+ if ((users != NULL) && (match_user(user, users) < 0))
+ return (0);
+
+ (void) papiAttributeListGetInteger(attrs, NULL, "job-k-octets", &size);
+ size *= 1024; /* for the approximate byte size */
+ (void) papiAttributeListGetInteger(attrs, NULL, "job-octets", &size);
+
+ (void) time(&clock);
+ (void) papiAttributeListGetInteger(attrs, NULL,
+ "time-at-creation", (int32_t *)&clock);
+ (void) strftime(date, sizeof (date), "%b %d %R", localtime(&clock));
+
+ (void) papiAttributeListGetString(attrs, NULL,
+ "job-printer-uri", &destination);
+ (void) papiAttributeListGetString(attrs, NULL,
+ "printer-name", &destination);
+ (void) papiAttributeListGetInteger(attrs, NULL,
+ "job-id", &id);
+ snprintf(request, sizeof (request), "%s-%d", destination, id);
+
+ if (show_rank != 0) {
+ int32_t rank = -1;
+
+ (void) papiAttributeListGetInteger(attrs, NULL,
+ "number-of-intervening-jobs", &rank);
+ rank++;
+
+ printf("%3d %-21s %-14s %7ld %s",
+ rank, request, user, size, date);
+ } else
+ printf("%-23s %-14s %7ld %s", request, user, size, date);
+
+ (void) papiAttributeListGetInteger(attrs, NULL,
+ "job-state", &jstate);
+ if (jstate == 0x04)
+ printf(gettext(", being held"));
+ else if (jstate == 0x07)
+ printf(gettext(", cancelled"));
+ else if (jstate == 0x09)
+ printf(gettext(", complete"));
+
+ if (verbose == 1) {
+ (void) papiAttributeListGetString(attrs, NULL,
+ "output-device-assigned", &destination);
+ printf("\n\t assigned %s", destination);
+ } else if (verbose > 1) {
+ printf("\n");
+ papiAttributeListPrint(stdout, attrs, "\t");
+ }
+
+ printf("\n");
+
+ return (0);
+}
+
+static int
+job_query(char *request, int (*report)(papi_job_t, int, int),
+ papi_encryption_t encryption, int show_rank, int verbose)
+{
+ int result = 0;
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ char *printer = NULL;
+ int32_t id = -1;
+
+ get_printer_id(request, &printer, &id);
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback,
+ encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"),
+ (printer ? printer : "all"),
+ verbose_papi_message(svc, status));
+ return (-1);
+ }
+
+ if (printer == NULL) { /* all */
+ char **interest = interest_list(svc);
+
+ if (interest != NULL) {
+ int i;
+
+ for (i = 0; interest[i] != NULL; i++)
+ result += job_query(interest[i], report,
+ encryption, show_rank, verbose);
+ }
+ } else if (id == -1) { /* a printer */
+ papi_job_t *jobs = NULL;
+
+ status = papiPrinterListJobs(svc, printer, NULL, 0, 0, &jobs);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to get job list: %s\n"),
+ verbose_papi_message(svc, status));
+ papiServiceDestroy(svc);
+ return (-1);
+ }
+
+ if (jobs != NULL) {
+ int i;
+
+ for (i = 0; jobs[i] != NULL; i++)
+ result += report(jobs[i], show_rank, verbose);
+ }
+
+ papiJobListFree(jobs);
+ } else { /* a job */
+ papi_job_t job = NULL;
+
+ status = papiJobQuery(svc, printer, id, NULL, &job);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to get job info for %s: %s\n"),
+ request, verbose_papi_message(svc, status));
+ papiServiceDestroy(svc);
+ return (-1);
+ }
+
+ if (job != NULL)
+ result = report(job, show_rank, verbose);
+
+ papiJobFree(job);
+ }
+
+ papiServiceDestroy(svc);
+
+ return (result);
+}
+
+static int
+report_form(char *name, papi_attribute_t **attrs, int verbose)
+{
+ papi_status_t status;
+ char *form = NULL;
+ void *iter = NULL;
+
+ for (status = papiAttributeListGetString(attrs, &iter,
+ "form-supported", &form);
+ status == PAPI_OK;
+ status = papiAttributeListGetString(attrs, &iter,
+ NULL, &form)) {
+ if ((name == NULL) || (strcmp(name, form) == 0)) {
+ printf(gettext("form %s is available to you\n"), form);
+ if (verbose != 0) {
+ char *detail = NULL;
+ status = papiAttributeListGetString(attrs, NULL,
+ "form-supported-detail",
+ &detail);
+ if (status == PAPI_OK)
+ printf("%s\n", detail);
+ }
+ }
+ }
+
+ return (0);
+}
+
+static int
+report_print_wheels(char *name, papi_attribute_t **attrs, int verbose)
+{
+ papi_status_t status;
+ char *pw = NULL;
+ void *iter = NULL;
+
+ for (status = papiAttributeListGetString(attrs, &iter,
+ "pw-supported", &pw);
+ status == PAPI_OK;
+ status = papiAttributeListGetString(attrs, &iter, NULL, &pw)) {
+ if ((name == NULL) || (strcmp(name, pw) == 0)) {
+ printf(gettext("charset %s is available\n"), pw);
+ if (verbose != 0) {
+ char *info = NULL;
+ status = papiAttributeListGetString(attrs, NULL,
+ "pw-supported-extra", &info);
+ if (status == PAPI_OK)
+ printf("%s\n", info);
+ }
+ }
+ }
+
+ return (0);
+}
+
+static int
+service_query(char *name, int (*report)(char *, papi_attribute_t **, int),
+ papi_encryption_t encryption, int verbose)
+{
+ int result = 0;
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_attribute_t **attrs = NULL;
+
+ status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback,
+ encryption, NULL);
+ if (status != PAPI_OK) {
+ papiServiceDestroy(svc);
+ return (-1);
+ }
+
+ attrs = papiServiceGetAttributeList(svc);
+ if (attrs != NULL) {
+ result = report(name, attrs, verbose);
+
+ if (verbose > 1) {
+ printf("\n");
+ papiAttributeListPrint(stdout, attrs, "\t");
+ printf("\n");
+ }
+ }
+
+ papiServiceDestroy(svc);
+
+ return (result);
+}
+
+int
+main(int ac, char *av[])
+{
+ int exit_code = 0;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ int rank = 0;
+ int verbose = 0;
+ int description = 0;
+ int c;
+ char **argv;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ argv = (char **)calloc((ac + 1), sizeof (char *));
+ for (c = 0; c < ac; c++)
+ argv[c] = av[c];
+ argv[c++] = "--";
+ ac = c;
+
+ /* preprocess argument list looking for '-l' or '-R' so it can trail */
+ while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF)
+ switch (c) {
+ case 'l':
+ if ((optarg == NULL) || (optarg[0] == '-'))
+ optarg = "1";
+ verbose = atoi(optarg);
+ break;
+ case 'D':
+ description = 1;
+ break;
+ case 'R':
+ rank = 1;
+ break;
+ case 'E':
+ encryption = PAPI_ENCRYPT_REQUIRED;
+ break;
+ default:
+ break;
+ }
+ optind = 1;
+
+ /* process command line arguments */
+ while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) {
+ switch (c) { /* these may or may not have an option */
+ case 'a':
+ case 'c':
+ case 'p':
+ case 'o':
+ case 'R':
+ case 'u':
+ case 'v':
+ case 'l':
+ case 'f':
+ case 'S':
+ if (optarg[0] == '-') {
+ /* this check stop a possible infinite loop */
+ if ((optind > 1) && (argv[optind-1][1] != c))
+ optind--;
+ optarg = NULL;
+ } else if (strcmp(optarg, "all") == 0)
+ optarg = NULL;
+ }
+
+ switch (c) {
+ case 'a':
+ exit_code += printer_query(optarg, report_accepting,
+ encryption, verbose, 0);
+ break;
+ case 'c':
+ exit_code += printer_query(optarg, report_class,
+ encryption, verbose, 0);
+ break;
+ case 'p':
+ exit_code += printer_query(optarg, report_printer,
+ encryption, verbose,
+ description);
+ break;
+ case 'd':
+ exit_code += lpstat_default_printer(encryption);
+ break;
+ case 'r':
+ exit_code += lpstat_service_status(encryption);
+ break;
+ case 'u':
+ if (optarg != NULL)
+ users = strsplit(optarg, ", \n");
+ exit_code += job_query(NULL, report_job,
+ encryption, rank, verbose);
+ if (users != NULL) {
+ free(users);
+ users = NULL;
+ }
+ break;
+ case 'v':
+ exit_code += printer_query(optarg, report_device,
+ encryption, verbose, 0);
+ break;
+ case 'o':
+ exit_code += job_query(optarg, report_job,
+ encryption, rank, verbose);
+ break;
+ case 'f':
+ exit_code += service_query(optarg, report_form,
+ encryption, verbose);
+ break;
+ case 'S':
+ exit_code += service_query(optarg, report_print_wheels,
+ encryption, verbose);
+ break;
+ case 's':
+ exit_code += lpstat_service_status(encryption);
+ exit_code += lpstat_default_printer(encryption);
+ exit_code += printer_query(NULL, report_class,
+ encryption, verbose, 0);
+ exit_code += printer_query(NULL, report_device,
+ encryption, verbose, 0);
+ exit_code += service_query(optarg, report_form,
+ encryption, verbose);
+ exit_code += service_query(optarg, report_print_wheels,
+ encryption, verbose);
+ break;
+ case 't':
+ exit_code += lpstat_service_status(encryption);
+ exit_code += lpstat_default_printer(encryption);
+ exit_code += printer_query(NULL, report_class,
+ encryption, verbose, 0);
+ exit_code += printer_query(NULL, report_device,
+ encryption, verbose, 0);
+ exit_code += printer_query(NULL, report_accepting,
+ encryption, verbose, 0);
+ exit_code += printer_query(NULL, report_printer,
+ encryption, verbose, 0);
+ exit_code += service_query(optarg, report_form,
+ encryption, verbose);
+ exit_code += service_query(optarg, report_print_wheels,
+ encryption, verbose);
+ exit_code += job_query(NULL, report_job,
+ encryption, rank, verbose);
+ break;
+ case 'L': /* local-only, ignored */
+ case 'l': /* increased verbose level in first pass */
+ case 'D': /* set "description" flag in first pass */
+ case 'R': /* set "rank" flag in first pass */
+ case 'E': /* set encryption in the first pass */
+ break;
+ default:
+ usage(av[0]);
+ }
+ }
+ ac--;
+
+ if (ac == 1) { /* report on my jobs */
+ struct passwd *pw = getpwuid(getuid());
+
+ if (pw != NULL)
+ users = strsplit(pw->pw_name, "");
+ exit_code += job_query(NULL, report_job, encryption,
+ rank, verbose);
+ if (users != NULL) {
+ free(users);
+ users = NULL;
+ }
+ } else {
+ for (c = optind; c < ac; c++)
+ exit_code += job_query(argv[c], report_job, encryption,
+ rank, verbose);
+ }
+
+
+ if (exit_code != 0)
+ exit_code = 1;
+
+ return (exit_code);
+}
diff --git a/usr/src/cmd/print/bsd-sysv-commands/reject.c b/usr/src/cmd/print/bsd-sysv-commands/reject.c
new file mode 100644
index 0000000000..58eb2829d0
--- /dev/null
+++ b/usr/src/cmd/print/bsd-sysv-commands/reject.c
@@ -0,0 +1,108 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: reject.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <papi.h>
+#include "common.h"
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stdout,
+ gettext("Usage: %s destination ...\n"),
+ name);
+ exit(1);
+}
+
+int
+main(int ac, char *av[])
+{
+ papi_status_t status;
+ papi_service_t svc = NULL;
+ papi_encryption_t encryption = PAPI_ENCRYPT_NEVER;
+ char *reason = NULL;
+ int exit_status = 0;
+ int c = 1;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain("SUNW_OST_OSCMD");
+
+ while ((c = getopt(ac, av, "Er:")) != EOF)
+ switch (c) {
+ case 'r': /* reason */
+ reason = optarg;
+ break;
+ case 'E':
+ encryption = PAPI_ENCRYPT_ALWAYS;
+ break;
+ default:
+ usage(av[0]);
+ }
+
+ if (ac <= optind)
+ usage(av[0]);
+
+ while (optind < ac) {
+ char *printer = av[optind++];
+
+ status = papiServiceCreate(&svc, printer, NULL, NULL,
+ cli_auth_callback, encryption, NULL);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext(
+ "Failed to contact service for %s: %s\n"),
+ printer, verbose_papi_message(svc, status));
+ exit_status = 1;
+ }
+
+ status = papiPrinterPause(svc, printer, reason);
+ if (status != PAPI_OK) {
+ fprintf(stderr, gettext("reject: %s: %s\n"), printer,
+ verbose_papi_message(svc, status));
+ exit_status = 1;
+ }
+
+ papiServiceDestroy(svc);
+ }
+
+ return (exit_status);
+}
diff --git a/usr/src/cmd/print/gateway/Makefile b/usr/src/cmd/print/gateway/Makefile
index 854e08ea98..59ecd07cae 100644
--- a/usr/src/cmd/print/gateway/Makefile
+++ b/usr/src/cmd/print/gateway/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# pragma ident "%Z%%M% %I% %E% SMI"
@@ -30,19 +29,29 @@
include ../Makefile.sp
-MANIFEST= rfc1179.xml
-
+MANIFEST= rfc1179.xml cleanup.xml
ROOTMANIFESTDIR= $(ROOTSVCAPPLICATIONPRINT)
$(ROOTMANIFEST) := FILEMODE= 444
-SUBDIRS= translators
+ROOTMETHOD= $(ROOTLIBSVCMETHOD)/print-cleanup
+$(ROOTLIBSVCMETHOD)/print-cleanup := FILEMODE=555
-PROG= in.lpd
+ROOTLIBPRINT= $(ROOTLIB)/print
+$(ROOTLIBPRINT) := OWNER=root
+$(ROOTLIBPRINT) := GROUP=lp
-SRCS= main.c adaptor.c
+PRINTDPROG= printd
+PRINTDSRCS= printd.c
+PRINTDOBJS= $(PRINTDSRCS:.c=.o)
+$(PRINTDPROG) := LDLIBS += $(LIBNPRT)
+$(ROOTLIBPRINT)/$(PRINTDPROG) := FILEMODE= 555
-OBJS= $(SRCS:.c=.o)
+INLPDPROG= in.lpd
+INLPDSRCS= main.c adaptor.c
+INLPDOBJS= $(INLPDSRCS:.c=.o)
+$(INLPDPROG) := LDLIBS += -lsocket -lnsl $(LIBNPRT)
+SUBDIRS= translators
FILEMODE= 0555
OWNER= root
@@ -50,31 +59,39 @@ GROUP= bin
CPPFLAGS += -I. -I$(NPRTINC) #$(CPPFLAGS.master)
-LDLIBS += -lsocket -lnsl $(LIBNPRT)
.KEEP_STATE:
-all: $(PROG) $(SUBDIRS)
+all: $(PRINTDPROG) $(INLPDPROG) $(SUBDIRS)
+
+$(PRINTDPROG): $(PRINTDOBJS)
+ $(LINK.c) $(PRINTDOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
-$(PROG): $(OBJS)
- $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
+$(INLPDPROG): $(INLPDOBJS)
+ $(LINK.c) $(INLPDOBJS) -o $@ $(LDLIBS)
$(POST_PROCESS)
-install: all $(ROOTLIBPRINTPROG) $(SUBDIRS) $(ROOTMANIFEST)
+ROOTLIBPRINTPROG= $(PRINTDPROG:%=$(ROOTLIBPRINT)/%) \
+ $(INLPDPROG:%=$(ROOTLIBPRINT)/%)
+
+install: all $(ROOTLIBPRINTPROG) $(SUBDIRS) $(ROOTMANIFEST) \
+ $(ROOTMETHOD) $(ROOTLIBPRINT)
check: $(CHKMANIFEST)
strip: $(SUBDIRS)
- $(STRIP) $(PROG)
+ $(STRIP) $(PRINTDPROG) $(INLPDPROG)
cstyle:
- cstyle $(SRCS)
+ cstyle $(PRINTDSRCS) $(INLPDSRCS)
lint:
- $(LINT.c) $(SRCS) $(LDLIBS)
+ $(LINT.c) $(PRINTDSRCS) $(LDLIBS)
+ $(LINT.c) $(INLPDSRCS) $(LDLIBS)
clean clobber: $(SUBDIRS)
- $(RM) $(OBJS)
+ $(RM) $(PRINTDOBJS) $(INLPDOBJS)
_msg:
@echo "Messages are made in usr/src/cmd/print"
@@ -83,3 +100,18 @@ $(SUBDIRS): FRC
@cd $@; pwd; $(MAKE) $(TARGET)
FRC:
+
+
+
+#
+# PRINTSYMLINK= $(ROOTLIB)/print/printd
+#
+# FILEMODE= 04511
+# OWNER= root
+#
+# CPPFLAGS += -I$(NPRTINC)
+# LDLIBS += $(LIBNPRT)
+#
+# install: all $(ROOTBIN) $(ROOTLIB)/print $(ROOTBINPROG) \
+# $(ROOTUSRBINSYMLINK) $(ROOTUSRUCBSYMLINK) $(PRINTSYMLINK) \
+# $(ROOTMANIFEST) $(ROOTMETHOD)
diff --git a/usr/src/cmd/print/gateway/adaptor.c b/usr/src/cmd/print/gateway/adaptor.c
index 8bb14c148b..e53e92bca7 100644
--- a/usr/src/cmd/print/gateway/adaptor.c
+++ b/usr/src/cmd/print/gateway/adaptor.c
@@ -37,7 +37,7 @@
#include <syslog.h>
#include <adaptor.h>
-#include <print/ns.h>
+#include <ns.h>
#ifndef RTLD_GLOBAL /* for OSF/1 */
#define RTLD_GLOBAL 0
diff --git a/usr/src/cmd/print/lp/cleanup.xml b/usr/src/cmd/print/gateway/cleanup.xml
index 50118847d2..50118847d2 100644
--- a/usr/src/cmd/print/lp/cleanup.xml
+++ b/usr/src/cmd/print/gateway/cleanup.xml
diff --git a/usr/src/cmd/print/lp/print-cleanup b/usr/src/cmd/print/gateway/print-cleanup
index 7780bcd68b..7780bcd68b 100644
--- a/usr/src/cmd/print/lp/print-cleanup
+++ b/usr/src/cmd/print/gateway/print-cleanup
diff --git a/usr/src/cmd/print/gateway/printd.c b/usr/src/cmd/print/gateway/printd.c
new file mode 100644
index 0000000000..d94ea5cbcb
--- /dev/null
+++ b/usr/src/cmd/print/gateway/printd.c
@@ -0,0 +1,336 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/systeminfo.h>
+#include <sys/param.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+#include <termios.h>
+#include <libintl.h>
+#include <locale.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include <ns.h>
+#include <network.h>
+#include <misc.h>
+#include <list.h>
+#include <job.h>
+
+static int connection_failed = 0;
+
+/*
+ * lpr/lp
+ * This program will submit print jobs to a spooler using the BSD
+ * printing protcol as defined in RFC1179, plus some extension for
+ * support of additional lp functionality.
+ */
+
+#define SEND_RETRY -1
+#define SEND_ABORT -2
+
+/*ARGSUSED*/
+static void sigpipe_handler(int i)
+{
+ syslog(LOG_ERR, "Warning: Received SIGPIPE; continuing");
+ (void) signal(SIGPIPE, sigpipe_handler);
+}
+
+static int
+sendfile(jobfile_t *file, int nd, int type)
+{
+ int rc = -1;
+
+ syslog(LOG_DEBUG, "sendfile(%s, %d, %d)",
+ ((file != NULL) ? file->jf_spl_path : "NULL"), nd, type);
+ if (file && file->jf_spl_path) {
+ rc = net_send_file(nd, file->jf_spl_path, file->jf_data,
+ file->jf_size, type);
+ }
+ return (rc);
+}
+
+
+/*
+ * send_job() sends a job to a remote print server.
+ */
+static int
+send_job(job_t *job)
+{
+ int lockfd,
+ lock_size,
+ nd,
+ tmp,
+ rc = 0;
+ struct passwd *p = NULL;
+ char buf[BUFSIZ];
+
+ syslog(LOG_DEBUG, "send_job(%s, %s, %d): called", job->job_printer,
+ job->job_server, job->job_id);
+ if ((lockfd = get_lock(job->job_cf->jf_src_path, 0)) < 0) {
+ (void) close(lockfd);
+ return (SEND_RETRY);
+ }
+
+ /* is job complete ? */
+
+ lock_size = file_size(job->job_cf->jf_src_path);
+ (void) sprintf(buf, "%ld\n", getpid()); /* add pid to lock file */
+ (void) lseek(lockfd, 0, SEEK_END);
+ (void) write(lockfd, buf, strlen(buf));
+
+ syslog(LOG_DEBUG, "send_job(%s, %s, %d): have lock", job->job_printer,
+ job->job_server, job->job_id);
+ connection_failed = 0;
+ if ((nd = net_open(job->job_server, 5)) < 0) {
+ connection_failed = 1;
+ if ((nd != NETWORK_ERROR_UNKNOWN) && (nd != NETWORK_ERROR_PORT))
+ job_destroy(job);
+ else
+ (void) ftruncate(lockfd, lock_size);
+ (void) close(lockfd);
+ return ((nd == NETWORK_ERROR_UNKNOWN) ||
+ (nd == NETWORK_ERROR_PORT) ? SEND_RETRY : SEND_ABORT);
+ }
+
+ if (net_send_message(nd, "%c%s\n", XFER_REQUEST, job->job_printer)
+ != 0) {
+ (void) net_close(nd);
+ syslog(LOG_WARNING,
+ "send_job failed job %d (%s@%s) check status\n",
+ job->job_id, job->job_printer, job->job_server);
+ (void) ftruncate(lockfd, lock_size);
+ (void) close(lockfd);
+ return (SEND_RETRY);
+ }
+
+ syslog(LOG_DEBUG, "send_job(%s, %s, %d): send data", job->job_printer,
+ job->job_server, job->job_id);
+
+ if ((p = getpwnam(job->job_user)) != NULL) {
+ /*
+ * attempt to become the job owner: uid, euid, gid, and
+ * supplementary groups while we try to send the job data.
+ * The real uid is changed with setreuid() separately from
+ * changing the effective uid so that we retain the saved
+ * uid to elevate privilege later. Combining these changes
+ * would result in a change to the saved uid also and a loss
+ * of the ability to elevate privilege later.
+ */
+ (void) setuid(0);
+ (void) initgroups(job->job_user, p->pw_gid);
+ (void) setgid(p->pw_gid);
+ (void) setreuid(p->pw_uid, -1);
+ (void) seteuid(p->pw_uid);
+ }
+
+ for (tmp = 0; job->job_df_list[tmp] != NULL; tmp++)
+ if ((rc = sendfile(job->job_df_list[tmp], nd, XFER_DATA)) < 0)
+ break; /* there was an error, quit now */
+ tmp = errno;
+ if (p != NULL) {
+ /*
+ * lose the supplemental groups and elevate our effective
+ * uid to root so that we can destroy jobs and/or become
+ * other job owners later on.
+ */
+ (void) seteuid(0);
+ (void) initgroups("root", 1);
+ }
+ errno = tmp;
+
+ if (rc < 0) {
+ if (errno == ENOENT) {
+ (void) net_close(nd);
+ job_destroy(job);
+ (void) close(lockfd);
+ return (SEND_ABORT);
+ } else if (errno == EACCES) {
+ /* probably trying to circumvent file security */
+ (void) net_close(nd);
+ job_destroy(job);
+ (void) close(lockfd);
+ return (SEND_ABORT);
+ } else {
+ (void) net_close(nd);
+ (void) ftruncate(lockfd, lock_size);
+ (void) close(lockfd);
+ return (SEND_RETRY);
+ }
+ }
+
+ if (sendfile(job->job_cf, nd, XFER_CONTROL) < 0) {
+ (void) net_send_message(nd, "%c\n", XFER_CLEANUP);
+ (void) net_close(nd);
+ (void) ftruncate(lockfd, lock_size);
+ (void) close(lockfd);
+ return (SEND_RETRY);
+ }
+
+ syslog(LOG_DEBUG, "send_job(%s, %s, %d): complete", job->job_printer,
+ job->job_server, job->job_id);
+ (void) net_close(nd);
+ job_destroy(job);
+ (void) close(lockfd);
+ return (0);
+}
+
+
+/*
+ * xfer_daemon() attempts to start up a daemon for transfering jobs to a remote
+ * print server. The daemon runs if it can get the master lock, and it
+ * runs until there are no jobs waiting for transfer.
+ */
+static void
+xfer_daemon()
+{
+ job_t **list = NULL;
+ int i,
+ rc;
+
+
+
+ closelog();
+ closefrom(0);
+
+ (void) open("/dev/null", O_RDONLY);
+ (void) open("/dev/null", O_WRONLY);
+ (void) dup(1);
+
+ (void) setuid(0);
+ (void) setsid();
+ openlog("printd", LOG_PID, LOG_LPR);
+ if (fork() != 0)
+ exit(0);
+
+ if ((i = get_lock(MASTER_LOCK, 1)) < 0)
+ exit(0);
+
+ (void) chdir(SPOOL_DIR);
+ while ((list = job_list_append(NULL, NULL, NULL, SPOOL_DIR)) != NULL) {
+ job_t **tmp;
+
+ syslog(LOG_DEBUG, "got the queue...");
+ for (tmp = list; *tmp != NULL; tmp++) {
+ /*
+ * Bugid: 4133175 printd dies when data is removed or
+ * permissions are changed. Memory is freed twice.
+ * Fix: Do not process anything else in the list
+ * if the return code is SEND_ABORT as the memory
+ * has already been freed by job_destroy().
+ */
+ rc = send_job(*tmp);
+ if ((rc != 0) && (rc != SEND_ABORT)) {
+ char *s = strdup((*tmp)->job_server);
+ char *p = strdup((*tmp)->job_printer);
+
+ if (rc != SEND_ABORT) /* already free */
+ job_free(*tmp);
+
+ for (tmp++; ((*tmp != NULL) &&
+ (strcmp(s, (*tmp)->job_server) == 0));
+ tmp++)
+ if ((connection_failed == 0) &&
+ (strcmp(p,
+ (*tmp)->job_printer) == 0))
+ job_free(*tmp);
+ else
+ break;
+ tmp--;
+ free(s);
+ free(p);
+ }
+ }
+ free(list);
+
+ /* look for more work to do before we sleep */
+ if ((list = job_list_append(NULL, NULL, NULL,
+ SPOOL_DIR)) != NULL) {
+ (void) list_iterate((void **)list, (VFUNC_T)job_free);
+ free(list);
+ (void) sleep(60);
+ }
+ }
+ syslog(LOG_DEBUG, "daemon exiting...");
+}
+
+int
+main(int ac, char *av[])
+{
+ ns_bsd_addr_t *binding = NULL;
+ int numFiles = 0,
+ queueStdin = 0,
+ exit_code = 0;
+ char *program,
+ *user,
+ hostname[128],
+ buf[BUFSIZ];
+ job_t *job;
+
+ (void) setlocale(LC_ALL, "");
+
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+
+ if ((program = strrchr(av[0], '/')) == NULL)
+ program = av[0];
+ else
+ program++;
+
+ openlog(program, LOG_PID, LOG_LPR);
+
+ /*
+ * Bugid: 4013980 Application changed fd 1 to a pipe that has
+ * no reader; we write to stdout and catch a sigpipe and exit.
+ * Fix: catch signal, complain to syslog, and continue.
+ */
+ (void) signal(SIGPIPE, sigpipe_handler);
+
+ if (check_client_spool(NULL) < 0) {
+ (void) fprintf(stderr,
+ gettext("couldn't validate local spool area (%s)\n"),
+ SPOOL_DIR);
+ return (-1);
+ }
+
+ xfer_daemon();
+
+ exit(0);
+}
diff --git a/usr/src/cmd/print/gateway/translators/cascade/cascade.c b/usr/src/cmd/print/gateway/translators/cascade/cascade.c
index 07372cdb99..8e50a9b0d7 100644
--- a/usr/src/cmd/print/gateway/translators/cascade/cascade.c
+++ b/usr/src/cmd/print/gateway/translators/cascade/cascade.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,11 +38,11 @@
#include <unistd.h>
#include <libintl.h>
-#include <print/ns.h>
-#include <print/job.h>
-#include <print/list.h>
-#include <print/misc.h>
-#include <print/network.h>
+#include <ns.h>
+#include <job.h>
+#include <list.h>
+#include <misc.h>
+#include <network.h>
static ns_printer_t *printer_object = NULL;
diff --git a/usr/src/cmd/print/gateway/translators/test/test.c b/usr/src/cmd/print/gateway/translators/test/test.c
index 243da2f740..1749e5c2e8 100644
--- a/usr/src/cmd/print/gateway/translators/test/test.c
+++ b/usr/src/cmd/print/gateway/translators/test/test.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1998 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -35,7 +34,7 @@
#include <stdarg.h>
#include <syslog.h>
-#include <print/ns.h>
+#include <ns.h>
static ns_printer_t *printer_object = NULL;
diff --git a/usr/src/cmd/print/lp/lp.c b/usr/src/cmd/print/lp/lp.c
deleted file mode 100644
index dce11659f7..0000000000
--- a/usr/src/cmd/print/lp/lp.c
+++ /dev/null
@@ -1,1281 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/systeminfo.h>
-#include <sys/param.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <syslog.h>
-#include <termios.h>
-#include <libintl.h>
-#include <locale.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include <print/ns.h>
-#include <print/network.h>
-#include <print/misc.h>
-#include <print/list.h>
-#include <print/job.h>
-
-/*
- * lpr/lp
- * This program will submit print jobs to a spooler using the BSD
- * printing protcol as defined in RFC1179, plus some extension for
- * support of additional lp functionality.
- */
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-extern char *getenv(const char *);
-
-#define SEND_RETRY -1
-#define SEND_ABORT -2
-
-
-static int priority = -1,
- copies = 1,
- width = -1, /* pr width */
- indent = -1, /* pr indent */
- linked = 0,
- mail = 0,
- delete = 0,
- suppress = 1,
- banner = 1,
- connection_failed = 0;
-static char *printer = NULL,
- *form = NULL,
- *charset = NULL,
- *title = NULL, /* pr title */
- *class = NULL,
- *jobName = NULL,
- *notification = NULL,
- *handling = NULL,
- *pages = NULL,
- **mode = NULL,
- **s5options = NULL,
- *s5type = NULL,
- *internal_type = NULL,
- *fontR = NULL,
- *fontI = NULL,
- *fontB = NULL,
- *fontS = NULL,
- type = CF_PRINT_ASCII;
-
-static struct s5_types {
- char *name;
- char type;
-} output_types[] = { /* known LP "-T" types */
-/*
- * Switched to ASCII, because some BSD systems don't like the 'o' file
- * type.
- */
- { "postscript", CF_PRINT_ASCII },
- { "ps", CF_PRINT_ASCII },
- { "simple", CF_PRINT_ASCII },
- { "ascii", CF_PRINT_ASCII },
- { "raw", CF_PRINT_RAW },
- { "dvi", CF_PRINT_DVI },
- { "tex", CF_PRINT_DVI },
- { "raster", CF_PRINT_RAS },
- { "ditroff", CF_PRINT_DROFF },
- { "otroff", CF_PRINT_TROFF },
- { "troff", CF_PRINT_DROFF },
- { "cif", CF_PRINT_CIF },
- { "plot", CF_PRINT_PLOT },
- { "fortran", CF_PRINT_FORT },
- { "pr", CF_PRINT_PR },
- NULL
-};
-
-/*ARGSUSED*/
-static void sigbus_handler(int i)
-{
- (void) fprintf(stderr,
- gettext("No space in /var/spool/print to store job"));
- exit(-1);
-}
-
-/*ARGSUSED*/
-static void sigpipe_handler(int i)
-{
- syslog(LOG_ERR, "Warning: Received SIGPIPE; continuing");
- (void) signal(SIGPIPE, sigpipe_handler);
-}
-
-
-#define OLD_LP "/usr/lib/lp/local/lp" /* for local lpsched printers */
-#ifdef OLD_LP
-/*
- * this will submit the job to a local lpsched using the old interface.
- * the argument vector is rebuilt with a new destination, because
- * the old name may have been an alias or because it was actually
- * lpr(1b) that was called.
- */
-static void
-submit_local_lp(char *program, int ac, char *av[])
-{
- uid_t ruid = getuid();
- struct passwd *pw;
- int argc = 0;
- char **argv;
-
- /*
- * We allocate the space for ac+5 items, which include all the file
- * arguments(ac), generic arguments(OLD_LP, "-d" and "printer") and
- * "-s" option of lpr. The extra item is just a cushion.
- */
- if ((argv = (char **)calloc(ac + 5, sizeof (char *))) == NULL) {
- (void) fprintf(stderr,
- gettext("not enough memory for argument vector\n"));
- exit(1);
- }
- argv[argc++] = OLD_LP;
- argv[argc++] = "-d";
- argv[argc++] = printer;
-
- if (strcmp(program, "lp") == 0) {
- int i = 0;
-
- while (++i < ac)
- if (strncmp(av[i], "-d", 2) != 0) {
- argv[argc++] = av[i];
- } else if (strlen(av[i]) == 2)
- i++;
- } else { /* convert lpr options */
- argv[argc++] = "-s"; /* supress id message */
-
- if (linked == 0)
- argv[argc++] = "-c";
-
- if (copies > 1) {
- char buf[12];
- (void) sprintf(buf, "%d", copies);
- argv[argc++] = "-n";
- argv[argc++] = strdup(buf);
- }
- if (banner == 0) {
- argv[argc++] = "-o";
- argv[argc++] = "nobanner";
- }
- if (title != NULL) {
- char buf[BUFSIZ];
- (void) snprintf(buf, sizeof (buf), "prtitle='%s'",
- title);
- argv[argc++] = "-y";
- argv[argc++] = strdup(buf);
- }
- if (width > 0) {
- char buf[16];
- (void) sprintf(buf, "prwidth=%d", width);
- argv[argc++] = "-y";
- argv[argc++] = strdup(buf);
- }
- if (indent > 0) {
- char buf[16];
- (void) sprintf(buf, "indent=%d", indent);
- argv[argc++] = "-y";
- argv[argc++] = strdup(buf);
- }
- if (mail != 0)
- argv[argc++] = "-m";
- if ((jobName != NULL) || (class != NULL)) {
- char buf[128];
- snprintf(buf, sizeof (buf), "%s%s%s",
- (jobName ? jobName : ""),
- (jobName && class ? "\\n#####\\n#####\\t\\t "
- : ""), (class ? class : ""));
- argv[argc++] = "-t";
- argv[argc++] = strdup(buf);
- }
-
- if (type != CF_PRINT_ASCII) {
- struct s5_types *tmp;
-
- for (tmp = output_types; tmp->name != NULL; tmp++)
- if (tmp->type == type) {
- argv[argc++] = "-T";
- argv[argc++] = tmp->name;
- break;
- }
- }
-
- while (optind < ac)
- argv[argc++] = av[optind++];
-
- }
-
- ruid = getuid();
- if ((pw = getpwuid(ruid)) != NULL)
- (void) initgroups(pw->pw_name, pw->pw_gid);
- (void) setuid(ruid);
-
- argv[argc++] = NULL;
- (void) execv(OLD_LP, argv);
-}
-#endif
-
-
-/*
- * cheat and look in the LP interface to determine if a local printer is
- * rejecting. If so, don't queue the job. If the printer is remote or
- * accepting, queue it. This approximates behaviour of previous releases
- * The check is being done this way for performance.
- */
-static int
-rejecting(char *printer)
-{
- int rc = 0, found = 0;
- FILE *fp;
-
- if ((fp = fopen("/usr/spool/lp/system/pstatus", "r+")) != NULL) {
- char buf[BUFSIZ];
-
- while (fgets(buf, sizeof (buf), fp) != NULL) {
- buf[strlen(buf)-1] = NULL;
- if (strcmp(buf, printer) == 0) {
- char *ptr;
-
- found = 1;
- (void) fgets(buf, sizeof (buf), fp);
- buf[strlen(buf)-1] = NULL;
- ptr = strrchr(buf, ' ');
- if (ptr && (strcmp(++ptr, "rejecting") == 0)) {
- rc = 1;
- break;
- }
- }
- }
- }
- (void) fclose(fp);
-
- /* if we have'nt found the name it could be a class */
- if (!found) {
- if ((fp = fopen("/usr/spool/lp/system/cstatus",
- "r+")) != NULL) {
-
- char buf2[BUFSIZ];
-
- while (fgets(buf2, sizeof (buf2), fp) != NULL) {
- buf2[strlen(buf2)-1] = NULL;
- if (strcmp(buf2, printer) == 0) {
- fgets(buf2, sizeof (buf2), fp);
- buf2[strlen(buf2)-1] = NULL;
- if (strcmp(buf2, "rejecting") == 0) {
- rc = 1;
- break;
- }
- }
- }
-
- }
- }
-
- (void) fclose(fp);
- return (rc);
-}
-
-/*
- * Remove special characters before popen (change them into '_').
- */
-static void
-clean_string(char *ptr)
-{
- char *cp;
- wchar_t wc;
- int len;
-
- for (cp = ptr; *cp != NULL; ) {
- if ((len = mbtowc(&wc, cp, MB_CUR_MAX)) == -1) {
- cp++;
- continue;
- }
-
- if (len == 1 &&
- ((wc == L'`') || (wc == L'&') || (wc == L';') ||
- (wc == L'|') || (wc == L'>') || (wc == L'^') ||
- (wc == L'$') || (wc == L'(') || (wc == L')') ||
- (wc == L'<') || (wc == L'*') || (wc == L'?') ||
- (wc == L'[')))
- *cp = '_';
- cp += len;
- }
-}
-
-
-static int _notified = 0;
-
-static void
-error_notify(char *user, int id, char *msg, ...)
-{
- if (_notified++ == 0) {
- char *tmp;
- char cmd[BUFSIZ];
- FILE *fp;
- va_list ap;
-
- va_start(ap, msg);
- tmp = strdup(user);
- clean_string(tmp);
- (void) snprintf(cmd, sizeof (cmd),
- "/bin/write %s >/dev/null 2>&1", tmp);
- free(tmp);
- fp = popen(cmd, "w+");
- (void) fprintf(fp,
- gettext("\n\tError transfering print job %d\n"), id);
- (void) vfprintf(fp, msg, ap);
- (void) pclose(fp);
- va_end(ap);
- }
-}
-
-
-
-/*
- * bsd_options() parses the command line using the BSD lpr semantics and sets
- * several global variables for use in building the print request.
- */
-static void
-bsd_options(int ac, char *av[])
-{
- int c;
-
- while ((c = getopt(ac, av,
- "P:#:C:J:T:w:i:hplrstdgvcfmn1:2:3:4:")) != EOF)
- switch (c) {
- case 'P':
- printer = optarg;
- break;
- case '#':
- copies = atoi(optarg);
- break;
- case 'C':
- class = optarg;
- break;
- case 'J':
- jobName = optarg;
- break;
- case 'T':
- title = optarg;
- break;
- case 'w':
- width = atoi(optarg);
- break;
- case 'm':
- mail++;
- break;
- case 'i': /* this may or may not have an arguement */
- if (isdigit(optarg[0]) == 0) {
- indent = 8;
- optind--;
- } else
- indent = atoi(optarg);
- break;
- case 'h':
- banner = 0;
- break;
- case 'r':
- delete = 1;
- break;
- case 's':
- linked = 1;
- break;
- case 'l' :
- type = CF_PRINT_RAW;
- break;
- case 'd' :
- type = CF_PRINT_DVI;
- break;
- case 't' :
- type = CF_PRINT_TROFF;
- break;
- case 'g' :
- type = CF_PRINT_PLOT;
- break;
- case 'v' :
- type = CF_PRINT_RAS;
- break;
- case 'c' :
- type = CF_PRINT_CIF;
- break;
- case 'f' :
- type = CF_PRINT_FORT;
- break;
- case 'n' :
- type = CF_PRINT_DROFF;
- break;
- case 'o' :
- type = CF_PRINT_PS;
- break;
- case 'p' :
- type = CF_PRINT_PR;
- break;
- case '1' :
- fontR = optarg;
- break;
- case '2' :
- fontI = optarg;
- break;
- case '3' :
- fontB = optarg;
- break;
- case '4' :
- fontS = optarg;
- break;
- default:
- (void) fprintf(stderr,
- gettext("Usage: %s [-Pprinter] [-#num] "
- "[-Cclass] [-Jjob] [-Ttitle] [-i [indent]] "
- "[-1234 font] [-wcols] [-m] [-h] [-s] "
- "[-pltndgvcf] files ...\n"),
- av[0]);
- exit(1);
- }
-
- /*
- * The pr filter must be specified with the
- * title, width, and indent options
- */
- if ((title != NULL) && (type != CF_PRINT_PR))
- (void) fprintf(stderr, gettext(
- "Warning: title option ignored as the pr "
- "filter option was not specified\n"));
- if ((width > 0) && (type != CF_PRINT_PR))
- (void) fprintf(stderr, gettext(
- "Warning: width option ignored as the pr "
- "filter option was not specified\n"));
- if ((indent > 0) && (type != CF_PRINT_PR))
- (void) fprintf(stderr, gettext(
- "Warning: indent option ignored as the pr "
- "filter option was not specified\n"));
-}
-
-/*
- * sysv_options() parses the command line using the BSD lpr semantics and sets
- * several global variables for use in building the print request.
- */
-static void
-sysv_options(int ac, char *av[])
-{
- int c;
-
-#ifdef OLD_LP
- if ((ac > 2) && (strcmp(av[1], "-i") == 0)) {
- if (access(OLD_LP, F_OK) == 0) {
- /*
- * limit ourselves to real user's perms before exec'ing
- */
- (void) setuid(getuid());
- (void) execv(OLD_LP, av);
- perror("exec local modify");
- } else
- (void) printf(gettext(
- "job modification not supported on clients\n"));
- exit(-1);
- }
-#endif
-
- linked = 1;
- suppress = 0;
- while ((c = getopt(ac, av, "H:P:S:T:d:f:i:o:q:t:y:cmwn:prs")) != EOF)
- switch (c) {
- case 'q':
- priority = atoi(optarg);
- break;
- case 'H':
- handling = optarg;
- break;
- case 'f':
- form = optarg;
- break;
- case 'd':
- printer = optarg;
- break;
- case 'T':
- {
- struct s5_types *tmp;
- int flag = 0;
-
- for (tmp = output_types;
- ((flag == 0) && (tmp->name != NULL)); tmp++)
- if (strcasecmp(tmp->name, optarg) == 0) {
- type = tmp->type;
- flag++;
- }
- if (flag == 0)
- s5type = optarg;
- else
- internal_type = optarg;
- break;
- }
- case 'S':
- charset = optarg;
- break;
- case 'o':
- {
- char *p, *q = strdup(optarg);
-
- /*
- * -o nobanner will no longer generate a warning or
- * Onobanner in the control file. If "nobanner" is
- * embedded in an option list, the option list will
- * still generate a warning or 'O' message in the
- * control file.
- */
- if (strcmp("nobanner", optarg) != 0)
- s5options = (char **)list_append(
- (void**)s5options,
- (void *)strdup(optarg));
-
- for (p = strtok(q, "\t ,"); p != NULL;
- p = strtok(NULL, "\t ,"))
- if (strcmp(p, "nobanner") == 0) {
- banner = 0;
- break;
- }
- }
- break;
- case 'y':
- {
- char *p, *q = strdup(optarg);
-
- for (p = strtok(q, "\t ,"); p != NULL;
- p = strtok(NULL, "\t ,"))
- if (strcmp(p, "catv_filter") == 0)
- type = CF_PRINT_RAW;
- else
- mode = (char **)list_append(
- (void **)mode,
- (void *)p);
- }
- break;
- case 'P':
- pages = optarg;
- break;
- case 'i':
- (void) printf(gettext(
- "job modification (-i) only supported on server\n"));
- break;
- case 'c':
- linked = 0;
- break;
- case 'm':
- mail++;
- break;
- case 'w':
- mail++;
- break;
- case 'p':
- notification = optarg;
- break;
- case 'n':
- if ((optarg == 0) || (*optarg == '-')) {
- (void) fprintf(stderr, gettext(
- "-n requires a positive integer argument\n"));
- exit(1);
- }
- copies = atoi(optarg);
- break;
- case 's':
- suppress = 1;
- break;
- case 't':
- jobName = optarg;
- break;
- case 'r':
- /* not supported - raw */
- break;
- default:
- (void) fprintf(stderr,
- gettext("Usage: %s [-d dest] [-cmwsr] [-n num] "
- "[-t title] [-p notification] [-P page-list] "
- "[-i job-id] [y modes] [-o options] "
- "[-S char-set] [-T input-type] [H handling] "
- "[-q priority] files ...\n"),
- av[0]);
- exit(1);
- }
-}
-
-
-/*
- * stdin_to_file() reads standard input into a file and returns the file name
- * to the caller
- */
-static char *
-stdin_to_file()
-{
- int fd,
- rc;
- char *name,
- buf[BUFSIZ];
-
- (void) putenv("TMPDIR="); /* stop user moving the temp file */
-
- snprintf(buf, sizeof (buf), "/tmp/stdinXXXXXX");
- if ((fd = mkstemp(buf)) < 0)
- return (NULL);
- fchmod(fd, 0640);
- if ((name = strdup(buf)) == NULL) {
- close(fd);
- return (NULL);
- }
- syslog(LOG_DEBUG, "stdin_to_file: %s", name);
- while ((rc = read(0, buf, sizeof (buf))) > 0)
- (void) write(fd, buf, rc);
- (void) close(fd);
- return (name);
-}
-
-
-static int
-sendfile(jobfile_t *file, int nd, int type)
-{
- int rc = -1;
-
- syslog(LOG_DEBUG, "sendfile(%s, %d, %d)",
- ((file != NULL) ? file->jf_spl_path : "NULL"), nd, type);
- if (file && file->jf_spl_path) {
- rc = net_send_file(nd, file->jf_spl_path, file->jf_data,
- file->jf_size, type);
- }
- return (rc);
-}
-
-
-/*
- * send_job() sends a job to a remote print server.
- */
-static int
-send_job(job_t *job)
-{
- int lockfd,
- lock_size,
- nd,
- tmp,
- rc = 0;
- struct passwd *p = NULL;
- char buf[BUFSIZ];
-
- syslog(LOG_DEBUG, "send_job(%s, %s, %d): called", job->job_printer,
- job->job_server, job->job_id);
- if ((lockfd = get_lock(job->job_cf->jf_src_path, 0)) < 0) {
- (void) close(lockfd);
- return (SEND_RETRY);
- }
-
- /* is job complete ? */
-
- lock_size = file_size(job->job_cf->jf_src_path);
- (void) sprintf(buf, "%ld\n", getpid()); /* add pid to lock file */
- (void) lseek(lockfd, 0, SEEK_END);
- (void) write(lockfd, buf, strlen(buf));
-
- syslog(LOG_DEBUG, "send_job(%s, %s, %d): have lock", job->job_printer,
- job->job_server, job->job_id);
- connection_failed = 0;
- if ((nd = net_open(job->job_server, 5)) < 0) {
- connection_failed = 1;
- if ((nd != NETWORK_ERROR_UNKNOWN) && (nd != NETWORK_ERROR_PORT))
- job_destroy(job);
- else
- (void) ftruncate(lockfd, lock_size);
- (void) close(lockfd);
- return ((nd == NETWORK_ERROR_UNKNOWN) ||
- (nd == NETWORK_ERROR_PORT) ? SEND_RETRY : SEND_ABORT);
- }
-
- if (net_send_message(nd, "%c%s\n", XFER_REQUEST, job->job_printer)
- != 0) {
- (void) net_close(nd);
- syslog(LOG_WARNING,
- "send_job failed job %d (%s@%s) check status\n",
- job->job_id, job->job_printer, job->job_server);
- error_notify(job->job_user, job->job_id,
- gettext("\t\t check queue for (%s@%s)\n"),
- job->job_printer, job->job_server);
- (void) ftruncate(lockfd, lock_size);
- (void) close(lockfd);
- return (SEND_RETRY);
- }
-
- syslog(LOG_DEBUG, "send_job(%s, %s, %d): send data", job->job_printer,
- job->job_server, job->job_id);
-
- if ((p = getpwnam(job->job_user)) != NULL) {
- /*
- * attempt to become the job owner: uid, euid, gid, and
- * supplementary groups while we try to send the job data.
- * The real uid is changed with setreuid() separately from
- * changing the effective uid so that we retain the saved
- * uid to elevate privilege later. Combining these changes
- * would result in a change to the saved uid also and a loss
- * of the ability to elevate privilege later.
- */
- (void) setuid(0);
- (void) initgroups(job->job_user, p->pw_gid);
- (void) setgid(p->pw_gid);
- (void) setreuid(p->pw_uid, -1);
- (void) seteuid(p->pw_uid);
- }
-
- for (tmp = 0; job->job_df_list[tmp] != NULL; tmp++)
- if ((rc = sendfile(job->job_df_list[tmp], nd, XFER_DATA)) < 0)
- break; /* there was an error, quit now */
- tmp = errno;
- if (p != NULL) {
- /*
- * lose the supplemental groups and elevate our effective
- * uid to root so that we can destroy jobs and/or become
- * other job owners later on.
- */
- (void) seteuid(0);
- (void) initgroups("root", 1);
- }
- errno = tmp;
-
- if (rc < 0) {
- if (errno == ENOENT) {
- (void) net_close(nd);
- error_notify(job->job_user, job->job_id, gettext(
- "\t\tdata removed before transfer, job "
- "canceled.\n\t\tTry \"lp -c\" or \"lpr\"\n"));
- job_destroy(job);
- (void) close(lockfd);
- return (SEND_ABORT);
- } else if (errno == EACCES) {
- /* probably trying to circumvent file security */
- (void) net_close(nd);
- error_notify(job->job_user, job->job_id, gettext(
- "\t\tunable to read job data.\n"));
- job_destroy(job);
- (void) close(lockfd);
- return (SEND_ABORT);
- } else {
- (void) net_close(nd);
- (void) ftruncate(lockfd, lock_size);
- error_notify(job->job_user, job->job_id,
- gettext("\t\t check queue for (%s@%s)\n"),
- job->job_printer, job->job_server);
- (void) close(lockfd);
- return (SEND_RETRY);
- }
- }
-
- if (sendfile(job->job_cf, nd, XFER_CONTROL) < 0) {
- (void) net_send_message(nd, "%c\n", XFER_CLEANUP);
- (void) net_close(nd);
- (void) ftruncate(lockfd, lock_size);
- error_notify(job->job_user, job->job_id,
- gettext("\t\t check queue for (%s@%s)\n"),
- job->job_printer, job->job_server);
- (void) close(lockfd);
- return (SEND_RETRY);
- }
-
- syslog(LOG_DEBUG, "send_job(%s, %s, %d): complete", job->job_printer,
- job->job_server, job->job_id);
- (void) net_close(nd);
- job_destroy(job);
- (void) close(lockfd);
- return (0);
-}
-
-
-/*
- * xfer_daemon() attempts to start up a daemon for transfering jobs to a remote
- * print server. The daemon runs if it can get the master lock, and it
- * runs until there are no jobs waiting for transfer.
- */
-static void
-xfer_daemon()
-{
- job_t **list = NULL;
- int i,
- rc;
-
-
-
- closelog();
- closefrom(0);
-
- _notified = 1;
- (void) open("/dev/null", O_RDONLY);
- (void) open("/dev/null", O_WRONLY);
- (void) dup(1);
-
- (void) setuid(0);
- (void) setsid();
- openlog("printd", LOG_PID, LOG_LPR);
- if (fork() != 0)
- exit(0);
-
- if ((i = get_lock(MASTER_LOCK, 1)) < 0)
- exit(0);
-
- (void) chdir(SPOOL_DIR);
- while ((list = job_list_append(NULL, NULL, NULL, SPOOL_DIR)) != NULL) {
- job_t **tmp;
-
- syslog(LOG_DEBUG, "got the queue...");
- for (tmp = list; *tmp != NULL; tmp++) {
- /*
- * Bugid: 4133175 printd dies when data is removed or
- * permissions are changed. Memory is freed twice.
- * Fix: Do not process anything else in the list
- * if the return code is SEND_ABORT as the memory
- * has already been freed by job_destroy().
- */
- rc = send_job(*tmp);
- if ((rc != 0) && (rc != SEND_ABORT)) {
- char *s = strdup((*tmp)->job_server);
- char *p = strdup((*tmp)->job_printer);
-
- if (rc != SEND_ABORT) /* already free */
- job_free(*tmp);
-
- for (tmp++; ((*tmp != NULL) &&
- (strcmp(s, (*tmp)->job_server) == 0));
- tmp++)
- if ((connection_failed == 0) &&
- (strcmp(p,
- (*tmp)->job_printer) == 0))
- job_free(*tmp);
- else
- break;
- tmp--;
- free(s);
- free(p);
- }
- }
- free(list);
-
- /* look for more work to do before we sleep */
- if ((list = job_list_append(NULL, NULL, NULL,
- SPOOL_DIR)) != NULL) {
- (void) list_iterate((void **)list, (VFUNC_T)job_free);
- free(list);
- (void) sleep(60);
- }
- }
- syslog(LOG_DEBUG, "daemon exiting...");
-}
-
-static void
-append_string(char *s, va_list ap)
-{
- char *buf = va_arg(ap, char *);
-
- if (strlen(buf) != 0)
- (void) strcat(buf, " ");
- (void) strcat(buf, s);
-}
-
-
-static char *
-build_string(char **list)
-{
- int size = 0;
- char *buf = NULL;
-
- if (list != NULL) {
- size = list_iterate((void **)list, (VFUNC_T)strlen);
- size += 16;
- buf = malloc(size);
- (void) memset(buf, NULL, size);
- (void) list_iterate((void **)list, (VFUNC_T)append_string, buf);
- }
- return (buf);
-}
-
-
-#define ADD_PRIMATIVE(job, primative, value) \
- if ((job != NULL) && (value != NULL)) \
- (void) job_primative(job, primative, value);
-#define ADD_SVR4_PRIMATIVE(job, primative, value) \
- if ((job != NULL) && (value != NULL)) (void) job_svr4_primative(job, \
- primative, value);
-
-#define ADD_INT_PRIMATIVE(job, primative, value, ok) \
- if ((job != NULL) && (value != ok)) { \
- (void) sprintf(buf, "%d", value); \
- (void) job_primative(job, primative, buf); \
- }
-#define ADD_SVR4_INT_PRIMATIVE(job, primative, value, ok) \
- if ((job != NULL) && (value != ok)) { \
- (void) sprintf(buf, "%d", value); \
- (void) job_svr4_primative(job, primative, \
- buf); \
- }
-
-#define OPTION_ERROR(option, value) \
- if (value != NULL) \
- (void) fprintf(stderr, gettext("\tignoring: %s %s\n"), \
- option, value);
-
-#define OPTION_ERROR_INT(option, value) \
- if (value != -1) \
- (void) fprintf(stderr, gettext("\tignoring: %s %d\n"), \
- option, value);
-
-
-
-/*
- * Main program. if called with "lpr" use the BSD syntax, if called
- * with "lp", use the SYSV syntax. If called by any other name,
- * become a transfer daemon. In the lpr/lp case, build a job and
- * attempt to send it to the print server. If the server doesn't
- * respond, become a daemon if none is currently running and attempt
- * to xfer all waiting jobs.
- */
-int
-main(int ac, char *av[])
-{
- ns_bsd_addr_t *binding = NULL;
- int numFiles = 0,
- queueStdin = 0,
- exit_code = 0;
- char *program,
- *user,
- hostname[128],
- buf[BUFSIZ];
- job_t *job;
-
- (void) setlocale(LC_ALL, "");
-
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- if ((program = strrchr(av[0], '/')) == NULL)
- program = av[0];
- else
- program++;
-
- openlog(program, LOG_PID, LOG_LPR);
-
- /*
- * Bugid: 4013980 Application changed fd 1 to a pipe that has
- * no reader; we write to stdout and catch a sigpipe and exit.
- * Fix: catch signal, complain to syslog, and continue.
- */
- (void) signal(SIGPIPE, sigpipe_handler);
-
- if (check_client_spool(NULL) < 0) {
- (void) fprintf(stderr,
- gettext("couldn't validate local spool area (%s)\n"),
- SPOOL_DIR);
- return (-1);
- }
- if (strcmp(program, "lpr") == 0) {
- if ((printer = getenv((const char *)"PRINTER")) == NULL)
- printer = getenv((const char *)"LPDEST");
- bsd_options(ac, av);
- } else if (strcmp(program, "lp") == 0) {
- if ((printer = getenv((const char *)"LPDEST")) == NULL)
- printer = getenv((const char *)"PRINTER");
- sysv_options(ac, av);
- } else {
- xfer_daemon();
- return (0);
- }
-
- if (printer == NULL) {
- ns_printer_t *pobj = ns_printer_get_name(NS_NAME_DEFAULT, NULL);
-
- if (pobj != NULL) {
- printer = ns_get_value_string(NS_KEY_USE, pobj);
- ns_printer_destroy(pobj);
- }
-
- if (printer == NULL)
- printer = NS_NAME_DEFAULT;
- }
-
- if (printer == NULL) {
- (void) fprintf(stderr, gettext("No default destination\n"));
- return (1);
- }
-
- if ((binding = ns_bsd_addr_get_name(printer)) == NULL) {
- (void) fprintf(stderr, gettext("%s: unknown printer\n"),
- printer);
- return (1);
- }
-
- if (rejecting(binding->printer) != 0) {
- (void) fprintf(stderr, gettext(
- "%s: requests are not being accepted\n"),
- printer);
- return (1);
- }
-
- (void) sysinfo(SI_HOSTNAME, hostname, sizeof (hostname));
-#ifdef OLD_LP
- /*
- * If the server is local, there is lp server configuration, and
- * the old lp is still hanging around, use it to submit the job.
- */
- {
- char cpath[MAXPATHLEN],
- ppath[MAXPATHLEN];
-
- (void) snprintf(ppath, sizeof (ppath),
- "/etc/lp/printers/%s/configuration", binding->printer);
- (void) snprintf(cpath, sizeof (cpath),
- "/etc/lp/classes/%s", binding->printer);
- if (((strcasecmp(binding->server, hostname) == 0) ||
- (strcasecmp(binding->server, "localhost") == 0)) &&
- ((access(ppath, F_OK) == 0) ||
- (access(cpath, F_OK) == 0)) &&
- (access(OLD_LP, F_OK) == 0)) {
- printer = binding->printer;
- submit_local_lp(program, ac, av);
- }
- }
-#endif
-
- if ((job = job_create(strdup(binding->printer), strdup(binding->server),
- SPOOL_DIR)) == NULL) {
- syslog(LOG_ERR,
- "Error creating job: check spooling directory: %s",
- SPOOL_DIR);
- (void) fprintf(stderr, gettext(
- "Error creating job: check spooling directory: %s\n"),
- SPOOL_DIR);
- return (-1);
- }
-
- (void) umask(0);
- user = get_user_name();
-
- ADD_PRIMATIVE(job, CF_HOST, hostname);
- ADD_PRIMATIVE(job, CF_USER, user);
- ADD_PRIMATIVE(job, CF_TITLE, title);
-
-
- if (banner != 0) {
- if (jobName != NULL) {
- ADD_PRIMATIVE(job, CF_JOBNAME, jobName);
- } else if ((av[optind] == NULL) ||
- (strcmp(av[optind], "-") == 0)) {
- ADD_PRIMATIVE(job, CF_JOBNAME, "standard input");
- } else {
- ADD_PRIMATIVE(job, CF_JOBNAME, av[optind]);
- }
- ADD_PRIMATIVE(job, CF_CLASS, (class ? class : hostname));
- ADD_PRIMATIVE(job, CF_PRINT_BANNER, user);
- }
-
- if (mail != 0) {
- (void) snprintf(buf, sizeof (buf), "%s@%s", user, hostname);
- ADD_PRIMATIVE(job, CF_MAIL, buf);
- }
-
- ADD_INT_PRIMATIVE(job, CF_INDENT, indent, -1); /* ASCII */
- ADD_INT_PRIMATIVE(job, CF_WIDTH, width, -1);
-
- if ((type == CF_PRINT_DVI) || (type == CF_PRINT_DROFF) ||
- (type == CF_PRINT_TROFF)) {
- ADD_PRIMATIVE(job, CF_FONT_TROFF_R, fontR);
- ADD_PRIMATIVE(job, CF_FONT_TROFF_I, fontI);
- ADD_PRIMATIVE(job, CF_FONT_TROFF_B, fontB);
- ADD_PRIMATIVE(job, CF_FONT_TROFF_S, fontS);
- }
-
- if (binding->extension == NULL)
- binding->extension = "";
-
- if ((strcasecmp(binding->extension, NS_EXT_SOLARIS) == 0) ||
- (strcasecmp(binding->extension, NS_EXT_GENERIC) == 0)) {
- /* RFC1179 compliant don't get this */
- syslog(LOG_DEBUG, "main(): add Solaris extensions");
- ADD_PRIMATIVE(job, CF_SYSV_OPTION, build_string(s5options));
- ADD_SVR4_INT_PRIMATIVE(job, CF_SYSV_PRIORITY, priority, -1);
- ADD_SVR4_PRIMATIVE(job, CF_SYSV_FORM, form);
- ADD_SVR4_PRIMATIVE(job, CF_SYSV_CHARSET, charset);
- ADD_SVR4_PRIMATIVE(job, CF_SYSV_NOTIFICATION, notification);
- ADD_SVR4_PRIMATIVE(job, CF_SYSV_HANDLING, handling);
- ADD_SVR4_PRIMATIVE(job, CF_SYSV_PAGES, pages);
- if (s5type != NULL) {
- ADD_SVR4_PRIMATIVE(job, CF_SYSV_TYPE, s5type);
- } else if (internal_type != NULL)
- ADD_SVR4_PRIMATIVE(job, CF_SYSV_TYPE, internal_type);
- ADD_SVR4_PRIMATIVE(job, CF_SYSV_MODE, build_string(mode));
- } else if (strcasecmp(binding->extension, NS_EXT_HPUX) == 0) {
- syslog(LOG_DEBUG, "main(): add HP-UX extensions");
- if (s5options != NULL) {
- char buf[BUFSIZ];
-
- (void) snprintf(buf, sizeof (buf), " O%s",
- build_string(s5options));
- ADD_PRIMATIVE(job, CF_SOURCE_NAME, buf);
- }
- } else {
- if ((s5options != NULL) || (form != NULL) || (pages != NULL) ||
- (charset != NULL) || (notification != NULL) ||
- (handling != NULL) || (s5type != NULL) || (mode != NULL) ||
- (priority != -1))
- (void) fprintf(stderr, gettext(
- "Warning: %s not configured to handle all lp options:\n"),
- printer);
- OPTION_ERROR("-o", build_string(s5options));
- OPTION_ERROR("-f", form);
- OPTION_ERROR("-P", pages);
- OPTION_ERROR("-S", charset);
- OPTION_ERROR("-p", notification);
- OPTION_ERROR("-H", handling);
- OPTION_ERROR("-T", s5type);
- OPTION_ERROR("-y", build_string(mode));
- OPTION_ERROR_INT("-q", priority);
- }
-
- syslog(LOG_DEBUG, "main(): add files");
- if (ac-optind > 0) {
- while (optind < ac)
- if (strcmp(av[optind++], "-") == 0)
- queueStdin++;
- else if (job_add_data_file(job, av[optind-1], title,
- type, copies, linked, delete) < 0) {
- switch (errno) {
- case EISDIR:
- (void) fprintf(stderr, gettext(
- "%s: not a regular file\n"),
- av[optind-1]);
- break;
- case ESRCH:
- (void) fprintf(stderr, gettext(
- "%s: empty file\n"),
- av[optind-1]);
- break;
- case ENFILE:
- (void) fprintf(stderr, gettext(
- "too many files, ignoring %s\n"),
- av[optind-1]);
- break;
- case EOVERFLOW:
- (void) fprintf(stderr, gettext(
- "%s: largefile (>= 2GB), ignoring\n"),
- av[optind-1]);
- break;
- default:
- perror(av[optind-1]);
- }
- exit_code = -1;
- } else
- numFiles++;
- } else
- queueStdin++;
-
- if (queueStdin != 0) {
- char *name;
-
- /* standard input */
- if ((name = stdin_to_file()) != NULL) {
- if (job_add_data_file(job, name,
- gettext("standard input"),
- type, copies, 0, 0) < 0) {
- switch (errno) {
- case ESRCH:
- (void) fprintf(stderr, gettext(
- "standard input empty\n"));
- break;
- case ENFILE:
- (void) fprintf(stderr, gettext(
- "too many files, ignoring standard input\n"));
- break;
- default:
- perror(name);
- }
- exit_code = -1;
- } else
- numFiles++;
- (void) unlink(name);
- free(name);
- }
- }
-
- if (numFiles == 0)
- return (-1);
-
- if (seteuid(0) < 0)
- perror("seteuid(0)");
-
- (void) signal(SIGBUS, sigbus_handler);
- (void) chdir(SPOOL_DIR);
- (void) job_store(job);
-
- if (suppress == 0)
- if (numFiles == 1)
- (void) printf(
- gettext("request id is %s-%d (%d file)\n"),
- printer, job->job_id, numFiles);
- else
- (void) printf(
- gettext("request id is %s-%d (%d files)\n"),
- printer, job->job_id, numFiles);
- (void) fflush(stdout);
-
- /*
- * bgolden 10/2/96
- * BUG 1264627
- * when executed from xemacs, a sighup will kill
- * the child before the job is sent. ignore the signal
- */
- (void) signal(SIGHUP, SIG_IGN);
-
- switch (fork()) { /* for immediate response */
- case -1:
- syslog(LOG_ERR, "fork() failed: %m");
- break;
- case 0:
- break;
- default:
- return (exit_code);
- }
-
- if (send_job(job) == SEND_RETRY) {
- syslog(LOG_DEBUG, "main(): transfer failed");
- start_daemon(0);
- }
- else
- syslog(LOG_DEBUG, "main(): transfer succeeded");
-
- return (0);
-}
diff --git a/usr/src/cmd/print/lpget/lpget.c b/usr/src/cmd/print/lpget/lpget.c
index abe52330e0..9e6b0e3f00 100644
--- a/usr/src/cmd/print/lpget/lpget.c
+++ b/usr/src/cmd/print/lpget/lpget.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1998 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -38,9 +37,9 @@
#include <libintl.h>
#endif
-#include <print/ns.h>
-#include <print/misc.h>
-#include <print/list.h>
+#include <ns.h>
+#include <misc.h>
+#include <list.h>
extern char *optarg;
extern int optind, opterr, optopt;
diff --git a/usr/src/cmd/print/lpset/lpset.c b/usr/src/cmd/print/lpset/lpset.c
index 716065c470..b579c0cee0 100644
--- a/usr/src/cmd/print/lpset/lpset.c
+++ b/usr/src/cmd/print/lpset/lpset.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1998-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,9 +40,9 @@
#endif
#include <pwd.h>
-#include <print/ns.h>
-#include <print/misc.h>
-#include <print/list.h>
+#include <ns.h>
+#include <misc.h>
+#include <list.h>
extern char *optarg;
extern int optind, opterr, optopt;
diff --git a/usr/src/cmd/print/scripts/Makefile b/usr/src/cmd/print/scripts/Makefile
index 5012684790..0e9e771bec 100644
--- a/usr/src/cmd/print/scripts/Makefile
+++ b/usr/src/cmd/print/scripts/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -39,7 +38,7 @@ OWNER = root
GROUP = lp
FILEMODE = 0755
-MSGFILES = accept lpadmin
+MSGFILES = lpadmin
POFILE = scripts.po
PROG = conv_lp conv_lpd Makefile.yp
@@ -47,7 +46,7 @@ ROOTLIBPRINTPROG= $(PROG:%=$(ROOTPRINTLIB)/%)
$(ROOTLIBPRINTPROG) := FILEMODE=0555
$(ROOTPRINTLIB)/Makefile.yp := FILEMODE=0444
-USRSBINPROG= accept lpsystem lpadmin
+USRSBINPROG= lpsystem lpadmin
ROOTUSRSBINPROG= $(USRSBINPROG:%=$(ROOTUSRSBIN)/%)
$(ROOTUSRSBINPROG) := FILEMODE=555
@@ -63,10 +62,6 @@ $(ROOTPPDPROGS) := OWNER=root
$(ROOTPPDPROGS) := GROUP=lp
$(ROOTPPDPROGS) := FILEMODE=555
-ACCEPTLINKS= $(ROOTUSRSBIN)/reject $(ROOTBIN)/enable \
- $(ROOTBIN)/disable $(ROOTLIB)/accept \
- $(ROOTLIB)/reject
-
LIBLINKS= $(ROOTLIB)/lpadmin $(ROOTLIB)/lpsystem
@@ -89,9 +84,6 @@ $(ROOTLIB)/lpadmin:
$(ROOTLIB)/lpsystem:
$(RM) $@; $(SYMLINK) ../sbin/lpsystem $@
-$(ACCEPTLINKS):
- $(RM) $@; $(SYMLINK) ../sbin/accept $@
-
$(ROOTLNKPROGS) : $(ROOTSTARTPROG)
$(RM) $@; $(LN) $(ROOTSTARTPROG) $@
@@ -116,8 +108,7 @@ install: $(ROOTINIT_D) $(ROOTLNKPROGS) \
$(ROOTLIBPRINTPROG) $(ROOTSTARTPROG) \
$(ROOTUSRSBIN) $(ROOTUSRSBINPROG) \
$(ROOTVARSPOOLPRINT) $(ROOTPCONF) \
- $(ROOTPPDPROGS) \
- $(LIBLINKS) $(ACCEPTLINKS)
+ $(ROOTPPDPROGS) $(LIBLINKS)
$(SYMLINKS1):
$(RM) $@; $(SYMLINK) ../sbin/$(SBINPROG1) $@
@@ -125,9 +116,6 @@ $(SYMLINKS1):
$(SYMLINKS2):
$(RM) $@; $(SYMLINK) ../sbin/$(SBINPROG2) $@
-$(REJECTLINK):
- $(RM) $@; $(SYMLINK) accept $@
-
clean:
$(RM) $(POFILE)
diff --git a/usr/src/cmd/print/scripts/lpadmin b/usr/src/cmd/print/scripts/lpadmin
index e4cc8ea85f..ee6d1ccb4d 100644
--- a/usr/src/cmd/print/scripts/lpadmin
+++ b/usr/src/cmd/print/scripts/lpadmin
@@ -3,9 +3,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -318,6 +317,14 @@ if [ -f /usr/lib/lp/local/$cmd_name ] ; then
fi
eval $CMD
exit_code=$?
+ # add filters to the print server
+ if [ ! -f /etc/lp/filter.table ] ; then
+ cd /etc/lp/fd ; for filter in *.fd ; do
+ /usr/sbin/lpfilter \
+ -f `/usr/bin/basename $filter .fd` \
+ -F $filter
+ done
+ fi
fi
fi
@@ -325,21 +332,34 @@ if [ $exit_code != 0 ] ; then
exit $exit_code
fi
-
-# split the "server" into printer and server
+# process the "server" value
+# It can be a hostname, UUCP form (server!queue), RCMD form(queue@server),
+# or in URI form ({scheme}://{endpoint})
+#
+case "${server}" in
+ *://*) # URI form
+ uri=${server}
+ rem_printer=`expr "${server}" : ".*://.*/\([^/]*\)"`
+ server=`expr "${server}" : ".*://\([^/]*\)/.*"`
+ ;;
+ *@*) # RCMD form
+ rem_printer=`expr "${server}" : "\(.*\)@.*"`
+ server=`expr "${server}" : ".*@\(.*\)"`
+ ;;
+ *!*) # UUCP form
+ rem_printer=`expr "${server}" : ".*!\(.*\)"`
+ server=`expr "${server}" : "\(.*\)!.*"`
+ ;;
+ *) # hostname
+ rem_printer=${printer}
+ ;;
+esac
+# default URI form is "lpd" form
if [ -n "${server}" ] ; then
- if [ `echo ${server} | /bin/grep -c !` = 1 ] ; then
- rem_printer=`echo ${server} | cut -d! -f2`
- fi
- server=`echo ${server} | cut -d! -f1`
+ uri=${uri:-"lpd://${server}/printers/${rem_printer}#Solaris"}
+ bsdaddr="${server},${rem_printer},Solaris"
fi
-if [ -z "${rem_printer}" ] ; then
- rem_printer=${printer}
-fi
-
-
-
#
# Do the Solstice Print Configuration in /etc
#
@@ -356,10 +376,12 @@ else
fi
fi
- if [ -n "${printer}" -a -n "${server}" ] ; then
- ${LPSET} -n system \
- -a "bsdaddr=${server},${rem_printer},Solaris" \
- ${printer}
+ if [ -n "${printer}" -a -n "${uri}" ] ; then
+ ${LPSET} -n system -a "printer-uri-supported=${uri}" ${printer}
+ exit_code=$?
+ fi
+ if [ -n "${printer}" -a -n "${bsdaddr}" ] ; then
+ ${LPSET} -n system -a "bsdaddr=${bsdaddr}" ${printer}
exit_code=$?
fi
if [ -n "${printer}" -a -n "${description}" ] ; then
@@ -377,14 +399,14 @@ else
# If the class doesn't already exist in printers.conf, add it.
- if [ -n "${server}" ] ; then
- CHOST=$server
- else
- CHOST=$HOST
- fi
+ server=${server:-$HOST}
+ uri="lpd://${server}/printers/${class}#Solaris"
+ bsdaddr="${server},${class},Solaris"
if [ ${lpget_class} -ne 0 ] ; then
${LPSET} -n system \
- -a "bsdaddr=${CHOST},${class},Solaris" ${class}
+ -a "printer-uri-supported=${uri}" \
+ -a "bsdaddr=${bsdaddr}" \
+ ${class}
exit_code=$?
fi
fi
diff --git a/usr/src/lib/print/Makefile b/usr/src/lib/print/Makefile
index 63feb1e6e9..fd931373e8 100644
--- a/usr/src/lib/print/Makefile
+++ b/usr/src/lib/print/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,71 +19,76 @@
# CDDL HEADER END
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
#
-# cmd/lp/client/lib/Makefile
-#
-
-LIBRARY = libprint.a
-VERS=.2
-
-FILEMODE= 0555
-
-NS_CMN = ns_bsd_addr.o ns_cmn_kvp.o ns_cmn_printer.o
-NS_SWITCH = nss_printer.o nss_convert.o nss_write.o nss_ldap.o
-NS_SUPPORT = ns.o ${NS_CMN} ${NS_SWITCH}
-
-OBJECTS = network.o job.o list.o misc.o $(NS_SUPPORT)
+SUBDIRS = \
+ libprint \
+ libpapi-common \
+ libpapi-dynamic \
+ libpapi-lpd \
+ libipp-core \
+ libhttp-core \
+ libpapi-ipp \
+ libipp-listener \
+ mod_ipp
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+install_h := TARGET = install_h
+lint := TARGET = lint
+
+include $(SRC)/Makefile.master
+
+TEXT_DOMAIN= SUNW_OST_OSLIB
+POFILE= print-lib.po
-include ../Makefile.lib
-
-MAPFILES= mapfile-vers
-MAPOPTS= $(MAPFILES:%=-M %)
-
-CPPFLAGS += -I../../head -I../ -I. -D_REENTRANT
-LDLIBS += -lnsl -lsocket -lc -lldap
-DYNFLAGS += $(MAPOPTS)
+.KEEP_STATE:
+all: $(TXTS) $(SUBDIRS)
-LIBS = $(DYNLIB) # could be += for static and dynamic
-# for messaging catalog
#
-POFILE= bsd.po
-SRCS= $(OBJECTS:%.o=%.c)
-XGETFLAGS +=-a
-
-.KEEP_STATE:
-
-_msg: $(POFILE)
+# Each message catalog file is generated in each sub
+# directory and copied to the usr/src/cmd/lp/ directory.
+# Those message catalog files are consolidated into one
+# message catalog file. The consolidated one will be copied
+# into the $(ROOT)/catalog/SUNW_OST_OSCMD/ directory.
+#
-$(POFILE): $(SRCS)
- $(RM) $@
- $(COMPILE.cpp) $(SRCS) > $(POFILE).i
- $(XGETTEXT) $(XGETFLAGS) $(POFILE).i
- sed "/^domain/d" messages.po > $@
- $(RM) messages.po $(POFILE).i
+_msg: $(MSGDOMAIN)
+ @$(RM) $(POFILE)
+ $(XGETTEXT) -s `/bin/find . -type d -name SCCS -prune -o -type f -name '*.c' -print`
+ @/bin/cat messages.po | sed '/domain/d' > $(POFILE)
+ @$(RM) messages.po
+ $(RM) $(MSGDOMAIN)/$(POFILE)
+ /bin/cp $(POFILE) $(MSGDOMAIN)
-all : $(LIBS)
+install: $(ROOTDIRS) $(ROOTSYMLINKDIRS) $(SUBDIRS)
-install: $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS)
+install_h clean strip lint: $(SUBDIRS)
-# definitions for lint
+clobber: $(SUBDIRS) local_clobber
-$(LINTLIB):= SRCS = llib-lprint
-CLEANFILES += $(LINTLIB) $(LINTOUT)
+local_clobber:
+ $(RM) $(CLOBBERFILES) $(POFILE)
-lint: lintcheck
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
-cstyle:
- cstyle $(SRCS)
+FRC:
-strip :
+include $(SRC)/Makefile.msg.targ
-$(ROOTLIBDIR):
- $(INS.dir)
+# Dependencies
+libpapi-dynamic: libpapi-common
+libpapi-lpd: libpapi-dynamic
+libipp-core: libpapi-common
+libpapi-ipp: libpapi-common libipp-core libhttp-core
+libipp-listener: libpapi-dynamic libipp-core
+mod_ipp: libipp-listener
-include ../Makefile.targ
diff --git a/usr/src/lib/print/job.h b/usr/src/lib/print/job.h
deleted file mode 100644
index eed81c5f00..0000000000
--- a/usr/src/lib/print/job.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 1998 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef _JOB_H
-#define _JOB_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/va_list.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Sequence number space
- */
-#define JOB_ID_START 0
-#define JOB_ID_END 999
-
-/*
- * Job related files
- */
-#define SEQUENCE_FILE ".seq" /* sequence numbers */
-#define TEMP_FILE_PREFIX "tf" /* printer:server */
-#define XFER_FILE_PREFIX "xf" /* printer:server */
-#define CONTROL_FILE_PREFIX "cf" /* job control data */
-#define DATA_FILE_PREFIX "df" /* job data file */
-
-/*
- * RFC-1179 Control File Primatives
- */
-#define CF_CLASS 'C' /* C(ClassName)\n - for banner page */
-#define CF_HOST 'H' /* H(Hostname)\n - host submitting job */
-#define CF_INDENT 'I' /* I(indent)\n - # of spaces for 'f' */
-#define CF_JOBNAME 'J' /* J(Jobname)\n - name of job for banner */
-#define CF_PRINT_BANNER 'L' /* L[User]\n - User name on burst page */
-#define CF_MAIL 'M' /* M(user)\n - User to mail when done */
-#define CF_SOURCE_NAME 'N' /* N(name)\n - source of data file */
-#define CF_USER 'P' /* P(name)\n - requesting user */
-#define CF_SYMLINK 'S' /* S(device) (inode)\n - foget it */
-#define CF_TITLE 'T' /* T(title)\n - for pr */
-#define CF_UNLINK 'U' /* U(file)\n - unlink file */
-#define CF_WIDTH 'W' /* W(width)\n - column width */
-#define CF_FONT_TROFF_R '1' /* 1(file)\n - file with Times Roman font */
-#define CF_FONT_TROFF_I '2' /* 2(file)\n - file with Times Italic font */
-#define CF_FONT_TROFF_B '3' /* 3(file)\n - file with Times Bold font */
-#define CF_FONT_TROFF_S '4' /* 4(file)\n - file with Times Special font */
-#define CF_PRINT_CIF 'c' /* c(file)\n - print/plot file as CIF data */
-#define CF_PRINT_DVI 'd' /* d(file)\n - print file as DVI data */
-#define CF_PRINT_ASCII 'f' /* f(file)\n - print file as ASCII */
-#define CF_PRINT_PLOT 'g' /* g(file)\n - print file as plot data */
-#define CF_KERBERIZED 'k' /* k...\n - for Kerberos */
-#define CF_PRINT_RAW 'l' /* l(file)\n - print file dammit */
-#define CF_PRINT_DROFF 'n' /* n(file)\n - print file as ditroff output */
-#define CF_PRINT_PS 'o' /* o(file)\n - print file as PostScript */
-#define CF_PRINT_PR 'p' /* p(file)\n - print file thru "pr" */
-#define CF_PRINT_FORT 'r' /* r(file)\n - print file as fortran */
-#define CF_PRINT_TROFF 't' /* n(file)\n - print file as troff output */
-#define CF_PRINT_RAS 'v' /* v(file)\n - print file as raster image */
-#define CF_PRINT_PLDM 'z' /* z...\n - for Palladium ??? */
-
-/*
- * Solaris 2.X LP - BSD protocol extensions
- */
-#define CF_SYSV_OPTION 'O' /* for SVR4 LP '-o' option */
-#define CF_SYSV_FEATURE '5' /* for SVR4 LP features */
-#define CF_SYSV_FORM 'f' /* for SVR4 Forms */
-#define CF_SYSV_HANDLING 'H' /* for SVR4 Handling */
-#define CF_SYSV_NOTIFICATION 'p' /* for SVR4 Notification */
-#define CF_SYSV_PAGES 'P' /* for SVR4 Pages */
-#define CF_SYSV_PRIORITY 'q' /* for SVR4 Priority */
-#define CF_SYSV_CHARSET 'S' /* for SVR4 Charset */
-#define CF_SYSV_TYPE 'T' /* for SVR4 Type */
-#define CF_SYSV_MODE 'y' /* for SVR4 Mode */
-
-
-typedef struct _jobfile jobfile_t;
-typedef struct _job job_t;
-
-struct _jobfile {
- char *jf_spl_path; /* df file */
- char *jf_src_path; /* source file */
- char *jf_name; /* title/name */
- char *jf_data; /* ptr to mmapped file */
- long jf_size; /* size of data */
- char jf_mmapped; /* is this mmapped or malloced */
-} ;
-
-struct _job {
- int job_id;
- char *job_printer;
- char *job_server;
- char *job_user;
- char *job_host;
- char *job_spool_dir;
- jobfile_t *job_cf;
- char job_df_next;
- jobfile_t **job_df_list;
-} ;
-
-
-extern int job_primative(job_t *job, char option, char *value);
-extern int job_svr4_primative(job_t *job, char option, char *value);
-extern int job_add_data_file(job_t *job, char *path, char *title,
- char type, int copies, int linked,
- int delete);
-extern int job_store(job_t *job);
-extern void job_free(job_t *job);
-extern void job_destroy(job_t *job);
-extern job_t *job_create(char *printer, char *server, char *spool);
-extern job_t *job_retrieve(char *xfer_file, char *spool);
-extern job_t **job_list_append(job_t **list, char *printer,
- char *server, char *spool);
-extern int vjob_match_attribute(char *attribute, __va_list ap);
-extern int vjob_cancel(job_t *job, __va_list ap);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_JOB_H */
diff --git a/usr/src/lib/print/libhttp-core/Makefile b/usr/src/lib/print/libhttp-core/Makefile
new file mode 100644
index 0000000000..b92d620b10
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../../Makefile.lib
+
+#HDRS = papi.h
+#HDRDIR = common
+SUBDIRS = $(MACH)
+#$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all clean clobber install: .WAIT $(SUBDIRS)
+
+lint: # $(SUBDIRS)
+
+install_h: # $(ROOTHDRS)
+
+check: # $(CHECKHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/print/libhttp-core/Makefile.com b/usr/src/lib/print/libhttp-core/Makefile.com
new file mode 100644
index 0000000000..c027f93270
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/Makefile.com
@@ -0,0 +1,64 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = libhttp-core.a
+VERS = .1
+OBJECTS = http-addr.o http-support.o http.o
+
+ROOTLIBDIR = $(ROOT)/usr/lib/print
+
+include ../../../Makefile.lib
+include ../../../Makefile.rootfs
+
+ROOTLIBDIR= $(ROOT)/usr/lib/print
+ROOTLIBDIR64= $(ROOT)/usr/lib/print/$(MACH)
+
+LIBS = $(DYNLIB)
+
+SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c)
+
+$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+MAPFILE = $(SRCDIR)/mapfile
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -I$(SRCDIR)
+CPPFLAGS += -I../../libpapi-common/common
+DYNFLAGS += -M $(MAPFILE)
+LDLIBS += -lsocket -lnsl -lc
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+$(ROOTLIBDIR):
+ $(INS.dir)
+
+include ../../../Makefile.targ
diff --git a/usr/src/lib/print/libhttp-core/common/debug.h b/usr/src/lib/print/libhttp-core/common/debug.h
new file mode 100644
index 0000000000..aebc790017
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/common/debug.h
@@ -0,0 +1,70 @@
+/*
+ * "$Id: debug.h 148 2006-04-25 16:54:17Z njacobs $
+ *
+ * Debugging macros for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2005 by Easy Software Products.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_DEBUG_H_
+#define _CUPS_DEBUG_H_
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Include necessary headers...
+ */
+
+# include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * The debug macros are used if you compile with DEBUG defined.
+ *
+ * Usage:
+ *
+ * DEBUG_puts("string")
+ * DEBUG_printf(("format string", arg, arg, ...));
+ *
+ * Note the extra parenthesis around the DEBUG_printf macro...
+ */
+
+# ifdef DEBUG
+# define DEBUG_puts(x) puts(x)
+# define DEBUG_printf(x) printf x
+# else
+# define DEBUG_puts(x)
+# define DEBUG_printf(x)
+# endif /* DEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_CUPS_DEBUG_H_ */
+
+/*
+ * End of "$Id: debug.h 148 2006-04-25 16:54:17Z njacobs $"
+ */
diff --git a/usr/src/lib/print/libhttp-core/common/http-addr.c b/usr/src/lib/print/libhttp-core/common/http-addr.c
new file mode 100644
index 0000000000..a872d4d3fd
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/common/http-addr.c
@@ -0,0 +1,371 @@
+/*
+ * "$Id: http-addr.c 148 2006-04-25 16:54:17Z njacobs $"
+ *
+ * HTTP address routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2005 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * Contents:
+ *
+ * httpAddrAny() - Check for the "any" address.
+ * httpAddrEqual() - Compare two addresses.
+ * httpAddrLoad() - Load a host entry address into an HTTP address.
+ * httpAddrLocalhost() - Check for the local loopback address.
+ * httpAddrLookup() - Lookup the hostname associated with the address.
+ * httpAddrString() - Convert an IP address to a dotted string.
+ * httpGetHostByName() - Lookup a hostname or IP address, and return
+ * address records for the specified name.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "http.h"
+#include "debug.h"
+#include "string.h"
+#include <ctype.h>
+
+
+/*
+ * 'httpAddrAny()' - Check for the "any" address.
+ */
+
+int /* O - 1 if "any", 0 otherwise */
+httpAddrAny(const http_addr_t *addr) /* I - Address to check */
+{
+#ifdef AF_INET6
+ if (addr->addr.sa_family == AF_INET6 &&
+ IN6_IS_ADDR_UNSPECIFIED(&(addr->ipv6.sin6_addr)))
+ return (1);
+#endif /* AF_INET6 */
+
+ if (addr->addr.sa_family == AF_INET &&
+ ntohl(addr->ipv4.sin_addr.s_addr) == 0x00000000)
+ return (1);
+
+ return (0);
+}
+
+
+/*
+ * 'httpAddrEqual()' - Compare two addresses.
+ */
+
+int /* O - 1 if equal, 0 if != */
+httpAddrEqual(const http_addr_t *addr1, /* I - First address */
+ const http_addr_t *addr2) /* I - Second address */
+{
+ if (addr1->addr.sa_family != addr2->addr.sa_family)
+ return (0);
+
+#ifdef AF_INET6
+ if (addr1->addr.sa_family == AF_INET6)
+ return (memcmp(&(addr1->ipv6.sin6_addr), &(addr2->ipv6.sin6_addr), 16) == 0);
+#endif /* AF_INET6 */
+
+ return (addr1->ipv4.sin_addr.s_addr == addr2->ipv4.sin_addr.s_addr);
+}
+
+
+/*
+ * 'httpAddrLoad()' - Load a host entry address into an HTTP address.
+ */
+
+void
+httpAddrLoad(const struct hostent *host, /* I - Host entry */
+ int port, /* I - Port number */
+ int n, /* I - Index into host entry */
+ http_addr_t *addr) /* O - Address to load */
+{
+#ifdef AF_INET6
+ if (host->h_addrtype == AF_INET6)
+ {
+# ifdef WIN32
+ addr->ipv6.sin6_port = htons((u_short)port);
+# else
+ addr->ipv6.sin6_port = htons(port);
+# endif /* WIN32 */
+
+ memcpy((char *)&(addr->ipv6.sin6_addr), host->h_addr_list[n],
+ host->h_length);
+ addr->ipv6.sin6_family = AF_INET6;
+ }
+ else
+#endif /* AF_INET6 */
+#ifdef AF_LOCAL
+ if (host->h_addrtype == AF_LOCAL)
+ {
+ addr->un.sun_family = AF_LOCAL;
+ strlcpy(addr->un.sun_path, host->h_addr_list[n], sizeof(addr->un.sun_path));
+ }
+ else
+#endif /* AF_LOCAL */
+ if (host->h_addrtype == AF_INET)
+ {
+# ifdef WIN32
+ addr->ipv4.sin_port = htons((u_short)port);
+# else
+ addr->ipv4.sin_port = htons(port);
+# endif /* WIN32 */
+
+ memcpy((char *)&(addr->ipv4.sin_addr), host->h_addr_list[n],
+ host->h_length);
+ addr->ipv4.sin_family = AF_INET;
+ }
+}
+
+
+/*
+ * 'httpAddrLocalhost()' - Check for the local loopback address.
+ */
+
+int /* O - 1 if local host, 0 otherwise */
+httpAddrLocalhost(const http_addr_t *addr)
+ /* I - Address to check */
+{
+#ifdef AF_INET6
+ if (addr->addr.sa_family == AF_INET6 &&
+ IN6_IS_ADDR_LOOPBACK(&(addr->ipv6.sin6_addr)))
+ return (1);
+#endif /* AF_INET6 */
+
+#ifdef AF_LOCAL
+ if (addr->addr.sa_family == AF_LOCAL)
+ return (1);
+#endif /* AF_LOCAL */
+
+ if (addr->addr.sa_family == AF_INET &&
+ ntohl(addr->ipv4.sin_addr.s_addr) == 0x7f000001)
+ return (1);
+
+ return (0);
+}
+
+
+#ifdef __sgi
+# define ADDR_CAST (struct sockaddr *)
+#else
+# define ADDR_CAST (char *)
+#endif /* __sgi */
+
+
+/*
+ * 'httpAddrLookup()' - Lookup the hostname associated with the address.
+ */
+
+char * /* O - Host name */
+httpAddrLookup(const http_addr_t *addr, /* I - Address to lookup */
+ char *name, /* I - Host name buffer */
+ int namelen) /* I - Size of name buffer */
+{
+ struct hostent *host; /* Host from name service */
+
+
+ DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)\n",
+ addr, name, namelen));
+
+#ifdef AF_INET6
+ if (addr->addr.sa_family == AF_INET6)
+ host = gethostbyaddr(ADDR_CAST &(addr->ipv6.sin6_addr),
+ sizeof(struct in6_addr), AF_INET6);
+ else
+#endif /* AF_INET6 */
+#ifdef AF_LOCAL
+ if (addr->addr.sa_family == AF_LOCAL)
+ {
+ strlcpy(name, addr->un.sun_path, namelen);
+ return (name);
+ }
+ else
+#endif /* AF_LOCAL */
+ if (addr->addr.sa_family == AF_INET)
+ host = gethostbyaddr(ADDR_CAST &(addr->ipv4.sin_addr),
+ sizeof(struct in_addr), AF_INET);
+ else
+ host = NULL;
+
+ if (host == NULL)
+ {
+ httpAddrString(addr, name, namelen);
+ return (NULL);
+ }
+
+ strlcpy(name, host->h_name, namelen);
+
+ return (name);
+}
+
+
+/*
+ * 'httpAddrString()' - Convert an IP address to a dotted string.
+ */
+
+char * /* O - IP string */
+httpAddrString(const http_addr_t *addr, /* I - Address to convert */
+ char *s, /* I - String buffer */
+ int slen) /* I - Length of string */
+{
+ DEBUG_printf(("httpAddrString(addr=%p, s=%p, slen=%d)\n",
+ addr, s, slen));
+
+#ifdef AF_INET6
+ if (addr->addr.sa_family == AF_INET6)
+ snprintf(s, slen, "%u.%u.%u.%u",
+ ntohl(addr->ipv6.sin6_addr.s6_addr32[0]),
+ ntohl(addr->ipv6.sin6_addr.s6_addr32[1]),
+ ntohl(addr->ipv6.sin6_addr.s6_addr32[2]),
+ ntohl(addr->ipv6.sin6_addr.s6_addr32[3]));
+ else
+#endif /* AF_INET6 */
+#ifdef AF_LOCAL
+ if (addr->addr.sa_family == AF_LOCAL)
+ strlcpy(s, addr->un.sun_path, slen);
+ else
+#endif /* AF_LOCAL */
+ if (addr->addr.sa_family == AF_INET)
+ {
+ unsigned temp; /* Temporary address */
+
+
+ temp = ntohl(addr->ipv4.sin_addr.s_addr);
+
+ snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255,
+ (temp >> 16) & 255, (temp >> 8) & 255, temp & 255);
+ }
+ else
+ strlcpy(s, "UNKNOWN", slen);
+
+ DEBUG_printf(("httpAddrString: returning \"%s\"...\n", s));
+
+ return (s);
+}
+
+
+/*
+ * 'httpGetHostByName()' - Lookup a hostname or IP address, and return
+ * address records for the specified name.
+ */
+
+struct hostent * /* O - Host entry */
+httpGetHostByName(const char *name) /* I - Hostname or IP address */
+{
+ const char *nameptr; /* Pointer into name */
+ unsigned ip[4]; /* IP address components */
+ static unsigned packed_ip; /* Packed IPv4 address */
+ static char *packed_ptr[2]; /* Pointer to packed address */
+ static struct hostent host_ip; /* Host entry for IP/domain address */
+
+
+ DEBUG_printf(("httpGetHostByName(name=\"%s\")\n", name));
+
+#if defined(__APPLE__)
+ /* OS X hack to avoid it's ocassional long delay in lookupd */
+ static const char sLoopback[] = "127.0.0.1";
+ if (strcmp(name, "localhost") == 0)
+ name = sLoopback;
+#endif /* __APPLE__ */
+
+ /*
+ * This function is needed because some operating systems have a
+ * buggy implementation of gethostbyname() that does not support
+ * IP addresses. If the first character of the name string is a
+ * number, then sscanf() is used to extract the IP components.
+ * We then pack the components into an IPv4 address manually,
+ * since the inet_aton() function is deprecated. We use the
+ * htonl() macro to get the right byte order for the address.
+ *
+ * We also support domain sockets when supported by the underlying
+ * OS...
+ */
+
+#ifdef AF_LOCAL
+ if (name[0] == '/')
+ {
+ /*
+ * A domain socket address, so make an AF_LOCAL entry and return it...
+ */
+
+ host_ip.h_name = (char *)name;
+ host_ip.h_aliases = NULL;
+ host_ip.h_addrtype = AF_LOCAL;
+ host_ip.h_length = strlen(name) + 1;
+ host_ip.h_addr_list = packed_ptr;
+ packed_ptr[0] = (char *)name;
+ packed_ptr[1] = NULL;
+
+ DEBUG_puts("httpGetHostByName: returning domain socket address...");
+
+ return (&host_ip);
+ }
+#endif /* AF_LOCAL */
+
+ for (nameptr = name; isdigit(*nameptr & 255) || *nameptr == '.'; nameptr ++);
+
+ if (!*nameptr)
+ {
+ /*
+ * We have an IP address; break it up and provide the host entry
+ * to the caller. Currently only supports IPv4 addresses, although
+ * it should be trivial to support IPv6 in CUPS 1.2.
+ */
+
+ if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4)
+ return (NULL); /* Must have 4 numbers */
+
+ if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255)
+ return (NULL); /* Invalid byte ranges! */
+
+ packed_ip = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3]));
+
+ /*
+ * Fill in the host entry and return it...
+ */
+
+ host_ip.h_name = (char *)name;
+ host_ip.h_aliases = NULL;
+ host_ip.h_addrtype = AF_INET;
+ host_ip.h_length = 4;
+ host_ip.h_addr_list = packed_ptr;
+ packed_ptr[0] = (char *)(&packed_ip);
+ packed_ptr[1] = NULL;
+
+ DEBUG_puts("httpGetHostByName: returning IPv4 address...");
+
+ return (&host_ip);
+ }
+ else
+ {
+ /*
+ * Use the gethostbyname() function to get the IP address for
+ * the name...
+ */
+
+ DEBUG_puts("httpGetHostByName: returning domain lookup address(es)...");
+
+ return (gethostbyname(name));
+ }
+}
+
+
+/*
+ * End of "$Id: http-addr.c 148 2006-04-25 16:54:17Z njacobs $".
+ */
diff --git a/usr/src/lib/print/libhttp-core/common/http-private.h b/usr/src/lib/print/libhttp-core/common/http-private.h
new file mode 100644
index 0000000000..a11b8bbb5e
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/common/http-private.h
@@ -0,0 +1,115 @@
+/*
+ * "$Id: http-private.h 148 2006-04-25 16:54:17Z njacobs $"
+ *
+ * Private HTTP definitions for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2005 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_HTTP_PRIVATE_H_
+#define _CUPS_HTTP_PRIVATE_H_
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Include necessary headers...
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+# include "config.h"
+
+
+# ifdef __sun
+/*
+ * Define FD_SETSIZE to CUPS_MAX_FDS on Solaris to get the correct version of
+ * select() for large numbers of file descriptors.
+ */
+
+#define CUPS_MAX_FDS 1024
+
+# define FD_SETSIZE CUPS_MAX_FDS
+# include <sys/select.h>
+# endif /* __sun */
+
+# include "http.h"
+
+# if defined HAVE_LIBSSL
+/*
+ * The OpenSSL library provides its own SSL/TLS context structure for its
+ * IO and protocol management...
+ */
+
+# include <openssl/err.h>
+# include <openssl/rand.h>
+# include <openssl/ssl.h>
+
+typedef SSL http_tls_t;
+
+# elif defined HAVE_GNUTLS
+/*
+ * The GNU TLS library is more of a "bare metal" SSL/TLS library...
+ */
+# include <gnutls/gnutls.h>
+
+typedef struct
+{
+ gnutls_session session; /* GNU TLS session object */
+ void *credentials; /* GNU TLS credentials object */
+} http_tls_t;
+
+# elif defined(HAVE_CDSASSL)
+/*
+ * Darwin's Security framework provides its own SSL/TLS context structure
+ * for its IO and protocol management...
+ */
+
+# include <Security/SecureTransport.h>
+
+typedef SSLConnectionRef http_tls_t;
+
+# endif /* HAVE_LIBSSL */
+
+/*
+ * Some OS's don't have hstrerror(), most notably Solaris...
+ */
+
+# ifndef HAVE_HSTRERROR
+extern const char *cups_hstrerror(int error);
+# define hstrerror cups_hstrerror
+# elif defined(_AIX) || defined(__osf__)
+/*
+ * AIX and Tru64 UNIX don't provide a prototype but do provide the function...
+ */
+extern const char *hstrerror(int error);
+# endif /* !HAVE_HSTRERROR */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_CUPS_HTTP_PRIVATE_H_ */
+
+/*
+ * End of "$Id: http-private.h 148 2006-04-25 16:54:17Z njacobs $"
+ */
diff --git a/usr/src/lib/print/libhttp-core/common/http-support.c b/usr/src/lib/print/libhttp-core/common/http-support.c
new file mode 100644
index 0000000000..2ef3911058
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/common/http-support.c
@@ -0,0 +1,379 @@
+/*
+ * "$Id: http-support.c 148 2006-04-25 16:54:17Z njacobs $"
+ *
+ * HTTP support routines for the Common UNIX Printing System (CUPS) scheduler.
+ *
+ * Copyright 1997-2005 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * httpSeparate() - Separate a Universal Resource Identifier into its
+ * components.
+ * httpSeparate2() - Separate a Universal Resource Identifier into its
+ * components.
+ * httpStatus() - Return a short string describing a HTTP status code.
+ * cups_hstrerror() - hstrerror() emulation function for Solaris and others...
+ * http_copy_decode() - Copy and decode a URI.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include "string.h"
+
+#include "http.h"
+
+
+/*
+ * Local functions...
+ */
+
+static const char *http_copy_decode(char *dst, const char *src,
+ int dstsize, const char *term);
+
+
+/*
+ * 'httpSeparate()' - Separate a Universal Resource Identifier into its
+ * components.
+ */
+
+void
+httpSeparate(const char *uri, /* I - Universal Resource Identifier */
+ char *method, /* O - Method [32] (http, https, etc.) */
+ char *username, /* O - Username [1024] */
+ char *host, /* O - Hostname [1024] */
+ int *port, /* O - Port number to use */
+ char *resource) /* O - Resource/filename [1024] */
+{
+ httpSeparate2(uri, method, 32, username, HTTP_MAX_URI, host, HTTP_MAX_URI,
+ port, resource, HTTP_MAX_URI);
+}
+
+
+/*
+ * 'httpSeparate2()' - Separate a Universal Resource Identifier into its
+ * components.
+ */
+
+void
+httpSeparate2(const char *uri, /* I - Universal Resource Identifier */
+ char *method, /* O - Method (http, https, etc.) */
+ int methodlen, /* I - Size of method buffer */
+ char *username, /* O - Username */
+ int usernamelen, /* I - Size of username buffer */
+ char *host, /* O - Hostname */
+ int hostlen, /* I - Size of hostname buffer */
+ int *port, /* O - Port number to use */
+ char *resource, /* O - Resource/filename */
+ int resourcelen) /* I - Size of resource buffer */
+{
+ char *ptr; /* Pointer into string... */
+ const char *atsign, /* @ sign */
+ *slash; /* Separator */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (uri == NULL || method == NULL || username == NULL || host == NULL ||
+ port == NULL || resource == NULL)
+ return;
+
+ /*
+ * Grab the method portion of the URI...
+ */
+
+ if (strncmp(uri, "//", 2) == 0)
+ {
+ /*
+ * Workaround for HP IPP client bug...
+ */
+
+ strlcpy(method, "ipp", methodlen);
+ }
+ else
+ {
+ /*
+ * Standard URI with method...
+ */
+
+ uri = http_copy_decode(host, uri, hostlen, ":");
+
+ if (*uri == ':')
+ uri ++;
+
+ /*
+ * If the method contains a period or slash, then it's probably
+ * hostname/filename...
+ */
+
+ if (strchr(host, '.') != NULL || strchr(host, '/') != NULL || *uri == '\0')
+ {
+ if ((ptr = strchr(host, '/')) != NULL)
+ {
+ strlcpy(resource, ptr, resourcelen);
+ *ptr = '\0';
+ }
+ else
+ resource[0] = '\0';
+
+ if (isdigit(*uri & 255))
+ {
+ /*
+ * OK, we have "hostname:port[/resource]"...
+ */
+
+ *port = strtol(uri, (char **)&uri, 10);
+
+ if (*uri == '/')
+ strlcpy(resource, uri, resourcelen);
+ }
+ else
+ *port = 631;
+
+ strlcpy(method, "http", methodlen);
+ username[0] = '\0';
+ return;
+ }
+ else
+ strlcpy(method, host, methodlen);
+ }
+
+ /*
+ * If the method starts with less than 2 slashes then it is a local resource...
+ */
+
+ if (strncmp(uri, "//", 2) != 0)
+ {
+ strlcpy(resource, uri, resourcelen);
+
+ username[0] = '\0';
+ host[0] = '\0';
+ *port = 0;
+ return;
+ }
+
+ /*
+ * Grab the username, if any...
+ */
+
+ uri += 2;
+
+ if ((slash = strchr(uri, '/')) == NULL)
+ slash = uri + strlen(uri);
+
+ if ((atsign = strchr(uri, '@')) != NULL && atsign < slash)
+ {
+ /*
+ * Got a username:password combo...
+ */
+
+ uri = http_copy_decode(username, uri, usernamelen, "@") + 1;
+ }
+ else
+ username[0] = '\0';
+
+ /*
+ * Grab the hostname...
+ */
+
+ uri = http_copy_decode(host, uri, hostlen, ":/");
+
+ if (*uri != ':')
+ {
+ if (strcasecmp(method, "http") == 0)
+ *port = 80;
+ else if (strcasecmp(method, "https") == 0)
+ *port = 443;
+ else if (strcasecmp(method, "ipp") == 0)
+ *port = 631;
+ else if (strcasecmp(method, "lpd") == 0)
+ *port = 515;
+ else if (strcasecmp(method, "socket") == 0) /* Not registered yet... */
+ *port = 9100;
+ else
+ *port = 0;
+ }
+ else
+ {
+ /*
+ * Parse port number...
+ */
+
+ *port = strtol(uri + 1, (char **)&uri, 10);
+ }
+
+ if (*uri == '\0')
+ {
+ /*
+ * Hostname but no port or path...
+ */
+
+ resource[0] = '/';
+ resource[1] = '\0';
+ return;
+ }
+
+ /*
+ * The remaining portion is the resource string...
+ */
+
+ http_copy_decode(resource, uri, resourcelen, "");
+}
+
+
+/*
+ * 'httpStatus()' - Return a short string describing a HTTP status code.
+ */
+
+const char * /* O - String or NULL */
+httpStatus(http_status_t status) /* I - HTTP status code */
+{
+ switch (status)
+ {
+ case HTTP_CONTINUE :
+ return ("Continue");
+ case HTTP_SWITCHING_PROTOCOLS :
+ return ("Switching Protocols");
+ case HTTP_OK :
+ return ("OK");
+ case HTTP_CREATED :
+ return ("Created");
+ case HTTP_ACCEPTED :
+ return ("Accepted");
+ case HTTP_NO_CONTENT :
+ return ("No Content");
+ case HTTP_NOT_MODIFIED :
+ return ("Not Modified");
+ case HTTP_BAD_REQUEST :
+ return ("Bad Request");
+ case HTTP_UNAUTHORIZED :
+ return ("Unauthorized");
+ case HTTP_FORBIDDEN :
+ return ("Forbidden");
+ case HTTP_NOT_FOUND :
+ return ("Not Found");
+ case HTTP_REQUEST_TOO_LARGE :
+ return ("Request Entity Too Large");
+ case HTTP_URI_TOO_LONG :
+ return ("URI Too Long");
+ case HTTP_UPGRADE_REQUIRED :
+ return ("Upgrade Required");
+ case HTTP_NOT_IMPLEMENTED :
+ return ("Not Implemented");
+ case HTTP_NOT_SUPPORTED :
+ return ("Not Supported");
+ default :
+ return ("Unknown");
+ }
+}
+
+
+#ifndef HAVE_HSTRERROR
+/*
+ * 'cups_hstrerror()' - hstrerror() emulation function for Solaris and others...
+ */
+
+const char * /* O - Error string */
+cups_hstrerror(int error) /* I - Error number */
+{
+ static const char * const errors[] = /* Error strings */
+ {
+ "OK",
+ "Host not found.",
+ "Try again.",
+ "Unrecoverable lookup error.",
+ "No data associated with name."
+ };
+
+
+ if (error < 0 || error > 4)
+ return ("Unknown hostname lookup error.");
+ else
+ return (errors[error]);
+}
+#endif /* !HAVE_HSTRERROR */
+
+
+/*
+ * 'http_copy_decode()' - Copy and decode a URI.
+ */
+
+static const char * /* O - New source pointer */
+http_copy_decode(char *dst, /* O - Destination buffer */
+ const char *src, /* I - Source pointer */
+ int dstsize, /* I - Destination size */
+ const char *term) /* I - Terminating characters */
+{
+ char *ptr, /* Pointer into buffer */
+ *end; /* End of buffer */
+ int quoted; /* Quoted character */
+
+
+ /*
+ * Copy the src to the destination until we hit a terminating character
+ * or the end of the string.
+ */
+
+ for (ptr = dst, end = dst + dstsize - 1; *src && !strchr(term, *src); src ++)
+ if (ptr < end)
+ {
+ if (*src == '%' && isxdigit(src[1] & 255) && isxdigit(src[2] & 255))
+ {
+ /*
+ * Grab a hex-encoded character...
+ */
+
+ src ++;
+ if (isalpha(*src))
+ quoted = (tolower(*src) - 'a' + 10) << 4;
+ else
+ quoted = (*src - '0') << 4;
+
+ src ++;
+ if (isalpha(*src))
+ quoted |= tolower(*src) - 'a' + 10;
+ else
+ quoted |= *src - '0';
+
+ *ptr++ = quoted;
+ }
+ else
+ *ptr++ = *src;
+ }
+
+ *ptr = '\0';
+
+ return (src);
+}
+
+
+/*
+ * End of "$Id: http-support.c 148 2006-04-25 16:54:17Z njacobs $"
+ */
diff --git a/usr/src/lib/print/libhttp-core/common/http.c b/usr/src/lib/print/libhttp-core/common/http.c
new file mode 100644
index 0000000000..83a0790022
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/common/http.c
@@ -0,0 +1,2569 @@
+/*
+ * "$Id: http.c 148 2006-04-25 16:54:17Z njacobs $"
+ *
+ * HTTP routines for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2005 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ *
+ * Contents:
+ *
+ * httpInitialize() - Initialize the HTTP interface library and set the
+ * default HTTP proxy (if any).
+ * httpCheck() - Check to see if there is a pending response from
+ * the server.
+ * httpClearCookie() - Clear the cookie value(s).
+ * httpClose() - Close an HTTP connection...
+ * httpConnect() - Connect to a HTTP server.
+ * httpConnectEncrypt() - Connect to a HTTP server using encryption.
+ * httpEncryption() - Set the required encryption on the link.
+ * httpReconnect() - Reconnect to a HTTP server...
+ * httpGetSubField() - Get a sub-field value.
+ * httpSetField() - Set the value of an HTTP header.
+ * httpDelete() - Send a DELETE request to the server.
+ * httpGet() - Send a GET request to the server.
+ * httpHead() - Send a HEAD request to the server.
+ * httpOptions() - Send an OPTIONS request to the server.
+ * httpPost() - Send a POST request to the server.
+ * httpPut() - Send a PUT request to the server.
+ * httpTrace() - Send an TRACE request to the server.
+ * httpFlush() - Flush data from a HTTP connection.
+ * httpRead() - Read data from a HTTP connection.
+ * httpSetCookie() - Set the cookie value(s)...
+ * httpWait() - Wait for data available on a connection.
+ * httpWrite() - Write data to a HTTP connection.
+ * httpGets() - Get a line of text from a HTTP connection.
+ * httpPrintf() - Print a formatted string to a HTTP connection.
+ * httpGetDateString() - Get a formatted date/time string from a time value.
+ * httpGetDateTime() - Get a time value from a formatted date/time string.
+ * httpUpdate() - Update the current HTTP state for incoming data.
+ * httpDecode64() - Base64-decode a string.
+ * httpDecode64_2() - Base64-decode a string.
+ * httpEncode64() - Base64-encode a string.
+ * httpEncode64_2() - Base64-encode a string.
+ * httpGetLength() - Get the amount of data remaining from the
+ * content-length or transfer-encoding fields.
+ * http_field() - Return the field index for a field name.
+ * http_send() - Send a request with all fields and the trailing
+ * blank line.
+ * http_wait() - Wait for data available on a connection.
+ * http_upgrade() - Force upgrade to TLS encryption.
+ * http_setup_ssl() - Set up SSL/TLS on a connection.
+ * http_shutdown_ssl() - Shut down SSL/TLS on a connection.
+ * http_read_ssl() - Read from a SSL/TLS connection.
+ * http_write_ssl() - Write to a SSL/TLS connection.
+ * CDSAReadFunc() - Read function for CDSA decryption code.
+ * CDSAWriteFunc() - Write function for CDSA encryption code.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Include necessary headers...
+ */
+
+#include "http-private.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include "string.h"
+#include <fcntl.h>
+#include <errno.h>
+
+#include "http.h"
+#include "debug.h"
+
+#ifndef WIN32
+# include <signal.h>
+# include <sys/time.h>
+# include <sys/resource.h>
+#endif /* !WIN32 */
+
+
+/*
+ * Some operating systems have done away with the Fxxxx constants for
+ * the fcntl() call; this works around that "feature"...
+ */
+
+#ifndef FNONBLK
+# define FNONBLK O_NONBLOCK
+#endif /* !FNONBLK */
+
+
+/*
+ * Local functions...
+ */
+
+static http_field_t http_field(const char *name);
+static int http_send(http_t *http, http_state_t request,
+ const char *uri);
+static int http_wait(http_t *http, int msec);
+#ifdef HAVE_SSL
+static int http_upgrade(http_t *http);
+static int http_setup_ssl(http_t *http);
+static void http_shutdown_ssl(http_t *http);
+static int http_read_ssl(http_t *http, char *buf, int len);
+static int http_write_ssl(http_t *http, const char *buf, int len);
+# ifdef HAVE_CDSASSL
+static OSStatus CDSAReadFunc(SSLConnectionRef connection, void *data, size_t *dataLength);
+static OSStatus CDSAWriteFunc(SSLConnectionRef connection, const void *data, size_t *dataLength);
+# endif /* HAVE_CDSASSL */
+#endif /* HAVE_SSL */
+
+
+/*
+ * Local globals...
+ */
+
+static const char * const http_fields[] =
+ {
+ "Accept-Language",
+ "Accept-Ranges",
+ "Authorization",
+ "Connection",
+ "Content-Encoding",
+ "Content-Language",
+ "Content-Length",
+ "Content-Location",
+ "Content-MD5",
+ "Content-Range",
+ "Content-Type",
+ "Content-Version",
+ "Date",
+ "Host",
+ "If-Modified-Since",
+ "If-Unmodified-since",
+ "Keep-Alive",
+ "Last-Modified",
+ "Link",
+ "Location",
+ "Range",
+ "Referer",
+ "Retry-After",
+ "Transfer-Encoding",
+ "Upgrade",
+ "User-Agent",
+ "WWW-Authenticate"
+ };
+static const char * const days[7] =
+ {
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat"
+ };
+static const char * const months[12] =
+ {
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+ };
+
+void
+httpDumpData(FILE *fp, char *tag, char *buffer, int bytes)
+{
+ int i, j, ch;
+
+ fprintf(fp, "%s %d(0x%x) bytes...\n", tag, bytes, bytes);
+ for (i = 0; i < bytes; i += 16) {
+ fprintf(fp, "%s ", (tag ? tag : ""));
+
+ for (j = 0; j < 16 && (i + j) < bytes; j ++)
+ fprintf(fp, " %02X", buffer[i + j] & 255);
+
+ while (j < 16) {
+ fprintf(fp, " ");
+ j++;
+ }
+
+ fprintf(fp, " ");
+ for (j = 0; j < 16 && (i + j) < bytes; j ++) {
+ ch = buffer[i + j] & 255;
+ if (ch < ' ' || ch == 127)
+ ch = '.';
+ putc(ch, fp);
+ }
+ putc('\n', fp);
+ }
+}
+
+
+/*
+ * 'httpInitialize()' - Initialize the HTTP interface library and set the
+ * default HTTP proxy (if any).
+ */
+
+void
+httpInitialize(void)
+{
+#ifdef HAVE_LIBSSL
+# ifndef WIN32
+ struct timeval curtime; /* Current time in microseconds */
+# endif /* !WIN32 */
+ int i; /* Looping var */
+ unsigned char data[1024]; /* Seed data */
+#endif /* HAVE_LIBSSL */
+
+#ifdef WIN32
+ WSADATA winsockdata; /* WinSock data */
+ static int initialized = 0; /* Has WinSock been initialized? */
+
+
+ if (!initialized)
+ WSAStartup(MAKEWORD(1,1), &winsockdata);
+#elif defined(HAVE_SIGSET)
+ sigset(SIGPIPE, SIG_IGN);
+#elif defined(HAVE_SIGACTION)
+ struct sigaction action; /* POSIX sigaction data */
+
+
+ /*
+ * Ignore SIGPIPE signals...
+ */
+
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &action, NULL);
+#else
+ signal(SIGPIPE, SIG_IGN);
+#endif /* WIN32 */
+
+#ifdef HAVE_GNUTLS
+ gnutls_global_init();
+#endif /* HAVE_GNUTLS */
+
+#ifdef HAVE_LIBSSL
+ SSL_load_error_strings();
+ SSL_library_init();
+
+ /*
+ * Using the current time is a dubious random seed, but on some systems
+ * it is the best we can do (on others, this seed isn't even used...)
+ */
+
+#ifdef WIN32
+#else
+ gettimeofday(&curtime, NULL);
+ srand(curtime.tv_sec + curtime.tv_usec);
+#endif /* WIN32 */
+
+ for (i = 0; i < sizeof(data); i ++)
+ data[i] = rand(); /* Yes, this is a poor source of random data... */
+
+ RAND_seed(&data, sizeof(data));
+#endif /* HAVE_LIBSSL */
+}
+
+
+/*
+ * 'httpCheck()' - Check to see if there is a pending response from the server.
+ */
+
+int /* O - 0 = no data, 1 = data available */
+httpCheck(http_t *http) /* I - HTTP connection */
+{
+ return (httpWait(http, 0));
+}
+
+
+/*
+ * 'httpClearCookie()' - Clear the cookie value(s).
+ */
+
+void
+httpClearCookie(http_t *http) /* I - Connection */
+{
+ if (!http)
+ return;
+
+ if (http->cookie)
+ {
+ free(http->cookie);
+ http->cookie = NULL;
+ }
+}
+
+
+/*
+ * 'httpClose()' - Close an HTTP connection...
+ */
+
+void
+httpClose(http_t *http) /* I - Connection to close */
+{
+ DEBUG_printf(("httpClose(http=%p)\n", http));
+
+ if (!http)
+ return;
+
+ if (http->input_set)
+ free(http->input_set);
+
+ if (http->cookie)
+ free(http->cookie);
+
+#ifdef HAVE_SSL
+ if (http->tls)
+ http_shutdown_ssl(http);
+#endif /* HAVE_SSL */
+
+#ifdef WIN32
+ closesocket(http->fd);
+#else
+ close(http->fd);
+#endif /* WIN32 */
+
+ free(http);
+}
+
+
+/*
+ * 'httpConnect()' - Connect to a HTTP server.
+ */
+
+http_t * /* O - New HTTP connection */
+httpConnect(const char *host, /* I - Host to connect to */
+ int port) /* I - Port number */
+{
+ http_encryption_t encrypt; /* Type of encryption to use */
+
+
+ /*
+ * Set the default encryption status...
+ */
+
+ if (port == 443)
+ encrypt = HTTP_ENCRYPT_ALWAYS;
+ else
+ encrypt = HTTP_ENCRYPT_IF_REQUESTED;
+
+ return (httpConnectEncrypt(host, port, encrypt));
+}
+
+
+/*
+ * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption.
+ */
+
+http_t * /* O - New HTTP connection */
+httpConnectEncrypt(const char *host, /* I - Host to connect to */
+ int port, /* I - Port number */
+ http_encryption_t encrypt)
+ /* I - Type of encryption to use */
+{
+ int i; /* Looping var */
+ http_t *http; /* New HTTP connection */
+ struct hostent *hostaddr; /* Host address data */
+
+
+ DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encrypt=%d)\n",
+ host ? host : "(null)", port, encrypt));
+
+ if (!host)
+ return (NULL);
+
+ httpInitialize();
+
+ /*
+ * Lookup the host...
+ */
+
+ if ((hostaddr = httpGetHostByName(host)) == NULL)
+ {
+ /*
+ * This hack to make users that don't have a localhost entry in
+ * their hosts file or DNS happy...
+ */
+
+ if (strcasecmp(host, "localhost") != 0)
+ return (NULL);
+ else if ((hostaddr = httpGetHostByName("127.0.0.1")) == NULL)
+ return (NULL);
+ }
+
+ /*
+ * Verify that it is an IPv4, IPv6, or domain address...
+ */
+
+ if ((hostaddr->h_addrtype != AF_INET || hostaddr->h_length != 4)
+#ifdef AF_INET6
+ && (hostaddr->h_addrtype != AF_INET6 || hostaddr->h_length != 16)
+#endif /* AF_INET6 */
+#ifdef AF_LOCAL
+ && (hostaddr->h_addrtype != AF_LOCAL)
+#endif /* AF_LOCAL */
+ )
+ return (NULL);
+
+ /*
+ * Allocate memory for the structure...
+ */
+
+ http = calloc(sizeof(http_t), 1);
+ if (http == NULL)
+ return (NULL);
+
+ http->version = HTTP_1_1;
+ http->blocking = 1;
+ http->activity = time(NULL);
+ http->fd = -1;
+
+ /*
+ * Set the encryption status...
+ */
+
+ if (port == 443) /* Always use encryption for https */
+ http->encryption = HTTP_ENCRYPT_ALWAYS;
+ else
+ http->encryption = encrypt;
+
+ /*
+ * Loop through the addresses we have until one of them connects...
+ */
+
+ strlcpy(http->hostname, host, sizeof(http->hostname));
+
+ for (i = 0; hostaddr->h_addr_list[i]; i ++)
+ {
+ /*
+ * Load the address...
+ */
+
+ httpAddrLoad(hostaddr, port, i, &(http->hostaddr));
+
+ /*
+ * Connect to the remote system...
+ */
+
+ if (!httpReconnect(http))
+ return (http);
+ }
+
+ /*
+ * Could not connect to any known address - bail out!
+ */
+
+ free(http);
+ return (NULL);
+}
+
+
+/*
+ * 'httpEncryption()' - Set the required encryption on the link.
+ */
+
+int /* O - -1 on error, 0 on success */
+httpEncryption(http_t *http, /* I - HTTP data */
+ http_encryption_t e) /* I - New encryption preference */
+{
+ DEBUG_printf(("httpEncryption(http=%p, e=%d)\n", http, e));
+
+#ifdef HAVE_SSL
+ if (!http)
+ return (0);
+
+ http->encryption = e;
+
+ if ((http->encryption == HTTP_ENCRYPT_ALWAYS && !http->tls) ||
+ (http->encryption == HTTP_ENCRYPT_NEVER && http->tls))
+ return (httpReconnect(http));
+ else if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
+ return (http_upgrade(http));
+ else
+ return (0);
+#else
+ if (e == HTTP_ENCRYPT_ALWAYS || e == HTTP_ENCRYPT_REQUIRED)
+ return (-1);
+ else
+ return (0);
+#endif /* HAVE_SSL */
+}
+
+
+/*
+ * 'httpReconnect()' - Reconnect to a HTTP server...
+ */
+
+int /* O - 0 on success, non-zero on failure */
+httpReconnect(http_t *http) /* I - HTTP data */
+{
+ int val; /* Socket option value */
+ int status; /* Connect status */
+
+
+ DEBUG_printf(("httpReconnect(http=%p)\n", http));
+
+ if (!http)
+ return (-1);
+
+#ifdef HAVE_SSL
+ if (http->tls)
+ http_shutdown_ssl(http);
+#endif /* HAVE_SSL */
+
+ /*
+ * Close any previously open socket...
+ */
+
+ if (http->fd >= 0)
+#ifdef WIN32
+ closesocket(http->fd);
+#else
+ close(http->fd);
+#endif /* WIN32 */
+
+ /*
+ * Create the socket and set options to allow reuse.
+ */
+
+ if ((http->fd = socket(http->hostaddr.addr.sa_family, SOCK_STREAM, 0)) < 0)
+ {
+#ifdef WIN32
+ http->error = WSAGetLastError();
+#else
+ http->error = errno;
+#endif /* WIN32 */
+ http->status = HTTP_ERROR;
+ return (-1);
+ }
+
+#ifdef FD_CLOEXEC
+ fcntl(http->fd, F_SETFD, FD_CLOEXEC); /* Close this socket when starting *
+ * other processes... */
+#endif /* FD_CLOEXEC */
+
+ val = 1;
+ setsockopt(http->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
+
+#ifdef SO_REUSEPORT
+ val = 1;
+ setsockopt(http->fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
+#endif /* SO_REUSEPORT */
+
+ /*
+ * Using TCP_NODELAY improves responsiveness, especially on systems
+ * with a slow loopback interface... Since we write large buffers
+ * when sending print files and requests, there shouldn't be any
+ * performance penalty for this...
+ */
+
+ val = 1;
+#ifdef WIN32
+ setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
+#else
+ setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
+#endif /* WIN32 */
+
+ /*
+ * Connect to the server...
+ */
+
+#ifdef AF_INET6
+ if (http->hostaddr.addr.sa_family == AF_INET6)
+ status = connect(http->fd, (struct sockaddr *)&(http->hostaddr),
+ sizeof(http->hostaddr.ipv6));
+ else
+#endif /* AF_INET6 */
+#ifdef AF_LOCAL
+ if (http->hostaddr.addr.sa_family == AF_LOCAL)
+ status = connect(http->fd, (struct sockaddr *)&(http->hostaddr),
+ SUN_LEN(&(http->hostaddr.un)));
+ else
+#endif /* AF_LOCAL */
+ status = connect(http->fd, (struct sockaddr *)&(http->hostaddr),
+ sizeof(http->hostaddr.ipv4));
+
+ if (status < 0)
+ {
+#ifdef WIN32
+ http->error = WSAGetLastError();
+#else
+ http->error = errno;
+#endif /* WIN32 */
+ http->status = HTTP_ERROR;
+
+#ifdef WIN32
+ closesocket(http->fd);
+#else
+ close(http->fd);
+#endif
+
+ http->fd = -1;
+
+ return (-1);
+ }
+
+ http->error = 0;
+ http->status = HTTP_CONTINUE;
+
+#ifdef HAVE_SSL
+ if (http->encryption == HTTP_ENCRYPT_ALWAYS)
+ {
+ /*
+ * Always do encryption via SSL.
+ */
+
+ if (http_setup_ssl(http) != 0)
+ {
+#ifdef WIN32
+ closesocket(http->fd);
+#else
+ close(http->fd);
+#endif /* WIN32 */
+
+ return (-1);
+ }
+ }
+ else if (http->encryption == HTTP_ENCRYPT_REQUIRED)
+ return (http_upgrade(http));
+#endif /* HAVE_SSL */
+
+ return (0);
+}
+
+
+/*
+ * 'httpGetSubField()' - Get a sub-field value.
+ */
+
+char * /* O - Value or NULL */
+httpGetSubField(http_t *http, /* I - HTTP data */
+ http_field_t field, /* I - Field index */
+ const char *name, /* I - Name of sub-field */
+ char *value) /* O - Value string */
+{
+ const char *fptr; /* Pointer into field */
+ char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */
+ *ptr; /* Pointer into string buffer */
+
+
+ DEBUG_printf(("httpGetSubField(http=%p, field=%d, name=\"%s\", value=%p)\n",
+ http, field, name, value));
+
+ if (http == NULL ||
+ field < HTTP_FIELD_ACCEPT_LANGUAGE ||
+ field > HTTP_FIELD_WWW_AUTHENTICATE ||
+ name == NULL || value == NULL)
+ return (NULL);
+
+ for (fptr = http->fields[field]; *fptr;)
+ {
+ /*
+ * Skip leading whitespace...
+ */
+
+ while (isspace(*fptr & 255))
+ fptr ++;
+
+ if (*fptr == ',')
+ {
+ fptr ++;
+ continue;
+ }
+
+ /*
+ * Get the sub-field name...
+ */
+
+ for (ptr = temp;
+ *fptr && *fptr != '=' && !isspace(*fptr & 255) && ptr < (temp + sizeof(temp) - 1);
+ *ptr++ = *fptr++);
+
+ *ptr = '\0';
+
+ DEBUG_printf(("httpGetSubField: name=\"%s\"\n", temp));
+
+ /*
+ * Skip trailing chars up to the '='...
+ */
+
+ while (isspace(*fptr & 255))
+ fptr ++;
+
+ if (!*fptr)
+ break;
+
+ if (*fptr != '=')
+ continue;
+
+ /*
+ * Skip = and leading whitespace...
+ */
+
+ fptr ++;
+
+ while (isspace(*fptr & 255))
+ fptr ++;
+
+ if (*fptr == '\"')
+ {
+ /*
+ * Read quoted string...
+ */
+
+ for (ptr = value, fptr ++;
+ *fptr && *fptr != '\"' && ptr < (value + HTTP_MAX_VALUE - 1);
+ *ptr++ = *fptr++);
+
+ *ptr = '\0';
+
+ while (*fptr && *fptr != '\"')
+ fptr ++;
+
+ if (*fptr)
+ fptr ++;
+ }
+ else
+ {
+ /*
+ * Read unquoted string...
+ */
+
+ for (ptr = value;
+ *fptr && !isspace(*fptr & 255) && *fptr != ',' && ptr < (value + HTTP_MAX_VALUE - 1);
+ *ptr++ = *fptr++);
+
+ *ptr = '\0';
+
+ while (*fptr && !isspace(*fptr & 255) && *fptr != ',')
+ fptr ++;
+ }
+
+ DEBUG_printf(("httpGetSubField: value=\"%s\"\n", value));
+
+ /*
+ * See if this is the one...
+ */
+
+ if (strcmp(name, temp) == 0)
+ return (value);
+ }
+
+ value[0] = '\0';
+
+ return (NULL);
+}
+
+
+/*
+ * 'httpSetField()' - Set the value of an HTTP header.
+ */
+
+void
+httpSetField(http_t *http, /* I - HTTP data */
+ http_field_t field, /* I - Field index */
+ const char *value) /* I - Value */
+{
+ if (http == NULL ||
+ field < HTTP_FIELD_ACCEPT_LANGUAGE ||
+ field > HTTP_FIELD_WWW_AUTHENTICATE ||
+ value == NULL)
+ return;
+
+ strlcpy(http->fields[field], value, HTTP_MAX_VALUE);
+}
+
+
+/*
+ * 'httpDelete()' - Send a DELETE request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpDelete(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI to delete */
+{
+ return (http_send(http, HTTP_DELETE, uri));
+}
+
+
+/*
+ * 'httpGet()' - Send a GET request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpGet(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI to get */
+{
+ return (http_send(http, HTTP_GET, uri));
+}
+
+
+/*
+ * 'httpHead()' - Send a HEAD request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpHead(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI for head */
+{
+ return (http_send(http, HTTP_HEAD, uri));
+}
+
+
+/*
+ * 'httpOptions()' - Send an OPTIONS request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpOptions(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI for options */
+{
+ return (http_send(http, HTTP_OPTIONS, uri));
+}
+
+
+/*
+ * 'httpPost()' - Send a POST request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpPost(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI for post */
+{
+ httpGetLength(http);
+
+ return (http_send(http, HTTP_POST, uri));
+}
+
+
+/*
+ * 'httpPut()' - Send a PUT request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpPut(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI to put */
+{
+ httpGetLength(http);
+
+ return (http_send(http, HTTP_PUT, uri));
+}
+
+
+/*
+ * 'httpTrace()' - Send an TRACE request to the server.
+ */
+
+int /* O - Status of call (0 = success) */
+httpTrace(http_t *http, /* I - HTTP data */
+ const char *uri) /* I - URI for trace */
+{
+ return (http_send(http, HTTP_TRACE, uri));
+}
+
+
+/*
+ * 'httpFlush()' - Flush data from a HTTP connection.
+ */
+
+void
+httpFlush(http_t *http) /* I - HTTP data */
+{
+ char buffer[8192]; /* Junk buffer */
+
+
+ DEBUG_printf(("httpFlush(http=%p), state=%d\n", http, http->state));
+
+ while (httpRead(http, buffer, sizeof(buffer)) > 0);
+}
+
+
+/*
+ * 'httpRead()' - Read data from a HTTP connection.
+ */
+
+int /* O - Number of bytes read */
+httpRead(http_t *http, /* I - HTTP data */
+ char *buffer, /* I - Buffer for data */
+ int length) /* I - Maximum number of bytes */
+{
+ int bytes; /* Bytes read */
+ char len[32]; /* Length string */
+
+
+ DEBUG_printf(("httpRead(http=%p, buffer=%p, length=%d)\n",
+ http, buffer, length));
+
+ if (http == NULL || buffer == NULL)
+ return (-1);
+
+ http->activity = time(NULL);
+
+ if (length <= 0)
+ return (0);
+
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED &&
+ http->data_remaining <= 0)
+ {
+ DEBUG_puts("httpRead: Getting chunk length...");
+
+ if (httpGets(len, sizeof(len), http) == NULL)
+ {
+ DEBUG_puts("httpRead: Could not get length!");
+ return (0);
+ }
+
+ http->data_remaining = strtol(len, NULL, 16);
+ if (http->data_remaining < 0)
+ {
+ DEBUG_puts("httpRead: Negative chunk length!");
+ return (0);
+ }
+ }
+
+ DEBUG_printf(("httpRead: data_remaining=%d\n", http->data_remaining));
+
+ if (http->data_remaining <= 0)
+ {
+ /*
+ * A zero-length chunk ends a transfer; unless we are reading POST
+ * data, go idle...
+ */
+
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED)
+ httpGets(len, sizeof(len), http);
+
+ if (http->state == HTTP_POST_RECV)
+ http->state ++;
+ else
+ http->state = HTTP_WAITING;
+
+ /*
+ * Prevent future reads for this request...
+ */
+
+ http->data_encoding = HTTP_ENCODE_LENGTH;
+
+ return (0);
+ }
+ else if (length > http->data_remaining)
+ length = http->data_remaining;
+
+ if (http->used == 0 && length <= 256)
+ {
+ /*
+ * Buffer small reads for better performance...
+ */
+
+ if (!http->blocking && !httpWait(http, 1000))
+ return (0);
+
+ if (http->data_remaining > sizeof(http->buffer))
+ bytes = sizeof(http->buffer);
+ else
+ bytes = http->data_remaining;
+
+#ifdef HAVE_SSL
+ if (http->tls)
+ bytes = http_read_ssl(http, http->buffer, bytes);
+ else
+#endif /* HAVE_SSL */
+ {
+ DEBUG_printf(("httpRead: reading %d bytes from socket into buffer...\n",
+ bytes));
+
+ bytes = recv(http->fd, http->buffer, bytes, 0);
+
+ DEBUG_printf(("httpRead: read %d bytes from socket into buffer...\n",
+ bytes));
+#ifdef DEBUG_HTTP
+ httpDumpData(stdout, "httpRead:", http->buffer, bytes);
+#endif
+ }
+
+ if (bytes > 0)
+ http->used = bytes;
+ else if (bytes < 0)
+ {
+#ifdef WIN32
+ http->error = WSAGetLastError();
+ return (-1);
+#else
+ if (errno != EINTR)
+ {
+ http->error = errno;
+ return (-1);
+ }
+#endif /* WIN32 */
+ }
+ else
+ {
+ http->error = EPIPE;
+ return (0);
+ }
+ }
+
+ if (http->used > 0)
+ {
+ if (length > http->used)
+ length = http->used;
+
+ bytes = length;
+
+ DEBUG_printf(("httpRead: grabbing %d bytes from input buffer...\n", bytes));
+
+ memcpy(buffer, http->buffer, length);
+ http->used -= length;
+
+ if (http->used > 0)
+ memmove(http->buffer, http->buffer + length, http->used);
+ }
+#ifdef HAVE_SSL
+ else if (http->tls)
+ {
+ if (!http->blocking && !httpWait(http, 1000))
+ return (0);
+
+ bytes = http_read_ssl(http, buffer, length);
+ }
+#endif /* HAVE_SSL */
+ else
+ {
+ if (!http->blocking && !httpWait(http, 1000))
+ return (0);
+
+ DEBUG_printf(("httpRead: reading %d bytes from socket...\n", length));
+
+ while ((bytes = recv(http->fd, buffer, length, 0)) < 0)
+ if (errno != EINTR)
+ break;
+ DEBUG_printf(("httpRead: read %d bytes from socket...\n", bytes));
+ }
+#ifdef DEBUG_HTTP
+ httpDumpData(stdout, "httpRead:", buffer, bytes);
+#endif
+
+ if (bytes > 0)
+ http->data_remaining -= bytes;
+ else if (bytes < 0)
+ {
+#ifdef WIN32
+ http->error = WSAGetLastError();
+#else
+ if (errno == EINTR)
+ bytes = 0;
+ else
+ http->error = errno;
+#endif /* WIN32 */
+ }
+ else
+ {
+ http->error = EPIPE;
+ return (0);
+ }
+
+ if (http->data_remaining == 0)
+ {
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED)
+ httpGets(len, sizeof(len), http);
+
+ if (http->data_encoding != HTTP_ENCODE_CHUNKED)
+ {
+ if (http->state == HTTP_POST_RECV)
+ http->state ++;
+ else
+ http->state = HTTP_WAITING;
+ }
+ }
+
+ return (bytes);
+}
+
+
+/*
+ * 'httpSetCookie()' - Set the cookie value(s)...
+ */
+
+void
+httpSetCookie(http_t *http, /* I - Connection */
+ const char *cookie) /* I - Cookie string */
+{
+ if (!http)
+ return;
+
+ if (http->cookie)
+ free(http->cookie);
+
+ if (cookie)
+ http->cookie = strdup(cookie);
+ else
+ http->cookie = NULL;
+}
+
+
+/*
+ * 'httpWait()' - Wait for data available on a connection.
+ */
+
+int /* O - 1 if data is available, 0 otherwise */
+httpWait(http_t *http, /* I - HTTP data */
+ int msec) /* I - Milliseconds to wait */
+{
+ /*
+ * First see if there is data in the buffer...
+ */
+
+ if (http == NULL)
+ return (0);
+
+ if (http->used)
+ return (1);
+
+ /*
+ * If not, check the SSL/TLS buffers and do a select() on the connection...
+ */
+
+ return (http_wait(http, msec));
+}
+
+
+/*
+ * 'httpWrite()' - Write data to a HTTP connection.
+ */
+
+int /* O - Number of bytes written */
+httpWrite(http_t *http, /* I - HTTP data */
+ const char *buffer, /* I - Buffer for data */
+ int length) /* I - Number of bytes to write */
+{
+ int tbytes, /* Total bytes sent */
+ bytes; /* Bytes sent */
+
+
+ if (http == NULL || buffer == NULL)
+ return (-1);
+
+ http->activity = time(NULL);
+
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED)
+ {
+ if (httpPrintf(http, "%x\r\n", length) < 0)
+ return (-1);
+
+ if (length == 0)
+ {
+ /*
+ * A zero-length chunk ends a transfer; unless we are sending POST
+ * or PUT data, go idle...
+ */
+
+ DEBUG_printf(("httpWrite: changing states from %d", http->state));
+
+ if (http->state == HTTP_POST_RECV)
+ http->state ++;
+ else if (http->state == HTTP_PUT_RECV)
+ http->state = HTTP_STATUS;
+ else
+ http->state = HTTP_WAITING;
+ DEBUG_printf((" to %d\n", http->state));
+
+ if (httpPrintf(http, "\r\n") < 0)
+ return (-1);
+
+ return (0);
+ }
+ }
+
+ tbytes = 0;
+
+ while (length > 0)
+ {
+#ifdef HAVE_SSL
+ if (http->tls)
+ bytes = http_write_ssl(http, buffer, length);
+ else
+#endif /* HAVE_SSL */
+ bytes = send(http->fd, buffer, length, 0);
+
+#ifdef DEBUG_HTTP
+ if (bytes >= 0)
+ httpDumpData(stdout, "httpWrite:", buffer, bytes);
+#endif /* DEBUG */
+
+
+ if (bytes < 0)
+ {
+#ifdef WIN32
+ if (WSAGetLastError() != http->error)
+ {
+ http->error = WSAGetLastError();
+ continue;
+ }
+#else
+ if (errno == EINTR)
+ continue;
+ else if (errno != http->error && errno != ECONNRESET)
+ {
+ http->error = errno;
+ continue;
+ }
+#endif /* WIN32 */
+
+ DEBUG_puts("httpWrite: error writing data...\n");
+
+ return (-1);
+ }
+
+ buffer += bytes;
+ tbytes += bytes;
+ length -= bytes;
+ if (http->data_encoding == HTTP_ENCODE_LENGTH)
+ http->data_remaining -= bytes;
+ }
+
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED)
+ if (httpPrintf(http, "\r\n") < 0)
+ return (-1);
+
+ if (http->data_remaining == 0 && http->data_encoding == HTTP_ENCODE_LENGTH)
+ {
+ /*
+ * Finished with the transfer; unless we are sending POST or PUT
+ * data, go idle...
+ */
+
+ DEBUG_printf(("httpWrite: changing states from %d", http->state));
+
+ if (http->state == HTTP_POST_RECV)
+ http->state ++;
+ else if (http->state == HTTP_PUT_RECV)
+ http->state = HTTP_STATUS;
+ else
+ http->state = HTTP_WAITING;
+
+ DEBUG_printf((" to %d\n", http->state));
+ }
+
+ return (tbytes);
+}
+
+
+/*
+ * 'httpGets()' - Get a line of text from a HTTP connection.
+ */
+
+char * /* O - Line or NULL */
+httpGets(char *line, /* I - Line to read into */
+ int length, /* I - Max length of buffer */
+ http_t *http) /* I - HTTP data */
+{
+ char *lineptr, /* Pointer into line */
+ *bufptr, /* Pointer into input buffer */
+ *bufend; /* Pointer to end of buffer */
+ int bytes; /* Number of bytes read */
+
+
+ DEBUG_printf(("httpGets(line=%p, length=%d, http=%p)\n", line, length, http));
+
+ if (http == NULL || line == NULL)
+ return (NULL);
+
+ /*
+ * Pre-scan the buffer and see if there is a newline in there...
+ */
+
+#ifdef WIN32
+ WSASetLastError(0);
+#else
+ errno = 0;
+#endif /* WIN32 */
+
+ do
+ {
+ bufptr = http->buffer;
+ bufend = http->buffer + http->used;
+
+ while (bufptr < bufend)
+ if (*bufptr == 0x0a)
+ break;
+ else
+ bufptr ++;
+
+ if (bufptr >= bufend && http->used < HTTP_MAX_BUFFER)
+ {
+ /*
+ * No newline; see if there is more data to be read...
+ */
+
+ if (!http->blocking && !http_wait(http, 1000))
+ return (NULL);
+
+#ifdef HAVE_SSL
+ if (http->tls)
+ bytes = http_read_ssl(http, bufend, HTTP_MAX_BUFFER - http->used);
+ else
+#endif /* HAVE_SSL */
+ bytes = recv(http->fd, bufend, HTTP_MAX_BUFFER - http->used, 0);
+
+ DEBUG_printf(("httpGets: read %d bytes...\n", bytes));
+#ifdef DEBUG_HTTP
+ httpDumpData(stdout, "httpGets:", bufend, bytes);
+#endif
+
+ if (bytes < 0)
+ {
+ /*
+ * Nope, can't get a line this time...
+ */
+
+#ifdef WIN32
+ if (WSAGetLastError() != http->error)
+ {
+ http->error = WSAGetLastError();
+ continue;
+ }
+
+ DEBUG_printf(("httpGets: recv() error %d!\n", WSAGetLastError()));
+#else
+ DEBUG_printf(("httpGets: recv() error %d!\n", errno));
+
+ if (errno == EINTR)
+ continue;
+ else if (errno != http->error)
+ {
+ http->error = errno;
+ continue;
+ }
+#endif /* WIN32 */
+
+ return (NULL);
+ }
+ else if (bytes == 0)
+ {
+ http->error = EPIPE;
+
+ return (NULL);
+ }
+
+ /*
+ * Yup, update the amount used and the end pointer...
+ */
+
+ http->used += bytes;
+ bufend += bytes;
+ bufptr = bufend;
+ }
+ }
+ while (bufptr >= bufend && http->used < HTTP_MAX_BUFFER);
+
+ http->activity = time(NULL);
+
+ /*
+ * Read a line from the buffer...
+ */
+
+ lineptr = line;
+ bufptr = http->buffer;
+ bytes = 0;
+ length --;
+
+ while (bufptr < bufend && bytes < length)
+ {
+ bytes ++;
+
+ if (*bufptr == 0x0a)
+ {
+ bufptr ++;
+ break;
+ }
+ else if (*bufptr == 0x0d)
+ bufptr ++;
+ else
+ *lineptr++ = *bufptr++;
+ }
+
+ if (bytes > 0)
+ {
+ *lineptr = '\0';
+
+ http->used -= bytes;
+ if (http->used > 0)
+ memmove(http->buffer, bufptr, http->used);
+
+ DEBUG_printf(("httpGets: Returning \"%s\"\n", line));
+ return (line);
+ }
+
+ DEBUG_puts("httpGets: No new line available!");
+
+ return (NULL);
+}
+
+
+/*
+ * 'httpPrintf()' - Print a formatted string to a HTTP connection.
+ */
+
+int /* O - Number of bytes written */
+httpPrintf(http_t *http, /* I - HTTP data */
+ const char *format, /* I - printf-style format string */
+ ...) /* I - Additional args as needed */
+{
+ int bytes, /* Number of bytes to write */
+ nbytes, /* Number of bytes written */
+ tbytes; /* Number of bytes all together */
+ char buf[HTTP_MAX_BUFFER], /* Buffer for formatted string */
+ *bufptr; /* Pointer into buffer */
+ va_list ap; /* Variable argument pointer */
+
+
+ DEBUG_printf(("httpPrintf: httpPrintf(http=%p, format=\"%s\", ...)\n", http, format));
+
+ va_start(ap, format);
+ bytes = vsnprintf(buf, sizeof(buf), format, ap);
+ va_end(ap);
+
+ DEBUG_printf(("httpPrintf: %s", buf));
+
+ for (tbytes = 0, bufptr = buf; tbytes < bytes; tbytes += nbytes, bufptr += nbytes)
+ {
+#ifdef HAVE_SSL
+ if (http->tls)
+ nbytes = http_write_ssl(http, bufptr, bytes - tbytes);
+ else
+#endif /* HAVE_SSL */
+ nbytes = send(http->fd, bufptr, bytes - tbytes, 0);
+
+#ifdef DEBUG_HTTP
+ if (nbytes >= 0)
+ httpDumpData(stdout, "httpPrintf:", bufptr, nbytes);
+#endif
+
+ if (nbytes < 0)
+ {
+ nbytes = 0;
+
+#ifdef WIN32
+ if (WSAGetLastError() != http->error)
+ {
+ http->error = WSAGetLastError();
+ continue;
+ }
+#else
+ if (errno == EINTR)
+ continue;
+ else if (errno != http->error)
+ {
+ http->error = errno;
+ continue;
+ }
+#endif /* WIN32 */
+
+ return (-1);
+ }
+ }
+
+ return (bytes);
+}
+
+
+/*
+ * 'httpGetDateString()' - Get a formatted date/time string from a time value.
+ */
+
+const char * /* O - Date/time string */
+httpGetDateString(time_t t) /* I - UNIX time */
+{
+ struct tm *tdate;
+ static char datetime[256];
+
+
+ tdate = gmtime(&t);
+ snprintf(datetime, sizeof(datetime), "%s, %02d %s %d %02d:%02d:%02d GMT",
+ days[tdate->tm_wday], tdate->tm_mday, months[tdate->tm_mon],
+ tdate->tm_year + 1900, tdate->tm_hour, tdate->tm_min, tdate->tm_sec);
+
+ return (datetime);
+}
+
+
+/*
+ * 'httpGetDateTime()' - Get a time value from a formatted date/time string.
+ */
+
+time_t /* O - UNIX time */
+httpGetDateTime(const char *s) /* I - Date/time string */
+{
+ int i; /* Looping var */
+ struct tm tdate; /* Time/date structure */
+ char mon[16]; /* Abbreviated month name */
+ int day, year; /* Day of month and year */
+ int hour, min, sec; /* Time */
+
+
+ if (sscanf(s, "%*s%d%15s%d%d:%d:%d", &day, mon, &year, &hour, &min, &sec) < 6)
+ return (0);
+
+ for (i = 0; i < 12; i ++)
+ if (strcasecmp(mon, months[i]) == 0)
+ break;
+
+ if (i >= 12)
+ return (0);
+
+ tdate.tm_mon = i;
+ tdate.tm_mday = day;
+ tdate.tm_year = year - 1900;
+ tdate.tm_hour = hour;
+ tdate.tm_min = min;
+ tdate.tm_sec = sec;
+ tdate.tm_isdst = 0;
+
+ return (mktime(&tdate));
+}
+
+
+/*
+ * 'httpUpdate()' - Update the current HTTP state for incoming data.
+ */
+
+http_status_t /* O - HTTP status */
+httpUpdate(http_t *http) /* I - HTTP data */
+{
+ char line[1024], /* Line from connection... */
+ *value; /* Pointer to value on line */
+ http_field_t field; /* Field index */
+ int major, minor, /* HTTP version numbers */
+ status; /* Request status */
+
+
+ DEBUG_printf(("httpUpdate(http=%p), state=%d\n", http, http->state));
+
+ /*
+ * If we haven't issued any commands, then there is nothing to "update"...
+ */
+
+ if (http->state == HTTP_WAITING)
+ return (HTTP_CONTINUE);
+
+ /*
+ * Grab all of the lines we can from the connection...
+ */
+
+ line[0] = '\0';
+ while (httpGets(line, sizeof(line), http) != NULL)
+ {
+ DEBUG_printf(("httpUpdate: Got \"%s\"\n", line));
+
+ if (line[0] == '\0')
+ {
+ /*
+ * Blank line means the start of the data section (if any). Return
+ * the result code, too...
+ *
+ * If we get status 100 (HTTP_CONTINUE), then we *don't* change states.
+ * Instead, we just return HTTP_CONTINUE to the caller and keep on
+ * tryin'...
+ */
+
+ if (http->status == HTTP_CONTINUE)
+ return (http->status);
+
+ if (http->status < HTTP_BAD_REQUEST)
+ http->digest_tries = 0;
+
+#ifdef HAVE_SSL
+ if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls)
+ {
+ if (http_setup_ssl(http) != 0)
+ {
+# ifdef WIN32
+ closesocket(http->fd);
+# else
+ close(http->fd);
+# endif /* WIN32 */
+
+ return (HTTP_ERROR);
+ }
+
+ return (HTTP_CONTINUE);
+ }
+#endif /* HAVE_SSL */
+
+ httpGetLength(http);
+
+ switch (http->state)
+ {
+ case HTTP_GET :
+ case HTTP_POST :
+ case HTTP_POST_RECV :
+ case HTTP_PUT :
+ http->state ++;
+ case HTTP_POST_SEND :
+ break;
+
+ default :
+ http->state = HTTP_WAITING;
+ break;
+ }
+
+ return (http->status);
+ }
+ else if (strncmp(line, "HTTP/", 5) == 0)
+ {
+ /*
+ * Got the beginning of a response...
+ */
+
+ if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &status) != 3)
+ return (HTTP_ERROR);
+
+ http->version = (http_version_t)(major * 100 + minor);
+ http->status = (http_status_t)status;
+ }
+ else if ((value = strchr(line, ':')) != NULL)
+ {
+ /*
+ * Got a value...
+ */
+
+ *value++ = '\0';
+ while (isspace(*value & 255))
+ value ++;
+
+ /*
+ * Be tolerants of servers that send unknown attribute fields...
+ */
+
+ if (!strcasecmp(line, "expect"))
+ {
+ /*
+ * "Expect: 100-continue" or similar...
+ */
+
+ http->expect = (http_status_t)atoi(value);
+ }
+ else if (!strcasecmp(line, "cookie"))
+ {
+ /*
+ * "Cookie: name=value[; name=value ...]" - replaces previous cookies...
+ */
+
+ httpSetCookie(http, value);
+ }
+ else if ((field = http_field(line)) == HTTP_FIELD_UNKNOWN)
+ {
+ DEBUG_printf(("httpUpdate: unknown field %s seen!\n", line));
+ continue;
+ }
+ else
+ httpSetField(http, field, value);
+ }
+ else
+ {
+ http->status = HTTP_ERROR;
+ return (HTTP_ERROR);
+ }
+ }
+
+ /*
+ * See if there was an error...
+ */
+
+ if (http->error == EPIPE && http->status > HTTP_CONTINUE)
+ return (http->status);
+
+ if (http->error)
+ {
+ DEBUG_printf(("httpUpdate: socket error %d - %s\n", http->error,
+ strerror(http->error)));
+ http->status = HTTP_ERROR;
+ return (HTTP_ERROR);
+ }
+
+ /*
+ * If we haven't already returned, then there is nothing new...
+ */
+
+ return (HTTP_CONTINUE);
+}
+
+
+/*
+ * 'httpDecode64()' - Base64-decode a string.
+ */
+
+char * /* O - Decoded string */
+httpDecode64(char *out, /* I - String to write to */
+ const char *in) /* I - String to read from */
+{
+ int outlen; /* Output buffer length */
+
+
+ /*
+ * Use the old maximum buffer size for binary compatibility...
+ */
+
+ outlen = 512;
+
+ return (httpDecode64_2(out, &outlen, in));
+}
+
+
+/*
+ * 'httpDecode64_2()' - Base64-decode a string.
+ */
+
+char * /* O - Decoded string */
+httpDecode64_2(char *out, /* I - String to write to */
+ int *outlen, /* IO - Size of output string */
+ const char *in) /* I - String to read from */
+{
+ int pos, /* Bit position */
+ base64; /* Value of this character */
+ char *outptr, /* Output pointer */
+ *outend; /* End of output buffer */
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!out || !outlen || *outlen < 1 || !in || !*in)
+ return (NULL);
+
+ /*
+ * Convert from base-64 to bytes...
+ */
+
+ for (outptr = out, outend = out + *outlen - 1, pos = 0; *in != '\0'; in ++)
+ {
+ /*
+ * Decode this character into a number from 0 to 63...
+ */
+
+ if (*in >= 'A' && *in <= 'Z')
+ base64 = *in - 'A';
+ else if (*in >= 'a' && *in <= 'z')
+ base64 = *in - 'a' + 26;
+ else if (*in >= '0' && *in <= '9')
+ base64 = *in - '0' + 52;
+ else if (*in == '+')
+ base64 = 62;
+ else if (*in == '/')
+ base64 = 63;
+ else if (*in == '=')
+ break;
+ else
+ continue;
+
+ /*
+ * Store the result in the appropriate chars...
+ */
+
+ switch (pos)
+ {
+ case 0 :
+ if (outptr < outend)
+ *outptr = base64 << 2;
+ pos ++;
+ break;
+ case 1 :
+ if (outptr < outend)
+ *outptr++ |= (base64 >> 4) & 3;
+ if (outptr < outend)
+ *outptr = (base64 << 4) & 255;
+ pos ++;
+ break;
+ case 2 :
+ if (outptr < outend)
+ *outptr++ |= (base64 >> 2) & 15;
+ if (outptr < outend)
+ *outptr = (base64 << 6) & 255;
+ pos ++;
+ break;
+ case 3 :
+ if (outptr < outend)
+ *outptr++ |= base64;
+ pos = 0;
+ break;
+ }
+ }
+
+ *outptr = '\0';
+
+ /*
+ * Return the decoded string and size...
+ */
+
+ *outlen = (int)(outptr - out);
+
+ return (out);
+}
+
+
+/*
+ * 'httpEncode64()' - Base64-encode a string.
+ */
+
+char * /* O - Encoded string */
+httpEncode64(char *out, /* I - String to write to */
+ const char *in) /* I - String to read from */
+{
+ return (httpEncode64_2(out, 512, in, strlen(in)));
+}
+
+
+/*
+ * 'httpEncode64_2()' - Base64-encode a string.
+ */
+
+char * /* O - Encoded string */
+httpEncode64_2(char *out, /* I - String to write to */
+ int outlen, /* I - Size of output string */
+ const char *in, /* I - String to read from */
+ int inlen) /* I - Size of input string */
+{
+ char *outptr, /* Output pointer */
+ *outend; /* End of output buffer */
+ static const char base64[] = /* Base64 characters... */
+ {
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"
+ "+/"
+ };
+
+
+ /*
+ * Range check input...
+ */
+
+ if (!out || outlen < 1 || !in || inlen < 1)
+ return (NULL);
+
+ /*
+ * Convert bytes to base-64...
+ */
+
+ for (outptr = out, outend = out + outlen - 1; inlen > 0; in ++, inlen --)
+ {
+ /*
+ * Encode the up to 3 characters as 4 Base64 numbers...
+ */
+
+ if (outptr < outend)
+ *outptr ++ = base64[(in[0] & 255) >> 2];
+ if (outptr < outend)
+ *outptr ++ = base64[(((in[0] & 255) << 4) | ((in[1] & 255) >> 4)) & 63];
+
+ in ++;
+ inlen --;
+ if (inlen <= 0)
+ {
+ if (outptr < outend)
+ *outptr ++ = '=';
+ if (outptr < outend)
+ *outptr ++ = '=';
+ break;
+ }
+
+ if (outptr < outend)
+ *outptr ++ = base64[(((in[0] & 255) << 2) | ((in[1] & 255) >> 6)) & 63];
+
+ in ++;
+ inlen --;
+ if (inlen <= 0)
+ {
+ if (outptr < outend)
+ *outptr ++ = '=';
+ break;
+ }
+
+ if (outptr < outend)
+ *outptr ++ = base64[in[0] & 63];
+ }
+
+ *outptr = '\0';
+
+ /*
+ * Return the encoded string...
+ */
+
+ return (out);
+}
+
+
+/*
+ * 'httpGetLength()' - Get the amount of data remaining from the
+ * content-length or transfer-encoding fields.
+ */
+
+int /* O - Content length */
+httpGetLength(http_t *http) /* I - HTTP data */
+{
+ DEBUG_printf(("httpGetLength(http=%p), state=%d\n", http, http->state));
+
+ if (strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked") == 0)
+ {
+ DEBUG_puts("httpGetLength: chunked request!");
+
+ http->data_encoding = HTTP_ENCODE_CHUNKED;
+ http->data_remaining = 0;
+ }
+ else
+ {
+ http->data_encoding = HTTP_ENCODE_LENGTH;
+
+ /*
+ * The following is a hack for HTTP servers that don't send a
+ * content-length or transfer-encoding field...
+ *
+ * If there is no content-length then the connection must close
+ * after the transfer is complete...
+ */
+
+ if (http->fields[HTTP_FIELD_CONTENT_LENGTH][0] == '\0')
+ http->data_remaining = 2147483647;
+ else
+ http->data_remaining = atoi(http->fields[HTTP_FIELD_CONTENT_LENGTH]);
+
+ DEBUG_printf(("httpGetLength: content_length=%d\n", http->data_remaining));
+ }
+
+ return (http->data_remaining);
+}
+
+
+/*
+ * 'http_field()' - Return the field index for a field name.
+ */
+
+static http_field_t /* O - Field index */
+http_field(const char *name) /* I - String name */
+{
+ int i; /* Looping var */
+
+
+ for (i = 0; i < HTTP_FIELD_MAX; i ++)
+ if (strcasecmp(name, http_fields[i]) == 0)
+ return ((http_field_t)i);
+
+ return (HTTP_FIELD_UNKNOWN);
+}
+
+
+/*
+ * 'http_send()' - Send a request with all fields and the trailing blank line.
+ */
+
+static int /* O - 0 on success, non-zero on error */
+http_send(http_t *http, /* I - HTTP data */
+ http_state_t request, /* I - Request code */
+ const char *uri) /* I - URI */
+{
+ int i; /* Looping var */
+ char *ptr, /* Pointer in buffer */
+ buf[1024]; /* Encoded URI buffer */
+ static const char * const codes[] =
+ { /* Request code strings */
+ NULL,
+ "OPTIONS",
+ "GET",
+ NULL,
+ "HEAD",
+ "POST",
+ NULL,
+ NULL,
+ "PUT",
+ NULL,
+ "DELETE",
+ "TRACE",
+ "CLOSE"
+ };
+ static const char hex[] = "0123456789ABCDEF";
+ /* Hex digits */
+
+
+ DEBUG_printf(("http_send(http=%p, request=HTTP_%s, uri=\"%s\")\n",
+ http, codes[request], uri));
+
+ if (http == NULL || uri == NULL)
+ return (-1);
+
+ /*
+ * Encode the URI as needed...
+ */
+
+ for (ptr = buf; *uri != '\0' && ptr < (buf + sizeof(buf) - 1); uri ++)
+ if (*uri <= ' ' || *uri >= 127)
+ {
+ if (ptr < (buf + sizeof(buf) - 1))
+ *ptr ++ = '%';
+ if (ptr < (buf + sizeof(buf) - 1))
+ *ptr ++ = hex[(*uri >> 4) & 15];
+ if (ptr < (buf + sizeof(buf) - 1))
+ *ptr ++ = hex[*uri & 15];
+ }
+ else
+ *ptr ++ = *uri;
+
+ *ptr = '\0';
+
+ /*
+ * See if we had an error the last time around; if so, reconnect...
+ */
+
+ if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST)
+ httpReconnect(http);
+
+ /*
+ * Send the request header...
+ */
+
+ http->state = request;
+ if (request == HTTP_POST || request == HTTP_PUT)
+ http->state ++;
+
+ http->status = HTTP_CONTINUE;
+
+#ifdef HAVE_SSL
+ if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls)
+ {
+ httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade");
+ httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0");
+ }
+#endif /* HAVE_SSL */
+
+ if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1)
+ {
+ http->status = HTTP_ERROR;
+ return (-1);
+ }
+
+ for (i = 0; i < HTTP_FIELD_MAX; i ++)
+ if (http->fields[i][0] != '\0')
+ {
+ DEBUG_printf(("%s: %s\n", http_fields[i], http->fields[i]));
+
+ if (httpPrintf(http, "%s: %s\r\n", http_fields[i], http->fields[i]) < 1)
+ {
+ http->status = HTTP_ERROR;
+ return (-1);
+ }
+ }
+
+ if (httpPrintf(http, "\r\n") < 1)
+ {
+ http->status = HTTP_ERROR;
+ return (-1);
+ }
+
+ httpClearFields(http);
+
+ return (0);
+}
+
+
+/*
+ * 'http_wait()' - Wait for data available on a connection.
+ */
+
+static int /* O - 1 if data is available, 0 otherwise */
+http_wait(http_t *http, /* I - HTTP data */
+ int msec) /* I - Milliseconds to wait */
+{
+#ifndef WIN32
+ struct rlimit limit; /* Runtime limit */
+#endif /* !WIN32 */
+ struct timeval timeout; /* Timeout */
+ int nfds; /* Result from select() */
+ int set_size; /* Size of select set */
+
+
+ DEBUG_printf(("http_wait(http=%p, msec=%d)\n", http, msec));
+
+ /*
+ * Check the SSL/TLS buffers for data first...
+ */
+
+#ifdef HAVE_SSL
+ if (http->tls)
+ {
+# ifdef HAVE_LIBSSL
+ if (SSL_pending((SSL *)(http->tls)))
+ return (1);
+# elif defined(HAVE_GNUTLS)
+ if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session))
+ return (1);
+# elif defined(HAVE_CDSASSL)
+ size_t bytes; /* Bytes that are available */
+
+ if (!SSLGetBufferedReadSize((SSLContextRef)http->tls, &bytes) && bytes > 0)
+ return;
+# endif /* HAVE_LIBSSL */
+ }
+#endif /* HAVE_SSL */
+
+ /*
+ * Then try doing a select() to poll the socket...
+ */
+
+ if (!http->input_set)
+ {
+#ifdef WIN32
+ /*
+ * Windows has a fixed-size select() structure, different (surprise,
+ * surprise!) from all UNIX implementations. Just allocate this
+ * fixed structure...
+ */
+
+ http->input_set = calloc(1, sizeof(fd_set));
+#else
+ /*
+ * Allocate the select() input set based upon the max number of file
+ * descriptors available for this process...
+ */
+
+ getrlimit(RLIMIT_NOFILE, &limit);
+
+ set_size = (limit.rlim_cur + 31) / 8 + 4;
+ if (set_size < sizeof(fd_set))
+ set_size = sizeof(fd_set);
+
+ http->input_set = calloc(1, set_size);
+#endif /* WIN32 */
+
+ if (!http->input_set)
+ return (0);
+ }
+
+ do
+ {
+ FD_SET(http->fd, http->input_set);
+
+ if (msec >= 0)
+ {
+ timeout.tv_sec = msec / 1000;
+ timeout.tv_usec = (msec % 1000) * 1000;
+
+ nfds = select(http->fd + 1, http->input_set, NULL, NULL, &timeout);
+ }
+ else
+ nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL);
+ }
+#ifdef WIN32
+ while (nfds < 0 && WSAGetLastError() == WSAEINTR);
+#else
+ while (nfds < 0 && errno == EINTR);
+#endif /* WIN32 */
+
+ FD_CLR(http->fd, http->input_set);
+
+ return (nfds > 0);
+}
+
+
+#ifdef HAVE_SSL
+/*
+ * 'http_upgrade()' - Force upgrade to TLS encryption.
+ */
+
+static int /* O - Status of connection */
+http_upgrade(http_t *http) /* I - HTTP data */
+{
+ int ret; /* Return value */
+ http_t myhttp; /* Local copy of HTTP data */
+
+
+ DEBUG_printf(("http_upgrade(%p)\n", http));
+
+ /*
+ * Copy the HTTP data to a local variable so we can do the OPTIONS
+ * request without interfering with the existing request data...
+ */
+
+ memcpy(&myhttp, http, sizeof(myhttp));
+
+ /*
+ * Send an OPTIONS request to the server, requiring SSL or TLS
+ * encryption on the link...
+ */
+
+ httpClearFields(&myhttp);
+ httpSetField(&myhttp, HTTP_FIELD_CONNECTION, "upgrade");
+ httpSetField(&myhttp, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0");
+
+ if ((ret = httpOptions(&myhttp, "*")) == 0)
+ {
+ /*
+ * Wait for the secure connection...
+ */
+
+ while (httpUpdate(&myhttp) == HTTP_CONTINUE);
+ }
+
+ httpFlush(&myhttp);
+
+ /*
+ * Copy the HTTP data back over, if any...
+ */
+
+ http->fd = myhttp.fd;
+ http->error = myhttp.error;
+ http->activity = myhttp.activity;
+ http->status = myhttp.status;
+ http->version = myhttp.version;
+ http->keep_alive = myhttp.keep_alive;
+ http->used = myhttp.used;
+
+ if (http->used)
+ memcpy(http->buffer, myhttp.buffer, http->used);
+
+ http->auth_type = myhttp.auth_type;
+ http->nonce_count = myhttp.nonce_count;
+
+ memcpy(http->nonce, myhttp.nonce, sizeof(http->nonce));
+
+ http->tls = myhttp.tls;
+ http->encryption = myhttp.encryption;
+
+ /*
+ * See if we actually went secure...
+ */
+
+ if (!http->tls)
+ {
+ /*
+ * Server does not support HTTP upgrade...
+ */
+
+ DEBUG_puts("Server does not support HTTP upgrade!");
+
+# ifdef WIN32
+ closesocket(http->fd);
+# else
+ close(http->fd);
+# endif
+
+ http->fd = -1;
+
+ return (-1);
+ }
+ else
+ return (ret);
+}
+
+
+/*
+ * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
+ */
+
+static int /* O - Status of connection */
+http_setup_ssl(http_t *http) /* I - HTTP data */
+{
+# ifdef HAVE_LIBSSL
+ SSL_CTX *context; /* Context for encryption */
+ SSL *conn; /* Connection for encryption */
+# elif defined(HAVE_GNUTLS)
+ http_tls_t *conn; /* TLS session object */
+ gnutls_certificate_client_credentials *credentials;
+ /* TLS credentials */
+# elif defined(HAVE_CDSASSL)
+ SSLContextRef conn; /* Context for encryption */
+ OSStatus error; /* Error info */
+# endif /* HAVE_LIBSSL */
+
+
+ DEBUG_printf(("http_setup_ssl(http=%p)\n", http));
+
+# ifdef HAVE_LIBSSL
+ context = SSL_CTX_new(SSLv23_client_method());
+
+ SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */
+
+ conn = SSL_new(context);
+
+ SSL_set_fd(conn, http->fd);
+ if (SSL_connect(conn) != 1)
+ {
+# ifdef DEBUG
+ unsigned long error; /* Error code */
+
+ while ((error = ERR_get_error()) != 0)
+ printf("http_setup_ssl: %s\n", ERR_error_string(error, NULL));
+# endif /* DEBUG */
+
+ SSL_CTX_free(context);
+ SSL_free(conn);
+
+# ifdef WIN32
+ http->error = WSAGetLastError();
+# else
+ http->error = errno;
+# endif /* WIN32 */
+ http->status = HTTP_ERROR;
+
+ return (HTTP_ERROR);
+ }
+
+# elif defined(HAVE_GNUTLS)
+ conn = (http_tls_t *)malloc(sizeof(http_tls_t));
+
+ if (conn == NULL)
+ {
+ http->error = errno;
+ http->status = HTTP_ERROR;
+
+ return (-1);
+ }
+
+ credentials = (gnutls_certificate_client_credentials *)
+ malloc(sizeof(gnutls_certificate_client_credentials));
+ if (credentials == NULL)
+ {
+ free(conn);
+
+ http->error = errno;
+ http->status = HTTP_ERROR;
+
+ return (-1);
+ }
+
+ gnutls_certificate_allocate_credentials(credentials);
+
+ gnutls_init(&(conn->session), GNUTLS_CLIENT);
+ gnutls_set_default_priority(conn->session);
+ gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials);
+ gnutls_transport_set_ptr(conn->session, http->fd);
+
+ if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS)
+ {
+ http->error = errno;
+ http->status = HTTP_ERROR;
+
+ return (-1);
+ }
+
+ conn->credentials = credentials;
+
+# elif defined(HAVE_CDSASSL)
+ error = SSLNewContext(false, &conn);
+
+ if (!error)
+ error = SSLSetIOFuncs(conn, CDSAReadFunc, CDSAWriteFunc);
+
+ if (!error)
+ error = SSLSetConnection(conn, (SSLConnectionRef)http->fd);
+
+ if (!error)
+ error = SSLSetAllowsExpiredCerts(conn, true);
+
+ if (!error)
+ error = SSLSetAllowsAnyRoot(conn, true);
+
+ if (!error)
+ error = SSLHandshake(conn);
+
+ if (error != 0)
+ {
+ http->error = error;
+ http->status = HTTP_ERROR;
+
+ SSLDisposeContext(conn);
+
+ close(http->fd);
+
+ return (-1);
+ }
+# endif /* HAVE_CDSASSL */
+
+ http->tls = conn;
+ return (0);
+}
+
+
+/*
+ * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection.
+ */
+
+static void
+http_shutdown_ssl(http_t *http) /* I - HTTP data */
+{
+# ifdef HAVE_LIBSSL
+ SSL_CTX *context; /* Context for encryption */
+ SSL *conn; /* Connection for encryption */
+
+
+ conn = (SSL *)(http->tls);
+ context = SSL_get_SSL_CTX(conn);
+
+ SSL_shutdown(conn);
+ SSL_CTX_free(context);
+ SSL_free(conn);
+
+# elif defined(HAVE_GNUTLS)
+ http_tls_t *conn; /* Encryption session */
+ gnutls_certificate_client_credentials *credentials;
+ /* TLS credentials */
+
+
+ conn = (http_tls_t *)(http->tls);
+ credentials = (gnutls_certificate_client_credentials *)(conn->credentials);
+
+ gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);
+ gnutls_deinit(conn->session);
+ gnutls_certificate_free_credentials(*credentials);
+ free(credentials);
+ free(conn);
+
+# elif defined(HAVE_CDSASSL)
+ SSLClose((SSLContextRef)http->tls);
+ SSLDisposeContext((SSLContextRef)http->tls);
+# endif /* HAVE_LIBSSL */
+
+ http->tls = NULL;
+}
+
+
+/*
+ * 'http_read_ssl()' - Read from a SSL/TLS connection.
+ */
+
+static int /* O - Bytes read */
+http_read_ssl(http_t *http, /* I - HTTP data */
+ char *buf, /* I - Buffer to store data */
+ int len) /* I - Length of buffer */
+{
+# if defined(HAVE_LIBSSL)
+ return (SSL_read((SSL *)(http->tls), buf, len));
+
+# elif defined(HAVE_GNUTLS)
+ return (gnutls_record_recv(((http_tls_t *)(http->tls))->session, buf, len));
+
+# elif defined(HAVE_CDSASSL)
+ OSStatus error; /* Error info */
+ size_t processed; /* Number of bytes processed */
+
+
+ error = SSLRead((SSLContextRef)http->tls, buf, len, &processed);
+
+ if (error == 0)
+ return (processed);
+ else
+ {
+ http->error = error;
+
+ return (-1);
+ }
+# endif /* HAVE_LIBSSL */
+}
+
+
+/*
+ * 'http_write_ssl()' - Write to a SSL/TLS connection.
+ */
+
+static int /* O - Bytes written */
+http_write_ssl(http_t *http, /* I - HTTP data */
+ const char *buf, /* I - Buffer holding data */
+ int len) /* I - Length of buffer */
+{
+# if defined(HAVE_LIBSSL)
+ return (SSL_write((SSL *)(http->tls), buf, len));
+
+# elif defined(HAVE_GNUTLS)
+ return (gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len));
+# elif defined(HAVE_CDSASSL)
+ OSStatus error; /* Error info */
+ size_t processed; /* Number of bytes processed */
+
+
+ error = SSLWrite((SSLContextRef)http->tls, buf, len, &processed);
+
+ if (error == 0)
+ return (processed);
+ else
+ {
+ http->error = error;
+ return (-1);
+ }
+# endif /* HAVE_LIBSSL */
+}
+
+
+# if defined(HAVE_CDSASSL)
+/*
+ * 'CDSAReadFunc()' - Read function for CDSA decryption code.
+ */
+
+static OSStatus /* O - -1 on error, 0 on success */
+CDSAReadFunc(SSLConnectionRef connection, /* I - SSL/TLS connection */
+ void *data, /* I - Data buffer */
+ size_t *dataLength) /* IO - Number of bytes */
+{
+ ssize_t bytes; /* Number of bytes read */
+
+#ifdef DEBUG_HTTP
+ httpDumpData(stdout, "CDSAReadFunc:", data, *dataLength);
+#endif
+ bytes = recv((int)connection, data, *dataLength, 0);
+ if (bytes >= 0)
+ {
+ *dataLength = bytes;
+ return (0);
+ }
+ else
+ return (-1);
+}
+
+
+/*
+ * 'CDSAWriteFunc()' - Write function for CDSA encryption code.
+ */
+
+static OSStatus /* O - -1 on error, 0 on success */
+CDSAWriteFunc(SSLConnectionRef connection, /* I - SSL/TLS connection */
+ const void *data, /* I - Data buffer */
+ size_t *dataLength) /* IO - Number of bytes */
+{
+ ssize_t bytes;
+
+
+ bytes = write((int)connection, data, *dataLength);
+ if (bytes >= 0)
+ {
+ *dataLength = bytes;
+ return (0);
+ }
+ else
+ return (-1);
+}
+# endif /* HAVE_CDSASSL */
+#endif /* HAVE_SSL */
+
+
+/*
+ * End of "$Id: http.c 148 2006-04-25 16:54:17Z njacobs $"
+ */
diff --git a/usr/src/lib/print/libhttp-core/common/http.h b/usr/src/lib/print/libhttp-core/common/http.h
new file mode 100644
index 0000000000..da36b461a3
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/common/http.h
@@ -0,0 +1,436 @@
+/*
+ * "$Id: http.h 148 2006-04-25 16:54:17Z njacobs $"
+ *
+ * Hyper-Text Transport Protocol definitions for the Common UNIX Printing
+ * System (CUPS).
+ *
+ * Copyright 1997-2005 by Easy Software Products, all rights reserved.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Easy Software Products and are protected by Federal
+ * copyright law. Distribution and use rights are outlined in the file
+ * "LICENSE.txt" which should have been included with this file. If this
+ * file is missing or damaged please contact Easy Software Products
+ * at:
+ *
+ * Attn: CUPS Licensing Information
+ * Easy Software Products
+ * 44141 Airport View Drive, Suite 204
+ * Hollywood, Maryland 20636 USA
+ *
+ * Voice: (301) 373-9600
+ * EMail: cups-info@cups.org
+ * WWW: http://www.cups.org
+ *
+ * This file is subject to the Apple OS-Developed Software exception.
+ */
+
+#ifndef _CUPS_HTTP_H_
+#define _CUPS_HTTP_H_
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Include necessary headers...
+ */
+
+# include <string.h>
+# include <time.h>
+# ifdef WIN32
+# include <winsock.h>
+# else
+# include <unistd.h>
+# include <sys/time.h>
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netinet/in_systm.h>
+# include <netinet/ip.h>
+# if !defined(__APPLE__) || !defined(TCP_NODELAY)
+# include <netinet/tcp.h>
+# endif /* !__APPLE__ || !TCP_NODELAY */
+# ifdef AF_LOCAL
+# include <sys/un.h>
+# endif /* AF_LOCAL */
+# endif /* WIN32 */
+
+
+/*
+ * C++ magic...
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Oh, the wonderful world of IPv6 compatibility. Apparently some
+ * implementations expose the (more logical) 32-bit address parts
+ * to everyone, while others only expose it to kernel code... To
+ * make supporting IPv6 even easier, each vendor chose different
+ * core structure and union names, so the same defines or code
+ * can't be used on all platforms.
+ *
+ * The following will likely need tweeking on new platforms that
+ * support IPv6 - the "s6_addr32" define maps to the 32-bit integer
+ * array in the in6_addr union, which is named differently on various
+ * platforms.
+ */
+
+#if defined(AF_INET6) && !defined(s6_addr32)
+# if defined(__sun)
+# define s6_addr32 _S6_un._S6_u32
+# elif defined(__FreeBSD__) || defined(__APPLE__)
+# define s6_addr32 __u6_addr.__u6_addr32
+# endif /* __sun */
+#endif /* AF_INET6 && !s6_addr32 */
+
+
+/*
+ * Limits...
+ */
+
+# define HTTP_MAX_URI 1024 /* Max length of URI string */
+# define HTTP_MAX_HOST 256 /* Max length of hostname string */
+# define HTTP_MAX_BUFFER 2048 /* Max length of data buffer */
+# define HTTP_MAX_VALUE 256 /* Max header field value length */
+
+
+/*
+ * HTTP state values...
+ */
+
+typedef enum /* States are server-oriented */
+{
+ HTTP_WAITING, /* Waiting for command */
+ HTTP_OPTIONS, /* OPTIONS command, waiting for blank line */
+ HTTP_GET, /* GET command, waiting for blank line */
+ HTTP_GET_SEND, /* GET command, sending data */
+ HTTP_HEAD, /* HEAD command, waiting for blank line */
+ HTTP_POST, /* POST command, waiting for blank line */
+ HTTP_POST_RECV, /* POST command, receiving data */
+ HTTP_POST_SEND, /* POST command, sending data */
+ HTTP_PUT, /* PUT command, waiting for blank line */
+ HTTP_PUT_RECV, /* PUT command, receiving data */
+ HTTP_DELETE, /* DELETE command, waiting for blank line */
+ HTTP_TRACE, /* TRACE command, waiting for blank line */
+ HTTP_CLOSE, /* CLOSE command, waiting for blank line */
+ HTTP_STATUS /* Command complete, sending status */
+} http_state_t;
+
+
+/*
+ * HTTP version numbers...
+ */
+
+typedef enum
+{
+ HTTP_0_9 = 9, /* HTTP/0.9 */
+ HTTP_1_0 = 100, /* HTTP/1.0 */
+ HTTP_1_1 = 101 /* HTTP/1.1 */
+} http_version_t;
+
+
+/*
+ * HTTP keep-alive values...
+ */
+
+typedef enum
+{
+ HTTP_KEEPALIVE_OFF = 0,
+ HTTP_KEEPALIVE_ON
+} http_keepalive_t;
+
+
+/*
+ * HTTP transfer encoding values...
+ */
+
+typedef enum
+{
+ HTTP_ENCODE_LENGTH, /* Data is sent with Content-Length */
+ HTTP_ENCODE_CHUNKED /* Data is chunked */
+} http_encoding_t;
+
+
+/*
+ * HTTP encryption values...
+ */
+
+typedef enum
+{
+ HTTP_ENCRYPT_IF_REQUESTED, /* Encrypt if requested (TLS upgrade) */
+ HTTP_ENCRYPT_NEVER, /* Never encrypt */
+ HTTP_ENCRYPT_REQUIRED, /* Encryption is required (TLS upgrade) */
+ HTTP_ENCRYPT_ALWAYS /* Always encrypt (SSL) */
+} http_encryption_t;
+
+
+/*
+ * HTTP authentication types...
+ */
+
+typedef enum
+{
+ HTTP_AUTH_NONE, /* No authentication in use */
+ HTTP_AUTH_BASIC, /* Basic authentication in use */
+ HTTP_AUTH_MD5, /* Digest authentication in use */
+ HTTP_AUTH_MD5_SESS, /* MD5-session authentication in use */
+ HTTP_AUTH_MD5_INT, /* Digest authentication in use for body */
+ HTTP_AUTH_MD5_SESS_INT /* MD5-session authentication in use for body */
+} http_auth_t;
+
+
+/*
+ * HTTP status codes...
+ */
+
+typedef enum
+{
+ HTTP_ERROR = -1, /* An error response from httpXxxx() */
+
+ HTTP_CONTINUE = 100, /* Everything OK, keep going... */
+ HTTP_SWITCHING_PROTOCOLS, /* HTTP upgrade to TLS/SSL */
+
+ HTTP_OK = 200, /* OPTIONS/GET/HEAD/POST/TRACE command was successful */
+ HTTP_CREATED, /* PUT command was successful */
+ HTTP_ACCEPTED, /* DELETE command was successful */
+ HTTP_NOT_AUTHORITATIVE, /* Information isn't authoritative */
+ HTTP_NO_CONTENT, /* Successful command, no new data */
+ HTTP_RESET_CONTENT, /* Content was reset/recreated */
+ HTTP_PARTIAL_CONTENT, /* Only a partial file was recieved/sent */
+
+ HTTP_MULTIPLE_CHOICES = 300, /* Multiple files match request */
+ HTTP_MOVED_PERMANENTLY, /* Document has moved permanently */
+ HTTP_MOVED_TEMPORARILY, /* Document has moved temporarily */
+ HTTP_SEE_OTHER, /* See this other link... */
+ HTTP_NOT_MODIFIED, /* File not modified */
+ HTTP_USE_PROXY, /* Must use a proxy to access this URI */
+
+ HTTP_BAD_REQUEST = 400, /* Bad request */
+ HTTP_UNAUTHORIZED, /* Unauthorized to access host */
+ HTTP_PAYMENT_REQUIRED, /* Payment required */
+ HTTP_FORBIDDEN, /* Forbidden to access this URI */
+ HTTP_NOT_FOUND, /* URI was not found */
+ HTTP_METHOD_NOT_ALLOWED, /* Method is not allowed */
+ HTTP_NOT_ACCEPTABLE, /* Not Acceptable */
+ HTTP_PROXY_AUTHENTICATION, /* Proxy Authentication is Required */
+ HTTP_REQUEST_TIMEOUT, /* Request timed out */
+ HTTP_CONFLICT, /* Request is self-conflicting */
+ HTTP_GONE, /* Server has gone away */
+ HTTP_LENGTH_REQUIRED, /* A content length or encoding is required */
+ HTTP_PRECONDITION, /* Precondition failed */
+ HTTP_REQUEST_TOO_LARGE, /* Request entity too large */
+ HTTP_URI_TOO_LONG, /* URI too long */
+ HTTP_UNSUPPORTED_MEDIATYPE, /* The requested media type is unsupported */
+ HTTP_UPGRADE_REQUIRED = 426, /* Upgrade to SSL/TLS required */
+
+ HTTP_SERVER_ERROR = 500, /* Internal server error */
+ HTTP_NOT_IMPLEMENTED, /* Feature not implemented */
+ HTTP_BAD_GATEWAY, /* Bad gateway */
+ HTTP_SERVICE_UNAVAILABLE, /* Service is unavailable */
+ HTTP_GATEWAY_TIMEOUT, /* Gateway connection timed out */
+ HTTP_NOT_SUPPORTED /* HTTP version not supported */
+} http_status_t;
+
+
+/*
+ * HTTP field names...
+ */
+
+typedef enum
+{
+ HTTP_FIELD_UNKNOWN = -1,
+ HTTP_FIELD_ACCEPT_LANGUAGE,
+ HTTP_FIELD_ACCEPT_RANGES,
+ HTTP_FIELD_AUTHORIZATION,
+ HTTP_FIELD_CONNECTION,
+ HTTP_FIELD_CONTENT_ENCODING,
+ HTTP_FIELD_CONTENT_LANGUAGE,
+ HTTP_FIELD_CONTENT_LENGTH,
+ HTTP_FIELD_CONTENT_LOCATION,
+ HTTP_FIELD_CONTENT_MD5,
+ HTTP_FIELD_CONTENT_RANGE,
+ HTTP_FIELD_CONTENT_TYPE,
+ HTTP_FIELD_CONTENT_VERSION,
+ HTTP_FIELD_DATE,
+ HTTP_FIELD_HOST,
+ HTTP_FIELD_IF_MODIFIED_SINCE,
+ HTTP_FIELD_IF_UNMODIFIED_SINCE,
+ HTTP_FIELD_KEEP_ALIVE,
+ HTTP_FIELD_LAST_MODIFIED,
+ HTTP_FIELD_LINK,
+ HTTP_FIELD_LOCATION,
+ HTTP_FIELD_RANGE,
+ HTTP_FIELD_REFERER,
+ HTTP_FIELD_RETRY_AFTER,
+ HTTP_FIELD_TRANSFER_ENCODING,
+ HTTP_FIELD_UPGRADE,
+ HTTP_FIELD_USER_AGENT,
+ HTTP_FIELD_WWW_AUTHENTICATE,
+ HTTP_FIELD_MAX
+} http_field_t;
+
+
+/*
+ * HTTP address structure (makes using IPv6 a little easier and more portable.)
+ */
+
+typedef union
+{
+ struct sockaddr addr; /* Base structure for family value */
+ struct sockaddr_in ipv4; /* IPv4 address */
+#ifdef AF_INET6
+ struct sockaddr_in6 ipv6; /* IPv6 address */
+#endif /* AF_INET6 */
+#ifdef AF_LOCAL
+ struct sockaddr_un un; /* Domain socket file */
+#endif /* AF_LOCAL */
+ char pad[128]; /* Pad to ensure binary compatibility */
+} http_addr_t;
+
+/*
+ * HTTP connection structure...
+ */
+
+typedef struct
+{
+ int fd; /* File descriptor for this socket */
+ int blocking; /* To block or not to block */
+ int error; /* Last error on read */
+ time_t activity; /* Time since last read/write */
+ http_state_t state; /* State of client */
+ http_status_t status; /* Status of last request */
+ http_version_t version; /* Protocol version */
+ http_keepalive_t keep_alive; /* Keep-alive supported? */
+ struct sockaddr_in oldaddr; /* Address of connected host */
+ char hostname[HTTP_MAX_HOST],
+ /* Name of connected host */
+ fields[HTTP_FIELD_MAX][HTTP_MAX_VALUE];
+ /* Field values */
+ char *data; /* Pointer to data buffer */
+ http_encoding_t data_encoding; /* Chunked or not */
+ int data_remaining; /* Number of bytes left */
+ int used; /* Number of bytes used in buffer */
+ char buffer[HTTP_MAX_BUFFER];
+ /* Buffer for messages */
+ int auth_type; /* Authentication in use */
+ char nonce[HTTP_MAX_VALUE];
+ /* Nonce value */
+ int nonce_count; /* Nonce count */
+ void *tls; /* TLS state information */
+ http_encryption_t encryption; /* Encryption requirements */
+ /**** New in CUPS 1.1.19 ****/
+ fd_set *input_set; /* select() set for httpWait() */
+ http_status_t expect; /* Expect: header */
+ char *cookie; /* Cookie value(s) */
+ /**** New in CUPS 1.1.20 ****/
+ char authstring[HTTP_MAX_VALUE],
+ /* Current Authentication value */
+ userpass[HTTP_MAX_VALUE];
+ /* Username:password string */
+ int digest_tries; /* Number of tries for digest auth */
+ /**** New in CUPS 1.2 ****/
+ http_addr_t hostaddr; /* Host address and port */
+} http_t;
+
+
+/*
+ * Prototypes...
+ */
+
+# define httpBlocking(http,b) (http)->blocking = (b)
+extern int httpCheck(http_t *http);
+# define httpClearFields(http) memset((http)->fields, 0, sizeof((http)->fields)),\
+ httpSetField((http), HTTP_FIELD_HOST, (http)->hostname)
+extern void httpClose(http_t *http);
+extern http_t *httpConnect(const char *host, int port);
+extern http_t *httpConnectEncrypt(const char *host, int port,
+ http_encryption_t encrypt);
+extern int httpDelete(http_t *http, const char *uri);
+extern int httpEncryption(http_t *http, http_encryption_t e);
+# define httpError(http) ((http)->error)
+extern void httpFlush(http_t *http);
+extern int httpGet(http_t *http, const char *uri);
+extern char *httpGets(char *line, int length, http_t *http);
+extern const char *httpGetDateString(time_t t);
+extern time_t httpGetDateTime(const char *s);
+# define httpGetField(http,field) (http)->fields[field]
+extern struct hostent *httpGetHostByName(const char *name);
+extern char *httpGetSubField(http_t *http, http_field_t field,
+ const char *name, char *value);
+extern int httpHead(http_t *http, const char *uri);
+extern void httpInitialize(void);
+extern int httpOptions(http_t *http, const char *uri);
+extern int httpPost(http_t *http, const char *uri);
+extern int httpPrintf(http_t *http, const char *format, ...)
+# ifdef __GNUC__
+__attribute__ ((__format__ (__printf__, 2, 3)))
+# endif /* __GNUC__ */
+;
+extern int httpPut(http_t *http, const char *uri);
+extern int httpRead(http_t *http, char *buffer, int length);
+extern int httpReconnect(http_t *http);
+extern void httpSeparate(const char *uri, char *method,
+ char *username, char *host, int *port,
+ char *resource);
+extern void httpSetField(http_t *http, http_field_t field,
+ const char *value);
+extern const char *httpStatus(http_status_t status);
+extern int httpTrace(http_t *http, const char *uri);
+extern http_status_t httpUpdate(http_t *http);
+extern int httpWrite(http_t *http, const char *buffer, int length);
+extern char *httpEncode64(char *out, const char *in);
+extern char *httpDecode64(char *out, const char *in);
+extern int httpGetLength(http_t *http);
+extern char *httpMD5(const char *, const char *, const char *,
+ char [33]);
+extern char *httpMD5Final(const char *, const char *, const char *,
+ char [33]);
+extern char *httpMD5String(const unsigned char *, char [33]);
+
+/**** New in CUPS 1.1.19 ****/
+extern void httpClearCookie(http_t *http);
+#define httpGetCookie(http) ((http)->cookie)
+extern void httpSetCookie(http_t *http, const char *cookie);
+extern int httpWait(http_t *http, int msec);
+
+/**** New in CUPS 1.1.21 ****/
+extern char *httpDecode64_2(char *out, int *outlen, const char *in);
+extern char *httpEncode64_2(char *out, int outlen, const char *in,
+ int inlen);
+extern void httpSeparate2(const char *uri,
+ char *method, int methodlen,
+ char *username, int usernamelen,
+ char *host, int hostlen, int *port,
+ char *resource, int resourcelen);
+
+/**** New in CUPS 1.2 ****/
+extern int httpAddrAny(const http_addr_t *addr);
+extern int httpAddrEqual(const http_addr_t *addr1,
+ const http_addr_t *addr2);
+extern void httpAddrLoad(const struct hostent *host, int port,
+ int n, http_addr_t *addr);
+extern int httpAddrLocalhost(const http_addr_t *addr);
+extern char *httpAddrLookup(const http_addr_t *addr,
+ char *name, int namelen);
+extern char *httpAddrString(const http_addr_t *addr,
+ char *s, int slen);
+
+
+/*
+ * C++ magic...
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_CUPS_HTTP_H_ */
+
+/*
+ * End of "$Id: http.h 148 2006-04-25 16:54:17Z njacobs $"
+ */
diff --git a/usr/src/lib/print/libhttp-core/common/mapfile b/usr/src/lib/print/libhttp-core/common/mapfile
new file mode 100644
index 0000000000..e799d3bc76
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/common/mapfile
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# Common interfaces that are most likely to be shared amongst the various
+# PAPI implementations.
+#
+
+SUNWprivate_1.0 {
+ global:
+ httpCheck ;
+ httpClose ;
+ httpConnectEncrypt ;
+ httpDumpData ;
+ httpEncode64 ;
+ httpEncryption ;
+ httpFlush ;
+ httpGetSubField ;
+ httpPost ;
+ httpRead ;
+ httpReconnect ;
+ httpSetField ;
+ httpUpdate ;
+ httpWait ;
+ httpWrite ;
+
+ local:
+ * ;
+} ;
diff --git a/usr/src/lib/print/libhttp-core/i386/Makefile b/usr/src/lib/print/libhttp-core/i386/Makefile
new file mode 100644
index 0000000000..0bc3313291
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/lib/print/libhttp-core/sparc/Makefile b/usr/src/lib/print/libhttp-core/sparc/Makefile
new file mode 100644
index 0000000000..0bc3313291
--- /dev/null
+++ b/usr/src/lib/print/libhttp-core/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/lib/print/libipp-core/Makefile b/usr/src/lib/print/libipp-core/Makefile
new file mode 100644
index 0000000000..b92d620b10
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../../Makefile.lib
+
+#HDRS = papi.h
+#HDRDIR = common
+SUBDIRS = $(MACH)
+#$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all clean clobber install: .WAIT $(SUBDIRS)
+
+lint: # $(SUBDIRS)
+
+install_h: # $(ROOTHDRS)
+
+check: # $(CHECKHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/print/libipp-core/Makefile.com b/usr/src/lib/print/libipp-core/Makefile.com
new file mode 100644
index 0000000000..56099a4aa9
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/Makefile.com
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = libipp-core.a
+VERS = .0
+OBJECTS = ipp.o ipp_types.o read.o strings.o write.o
+
+include ../../../Makefile.lib
+include ../../../Makefile.rootfs
+
+ROOTLIBDIR= $(ROOT)/usr/lib
+
+LIBS = $(DYNLIB)
+
+SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c)
+
+$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+MAPFILE = $(SRCDIR)/mapfile
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -I$(SRCDIR)
+CPPFLAGS += -I../../libpapi-common/common
+DYNFLAGS += -M $(MAPFILE)
+LDLIBS += -lpapi-common -lc
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include ../../../Makefile.targ
diff --git a/usr/src/lib/print/libipp-core/common/ipp.c b/usr/src/lib/print/libipp-core/common/ipp.c
new file mode 100644
index 0000000000..133fb0ad13
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/common/ipp.c
@@ -0,0 +1,136 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: ipp.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <papi.h>
+#include "ipp.h"
+
+/*
+ * IPP requests/responses are represented as attribute lists. An IPP request
+ * attribute list will contain header information attributes:
+ * version-major (int)
+ * version-minor (int)
+ * request-id (int)
+ * operation-id (int)
+ * It will also contain 1 or more attribute groups (collections)
+ * operational-attribute-group
+ * ...
+ * this routine validates that the request falls within the guidelines of
+ * the protocol specification (or some other level of conformance if the
+ * restrictions have been specified at the top level of the request using
+ * a "conformance" attribute.
+ */
+papi_status_t
+ipp_validate_request(papi_attribute_t **request, papi_attribute_t ***response)
+{
+ papi_attribute_t **attributes = NULL;
+ papi_status_t result = PAPI_OK;
+ char *s;
+
+ if ((request == NULL) || (response == NULL) || (*response == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* validate the operational attributes group */
+ result = papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &attributes);
+ if (result != PAPI_OK) {
+ ipp_set_status(response, result,
+ "operational attribute group: %s",
+ papiStatusString(result));
+ return (result);
+ }
+
+ result = papiAttributeListGetString(attributes, NULL,
+ "attributes-charset", &s);
+ if (result != PAPI_OK) {
+ ipp_set_status(response, result, "attributes-charset: %s",
+ papiStatusString(result));
+ return (result);
+ }
+
+ result = papiAttributeListGetString(attributes, NULL,
+ "attributes-natural-language", &s);
+ if (result != PAPI_OK) {
+ ipp_set_status(response, result,
+ "attributes-natural-language: %s",
+ papiStatusString(result));
+ return (result);
+ }
+
+ return (result);
+}
+
+/*
+ * Add/Modify the statuse-code and status-message in an IPP response's
+ * operational attributes group.
+ */
+void
+ipp_set_status(papi_attribute_t ***message, papi_status_t status,
+ char *format, ...)
+{
+ if (message == NULL)
+ return;
+
+ if (format != NULL) {
+ papi_attribute_t **operational = NULL;
+ papi_attribute_t **saved;
+ char mesg[256]; /* status-message is type text(255) */
+ va_list ap;
+
+ (void) papiAttributeListGetCollection(*message, NULL,
+ "operational-attributes-group",
+ &operational);
+ saved = operational;
+
+ va_start(ap, format);
+ (void) vsnprintf(mesg, sizeof (mesg), format, ap);
+ va_end(ap);
+
+ (void) papiAttributeListAddString(&operational,
+ PAPI_ATTR_APPEND, "status-message", mesg);
+
+ /*
+ * We need to check and see if adding the status-message caused
+ * the operational attributes group to be relocated in memory.
+ * If it has been, we will need to re-add the collection to
+ * the message.
+ */
+ if (saved != operational)
+ (void) papiAttributeListAddCollection(message,
+ PAPI_ATTR_REPLACE,
+ "operational-attributes-group",
+ operational);
+ }
+
+ (void) papiAttributeListAddInteger(message, PAPI_ATTR_APPEND,
+ "status-code", status);
+}
diff --git a/usr/src/lib/print/libipp-core/common/ipp.h b/usr/src/lib/print/libipp-core/common/ipp.h
new file mode 100644
index 0000000000..c13728e334
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/common/ipp.h
@@ -0,0 +1,348 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#ifndef _IPP_H
+#define _IPP_H
+
+/* $Id: ipp.h 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+#include <sys/time.h>
+#include <papi.h>
+#include <inttypes.h>
+
+
+typedef ssize_t (*ipp_reader_t)(void *fd, void *buffer, size_t buffer_size);
+typedef ssize_t (*ipp_writer_t)(void *fd, void *buffer, size_t buffer_size);
+
+enum {
+ IPP_TYPE_UNKNOWN = 0,
+ IPP_TYPE_REQUEST = 1,
+ IPP_TYPE_RESPONSE = 2
+};
+
+/*
+ * How closely do we conform to the spec when parsing? Do we
+ * a) Stop parsing only when we encounter an error that prevents us from
+ * continuing parsing (a server error or ridiculously malformed request)?
+ * b) Stop parsing when we know the server wouldn't be able to act on the
+ * response correctly, even if we can make sense of some of the data?
+ * c) Jawohl, Mein IPP Spec!
+ * The answer will usually be b, though a will be useful for debugging.
+ */
+enum {
+ IPP_PARSE_CONFORMANCE_RASH = 0,
+ IPP_PARSE_CONFORMANCE_LOOSE = 1,
+ IPP_PARSE_CONFORMANCE_STRICT = 2
+};
+
+
+/* Operation IDs */
+enum {
+ OPID_MIN = 0x0000, /* 0x0000 */
+ OPID_RESERVED_0000 = 0x0000, /* 0x0000 */
+ OPID_RESERVED_0001, /* 0x0001 */
+ OPID_PRINT_JOB, /* 0x0002 */
+ OPID_PRINT_URI, /* 0x0003 */
+ OPID_VALIDATE_JOB, /* 0x0004 */
+ OPID_CREATE_JOB, /* 0x0005 */
+ OPID_SEND_DOCUMENT, /* 0x0006 */
+ OPID_SEND_URI, /* 0x0007 */
+ OPID_CANCEL_JOB, /* 0x0008 */
+ OPID_GET_JOB_ATTRIBUTES, /* 0x0009 */
+ OPID_GET_JOBS, /* 0x000a */
+ OPID_GET_PRINTER_ATTRIBUTES, /* 0x000b */
+ OPID_HOLD_JOB, /* 0x000c */
+ OPID_RELEASE_JOB, /* 0x000d */
+ OPID_RESTART_JOB, /* 0x000e */
+ OPID_RESERVED_000F, /* 0x000f */
+ OPID_PAUSE_PRINTER, /* 0x0010 */
+ OPID_RESUME_PRINTER, /* 0x0011 */
+ OPID_PURGE_JOBS, /* 0x0012 */
+ OPID_SET_PRINTER_ATTRIBUTES, /* 0x0013 */
+ OPID_SET_JOB_ATTRIBUTES, /* 0x0014 */
+ OPID_GET_PRINTER_SUPPORTED_VALUES, /* 0x0015 */
+ OPID_CREATE_PRINTER_SUBSCRIPTION, /* 0x0016 */
+ OPID_CREATE_JOB_SUBSCRIPTION, /* 0x0017 */
+ OPID_GET_SUBSCRIPTION_ATTRIBUTES, /* 0x0018 */
+ OPID_GET_SUBSCRIPTIONS, /* 0x0019 */
+ OPID_RENEW_SUBSCRIPTION, /* 0x001a */
+ OPID_CANCEL_SUBSCRIPTION, /* 0x001b */
+ OPID_GET_NOTIFICATIONS, /* 0x001c */
+ OPID_SEND_NOTIFICATIONS, /* 0x001d */
+ OPID_GET_RESOURCE_ATTRIBUTES, /* 0x001e */
+ OPID_GET_RESOURCE_DATA, /* 0x001f */
+ OPID_GET_RESOURCES, /* 0x0020 */
+ OPID_GET_PRINT_SUPPORT_FILES, /* 0x0021 */
+ OPID_ENABLE_PRINTER, /* 0x0022 */
+ OPID_DISABLE_PRINTER, /* 0x0023 */
+ OPID_PAUSE_PRINTER_AFTER_CURRENT_JOB, /* 0x0024 */
+ OPID_HOLD_NEW_JOBS, /* 0x0025 */
+ OPID_RELEASE_HELD_NEW_JOBS, /* 0x0026 */
+ OPID_DEACTIVATE_PRINTER, /* 0x0027 */
+ OPID_ACTIVATE_PRINTER, /* 0x0028 */
+ OPID_RESTART_PRINTER, /* 0x0029 */
+ OPID_SHUTDOWN_PRINTER, /* 0x002a */
+ OPID_STARTUP_PRINTER, /* 0x002b */
+ OPID_REPROCESS_JOB, /* 0x002c */
+ OPID_CANCEL_CURRENT_JOB, /* 0x002d */
+ OPID_SUSPEND_CURRENT_JOB, /* 0x002e */
+ OPID_RESUME_JOB, /* 0x002f */
+ OPID_PROMOTE_JOB, /* 0x0030 */
+ OPID_SCHEDULE_JOB_AFTER, /* 0x0031 */
+ OPID_RESERVED_MIN, /* 0x0032 */
+ OPID_RESERVED_0032 = 0x0032, /* 0x0032 */
+ /* ... */
+ OPID_RESERVED_3FFF = 0x3fff, /* 0x3fff */
+ OPID_RESERVED_MAX = 0x3fff, /* 0x3fff */
+ OPID_RESERVED_VENDOR_MIN = 0x4000, /* 0x4000 */
+ OPID_RESERVED_VENDOR_4000 = 0x4000, /* 0x4000 */
+ /* ... */
+ OPID_RESERVED_VENDOR_8FFF = 0x8fff, /* 0x8fff */
+ OPID_RESERVED_VENDOR_MAX = 0x8fff, /* 0x8fff */
+ OPID_MAX = 0x8fff /* 0x8fff */
+};
+
+enum {
+ /* Delimiter Tags */
+ DTAG_MIN = 0x00, /* 0x00 */
+ DTAG_RESERVED_DELIMITER_00 = 0x00, /* 0x00 */
+ DTAG_OPERATION_ATTRIBUTES, /* 0x01 */
+ DTAG_JOB_ATTRIBUTES, /* 0x02 */
+ DTAG_END_OF_ATTRIBUTES, /* 0x03 */
+ DTAG_PRINTER_ATTRIBUTES, /* 0x04 */
+ DTAG_UNSUPPORTED_ATTRIBUTES, /* 0x05 */
+ DTAG_SUBSCRIPTION_ATTRIBUTES, /* 0x06 */
+ DTAG_EVENT_NOTIFICATION_ATTRIBUTES, /* 0x07 */
+ DTAG_RESERVED_DELIMITER_08, /* 0x08 */
+ DTAG_RESERVED_DELIMITER_09, /* 0x09 */
+ DTAG_RESERVED_DELIMITER_0A, /* 0x0a */
+ DTAG_RESERVED_DELIMITER_0B, /* 0x0b */
+ DTAG_RESERVED_DELIMITER_0C, /* 0x0c */
+ DTAG_RESERVED_DELIMITER_0D, /* 0x0d */
+ DTAG_RESERVED_DELIMITER_0E, /* 0x0e */
+ DTAG_RESERVED_DELIMITER_0F, /* 0x0f */
+ DTAG_MAX = 0x0f, /* 0x0f */
+
+ /* Value Tags */
+ VTAG_MIN = 0x10, /* 0x10 */
+ VTAG_UNSUPPORTED = 0x10, /* 0x10 */
+ VTAG_RESERVED_DEFAULT, /* 0x11 */
+ VTAG_UNKNOWN, /* 0x12 */
+ VTAG_NOVALUE, /* 0x13 */
+ VTAG_RESERVED_OOB_14, /* 0x14 */
+ VTAG_NOT_SETTABLE, /* 0x15 */
+ VTAG_DELETE_ATTRIBUTE, /* 0x16 */
+ VTAG_ADMIN_DEFINE, /* 0x17 */
+ VTAG_RESERVED_OOB_18, /* 0x18 */
+ VTAG_RESERVED_OOB_19, /* 0x19 */
+ VTAG_RESERVED_OOB_1A, /* 0x1a */
+ VTAG_RESERVED_OOB_1B, /* 0x1b */
+ VTAG_RESERVED_OOB_1C, /* 0x1c */
+ VTAG_RESERVED_OOB_1D, /* 0x1d */
+ VTAG_RESERVED_OOB_1E, /* 0x1e */
+ VTAG_RESERVED_OOB_1F, /* 0x1f */
+ VTAG_RESERVED_INT_GEN, /* 0x20 */
+ VTAG_INTEGER, /* 0x21 */
+ VTAG_BOOLEAN, /* 0x22 */
+ VTAG_ENUM, /* 0x23 */
+ VTAG_RESERVED_INT_24, /* 0x24 */
+ VTAG_RESERVED_INT_25, /* 0x25 */
+ VTAG_RESERVED_INT_26, /* 0x26 */
+ VTAG_RESERVED_INT_27, /* 0x27 */
+ VTAG_RESERVED_INT_28, /* 0x28 */
+ VTAG_RESERVED_INT_29, /* 0x29 */
+ VTAG_RESERVED_INT_2A, /* 0x2a */
+ VTAG_RESERVED_INT_2B, /* 0x2b */
+ VTAG_RESERVED_INT_2C, /* 0x2c */
+ VTAG_RESERVED_INT_2D, /* 0x2d */
+ VTAG_RESERVED_INT_2E, /* 0x2e */
+ VTAG_RESERVED_INT_2F, /* 0x2f */
+ VTAG_OCTET_STRING, /* 0x30 */
+ VTAG_DATE_TIME, /* 0x31 */
+ VTAG_RESOLUTION, /* 0x32 */
+ VTAG_RANGE_OF_INTEGER, /* 0x33 */
+ VTAG_BEGIN_COLLECTION, /* 0x34 */
+ VTAG_TEXT_WITH_LANGUAGE, /* 0x35 */
+ VTAG_NAME_WITH_LANGUAGE, /* 0x36 */
+ VTAG_END_COLLECTION, /* 0x37 */
+ VTAG_RESERVED_STRING_38, /* 0x38 */
+ VTAG_RESERVED_STRING_39, /* 0x39 */
+ VTAG_RESERVED_STRING_3A, /* 0x3a */
+ VTAG_RESERVED_STRING_3B, /* 0x3b */
+ VTAG_RESERVED_STRING_3C, /* 0x3c */
+ VTAG_RESERVED_STRING_3D, /* 0x3d */
+ VTAG_RESERVED_STRING_3E, /* 0x3e */
+ VTAG_RESERVED_STRING_3F, /* 0x3f */
+ VTAG_RESERVED_CHAR_GEN, /* 0x40 */
+ VTAG_TEXT_WITHOUT_LANGUAGE, /* 0x41 */
+ VTAG_NAME_WITHOUT_LANGUAGE, /* 0x42 */
+ VTAG_RESERVED_43, /* 0x43 */
+ VTAG_KEYWORD, /* 0x44 */
+ VTAG_URI, /* 0x45 */
+ VTAG_URI_SCHEME, /* 0x46 */
+ VTAG_CHARSET, /* 0x47 */
+ VTAG_NATURAL_LANGUAGE, /* 0x48 */
+ VTAG_MIME_MEDIA_TYPE, /* 0x49 */
+ VTAG_MEMBER_ATTR_NAME, /* 0x4a */
+ VTAG_RESERVED_STRING_4B, /* 0x4b */
+ VTAG_RESERVED_STRING_4C, /* 0x4c */
+ VTAG_RESERVED_STRING_4D, /* 0x4d */
+ VTAG_RESERVED_STRING_4E, /* 0x4e */
+ VTAG_RESERVED_STRING_4F, /* 0x4f */
+ VTAG_RESERVED_STRING_50, /* 0x50 */
+ VTAG_RESERVED_STRING_51, /* 0x51 */
+ VTAG_RESERVED_STRING_52, /* 0x52 */
+ VTAG_RESERVED_STRING_53, /* 0x53 */
+ VTAG_RESERVED_STRING_54, /* 0x54 */
+ VTAG_RESERVED_STRING_55, /* 0x55 */
+ VTAG_RESERVED_STRING_56, /* 0x56 */
+ VTAG_RESERVED_STRING_57, /* 0x57 */
+ VTAG_RESERVED_STRING_58, /* 0x58 */
+ VTAG_RESERVED_STRING_59, /* 0x59 */
+ VTAG_RESERVED_STRING_5A, /* 0x5a */
+ VTAG_RESERVED_STRING_5B, /* 0x5b */
+ VTAG_RESERVED_STRING_5C, /* 0x5c */
+ VTAG_RESERVED_STRING_5D, /* 0x5d */
+ VTAG_RESERVED_STRING_5E, /* 0x5e */
+ VTAG_RESERVED_STRING_5F, /* 0x5f */
+ VTAG_RESERVED_MAX = 0x5f, /* 0x5f */
+ VTAG_MAX = 0x5f, /* 0x5f */
+ VTAG_EXTEND = 0x7f /* 0x7f */
+};
+
+/* Response codes */
+enum {
+ IPP_OK_MIN = 0x0000,
+ IPP_OK = 0x0000, /* 0x0000 */
+ IPP_OK_IGNORED_ATTRIBUTES, /* 0x0001 */
+ IPP_OK_CONFLICTING_ATTRIBUTES, /* 0x0002 */
+ IPP_OK_IGNORED_SUBSCRIPTIONS, /* 0x0003 */
+ IPP_OK_IGNORED_NOTIFICATIONS, /* 0x0004 */
+ IPP_OK_TOO_MANY_EVENTS, /* 0x0005 */
+ IPP_OK_BUT_CANCEL_SUBSCRIPTION, /* 0x0006 */
+ IPP_OK_MAX = IPP_OK_BUT_CANCEL_SUBSCRIPTION,
+
+ IPP_REDIR_MIN = 0x0300,
+ IPP_REDIR_OTHER_SIZE = 0x0300, /* 0x0300 */
+ IPP_REDIR_MAX = 0x0300,
+
+ IPP_CERR_MIN = 0x0400,
+ IPP_CERR_BAD_REQUEST = 0x0400, /* 0x0400 */
+ IPP_CERR_FORBIDDEN, /* 0x0401 */
+ IPP_CERR_NOT_AUTHENTICATED, /* 0x0402 */
+ IPP_CERR_NOT_AUTHORIZED, /* 0x0403 */
+ IPP_CERR_NOT_POSSIBLE, /* 0x0404 */
+ IPP_CERR_TIMEOUT, /* 0x0405 */
+ IPP_CERR_NOT_FOUND, /* 0x0406 */
+ IPP_CERR_GONE, /* 0x0407 */
+ IPP_CERR_REQUEST_ENTITY, /* 0x0408 */
+ IPP_CERR_REQUEST_VALUE, /* 0x0409 */
+ IPP_CERR_DOCUMENT_FORMAT, /* 0x040a */
+ IPP_CERR_ATTRIBUTES, /* 0x040b */
+ IPP_CERR_URI_SCHEME, /* 0x040c */
+ IPP_CERR_CHARSET, /* 0x040d */
+ IPP_CERR_CONFLICT, /* 0x040e */
+ IPP_CERR_COMPRESSION_NOT_SUPPORTED, /* 0x040f */
+ IPP_CERR_COMPRESSION_ERROR, /* 0x0410 */
+ IPP_CERR_DOCUMENT_FORMAT_ERROR, /* 0x0411 */
+ IPP_CERR_DOCUMENT_ACCESS_ERROR, /* 0x0412 */
+ IPP_CERR_ATTRIBUTES_NOT_SETTABLE, /* 0x0413 */
+ IPP_CERR_IGNORED_ALL_SUBSCRIPTIONS, /* 0x0414 */
+ IPP_CERR_TOO_MANY_SUBSCRIPTIONS, /* 0x0415 */
+ IPP_CERR_IGNORED_ALL_NOTIFICATIONS, /* 0x0416 */
+ IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND, /* 0x0417 */
+ IPP_CERR_MAX = IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND,
+
+ IPP_SERR_MIN = 0x0500,
+ IPP_SERR_INTERNAL = 0x0500, /* 0x0500 */
+ IPP_SERR_OPERATION_NOT_SUPPORTED, /* 0x0501 */
+ IPP_SERR_SERVICE_UNAVAILABLE, /* 0x0502 */
+ IPP_SERR_VERSION_NOT_SUPPORTED, /* 0x0503 */
+ IPP_SERR_DEVICE_ERROR, /* 0x0504 */
+ IPP_SERR_TEMPORARY_ERROR, /* 0x0505 */
+ IPP_SERR_NOT_ACCEPTING, /* 0x0506 */
+ IPP_SERR_BUSY, /* 0x0507 */
+ IPP_SERR_CANCELLED, /* 0x0508 */
+ IPP_SERR_MULTIPLE_DOCS_NOT_SUPPORTED, /* 0x0509 */
+ IPP_SERR_PRINTER_IS_DEACTIVATED, /* 0x050a */
+ IPP_SERR_MAX = IPP_SERR_PRINTER_IS_DEACTIVATED
+};
+
+/* Job state codes */
+enum {
+ IPP_JOB_STATE_PENDING = 3,
+ IPP_JOB_STATE_PENDING_HELD = 4,
+ IPP_JOB_STATE_PROCESSING = 5,
+ IPP_JOB_STATE_PROCESSING_STOPPED = 6,
+ IPP_JOB_STATE_CANCELED = 7,
+ IPP_JOB_STATE_ABORTED = 8,
+ IPP_JOB_STATE_COMPLETED = 9
+};
+
+/* exported functions */
+extern papi_status_t ipp_read_message(ipp_reader_t iread, void *fd,
+ papi_attribute_t ***message, char type);
+
+extern papi_status_t ipp_write_message(ipp_writer_t iwrite, void *fd,
+ papi_attribute_t **message);
+
+/* internal functions shared between modules */
+extern void ipp_set_status(papi_attribute_t ***message, papi_status_t status,
+ char *format, ...);
+extern papi_status_t ipp_validate_request(papi_attribute_t **request,
+ papi_attribute_t ***response);
+
+extern int ipp_severity(int16_t status);
+
+extern int16_t ipp_charset_supported(char *charset);
+
+extern void *string_to_ipp_attr_value(int8_t type, char *value);
+
+extern char *ipp_uri_to_printer(char *uri);
+extern void *papi_attribute_to_ipp_attr(int8_t type, papi_attribute_t *attr);
+
+extern int8_t name_to_ipp_type(char *name);
+extern char *job_template[];
+extern char *job_description[];
+extern char *printer_description[];
+extern char *ipp_tag_string(int8_t tag, char *buf, size_t bufsiz);
+extern size_t min_val_len(int8_t type, char *name);
+extern size_t max_val_len(int8_t type, char *name);
+extern int is_keyword(char *value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IPP_H */
diff --git a/usr/src/lib/print/libipp-core/common/ipp_types.c b/usr/src/lib/print/libipp-core/common/ipp_types.c
new file mode 100644
index 0000000000..47fc32c259
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/common/ipp_types.c
@@ -0,0 +1,303 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: ipp_types.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ipp.h>
+#include <errno.h>
+#include <values.h>
+
+#ifndef MININT
+#define MININT (-MAXINT - 1)
+#endif
+
+typedef struct {
+ char *name;
+ int8_t ipp_type;
+ int min;
+ int max;
+} attr_info_list_t;
+
+static attr_info_list_t attr_list[] = {
+ {"operation-attribute-group", DTAG_OPERATION_ATTRIBUTES, 0, 0},
+ {"job-attribute-group", DTAG_JOB_ATTRIBUTES, 0, 0},
+ {"printer-attribute-group", DTAG_PRINTER_ATTRIBUTES, 0, 0},
+ {"unsupported-attribute-group", DTAG_UNSUPPORTED_ATTRIBUTES, 0, 0},
+ {"subscription-attribute-group", DTAG_SUBSCRIPTION_ATTRIBUTES, 0, 0},
+ {"even-notificaton-attribute-group",
+ DTAG_EVENT_NOTIFICATION_ATTRIBUTES, 0, 0},
+ {"attributes-charset", VTAG_CHARSET, 0, 255},
+ {"attributes-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255},
+ {"charset-configured", VTAG_CHARSET, 0, 255},
+ {"charset-supported", VTAG_CHARSET, 0, 255},
+ {"color-supported", VTAG_BOOLEAN, 0, 1},
+ {"compression", VTAG_KEYWORD, 1, 255},
+ {"compression-supported", VTAG_KEYWORD, 1, 255},
+ {"copies", VTAG_INTEGER, 1, MAXINT},
+ {"copies-default", VTAG_INTEGER, 1, MAXINT},
+ {"copies-supported", VTAG_RANGE_OF_INTEGER, 1, MAXINT},
+ {"date-at-completed", VTAG_DATE_TIME, 0, 0},
+ {"date-at-creation", VTAG_DATE_TIME, 0, 0},
+ {"date-at-processing", VTAG_DATE_TIME, 0, 0},
+ {"detailed-status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
+ {"document-access-error", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
+ {"document-format", VTAG_MIME_MEDIA_TYPE, 0, 255},
+ {"document-format-default", VTAG_MIME_MEDIA_TYPE, 0, 255},
+ {"document-format-supported", VTAG_MIME_MEDIA_TYPE, 0, 255},
+ {"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"document-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255},
+ {"finishing", VTAG_ENUM, 3, 31},
+ {"finishing-default", VTAG_ENUM, 3, 31},
+ {"finishing-supported", VTAG_ENUM, 3, 31},
+ {"generated-natural-language-supported", VTAG_NATURAL_LANGUAGE, 0, 255},
+ {"ipp-attribute-fidelity", VTAG_BOOLEAN, 0, 1},
+ {"ipp-versions-supported", VTAG_KEYWORD, 1, 255},
+ {"job-detailed-status-messages", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
+ {"job-document-access-errors", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
+ {"job-hold-until", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"job-hold-until-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"job-hold-until-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"job-id", VTAG_INTEGER, 1, MAXINT},
+ {"job-impressions", VTAG_INTEGER, 0, MAXINT},
+ {"job-impressions-completed", VTAG_INTEGER, 0, MAXINT},
+ {"job-impressions-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT},
+ {"job-k-octets", VTAG_INTEGER, 0, MAXINT},
+ {"job-k-octets-processed", VTAG_INTEGER, 0, MAXINT},
+ {"job-k-octets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT},
+ {"job-media-sheets", VTAG_INTEGER, 0, MAXINT},
+ {"job-media-sheets-completed", VTAG_INTEGER, 0, MAXINT},
+ {"job-media-sheets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT},
+ {"job-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
+ {"job-more-info", VTAG_URI, 0, 1023},
+ {"job-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"job-originating-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"job-printer-up-time", VTAG_INTEGER, 1, MAXINT},
+ {"job-printer-uri", VTAG_URI, 0, 1023},
+ {"job-priority", VTAG_INTEGER, 1, 100},
+ {"job-priority-default", VTAG_INTEGER, 1, 100},
+ {"job-priority-supported", VTAG_INTEGER, 1, 100},
+ {"job-sheets", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"job-sheets-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"job-sheets-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"job-state", VTAG_ENUM, 3, 9},
+ {"job-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
+ {"job-state-reasons", VTAG_KEYWORD, 1, 255},
+ {"job-uri", VTAG_URI, 0, 1023},
+ {"last-document", VTAG_BOOLEAN, 0, 1},
+ {"limit", VTAG_INTEGER, 1, MAXINT},
+ {"media", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"media-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"media-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
+ {"multiple-document-handling", VTAG_KEYWORD, 1, 255},
+ {"multiple-document-handling-default", VTAG_KEYWORD, 1, 255},
+ {"multiple-document-handling-supported", VTAG_KEYWORD, 1, 255},
+ {"multiple-document-jobs-supported", VTAG_BOOLEAN, 0, 1},
+ {"multiple-operation-time-out", VTAG_INTEGER, 1, MAXINT},
+ {"my-jobs", VTAG_BOOLEAN, 0, 1},
+ {"natural-language-configured", VTAG_NATURAL_LANGUAGE, 0, 255},
+ {"number-of-documents", VTAG_INTEGER, 0, MAXINT},
+ {"number-of-intervening-jobs", VTAG_INTEGER, 0, MAXINT},
+ {"number-up", VTAG_INTEGER, 1, MAXINT},
+ {"number-up-default", VTAG_INTEGER, 1, MAXINT},
+ {"number-up-supported", VTAG_INTEGER, 1, MAXINT},
+ {"operations-supported", VTAG_ENUM, 1, 0x8FFF},
+ {"orientation-requested", VTAG_ENUM, 3, 6},
+ {"orientation-requested-default", VTAG_ENUM, 3, 6},
+ {"orientation-requested-supported", VTAG_ENUM, 3, 6},
+ {"output-device-assigned", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127},
+ {"page-ranges", VTAG_RANGE_OF_INTEGER, 1, MAXINT},
+ {"page-ranges-supported", VTAG_BOOLEAN, 0, 1},
+ {"pages-per-minute", VTAG_INTEGER, 0, MAXINT},
+ {"pages-per-minute-color", VTAG_INTEGER, 0, MAXINT},
+ {"pdl-override-supported", VTAG_KEYWORD, 1, 255},
+ {"print-quality", VTAG_ENUM, 3, 5},
+ {"print-quality-default", VTAG_ENUM, 3, 5},
+ {"print-quality-supported", VTAG_ENUM, 3, 5},
+ {"printer-current-time", VTAG_DATE_TIME, 0, 1},
+ {"printer-driver-installer", VTAG_URI, 0, 1023},
+ {"printer-id", VTAG_INTEGER, 1, MAXINT},
+ {"printer-info", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
+ {"printer-is-accepting-jobs", VTAG_BOOLEAN, 0, 1},
+ {"printer-location", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
+ {"printer-make-and-model", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
+ {"printer-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127},
+ {"printer-more-info", VTAG_URI, 0, 1023},
+ {"printer-more-info-manufacturer", VTAG_URI, 0, 1023},
+ {"printer-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127},
+ {"printer-resolution", VTAG_RESOLUTION, 0, 0},
+ {"printer-resolution-default", VTAG_RESOLUTION, 0, 0},
+ {"printer-resolution-supported", VTAG_RESOLUTION, 0, 0},
+ {"printer-state", VTAG_ENUM, 3, 5},
+ {"printer-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023},
+ {"printer-state-reasons", VTAG_KEYWORD, 1, 255},
+ {"printer-up-time", VTAG_INTEGER, 1, MAXINT},
+ {"printer-uri", VTAG_URI, 0, 1023},
+ {"printer-uri-supported", VTAG_URI, 0, 1023},
+ {"queued-job-count", VTAG_INTEGER, 0, MAXINT},
+ {"reference-uri-schemes-supported", VTAG_URI_SCHEME, 0, 63},
+ {"requested-attributes", VTAG_KEYWORD, 1, 255},
+ {"requesting-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255},
+ {"sides", VTAG_KEYWORD, 1, 255},
+ {"sides-default", VTAG_KEYWORD, 1, 255},
+ {"sides-supported", VTAG_KEYWORD, 1, 255},
+ {"status-code", VTAG_ENUM, 1, 0x7FFF},
+ {"status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 255},
+ {"time-at-completed", VTAG_INTEGER, MININT, MAXINT},
+ {"time-at-creation", VTAG_INTEGER, MININT, MAXINT},
+ {"time-at-processing", VTAG_INTEGER, MININT, MAXINT},
+ {"uri-authentication-supported", VTAG_KEYWORD, 1, 255},
+ {"uri-security-supported", VTAG_KEYWORD, 1, 255},
+ {"which-jobs", VTAG_KEYWORD, 1, 255},
+ {NULL, 0, 0, 0}
+};
+
+
+static attr_info_list_t *
+get_attr_info_by_name(char *name)
+{
+ if (name != NULL) {
+ int i;
+
+ for (i = 0; attr_list[i].name != NULL; i++)
+ if (strcasecmp(attr_list[i].name, name) == 0)
+ return (&attr_list[i]);
+ }
+
+ return (NULL);
+}
+
+size_t
+max_val_len(int8_t type, char *name)
+{
+ attr_info_list_t *t;
+ int result;
+
+ switch (type) {
+ case VTAG_INTEGER:
+ case VTAG_RANGE_OF_INTEGER:
+ case VTAG_ENUM:
+ result = MAXINT;
+ break;
+ case VTAG_URI:
+ case VTAG_OCTET_STRING:
+ case VTAG_TEXT_WITHOUT_LANGUAGE:
+ result = 1023;
+ break;
+ case VTAG_NATURAL_LANGUAGE:
+ case VTAG_URI_SCHEME:
+ case VTAG_CHARSET:
+ result = 63;
+ break;
+ case VTAG_NAME_WITHOUT_LANGUAGE:
+ case VTAG_MIME_MEDIA_TYPE:
+ case VTAG_KEYWORD:
+ result = 255;
+ break;
+ default:
+ result = MAXINT;
+ }
+
+#define min(a, b) ((a < b) ? a : b)
+ if ((t = get_attr_info_by_name(name)) != NULL)
+ result = min(t->max, result);
+#undef min
+
+ return (result);
+}
+
+size_t
+min_val_len(int8_t type, char *name)
+{
+ attr_info_list_t *t;
+ int result;
+
+ switch (type) {
+ case VTAG_INTEGER:
+ case VTAG_RANGE_OF_INTEGER:
+ result = MININT;
+ break;
+ case VTAG_ENUM:
+ result = 1;
+ break;
+ case VTAG_URI:
+ case VTAG_OCTET_STRING:
+ case VTAG_TEXT_WITHOUT_LANGUAGE:
+ case VTAG_MIME_MEDIA_TYPE:
+ case VTAG_NAME_WITHOUT_LANGUAGE:
+ case VTAG_URI_SCHEME:
+ case VTAG_CHARSET:
+ case VTAG_NATURAL_LANGUAGE:
+ result = 0;
+ break;
+ case VTAG_KEYWORD:
+ result = 1;
+ break;
+ default:
+ result = MININT;
+ }
+
+#define max(a, b) ((a > b) ? a : b)
+ if ((t = get_attr_info_by_name(name)) != NULL)
+ result = max(t->min, result);
+#undef max
+
+ return (result);
+}
+
+int
+is_keyword(char *k)
+{
+ /* [a-z][a-z0-9._-]* */
+ if (*k < 'a' && *k > 'z')
+ return (0);
+ while (*(++k) != '\0')
+ if (*k < 'a' && *k > 'z' && *k < '0' && *k > '9' &&
+ *k != '.' && *k != '_' && *k != '-')
+ return (0);
+ return (1);
+}
+
+int8_t
+name_to_ipp_type(char *name)
+{
+ int i;
+
+ if (name != NULL)
+ for (i = 0; attr_list[i].name != NULL; i++)
+ if (strcasecmp(attr_list[i].name, name) == 0)
+ return (attr_list[i].ipp_type);
+
+ return (0);
+}
diff --git a/usr/src/lib/print/libipp-core/common/mapfile b/usr/src/lib/print/libipp-core/common/mapfile
new file mode 100644
index 0000000000..7911a40932
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/common/mapfile
@@ -0,0 +1,48 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# $Id: mapfile 151 2006-04-25 16:55:34Z njacobs $
+
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+
+#
+# Common interfaces that are most likely to be shared amongst the various
+# PAPI implementations.
+#
+
+SUNWprivate_1.0 {
+ global:
+ ipp_read_message ;
+ ipp_write_message ;
+ ipp_validate_request ;
+ ipp_set_status ;
+
+ local:
+ * ;
+} ;
diff --git a/usr/src/lib/print/libipp-core/common/read.c b/usr/src/lib/print/libipp-core/common/read.c
new file mode 100644
index 0000000000..8bfca1e15b
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/common/read.c
@@ -0,0 +1,666 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: read.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <alloca.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <inttypes.h>
+
+#include <papi.h>
+#include <ipp.h>
+
+
+#define _ipp_tag_string(id) ipp_tag_string((id), buf, sizeof (buf))
+
+static papi_status_t
+read_name_with_language(ipp_reader_t iread, void *fd,
+ papi_attribute_t ***message)
+{
+ char *string;
+ uint16_t size;
+
+ /* read the language */
+ if (iread(fd, &size, 2) != 2) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "read failed: lang len\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ size = (uint16_t)ntohs(size);
+
+ if ((string = alloca(size + 1)) == NULL) {
+ ipp_set_status(message, PAPI_TEMPORARY_ERROR,
+ "Memory allocation failed");
+ return (PAPI_TEMPORARY_ERROR);
+ }
+ if (iread(fd, string, size) != size) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "read failed: lang\n");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /* read the text */
+ if (iread(fd, &size, 2) != 2) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "read failed: text len\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ size = (uint16_t)ntohs(size);
+
+ if ((string = alloca(size + 1)) == NULL) {
+ ipp_set_status(message, PAPI_TEMPORARY_ERROR,
+ "Memory allocation failed");
+ return (PAPI_TEMPORARY_ERROR);
+ }
+ if (iread(fd, string, size) != size) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "read failed: text\n");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ return (PAPI_OK);
+}
+
+
+static struct {
+ int8_t ipp_type;
+ int8_t size;
+} type_info[] = {
+ { VTAG_INTEGER, 4 },
+ { VTAG_ENUM, 4 },
+ { VTAG_BOOLEAN, 1 },
+ { VTAG_RANGE_OF_INTEGER, 8 },
+ { VTAG_RESOLUTION, 9 },
+ { VTAG_DATE_TIME, 11 },
+ { DTAG_MIN, 0 }
+};
+
+/* verify that the IPP type and size are compatible */
+static int
+validate_length(int8_t type, int8_t size)
+{
+ int i;
+
+ for (i = 0; type_info[i].ipp_type != DTAG_MIN; i++)
+ if (type_info[i].ipp_type == type)
+ return ((type_info[i].size == size) ? 0 : -1);
+ return (0);
+}
+
+/* convert tyep IPP type to a type that is marginally compatible */
+static int8_t
+base_type(int8_t i)
+{
+ switch (i) {
+ case VTAG_ENUM:
+ case VTAG_INTEGER:
+ return (VTAG_INTEGER);
+ case VTAG_URI:
+ case VTAG_OCTET_STRING:
+ case VTAG_TEXT_WITHOUT_LANGUAGE:
+ case VTAG_URI_SCHEME:
+ case VTAG_CHARSET:
+ case VTAG_NATURAL_LANGUAGE:
+ case VTAG_MIME_MEDIA_TYPE:
+ case VTAG_NAME_WITHOUT_LANGUAGE:
+ case VTAG_KEYWORD:
+ return (VTAG_TEXT_WITHOUT_LANGUAGE);
+ case VTAG_BOOLEAN:
+ case VTAG_RANGE_OF_INTEGER:
+ case VTAG_DATE_TIME:
+ case VTAG_RESOLUTION:
+ default:
+ return (i);
+ }
+}
+
+/* verify that the IPP type is correct for the named attribute */
+static papi_status_t
+validate_type(char *name, int8_t type)
+{
+ int8_t t = name_to_ipp_type(name);
+
+ if (t == 0) /* The attribute is not defined in the RFC */
+ return (PAPI_NOT_FOUND);
+ else if (t == type) /* The supplied type matched the RFC type */
+ return (PAPI_OK);
+ else { /* The supplied type doesn't match the RFC */
+ if (base_type(t) == base_type(type))
+ return (PAPI_OK);
+
+ return (PAPI_CONFLICT);
+ }
+}
+
+/* verify that the IPP value is within specification for the named attribute */
+static int
+validate_value(papi_attribute_t ***message, char *name, int8_t type, ...)
+{
+#define within(a, b, c) ((b >= a) && (b <= c))
+ va_list ap;
+ int rc = -1;
+ int min = min_val_len(type, name),
+ max = max_val_len(type, name);
+ char buf[64]; /* For _ipp_<...>_string() */
+
+ va_start(ap, type);
+ switch (type) {
+ case VTAG_ENUM:
+ case VTAG_INTEGER: {
+ int32_t i = (int32_t)va_arg(ap, int32_t);
+
+ if (within(min, i, max))
+ rc = 0;
+ else
+ ipp_set_status(message, PAPI_BAD_ARGUMENT,
+ "%s(%s): %d: out of range (%d - %d)", name,
+ _ipp_tag_string(type), i, min, max);
+ }
+ break;
+ case VTAG_BOOLEAN: {
+ int8_t v = (int8_t)va_arg(ap, int);
+
+ if (within(0, v, 1))
+ rc = 0;
+ else
+ ipp_set_status(message, PAPI_BAD_ARGUMENT,
+ "%s(%s): %d: out of range (0 - 1)", name,
+ _ipp_tag_string(type), v);
+ }
+ break;
+ case VTAG_RANGE_OF_INTEGER: {
+ int32_t lower = (int32_t)va_arg(ap, int32_t);
+ int32_t upper = (int32_t)va_arg(ap, int32_t);
+
+ if (within(min, lower, max) &&
+ within(min, upper, max))
+ rc = 0;
+ else
+ ipp_set_status(message, PAPI_BAD_ARGUMENT,
+ "%s(%s): %d - %d: out of range (%d - %d)", name,
+ _ipp_tag_string(type), lower, upper, min, max);
+ }
+ break;
+ case VTAG_URI:
+ case VTAG_OCTET_STRING:
+ case VTAG_TEXT_WITHOUT_LANGUAGE:
+ case VTAG_URI_SCHEME:
+ case VTAG_CHARSET:
+ case VTAG_NATURAL_LANGUAGE:
+ case VTAG_MIME_MEDIA_TYPE:
+ case VTAG_NAME_WITHOUT_LANGUAGE: {
+ char *v = (char *)va_arg(ap, char *);
+
+ if (strlen(v) < max)
+ rc = 0;
+ else
+ ipp_set_status(message, PAPI_BAD_ARGUMENT,
+ "%s(%s): %s: too long (max length: %d)", name,
+ _ipp_tag_string(type), v, max);
+ }
+ break;
+ case VTAG_KEYWORD: {
+ char *v = (char *)va_arg(ap, char *);
+
+ if (strlen(v) >= max)
+ ipp_set_status(message, PAPI_BAD_ARGUMENT,
+ "%s(%s): %s: too long (max length: %d)", name,
+ _ipp_tag_string(type), v, max);
+ else if (is_keyword(v) == 0)
+ ipp_set_status(message, PAPI_BAD_ARGUMENT,
+ "%s(%s): %s: invalid keyword", name,
+ _ipp_tag_string(type), v);
+ else
+ rc = 0;
+ }
+ break;
+ case VTAG_DATE_TIME:
+ case VTAG_RESOLUTION:
+ default:
+ rc = 0;
+ }
+ va_end(ap);
+
+ return (rc);
+#undef within
+}
+
+/*
+ * read_attr_group() reads in enough of the message data to parse an entire
+ * attribute group. Since to determine that the group is finished you have to
+ * read the character that determines the type of the next group, this function
+ * must return that character, in order that our caller knows how to call us for
+ * the next group. Thus type is used both as an input parameter (the type of
+ * attribute group to read in) and an output parameter (the type of the next
+ * attribute group).
+ */
+
+static papi_status_t
+ipp_read_attribute_group(ipp_reader_t iread, void *fd, int8_t *type,
+ papi_attribute_t ***message)
+{
+ int8_t value_tag;
+ uint16_t name_length, value_length;
+ papi_attribute_t **attributes = NULL;
+ char *name = NULL;
+ int i;
+ char buf[64]; /* For _ipp_<...>_string() */
+
+ /*
+ * RFC2910 3.3 says we need to handle `An expected but missing
+ * "begin-attribute-group-tag" field. How?
+ */
+ if (*type > DTAG_MAX) {
+ /* Scream bloody murder, or assign a new type? */
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "Bad attribute group tag 0x%.2hx (%s)",
+ *type, _ipp_tag_string(*type));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /* This loops through *values* not *attributes*! */
+ for (i = 0; ; i++) {
+ papi_status_t valid = PAPI_OK;
+ if (iread(fd, &value_tag, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: value tag\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ /* are we done with this group ? */
+ if (value_tag <= DTAG_MAX)
+ break;
+
+ if (iread(fd, &name_length, 2) != 2) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: name length\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ name_length = (uint16_t)ntohs(name_length);
+
+ /* Not just another value for the previous attribute */
+ if (name_length != 0) {
+ if ((name = alloca(name_length + 1)) == NULL) {
+ ipp_set_status(message, PAPI_TEMPORARY_ERROR,
+ "alloca(): failed\n");
+ return (PAPI_TEMPORARY_ERROR);
+ }
+ (void) memset(name, 0, name_length + 1);
+
+ if (iread(fd, name, name_length) != name_length) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: name\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ }
+
+ valid = validate_type(name, value_tag);
+ if ((valid != PAPI_OK) && (valid != PAPI_NOT_FOUND))
+ ipp_set_status(message, valid, "%s(%s): %s", name,
+ _ipp_tag_string(value_tag),
+ papiStatusString(valid));
+
+ if (iread(fd, &value_length, 2) != 2) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: value length\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ value_length = (uint16_t)ntohs(value_length);
+
+ if (validate_length(value_tag, value_length) < 0) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "Bad value length (%d) for type %s",
+ value_length, _ipp_tag_string(value_tag));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ switch (value_tag) {
+ case VTAG_INTEGER:
+ case VTAG_ENUM: {
+ int32_t v;
+
+ if (iread(fd, &v, value_length) != value_length) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: int/enum\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ v = (int32_t)ntohl(v);
+ (void) validate_value(message, name, value_tag, v);
+ papiAttributeListAddInteger(&attributes,
+ PAPI_ATTR_APPEND, name, v);
+
+ }
+ break;
+ case VTAG_BOOLEAN: {
+ int8_t v;
+
+ if (iread(fd, &v, value_length) != value_length) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: boolean\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ (void) validate_value(message, name, value_tag, v);
+ papiAttributeListAddBoolean(&attributes,
+ PAPI_ATTR_APPEND, name, v);
+ }
+ break;
+ case VTAG_RANGE_OF_INTEGER: {
+ int32_t min, max;
+
+ if (iread(fd, &min, 4) != 4) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: min\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ if (iread(fd, &max, 4) != 4) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: max\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ min = (int32_t)ntohl(min);
+ max = (int32_t)ntohl(max);
+ (void) validate_value(message, name, value_tag,
+ min, max);
+ papiAttributeListAddRange(&attributes, PAPI_ATTR_APPEND,
+ name, min, max);
+ }
+ break;
+ case VTAG_RESOLUTION: {
+ int32_t x, y;
+ int8_t units;
+
+ if (iread(fd, &x, 4) != 4) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: x\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ if (iread(fd, &y, 4) != 4) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: y\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ if (iread(fd, &units, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: units\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ x = (int32_t)ntohl(x);
+ y = (int32_t)ntohl(y);
+ papiAttributeListAddResolution(&attributes,
+ PAPI_ATTR_APPEND, name, x, y,
+ (papi_resolution_unit_t)units);
+ }
+ break;
+ case VTAG_DATE_TIME: {
+ struct tm tm;
+ time_t v;
+ int8_t c;
+ uint16_t s;
+
+ (void) memset(&tm, 0, sizeof (tm));
+ if (iread(fd, &s, 2) != 2) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: year\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ tm.tm_year = (uint16_t)ntohs(s) - 1900;
+ if (iread(fd, &c, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: month\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ tm.tm_mon = c - 1;
+ if (iread(fd, &c, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: day\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ tm.tm_mday = c;
+ if (iread(fd, &c, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: hour\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ tm.tm_hour = c;
+ if (iread(fd, &c, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: minutes\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ tm.tm_min = c;
+ if (iread(fd, &c, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: seconds\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ tm.tm_sec = c;
+ if (iread(fd, &c, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: decisec\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ /* tm.deciseconds = c; */
+ if (iread(fd, &c, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: utc_dir\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ /* tm.utc_dir = c; */
+ if (iread(fd, &c, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: utc_hour\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ /* tm.utc_hours = c; */
+ if (iread(fd, &c, 1) != 1) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: utc_min\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ /* tm.utc_minutes = c; */
+
+ v = mktime(&tm);
+
+ (void) validate_value(message, name, value_tag, v);
+ papiAttributeListAddDatetime(&attributes,
+ PAPI_ATTR_APPEND, name, v);
+ }
+ break;
+ case VTAG_NAME_WITH_LANGUAGE:
+ case VTAG_TEXT_WITH_LANGUAGE:
+ /*
+ * we are dropping this because we don't support
+ * name with language at this time.
+ */
+ (void) read_name_with_language(iread, fd, message);
+ break;
+ case VTAG_NAME_WITHOUT_LANGUAGE:
+ case VTAG_TEXT_WITHOUT_LANGUAGE:
+ case VTAG_URI:
+ case VTAG_KEYWORD:
+ case VTAG_CHARSET: {
+ char *v;
+
+ if ((v = calloc(1, value_length + 1)) == NULL) {
+ ipp_set_status(message, PAPI_TEMPORARY_ERROR,
+ "calloc(): failed\n");
+ return (PAPI_TEMPORARY_ERROR);
+ }
+#ifdef NOTDEF
+ if (iread(fd, v, value_length) != value_length) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: stringy\n");
+ return (PAPI_BAD_REQUEST);
+ }
+#else
+ {
+ int rc, i = value_length;
+ char *p = v;
+
+ while ((rc = iread(fd, p, i)) != i) {
+ if (rc <= 0) {
+ ipp_set_status(message,
+ PAPI_BAD_REQUEST,
+ "bad read: stringy\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ i -= rc;
+ p += rc;
+ }
+ }
+#endif
+ (void) validate_value(message, name, value_tag, v);
+ papiAttributeListAddString(&attributes,
+ PAPI_ATTR_APPEND, name, v);
+ }
+ break;
+ case VTAG_UNKNOWN:
+ case VTAG_NOVALUE:
+ case VTAG_UNSUPPORTED:
+ papiAttributeListAddValue(&attributes, PAPI_ATTR_EXCL,
+ name, PAPI_COLLECTION, NULL);
+ break;
+ default: {
+ char *v;
+
+ if ((v = calloc(1, value_length + 1)) == NULL) {
+ ipp_set_status(message, PAPI_TEMPORARY_ERROR,
+ "calloc(): failed\n");
+ return (PAPI_TEMPORARY_ERROR);
+ }
+ if (iread(fd, v, value_length) != value_length) {
+ ipp_set_status(message, PAPI_BAD_REQUEST,
+ "bad read: other\n");
+ return (PAPI_BAD_REQUEST);
+ }
+ papiAttributeListAddString(&attributes,
+ PAPI_ATTR_APPEND, name, v);
+ }
+ break;
+ }
+ }
+
+ if (attributes != NULL) {
+ char name[32];
+
+ (void) ipp_tag_string(*type, name, sizeof (name));
+ papiAttributeListAddCollection(message, PAPI_ATTR_APPEND, name,
+ attributes);
+ }
+
+ *type = value_tag;
+
+ return (PAPI_OK);
+}
+
+
+static papi_status_t
+ipp_read_header(ipp_reader_t iread, void *fd, papi_attribute_t ***message,
+ char type)
+{
+ char *attr_name = "status-code"; /* default to a response */
+ char buf[8];
+ int8_t c;
+ uint16_t s;
+ int32_t i;
+
+ if ((iread == NULL) || (fd == NULL) || (message == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /*
+ * Apache 1.X uses the buffer supplied to it's read call to read in
+ * the chunk size when chunking is used. This causes problems
+ * reading the header a piece at a time, because we don't have
+ * enough room to read in the chunk size prior to reading the
+ * chunk.
+ */
+
+ if (iread(fd, buf, 8) != 8)
+ return (PAPI_BAD_REQUEST);
+
+ c = buf[0];
+ (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE,
+ "version-major", c);
+
+ c = buf[1];
+ (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE,
+ "version-minor", c);
+
+ memcpy(&s, &buf[2], 2);
+ s = (uint16_t)ntohs(s);
+ if (type == IPP_TYPE_REQUEST)
+ attr_name = "operation-id";
+ (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE,
+ attr_name, s);
+
+ memcpy(&s, &buf[4], 4);
+ i = (uint32_t)ntohl(i);
+ (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE,
+ "request-id", i);
+
+ return (PAPI_OK);
+}
+
+static papi_status_t
+ipp_read_attribute_groups(ipp_reader_t iread, void *fd,
+ papi_attribute_t ***message)
+{
+ papi_status_t result = PAPI_OK;
+ int8_t tag;
+
+ /* start reading the attribute groups */
+ if (iread(fd, &tag, 1) != 1) /* prime the pump */
+ return (PAPI_BAD_REQUEST);
+
+ while ((tag != DTAG_END_OF_ATTRIBUTES) && (result == PAPI_OK)) {
+ result = ipp_read_attribute_group(iread, fd, &tag, message);
+ }
+
+ return (result);
+}
+
+papi_status_t
+ipp_read_message(ipp_reader_t iread, void *fd, papi_attribute_t ***message,
+ char type)
+{
+ papi_status_t result = PAPI_OK;
+
+ if ((iread == NULL) || (fd == NULL) || (message == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ result = ipp_read_header(iread, fd, message, type);
+ if (result == PAPI_OK)
+ result = ipp_read_attribute_groups(iread, fd, message);
+
+ return (result);
+}
diff --git a/usr/src/lib/print/libipp-core/common/strings.c b/usr/src/lib/print/libipp-core/common/strings.c
new file mode 100644
index 0000000000..b47449b8cc
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/common/strings.c
@@ -0,0 +1,411 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: strings.c 151 2006-04-25 16:55:34Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ipp.h"
+
+static char *tag_strings[] = {
+ /* delimiter tags */
+ "reserved-delimiter-00",
+ "operational-attributes-group",
+ "job-attributes-group",
+ "end-of-attributes-group",
+ "printer-attributes-group",
+ "unsupported-attributes-group",
+ "subscription-attributes-group",
+ "event-notification-attributes-group",
+ "reserved-delimiter-08",
+ "reserved-delimiter-09",
+ "reserved-delimiter-0a",
+ "reserved-delimiter-0b",
+ "reserved-delimiter-0c",
+ "reserved-delimiter-0d",
+ "reserved-delimiter-0e",
+ "reserved-delimiter-0f",
+ /* value tags */
+ "unsupported",
+ "reserved-default",
+ "unknown",
+ "no-value",
+ "reserved-out-of-band-14",
+ "not-settable",
+ "delete-attribute",
+ "admin-define",
+ "reserved-out-of-band-18",
+ "reserved-out-of-band-19",
+ "reserved-out-of-band-1a",
+ "reserved-out-of-band-1b",
+ "reserved-out-of-band-1c",
+ "reserved-out-of-band-1d",
+ "reserved-out-of-band-1e",
+ "reserved-out-of-band-1f",
+ "reserved",
+ "integer",
+ "boolean",
+ "enum",
+ "reserved-integer-type-24",
+ "reserved-integer-type-25",
+ "reserved-integer-type-26",
+ "reserved-integer-type-27",
+ "reserved-integer-type-28",
+ "reserved-integer-type-29",
+ "reserved-integer-type-2a",
+ "reserved-integer-type-2b",
+ "reserved-integer-type-2c",
+ "reserved-integer-type-2d",
+ "reserved-integer-type-2e",
+ "reserved-integer-type-2f",
+ "octetString",
+ "dateTime",
+ "resolution",
+ "rangeOfInteger",
+ "begCollection",
+ "textWithLanguage",
+ "nameWithLanguage",
+ "endCollection",
+ "reserved-octetString-38",
+ "reserved-octetString-39",
+ "reserved-octetString-3a",
+ "reserved-octetString-3b",
+ "reserved-octetString-3c",
+ "reserved-octetString-3d",
+ "reserved-octetString-3e",
+ "reserved-octetString-3f",
+ "reserved",
+ "textWithoutLanguage",
+ "nameWithoutLanguage",
+ "reserved",
+ "keyword",
+ "uri",
+ "uriScheme",
+ "charset",
+ "naturalLanguage",
+ "mimeMediaType",
+ "memberAttrName",
+ "reserved-charString-4b",
+ "reserved-charString-4c",
+ "reserved-charString-4d",
+ "reserved-charString-4e",
+ "reserved-charString-4f",
+ "reserved-charString-50",
+ "reserved-charString-51",
+ "reserved-charString-52",
+ "reserved-charString-53",
+ "reserved-charString-54",
+ "reserved-charString-55",
+ "reserved-charString-56",
+ "reserved-charString-57",
+ "reserved-charString-58",
+ "reserved-charString-59",
+ "reserved-charString-5a",
+ "reserved-charString-5b",
+ "reserved-charString-5c",
+ "reserved-charString-5d",
+ "reserved-charString-5e",
+ "reserved-charString-5f",
+};
+
+static char *opid_strings[] = {
+ "reserved-0x0000",
+ "reserved-0x0001",
+ "Print-Job",
+ "Print-URI",
+ "Validate-Job",
+ "Create-Job",
+ "Send-Document",
+ "Send-URI",
+ "Cancel-Job",
+ "Get-Job-Attributes",
+ "Get-Jobs",
+ "Get-Printer-Attributes",
+ "Hold-Job",
+ "Release-Job",
+ "Restart-Job",
+ "reserved-0x000f",
+ "Pause-Printer",
+ "Resume-Printer",
+ "Purge-Jobs",
+ "Set-Printer-Attributes",
+ "Set-Job-Attributes",
+ "Get-Printer-Supported-Values",
+ "Create-Printer-Subscription",
+ "Create-Job-Subscription",
+ "Get-Subscription-Attributes",
+ "Get-Subscriptions",
+ "Renew-Subscription",
+ "Cancel-Subscription",
+ "Get-Notifications",
+ "Send-Notifications",
+ "Get-Resource-Attributes-deleted",
+ "Get-Resource-Data-deleted",
+ "Get-Resources-deleted",
+ "Get-Print-Support-Files",
+ "Disable-Printer",
+ "Pause-Printer-After-Current-Job",
+ "Hold-New-Jobs",
+ "Release-Held-New-Jobs",
+ "Deactivate-Printer",
+ "Activate-Printer",
+ "Restart-Printer",
+ "Shutdown-Printer",
+ "Startup-Printer",
+ "Reprocess-Job",
+ "Cancel-Current-Job",
+ "Suspend-Current-Job",
+ "Resume-Job",
+ "Promote-Job",
+ "Schedule-Job-After",
+ NULL
+};
+
+static char *res_opid_strings[] = {
+ "Microsoft-0x4000",
+ "CUPS-Get-Default",
+ "CUPS-Get-Printers",
+ "CUPS-Add-Printer",
+ "CUPS-Delete-Printer",
+ "CUPS-Get-Classes",
+ "CUPS-Add-Class",
+ "CUPS-Delete-Class",
+ "CUPS-Accept-Jobs",
+ "CUPS-Reject-Jobs",
+ "CUPS-Set-Default",
+ "CUPS-Get-Devices",
+ "CUPS-Get-PPDs",
+ "CUPS-Move-Job",
+ "CUPS-0x400e",
+ "CUPS-0x400f",
+ "Peerless-0x4010",
+ NULL
+};
+#define KNOWN_RESERVED_MIN 0x4000
+#define KNOWN_RESERVED_MAX 0x4010
+
+static char *ok_status_strings[] = {
+ "successful-ok",
+ "successful-ok-ignored-or-substituted-attributes",
+ "successful-ok-conflicting-attributes",
+ "successful-ok-ignored-subscriptions",
+ "successful-ok-ignored-notifications",
+ "successful-ok-too-many-events",
+ "successful-ok-but-cancel-subscription"
+};
+
+static char *redir_status_strings[] = {
+ "redirection-other-site"
+};
+
+static char *client_error_status_strings[] = {
+ "client-error-bad-request",
+ "client-error-forbidden",
+ "client-error-not-authenticated",
+ "client-error-not-authorized",
+ "client-error-not-possible",
+ "client-error-timeout",
+ "client-error-not-found",
+ "client-error-gone",
+ "client-error-request-entity-too-large",
+ "client-error-request-value-too-long",
+ "client-error-document-format-not-supported",
+ "client-error-attributes-or-values-not-supported",
+ "client-error-uri-scheme-not-supported",
+ "client-error-charset-not-supported",
+ "client-error-conflicting-attributes",
+ "client-error-compression-not-supported",
+ "client-error-compression-error",
+ "client-error-document-format-error",
+ "client-error-document-access-error",
+ "client-error-attributes-not-settable",
+ "client-error-ignored-all-subscriptions",
+ "client-error-too-many-subscriptions",
+ "client-error-ignored-all-notifications",
+ "client-error-print-support-file-not-found"
+};
+
+static char *server_error_status_strings[] = {
+ "server-error-internal-error",
+ "server-error-operation-not-supported",
+ "server-error-service-unavailable",
+ "server-error-version-not-supported",
+ "server-error-device-error",
+ "server-error-temporary-error",
+ "server-error-not-accepting-jobs",
+ "server-error-busy",
+ "server-error-job-canceled",
+ "server-error-multiple-document-jobs-not-supported",
+ "server-error-printer-is-deactivated"
+};
+
+char *
+ipp_tag_string(int8_t id, char *ret, size_t len)
+{
+ if (id < VTAG_MAX)
+ (void) strlcpy(ret, tag_strings[id], len);
+ else if (id == VTAG_EXTEND)
+ (void) strlcpy(ret, "extension", len);
+ else
+ (void) snprintf(ret, len, "bogus-0x%.2x", id);
+
+ return (ret);
+}
+
+char *
+ipp_opid_string(int16_t id, char *ret, size_t len)
+{
+ if (id < OPID_RESERVED_MIN)
+ (void) strlcpy(ret, opid_strings[id], len);
+ else if (id < OPID_RESERVED_VENDOR_MIN)
+ (void) snprintf(ret, len, "reserved-0x%.4x", id);
+ else if (id <= KNOWN_RESERVED_MAX)
+ (void) strlcpy(ret,
+ res_opid_strings[id - KNOWN_RESERVED_MIN], len);
+ else /* if (id <= OPID_RESERVED_VENDOR_MAX) */
+ (void) snprintf(ret, len, "reserved-vendor-0x%.4x", id);
+
+ return (ret);
+}
+
+int16_t
+ipp_string_opid(char *string)
+{
+ int i;
+
+ for (i = 0; opid_strings[i] != NULL; i++)
+ if (strcasecmp(opid_strings[i], string) == 0)
+ return (i);
+
+ for (i = 0; res_opid_strings[i] != NULL; i++)
+ if (strcasecmp(res_opid_strings[i], string) == 0)
+ return (0x4000 + i);
+
+ return (-1);
+}
+
+char *
+ipp_status_string(int16_t id, char *ret, size_t len)
+{
+ if (id <= IPP_OK_MAX)
+ (void) strlcpy(ret, ok_status_strings[id], len);
+ else if (id >= IPP_REDIR_MIN && id <= IPP_REDIR_MAX)
+ (void) strlcpy(ret,
+ redir_status_strings[id - IPP_REDIR_MIN], len);
+ else if (id >= IPP_CERR_MIN && id <= IPP_CERR_MAX)
+ (void) strlcpy(ret,
+ client_error_status_strings[id - IPP_CERR_MIN], len);
+ else if (id >= IPP_SERR_MIN && id <= IPP_SERR_MAX)
+ (void) strlcpy(ret,
+ server_error_status_strings[id - IPP_SERR_MIN], len);
+ else
+ (void) snprintf(ret, len, "bogus-0x%.4hx", id);
+
+ return (ret);
+}
+
+
+
+/*
+ * attribute template handling routines
+ */
+char *job_template[] = {
+ "copies",
+ "finishing",
+ "job-hold-until",
+ "job-priority",
+ "job-sheets",
+ "media",
+ "multiple-document-handling",
+ "number-up",
+ "page-ranges-supported",
+ "print-quality",
+ "printer-resoultion",
+ "sides",
+ NULL
+};
+
+char *job_description[] = {
+ "copies-default", "copies-supported",
+ "finishing-default", "finishing-supported",
+ "job-hold-until-default", "job-hold-until-supported",
+ "job-priority-default", "job-priority-supported",
+ "job-sheets-default", "job-sheets-supported",
+ "media-default", "media-supported",
+ "multiple-document-handling-default",
+ "multiple-document-handling-supported",
+ "number-up-default", "number-up-supported",
+ "page-ranges-supported",
+ "print-quality-default", "print-quality-supported",
+ "printer-resoultion-default", "printer-resoultion-supported",
+ "sides-default", "sides-supported",
+ NULL
+};
+
+char *printer_description[] = {
+ "printer-uri-supported",
+ "uri-security-supported",
+ "uri-authentication-supported",
+ "printer-name",
+ "printer-location",
+ "printer-info",
+ "printer-more-info",
+ "printer-driver-installer",
+ "printer-make-and-model",
+ "printer-more-info-manufacturer",
+ "printer-state",
+ "printer-state-reasons",
+ "printer-state-message",
+ "ipp-versions-supported",
+ "multiple-document-jobs-supported",
+ "charset-configured",
+ "charset-supported",
+ "natural-language-configured",
+ "generated-natural-language-supported",
+ "document-format-default",
+ "document-format-supported",
+ "printer-is-accepting-jobs",
+ "queued-job-count",
+ "printer-message-from-operator",
+ "color-supported",
+ "reference-uri-schemes-supported",
+ "pdl-override-supported",
+ "printer-up-time",
+ "printer-current-time",
+ "multiple-operation-time-out",
+ "compression-supported",
+ "job-k-octets-supported",
+ "job-impressions-supported",
+ "job-media-sheets-supported",
+ "pages-per-minute",
+ "pages-per-minute-color",
+ NULL
+};
diff --git a/usr/src/lib/print/libipp-core/common/write.c b/usr/src/lib/print/libipp-core/common/write.c
new file mode 100644
index 0000000000..aef693a365
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/common/write.c
@@ -0,0 +1,415 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: write.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <inttypes.h>
+
+#include <papi.h>
+#include <ipp.h>
+
+static int8_t
+papi_attribute_to_ipp_type(papi_attribute_value_type_t type)
+{
+ switch (type) {
+ case PAPI_INTEGER:
+ return (VTAG_INTEGER);
+ case PAPI_BOOLEAN:
+ return (VTAG_BOOLEAN);
+ case PAPI_RANGE:
+ return (VTAG_RANGE_OF_INTEGER);
+ case PAPI_RESOLUTION:
+ return (VTAG_RESOLUTION);
+ case PAPI_DATETIME:
+ return (VTAG_DATE_TIME);
+ case PAPI_STRING:
+ return (VTAG_TEXT_WITHOUT_LANGUAGE);
+ }
+
+ return (0);
+}
+
+static papi_status_t
+papi_ipp_type_match(papi_attribute_value_type_t papi, int8_t ipp)
+{
+ switch (papi) {
+ case PAPI_STRING:
+ switch (ipp) {
+ case VTAG_URI:
+ case VTAG_OCTET_STRING:
+ case VTAG_TEXT_WITHOUT_LANGUAGE:
+ case VTAG_URI_SCHEME:
+ case VTAG_CHARSET:
+ case VTAG_NATURAL_LANGUAGE:
+ case VTAG_MIME_MEDIA_TYPE:
+ case VTAG_NAME_WITHOUT_LANGUAGE:
+ case VTAG_KEYWORD:
+ break;
+ default:
+ return (PAPI_CONFLICT);
+ }
+ break;
+ case PAPI_INTEGER:
+ switch (ipp) {
+ case VTAG_ENUM:
+ case VTAG_INTEGER:
+ break;
+ default:
+ return (PAPI_CONFLICT);
+ }
+ break;
+ case PAPI_BOOLEAN:
+ if (ipp != VTAG_BOOLEAN)
+ return (PAPI_CONFLICT);
+ break;
+ case PAPI_RANGE:
+ if (ipp != VTAG_RANGE_OF_INTEGER)
+ return (PAPI_CONFLICT);
+ break;
+ case PAPI_RESOLUTION:
+ if (ipp != VTAG_RESOLUTION)
+ return (PAPI_CONFLICT);
+ break;
+ case PAPI_DATETIME:
+ if (ipp != VTAG_DATE_TIME)
+ return (PAPI_CONFLICT);
+ break;
+ case PAPI_COLLECTION:
+ /* don't need to match */
+ break;
+ }
+
+ return (PAPI_OK);
+}
+
+static papi_status_t
+ipp_write_attribute(ipp_writer_t iwrite, void *fd, papi_attribute_t *attribute)
+{
+ papi_status_t status;
+ papi_attribute_value_t **values;
+ int8_t type;
+ int i;
+ char *name;
+
+ name = attribute->name;
+ values = attribute->values;
+
+ if ((type = name_to_ipp_type(name)) == 0)
+ type = papi_attribute_to_ipp_type(attribute->type);
+
+ /* The types don't match, so don't send the attribute */
+ if ((status = papi_ipp_type_match(attribute->type, type)) != PAPI_OK)
+ return (status);
+
+ if (values == NULL) {
+ uint16_t length;
+
+ type = VTAG_UNSUPPORTED;
+ if (iwrite(fd, &type, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+
+ if (name != NULL) { /* first value gets named */
+ length = (uint16_t)htons(strlen(name));
+
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ if (iwrite(fd, name, strlen(name)) != strlen(name))
+ return (PAPI_DEVICE_ERROR);
+ }
+
+ length = (uint16_t)htons(0);
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+
+ return (PAPI_OK);
+ }
+
+
+
+ for (i = 0; values[i] != NULL; i++) {
+ papi_attribute_value_t *value = values[i];
+ uint16_t length = 0;
+
+ if (iwrite(fd, &type, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+
+ if (name != NULL) { /* first value gets named */
+ length = (uint16_t)htons(strlen(name));
+
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ if (iwrite(fd, name, strlen(name)) != strlen(name))
+ return (PAPI_DEVICE_ERROR);
+ name = NULL;
+ } else {
+ length = (uint16_t)htons(0);
+
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ }
+
+ switch (attribute->type) {
+ case PAPI_STRING: {
+ char *v = (char *)value->string;
+
+ if (v != NULL) {
+ size_t str_length = strlen(v);
+
+ /*
+ * if the length is more than 16 bits can
+ * express, send what can be represented
+ * in 16 bits. IPP "strings" can only be
+ * that large.
+ */
+ if (str_length > 0xFFFF)
+ str_length = 0xFFFF;
+
+ length = (uint16_t)htons(str_length);
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ if (iwrite(fd, v, str_length) != str_length)
+ return (PAPI_DEVICE_ERROR);
+ } else
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ }
+ break;
+ case PAPI_BOOLEAN: {
+ int8_t v = (int8_t)value->boolean;
+
+ length = (uint16_t)htons(1);
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ if (iwrite(fd, &v, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ }
+ break;
+ case PAPI_INTEGER: {
+ int32_t v = (int32_t)value->integer;
+
+ length = (uint16_t)htons(4);
+ v = (int32_t)htonl(v);
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ if (iwrite(fd, &v, 4) != 4)
+ return (PAPI_DEVICE_ERROR);
+ }
+ break;
+ case PAPI_RANGE: {
+ int32_t min = (int32_t)htonl((int)(value->range).lower),
+ max = (int32_t)htonl((int)(value->range).upper);
+
+ length = (uint16_t)htons(8);
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ if (iwrite(fd, &min, 4) != 4)
+ return (PAPI_DEVICE_ERROR);
+ if (iwrite(fd, &max, 4) != 4)
+ return (PAPI_DEVICE_ERROR);
+ }
+ break;
+ case PAPI_RESOLUTION: {
+ int32_t x = (int)(value->resolution).xres,
+ y = (int)(value->resolution).yres;
+ int8_t units = (int8_t)(value->resolution).units;
+
+ length = (uint16_t)htons(9);
+ x = (int32_t)htonl(x);
+ y = (int32_t)htonl(y);
+
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ if (iwrite(fd, &x, 4) != 4)
+ return (PAPI_DEVICE_ERROR);
+ if (iwrite(fd, &y, 4) != 4)
+ return (PAPI_DEVICE_ERROR);
+ if (iwrite(fd, &units, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ }
+ break;
+ case PAPI_DATETIME: {
+ struct tm *v = gmtime(&value->datetime);
+ int8_t c;
+ uint16_t s;
+
+ length = (uint16_t)htons(11);
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ s = (uint16_t)htons(v->tm_year + 1900);
+ if (iwrite(fd, &s, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ c = v->tm_mon + 1;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ c = v->tm_mday;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ c = v->tm_hour;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ c = v->tm_min;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ c = v->tm_sec;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ c = /* v->deciseconds */ 0;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ c = /* v->utc_dir */ 0;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ c = /* v->utc_hours */ 0;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ c = /* v->utc_minutes */ 0;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+ }
+ break;
+ default: {
+ /*
+ * If there is a value, it is not one of our
+ * types, so we couldn't use it anyway. We assume
+ * that it was an OOB type with no value
+ */
+ length = (uint16_t)htons(0);
+ if (iwrite(fd, &length, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+ }
+ break;
+ }
+ }
+
+ return (PAPI_OK);
+}
+
+static papi_status_t
+ipp_write_attribute_group(ipp_writer_t iwrite, void *fd, int8_t type,
+ papi_attribute_t **attributes)
+{
+ papi_status_t result = PAPI_OK;
+ int i;
+
+ /* write group tag */
+ if (iwrite(fd, &type, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+
+ /* write values */
+ for (i = 0; ((attributes[i] != NULL) && (result == PAPI_OK)); i++)
+ result = ipp_write_attribute(iwrite, fd, attributes[i]);
+
+ return (result);
+}
+
+static papi_status_t
+ipp_write_attribute_groups(ipp_writer_t iwrite, void *fd,
+ papi_attribute_t **groups)
+{
+ papi_status_t result = PAPI_OK;
+ int8_t c;
+
+ for (c = DTAG_MIN; c <= DTAG_MAX; c++) {
+ papi_status_t status;
+ papi_attribute_t **group = NULL;
+ void *iter = NULL;
+ char name[32];
+
+ (void) ipp_tag_string(c, name, sizeof (name));
+ for (status = papiAttributeListGetCollection(groups, &iter,
+ name, &group);
+ ((status == PAPI_OK) && (result == PAPI_OK));
+ status = papiAttributeListGetCollection(groups, &iter,
+ NULL, &group))
+ result = ipp_write_attribute_group(iwrite, fd,
+ c, group);
+ }
+
+ c = DTAG_END_OF_ATTRIBUTES;
+ if (iwrite(fd, &c, 1) != 1)
+ result = PAPI_DEVICE_ERROR;
+
+ return (result);
+}
+
+static papi_status_t
+ipp_write_message_header(ipp_writer_t iwrite, void *fd,
+ papi_attribute_t **message)
+{
+ int tmp;
+ int8_t c;
+ uint16_t s;
+ int32_t i;
+
+ /* write the version */
+ papiAttributeListGetInteger(message, NULL, "version-major", &tmp);
+ c = tmp;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+
+ papiAttributeListGetInteger(message, NULL, "version-minor", &tmp);
+ c = tmp;
+ if (iwrite(fd, &c, 1) != 1)
+ return (PAPI_DEVICE_ERROR);
+
+ /* write the request/status code */
+ papiAttributeListGetInteger(message, NULL, "status-code", &tmp);
+ papiAttributeListGetInteger(message, NULL, "operation-id", &tmp);
+ s = (uint16_t)htons(tmp);
+ if (iwrite(fd, &s, 2) != 2)
+ return (PAPI_DEVICE_ERROR);
+
+ /* write the request id */
+ papiAttributeListGetInteger(message, NULL, "request-id", &tmp);
+ i = (uint32_t)htonl(tmp);
+ if (iwrite(fd, &i, 4) != 4)
+ return (PAPI_DEVICE_ERROR);
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+ipp_write_message(ipp_writer_t iwrite, void *fd, papi_attribute_t **message)
+{
+ papi_status_t result;
+
+ if ((iwrite == NULL) || (fd == NULL) || (message == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ result = ipp_write_message_header(iwrite, fd, message);
+ if (result == PAPI_OK)
+ result = ipp_write_attribute_groups(iwrite, fd, message);
+
+ return (result);
+}
diff --git a/usr/src/lib/print/libipp-core/i386/Makefile b/usr/src/lib/print/libipp-core/i386/Makefile
new file mode 100644
index 0000000000..3b985583a4
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT)
diff --git a/usr/src/lib/print/libipp-core/sparc/Makefile b/usr/src/lib/print/libipp-core/sparc/Makefile
new file mode 100644
index 0000000000..3b985583a4
--- /dev/null
+++ b/usr/src/lib/print/libipp-core/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT)
diff --git a/usr/src/lib/print/libipp-listener/Makefile b/usr/src/lib/print/libipp-listener/Makefile
new file mode 100644
index 0000000000..b92d620b10
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../../Makefile.lib
+
+#HDRS = papi.h
+#HDRDIR = common
+SUBDIRS = $(MACH)
+#$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all clean clobber install: .WAIT $(SUBDIRS)
+
+lint: # $(SUBDIRS)
+
+install_h: # $(ROOTHDRS)
+
+check: # $(CHECKHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/print/libipp-listener/Makefile.com b/usr/src/lib/print/libipp-listener/Makefile.com
new file mode 100644
index 0000000000..75672ad6d6
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/Makefile.com
@@ -0,0 +1,67 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = libipp-listener.a
+VERS = .0
+OBJECTS = \
+ cancel-job.o common.o create-job.o cups-accept-jobs.o \
+ cups-get-classes.o cups-get-default.o cups-get-printers.o \
+ cups-move-job.o cups-reject-jobs.o disable-printer.o enable-printer.o \
+ get-job-attributes.o get-jobs.o get-printer-attributes.o hold-job.o \
+ ipp-listener.o pause-printer.o print-job.o purge-jobs.o release-job.o \
+ restart-job.o resume-printer.o send-document.o set-job-attributes.o \
+ set-printer-attributes.o validate-job.o
+
+include ../../../Makefile.lib
+include ../../../Makefile.rootfs
+
+ROOTLIBDIR= $(ROOT)/usr/lib
+
+LIBS = $(DYNLIB)
+
+SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c)
+
+$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+MAPFILE = $(SRCDIR)/mapfile
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -DSOLARIS_PRIVATE_POST_0_9
+CPPFLAGS += -I$(SRCDIR)
+CPPFLAGS += -I../../libpapi-common/common
+CPPFLAGS += -I../../libipp-core/common
+DYNFLAGS += -M $(MAPFILE)
+LDLIBS += -lipp-core -lpapi -lc
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include ../../../Makefile.targ
diff --git a/usr/src/lib/print/libipp-listener/common/cancel-job.c b/usr/src/lib/print/libipp-listener/common/cancel-job.c
new file mode 100644
index 0000000000..49ad1980f8
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/cancel-job.c
@@ -0,0 +1,96 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: cancel-job.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_cancel_job(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+
+ char *message = NULL;
+ char *queue = NULL;
+ int id = -1;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * the operational-attributes-group must contain:
+ * job-uri (or printer-uri/job-id)
+ */
+ get_printer_id(operational, &queue, &id);
+ if (id < 0) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing job-uri or job-id");
+ return (PAPI_BAD_REQUEST);
+ } else if (queue == NULL) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing printer-uri or job-uri");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * the operational-attributes-group may contain:
+ * message
+ */
+ (void) papiAttributeListGetString(operational, NULL,
+ "message", &message);
+
+ status = papiJobCancel(svc, queue, id);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status,
+ "cancel failed: %s-%d: %s",
+ (queue ? queue : "(null)"), id,
+ ipp_svc_status_mesg(svc, status));
+ } else if (message != NULL) { /* add unsupported attribute group */
+ papi_attribute_t **unsupported = NULL;
+
+ papiAttributeListAddValue(&unsupported, PAPI_ATTR_EXCL,
+ "message", PAPI_COLLECTION, NULL);
+ (void) papiAttributeListAddCollection(response,
+ PAPI_ATTR_REPLACE, "unsupported-attributes-group",
+ unsupported);
+ papiAttributeListFree(unsupported);
+
+ status = PAPI_OK_SUBST;
+ ipp_set_status(response, status,
+ "unsupported attribute in request");
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/common.c b/usr/src/lib/print/libipp-listener/common/common.c
new file mode 100644
index 0000000000..c3715dc1b3
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/common.c
@@ -0,0 +1,313 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: common.c 155 2006-04-26 02:34:54Z ktou $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <papi.h>
+#include <ipp-listener.h>
+
+char *
+ipp_svc_status_mesg(papi_service_t svc, papi_status_t status)
+{
+ char *mesg = papiServiceGetStatusMessage(svc);
+
+ if (mesg == NULL)
+ mesg = papiStatusString(status);
+
+ return (mesg);
+}
+
+char *
+destination_from_printer_uri(char *uri)
+{
+ static char buf[64];
+ char *result = NULL;
+
+ if (uri != NULL)
+ result = strrchr(uri, '/');
+
+ if (result == NULL)
+ result = uri;
+ else
+ result++;
+
+#ifdef FORCE_LPSCHED_URI
+ snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s", result);
+ result = buf;
+#endif /* FORCE_LPSCHED_URI */
+
+ return (result);
+}
+
+void
+get_printer_id(papi_attribute_t **attributes, char **printer, int *id)
+{
+ papi_status_t result;
+ char *job = NULL;
+ char *fodder;
+ int junk;
+
+ if (printer == NULL)
+ printer = &fodder;
+ if (id == NULL)
+ id = &junk;
+
+ *printer = NULL;
+ *id = -1;
+
+ result = papiAttributeListGetString(attributes, NULL, "job-uri", &job);
+ if (result != PAPI_OK) {
+ result = papiAttributeListGetString(attributes, NULL,
+ "printer-uri", printer);
+ if (result == PAPI_OK)
+ papiAttributeListGetInteger(attributes, NULL,
+ "job-id", id);
+ } else {
+ *printer = job;
+ if ((job = strrchr(*printer, '/')) != NULL) {
+ *job = '\0';
+ *id = atoi(++job);
+ }
+ }
+
+ /* move to the last component of the name */
+ if (*printer != NULL)
+ *printer = strrchr(*printer, '/') + 1;
+}
+
+void
+get_string_list(papi_attribute_t **attributes, char *name, char ***values)
+{
+ papi_status_t result;
+
+ void *iterator = NULL;
+ char *value = NULL;
+
+ for (result = papiAttributeListGetString(attributes, &iterator,
+ name, &value);
+ result == PAPI_OK;
+ result = papiAttributeListGetString(attributes, &iterator,
+ NULL, &value))
+ list_append(values, value);
+}
+
+void
+add_default_attributes(papi_attribute_t ***attributes)
+{
+
+ (void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND,
+ "ipp-versions-supported", "1.0");
+ (void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND,
+ "ipp-versions-supported", "1.1");
+ (void) papiAttributeListAddBoolean(attributes, PAPI_ATTR_EXCL,
+ "multiple-document-jobs-supported", 0);
+ /*
+ * Should be able to ask the web server if it supports SSL or TLS, but
+ * for now, we pick only "none"
+ */
+ (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
+ "uri-security-supported", "none");
+
+ /*
+ * For now, we only "none". As we support more authentication methods,
+ * we will need to add the associated uri for each. Valid values would
+ * be:
+ * "none", "requesting-user-name", "basic", "digest", "certificate"
+ * See RFC2911 page 127 for more information.
+ */
+ (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
+ "uri-authentication-supported", "requesting-user-name");
+ (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
+ "uri-security-supported", "none");
+ /* printer-uri-supported is added in the service based attributes */
+
+ (void) papiAttributeListAddInteger(attributes, PAPI_ATTR_EXCL,
+ "multiple-operation-time-out", 60);
+
+ /* I18N related */
+ (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
+ "charset-configured", "utf-8");
+ (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL,
+ "charset-supported", "utf-8");
+ (void) papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
+ "natural-language-configured", "en-us");
+}
+
+static void
+massage_printer_attributes_group(papi_attribute_t **group, char *printer_uri)
+{
+ if (papiAttributeListFind(group, "printer-uri-supported") != NULL)
+ papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
+ "printer-uri-supported", printer_uri);
+}
+
+static void
+massage_job_attributes_group(papi_attribute_t **group, char *printer_uri)
+{
+ if (papiAttributeListFind(group, "job-printer-uri") != NULL)
+ papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
+ "job-printer-uri", printer_uri);
+
+ if (papiAttributeListFind(group, "job-printer-uri") != NULL) {
+ char buf[BUFSIZ];
+ int32_t id = -1;
+
+ papiAttributeListGetInteger(group, NULL, "job-id", &id);
+ snprintf(buf, sizeof (buf), "%s/%d", printer_uri, id);
+ papiAttributeListAddString(&group, PAPI_ATTR_REPLACE,
+ "job-uri", buf);
+ }
+}
+
+/*
+ * This function will replace the job/printer URIs with the requested
+ * uri because the print service may return a URI that isn't IPP based.
+ */
+void
+massage_response(papi_attribute_t **request, papi_attribute_t **response)
+{
+ papi_status_t status;
+ papi_attribute_t **group = NULL;
+ void *iter = NULL;
+ char *host = "localhost";
+ char *path = "/printers/";
+ int port = 631;
+ char buf[BUFSIZ];
+
+ (void) papiAttributeListGetString(request, NULL, "uri-host", &host);
+ (void) papiAttributeListGetString(request, NULL, "uri-path", &path);
+ (void) papiAttributeListGetInteger(request, NULL, "uri-port", &port);
+
+ if (port == 631)
+ snprintf(buf, sizeof (buf), "ipp://%s%s", host, path);
+ else
+ snprintf(buf, sizeof (buf), "http://%s:%d%s", host, port, path);
+
+ for (status = papiAttributeListGetCollection(response, &iter,
+ "printer-attributes-group", &group);
+ status == PAPI_OK;
+ status = papiAttributeListGetCollection(NULL, &iter,
+ NULL, &group))
+ massage_printer_attributes_group(group, buf);
+
+ iter = NULL;
+ for (status = papiAttributeListGetCollection(response, &iter,
+ "job-attributes-group", &group);
+ status == PAPI_OK;
+ status = papiAttributeListGetCollection(NULL, &iter,
+ NULL, &group))
+ massage_job_attributes_group(group, buf);
+}
+
+/*
+ * This walks through the locale tab and returns the installed
+ * locales. There must be a better way.
+ */
+void
+add_supported_locales(papi_attribute_t ***attributes)
+{
+ FILE *fp;
+
+ papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE,
+ "generated-natural-language-supported", "en-us");
+
+#ifndef __linux__ /* this is Solaris specific */
+ if ((fp = fopen("/usr/lib/locale/lcttab", "r")) != NULL) {
+ char buf[1024];
+
+ while (fgets(buf, sizeof (buf), fp) != NULL) {
+ char *name, *file;
+ int i, passed = 1;
+
+ name = strtok(buf, " \t\n");
+
+ for (i = 0; ((passed == 1) && (name[i] != NULL)); i++)
+ if (isalpha(name[i]) != 0)
+ name[i] = tolower(name[i]);
+ else if ((name[i] == '_') || (name[i] == '-'))
+ name[i] = '-';
+ else
+ passed = 0;
+
+ if ((passed == 1) &&
+ ((file = strtok(NULL, " \t\n")) != NULL)) {
+ char path[1024];
+
+ snprintf(path, sizeof (path),
+ "/usr/lib/locale/%s", file);
+
+ if (access(path, F_OK) == 0)
+ papiAttributeListAddString(attributes,
+ PAPI_ATTR_APPEND,
+ "generated-natural-language-supported",
+ name);
+ }
+ }
+ }
+#endif
+}
+
+void
+papi_to_ipp_printer_group(papi_attribute_t ***response,
+ papi_attribute_t **request, int flags, papi_printer_t p)
+{
+ papi_attribute_t **ipp_group = NULL;
+
+ copy_attributes(&ipp_group, papiPrinterGetAttributeList(p));
+
+ /* Windows clients appear to have a problem with very large values */
+ papiAttributeListDelete(&ipp_group, "lpsched-printer-ppd-contents");
+
+ add_default_attributes(&ipp_group);
+ ipp_operations_supported(&ipp_group, request);
+
+ (void) papiAttributeListAddCollection(response, flags,
+ "printer-attributes-group", ipp_group);
+ papiAttributeListFree(ipp_group);
+}
+
+void
+papi_to_ipp_job_group(papi_attribute_t ***response,
+ papi_attribute_t **request, int flags, papi_job_t j)
+{
+ papi_attribute_t **ipp_group = NULL;
+
+ copy_attributes(&ipp_group, papiJobGetAttributeList(j));
+
+ (void) papiAttributeListAddCollection(response, flags,
+ "job-attributes-group", ipp_group);
+ papiAttributeListFree(ipp_group);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/create-job.c b/usr/src/lib/print/libipp-listener/common/create-job.c
new file mode 100644
index 0000000000..996b235cea
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/create-job.c
@@ -0,0 +1,108 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: create-job.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_create_job(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_job_t j = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_attribute_t **job_attributes = NULL;
+ char *queue = NULL;
+ char *keys[] = { "attributes-natural-language", "attributes-charset",
+ "printer-uri", NULL };
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * The operational-attributes-group may contain:
+ * job-name
+ * ipp-attribute-fidelity
+ * document-name
+ * compression
+ * document-format
+ * document-natural-language
+ * job-k-octets
+ * job-impressions
+ * job-media-sheets
+ * Simply copy the entire contents of the operational-attributes-group
+ * for the PAPI call's possible use.
+ */
+
+ /* copy the pointers only, not the elements */
+ split_and_copy_attributes(keys, operational, NULL, &job_attributes);
+
+ /* copy any job-attributes-group attributes for the PAPI call */
+ if (papiAttributeListGetCollection(request, NULL,
+ "job-attributes-group", &operational) == PAPI_OK)
+ copy_attributes(&job_attributes, operational);
+
+ /*
+ * request job creation, using Sun extention to PAPI. The
+ * functionality in this extension is expected to make the
+ * next revision of the PAPI.
+ */
+ status = papiJobCreate(svc, queue, job_attributes, NULL, &j);
+ papiAttributeListFree(job_attributes);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "job creation: %s",
+ ipp_svc_status_mesg(svc, status));
+ return (status);
+ }
+
+ /* add the job attributes to the response in a job-attributes-group */
+ if (j != NULL) {
+ papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j);
+ papiJobFree(j);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/cups-accept-jobs.c b/usr/src/lib/print/libipp-listener/common/cups-accept-jobs.c
new file mode 100644
index 0000000000..01a91ba5fd
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/cups-accept-jobs.c
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: cups-accept-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+cups_accept_jobs(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+
+ char *queue = NULL;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ if ((status = papiPrinterResume(svc, queue)) != PAPI_OK) {
+ ipp_set_status(response, status, "accept failed: %s: %s",
+ (queue ? queue : "(null)"),
+ ipp_svc_status_mesg(svc, status));
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/cups-get-classes.c b/usr/src/lib/print/libipp-listener/common/cups-get-classes.c
new file mode 100644
index 0000000000..a6aea61908
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/cups-get-classes.c
@@ -0,0 +1,90 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: cups-get-classes.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+cups_get_classes(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_printer_t *p = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_filter_t filt;
+
+ char **req_attrs = NULL;
+ int limit = 0;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group may contain:
+ * limit
+ * printer-info
+ * printer-location
+ * printer-type
+ * printer-type-mask
+ * requested-attributes
+ */
+
+ papiAttributeListGetInteger(operational, NULL, "limit", &limit);
+
+ get_string_list(operational, "requested-attributes", &req_attrs);
+
+ /* only ask for the classes */
+ filt.type = PAPI_FILTER_BITMASK;
+ filt.filter.bitmask.mask = ~PAPI_PRINTER_CLASS;
+ filt.filter.bitmask.value = PAPI_PRINTER_CLASS;
+
+ status = papiPrintersList(svc, req_attrs, &filt, &p);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "query printers: %s",
+ ipp_svc_status_mesg(svc, status));
+ papiPrinterFree(p); /* we shouldn't have a printer */
+ return (status);
+ }
+
+ if (p != NULL) {
+ int i;
+
+ for (i = 0; p[i] != NULL; i++)
+ papi_to_ipp_printer_group(response, request,
+ PAPI_ATTR_APPEND, p[i]);
+ papiPrinterListFree(p);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/cups-get-default.c b/usr/src/lib/print/libipp-listener/common/cups-get-default.c
new file mode 100644
index 0000000000..0bb084ac9e
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/cups-get-default.c
@@ -0,0 +1,81 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: cups-get-default.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+#include <config-site.h>
+
+papi_status_t
+cups_get_default(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_printer_t p = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_attribute_t **printer_attributes = NULL;
+
+ char **req_attrs = NULL;
+ int limit = 0;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group may contain:
+ * requested-attributes
+ */
+ get_string_list(operational, "requested-attributes", &req_attrs);
+
+ status = papiPrinterQuery(svc, DEFAULT_DEST, req_attrs, NULL, &p);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "query default: %s",
+ ipp_svc_status_mesg(svc, status));
+ papiPrinterFree(p); /* we shouldn't have a printer */
+ return (status);
+ }
+
+ /*
+ * add the printer attributes to the response in a
+ * printer-attributes-group
+ */
+ printer_attributes = papiPrinterGetAttributeList(p);
+ add_default_attributes(&printer_attributes);
+ (void) papiAttributeListAddCollection(response, PAPI_ATTR_REPLACE,
+ "printer-attributes-group", printer_attributes);
+
+ papiPrinterFree(p);
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/cups-get-printers.c b/usr/src/lib/print/libipp-listener/common/cups-get-printers.c
new file mode 100644
index 0000000000..e883543381
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/cups-get-printers.c
@@ -0,0 +1,91 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: cups-get-printers.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+cups_get_printers(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_printer_t *p = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_filter_t filt;
+
+ char **req_attrs = NULL;
+ int limit = 0;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group may contain:
+ * limit
+ * printer-info
+ * printer-location
+ * printer-type
+ * printer-type-mask
+ * requested-attributes
+ */
+
+ papiAttributeListGetInteger(operational, NULL, "limit", &limit);
+
+ get_string_list(operational, "requested-attributes", &req_attrs);
+
+ /* only ask for the classes */
+ filt.type = PAPI_FILTER_BITMASK;
+ filt.filter.bitmask.mask = ~PAPI_PRINTER_CLASS;
+ filt.filter.bitmask.value = PAPI_PRINTER_LOCAL | PAPI_PRINTER_REMOTE;
+
+ /* query the print service for printers information */
+ status = papiPrintersList(svc, req_attrs, &filt, &p);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "query printers: %s",
+ ipp_svc_status_mesg(svc, status));
+ papiPrinterListFree(p); /* we shouldn't have any printers */
+ return (status);
+ }
+
+ if (p != NULL) {
+ int i;
+
+ for (i = 0; p[i] != NULL; i++)
+ papi_to_ipp_printer_group(response, request,
+ PAPI_ATTR_APPEND, p[i]);
+ papiPrinterListFree(p);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/cups-move-job.c b/usr/src/lib/print/libipp-listener/common/cups-move-job.c
new file mode 100644
index 0000000000..137a507f93
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/cups-move-job.c
@@ -0,0 +1,103 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: cups-move-job.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+cups_move_job(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL, **job = NULL;
+
+ char *message = NULL;
+ char *job_printer_uri = NULL;
+ char *queue = NULL;
+ char *dest = NULL;
+ int id = -1;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * Get job attributes from the request
+ */
+ status = papiAttributeListGetCollection(request, NULL,
+ "job-attributes-group", &job);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status,
+ "job-attributes-group: %s",
+ papiStatusString(status));
+ return (status);
+ }
+
+ /*
+ * the operational-attributes-group must contain:
+ * job-uri (or printer-uri/job-id)
+ */
+ get_printer_id(operational, &queue, &id);
+ if (id < 0) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing job-uri or job-id");
+ return (PAPI_BAD_REQUEST);
+ } else if (queue == NULL) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing printer-uri or job-uri");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * the job-attributes-group must contain:
+ * job-printer-uri
+ */
+ job_printer_uri = NULL;
+ (void) papiAttributeListGetString(job, NULL,
+ "job-printer-uri", &job_printer_uri);
+ if (job_printer_uri == NULL) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing job-printer-uri");
+ return (PAPI_BAD_REQUEST);
+ } else
+ dest = destination_from_printer_uri(job_printer_uri);
+
+ if ((status = papiJobMove(svc, queue, id, dest)) != PAPI_OK)
+ ipp_set_status(response, status,
+ "move failed: %s-%d to %s: %s",
+ (queue ? queue : "(null)"), id,
+ (dest ? dest : "(null)"),
+ ipp_svc_status_mesg(svc, status));
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/cups-reject-jobs.c b/usr/src/lib/print/libipp-listener/common/cups-reject-jobs.c
new file mode 100644
index 0000000000..1a35acdf62
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/cups-reject-jobs.c
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: cups-reject-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+cups_reject_jobs(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+
+ char *queue = NULL;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ if ((status = papiPrinterPause(svc, queue, NULL)) != PAPI_OK) {
+ ipp_set_status(response, status, "pause failed: %s: %s",
+ (queue ? queue : "(null)"),
+ ipp_svc_status_mesg(svc, status));
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/disable-printer.c b/usr/src/lib/print/libipp-listener/common/disable-printer.c
new file mode 100644
index 0000000000..e1c2fd3b5c
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/disable-printer.c
@@ -0,0 +1,77 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: disable-printer.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_disable_printer(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+
+ char *queue = NULL;
+ char *message = NULL;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * The operational-attributes-group may contain:
+ * printer-message-from-operator
+ */
+ (void) papiAttributeListGetString(operational, NULL,
+ "printer-message-from-operator", &message);
+
+ if ((status = papiPrinterDisable(svc, queue, message)) != PAPI_OK) {
+ ipp_set_status(response, status, "disable failed: %s: %s",
+ (queue ? queue : "(null)"),
+ ipp_svc_status_mesg(svc, status));
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/enable-printer.c b/usr/src/lib/print/libipp-listener/common/enable-printer.c
new file mode 100644
index 0000000000..0d5419d51d
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/enable-printer.c
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: enable-printer.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_enable_printer(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+
+ char *queue = NULL;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ if ((status = papiPrinterEnable(svc, queue)) != PAPI_OK) {
+ ipp_set_status(response, status, "enable failed: %s: %s",
+ (queue ? queue : "(null)"),
+ ipp_svc_status_mesg(svc, status));
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/get-job-attributes.c b/usr/src/lib/print/libipp-listener/common/get-job-attributes.c
new file mode 100644
index 0000000000..7f74054ebe
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/get-job-attributes.c
@@ -0,0 +1,89 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: get-job-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_get_job_attributes(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_job_t j = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_attribute_t **job_attributes = NULL;
+
+ char **req_attrs = NULL;
+ char *queue = NULL;
+ int id = -1;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * the operational-attributes-group must contain:
+ * job-uri (or printer-uri/job-id)
+ */
+ get_printer_id(operational, &queue, &id);
+ if (id < 0) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing job-uri or job-id");
+ return (PAPI_BAD_REQUEST);
+ } else if (queue == NULL) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing printer-uri or job-uri");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * the operational-attributes-group should contain:
+ * requested-attributes
+ */
+ get_string_list(operational, "requested-attributes", &req_attrs);
+
+ if ((status = papiJobQuery(svc, queue, id, req_attrs, &j)) != PAPI_OK) {
+ ipp_set_status(response, status, "query job: %s",
+ ipp_svc_status_mesg(svc, status));
+ papiJobFree(j); /* we shouldn't have a job, but just in case */
+ return (status);
+ }
+
+ /* add the job attributes to the response in a job-attributes-group */
+ if (j != NULL) {
+ papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j);
+ papiJobFree(j);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/get-jobs.c b/usr/src/lib/print/libipp-listener/common/get-jobs.c
new file mode 100644
index 0000000000..0e5e56f44c
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/get-jobs.c
@@ -0,0 +1,99 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: get-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_get_jobs(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_job_t *j = NULL;
+ papi_attribute_t **operational = NULL;
+
+ char **req_attrs = NULL;
+ char *queue = NULL;
+ int limit = 0;
+ char my_jobs = PAPI_FALSE;
+ char *which;
+ int type = 0;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * The operational-attributes-group may contain:
+ * limit
+ * requested-attributes
+ * which-jobs
+ * my-jobs
+ */
+ (void) papiAttributeListGetString(operational, NULL,
+ "which-jobs", &which);
+ (void) papiAttributeListGetBoolean(operational, NULL,
+ "my-jobs", &my_jobs);
+ (void) papiAttributeListGetInteger(operational, NULL, "limit", &limit);
+ get_string_list(operational, "requested-attributes", &req_attrs);
+
+ status = papiPrinterListJobs(svc, queue, req_attrs, type, limit, &j);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "query jobs: %s",
+ ipp_svc_status_mesg(svc, status));
+ return (status);
+ }
+
+ /* add any job's attributes to the response in job-attribute-groups */
+ if (j != NULL) {
+ int i;
+
+ for (i = 0; j[i] != NULL; i++)
+ papi_to_ipp_job_group(response, request,
+ PAPI_ATTR_APPEND, j[i]);
+ papiJobListFree(j);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/get-printer-attributes.c b/usr/src/lib/print/libipp-listener/common/get-printer-attributes.c
new file mode 100644
index 0000000000..2f33d0039c
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/get-printer-attributes.c
@@ -0,0 +1,92 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: get-printer-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_get_printer_attributes(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_printer_t p = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_attribute_t **printer_attributes = NULL;
+
+ char **req_attrs = NULL;
+ char *doc_fmt = NULL;
+ char *queue = NULL;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * The operational-attributes-group may contain:
+ * requested-attributes
+ * document-format
+ */
+ get_string_list(operational, "requested-attributes", &req_attrs);
+ (void) papiAttributeListGetString(operational, NULL,
+ "document-format", &doc_fmt);
+ status = papiPrinterQuery(svc, queue, req_attrs, NULL, &p);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "query printer: %s",
+ ipp_svc_status_mesg(svc, status));
+ papiPrinterFree(p); /* we shouldn't have a printer */
+ return (status);
+ }
+
+ /*
+ * add the printer attributes to the response in a
+ * printer-attributes-group
+ */
+ if (p != NULL) {
+ papi_to_ipp_printer_group(response, request,
+ PAPI_ATTR_REPLACE, p);
+ papiPrinterFree(p);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/hold-job.c b/usr/src/lib/print/libipp-listener/common/hold-job.c
new file mode 100644
index 0000000000..fcb1409df6
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/hold-job.c
@@ -0,0 +1,96 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: hold-job.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_hold_job(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+
+ char *message = NULL;
+ char *queue = NULL;
+ int id = -1;
+
+ /* Get operational attributes from the request */
+ papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * the operational-attributes-group must contain:
+ * job-uri (or printer-uri/job-id)
+ */
+ get_printer_id(operational, &queue, &id);
+ if (id < 0) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing job-uri or job-id");
+ return (PAPI_BAD_REQUEST);
+ } else if (queue == NULL) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing printer-uri or job-uri");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * the operational-attributes-group may contain:
+ * message
+ * job-hold-until (ingored)
+ */
+ (void) papiAttributeListGetString(operational, NULL,
+ "message", &message);
+
+ if ((status = papiJobHold(svc, queue, id)) != PAPI_OK) {
+ ipp_set_status(response, status,
+ "hold failed: %s-%d: %s",
+ (queue ? queue : "(null)"), id,
+ ipp_svc_status_mesg(svc, status));
+ } else if (message != NULL) { /* add unsupported attribute group */
+ papi_attribute_t **unsupported = NULL;
+
+ papiAttributeListAddValue(&unsupported, PAPI_ATTR_EXCL,
+ "message", PAPI_COLLECTION, NULL);
+ (void) papiAttributeListAddCollection(response,
+ PAPI_ATTR_REPLACE, "unsupported-attributes-group",
+ unsupported);
+ papiAttributeListFree(unsupported);
+
+ status = PAPI_OK_SUBST;
+ ipp_set_status(response, status,
+ "unsupported attribute in request");
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/ipp-listener.c b/usr/src/lib/print/libipp-listener/common/ipp-listener.c
new file mode 100644
index 0000000000..4be81c95d8
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/ipp-listener.c
@@ -0,0 +1,455 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: ipp-listener.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <assert.h>
+#include <errno.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <papi.h>
+#include <ipp-listener.h>
+
+typedef papi_status_t (ipp_handler_t)(papi_service_t svc,
+ papi_attribute_t **request,
+ papi_attribute_t ***response,
+ ipp_reader_t iread, void *fd);
+
+/*
+ * protocol request handlers are inserted below. The handler must be
+ * declared extern immediately below this comment and then an entry
+ * must be inserted in the "handlers" table a little further down.
+ */
+extern ipp_handler_t ipp_print_job;
+extern ipp_handler_t ipp_validate_job;
+extern ipp_handler_t ipp_create_job;
+extern ipp_handler_t ipp_get_printer_attributes;
+extern ipp_handler_t ipp_get_jobs;
+extern ipp_handler_t ipp_pause_printer;
+extern ipp_handler_t ipp_resume_printer;
+extern ipp_handler_t ipp_disable_printer;
+extern ipp_handler_t ipp_enable_printer;
+extern ipp_handler_t ipp_purge_jobs;
+extern ipp_handler_t ipp_send_document;
+extern ipp_handler_t ipp_cancel_job;
+extern ipp_handler_t ipp_get_job_attributes;
+extern ipp_handler_t ipp_release_job;
+extern ipp_handler_t ipp_hold_job;
+extern ipp_handler_t ipp_restart_job;
+extern ipp_handler_t ipp_set_job_attributes;
+extern ipp_handler_t ipp_set_printer_attributes;
+extern ipp_handler_t cups_get_default;
+extern ipp_handler_t cups_get_printers;
+extern ipp_handler_t cups_get_classes;
+extern ipp_handler_t cups_accept_jobs;
+extern ipp_handler_t cups_reject_jobs;
+extern ipp_handler_t cups_move_job;
+
+/* ARGSUSED0 */
+static papi_status_t
+default_handler(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response, ipp_reader_t iread, void *fd)
+{
+ int result = (int)PAPI_INTERNAL_ERROR;
+
+ if (response != NULL)
+ (void) papiAttributeListGetInteger(*response, NULL,
+ "status-code", &result);
+
+ return ((papi_status_t)result);
+}
+
+static struct {
+ int16_t id;
+ char *name;
+ ipp_handler_t *function;
+ enum { OP_REQUIRED, OP_OPTIONAL, OP_VENDOR } type;
+} handlers[] = {
+ /* Printer Operations */
+ { 0x0002, "print-job", ipp_print_job, OP_REQUIRED },
+ { 0x0003, "print-uri", NULL, OP_OPTIONAL },
+ { 0x0004, "validate-job", ipp_validate_job,
+ OP_REQUIRED },
+ { 0x0005, "create-job", ipp_create_job, OP_OPTIONAL },
+ { 0x000a, "get-jobs", ipp_get_jobs, OP_REQUIRED },
+ { 0x000b, "get-printer-attributes", ipp_get_printer_attributes,
+ OP_REQUIRED },
+ { 0x0010, "pause-printer", ipp_pause_printer,
+ OP_OPTIONAL },
+ { 0x0011, "resume-printer", ipp_resume_printer,
+ OP_OPTIONAL },
+ { 0x0012, "purge-jobs", ipp_purge_jobs, OP_OPTIONAL },
+ { 0x0013, "set-printer-attributes", ipp_set_printer_attributes,
+ OP_OPTIONAL },
+ { 0x0014, "set-job-attributes", ipp_set_job_attributes,
+ OP_OPTIONAL },
+ { 0x0022, "enable-printer", ipp_enable_printer,
+ OP_OPTIONAL },
+ { 0x0023, "disable-printer", ipp_disable_printer,
+ OP_OPTIONAL },
+ /* Job Operations */
+ { 0x0006, "send-document", ipp_send_document,
+ OP_OPTIONAL },
+ { 0x0007, "send-uri", NULL, OP_OPTIONAL },
+ { 0x0008, "cancel-job", ipp_cancel_job, OP_REQUIRED },
+ { 0x0009, "get-job-attributes", ipp_get_job_attributes,
+ OP_REQUIRED },
+ { 0x000c, "hold-job", ipp_hold_job, OP_OPTIONAL },
+ { 0x000d, "release-job", ipp_release_job,
+ OP_OPTIONAL },
+ { 0x000e, "restart-job", ipp_restart_job,
+ OP_OPTIONAL },
+ /* Other Operations */
+ { 0x4001, "cups-get-default", cups_get_default,
+ OP_VENDOR },
+ { 0x4002, "cups-get-printers", cups_get_printers,
+ OP_VENDOR },
+ { 0x4005, "cups-get-classes", cups_get_classes,
+ OP_VENDOR },
+ { 0x4008, "cups-accept-jobs", cups_accept_jobs,
+ OP_VENDOR },
+ { 0x4009, "cups-reject-jobs", cups_reject_jobs,
+ OP_VENDOR },
+ { 0x400D, "cups-move-job", cups_move_job, OP_VENDOR },
+ { 0, NULL, NULL, OP_VENDOR }
+};
+
+static int
+ipp_operation_name_to_index(char *name)
+{
+ int i;
+
+ for (i = 0; handlers[i].name != NULL; i++)
+ if (strcasecmp(name, handlers[i].name) == 0)
+ return (i);
+
+ return (-1);
+}
+
+static int
+ipp_operation_id_to_index(int16_t id)
+{
+ int i;
+
+ for (i = 0; handlers[i].name != NULL; i++)
+ if (id == handlers[i].id)
+ return (i);
+
+ return (-1);
+}
+
+static ipp_handler_t *
+ipp_operation_handler(papi_attribute_t **request, papi_attribute_t ***response)
+{
+ int id = 0;
+ int index;
+ papi_attribute_t **ops = NULL;
+ papi_status_t status;
+ char configured = PAPI_FALSE;
+
+ /* get the operation from the request */
+ status = papiAttributeListGetInteger(request, NULL,
+ "operation-id", &id);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, PAPI_BAD_ARGUMENT,
+ "no operation specified in request");
+ return (default_handler);
+ }
+
+ /* find the operation in the handler table */
+ index = ipp_operation_id_to_index(id);
+#ifdef DEBUG
+ if (index == -1)
+ fprintf(stderr, "Operation: 0x%4.4x\n", id);
+ else
+ fprintf(stderr, "Operation: 0x%4.4x(%s)\n", id,
+ handlers[index].name);
+ fflush(stderr);
+#endif
+
+ if ((index == -1) || (handlers[index].function == NULL)) {
+ ipp_set_status(response, PAPI_OPERATION_NOT_SUPPORTED,
+ "operation (0x%4.4x) not implemented by server",
+ id);
+ return (default_handler);
+ }
+
+ /* find the configured operations */
+ status = papiAttributeListGetCollection(request, NULL,
+ "operations", &ops);
+ if (status != PAPI_OK) { /* this should not be possible */
+ ipp_set_status(response, PAPI_INTERNAL_ERROR,
+ "sofware error, no operations configured");
+ return (default_handler);
+ }
+
+ /* check if the requested operation is configured */
+ status = papiAttributeListGetBoolean(ops, NULL,
+ handlers[index].name, &configured);
+ if ((status != PAPI_OK) || (configured != PAPI_TRUE)) {
+ ipp_set_status(response, PAPI_OPERATION_NOT_SUPPORTED,
+ "operation (%s 0x%4.4x) not enabled on server",
+ handlers[index].name, id);
+ return (default_handler);
+ }
+
+ return (handlers[index].function);
+}
+
+static char
+type_to_boolean(char *type)
+{
+ char result = PAPI_FALSE;
+
+ if ((strcasecmp(type, "true") == 0) ||
+ (strcasecmp(type, "yes") == 0) ||
+ (strcasecmp(type, "on") == 0) ||
+ (strcasecmp(type, "enable") == 0))
+ result = PAPI_TRUE;
+
+ return (result);
+}
+
+static papi_status_t
+ipp_configure_required_operations(papi_attribute_t ***list, char boolean)
+{
+ papi_status_t result = PAPI_OK;
+ int i;
+
+ for (i = 0; ((result == PAPI_OK) && (handlers[i].name != NULL)); i++)
+ if (handlers[i].type == OP_REQUIRED)
+ result = papiAttributeListAddBoolean(list,
+ PAPI_ATTR_REPLACE, handlers[i].name,
+ boolean);
+
+ return (result);
+
+}
+
+static papi_status_t
+ipp_configure_all_operations(papi_attribute_t ***list, char boolean)
+{
+ papi_status_t result = PAPI_OK;
+ int i;
+
+ for (i = 0; ((result == PAPI_OK) && (handlers[i].name != NULL)); i++)
+ result = papiAttributeListAddBoolean(list, PAPI_ATTR_REPLACE,
+ handlers[i].name, boolean);
+
+ return (result);
+}
+
+papi_status_t
+ipp_configure_operation(papi_attribute_t ***list, char *operation, char *type)
+{
+ papi_status_t result = PAPI_OPERATION_NOT_SUPPORTED;
+ char boolean = PAPI_FALSE;
+
+ if ((list == NULL) || (operation == NULL) || (type == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ boolean = type_to_boolean(type);
+
+ if (strcasecmp(operation, "all") == 0) {
+ result = ipp_configure_all_operations(list, boolean);
+ } else if (strcasecmp(operation, "required") == 0) {
+ result = ipp_configure_required_operations(list, boolean);
+ } else if (ipp_operation_name_to_index(operation) != -1) {
+ result = papiAttributeListAddBoolean(list, PAPI_ATTR_REPLACE,
+ operation, boolean);
+ }
+
+ return (result);
+}
+
+void
+ipp_operations_supported(papi_attribute_t ***list, papi_attribute_t **request)
+{
+ papi_attribute_t **group = NULL;
+
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operations", &group);
+ if (group != NULL) {
+ int i;
+
+ for (i = 0; handlers[i].name != NULL; i++) {
+ char boolean = PAPI_FALSE;
+ (void) papiAttributeListGetBoolean(group, NULL,
+ handlers[i].name, &boolean);
+
+ if (boolean == PAPI_TRUE)
+ (void) papiAttributeListAddInteger(list,
+ PAPI_ATTR_APPEND,
+ "operations-supported",
+ handlers[i].id);
+ }
+ }
+}
+
+static papi_status_t
+ipp_initialize_response(papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_attribute_t **operational = NULL;
+ int i;
+
+ if ((request == NULL) || (response == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* If the response was initialized, start over */
+ if (*response != NULL) {
+ papiAttributeListFree(*response);
+ *response = NULL;
+ }
+
+ /* Add the basic ipp header information to the response */
+ (void) papiAttributeListGetInteger(request, NULL, "version-major", &i);
+ (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE,
+ "version-major", i);
+ (void) papiAttributeListGetInteger(request, NULL, "version-minor", &i);
+ (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE,
+ "version-minor", i);
+
+ (void) papiAttributeListGetInteger(request, NULL, "request-id", &i);
+ (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE,
+ "request-id", i);
+
+ /* Add a default operational attributes group to the response */
+ (void) papiAttributeListAddString(&operational, PAPI_ATTR_EXCL,
+ "attributes-charset", "utf-8");
+ (void) papiAttributeListAddString(&operational, PAPI_ATTR_EXCL,
+ "attributes-natural-language", "en-us");
+
+ (void) papiAttributeListAddCollection(response, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", operational);
+ papiAttributeListFree(operational);
+
+ return (PAPI_OK);
+}
+
+static papi_status_t
+print_service_connect(papi_service_t *svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+ char *printer_uri = NULL;
+ char *svc_name = NULL;
+ char *user = NULL;
+
+ /* Get the operational attributes group from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /* get the user name */
+ (void) papiAttributeListGetString(request, NULL, "default-user", &user);
+ (void) papiAttributeListGetString(operational, NULL,
+ "requesting-user-name", &user);
+
+ /* get the printer or service name */
+ get_printer_id(operational, &printer_uri, NULL);
+ svc_name = destination_from_printer_uri(printer_uri);
+ (void) papiAttributeListGetString(request, NULL,
+ "default-service", &svc_name);
+
+ status = papiServiceCreate(svc, svc_name, user, NULL, NULL,
+ PAPI_ENCRYPT_NEVER, NULL);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "print service: %s",
+ papiStatusString(status));
+ return (status);
+ }
+
+ /*
+ * Trusted Solaris can't be trusting of intermediaries. Pass
+ * the socket connection to the print service to retrieve the
+ * sensativity label off of a multi-level port.
+ */
+ {
+ int fd = -1;
+
+ (void) papiAttributeListGetInteger(request, NULL,
+ "peer-socket", &fd);
+ if (fd != -1)
+ papiServiceSetPeer(*svc, fd);
+ }
+
+ return (status);
+}
+
+papi_status_t
+ipp_process_request(papi_attribute_t **request, papi_attribute_t ***response,
+ ipp_reader_t iread, void *fd)
+{
+ papi_status_t result = PAPI_OK;
+
+ ipp_initialize_response(request, response);
+
+#ifdef DEBUG
+ fprintf(stderr, "REQUEST:");
+ papiAttributeListPrint(stderr, request, " %d ", getpid());
+ fprintf(stderr, "\n");
+#endif
+
+ /* verify that the request is "well-formed" */
+ if ((result = ipp_validate_request(request, response)) == PAPI_OK) {
+ papi_service_t svc = NULL;
+ ipp_handler_t *handler;
+
+ result = print_service_connect(&svc, request, response);
+ handler = ipp_operation_handler(request, response);
+
+ /* process the request */
+ if ((result == PAPI_OK) && (handler != NULL))
+ result = (handler)(svc, request, response, iread, fd);
+#ifdef DEBUG
+ fprintf(stderr, "RESULT: %s\n", papiStatusString(result));
+#endif
+ papiServiceDestroy(svc);
+ }
+
+ (void) papiAttributeListAddInteger(response, PAPI_ATTR_EXCL,
+ "status-code", result);
+ massage_response(request, *response);
+
+#ifdef DEBUG
+ fprintf(stderr, "RESPONSE:");
+ papiAttributeListPrint(stderr, *response, " %d ", getpid());
+ fprintf(stderr, "\n");
+#endif
+
+ return (result);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/ipp-listener.h b/usr/src/lib/print/libipp-listener/common/ipp-listener.h
new file mode 100644
index 0000000000..5a8718477e
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/ipp-listener.h
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#ifndef _IPP_LISTENER_H
+#define _IPP_LISTENER_H
+
+/* $Id: ipp-listener.h 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <ipp.h>
+
+/* exported functions */
+extern papi_status_t ipp_configure_operation(papi_attribute_t ***list,
+ char *operation, char *type);
+extern papi_status_t ipp_process_request(papi_attribute_t **request,
+ papi_attribute_t ***response,
+ ipp_reader_t iread, void *fd);
+
+/* shared internal functions */
+extern char *ipp_svc_status_mesg(papi_service_t svc, papi_status_t status);
+extern char *destination_from_printer_uri(char *);
+extern void get_printer_id(papi_attribute_t **attributes, char **printer,
+ int *id);
+extern void ipp_operations_supported(papi_attribute_t ***list,
+ papi_attribute_t **request);
+extern void get_string_list(papi_attribute_t **attributes, char *name,
+ char ***values);
+extern void add_default_attributes(papi_attribute_t ***attributes);
+extern void papi_to_ipp_printer_group(papi_attribute_t ***response,
+ papi_attribute_t **request, int flags,
+ papi_printer_t p);
+extern void papi_to_ipp_job_group(papi_attribute_t ***response,
+ papi_attribute_t **request, int flags, papi_job_t j);
+extern void massage_response(papi_attribute_t **request,
+ papi_attribute_t **response);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IPP_LISTENER_H */
diff --git a/usr/src/lib/print/libipp-listener/common/mapfile b/usr/src/lib/print/libipp-listener/common/mapfile
new file mode 100644
index 0000000000..aa1d9a583e
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/mapfile
@@ -0,0 +1,39 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# $Id: mapfile 151 2006-04-25 16:55:34Z njacobs $
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+SUNWprivate_1.0 {
+ global:
+ ipp_configure_operation;
+ ipp_process_request;
+ local:
+ *;
+};
diff --git a/usr/src/lib/print/libipp-listener/common/pause-printer.c b/usr/src/lib/print/libipp-listener/common/pause-printer.c
new file mode 100644
index 0000000000..0afe4aadf0
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/pause-printer.c
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: pause-printer.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_pause_printer(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+
+ char *queue = NULL;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ if ((status = papiPrinterPause(svc, queue, NULL)) != PAPI_OK) {
+ ipp_set_status(response, status, "pause failed: %s: %s",
+ (queue ? queue : "(null)"),
+ ipp_svc_status_mesg(svc, status));
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/print-job.c b/usr/src/lib/print/libipp-listener/common/print-job.c
new file mode 100644
index 0000000000..3b24d53339
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/print-job.c
@@ -0,0 +1,123 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: print-job.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_print_job(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response, ipp_reader_t iread, void *fd)
+{
+ papi_status_t status;
+ papi_stream_t s = NULL;
+ papi_job_t j = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_attribute_t **job_attributes = NULL;
+ char *queue = NULL;
+ ssize_t rc;
+ char buf[BUFSIZ];
+ char *keys[] = { "attributes-natural-language", "attributes-charset",
+ "printer-uri", NULL };
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * The operational-attributes-group may contain:
+ * job-name
+ * ipp-attribute-fidelity
+ * document-name
+ * compression
+ * document-format
+ * document-natural-language
+ * job-k-octets
+ * job-impressions
+ * job-media-sheets
+ * Simply copy the entire contents of the operational-attributes-group
+ * for the PAPI call's possible use.
+ */
+ split_and_copy_attributes(keys, operational, NULL, &job_attributes);
+
+ /* copy any job-attributes-group attributes for the PAPI call */
+ if (papiAttributeListGetCollection(request, NULL,
+ "job-attributes-group", &operational) == PAPI_OK)
+ copy_attributes(&job_attributes, operational);
+
+ /* request job creation with a resulting stream that we can write to */
+ status = papiJobStreamOpen(svc, queue, job_attributes, NULL, &s);
+ papiAttributeListFree(job_attributes);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "job submission: %s",
+ ipp_svc_status_mesg(svc, status));
+ return (status);
+ }
+
+ /* copy the document data from the IPP connection to the stream */
+ while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0))
+ status = papiJobStreamWrite(svc, s, buf, rc);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "write job data: %s",
+ ipp_svc_status_mesg(svc, status));
+ return (status);
+ }
+
+ /* close the stream, committing the job */
+ status = papiJobStreamClose(svc, s, &j);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "close job stream: %s",
+ ipp_svc_status_mesg(svc, status));
+ papiJobFree(j); /* we shouldn't have a job, but just in case */
+ return (status);
+ }
+
+ /* add the job attributes to the response in a job-attributes-group */
+ if (j != NULL) {
+ papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j);
+ papiJobFree(j);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/purge-jobs.c b/usr/src/lib/print/libipp-listener/common/purge-jobs.c
new file mode 100644
index 0000000000..7128595844
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/purge-jobs.c
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: purge-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_purge_jobs(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_job_t *jobs = NULL;
+ papi_attribute_t **operational = NULL;
+
+ char *queue = NULL;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ if ((status = papiPrinterPurgeJobs(svc, queue, &jobs)) != PAPI_OK) {
+ ipp_set_status(response, status, "purge failed: %s: %s",
+ (queue ? queue : "(null)"),
+ ipp_svc_status_mesg(svc, status));
+ }
+
+ papiJobListFree(jobs);
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/release-job.c b/usr/src/lib/print/libipp-listener/common/release-job.c
new file mode 100644
index 0000000000..0ae16906a6
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/release-job.c
@@ -0,0 +1,95 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: release-job.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_release_job(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+
+ char *message = NULL;
+ char *queue = NULL;
+ int id = -1;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * the operational-attributes-group must contain:
+ * job-uri (or printer-uri/job-id)
+ */
+ get_printer_id(operational, &queue, &id);
+ if (id < 0) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing job-uri or job-id");
+ return (PAPI_BAD_REQUEST);
+ } else if (queue == NULL) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing printer-uri or job-uri");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * the operational-attributes-group may contain:
+ * message
+ */
+ (void) papiAttributeListGetString(operational, NULL,
+ "message", &message);
+
+ if ((status = papiJobRelease(svc, queue, id)) != PAPI_OK) {
+ ipp_set_status(response, status,
+ "release failed: %s-%d: %s",
+ (queue ? queue : "(null)"), id,
+ ipp_svc_status_mesg(svc, status));
+ } else if (message != NULL) { /* add unsupported attribute group */
+ papi_attribute_t **unsupported = NULL;
+
+ papiAttributeListAddValue(&unsupported, PAPI_ATTR_EXCL,
+ "message", PAPI_COLLECTION, NULL);
+ (void) papiAttributeListAddCollection(response,
+ PAPI_ATTR_REPLACE, "unsupported-attributes-group",
+ unsupported);
+ papiAttributeListFree(unsupported);
+
+ status = PAPI_OK_SUBST;
+ ipp_set_status(response, status,
+ "unsupported attribute in request");
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/restart-job.c b/usr/src/lib/print/libipp-listener/common/restart-job.c
new file mode 100644
index 0000000000..d78967b0f2
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/restart-job.c
@@ -0,0 +1,106 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: restart-job.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_restart_job(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+
+ char *message = NULL;
+ char *hold_until = NULL;
+ char *queue = NULL;
+ int id = -1;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * the operational-attributes-group must contain:
+ * job-uri (or printer-uri/job-id)
+ */
+ get_printer_id(operational, &queue, &id);
+ if (id < 0) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing job-uri or job-id");
+ return (PAPI_BAD_REQUEST);
+ } else if (queue == NULL) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing printer-uri or job-uri");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * the operational-attributes-group may contain:
+ * message
+ * job-hold-until
+ */
+ (void) papiAttributeListGetString(operational, NULL,
+ "job-hold-until", &hold_until);
+ (void) papiAttributeListGetString(operational, NULL,
+ "message", &message);
+
+ if ((status = papiJobRestart(svc, queue, id)) != PAPI_OK) {
+ ipp_set_status(response, status,
+ "restart failed: %s-%d: %s",
+ (queue ? queue : "(null)"), id,
+ ipp_svc_status_mesg(svc, status));
+ } else if ((message != NULL) || (hold_until != NULL)) {
+ /* add unsupported attribute group */
+ papi_attribute_t **unsupported = NULL;
+
+ if (message != NULL)
+ (void) papiAttributeListAddValue(&unsupported,
+ PAPI_ATTR_EXCL, "message",
+ PAPI_COLLECTION, NULL);
+ if (hold_until != NULL)
+ (void) papiAttributeListAddValue(&unsupported,
+ PAPI_ATTR_EXCL, "hold-until",
+ PAPI_COLLECTION, NULL);
+ (void) papiAttributeListAddCollection(response,
+ PAPI_ATTR_REPLACE, "unsupported-attributes-group",
+ unsupported);
+ papiAttributeListFree(unsupported);
+
+ status = PAPI_OK_SUBST;
+ ipp_set_status(response, status,
+ "unsupported attribute in request");
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/resume-printer.c b/usr/src/lib/print/libipp-listener/common/resume-printer.c
new file mode 100644
index 0000000000..8d48ee9adb
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/resume-printer.c
@@ -0,0 +1,68 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: resume-printer.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_resume_printer(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ papi_status_t status;
+ papi_attribute_t **operational = NULL;
+
+ char *queue = NULL;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ if ((status = papiPrinterResume(svc, queue)) != PAPI_OK) {
+ ipp_set_status(response, status, "resume failed: %s: %s",
+ (queue ? queue : "(null)"),
+ ipp_svc_status_mesg(svc, status));
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/send-document.c b/usr/src/lib/print/libipp-listener/common/send-document.c
new file mode 100644
index 0000000000..4a4d3a4314
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/send-document.c
@@ -0,0 +1,143 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: send-document.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+/*
+ * When the PAPI supports papiJobCreate(), papiJobStreamAdd() and
+ * papiJobClose(), this will be much cleaner and more efficient, but in the
+ * meantime, we are using a private, non-standard interface to do this.
+ */
+papi_status_t
+ipp_send_document(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response, ipp_reader_t iread, void *fd)
+{
+ papi_status_t status;
+ papi_stream_t s = NULL;
+ papi_job_t j = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_attribute_t **job_attributes = NULL;
+ char *queue = NULL;
+ ssize_t rc;
+ int id = -1;
+ char buf[BUFSIZ];
+ char last = PAPI_FALSE;
+ char *keys[] = { "attributes-natural-language", "attributes-charset",
+ "printer-uri", "job-id", "job-uri", "last-document",
+ NULL };
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * the operational-attributes-group must contain:
+ * job-uri (or printer-uri/job-id)
+ * last-document
+ */
+ get_printer_id(operational, &queue, &id);
+ if (id < 0) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing job-uri or job-id");
+ return (PAPI_BAD_REQUEST);
+ } else if (queue == NULL) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing printer-uri or job-uri");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ status = papiAttributeListGetBoolean(operational, NULL,
+ "last-document", &last);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "last-document: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * the operational-attributes-group may contain:
+ * document-name
+ * compression
+ * document-format
+ * document-natural-language
+ * Simply copy the entire contents of the operational-attributes-group
+ * for the PAPI call's possible use.
+ */
+ split_and_copy_attributes(keys, operational, NULL, &job_attributes);
+
+ /* copy any job-attributes-group attributes for the PAPI call */
+ if (papiAttributeListGetCollection(request, NULL,
+ "job-attributes-group", &operational) == PAPI_OK)
+ copy_attributes(&job_attributes, operational);
+
+ /* create a stream to write the document data on */
+ status = papiJobStreamAdd(svc, queue, id, &s);
+ papiAttributeListFree(job_attributes);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "job submission: %s",
+ ipp_svc_status_mesg(svc, status));
+ return (status);
+ }
+
+ /* copy the document data from the IPP connection to the stream */
+ while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0))
+ status = papiJobStreamWrite(svc, s, buf, rc);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "write job data: %s",
+ ipp_svc_status_mesg(svc, status));
+ return (status);
+ }
+
+ /* close the stream */
+ status = papiJobStreamClose(svc, s, &j);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "close job stream: %s",
+ ipp_svc_status_mesg(svc, status));
+ papiJobFree(j); /* we shouldn't have a job, but just in case */
+ return (status);
+ }
+
+ /* if it's the last document, commit the job */
+ if (last == PAPI_TRUE) {
+ status = papiJobCommit(svc, queue, id);
+ }
+
+ /* add the job attributes to the response in a job-attributes-group */
+ if (j != NULL) {
+ papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j);
+ papiJobFree(j);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/set-job-attributes.c b/usr/src/lib/print/libipp-listener/common/set-job-attributes.c
new file mode 100644
index 0000000000..57c0b899f3
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/set-job-attributes.c
@@ -0,0 +1,90 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: set-job-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_set_job_attributes(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response, ipp_reader_t iread, void *fd)
+{
+ papi_status_t status;
+ papi_stream_t s = NULL;
+ papi_job_t j = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_attribute_t **job_attributes = NULL;
+
+ char *queue = NULL;
+ int32_t id = -1;
+ ssize_t rc;
+ char buf[BUFSIZ];
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * job-uri
+ */
+ get_printer_id(operational, &queue, &id);
+ if (id < 0) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing job-uri or job-id");
+ return (PAPI_BAD_REQUEST);
+ } else if (queue == NULL) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing printer-uri or job-uri");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /* get the job-attributes-group attributes for the PAPI call */
+ papiAttributeListGetCollection(request, NULL,
+ "job-attributes-group", &job_attributes);
+
+ /* request job modification */
+ status = papiJobModify(svc, queue, id, job_attributes, &j);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "job modification: %s",
+ ipp_svc_status_mesg(svc, status));
+ return (status);
+ }
+
+ /* add the job attributes to the response in a job-attributes-group */
+ if (j != NULL) {
+ papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j);
+ papiJobFree(j);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/set-printer-attributes.c b/usr/src/lib/print/libipp-listener/common/set-printer-attributes.c
new file mode 100644
index 0000000000..7d80864961
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/set-printer-attributes.c
@@ -0,0 +1,83 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: set-printer-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_set_printer_attributes(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response, ipp_reader_t iread, void *fd)
+{
+ papi_status_t status;
+ papi_printer_t p = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_attribute_t **printer_attributes = NULL;
+
+ char *queue = NULL;
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, PAPI_BAD_REQUEST,
+ "missing printer-uri or job-uri");
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /* get the printer-attributes-group attributes for the PAPI call */
+ papiAttributeListGetCollection(request, NULL,
+ "printer-attributes-group", &printer_attributes);
+
+ /* request job modification */
+ status = papiPrinterModify(svc, queue, printer_attributes, &p);
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "printer modification: %s",
+ ipp_svc_status_mesg(svc, status));
+ return (status);
+ }
+
+ /* add the job attributes to the response in a job-attributes-group */
+ if (p != NULL) {
+ papi_to_ipp_printer_group(response, request,
+ PAPI_ATTR_REPLACE, p);
+ papiPrinterFree(p);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/common/validate-job.c b/usr/src/lib/print/libipp-listener/common/validate-job.c
new file mode 100644
index 0000000000..8ea72ee38b
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/common/validate-job.c
@@ -0,0 +1,107 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: validate-job.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <papi.h>
+#include <ipp.h>
+#include <ipp-listener.h>
+
+papi_status_t
+ipp_validate_job(papi_service_t svc, papi_attribute_t **request,
+ papi_attribute_t ***response, ipp_reader_t iread, void *fd)
+{
+ papi_status_t status;
+ papi_job_t j = NULL;
+ papi_attribute_t **operational = NULL;
+ papi_attribute_t **job_attributes = NULL;
+ char *queue = NULL;
+ char *files[] = { "/etc/syslog.conf", NULL };
+ ssize_t rc;
+ char buf[BUFSIZ];
+ char *keys[] = { "attributes-natural-language", "attributes-charset",
+ "printer-uri", NULL };
+
+ /* Get operational attributes from the request */
+ (void) papiAttributeListGetCollection(request, NULL,
+ "operational-attributes-group", &operational);
+
+ /*
+ * The operational-attributes-group must contain:
+ * printer-uri
+ */
+ get_printer_id(operational, &queue, NULL);
+ if (queue == NULL) {
+ ipp_set_status(response, status, "printer-uri: %s",
+ papiStatusString(status));
+ return (PAPI_BAD_REQUEST);
+ }
+
+ /*
+ * The operational-attributes-group may contain:
+ * job-name
+ * ipp-attribute-fidelity
+ * document-name
+ * compression
+ * document-format
+ * document-natural-language
+ * job-k-octets
+ * job-impressions
+ * job-media-sheets
+ * Simply copy the entire contents of the operational-attributes-group
+ * for the PAPI call's possible use.
+ */
+ split_and_copy_attributes(keys, operational, NULL, &job_attributes);
+
+ /* copy any job-attributes-group attributes for the PAPI call */
+ if (papiAttributeListGetCollection(request, NULL,
+ "job-attributes-group", &operational) == PAPI_OK)
+ copy_attributes(&job_attributes, operational);
+
+ /* request job validation */
+ status = papiJobValidate(svc, queue, job_attributes, NULL, files, &j);
+ papiAttributeListFree(job_attributes);
+
+ if (status != PAPI_OK) {
+ ipp_set_status(response, status, "validating job: %s",
+ ipp_svc_status_mesg(svc, status));
+ papiJobFree(j); /* we shouldn't have a job, but just in case */
+ return (status);
+ }
+
+ /* add the job attributes to the response in a job-attributes-group */
+ if (j != NULL) {
+ papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j);
+ papiJobFree(j);
+ }
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libipp-listener/i386/Makefile b/usr/src/lib/print/libipp-listener/i386/Makefile
new file mode 100644
index 0000000000..3b985583a4
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT)
diff --git a/usr/src/lib/print/libipp-listener/sparc/Makefile b/usr/src/lib/print/libipp-listener/sparc/Makefile
new file mode 100644
index 0000000000..3b985583a4
--- /dev/null
+++ b/usr/src/lib/print/libipp-listener/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT)
diff --git a/usr/src/lib/print/libpapi-common/Makefile b/usr/src/lib/print/libpapi-common/Makefile
new file mode 100644
index 0000000000..ef7e964b85
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/Makefile
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../../Makefile.lib
+
+HDRS = papi.h
+HDRDIR = common
+SUBDIRS = $(MACH)
+#$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all clean clobber: .WAIT $(SUBDIRS)
+install: .WAIT $(SUBDIRS) install_h
+
+lint: # $(SUBDIRS)
+
+install_h: $(ROOTHDRS)
+
+check: $(CHECKHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/print/libpapi-common/Makefile.com b/usr/src/lib/print/libpapi-common/Makefile.com
new file mode 100644
index 0000000000..3d21ee6c40
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/Makefile.com
@@ -0,0 +1,57 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = libpapi-common.a
+VERS = .0
+OBJECTS = attribute.o common.o library.o list.o misc.o status.o uri.o
+
+include ../../../Makefile.lib
+include ../../../Makefile.rootfs
+
+ROOTLIBDIR= $(ROOT)/usr/lib
+
+LIBS = $(DYNLIB)
+
+SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c)
+
+$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+MAPFILE = $(SRCDIR)/mapfile
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -I$(SRCDIR)
+DYNFLAGS += -M $(MAPFILE)
+LDLIBS += -lc
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include ../../../Makefile.targ
diff --git a/usr/src/lib/print/libpapi-common/common/attribute.c b/usr/src/lib/print/libpapi-common/common/attribute.c
new file mode 100644
index 0000000000..2b2e035cfe
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/attribute.c
@@ -0,0 +1,1181 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: attribute.c 157 2006-04-26 15:07:55Z ktou $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <alloca.h>
+#include <papi.h>
+
+static void papiAttributeFree(papi_attribute_t *attribute);
+
+static void
+papiAttributeValueFree(papi_attribute_value_type_t type,
+ papi_attribute_value_t *value)
+{
+ if (value != NULL) {
+ switch (type) {
+ case PAPI_STRING:
+ if (value->string != NULL)
+ free(value->string);
+ break;
+ case PAPI_COLLECTION:
+ if (value->collection != NULL) {
+ int i;
+
+ for (i = 0; value->collection[i] != NULL; i++)
+ papiAttributeFree(value->collection[i]);
+
+ free(value->collection);
+ }
+ break;
+ default: /* don't need to free anything extra */
+ break;
+ }
+
+ free(value);
+ }
+}
+
+static void
+papiAttributeValuesFree(papi_attribute_value_type_t type,
+ papi_attribute_value_t **values)
+{
+ if (values != NULL) {
+ int i;
+
+ for (i = 0; values[i] != NULL; i++)
+ papiAttributeValueFree(type, values[i]);
+
+ free(values);
+ }
+}
+
+static void
+papiAttributeFree(papi_attribute_t *attribute)
+{
+ if (attribute != NULL) {
+ if (attribute->name != NULL)
+ free(attribute->name);
+ if (attribute->values != NULL)
+ papiAttributeValuesFree(attribute->type,
+ attribute->values);
+ free(attribute);
+ }
+}
+
+void
+papiAttributeListFree(papi_attribute_t **list)
+{
+ if (list != NULL) {
+ int i;
+
+ for (i = 0; list[i] != NULL; i++)
+ papiAttributeFree(list[i]);
+
+ free(list);
+ }
+}
+
+static papi_attribute_t **
+collection_dup(papi_attribute_t **collection)
+{
+ papi_attribute_t **result = NULL;
+
+ /* allows a NULL collection that is "empty" or "no value" */
+ if (collection != NULL) {
+ papi_status_t status = PAPI_OK;
+ int i;
+
+ for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK));
+ i++) {
+ papi_attribute_t *a = collection[i];
+
+ status = papiAttributeListAddValue(&result,
+ PAPI_ATTR_APPEND, a->name, a->type,
+ NULL);
+ if ((status == PAPI_OK) && (a->values != NULL)) {
+ int j;
+
+ for (j = 0; ((a->values[j] != NULL) &&
+ (status == PAPI_OK)); j++)
+ status = papiAttributeListAddValue(
+ &result,
+ PAPI_ATTR_APPEND,
+ a->name, a->type,
+ a->values[j]);
+ }
+ }
+ if (status != PAPI_OK) {
+ papiAttributeListFree(result);
+ result = NULL;
+ }
+ }
+
+ return (result);
+}
+
+static papi_attribute_value_t *
+papiAttributeValueDup(papi_attribute_value_type_t type,
+ papi_attribute_value_t *v)
+{
+ papi_attribute_value_t *result = NULL;
+
+ if ((v != NULL) && ((result = calloc(1, sizeof (*result))) != NULL)) {
+ switch (type) {
+ case PAPI_STRING:
+ if (v->string == NULL) {
+ free(result);
+ result = NULL;
+ } else
+ result->string = strdup(v->string);
+ break;
+ case PAPI_INTEGER:
+ result->integer = v->integer;
+ break;
+ case PAPI_BOOLEAN:
+ result->boolean = v->boolean;
+ break;
+ case PAPI_RANGE:
+ result->range.lower = v->range.lower;
+ result->range.upper = v->range.upper;
+ break;
+ case PAPI_RESOLUTION:
+ result->resolution.xres = v->resolution.xres;
+ result->resolution.yres = v->resolution.yres;
+ result->resolution.units = v->resolution.units;
+ break;
+ case PAPI_DATETIME:
+ result->datetime = v->datetime;
+ break;
+ case PAPI_COLLECTION:
+ result->collection = collection_dup(v->collection);
+ break;
+ case PAPI_METADATA:
+ result->metadata = v->metadata;
+ break;
+ default: /* unknown type, fail to duplicate */
+ free(result);
+ result = NULL;
+ }
+ }
+
+ return (result);
+}
+
+static papi_attribute_t *
+papiAttributeAlloc(char *name, papi_attribute_value_type_t type)
+{
+ papi_attribute_t *result = NULL;
+
+ if ((result = calloc(1, sizeof (*result))) != NULL) {
+ result->name = strdup(name);
+ result->type = type;
+ }
+
+ return (result);
+}
+
+static papi_status_t
+papiAttributeListAppendValue(papi_attribute_value_t ***values,
+ papi_attribute_value_type_t type,
+ papi_attribute_value_t *value)
+{
+
+ if (values == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ if (value != NULL) { /* this allows "empty" attributes */
+ papi_attribute_value_t *tmp = NULL;
+
+ if ((tmp = papiAttributeValueDup(type, value)) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ list_append(values, tmp);
+ }
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+papiAttributeListAddValue(papi_attribute_t ***list, int flgs,
+ char *name, papi_attribute_value_type_t type,
+ papi_attribute_value_t *value)
+{
+ papi_status_t result;
+ int flags = flgs;
+ papi_attribute_t *attribute = NULL;
+ papi_attribute_value_t **values = NULL;
+
+ if ((list == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((type == PAPI_RANGE) && (value != NULL) &&
+ (value->range.lower > value->range.upper))
+ return (PAPI_BAD_ARGUMENT); /* RANGE must have min <= max */
+
+ if (flags == 0) /* if it wasn't set, set a default behaviour */
+ flags = PAPI_ATTR_APPEND;
+
+ /* look for an existing one */
+ attribute = papiAttributeListFind(*list, name);
+
+ if (((flags & PAPI_ATTR_EXCL) != 0) && (attribute != NULL))
+ return (PAPI_CONFLICT); /* EXISTS */
+
+ if (((flags & PAPI_ATTR_REPLACE) == 0) && (attribute != NULL) &&
+ (attribute->type != type))
+ return (PAPI_CONFLICT); /* TYPE CONFLICT */
+
+ /* if we don't have one, create it and add it to the list */
+ if ((attribute == NULL) &&
+ ((attribute = papiAttributeAlloc(name, type)) != NULL))
+ list_append(list, attribute);
+
+ /* if we don't have one by now, it's most likely an alloc fail */
+ if (attribute == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ /*
+ * if we are replacing, clear any existing values, but don't free
+ * until after we have replaced the values, in case we are replacing
+ * a collection with a relocated version of the original collection.
+ */
+ if (((flags & PAPI_ATTR_REPLACE) != 0) && (attribute->values != NULL)) {
+ values = attribute->values;
+ attribute->values = NULL;
+ }
+
+ attribute->type = type;
+
+ result = papiAttributeListAppendValue(&attribute->values, type, value);
+
+ /* free old values if we replaced them */
+ if (values != NULL)
+ papiAttributeValuesFree(type, values);
+
+ return (result);
+}
+
+papi_status_t
+papiAttributeListAddString(papi_attribute_t ***list, int flags,
+ char *name, char *string)
+{
+ papi_attribute_value_t v;
+
+ v.string = (char *)string;
+ return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v));
+}
+
+papi_status_t
+papiAttributeListAddInteger(papi_attribute_t ***list, int flags,
+ char *name, int integer)
+{
+ papi_attribute_value_t v;
+
+ v.integer = integer;
+ return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v));
+}
+
+papi_status_t
+papiAttributeListAddBoolean(papi_attribute_t ***list, int flags,
+ char *name, char boolean)
+{
+ papi_attribute_value_t v;
+
+ v.boolean = boolean;
+ return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v));
+}
+
+papi_status_t
+papiAttributeListAddRange(papi_attribute_t ***list, int flags,
+ char *name, int lower, int upper)
+{
+ papi_attribute_value_t v;
+
+ v.range.lower = lower;
+ v.range.upper = upper;
+ return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v));
+}
+
+papi_status_t
+papiAttributeListAddResolution(papi_attribute_t ***list, int flags,
+ char *name, int xres, int yres,
+ papi_resolution_unit_t units)
+{
+ papi_attribute_value_t v;
+
+ v.resolution.xres = xres;
+ v.resolution.yres = yres;
+ v.resolution.units = units;
+ return (papiAttributeListAddValue(list, flags, name,
+ PAPI_RESOLUTION, &v));
+}
+
+papi_status_t
+papiAttributeListAddDatetime(papi_attribute_t ***list, int flags,
+ char *name, time_t datetime)
+{
+ papi_attribute_value_t v;
+
+ v.datetime = datetime;
+ return (papiAttributeListAddValue(list, flags, name,
+ PAPI_DATETIME, &v));
+}
+
+papi_status_t
+papiAttributeListAddCollection(papi_attribute_t ***list, int flags,
+ char *name, papi_attribute_t **collection)
+{
+ papi_attribute_value_t v;
+
+ v.collection = (papi_attribute_t **)collection;
+ return (papiAttributeListAddValue(list, flags, name,
+ PAPI_COLLECTION, &v));
+}
+
+papi_status_t
+papiAttributeListAddMetadata(papi_attribute_t ***list, int flags,
+ char *name, papi_metadata_t metadata)
+{
+ papi_attribute_value_t v;
+
+ v.metadata = metadata;
+ return (papiAttributeListAddValue(list, flags, name,
+ PAPI_METADATA, &v));
+}
+
+papi_status_t
+papiAttributeListDelete(papi_attribute_t ***list, char *name)
+{
+ papi_attribute_t *attribute;
+
+ if ((list == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((attribute = papiAttributeListFind(*list, name)) == NULL)
+ return (PAPI_NOT_FOUND);
+
+ list_remove(*list, attribute);
+ papiAttributeFree(attribute);
+
+ return (PAPI_OK);
+}
+
+papi_attribute_t *
+papiAttributeListFind(papi_attribute_t **list, char *name)
+{
+ int i;
+ if ((list == NULL) || (name == NULL))
+ return (NULL);
+
+ for (i = 0; list[i] != NULL; i++)
+ if (strcasecmp(list[i]->name, name) == 0)
+ return ((papi_attribute_t *)list[i]);
+
+ return (NULL);
+}
+
+papi_attribute_t *
+papiAttributeListGetNext(papi_attribute_t **list, void **iter)
+{
+ papi_attribute_t **tmp, *result;
+
+ if ((list == NULL) && (iter == NULL))
+ return (NULL);
+
+ if (*iter == NULL)
+ *iter = list;
+
+ tmp = *iter;
+ result = *tmp;
+ *iter = ++tmp;
+
+ return (result);
+}
+
+papi_status_t
+papiAttributeListGetValue(papi_attribute_t **list, void **iter,
+ char *name, papi_attribute_value_type_t type,
+ papi_attribute_value_t **value)
+{
+ papi_attribute_value_t **tmp;
+ void *fodder = NULL;
+
+ if ((list == NULL) || ((name == NULL) && (iter == NULL)) ||
+ (value == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if (iter == NULL)
+ iter = &fodder;
+
+ if ((iter == NULL) || (*iter == NULL)) {
+ papi_attribute_t *attr = papiAttributeListFind(list, name);
+
+ if (attr == NULL)
+ return (PAPI_NOT_FOUND);
+
+ if (attr->type != type)
+ return (PAPI_NOT_POSSIBLE);
+
+ tmp = attr->values;
+ } else
+ tmp = *iter;
+
+ if (tmp == NULL)
+ return (PAPI_NOT_FOUND);
+
+ *value = *tmp;
+ *iter = ++tmp;
+
+ if (*value == NULL)
+ return (PAPI_GONE);
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+papiAttributeListGetString(papi_attribute_t **list, void **iter,
+ char *name, char **vptr)
+{
+ papi_status_t status;
+ papi_attribute_value_t *value = NULL;
+
+ if (vptr == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ status = papiAttributeListGetValue(list, iter, name,
+ PAPI_STRING, &value);
+ if (status == PAPI_OK)
+ *vptr = value->string;
+
+ return (status);
+}
+
+papi_status_t
+papiAttributeListGetInteger(papi_attribute_t **list, void **iter,
+ char *name, int *vptr)
+{
+ papi_status_t status;
+ papi_attribute_value_t *value = NULL;
+
+ if (vptr == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ status = papiAttributeListGetValue(list, iter, name,
+ PAPI_INTEGER, &value);
+ if (status == PAPI_OK)
+ *vptr = value->integer;
+
+ return (status);
+}
+
+papi_status_t
+papiAttributeListGetBoolean(papi_attribute_t **list, void **iter,
+ char *name, char *vptr)
+{
+ papi_status_t status;
+ papi_attribute_value_t *value = NULL;
+
+ if (vptr == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ status = papiAttributeListGetValue(list, iter, name,
+ PAPI_BOOLEAN, &value);
+ if (status == PAPI_OK)
+ *vptr = value->boolean;
+
+ return (status);
+}
+
+papi_status_t
+papiAttributeListGetRange(papi_attribute_t **list, void **iter,
+ char *name, int *min, int *max)
+{
+ papi_status_t status;
+ papi_attribute_value_t *value = NULL;
+
+ if ((min == NULL) || (max == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ status = papiAttributeListGetValue(list, iter, name,
+ PAPI_RANGE, &value);
+ if (status == PAPI_OK) {
+ *min = value->range.lower;
+ *max = value->range.upper;
+ }
+
+ return (status);
+}
+
+papi_status_t
+papiAttributeListGetResolution(papi_attribute_t **list, void **iter,
+ char *name, int *x, int *y,
+ papi_resolution_unit_t *units)
+{
+ papi_status_t status;
+ papi_attribute_value_t *value = NULL;
+
+ if ((x == NULL) || (y == NULL) || (units == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ status = papiAttributeListGetValue(list, iter, name,
+ PAPI_RESOLUTION, &value);
+ if (status == PAPI_OK) {
+ *x = value->resolution.xres;
+ *y = value->resolution.yres;
+ *units = value->resolution.units;
+ }
+
+ return (status);
+}
+
+papi_status_t
+papiAttributeListGetDatetime(papi_attribute_t **list, void **iter,
+ char *name, time_t *dt)
+{
+ papi_status_t status;
+ papi_attribute_value_t *value = NULL;
+
+ if (dt == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ status = papiAttributeListGetValue(list, iter, name,
+ PAPI_DATETIME, &value);
+ if (status == PAPI_OK) {
+ *dt = value->datetime;
+ }
+
+ return (status);
+}
+
+papi_status_t
+papiAttributeListGetCollection(papi_attribute_t **list, void **iter,
+ char *name, papi_attribute_t ***collection)
+{
+ papi_status_t status;
+ papi_attribute_value_t *value = NULL;
+
+ if (collection == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ status = papiAttributeListGetValue(list, iter, name,
+ PAPI_COLLECTION, &value);
+ if (status == PAPI_OK) {
+ *collection = value->collection;
+ }
+
+ return (status);
+}
+
+papi_status_t
+papiAttributeListGetMetadata(papi_attribute_t **list, void **iter,
+ char *name, papi_metadata_t *vptr)
+{
+ papi_status_t status;
+ papi_attribute_value_t *value = NULL;
+
+ if (vptr == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ status = papiAttributeListGetValue(list, iter, name,
+ PAPI_METADATA, &value);
+ if (status == PAPI_OK)
+ *vptr = value->metadata;
+
+ return (status);
+}
+
+/*
+ * Description: The given string contains one or more attributes, in the
+ * following form:
+ * "aaaa=true bbbbb=1 ccccc=abcd"
+ * extract the next attribute from that string; the 'next'
+ * parameter should be set to zero to extract the first attribute
+ * in the string.
+ *
+ */
+
+static char *
+_getNextAttr(char *string, int *next)
+
+{
+ char *result = NULL;
+ char *start = (char *)string + *next;
+ char *nl = NULL;
+ char *sp = NULL;
+ char *tab = NULL;
+ char *val = NULL;
+ int len = 0;
+
+ if ((string != NULL) && (*start != '\0')) {
+ while ((*start == ' ') || (*start == '\t') || (*start == '\n'))
+ {
+ start++;
+ }
+ nl = strchr(start, '\n');
+ sp = strchr(start, ' ');
+ tab = strchr(start, '\t');
+
+ val = strchr(start, '=');
+
+ if ((val != NULL) && ((val[1] == '"') || (val[1] == '\''))) {
+ val = strchr(&val[2], val[1]);
+ if (val != NULL) {
+ nl = strchr(&val[1], '\n');
+ sp = strchr(&val[1], ' ');
+ tab = strchr(&val[1], '\t');
+ }
+ }
+
+ if ((nl != NULL) &&
+ ((sp == NULL) || ((sp != NULL) && (nl < sp))) &&
+ ((tab == NULL) || ((tab != NULL) && (nl < tab)))) {
+ len = nl-start;
+ } else if ((sp != NULL) && (tab != NULL) && (sp > tab)) {
+ len = tab-start;
+ } else if ((sp != NULL) && (sp != NULL)) {
+ len = sp-start;
+ } else if ((tab != NULL) && (tab != NULL)) {
+ len = tab-start;
+ }
+
+ if (len == 0) {
+ len = strlen(start);
+ }
+
+ if (len > 0) {
+ result = (char *)malloc(len+1);
+ if (result != NULL) {
+ strncpy(result, start, len);
+ result[len] = '\0';
+ *next = (start-string)+len;
+ }
+ }
+ }
+
+ return (result);
+} /* _getNextAttr() */
+
+
+/*
+ * Description: Parse the given attribute string value and transform it into
+ * the papi_attribute_value_t in the papi_attribute_t structure.
+ *
+ */
+
+static papi_status_t
+_parseAttrValue(char *value, papi_attribute_t *attr)
+
+{
+ papi_status_t result = PAPI_OK;
+ int len = 0;
+ int i = 0;
+ char *papiString = NULL;
+ char *tmp1 = NULL;
+ char *tmp2 = NULL;
+ char *tmp3 = NULL;
+ papi_attribute_value_t **avalues = NULL;
+
+ avalues = malloc(sizeof (papi_attribute_value_t *) * 2);
+ if (avalues == NULL) {
+ result = PAPI_TEMPORARY_ERROR;
+ return (result);
+ }
+ avalues[0] = malloc(sizeof (papi_attribute_value_t));
+ avalues[1] = NULL;
+ if (avalues[0] == NULL) {
+ free(avalues);
+ result = PAPI_TEMPORARY_ERROR;
+ return (result);
+ }
+
+
+/*
+ * TODO - need to sort out 'resolution', 'dateandtime' & 'collection' values
+ */
+ if ((value != NULL) && (strlen(value) > 0) && (attr != NULL)) {
+
+ len = strlen(value);
+ if ((len >= 2) && (((value[0] == '"') &&
+ (value[len-1] == '"')) || ((value[0] == '\'') &&
+ (value[len-1] == '\'')))) {
+ /* string value */
+ attr->type = PAPI_STRING;
+
+ papiString = strdup(value+1);
+ if (papiString != NULL) {
+ papiString[strlen(papiString)-1] = '\0';
+ avalues[0]->string = papiString;
+ } else {
+ result = PAPI_TEMPORARY_ERROR;
+ }
+ } else if ((strcasecmp(value, "true") == 0) ||
+ (strcasecmp(value, "YES") == 0)) {
+ /* boolean = true */
+ attr->type = PAPI_BOOLEAN;
+ avalues[0]->boolean = PAPI_TRUE;
+ } else if ((strcasecmp(value, "false") == 0) ||
+ (strcasecmp(value, "NO") == 0)) {
+ /* boolean = false */
+ attr->type = PAPI_BOOLEAN;
+ avalues[0]->boolean = PAPI_FALSE;
+ } else {
+ /* is value an integer or a range ? */
+
+ i = 0;
+ attr->type = PAPI_INTEGER;
+ tmp1 = strdup(value);
+ while (((value[i] >= '0') && (value[i] <= '9')) ||
+ (value[i] == '-')) {
+ if (value[i] == '-') {
+ tmp1[i] = '\0';
+ tmp2 = &tmp1[i+1];
+ attr->type = PAPI_RANGE;
+ }
+
+ i++;
+ }
+
+ if (strlen(value) == i) {
+ if (attr->type == PAPI_RANGE) {
+ avalues[0]->range.lower = atoi(tmp1);
+ avalues[0]->range.upper = atoi(tmp2);
+ } else {
+ avalues[0]->integer = atoi(value);
+ }
+ } else {
+ /* is value a resolution ? */
+ i = 0;
+ attr->type = PAPI_INTEGER;
+ tmp1 = strdup(value);
+ while (((value[i] >= '0') &&
+ (value[i] <= '9')) ||
+ (value[i] == 'x')) {
+ if (value[i] == 'x') {
+ tmp1[i] = '\0';
+ if (attr->type == PAPI_INTEGER)
+ {
+ tmp2 = &tmp1[i+1];
+ attr->type =
+ PAPI_RESOLUTION;
+ } else {
+ tmp3 = &tmp1[i+1];
+ }
+ }
+
+ i++;
+ }
+
+ if (strlen(value) == i) {
+ if (attr->type == PAPI_RESOLUTION) {
+ avalues[0]->resolution.xres =
+ atoi(tmp1);
+ avalues[0]->resolution.yres =
+ atoi(tmp2);
+ if (tmp3 != NULL) {
+ avalues[0]->
+ resolution.units =
+ atoi(tmp3);
+ } else {
+ avalues[0]->
+ resolution.units = 0;
+ }
+ }
+ }
+
+ if (attr->type != PAPI_RESOLUTION) {
+ attr->type = PAPI_STRING;
+ avalues[0]->string = strdup(value);
+ if (avalues[0]->string == NULL) {
+ result = PAPI_TEMPORARY_ERROR;
+ }
+ }
+ }
+ free(tmp1);
+ }
+
+ } else {
+ result = PAPI_BAD_ARGUMENT;
+ }
+
+ if (result != PAPI_OK) {
+ i = 0;
+ while (avalues[i] != NULL) {
+ free(avalues[i]);
+ i++;
+ }
+ free(avalues);
+ } else {
+ attr->values = avalues;
+ }
+
+ return (result);
+} /* _parseAttrValue() */
+
+
+/*
+ * Description: Parse the given attribute string and transform it into the
+ * papi_attribute_t structure.
+ *
+ */
+
+static papi_status_t
+_parseAttributeString(char *attrString, papi_attribute_t *attr)
+
+{
+ papi_status_t result = PAPI_OK;
+ char *string = NULL;
+ char *p = NULL;
+ papi_attribute_value_t **avalues = NULL;
+
+ if ((attrString != NULL) && (strlen(attrString) >= 3) &&
+ (attr != NULL)) {
+ attr->name = NULL;
+ string = strdup(attrString);
+ if (string != NULL) {
+ p = strchr(string, '=');
+ if (p != NULL) {
+ *p = '\0';
+ attr->name = string;
+ p++; /* pointer to value */
+
+ result = _parseAttrValue(p, attr);
+ } else {
+ char value;
+ /* boolean - no value so assume 'true' */
+ if (strncasecmp(string, "no", 2) == 0) {
+ string += 2;
+ value = PAPI_FALSE;
+ } else
+ value = PAPI_TRUE;
+
+ attr->name = string;
+ attr->type = PAPI_BOOLEAN;
+
+ avalues = malloc(
+ sizeof (papi_attribute_value_t *) * 2);
+ if (avalues == NULL) {
+ result = PAPI_TEMPORARY_ERROR;
+ } else {
+ avalues[0] = malloc(
+ sizeof (papi_attribute_value_t));
+ avalues[1] = NULL;
+ if (avalues[0] == NULL) {
+ free(avalues);
+ result = PAPI_TEMPORARY_ERROR;
+ } else {
+ avalues[0]->boolean = value;
+ attr->values = avalues;
+ }
+ }
+ }
+ }
+ } else {
+ result = PAPI_BAD_ARGUMENT;
+ }
+
+ return (result);
+} /* _parseAttributeString() */
+
+
+papi_status_t
+papiAttributeListFromString(papi_attribute_t ***attrs,
+ int flags, char *string)
+{
+ papi_status_t result = PAPI_OK;
+ int next = 0;
+ char *attrString = NULL;
+ papi_attribute_t attr;
+
+ if ((attrs != NULL) && (string != NULL) &&
+ ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL))
+ == 0)) {
+ attrString = _getNextAttr(string, &next);
+ while ((result == PAPI_OK) && (attrString != NULL)) {
+ result = _parseAttributeString(attrString, &attr);
+ if ((result == PAPI_OK) && (attr.name != NULL)) {
+ /* add this attribute to the list */
+ if ((attr.values != NULL) &&
+ (attr.values[0] != NULL)) {
+ result = papiAttributeListAddValue(
+ attrs, PAPI_ATTR_APPEND,
+ attr.name, attr.type,
+ attr.values[0]);
+ free(attr.values[0]);
+ free(attr.values);
+ } else {
+ result = PAPI_TEMPORARY_ERROR;
+ }
+ }
+ free(attrString);
+
+ attrString = _getNextAttr(string, &next);
+ }
+ }
+ else
+ {
+ result = PAPI_BAD_ARGUMENT;
+ }
+
+ return (result);
+}
+
+static papi_status_t
+papiAttributeToString(papi_attribute_t *attribute, char *delim,
+ char *buffer, size_t buflen)
+{
+ papi_attribute_value_t **values = attribute->values;
+ int rc, i;
+
+ strlcat(buffer, attribute->name, buflen);
+ strlcat(buffer, "=", buflen);
+
+ if (values == NULL)
+ return (PAPI_OK);
+
+ for (i = 0; values[i] != NULL; i++) {
+ switch (attribute->type) {
+ case PAPI_STRING:
+ rc = strlcat(buffer, values[i]->string, buflen);
+ break;
+ case PAPI_INTEGER: {
+ char string[24];
+
+ snprintf(string, sizeof (string), "%d",
+ values[i]->integer);
+ rc = strlcat(buffer, string, buflen);
+ }
+ break;
+ case PAPI_BOOLEAN:
+ rc = strlcat(buffer, (values[i]->boolean ? "true" :
+ "false"), buflen);
+ break;
+ case PAPI_RANGE: {
+ char string[24];
+
+ snprintf(string, sizeof (string), "%d-%d",
+ values[i]->range.lower, values[i]->range.upper);
+ rc = strlcat(buffer, string, buflen);
+ }
+ break;
+ case PAPI_RESOLUTION: {
+ char string[24];
+
+ snprintf(string, sizeof (string), "%dx%ddp%c",
+ values[i]->resolution.xres,
+ values[i]->resolution.yres,
+ (values[i]->resolution.units == PAPI_RES_PER_CM
+ ? 'c' : 'i'));
+ rc = strlcat(buffer, string, buflen);
+ }
+ break;
+ case PAPI_DATETIME: {
+ struct tm *tm = localtime(&values[i]->datetime);
+
+ if (tm != NULL) {
+ char string[64];
+
+ strftime(string, sizeof (string), "%C", tm);
+ rc = strlcat(buffer, string, buflen);
+ }}
+ break;
+ case PAPI_COLLECTION: {
+ char *string = alloca(buflen);
+#ifdef DEBUG
+ char prefix[256];
+
+ snprintf(prefix, sizeof (prefix), "%s %s(%d) ", delim,
+ attribute->name, i);
+
+ papiAttributeListToString(values[i]->collection,
+ prefix, string, buflen);
+#else
+ papiAttributeListToString(values[i]->collection,
+ delim, string, buflen);
+#endif
+ rc = strlcat(buffer, string, buflen);
+ }
+ break;
+ default: {
+ char string[32];
+
+ snprintf(string, sizeof (string), "unknown-type-0x%x",
+ attribute->type);
+ rc = strlcat(buffer, string, buflen);
+ }
+ }
+ if (values[i+1] != NULL)
+ rc = strlcat(buffer, ",", buflen);
+
+ if (rc >= buflen)
+ return (PAPI_NOT_POSSIBLE);
+
+ }
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+papiAttributeListToString(papi_attribute_t **attrs,
+ char *delim, char *buffer, size_t buflen)
+{
+ papi_status_t status = PAPI_OK;
+ int i;
+
+ if ((attrs == NULL) || (buffer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ buffer[0] = '\0';
+ if (!delim)
+ delim = " ";
+
+#ifdef DEBUG
+ strlcat(buffer, delim, buflen);
+#endif
+ for (i = 0; ((attrs[i] != NULL) && (status == PAPI_OK)); i++) {
+ status = papiAttributeToString(attrs[i], delim, buffer, buflen);
+ if (attrs[i+1] != NULL)
+ strlcat(buffer, delim, buflen);
+ }
+
+ return (status);
+}
+
+static int
+is_in_list(char *value, char **list)
+{
+ if ((list != NULL) && (value != NULL)) {
+ int i;
+
+ for (i = 0; list[i] != NULL; i++)
+ if (strcasecmp(value, list[i]) == 0)
+ return (0);
+ }
+
+ return (1);
+}
+
+static papi_status_t
+copy_attribute(papi_attribute_t ***list, papi_attribute_t *attribute)
+{
+ papi_status_t status;
+ int i = 0;
+
+ if ((list == NULL) || (attribute == NULL) ||
+ (attribute->values == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ for (status = papiAttributeListAddValue(list, PAPI_ATTR_EXCL,
+ attribute->name, attribute->type,
+ attribute->values[i]);
+ ((status == PAPI_OK) && (attribute->values[i] != NULL));
+ status = papiAttributeListAddValue(list, PAPI_ATTR_APPEND,
+ attribute->name, attribute->type,
+ attribute->values[i]))
+ i++;
+
+ return (status);
+}
+
+void
+copy_attributes(papi_attribute_t ***result, papi_attribute_t **attributes)
+{
+ int i;
+
+ if ((result == NULL) || (attributes == NULL))
+ return;
+
+ for (i = 0; attributes[i] != NULL; i++)
+ copy_attribute(result, attributes[i]);
+}
+
+void
+split_and_copy_attributes(char **list, papi_attribute_t **attributes,
+ papi_attribute_t ***in, papi_attribute_t ***out)
+{
+ int i;
+
+ if ((list == NULL) || (attributes == NULL))
+ return;
+
+ for (i = 0; attributes[i] != NULL; i++)
+ if (is_in_list(attributes[i]->name, list) == 0)
+ copy_attribute(in, attributes[i]);
+ else
+ copy_attribute(out, attributes[i]);
+}
+
+void
+papiAttributeListPrint(FILE *fp, papi_attribute_t **attributes,
+ char *prefix_fmt, ...)
+{
+ char *prefix = NULL;
+ char *buffer = NULL;
+ char *newfmt = NULL;
+ void *mem;
+ ssize_t size = 0;
+ va_list ap;
+
+ newfmt = malloc(strlen(prefix_fmt) + 2);
+ sprintf(newfmt, "\n%s", prefix_fmt);
+
+ va_start(ap, prefix_fmt);
+ while (vsnprintf(prefix, size, newfmt, ap) > size) {
+ size += 1024;
+ mem = realloc(prefix, size);
+ if (!mem) goto error;
+ prefix = mem;
+ }
+ va_end(ap);
+
+ if (attributes) {
+ size = 0;
+ while (papiAttributeListToString(attributes, prefix, buffer,
+ size) != PAPI_OK) {
+ size += 1024;
+ mem = realloc(buffer, size);
+ if (!mem) goto error;
+ buffer = mem;
+ }
+ }
+
+ fprintf(fp, "%s%s\n", prefix, buffer ? buffer : "");
+ fflush(fp);
+
+ error:
+ free(newfmt);
+ free(prefix);
+ free(buffer);
+}
diff --git a/usr/src/lib/print/libpapi-common/common/common.c b/usr/src/lib/print/libpapi-common/common/common.c
new file mode 100644
index 0000000000..318b1d2c83
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/common.c
@@ -0,0 +1,132 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: common.c 151 2006-04-25 16:55:34Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Shared "unsupported" function implementations that can be overridden
+ * by libpapi and the various print service modules (psms).
+ */
+
+#include <stdlib.h>
+#include <papi.h>
+
+static papi_status_t
+_unsupported()
+{
+ return (PAPI_OPERATION_NOT_SUPPORTED);
+}
+
+static void *
+_unsupported_null_return()
+{
+ return (NULL);
+}
+
+static void
+_unsupported_no_return()
+{
+}
+
+/*
+ * Service interfaces
+ */
+#pragma weak papiServiceCreate = _unsupported
+#pragma weak papiServiceDestroy = _unsupported_no_return
+#pragma weak papiServiceSetPeer = _unsupported
+#pragma weak papiServiceSetUserName = _unsupported
+#pragma weak papiServiceSetPassword = _unsupported
+#pragma weak papiServiceSetEncryption = _unsupported
+#pragma weak papiServiceSetAuthCB = _unsupported
+#pragma weak papiServiceSetAppData = _unsupported
+
+#pragma weak papiServiceGetServiceName = _unsupported_null_return
+#pragma weak papiServiceGetUserName = _unsupported_null_return
+#pragma weak papiServiceGetPassword = _unsupported_null_return
+#pragma weak papiServiceGetAppData = _unsupported_null_return
+
+papi_encryption_t
+papiServiceGetEncryption(papi_service_t handle)
+{
+ return (PAPI_ENCRYPT_NEVER);
+}
+
+#pragma weak papiServiceGetAttributeList = _unsupported_null_return
+#pragma weak papiServiceGetStatusMessage = _unsupported_null_return
+
+/*
+ * Printer operations
+ */
+#pragma weak papiPrintersList = _unsupported
+#pragma weak papiPrinterQuery = _unsupported
+#pragma weak papiPrinterEnable = _unsupported
+#pragma weak papiPrinterDisable = _unsupported
+#pragma weak papiPrinterPause = _unsupported
+#pragma weak papiPrinterResume = _unsupported
+#pragma weak papiPrinterAdd = _unsupported
+#pragma weak papiPrinterModify = _unsupported
+#pragma weak papiPrinterRemove = _unsupported
+#pragma weak papiPrinterPurgeJobs = _unsupported
+#pragma weak papiPrinterListJobs = _unsupported
+#pragma weak papiPrinterGetAttributeList = _unsupported_null_return
+#pragma weak papiPrinterFree = _unsupported_no_return
+#pragma weak papiPrinterListFree = _unsupported_no_return
+
+/*
+ * Job interfaces
+ */
+#pragma weak papiJobHold = _unsupported
+#pragma weak papiJobRelease = _unsupported
+#pragma weak papiJobRestart = _unsupported
+#pragma weak papiJobPromote = _unsupported
+#pragma weak papiJobModify = _unsupported
+#pragma weak papiJobSubmit = _unsupported
+#pragma weak papiJobSubmitByReference = _unsupported
+#pragma weak papiJobValidate = _unsupported
+#pragma weak papiJobStreamOpen = _unsupported
+#pragma weak papiJobStreamWrite = _unsupported
+#pragma weak papiJobStreamClose = _unsupported
+#pragma weak papiJobQuery = _unsupported
+#pragma weak papiJobMove = _unsupported
+#pragma weak papiJobCancel = _unsupported
+#pragma weak papiJobGetAttributeList = _unsupported_null_return
+#pragma weak papiJobGetPrinterName = _unsupported_null_return
+#pragma weak papiJobCreate = _unsupported
+#pragma weak papiJobStreamAdd = _unsupported
+#pragma weak papiJobCommit = _unsupported
+
+int
+papiJobGetId(papi_job_t job)
+{
+ return (-1);
+}
+
+#pragma weak papiJobGetJobTicket = _unsupported_null_return
+#pragma weak papiJobFree = _unsupported_no_return
+#pragma weak papiJobListFree = _unsupported_no_return
diff --git a/usr/src/lib/print/libpapi-common/common/config-site.h b/usr/src/lib/print/libpapi-common/common/config-site.h
new file mode 100644
index 0000000000..2007f4f669
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/config-site.h
@@ -0,0 +1,60 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#ifndef _CONFIG_SITE_H
+#define _CONFIG_SITE_H
+
+/* $Id: config-site.h.in 171 2006-05-20 06:00:32Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* the "default" destination for various commands and libraries */
+#define DEFAULT_DEST "_default"
+
+/* the "default" server uri to fallback to */
+#define DEFAULT_SERVICE_URI "lpsched://localhost/printers"
+
+/* the "default" IPP service to fallback to in the IPP psm */
+#define DEFAULT_IPP_SERVICE_URI "ipp://localhost/printers"
+
+/* the name of the SUID lpd-port binary that hands psm-lpd a connected socket */
+#define SUID_LPD_PORT "/usr/lib/print/lpd-port"
+
+/* enable/disable printer-uri in enumeration results */
+#define NEED_BROKEN_PRINTER_URI_SEMANTIC
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CONFIG_SITE_H */
diff --git a/usr/src/lib/print/libpapi-common/common/config.h b/usr/src/lib/print/libpapi-common/common/config.h
new file mode 100644
index 0000000000..280ac6d6b4
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/config.h
@@ -0,0 +1,159 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+/* source/libpapi-common/config.h. Generated by configure. */
+/* source/libpapi-common/config.h.in. Generated from configure.in by autoheader. */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `dlopen' function. */
+#define HAVE_DLOPEN 1
+
+/* Define to 1 if you have the `dlsym' function. */
+#define HAVE_DLSYM 1
+
+/* Define to 1 if you have the `fprintf' function. */
+#define HAVE_FPRINTF 1
+
+/* define if you have getipnodbyname */
+#define HAVE_GETIPNODEBYNAME 1
+
+/* Define to 1 if you have the `getpassphrase' function. */
+#define HAVE_GETPASSPHRASE 1
+
+/* Define to 1 if you have the `gettext' function. */
+#define HAVE_GETTEXT 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `is_system_labeled' function. */
+#define HAVE_IS_SYSTEM_LABELED 1
+
+/* Define to 1 if you have the `localtime' function. */
+#define HAVE_LOCALTIME 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <priv.h> header file. */
+#define HAVE_PRIV_H 1
+
+/* define if you have rresvport_af */
+#define HAVE_RRESVPORT_AF 1
+
+/* Define to 1 if you have the <ruby.h> header file. */
+/* #undef HAVE_RUBY_H */
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcmp' function. */
+#define HAVE_STRCMP 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcat' function. */
+#define HAVE_STRLCAT 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+#define HAVE_STRLCPY 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Name of package */
+#define PACKAGE "papi"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "1.0_rc1"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CONFIG_H */
diff --git a/usr/src/lib/print/libpapi-common/common/library.c b/usr/src/lib/print/libpapi-common/common/library.c
new file mode 100644
index 0000000000..12b1ffb449
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/library.c
@@ -0,0 +1,105 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: library.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <alloca.h>
+#include <libintl.h>
+#include <papi.h>
+
+static char *calls[] = {
+ /* Attribute Calls */
+ "papiAttributeListAddValue",
+ "papiAttributeListAddBoolean", "papiAttributeListAddCollection",
+ "papiAttributeListAddDatetime", "papiAttributeListAddInteger",
+ "papiAttributeListAddMetadata", "papiAttributeListAddRange",
+ "papiAttributeListAddResolution", "papiAttributeListAddString",
+ "papiAttributeListDelete",
+ "papiAttributeListGetValue", "papiAttributeListGetNext",
+ "papiAttributeListFind",
+ "papiAttributeListGetBoolean", "papiAttributeListGetCollection",
+ "papiAttributeListGetDatetime", "papiAttributeListGetInteger",
+ "papiAttributeListGetMetadata", "papiAttributeListGetRange",
+ "papiAttributeListGetResolution", "papiAttributeListGetString",
+ "papiAttributeListFromString", "papiAttributeListToString",
+ "papiAttributeListFree",
+ /* Job Calls */
+ "papiJobSubmit", "papiJobSubmitByReference", "papiJobValidate",
+ "papiJobStreamOpen", "papiJobStreamWrite", "papiJobStreamClose",
+ "papiJobQuery", "papiJobModify", "papiJobCancel", "papiJobPromote",
+ "papiJobGetAttributeList", "papiJobGetId", "papiJobGetPrinterName",
+ "papiJobGetJobTicket",
+ "papiJobFree", "papiJobListFree",
+ "papiJobHold", "papiJobRelease", "papiJobRestart",
+ /* Printer Calls */
+ "papiPrintersList", "papiPrinterQuery", "papiPrinterModify",
+ "papiPrinterAdd", "papiPrinterRemove",
+ "papiPrinterPause", "papiPrinterResume",
+ "papiPrinterDisable", "papiPrinterEnable",
+ "papiPrinterPurgeJobs", "papiPrinterListJobs",
+ "papiPrinterGetAttributeList",
+ "papiPrinterFree", "papiPrinterListFree",
+ /* Service Calls */
+ "papiServiceCreate", "papiServiceDestroy",
+ "papiServiceGetAppData",
+ "papiServiceGetEncryption", "papiServiceGetPassword",
+ "papiServiceGetServiceName", "papiServiceGetUserName",
+ "papiServiceSetAppData", "papiServiceSetAuthCB",
+ "papiServiceSetEncryption", "papiServiceSetPassword",
+ "papiServiceSetUserName",
+ "papiServiceGetAttributeList", "papiServiceGetStatusMessage",
+ /* Misc Calls */
+ "papiStatusString",
+ "papiLibrarySupportedCall", "papiLibrarySupportedCalls",
+ NULL
+};
+
+char **
+papiLibrarySupportedCalls()
+{
+ return (calls);
+}
+
+char
+papiLibrarySupportedCall(const char *name)
+{
+ int i;
+
+ for (i = 0; calls[i] != NULL; i++)
+ if (strcmp(name, calls[i]) == 0)
+ return (PAPI_TRUE);
+
+ return (PAPI_FALSE);
+}
diff --git a/usr/src/lib/print/libpapi-common/common/list.c b/usr/src/lib/print/libpapi-common/common/list.c
new file mode 100644
index 0000000000..9ed0d2ded2
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/list.c
@@ -0,0 +1,161 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: list.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+
+static int __list_increment = 16;
+
+int
+list_append(void ***list, void *item)
+{
+ int count;
+
+ if ((list == NULL) || (item == NULL)) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (item != NULL) {
+ if (*list == NULL)
+ *list = (void **)calloc(__list_increment,
+ sizeof (void *));
+
+ for (count = 0; (*list)[count] != NULL; count++);
+
+ if ((count + 1) % __list_increment == 0) { /* expand the list */
+ void **new_list = NULL;
+ int new_size = (((count + 1) / __list_increment) + 1) *
+ __list_increment;
+
+ new_list = (void **)calloc(new_size, sizeof (void *));
+
+ for (count = 0; (*list)[count] != NULL; count++)
+ new_list[count] = (*list)[count];
+ free(*list);
+ *list = new_list;
+ }
+
+ (*list)[count] = item;
+ }
+
+ return (0);
+}
+
+/*
+ * list_concatenate() takes in two NULL terminated lists of items (type **)
+ * and creates a new list with items from list2 appended on the end of
+ * the list of items from list1. The result is a list (type **). If
+ * there is a failure, -1 is returned.
+ */
+int
+list_concatenate(void ***result, void **list2)
+{
+ void **list1;
+ int size1 = 0,
+ size2 = 0,
+ new_size = 0;
+
+ if ((result == NULL) || ((*result == NULL) && (list2 == NULL))) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ list1 = *result;
+
+ if (list1 != NULL)
+ for (size1 = 0; list1[size1] != NULL; size1++);
+ if (list2 != NULL)
+ for (size2 = 0; list2[size2] != NULL; size2++);
+
+ /* list1 + list2 padded to a multiple of _list_increment */
+ new_size = ((size1 + size2)/__list_increment + 2) * __list_increment;
+
+ if ((*result = (void **)calloc((new_size), sizeof (void *)))
+ != NULL) {
+ int count = 0;
+
+ if (list1 != NULL)
+ for (size1 = 0; list1[size1] != NULL; size1++)
+ (*result)[count++] = list1[size1];
+ if (list2 != NULL)
+ for (size2 = 0; list2[size2] != NULL; size2++)
+ (*result)[count++] = list2[size2];
+ free(list1);
+ }
+
+ return (0);
+}
+
+/*
+ * list_locate() iterates through the list passed in and uses the comparison
+ * routine and element passed in to find an element in the list. It
+ * returns the first element matched, or NULL if none exists
+ */
+void *
+list_locate(void **list, int (*compare)(void *, void *), void *element)
+{
+ int current = 0;
+
+ if ((list != NULL) && (element != NULL))
+ for (current = 0; list[current] != NULL; current++)
+ if ((compare)(list[current], element) == 0)
+ return (list[current]);
+ return (NULL);
+}
+
+void
+list_remove(void **list, void *item)
+{
+ int i, last;
+
+ if ((list == NULL) || (*list == NULL) || (item == NULL))
+ return;
+
+ for (last = 0; list[last] != NULL; last++)
+ ;
+ --last;
+
+ /*
+ * This doesn't preserve order, and doesn't shrink the allocation if we
+ * go below % __list_increment == 0. <shrug>
+ */
+ for (i = 0; list[i] != NULL; i++) {
+ if (list[i] == item) {
+ list[i] = list[last];
+ list[last] = NULL;
+ break;
+ }
+ }
+}
diff --git a/usr/src/lib/print/libpapi-common/common/mapfile b/usr/src/lib/print/libpapi-common/common/mapfile
new file mode 100644
index 0000000000..81f8f0308f
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/mapfile
@@ -0,0 +1,151 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# Common interfaces that are most likely to be shared amongst the various
+# PAPI implementations.
+#
+
+SUNW_1.0 {
+ global:
+ # PAPI Attribute Calls
+ papiAttributeListAddValue;
+ papiAttributeListAddBoolean;
+ papiAttributeListAddCollection;
+ papiAttributeListAddDatetime;
+ papiAttributeListAddInteger;
+ papiAttributeListAddMetadata;
+ papiAttributeListAddRange;
+ papiAttributeListAddResolution;
+ papiAttributeListAddString;
+ papiAttributeListDelete;
+ papiAttributeListGetValue;
+ papiAttributeListGetNext;
+ papiAttributeListFind;
+ papiAttributeListGetBoolean;
+ papiAttributeListGetCollection;
+ papiAttributeListGetDatetime;
+ papiAttributeListGetInteger;
+ papiAttributeListGetMetadata;
+ papiAttributeListGetRange;
+ papiAttributeListGetResolution;
+ papiAttributeListGetString;
+ papiAttributeListFromString;
+ papiAttributeListToString;
+ papiAttributeListFree;
+
+ # PAPI Service Calls
+ papiServiceCreate;
+ papiServiceDestroy;
+ papiServiceSetUserName;
+ papiServiceSetPassword;
+ papiServiceSetEncryption;
+ papiServiceSetAuthCB;
+ papiServiceSetAppData;
+ papiServiceGetUserName;
+ papiServiceGetPassword;
+ papiServiceGetEncryption;
+ papiServiceGetAppData;
+ papiServiceGetServiceName;
+ papiServiceGetAttributeList;
+ papiServiceGetStatusMessage;
+
+ # PAPI Printer Calls
+ papiPrintersList;
+ papiPrinterQuery;
+ papiPrinterAdd;
+ papiPrinterModify;
+ papiPrinterRemove;
+ papiPrinterDisable;
+ papiPrinterEnable;
+ papiPrinterPause;
+ papiPrinterResume;
+ papiPrinterPurgeJobs;
+ papiPrinterListJobs;
+ papiPrinterGetAttributeList;
+ papiPrinterFree;
+ papiPrinterListFree;
+
+ # PAPI Job Calls
+ papiJobSubmit;
+ papiJobSubmitByReference;
+ papiJobValidate;
+ papiJobStreamOpen;
+ papiJobStreamWrite;
+ papiJobStreamClose;
+ papiJobQuery;
+ papiJobModify;
+ papiJobMove;
+ papiJobCancel;
+ papiJobHold;
+ papiJobRelease;
+ papiJobRestart;
+ papiJobPromote;
+ papiJobGetAttributeList;
+ papiJobGetPrinterName;
+ papiJobGetId;
+ papiJobGetJobTicket;
+ papiJobFree;
+ papiJobListFree;
+
+ # Misc. PAPI Calls
+ papiStatusString;
+ papiLibrarySupportedCall;
+ papiLibrarySupportedCalls;
+};
+
+SUNWprivate_1.0 { # Misc. semi-private supporting calls
+ global:
+ papiServiceSetPeer;
+ papiJobCreate;
+ papiJobStreamAdd;
+ papiJobCommit;
+
+ # URI
+ uri_from_string;
+ uri_to_string;
+ uri_free;
+ # list
+ list_remove;
+ list_append;
+ list_concatenate;
+
+ # extra Attribute Calls
+ copy_attributes;
+ split_and_copy_attributes;
+ papiAttributeListPrint;
+
+ local:
+ *;
+};
+
+FSG_1.0 {} SUNW_1.0;
diff --git a/usr/src/lib/print/libpapi-common/common/misc.c b/usr/src/lib/print/libpapi-common/common/misc.c
new file mode 100644
index 0000000000..646a26e18a
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/misc.c
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: misc.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <string.h>
+#include <papi.h>
+
+#include <config-site.h>
+
+/*
+ * The implementations of strlcpy() and strlcat() have been taken directly
+ * from OpenSolaris. The contents of this file originated from
+ * usr/src/lib/libc/port/gen/strlcpy.c
+ * usr/src/lib/libc/port/gen/strcat.c
+ */
+
+#ifndef HAVE_STRLCPY
+size_t
+strlcpy(char *dst, const char *src, size_t len)
+{
+ size_t slen = strlen(src);
+ size_t copied;
+
+ if (len == 0)
+ return (slen);
+
+ if (slen >= len)
+ copied = len - 1;
+ else
+ copied = slen;
+ (void) memcpy(dst, src, copied);
+ dst[copied] = '\0';
+ return (slen);
+}
+#endif
+
+#ifndef HAVE_STRLCAT
+size_t
+strlcat(char *dst, const char *src, size_t dstsize)
+{
+ char *df = dst;
+ size_t left = dstsize;
+ size_t l1;
+ size_t l2 = strlen(src);
+ size_t copied;
+
+ while (left-- != 0 && *df != '\0')
+ df++;
+ l1 = df - dst;
+ if (dstsize == l1)
+ return (l1 + l2);
+
+ copied = l1 + l2 >= dstsize ? dstsize - l1 - 1 : l2;
+ (void) memcpy(dst + l1, src, copied);
+ dst[l1+copied] = '\0';
+ return (l1 + l2);
+}
+#endif
diff --git a/usr/src/lib/print/libpapi-common/common/papi.h b/usr/src/lib/print/libpapi-common/common/papi.h
new file mode 100644
index 0000000000..7c1d891eb2
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/papi.h
@@ -0,0 +1,448 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#ifndef _PAPI_H
+#define _PAPI_H
+
+/* $Id: papi.h 161 2006-05-03 04:32:59Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <time.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Types
+ */
+
+/* service related types */
+typedef void *papi_service_t;
+typedef void *papi_printer_t;
+typedef void *papi_job_t;
+typedef void *papi_stream_t;
+
+typedef enum {
+ PAPI_ENCRYPT_IF_REQUESTED, /* Encrypt if requested (TLS upgrade) */
+ PAPI_ENCRYPT_NEVER, /* Never encrypt */
+ PAPI_ENCRYPT_REQUIRED, /* Encryption required (TLS upgrade) */
+ PAPI_ENCRYPT_ALWAYS /* Always encrypt (SSL) */
+} papi_encryption_t;
+
+/* attribute related types */
+typedef enum {
+ PAPI_STRING,
+ PAPI_INTEGER,
+ PAPI_BOOLEAN,
+ PAPI_RANGE,
+ PAPI_RESOLUTION,
+ PAPI_DATETIME,
+ PAPI_COLLECTION,
+ PAPI_METADATA
+} papi_attribute_value_type_t;
+
+typedef enum {
+ PAPI_RES_PER_INCH = 3,
+ PAPI_RES_PER_CM
+} papi_resolution_unit_t;
+
+enum { /* for boolean values */
+ PAPI_FALSE = 0,
+ PAPI_TRUE = 1
+};
+
+typedef enum {
+ PAPI_UNSUPPORTED = 0x10,
+ PAPI_DEFAULT = 0x11,
+ PAPI_UNKNOWN,
+ PAPI_NO_VALUE,
+ PAPI_NOT_SETTABLE = 0x15,
+ PAPI_DELETE = 0x16
+} papi_metadata_t;
+
+#define PAPI_LIST_JOBS_OTHERS 0x0001
+#define PAPI_LIST_JOBS_COMPLETED 0x0002
+#define PAPI_LIST_JOBS_NOT_COMPLETED 0x0004
+#define PAPI_LIST_JOBS_ALL 0xFFFF
+
+typedef struct papi_attribute_s papi_attribute_t;
+
+typedef union {
+ char *string; /* PAPI_STRING value */
+ int integer; /* PAPI_INTEGER value */
+ char boolean; /* PAPI_BOOLEAN value */
+ struct { /* PAPI_RANGE value */
+ int lower;
+ int upper;
+ } range;
+ struct { /* PAPI_RESOLUTION value */
+ int xres;
+ int yres;
+ papi_resolution_unit_t units;
+ } resolution;
+ time_t datetime; /* PAPI_DATETIME value */
+ papi_attribute_t **collection; /* PAPI_COLLECTION value */
+ papi_metadata_t metadata; /* PAPI_METADATA value */
+} papi_attribute_value_t;
+
+struct papi_attribute_s {
+ char *name; /* attribute name */
+ papi_attribute_value_type_t type; /* type of values */
+ papi_attribute_value_t **values; /* list of values */
+};
+
+#define PAPI_ATTR_APPEND 0x0001 /* Add values to attr */
+#define PAPI_ATTR_REPLACE 0x0002 /* Delete existing values, then add */
+#define PAPI_ATTR_EXCL 0x0004 /* Fail if attr exists */
+
+/* job related types */
+typedef enum {
+ PAPI_JT_FORMAT_JDF = 0,
+ PAPI_JT_FORMAT_PWG = 1
+} papi_jt_format_t;
+
+typedef struct {
+ papi_jt_format_t format;
+ char *ticket_data;
+ char *file_name;
+} papi_job_ticket_t;
+
+/* status related types */
+typedef enum {
+ PAPI_OK = 0x0000,
+ PAPI_OK_SUBST,
+ PAPI_OK_CONFLICT,
+ PAPI_OK_IGNORED_SUBSCRIPTIONS,
+ PAPI_OK_IGNORED_NOTIFICATIONS,
+ PAPI_OK_TOO_MANY_EVENTS,
+ PAPI_OK_BUT_CANCEL_SUBSCRIPTION,
+ PAPI_REDIRECTION_OTHER_SITE = 0x0300,
+ PAPI_BAD_REQUEST = 0x0400,
+ PAPI_FORBIDDEN,
+ PAPI_NOT_AUTHENTICATED,
+ PAPI_NOT_AUTHORIZED,
+ PAPI_NOT_POSSIBLE,
+ PAPI_TIMEOUT,
+ PAPI_NOT_FOUND,
+ PAPI_GONE,
+ PAPI_REQUEST_ENTITY,
+ PAPI_REQUEST_VALUE,
+ PAPI_DOCUMENT_FORMAT,
+ PAPI_ATTRIBUTES,
+ PAPI_URI_SCHEME,
+ PAPI_CHARSET,
+ PAPI_CONFLICT,
+ PAPI_COMPRESSION_NOT_SUPPORTED,
+ PAPI_COMPRESSION_ERROR,
+ PAPI_DOCUMENT_FORMAT_ERROR,
+ PAPI_DOCUMENT_ACCESS_ERROR,
+ PAPI_ATTRIBUTES_NOT_SETTABLE,
+ PAPI_IGNORED_ALL_SUBSCRIPTIONS,
+ PAPI_TOO_MANY_SUBSCRIPTIONS,
+ PAPI_IGNORED_ALL_NOTIFICATIONS,
+ PAPI_PRINT_SUPPORT_FILE_NOT_FOUND,
+ PAPI_INTERNAL_ERROR = 0x0500,
+ PAPI_OPERATION_NOT_SUPPORTED,
+ PAPI_SERVICE_UNAVAILABLE,
+ PAPI_VERSION_NOT_SUPPORTED,
+ PAPI_DEVICE_ERROR,
+ PAPI_TEMPORARY_ERROR,
+ PAPI_NOT_ACCEPTING,
+ PAPI_PRINTER_BUSY,
+ PAPI_ERROR_JOB_CANCELLED,
+ PAPI_MULTIPLE_JOBS_NOT_SUPPORTED,
+ PAPI_PRINTER_IS_DEACTIVATED,
+ PAPI_BAD_ARGUMENT,
+ PAPI_JOB_TICKET_NOT_SUPPORTED
+} papi_status_t;
+
+/* list filter related */
+typedef enum {
+ PAPI_FILTER_BITMASK = 0
+} papi_filter_type_t;
+
+typedef struct {
+ papi_filter_type_t type;
+ union {
+ struct { /* PAPI_FILTER_BITMASK */
+ unsigned int mask;
+ unsigned int value;
+ } bitmask;
+ } filter;
+} papi_filter_t;
+
+enum {
+ PAPI_PRINTER_LOCAL = 0x0000, /* Local destination */
+ PAPI_PRINTER_CLASS = 0x0001, /* Printer class */
+ PAPI_PRINTER_REMOTE = 0x0002, /* Remote destination */
+ PAPI_PRINTER_BW = 0x0004, /* Can do B&W printing */
+ PAPI_PRINTER_COLOR = 0x0008, /* Can do color printing */
+ PAPI_PRINTER_DUPLEX = 0x0010, /* Can do duplex printing */
+ PAPI_PRINTER_STAPLE = 0x0020, /* Can do stapling */
+ PAPI_PRINTER_COPIES = 0x0040, /* Can do copies */
+ PAPI_PRINTER_COLLATE = 0x0080, /* Can collate copies */
+ PAPI_PRINTER_PUNCH = 0x0100, /* Can punch output */
+ PAPI_PRINTER_COVER = 0x0200, /* Can cover output */
+ PAPI_PRINTER_BIND = 0x0400, /* Can bind output */
+ PAPI_PRINTER_SORT = 0x0800, /* Can sort output */
+ PAPI_PRINTER_SMALL = 0x1000, /* Can do letter/legal/a4 */
+ PAPI_PRINTER_MEDIUM = 0x2000, /* Can do tabloid/B/C/A3/A2 */
+ PAPI_PRINTER_LARGE = 0x4000, /* Can do D/E/A1/A0 */
+ PAPI_PRINTER_VARIABLE = 0x8000, /* Can do variable sizes */
+ PAPI_PRINTER_IMPLICIT = 0x10000, /* implicit class */
+ PAPI_PRINTER_DEFAULT = 0x20000, /* Default printer on network */
+ PAPI_PRINTER_OPTIONS = 0xfffc /* ~ (CLASS | REMOTE | IMPLICIT) */
+};
+
+/*
+ * Functions
+ */
+
+/* Service related */
+extern papi_status_t papiServiceCreate(papi_service_t *handle,
+ char *service_name, char *user_name,
+ char *password,
+ int (*authCB)(papi_service_t svc,
+ void *app_data),
+ papi_encryption_t encryption,
+ void *app_data);
+extern void papiServiceDestroy(papi_service_t handle);
+extern papi_status_t papiServiceSetUserName(papi_service_t handle,
+ char *user_name);
+extern papi_status_t papiServiceSetPassword(papi_service_t handle,
+ char *password);
+extern papi_status_t papiServiceSetEncryption(papi_service_t handle,
+ papi_encryption_t encryption);
+extern papi_status_t papiServiceSetAuthCB(papi_service_t handle,
+ int (*authCB)(papi_service_t s,
+ void *app_data));
+extern papi_status_t papiServiceSetAppData(papi_service_t handle,
+ void *app_data);
+extern char *papiServiceGetServiceName(papi_service_t handle);
+extern char *papiServiceGetUserName(papi_service_t handle);
+extern char *papiServiceGetPassword(papi_service_t handle);
+extern papi_encryption_t papiServiceGetEncryption(papi_service_t handle);
+extern void *papiServiceGetAppData(papi_service_t handle);
+extern papi_attribute_t **papiServiceGetAttributeList(papi_service_t handle);
+extern char *papiServiceGetStatusMessage(papi_service_t handle);
+
+/* Attribute related */
+extern papi_status_t papiAttributeListAddValue(papi_attribute_t ***attrs,
+ int flags, char *name,
+ papi_attribute_value_type_t type,
+ papi_attribute_value_t *value);
+extern papi_status_t papiAttributeListAddString(papi_attribute_t ***attrs,
+ int flags, char *name, char *string);
+extern papi_status_t papiAttributeListAddInteger(papi_attribute_t ***attrs,
+ int flags, char *name, int integer);
+extern papi_status_t papiAttributeListAddBoolean(papi_attribute_t ***attrs,
+ int flags, char *name, char boolean);
+extern papi_status_t papiAttributeListAddRange(papi_attribute_t ***attrs,
+ int flags, char *name,
+ int lower, int upper);
+extern papi_status_t papiAttributeListAddResolution(papi_attribute_t ***attrs,
+ int flags, char *name,
+ int xres, int yres,
+ papi_resolution_unit_t units);
+extern papi_status_t papiAttributeListAddDatetime(papi_attribute_t ***attrs,
+ int flags, char *name, time_t datetime);
+extern papi_status_t papiAttributeListAddCollection(papi_attribute_t ***attrs,
+ int flags, char *name,
+ papi_attribute_t **collection);
+extern papi_status_t papiAttributeListAddMetadata(papi_attribute_t ***attrs,
+ int flags, char *name,
+ papi_metadata_t metadata);
+extern papi_status_t papiAttributeListDelete(papi_attribute_t ***attributes,
+ char *name);
+extern papi_status_t papiAttributeListGetValue(papi_attribute_t **list,
+ void **iterator, char *name,
+ papi_attribute_value_type_t type,
+ papi_attribute_value_t **value);
+extern papi_status_t papiAttributeListGetString(papi_attribute_t **list,
+ void **iterator, char *name,
+ char **vptr);
+extern papi_status_t papiAttributeListGetInteger(papi_attribute_t **list,
+ void **iterator, char *name, int *vptr);
+extern papi_status_t papiAttributeListGetBoolean(papi_attribute_t **list,
+ void **iterator, char *name,
+ char *vptr);
+extern papi_status_t papiAttributeListGetRange(papi_attribute_t **list,
+ void **iterator, char *name,
+ int *min, int *max);
+extern papi_status_t papiAttributeListGetResolution(papi_attribute_t **list,
+ void **iterator, char *name,
+ int *x, int *y,
+ papi_resolution_unit_t *units);
+extern papi_status_t papiAttributeListGetDatetime(papi_attribute_t **list,
+ void **iterator, char *name,
+ time_t *dt);
+extern papi_status_t papiAttributeListGetCollection(papi_attribute_t **list,
+ void **iterator, char *name,
+ papi_attribute_t ***collection);
+extern papi_status_t papiAttributeListGetMetadata(papi_attribute_t **list,
+ void **iterator, char *name,
+ papi_metadata_t *vptr);
+extern papi_attribute_t *papiAttributeListFind(papi_attribute_t **list,
+ char *name);
+extern papi_attribute_t *papiAttributeListGetNext(papi_attribute_t **list,
+ void **iterator);
+extern void papiAttributeListFree(papi_attribute_t **attributes);
+
+extern papi_status_t papiAttributeListFromString(papi_attribute_t ***attrs,
+ int flags, char *string);
+extern papi_status_t papiAttributeListToString(papi_attribute_t **attrs,
+ char *delim,
+ char *buffer, size_t buflen);
+extern void papiAttributeListPrint(FILE *fp, papi_attribute_t **list,
+ char *prefix_fmt, ...);
+
+/* Printer related */
+extern papi_status_t papiPrintersList(papi_service_t handle,
+ char **requested_attrs,
+ papi_filter_t *filter,
+ papi_printer_t **printers);
+extern papi_status_t papiPrinterQuery(papi_service_t handle, char *name,
+ char **requested_attrs,
+ papi_attribute_t **job_attributes,
+ papi_printer_t *printer);
+extern papi_status_t papiPrinterAdd(papi_service_t handle, char *name,
+ papi_attribute_t **attributes,
+ papi_printer_t *printer);
+extern papi_status_t papiPrinterModify(papi_service_t handle, char *name,
+ papi_attribute_t **attributes,
+ papi_printer_t *printer);
+extern papi_status_t papiPrinterRemove(papi_service_t handle, char *name);
+extern papi_status_t papiPrinterDisable(papi_service_t handle, char *name,
+ char *message);
+extern papi_status_t papiPrinterEnable(papi_service_t handle, char *name);
+extern papi_status_t papiPrinterPause(papi_service_t handle, char *name,
+ char *message);
+extern papi_status_t papiPrinterResume(papi_service_t handle, char *name);
+extern papi_status_t papiPrinterPurgeJobs(papi_service_t handle,
+ char *name, papi_job_t **jobs);
+extern papi_status_t papiPrinterListJobs(papi_service_t handle,
+ char *name, char **requested_attrs,
+ int type_mask, int max_num_jobs,
+ papi_job_t **jobs);
+extern papi_attribute_t **papiPrinterGetAttributeList(papi_printer_t printer);
+extern void papiPrinterFree(papi_printer_t printer);
+extern void papiPrinterListFree(papi_printer_t *printers);
+
+/* Job related */
+extern papi_status_t papiJobSubmit(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket,
+ char **files, papi_job_t *job);
+extern papi_status_t papiJobSubmitByReference(papi_service_t handle,
+ char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket,
+ char **files, papi_job_t *job);
+extern papi_status_t papiJobValidate(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket,
+ char **files, papi_job_t *job);
+extern papi_status_t papiJobStreamOpen(papi_service_t handle,
+ char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket,
+ papi_stream_t *stream);
+extern papi_status_t papiJobStreamWrite(papi_service_t handle,
+ papi_stream_t stream,
+ void *buffer, size_t buflen);
+extern papi_status_t papiJobStreamClose(papi_service_t handle,
+ papi_stream_t stream,
+ papi_job_t *job);
+extern papi_status_t papiJobQuery(papi_service_t handle, char *printer,
+ int32_t job_id, char **requested_attrs,
+ papi_job_t *job);
+extern papi_status_t papiJobModify(papi_service_t handle, char *printer,
+ int32_t job_id,
+ papi_attribute_t **attributes,
+ papi_job_t *job);
+extern papi_status_t papiJobMove(papi_service_t handle, char *printer,
+ int32_t job_id, char *destination);
+extern papi_status_t papiJobCancel(papi_service_t handle, char *printer,
+ int32_t job_id);
+extern papi_status_t papiJobHold(papi_service_t handle, char *printer,
+ int32_t job_id);
+extern papi_status_t papiJobRelease(papi_service_t handle, char *printer,
+ int32_t job_id);
+extern papi_status_t papiJobRestart(papi_service_t handle, char *printer,
+ int32_t job_id);
+extern papi_status_t papiJobPromote(papi_service_t handle, char *printer,
+ int32_t job_id);
+extern papi_attribute_t **papiJobGetAttributeList(papi_job_t printer);
+extern char *papiJobGetPrinterName(papi_job_t printer);
+extern int32_t papiJobGetId(papi_job_t printer);
+extern papi_job_ticket_t *papiJobGetJobTicket(papi_job_t printer);
+extern void papiJobFree(papi_job_t job);
+extern void papiJobListFree(papi_job_t *jobs);
+
+#ifdef SOLARIS_PRIVATE_POST_0_9
+/*
+ * These have been added to support IPP create-job/send-document with PAPI v0.9
+ * in an IPP listener using PAPI as it's spooler interface. A future version
+ * of the API is expected to support this type of functionality
+ */
+extern papi_status_t papiJobCreate(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket,
+ papi_job_t *job);
+extern papi_status_t papiJobStreamAdd(papi_service_t handle, char *printer,
+ int32_t id, papi_stream_t *stream);
+extern papi_status_t papiJobCommit(papi_service_t handle, char *printer,
+ int32_t id);
+extern papi_status_t papiServiceSetPeer(papi_service_t handle, int peerfd);
+#endif /* SOLARIS_PRIVATE_POST_0_9 */
+
+extern char *papiStatusString(papi_status_t status);
+
+/*
+ * Internal functions that aren't in the API, but are shared across
+ * protocol support implementations(psms) and the tightly bound
+ * listener library. Do not use these in your applications.
+ */
+extern void list_append();
+extern void list_concatenate();
+extern void list_remove();
+extern void copy_attributes(papi_attribute_t ***result,
+ papi_attribute_t **list);
+extern void split_and_copy_attributes(char **list,
+ papi_attribute_t **attributes,
+ papi_attribute_t ***in,
+ papi_attribute_t ***out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAPI_H */
diff --git a/usr/src/lib/print/libpapi-common/common/status.c b/usr/src/lib/print/libpapi-common/common/status.c
new file mode 100644
index 0000000000..897aa1322d
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/status.c
@@ -0,0 +1,133 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: status.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <papi.h>
+#include <libintl.h>
+
+char *
+papiStatusString(const papi_status_t status)
+{
+ switch (status) {
+ case PAPI_OK:
+ return (gettext("ok"));
+ case PAPI_OK_SUBST:
+ return (gettext("ok-substitution"));
+ case PAPI_OK_CONFLICT:
+ return (gettext("ok-conflict"));
+ case PAPI_OK_IGNORED_SUBSCRIPTIONS:
+ return (gettext("ok-ignored-subscriptions"));
+ case PAPI_OK_IGNORED_NOTIFICATIONS:
+ return (gettext("ok-ignored-notifications"));
+ case PAPI_OK_TOO_MANY_EVENTS:
+ return (gettext("ok-too-many-events"));
+ case PAPI_OK_BUT_CANCEL_SUBSCRIPTION:
+ return (gettext("ok-but-cancel-subscription"));
+ case PAPI_REDIRECTION_OTHER_SITE:
+ return (gettext("redirection-to-other-site"));
+ case PAPI_BAD_REQUEST:
+ return (gettext("bad-request"));
+ case PAPI_FORBIDDEN:
+ return (gettext("forbidden"));
+ case PAPI_NOT_AUTHENTICATED:
+ return (gettext("not-authenticated"));
+ case PAPI_NOT_AUTHORIZED:
+ return (gettext("not-authorized"));
+ case PAPI_NOT_POSSIBLE:
+ return (gettext("not-possible"));
+ case PAPI_TIMEOUT:
+ return (gettext("timeout"));
+ case PAPI_NOT_FOUND:
+ return (gettext("not-found"));
+ case PAPI_GONE:
+ return (gettext("gone"));
+ case PAPI_REQUEST_ENTITY:
+ return (gettext("request-entity"));
+ case PAPI_REQUEST_VALUE:
+ return (gettext("request-value"));
+ case PAPI_DOCUMENT_FORMAT:
+ return (gettext("document-format"));
+ case PAPI_ATTRIBUTES:
+ return (gettext("attributes"));
+ case PAPI_URI_SCHEME:
+ return (gettext("uri-scheme"));
+ case PAPI_CHARSET:
+ return (gettext("charset"));
+ case PAPI_CONFLICT:
+ return (gettext("conflict"));
+ case PAPI_COMPRESSION_NOT_SUPPORTED:
+ return (gettext("compression-not-supported"));
+ case PAPI_COMPRESSION_ERROR:
+ return (gettext("compression-error"));
+ case PAPI_DOCUMENT_FORMAT_ERROR:
+ return (gettext("document-format-error"));
+ case PAPI_DOCUMENT_ACCESS_ERROR:
+ return (gettext("document-access-error"));
+ case PAPI_ATTRIBUTES_NOT_SETTABLE:
+ return (gettext("attributes-not-settable"));
+ case PAPI_IGNORED_ALL_SUBSCRIPTIONS:
+ return (gettext("ignored-all-subscriptions"));
+ case PAPI_TOO_MANY_SUBSCRIPTIONS:
+ return (gettext("too-many-subscriptions"));
+ case PAPI_IGNORED_ALL_NOTIFICATIONS:
+ return (gettext("ignored-all-notifications"));
+ case PAPI_PRINT_SUPPORT_FILE_NOT_FOUND:
+ return (gettext("print-support-file-not-found"));
+ case PAPI_INTERNAL_ERROR:
+ return (gettext("internal-error"));
+ case PAPI_OPERATION_NOT_SUPPORTED:
+ return (gettext("operation-not-supported"));
+ case PAPI_SERVICE_UNAVAILABLE:
+ return (gettext("service-unavailable"));
+ case PAPI_VERSION_NOT_SUPPORTED:
+ return (gettext("version-not-supported"));
+ case PAPI_DEVICE_ERROR:
+ return (gettext("device-error"));
+ case PAPI_TEMPORARY_ERROR:
+ return (gettext("temporary-error"));
+ case PAPI_NOT_ACCEPTING:
+ return (gettext("not-accepting"));
+ case PAPI_PRINTER_BUSY:
+ return (gettext("printer-busy"));
+ case PAPI_ERROR_JOB_CANCELLED:
+ return (gettext("error-job-cancelled"));
+ case PAPI_MULTIPLE_JOBS_NOT_SUPPORTED:
+ return (gettext("multiple-jobs-not-supported"));
+ case PAPI_PRINTER_IS_DEACTIVATED:
+ return (gettext("printer-is-deactivated"));
+ case PAPI_BAD_ARGUMENT:
+ return (gettext("bad-argument"));
+ case PAPI_JOB_TICKET_NOT_SUPPORTED:
+ return (gettext("job-ticket-not-supported"));
+ default:
+ return (gettext("unknown-error"));
+ }
+}
diff --git a/usr/src/lib/print/libpapi-common/common/uri.c b/usr/src/lib/print/libpapi-common/common/uri.c
new file mode 100644
index 0000000000..9cc6f59006
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/uri.c
@@ -0,0 +1,303 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: uri.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <errno.h>
+#include "uri.h"
+
+static char *
+strndup(char *string, size_t length)
+{
+ char *result = NULL;
+
+ if (length > 0) {
+ length++;
+
+
+ if ((result = calloc(1, length)) != NULL)
+ (void) strlcat(result, string, length);
+ }
+
+ return (result);
+}
+
+
+/*
+ * This will handle the following forms:
+ * scheme:scheme_data
+ * scheme://[[user[:password]@]host[:port]]/path[[#fragment]|[?query]]
+ */
+int
+uri_from_string(char *string, uri_t **uri)
+{
+ char *ptr;
+ uri_t *u;
+
+ if ((string == NULL) || (uri == NULL)) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /* find the scheme:scheme_part split */
+ if ((ptr = strchr(string, ':')) == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if ((*uri = u = calloc(1, sizeof (*u))) == NULL)
+ return (-1);
+
+ u->scheme = strndup(string, ptr - string);
+
+ if ((ptr[1] == '/') && (ptr[2] == '/')) {
+ /*
+ * CSTYLED
+ * scheme://[host_part]/[path_part]
+ */
+ char *end = NULL, *user = NULL, *host = NULL, *path = NULL;
+
+ string = ptr + 3; /* skip the :// */
+
+ if ((path = end = strchr(string, '/')) == NULL)
+ for (end = string; *end != '\0'; end++);
+
+ u->host_part = strndup(string, end - string);
+
+ for (host = string; host < end; host ++)
+ if (*host == '@') {
+ /* string to host is the user part */
+ u->user_part = strndup(string, host-string);
+ /* host+1 to end is the host part */
+ u->host_part = strndup(host + 1,
+ end - (host+1));
+ user = string;
+ host++;
+ break;
+ }
+
+ if (user != NULL) {
+ char *password = NULL;
+
+ for (password = user; (password < host - 1); password++)
+ if (*password == ':') {
+ u->password = strndup(password + 1,
+ host - password - 2);
+ break;
+ }
+ u->user = strndup(user, password - user);
+ } else
+ host = string;
+
+ if (host != NULL) {
+ char *port = NULL;
+
+ for (port = host; (port < path); port++)
+ if ((*port == ':') || (*port == '/'))
+ break;
+
+ if (port < path) {
+ u->port = strndup(port + 1, path - port - 1);
+ }
+
+ u->host = strndup(host, port - host);
+ }
+
+ if (path != NULL) {
+ char *name = strrchr(path, '/');
+
+ u->path_part = strdup(path);
+
+ if (name != NULL) {
+ char *query, *fragment;
+
+ query = strrchr(name, '?');
+ if ((query != NULL) && (*query != '\0')) {
+ u->query = strdup(query + 1);
+ end = query;
+ } else
+ for (end = path; *end != '\0'; end++);
+
+ fragment = strrchr(name, '#');
+ if ((fragment != NULL) && (*fragment != '\0')) {
+ u->fragment = strndup(fragment + 1,
+ end - fragment - 1);
+ end = fragment;
+ }
+
+ u->path = strndup(path, end - path);
+ }
+ }
+ } else { /* scheme:scheme_part */
+ u->scheme_part = strdup(&ptr[1]);
+ }
+
+ return (0);
+}
+
+int
+uri_to_string(uri_t *uri, char *buffer, size_t buflen)
+{
+ if ((uri == NULL) || (buffer == NULL) || (buflen == 0) ||
+ (uri->scheme == NULL) ||
+ ((uri->password != NULL) && (uri->user == NULL)) ||
+ ((uri->user != NULL) && (uri->host == NULL)) ||
+ ((uri->port != NULL) && (uri->host == NULL)) ||
+ ((uri->fragment != NULL) && (uri->path == NULL)) ||
+ ((uri->query != NULL) && (uri->path == NULL))) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ (void) memset(buffer, 0, buflen);
+
+ if (uri->scheme_part == NULL) {
+ (void) snprintf(buffer, buflen,
+ "%s://%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ uri->scheme,
+ (uri->user ? uri->user : ""),
+ (uri->password ? ":" : ""),
+ (uri->password ? uri->password : ""),
+ (uri->user ? "@": ""),
+ (uri->host ? uri->host : ""),
+ (uri->port ? ":" : ""),
+ (uri->port ? uri->port : ""),
+ (uri->path[0] != '/' ? "/" : ""), uri->path,
+ (uri->fragment ? "#" : ""),
+ (uri->fragment ? uri->fragment : ""),
+ (uri->query ? "?" : ""),
+ (uri->query ? uri->query : ""));
+ } else {
+ (void) snprintf(buffer, buflen, "%s:%s", uri->scheme,
+ uri->scheme_part);
+ }
+
+ return (0);
+}
+
+void
+uri_free(uri_t *uri)
+{
+ if (uri != NULL) {
+ if (uri->scheme != NULL)
+ free(uri->scheme);
+ if (uri->scheme_part != NULL)
+ free(uri->scheme_part);
+ if (uri->user != NULL)
+ free(uri->user);
+ if (uri->password != NULL)
+ free(uri->password);
+ if (uri->host != NULL)
+ free(uri->host);
+ if (uri->port != NULL)
+ free(uri->port);
+ if (uri->path != NULL)
+ free(uri->path);
+ if (uri->fragment != NULL)
+ free(uri->fragment);
+ if (uri->query != NULL)
+ free(uri->query);
+ /* help me debug */
+ if (uri->user_part != NULL)
+ free(uri->user_part);
+ if (uri->host_part != NULL)
+ free(uri->host_part);
+ if (uri->path_part != NULL)
+ free(uri->path_part);
+ free(uri);
+ }
+}
+
+#ifdef DEADBEEF
+static void
+uri_dump(FILE *fp, uri_t *uri)
+{
+ if (uri != NULL) {
+ fprintf(fp, "URI:\n");
+ if (uri->scheme != NULL)
+ fprintf(fp, "scheme: %s\n", uri->scheme);
+ if (uri->scheme_part != NULL)
+ fprintf(fp, "scheme_part: %s\n", uri->scheme_part);
+ if (uri->user != NULL)
+ fprintf(fp, "user: %s\n", uri->user);
+ if (uri->password != NULL)
+ fprintf(fp, "password: %s\n", uri->password);
+ if (uri->host != NULL)
+ fprintf(fp, "host: %s\n", uri->host);
+ if (uri->port != NULL)
+ fprintf(fp, "port: %s\n", uri->port);
+ if (uri->path != NULL)
+ fprintf(fp, "path: %s\n", uri->path);
+ if (uri->fragment != NULL)
+ fprintf(fp, "fragment: %s\n", uri->fragment);
+ if (uri->query != NULL)
+ fprintf(fp, "query: %s\n", uri->query);
+ /* help me debug */
+ if (uri->user_part != NULL)
+ fprintf(fp, "user_part: %s\n", uri->user_part);
+ if (uri->host_part != NULL)
+ fprintf(fp, "host_part: %s\n", uri->host_part);
+ if (uri->path_part != NULL)
+ fprintf(fp, "path_part: %s\n", uri->path_part);
+ fflush(fp);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ uri_t *u = NULL;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s uri\n", argv[0]);
+ exit(1);
+ }
+
+ if (uri_from_string(argv[1], &u) == 0) {
+ char buf[BUFSIZ];
+
+ uri_dump(stdout, u);
+ uri_to_string(u, buf, sizeof (buf));
+ fprintf(stdout, "reconstituted: %s\n", buf);
+
+ uri_to_string(u, buf, 12);
+ fprintf(stdout, "reconstituted(12): %s\n", buf);
+ } else
+ printf(" failed for %s (%s)\n", argv[1], strerror(errno));
+
+ exit(0);
+}
+#endif /* DEADBEEF */
diff --git a/usr/src/lib/print/libpapi-common/common/uri.h b/usr/src/lib/print/libpapi-common/common/uri.h
new file mode 100644
index 0000000000..5dd714a199
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/common/uri.h
@@ -0,0 +1,66 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#ifndef _URI_H
+#define _URI_H
+
+/* $Id: uri.h 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * scheme://[[user[:password]@]host[:port]]/path[[#fragment]|[?query]]
+ */
+typedef struct {
+ char *scheme;
+ char *scheme_part;
+ char *user;
+ char *password;
+ char *host;
+ char *port;
+ char *path;
+ char *fragment;
+ char *query;
+ /* really for testing, but left in */
+ char *user_part;
+ char *host_part;
+ char *path_part;
+} uri_t;
+
+extern int uri_from_string(char *string, uri_t **uri);
+extern int uri_to_string(uri_t *uri, char *buffer, size_t buflen);
+extern void uri_free(uri_t *uri);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _URI_H */
diff --git a/usr/src/lib/print/libpapi-common/i386/Makefile b/usr/src/lib/print/libpapi-common/i386/Makefile
new file mode 100644
index 0000000000..3b985583a4
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT)
diff --git a/usr/src/lib/print/libpapi-common/sparc/Makefile b/usr/src/lib/print/libpapi-common/sparc/Makefile
new file mode 100644
index 0000000000..3b985583a4
--- /dev/null
+++ b/usr/src/lib/print/libpapi-common/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT)
diff --git a/usr/src/lib/print/libpapi-dynamic/Makefile b/usr/src/lib/print/libpapi-dynamic/Makefile
new file mode 100644
index 0000000000..b92d620b10
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../../Makefile.lib
+
+#HDRS = papi.h
+#HDRDIR = common
+SUBDIRS = $(MACH)
+#$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all clean clobber install: .WAIT $(SUBDIRS)
+
+lint: # $(SUBDIRS)
+
+install_h: # $(ROOTHDRS)
+
+check: # $(CHECKHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/print/libpapi-dynamic/Makefile.com b/usr/src/lib/print/libpapi-dynamic/Makefile.com
new file mode 100644
index 0000000000..ecd8cba003
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/Makefile.com
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = libpapi.a
+VERS = .0
+OBJECTS = job.o nss.o printer.o psm.o service.o
+
+include ../../../Makefile.lib
+include ../../../Makefile.rootfs
+
+ROOTLIBDIR= $(ROOT)/usr/lib
+
+LIBS = $(DYNLIB)
+
+SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c)
+
+$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+MAPFILE = $(SRCDIR)/mapfile
+DYNFLAGS += -M $(MAPFILE)
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -I$(SRCDIR)
+CPPFLAGS += -I../../libpapi-common/common
+CPPFLAGS += -DNSS_SOLARIS
+LDLIBS += -lc
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include ../../../Makefile.targ
diff --git a/usr/src/lib/print/libpapi-dynamic/common/job.c b/usr/src/lib/print/libpapi-dynamic/common/job.c
new file mode 100644
index 0000000000..e7bca751a0
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/common/job.c
@@ -0,0 +1,457 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: job.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdlib.h>
+#include <papi_impl.h>
+
+void
+papiJobFree(papi_job_t job)
+{
+ job_t *tmp = (job_t *)job;
+
+ if (tmp != NULL) {
+ void (*f)();
+
+ f = (void (*)())psm_sym(tmp->svc, "papiJobFree");
+ if (f != NULL)
+ f(tmp->job);
+ free(tmp);
+ }
+}
+
+void
+papiJobListFree(papi_job_t *jobs)
+{
+ if (jobs != NULL) {
+ int i;
+
+ for (i = 0; jobs[i] != NULL; i++)
+ papiJobFree(jobs[i]);
+ free(jobs);
+ }
+}
+
+papi_attribute_t **
+papiJobGetAttributeList(papi_job_t job)
+{
+ papi_attribute_t **result = NULL;
+ job_t *j = job;
+
+ if (job != NULL) {
+ papi_attribute_t **(*f)();
+
+ f = (papi_attribute_t **(*)())psm_sym(j->svc,
+ "papiJobGetAttributeList");
+ if (f != NULL)
+ result = f(j->job);
+ }
+
+ return (result);
+}
+
+char *
+papiJobGetPrinterName(papi_job_t job)
+{
+ char *result = NULL;
+ job_t *j = job;
+
+ if (job != NULL) {
+ char *(*f)();
+
+ f = (char *(*)())psm_sym(j->svc, "papiJobGetPrinterName");
+ if (f != NULL)
+ result = f(j->job);
+ }
+
+ return (result);
+}
+
+int32_t
+papiJobGetId(papi_job_t job)
+{
+ int32_t result = -1;
+ job_t *j = job;
+
+ if (job != NULL) {
+ int32_t (*f)();
+
+ f = (int32_t (*)())psm_sym(j->svc, "papiJobGetId");
+ if (f != NULL)
+ result = f(j->job);
+ }
+
+ return (result);
+}
+
+papi_job_ticket_t *
+papiJobGetJobTicket(papi_job_t job)
+{
+ papi_job_ticket_t *result = NULL;
+ job_t *j = job;
+
+ if (job != NULL) {
+ papi_job_ticket_t *(*f)();
+
+ f = (papi_job_ticket_t *(*)())psm_sym(j->svc,
+ "papiJobGetJobTicket");
+ if (f != NULL)
+ result = f(j->job);
+ }
+
+ return (result);
+}
+
+/* common support for papiJob{Submit|SubmitByReference|Validate} */
+static papi_status_t
+_papi_job_submit_reference_or_validate(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, char **files, papi_job_t *job,
+ char *function)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ job_t *j = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (printer == NULL) || (files == NULL) ||
+ (job == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ if ((*job = j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ j->svc = svc;
+ f = (papi_status_t (*)())psm_sym(j->svc, function);
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, job_attributes,
+ job_ticket, files, &j->job);
+
+ return (result);
+}
+
+papi_status_t
+papiJobSubmit(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
+{
+ return (_papi_job_submit_reference_or_validate(handle, printer,
+ job_attributes, job_ticket, files, job,
+ "papiJobSubmit"));
+}
+
+papi_status_t
+papiJobSubmitByReference(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
+{
+ return (_papi_job_submit_reference_or_validate(handle, printer,
+ job_attributes, job_ticket, files, job,
+ "papiJobSubmitByReference"));
+}
+
+papi_status_t
+papiJobValidate(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
+{
+ return (_papi_job_submit_reference_or_validate(handle, printer,
+ job_attributes, job_ticket, files, job,
+ "papiJobValidate"));
+}
+
+papi_status_t
+papiJobStreamOpen(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, papi_stream_t *stream)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (printer == NULL) || (stream == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ f = (papi_status_t (*)())psm_sym(svc, "papiJobStreamOpen");
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, job_attributes,
+ job_ticket, stream);
+
+ return (result);
+}
+
+papi_status_t
+papiJobStreamWrite(papi_service_t handle,
+ papi_stream_t stream, void *buffer, size_t buflen)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (stream == NULL) || (buffer == NULL) ||
+ (buflen == 0))
+ return (PAPI_BAD_ARGUMENT);
+
+ f = (papi_status_t (*)())psm_sym(svc, "papiJobStreamWrite");
+ if (f != NULL)
+ result = f(svc->svc_handle, stream, buffer, buflen);
+
+ return (result);
+}
+
+papi_status_t
+papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ job_t *j = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (stream == NULL) || (job == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((*job = j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ j->svc = svc;
+ f = (papi_status_t (*)())psm_sym(j->svc, "papiJobStreamClose");
+ if (f != NULL)
+ result = f(svc->svc_handle, stream, &j->job);
+
+ return (result);
+}
+
+papi_status_t
+papiJobQuery(papi_service_t handle, char *printer, int32_t job_id,
+ char **requested_attrs, papi_job_t *job)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ job_t *j = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (printer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ if ((*job = j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ j->svc = svc;
+ f = (papi_status_t (*)())psm_sym(j->svc, "papiJobQuery");
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, job_id,
+ requested_attrs, &j->job);
+
+ return (result);
+}
+
+papi_status_t
+papiJobMove(papi_service_t handle, char *printer, int32_t job_id,
+ char *destination)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (printer == NULL) || (job_id < 0))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ f = (papi_status_t (*)())psm_sym(svc, "papiJobMove");
+ if (f != NULL) {
+ papi_attribute_t **attrs = getprinterbyname(destination, NULL);
+
+ papiAttributeListGetString(attrs, NULL,
+ "printer-uri-supported", &destination);
+ result = f(svc->svc_handle, svc->name, job_id, destination);
+ papiAttributeListFree(attrs);
+ }
+
+ return (result);
+}
+
+/* common support for papiJob{Cancel|Release|Restart|Promote} */
+static papi_status_t
+_papi_job_handle_printer_id(papi_service_t handle,
+ char *printer, int32_t job_id, char *function)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (printer == NULL) || (job_id < 0))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ f = (papi_status_t (*)())psm_sym(svc, function);
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, job_id);
+
+ return (result);
+}
+
+papi_status_t
+papiJobCancel(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_papi_job_handle_printer_id(handle, printer, job_id,
+ "papiJobCancel"));
+}
+
+papi_status_t
+papiJobRelease(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_papi_job_handle_printer_id(handle, printer, job_id,
+ "papiJobRelease"));
+}
+
+papi_status_t
+papiJobRestart(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_papi_job_handle_printer_id(handle, printer, job_id,
+ "papiJobRestart"));
+}
+
+papi_status_t
+papiJobPromote(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_papi_job_handle_printer_id(handle, printer, job_id,
+ "papiJobPromote"));
+}
+
+papi_status_t
+papiJobCommit(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_papi_job_handle_printer_id(handle, printer, job_id,
+ "papiJobCommit"));
+}
+
+papi_status_t
+papiJobHold(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_papi_job_handle_printer_id(handle, printer, job_id,
+ "papiJobHold"));
+}
+
+papi_status_t
+papiJobModify(papi_service_t handle, char *printer, int32_t job_id,
+ papi_attribute_t **attributes, papi_job_t *job)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ job_t *j = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (printer == NULL) || (job_id < 0) ||
+ (attributes == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ if ((*job = j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ j->svc = svc;
+ f = (papi_status_t (*)())psm_sym(j->svc, "papiJobModify");
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, job_id, attributes,
+ &j->job);
+
+ return (result);
+}
+
+/*
+ * The functions defined below are private to Solaris. They are here
+ * temporarily, until equivalent functionality makes it's way into the PAPI
+ * spec. This is expected in the next minor version after v1.0.
+ */
+papi_status_t
+papiJobCreate(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, papi_job_t *job)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ job_t *j = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (printer == NULL) || (job == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ if ((*job = j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ j->svc = svc;
+ f = (papi_status_t (*)())psm_sym(j->svc, "papiJobCreate");
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, job_attributes,
+ job_ticket, &j->job);
+
+ return (result);
+}
+
+papi_status_t
+papiJobStreamAdd(papi_service_t handle, char *printer, int32_t id,
+ papi_stream_t *stream)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (printer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ f = (papi_status_t (*)())psm_sym(svc, "papiJobStreamAdd");
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, id, stream);
+
+ return (result);
+}
diff --git a/usr/src/lib/print/libpapi-dynamic/common/mapfile b/usr/src/lib/print/libpapi-dynamic/common/mapfile
new file mode 100644
index 0000000000..7c6d07953c
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/common/mapfile
@@ -0,0 +1,150 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# Common interfaces that are most likely to be shared amongst the various
+# PAPI implementations.
+#
+
+SUNW_1.0 {
+ global:
+ # PAPI Attribute Calls
+ papiAttributeListAddValue = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddBoolean = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddCollection = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddDatetime = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddInteger = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddMetadata = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddRange = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddResolution = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListDelete = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetValue = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetNext = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFind = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetBoolean = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetCollection = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetDatetime = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetInteger = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetMetadata = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetRange = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetResolution = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFromString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListToString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFree = FUNCTION FILTER libpapi-common.so ;
+
+ # PAPI Service Calls
+ papiServiceCreate ;
+ papiServiceDestroy ;
+ papiServiceSetUserName ;
+ papiServiceSetPassword ;
+ papiServiceSetEncryption ;
+ papiServiceSetAuthCB ;
+ papiServiceSetAppData ;
+ papiServiceGetUserName ;
+ papiServiceGetPassword ;
+ papiServiceGetEncryption ;
+ papiServiceGetAppData ;
+ papiServiceGetServiceName ;
+ papiServiceGetAttributeList ;
+ papiServiceGetStatusMessage ;
+
+ # PAPI Printer Calls
+ papiPrintersList ;
+ papiPrinterQuery ;
+ papiPrinterAdd ;
+ papiPrinterModify ;
+ papiPrinterRemove ;
+ papiPrinterDisable ;
+ papiPrinterEnable ;
+ papiPrinterPause ;
+ papiPrinterResume ;
+ papiPrinterPurgeJobs ;
+ papiPrinterListJobs ;
+ papiPrinterGetAttributeList ;
+ papiPrinterFree ;
+ papiPrinterListFree ;
+
+ # PAPI Job Calls
+ papiJobSubmit ;
+ papiJobSubmitByReference ;
+ papiJobValidate ;
+ papiJobStreamOpen ;
+ papiJobStreamWrite ;
+ papiJobStreamClose ;
+ papiJobQuery ;
+ papiJobModify ;
+ papiJobMove ;
+ papiJobCancel ;
+ papiJobHold ;
+ papiJobRelease ;
+ papiJobRestart ;
+ papiJobPromote ;
+ papiJobGetAttributeList ;
+ papiJobGetPrinterName ;
+ papiJobGetId ;
+ papiJobGetJobTicket ;
+ papiJobFree ;
+ papiJobListFree ;
+
+ # Misc. PAPI Calls
+ papiStatusString = FUNCTION FILTER libpapi-common.so ;
+ papiLibrarySupportedCall = FUNCTION FILTER libpapi-common.so ;
+ papiLibrarySupportedCalls = FUNCTION FILTER libpapi-common.so ;
+};
+
+SUNWprivate_1.0 {
+ global:
+ papiServiceSetPeer ; # extension
+ papiJobCreate ;
+ papiJobStreamAdd ;
+ papiJobCommit ;
+
+ # Misc. supporting calls
+ # URI
+ uri_from_string = FUNCTION FILTER libpapi-common.so ;
+ uri_to_string = FUNCTION FILTER libpapi-common.so ;
+ uri_free = FUNCTION FILTER libpapi-common.so ;
+ # list
+ list_remove = FUNCTION FILTER libpapi-common.so ;
+ list_append = FUNCTION FILTER libpapi-common.so ;
+ list_concatenate = FUNCTION FILTER libpapi-common.so ;
+
+ # extra Attribute Calls
+ copy_attributes = FUNCTION FILTER libpapi-common.so ;
+ split_and_copy_attributes = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListPrint = FUNCTION FILTER libpapi-common.so ;
+
+ local:
+ * ;
+} ;
diff --git a/usr/src/lib/print/libpapi-dynamic/common/nss.c b/usr/src/lib/print/libpapi-dynamic/common/nss.c
new file mode 100644
index 0000000000..9a142827c4
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/common/nss.c
@@ -0,0 +1,497 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: nss.c 166 2006-05-20 05:48:55Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <syslog.h>
+#include <papi.h>
+#include <uri.h>
+#include <papi_impl.h>
+#ifdef NSS_EMULATION
+#include <nss-emulation.h>
+#elif NSS_SOLARIS
+#include <nss_dbdefs.h>
+#endif
+#include <config-site.h>
+#if defined(__sun) && defined(__SVR4)
+#include <sys/systeminfo.h>
+#endif
+
+
+static char *
+bsdaddr_to_uri(char *bsdaddr)
+{
+ char *result = NULL;
+
+ if (bsdaddr != NULL) {
+ char *bsd[3], *tmp, *iter = NULL;
+ char buf[512];
+
+ tmp = strdup(bsdaddr);
+
+ bsd[0] = strtok_r(tmp, ":,", &iter);
+ bsd[1] = strtok_r(NULL, ":,", &iter);
+ bsd[2] = strtok_r(NULL, ":,", &iter);
+
+ snprintf(buf, sizeof (buf), "lpd://%s/%s%s%s", bsd[0], bsd[1],
+ (bsd[2] != NULL) ? "#" : "",
+ (bsd[2] != NULL) ? bsd[2] : "");
+
+ free(tmp);
+
+ result = strdup(buf);
+ }
+
+ return (result);
+}
+
+#if defined(__sun) && defined(__SVR4)
+/*
+ * This is an awful HACK to force the dynamic PAPI library to use the
+ * lpsched support when the destination apears to be a local lpsched
+ * queue on Solaris.
+ */
+static void
+solaris_lpsched_shortcircuit_hack(papi_attribute_t ***list)
+{
+ papi_attribute_t *attribute;
+ uri_t *uri = NULL;
+ char *printer = NULL;
+ char hostname[BUFSIZ];
+ char buf[128], buf2[128];
+
+ /* setting this in the calling env can be useful for debugging */
+ if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL)
+ return;
+
+ papiAttributeListGetString(*list, NULL,
+ "printer-uri-supported", &printer);
+ if (uri_from_string(printer, &uri) < 0)
+ return;
+
+ /* already an lpsched URI ? */
+ if (strcasecmp(uri->scheme, "lpsched") == 0)
+ return;
+
+ sysinfo(SI_HOSTNAME, hostname, sizeof (hostname));
+ if ((uri->host != NULL) &&
+ (strncasecmp(uri->host, hostname, strlen(hostname)) != 0) &&
+ (strncasecmp(uri->host, "localhost", 10) != 0))
+ return;
+
+ if ((printer = strrchr(uri->path, '/')) == NULL)
+ printer = uri->path;
+ else
+ printer++;
+
+ /* is there an lpsched queue (printer/class) */
+ snprintf(buf, sizeof (buf), "/etc/lp/interfaces/%s", printer);
+ snprintf(buf2, sizeof (buf2), "/etc/lp/classes/%s", printer);
+ if ((access(buf, F_OK) < 0) && (access(buf2, F_OK) < 0))
+ return;
+
+ snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s", printer);
+ papiAttributeListAddString(list, PAPI_ATTR_REPLACE,
+ "printer-uri-supported", buf);
+}
+#endif
+
+static void
+fill_printer_uri_supported(papi_attribute_t ***list)
+{
+ papi_attribute_t *attribute;
+ char *string = NULL;
+
+ /* do we have a printer-uri-supported */
+ attribute = papiAttributeListFind(*list, "printer-uri-supported");
+ if (attribute != NULL) /* we have what we need, return */
+ return;
+
+ /* do we have a printer-uri to rename */
+ attribute = papiAttributeListFind(*list, "printer-uri");
+ if (attribute != NULL) { /* rename it in place and return */
+ free(attribute->name);
+ attribute->name = strdup("printer-uri-supported");
+ return;
+ }
+
+ /* do we have a printers.conf(4) "bsdaddr" to convert */
+ papiAttributeListGetString(*list, NULL, "bsdaddr", &string);
+ if (string != NULL) { /* parse it, convert it, add it */
+ char *uri = bsdaddr_to_uri(string);
+
+ if (uri != NULL) {
+ papiAttributeListAddString(list, PAPI_ATTR_APPEND,
+ "printer-uri-supported", uri);
+ papiAttributeListDelete(list, "bsdaddr");
+ free(uri);
+ return;
+ }
+ }
+
+ /* do we have a printers.conf(4) "rm" (and "rp") to convert */
+ papiAttributeListGetString(*list, NULL, "rm", &string);
+ if (string != NULL) {
+ char *rp = NULL;
+
+ /* default to "printer-name", but use "rp" if we have it */
+ papiAttributeListGetString(*list, NULL, "printer-name", &rp);
+ papiAttributeListGetString(*list, NULL, "rp", &rp);
+
+ if (rp != NULL) { /* fill in the uri if we have the data */
+ char buf[BUFSIZ];
+
+ snprintf(buf, sizeof (buf), "lpd://%s/printers/%s",
+ string, rp);
+ papiAttributeListAddString(list, PAPI_ATTR_APPEND,
+ "printer-uri-supported", strdup(buf));
+ return;
+ }
+ }
+
+ /* if were are here, we don't have a printer-uri-supported */
+}
+
+#ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC
+static void
+fill_printer_uri(papi_attribute_t ***list)
+{
+ papi_attribute_t *attribute;
+ char *uri = NULL;
+
+ if ((list == NULL) || (*list == NULL))
+ return;
+
+ /* do we have a printer-uri-supported */
+ attribute = papiAttributeListFind(*list, "printer-uri");
+ if (attribute != NULL) /* we have what we need, return */
+ return;
+
+ /*
+ * this is sufficient to fool libgnomeprintpapi, but not promote it's
+ * use in the future.
+ */
+ papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri",
+ "broken printer-uri semantic");
+}
+#endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */
+
+static void
+cvt_all_to_member_names(papi_attribute_t ***list)
+{
+ papi_status_t status;
+ void *iter = NULL;
+ char *string = NULL;
+
+ papiAttributeListGetString(*list, NULL, "member-names", &string);
+ if (string != NULL) /* already have a member-names */
+ return;
+
+ for (status = papiAttributeListGetString(*list, &iter, "all", &string);
+ status == PAPI_OK;
+ status = papiAttributeListGetString(*list, &iter, NULL, &string)) {
+ char *s_iter = NULL, *value, *tmp = strdup(string);
+
+ for (value = strtok_r(tmp, ", \t", &s_iter);
+ value != NULL;
+ value = strtok_r(NULL, ", \t", &s_iter))
+ papiAttributeListAddString(list, PAPI_ATTR_APPEND,
+ "member-names", value);
+ free(tmp);
+ }
+}
+
+static papi_attribute_t **
+_cvt_nss_entry_to_printer(char *entry)
+{
+ char *key = NULL,
+ *cp,
+ buf[BUFSIZ];
+ int in_namelist = 1, buf_pos = 0;
+ papi_attribute_t **list = NULL;
+
+ if (entry == NULL)
+ return (NULL);
+
+ memset(buf, 0, sizeof (buf));
+ for (cp = entry; *cp != '\0'; cp++) {
+ switch (*cp) {
+ case ':': /* end of kvp */
+ if (in_namelist != 0) {
+ papiAttributeListAddString(&list,
+ PAPI_ATTR_APPEND, "printer-name", buf);
+ in_namelist = 0;
+ } else if (key != NULL)
+ papiAttributeListAddString(&list,
+ PAPI_ATTR_APPEND, key, buf);
+ memset(buf, 0, sizeof (buf));
+ buf_pos = 0;
+ key = NULL;
+ break;
+ case '=': /* kvp seperator */
+ if (key == NULL) {
+ key = strdup(buf);
+ memset(buf, 0, sizeof (buf));
+ buf_pos = 0;
+ } else
+ buf[buf_pos++] = *cp;
+ break;
+ case '|': /* namelist seperator */
+ if (in_namelist != 0) {
+ papiAttributeListAddString(&list,
+ PAPI_ATTR_APPEND, "printer-name", buf);
+ memset(buf, 0, sizeof (buf));
+ buf_pos = 0;
+ } else /* add it to the buffer */
+ buf[buf_pos++] = *cp;
+ break;
+ case '\\': /* escape char */
+ buf[buf_pos++] = *(++cp);
+ break;
+ default:
+ buf[buf_pos++] = *cp;
+ }
+
+ }
+
+ if (key != NULL)
+ papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf);
+
+ /* resolve any "use" references in the configuration DB */
+ key = NULL;
+ papiAttributeListGetString(list, NULL, "use", &key);
+ if (key != NULL) {
+ papi_attribute_t **use_attrs = getprinterbyname(key, NULL);
+
+ list_concatenate(&list, use_attrs);
+ }
+
+ fill_printer_uri_supported(&list);
+#if defined(__sun) && defined(__SVR4)
+ solaris_lpsched_shortcircuit_hack(&list);
+#endif
+ cvt_all_to_member_names(&list); /* convert "all" to "member-names" */
+
+ return (list);
+}
+
+#if defined(NSS_SOLARIS) && !defined(NSS_EMULATION)
+
+#ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */
+#define NSS_DBNAM__PRINTERS "_printers"
+#endif
+
+static DEFINE_NSS_DB_ROOT(db_root);
+static DEFINE_NSS_GETENT(context);
+
+static char *private_ns = NULL;
+static char initialized = 0;
+
+static void
+_nss_initf_printers(p)
+ nss_db_params_t *p;
+{
+ if (private_ns != NULL) {
+ /*
+ * because we need to support a legacy interface that allows
+ * us to select a specific name service, we need to dummy up
+ * the parameters to use a private nsswitch database and set
+ * the * default_config entry to the name service we are
+ * looking into.
+ */
+ p->name = NSS_DBNAM__PRINTERS; /* "_printers" */
+ p->default_config = private_ns;
+ private_ns = NULL;
+ } else if (initialized == 0) {
+ /* regular behaviour */
+ p->name = NSS_DBNAM_PRINTERS; /* "printers" */
+ p->default_config = NSS_DEFCONF_PRINTERS;
+ initialized = 1;
+ }
+ syslog(LOG_DEBUG, "database: %s, services: %s",
+ (p->name ? p->name : "NULL"),
+ (p->default_config ? p->default_config : "NULL"));
+}
+
+/*
+ * Return values: 0 = success, 1 = parse error, 2 = erange ...
+ * The structure pointer passed in is a structure in the caller's space
+ * wherein the field pointers would be set to areas in the buffer if
+ * need be. instring and buffer should be separate areas.
+ */
+/* ARGSUSED */
+static int
+str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen)
+{
+ if (lenstr + 1 > buflen)
+ return (NSS_STR_PARSE_ERANGE);
+ /*
+ * We copy the input string into the output buffer
+ */
+ (void) memcpy(buffer, instr, lenstr);
+ buffer[lenstr] = '\0';
+
+ return (NSS_STR_PARSE_SUCCESS);
+}
+#endif /* NSS_SOLARIS */
+
+int
+setprinterentry(int stayopen, char *ns)
+{
+#ifdef NSS_EMULATION
+ emul_setprinterentry(stayopen);
+#elif NSS_SOLARIS
+ initialized = 0;
+ private_ns = ns;
+ nss_setent(&db_root, _nss_initf_printers, &context);
+#endif
+ return (0);
+}
+
+
+int
+endprinterentry(int i)
+{
+#ifdef NSS_EMULATION
+ emul_endprinterentry();
+#elif NSS_SOLARIS
+ initialized = 0;
+ nss_endent(&db_root, _nss_initf_printers, &context);
+ nss_delete(&db_root);
+#endif
+ return (0);
+}
+
+/* ARGSUSED2 */
+papi_attribute_t **
+getprinterentry(char *ns)
+{
+ papi_attribute_t **result = NULL;
+
+#if defined(NSS_EMULATION) || defined(NSS_SOLARIS)
+ char buf[10240];
+ nss_status_t res = NSS_NOTFOUND;
+
+#ifdef NSS_EMULATION
+ res = emul_getprinterentry_r(buf, sizeof (buf));
+#elif NSS_SOLARIS
+ nss_XbyY_args_t arg;
+
+ NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer);
+ res = nss_getent(&db_root, _nss_initf_printers, &context, &arg);
+ (void) NSS_XbyY_FINI(&arg);
+#endif
+
+ if (res != NSS_SUCCESS)
+ buf[0] = '\0';
+
+ result = _cvt_nss_entry_to_printer(buf);
+#ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC
+ fill_printer_uri(&result);
+#endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */
+#endif
+
+#ifdef DEBUG
+ printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result);
+ if (result != NULL) {
+ char buf[4096];
+
+ papiAttributeListToString(result, "\n\t", buf, sizeof (buf));
+ printf("\t%s\n", buf);
+ }
+#endif /* DEBUG */
+
+ return (result);
+}
+
+
+papi_attribute_t **
+getprinterbyname(char *name, char *ns)
+{
+ papi_attribute_t **result = NULL;
+
+ if (strstr(name, "://") != NULL) { /* shortcut for URI form */
+ papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
+ "printer-name", name);
+ papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
+ "printer-uri-supported", name);
+ } else if (strchr(name, ':') != NULL) { /* shortcut for POSIX form */
+ char *uri = bsdaddr_to_uri(name);
+
+ papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
+ "printer-name", name);
+ if (uri != NULL) {
+ papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
+ "printer-uri-supported", uri);
+ free(uri);
+ }
+ } else { /* anything else */
+#if defined(NSS_EMULATION) || defined(NSS_SOLARIS)
+ char buf[10240];
+ nss_status_t res = NSS_NOTFOUND;
+
+#ifdef NSS_EMULATION
+ res = emul_getprinterbyname_r(name, buf, sizeof (buf));
+#elif NSS_SOLARIS
+ nss_XbyY_args_t arg;
+
+ private_ns = ns;
+ NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer);
+ arg.key.name = name;
+ res = nss_search(&db_root, _nss_initf_printers,
+ NSS_DBOP_PRINTERS_BYNAME, &arg);
+ (void) NSS_XbyY_FINI(&arg);
+
+ if (res != NSS_SUCCESS)
+ buf[0] = '\0';
+#endif
+
+ result = _cvt_nss_entry_to_printer(buf);
+#endif
+ }
+
+#ifdef DEBUG
+ printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"),
+ name, result);
+ if (result != NULL) {
+ char buf[4096];
+
+ papiAttributeListToString(result, "\n\t", buf, sizeof (buf));
+ printf("\t%s\n", buf);
+ }
+#endif /* DEBUG */
+
+ return (result);
+}
diff --git a/usr/src/lib/print/libpapi-dynamic/common/papi_impl.h b/usr/src/lib/print/libpapi-dynamic/common/papi_impl.h
new file mode 100644
index 0000000000..be28a9de0c
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/common/papi_impl.h
@@ -0,0 +1,97 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#ifndef _PAPI_IMPL_H
+#define _PAPI_IMPL_H
+
+/* $Id: papi_impl.h 161 2006-05-03 04:32:59Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <papi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <uri.h>
+
+/*
+ * Implementation specific types/prototypes/definitions follow
+ *
+ *
+ * Ex:
+ */
+
+typedef struct {
+ papi_attribute_t **attributes;
+ void *so_handle;
+ void *svc_handle;
+ char *name;
+ char *user;
+ char *password;
+ int (*authCB)(papi_service_t svc, void *app_data);
+ papi_encryption_t encryption;
+ void *app_data;
+ uri_t *uri;
+ int peer_fd;
+} service_t;
+
+typedef struct job {
+ service_t *svc;
+ papi_job_t *job;
+} job_t;
+
+typedef struct {
+ service_t *svc;
+ papi_printer_t *printer;
+ papi_attribute_t **attributes;
+ char svc_is_internal;
+} printer_t;
+
+extern papi_status_t psm_open(service_t *svc, char *name);
+extern void *psm_sym(service_t *svc, char *name);
+extern void psm_close(void *handle);
+extern void detailed_error(service_t *svc, char *fmt, ...);
+extern papi_status_t service_connect(service_t *svc, char *uri);
+extern papi_attribute_t **getprinterentry(char *ns);
+extern papi_attribute_t **getprinterbyname(char *name, char *ns);
+extern int setprinterentry(int stayopen, char *ns);
+extern int endprinterentry(int stayopen);
+
+
+
+extern void list_remove();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAPI_IMPL_H */
diff --git a/usr/src/lib/print/libpapi-dynamic/common/printer.c b/usr/src/lib/print/libpapi-dynamic/common/printer.c
new file mode 100644
index 0000000000..321492703e
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/common/printer.c
@@ -0,0 +1,512 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: printer.c 151 2006-04-25 16:55:34Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdlib.h>
+#include <papi_impl.h>
+
+void
+papiPrinterFree(papi_printer_t printer)
+{
+ printer_t *tmp = printer;
+
+ if (tmp != NULL) {
+ void (*f)();
+
+ f = (void (*)())psm_sym(tmp->svc, "papiPrinterFree");
+ if (f != NULL)
+ f(tmp->printer);
+ if (tmp->attributes != NULL)
+ papiAttributeListFree(tmp->attributes);
+ if (tmp->svc_is_internal != 0)
+ papiServiceDestroy(tmp->svc);
+ free(tmp);
+ }
+}
+
+void
+papiPrinterListFree(papi_printer_t *printers)
+{
+ if (printers != NULL) {
+ int i;
+
+ for (i = 0; printers[i] != NULL; i++)
+ papiPrinterFree(printers[i]);
+ free(printers);
+ }
+}
+
+/* Enumerate a list of printers from the loaded print service. */
+static papi_status_t
+printers_from_service(service_t *svc, char **requested_attrs,
+ papi_filter_t *filter, papi_printer_t **printers)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ papi_printer_t *svc_printers = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (printers == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* connect to the service if we are not connected */
+ if ((result = service_connect(svc, svc->name)) != PAPI_OK)
+ return (result);
+
+ f = (papi_status_t (*)())psm_sym(svc, "papiPrintersList");
+ if (f != NULL)
+ result = f(svc->svc_handle, requested_attrs, filter,
+ &svc_printers);
+
+ /*
+ * copy the resulting printer object pointers into our own
+ * representation of a printer object because we need the
+ * service context to operate against the individual printer
+ * objects. We free the list now because we no longer need
+ * it and would have no way of freeing it later.
+ */
+ if ((result == PAPI_OK) && (svc_printers != NULL)) {
+ int i;
+
+ *printers = NULL;
+ for (i = 0; svc_printers[i] != NULL; i++) {
+ printer_t *p = NULL;
+
+ if ((p = calloc(1, sizeof (*p))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ p->svc = svc;
+ p->printer = svc_printers[i];
+ list_append(printers, p);
+ }
+ free(svc_printers);
+ }
+
+ return (result);
+}
+
+/* Get printer attributes from it's print service */
+static papi_status_t
+printer_from_service(service_t *svc, printer_t *p, char **requested_attrs)
+{
+ papi_status_t result;
+ papi_service_t p_svc = NULL;
+ papi_printer_t printer = NULL;
+ char *psm = NULL;
+ char *uri = NULL;
+
+ /* get the psm and uri from the attributes */
+ papiAttributeListGetString(p->attributes, NULL,
+ "print-service-module", &psm);
+ papiAttributeListGetString(p->attributes, NULL, "printer-name", &uri);
+ papiAttributeListGetString(p->attributes, NULL, "printer-uri-supported",
+ &uri);
+
+ /* contact the service for the printer */
+ result = papiServiceCreate((papi_service_t *)&p_svc, psm, svc->user,
+ svc->password, svc->authCB, svc->encryption,
+ svc->app_data);
+ if (result != PAPI_OK)
+ return (result);
+
+ /* get the printer from the service */
+ result = papiPrinterQuery(p_svc, uri, requested_attrs, NULL, &printer);
+ if (result == PAPI_OK) {
+ papi_attribute_t **attributes;
+
+ attributes = papiPrinterGetAttributeList(printer);
+ copy_attributes(&p->attributes, attributes);
+ }
+ papiPrinterFree(printer);
+ papiServiceDestroy(p_svc);
+
+ return (result);
+}
+
+/* are the requested attributes contained in the list */
+static int
+contained(char **requested, papi_attribute_t **list)
+{
+ int i;
+
+ if (requested == NULL) /* we want every possible attribute */
+ return (0);
+
+ for (i = 0; requested[i] != NULL; i++)
+ if (papiAttributeListFind(list, requested[i]) == NULL)
+ return (0);
+
+ return (1);
+}
+
+/* Enumerate a list of printers from the Name Service */
+static papi_status_t
+printers_from_name_service(service_t *svc, char **requested_attrs,
+ papi_filter_t *filter, papi_printer_t **printers)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ papi_attribute_t **attrs;
+
+ if ((svc == NULL) || (printers == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* retrieve printers from the nameservice */
+ while ((attrs = getprinterentry(NULL)) != NULL) {
+ printer_t *p = NULL;
+
+ if ((p = calloc(1, sizeof (*p))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ p->attributes = attrs;
+ list_append(printers, p);
+ }
+
+ /* if we have printers, check if our request has been satisfied */
+ if ((printers != NULL) && (*printers != NULL)) {
+ int i;
+
+ /* walk through the list */
+ for (i = 0; (*printers)[i] != NULL; i++) {
+ printer_t *p = (*printers)[i];
+
+ /* see if the name service satisfied the request */
+ if (contained(requested_attrs, p->attributes) == 0)
+ printer_from_service(svc, p, requested_attrs);
+ }
+ }
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+papiPrintersList(papi_service_t handle, char **requested_attrs,
+ papi_filter_t *filter, papi_printer_t **printers)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_printer_t *svc_printers = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (printers == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if (svc->so_handle != NULL) /* connected, use the print svc */
+ result = printers_from_service(svc, requested_attrs,
+ filter, printers);
+ else /* not connected, use the name svc */
+ result = printers_from_name_service(svc, requested_attrs,
+ filter, printers);
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs,
+ papi_attribute_t **job_attributes, papi_printer_t *printer)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ printer_t *p = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (name == NULL) || (printer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ if ((svc->name != NULL) && (svc->svc_handle != NULL) &&
+ (svc->uri != NULL)) {
+ p->svc = svc;
+ f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery");
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, requested_attrs,
+ job_attributes, &p->printer);
+ } else {
+ setprinterentry(0, NULL);
+ p->attributes = getprinterbyname(name, NULL);
+ if (p->attributes == NULL)
+ result = PAPI_NOT_FOUND;
+ else
+ result = PAPI_OK;
+ }
+
+ return (result);
+}
+
+static papi_status_t
+_papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message,
+ char *function)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ f = (papi_status_t (*)())psm_sym(svc, function);
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, message);
+
+ return (result);
+}
+
+static papi_status_t
+_papi_printer_enable_or_resume(papi_service_t handle, char *name,
+ char *function)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ f = (papi_status_t (*)())psm_sym(svc, function);
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name);
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterDisable(papi_service_t handle, char *name, char *message)
+{
+ return (_papi_printer_disable_or_pause(handle, name, message,
+ "papiPrinterDisable"));
+}
+
+papi_status_t
+papiPrinterPause(papi_service_t handle, char *name, char *message)
+{
+ return (_papi_printer_disable_or_pause(handle, name, message,
+ "papiPrinterPause"));
+}
+
+papi_status_t
+papiPrinterEnable(papi_service_t handle, char *name)
+{
+ return (_papi_printer_enable_or_resume(handle, name,
+ "papiPrinterEnable"));
+}
+
+papi_status_t
+papiPrinterResume(papi_service_t handle, char *name)
+{
+ return (_papi_printer_enable_or_resume(handle, name,
+ "papiPrinterResume"));
+}
+
+static papi_status_t
+_papi_printer_add_or_modify(papi_service_t handle, char *name,
+ papi_attribute_t **attributes, papi_printer_t *printer,
+ char *function)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ printer_t *p = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (name == NULL) || (attributes == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ p->svc = svc;
+ f = (papi_status_t (*)())psm_sym(p->svc, function);
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, attributes,
+ &p->printer);
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterAdd(papi_service_t handle, char *name,
+ papi_attribute_t **attributes, papi_printer_t *printer)
+{
+ return (_papi_printer_add_or_modify(handle, name, attributes, printer,
+ "papiPrinterAdd"));
+}
+
+papi_status_t
+papiPrinterModify(papi_service_t handle, char *name,
+ papi_attribute_t **attributes, papi_printer_t *printer)
+{
+ return (_papi_printer_add_or_modify(handle, name, attributes, printer,
+ "papiPrinterModify"));
+}
+
+
+papi_status_t
+papiPrinterRemove(papi_service_t handle, char *name)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove");
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name);
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_job_t *svc_jobs = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs");
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, &svc_jobs);
+
+ /*
+ * copy the resulting job object pointers into our own
+ * representation of a job object because we need the
+ * service context to operate against the individual job
+ * objects. We free the list now because we no longer need
+ * it and would have no way of freeing it later.
+ */
+ if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) {
+ int i;
+
+ *jobs = NULL;
+ for (i = 0; svc_jobs[i] != NULL; i++) {
+ job_t *j = NULL;
+
+ if ((j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ j->svc = svc;
+ j->job = svc_jobs[i];
+ list_append(jobs, j);
+ }
+ free(svc_jobs);
+ }
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs,
+ int type_mask, int max_num_jobs, papi_job_t **jobs)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_job_t *svc_jobs = NULL;
+ papi_status_t (*f)();
+
+ if ((svc == NULL) || (name == NULL) || (jobs == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs");
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->name, requested_attrs,
+ type_mask, max_num_jobs, &svc_jobs);
+
+ /*
+ * copy the resulting job object pointers into our own
+ * representation of a job object because we need the
+ * service context to operate against the individual job
+ * objects. We free the list now because we no longer need
+ * it and would have no way of freeing it later.
+ */
+ if ((result == PAPI_OK) && (svc_jobs != NULL)) {
+ int i;
+
+ *jobs = NULL;
+ for (i = 0; svc_jobs[i] != NULL; i++) {
+ job_t *j = NULL;
+
+ if ((j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ j->svc = svc;
+ j->job = svc_jobs[i];
+ list_append(jobs, j);
+ }
+ free(svc_jobs);
+ }
+
+ return (result);
+}
+
+papi_attribute_t **
+papiPrinterGetAttributeList(papi_printer_t printer)
+{
+ papi_attribute_t **result = NULL;
+ printer_t *p = printer;
+
+ if ((p != NULL) && (p->printer != NULL)) {
+ papi_attribute_t **(*f)();
+
+ f = (papi_attribute_t **(*)())psm_sym(p->svc,
+ "papiPrinterGetAttributeList");
+ if (f != NULL)
+ result = f(p->printer);
+ } else
+ result = p->attributes;
+
+ return (result);
+}
diff --git a/usr/src/lib/print/libpapi-dynamic/common/psm.c b/usr/src/lib/print/libpapi-dynamic/common/psm.c
new file mode 100644
index 0000000000..6bc679b79e
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/common/psm.c
@@ -0,0 +1,100 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: psm.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <papi_impl.h>
+
+#ifndef RTLD_GROUP
+#define RTLD_GROUP 0
+#endif /* RTLD_GROUP */
+
+#ifndef PSM_DIR
+#define PSM_DIR "/usr/lib/print"
+#endif
+
+papi_status_t
+psm_open(service_t *svc, char *scheme)
+{
+ papi_status_t result = PAPI_OK;
+ char *path;
+ char buf[BUFSIZ];
+
+ if (scheme == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ if (strchr(scheme, '/') == NULL) {
+ snprintf(buf, sizeof (buf), PSM_DIR "/psm-%s.so", scheme);
+ path = buf;
+ } else
+ path = scheme;
+
+ svc->so_handle = dlopen(path, RTLD_LAZY|RTLD_LOCAL|RTLD_GROUP);
+ if (svc->so_handle == NULL) { /* failed, set the result/message */
+ if ((access(path, F_OK) < 0) && (errno == ENOENT))
+ result = PAPI_URI_SCHEME;
+ else
+ result = PAPI_NOT_POSSIBLE;
+#ifdef DEBUG
+ detailed_error(svc, "psm_open(%s): %s: %s", scheme, path,
+ dlerror());
+#endif
+ }
+
+ return (result);
+}
+
+void
+psm_close(void *handle)
+{
+ dlclose(handle);
+}
+
+void *
+psm_sym(service_t *svc, char *name)
+{
+ char *error = "invalid input";
+ void *func = NULL;
+
+ if ((svc != NULL) && (svc->so_handle != NULL) && (name != NULL)) {
+ if ((func = dlsym(svc->so_handle, name)) == NULL)
+ error = dlerror();
+ }
+#ifdef DEBUG
+ if (func == NULL)
+ detailed_error(svc, "psm_sym(%s): %s", name, error);
+#endif
+
+ return (func);
+}
diff --git a/usr/src/lib/print/libpapi-dynamic/common/service.c b/usr/src/lib/print/libpapi-dynamic/common/service.c
new file mode 100644
index 0000000000..9d441af90d
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/common/service.c
@@ -0,0 +1,564 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: service.c 172 2006-05-24 20:54:00Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <alloca.h>
+#include <libintl.h>
+#include <papi_impl.h>
+#include <config-site.h>
+
+static int
+interposed_auth_callback(papi_service_t handle, void *app_data)
+{
+ int result = -1;
+ service_t *svc = app_data;
+
+ if (svc != NULL)
+ result = svc->authCB(svc, svc->app_data);
+
+ return (result);
+}
+
+static char *
+default_service_uri(char *fallback)
+{
+ char *result = NULL;
+
+ if ((result = getenv("PAPI_SERVICE_URI")) == NULL) {
+ char *cups;
+
+ if ((cups = getenv("CUPS_SERVER")) != NULL) {
+ char buf[BUFSIZ];
+
+ snprintf(buf, sizeof (buf), "ipp://%s/printers/", cups);
+ result = strdup(buf);
+ }
+ }
+
+ if (result == NULL)
+ result = fallback;
+
+ return (result);
+}
+
+static char *
+default_print_service()
+{
+ static char *result = NULL;
+
+ if (result == NULL) {
+ char *service_uri = default_service_uri(DEFAULT_SERVICE_URI);
+ uri_t *uri = NULL;
+
+ if (uri_from_string(service_uri, &uri) != -1)
+ result = strdup(uri->scheme);
+
+ if (uri != NULL)
+ uri_free(uri);
+ }
+
+ return (result);
+}
+
+static papi_status_t
+service_load(service_t *svc, char *name)
+{
+ papi_status_t result;
+ char *scheme = default_print_service();
+
+ if (svc->so_handle != NULL) /* already loaded */
+ return (PAPI_OK);
+
+ if (name == NULL) /* no info, can't load yet */
+ return (PAPI_OK);
+
+ /* Lookup the printer in the configuration DB */
+ svc->attributes = getprinterbyname((char *)name, NULL);
+
+ if (svc->attributes != NULL) {
+ char *tmp = NULL;
+
+ /* Printer found (or was a URI), use the attribute data */
+ papiAttributeListGetString(svc->attributes, NULL,
+ "printer-uri-supported", &tmp);
+ if (tmp != NULL)
+ svc->name = strdup(tmp);
+
+ /* parse the URI and set the scheme(print service) */
+ if (uri_from_string(svc->name, &svc->uri) != -1)
+ scheme = (svc->uri)->scheme;
+
+ /* override the scheme if it was in the attributes */
+ papiAttributeListGetString(svc->attributes, NULL,
+ "print-service-module", &scheme);
+
+ } else /* not found, assume it is the actual print service name */
+ scheme = name;
+
+ result = psm_open(svc, scheme);
+ switch (result) {
+ case PAPI_OK:
+ break; /* no error */
+ case PAPI_URI_SCHEME:
+ result = PAPI_NOT_FOUND;
+#ifdef DEBUG
+ detailed_error(svc, "Unable to load service for: %s", name);
+#endif
+ break;
+ default: /* set the detailed message */
+ detailed_error(svc, "Unable to load service (%s) for: %s",
+ scheme, name);
+ }
+
+ return (result);
+}
+
+static papi_status_t
+service_send_peer(service_t *svc)
+{
+ papi_status_t result = PAPI_OK;
+
+ if ((svc->peer_fd != -1) && (svc->so_handle != NULL) &&
+ (svc->svc_handle != NULL)) {
+ papi_status_t (*f)();
+
+ f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPeer");
+
+ if (f != NULL)
+ result = f(svc->svc_handle, svc->peer_fd);
+ }
+
+ return (result);
+}
+
+papi_status_t
+service_connect(service_t *svc, char *name)
+{
+ papi_status_t result = PAPI_NOT_POSSIBLE;
+
+ /* if there is no print service module loaded, try and load one. */
+ if (svc->so_handle == NULL)
+ result = service_load(svc, name);
+ else if ((svc->name == NULL) && (name != NULL))
+ svc->name = strdup(name);
+
+ /*
+ * the print service module is loaded, but we don't have a service
+ * handle.
+ */
+ if (svc->so_handle != NULL) {
+ papi_status_t (*f)();
+
+ f = (papi_status_t (*)())psm_sym(svc, "papiServiceCreate");
+
+ if (f != NULL) {
+ char *user = svc->user;
+ char *password = svc->password;
+
+ /* if no API user, try the URI user */
+ if ((user == NULL) && (svc->uri != NULL))
+ user = (svc->uri)->user;
+ /* if no API password, try the URI password */
+ if ((password == NULL) && (svc->uri != NULL))
+ password = (svc->uri)->password;
+
+ result = f(&svc->svc_handle, svc->name, user, password,
+ (svc->authCB ? interposed_auth_callback
+ : NULL),
+ svc->encryption, svc);
+ (void) service_send_peer(svc);
+ }
+ }
+
+ return (result);
+}
+
+papi_status_t
+papiServiceCreate(papi_service_t *handle, char *service_name, char *user_name,
+ char *password,
+ int (*authCB)(papi_service_t svc, void *app_data),
+ papi_encryption_t encryption, void *app_data)
+{
+ papi_status_t result = PAPI_NOT_POSSIBLE;
+ service_t *svc = NULL;
+ uri_t *u = NULL;
+
+ if (handle == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ svc->peer_fd = -1;
+
+ if (user_name != NULL)
+ svc->user = strdup(user_name);
+
+ if (password != NULL)
+ svc->password = strdup(password);
+
+ svc->encryption = encryption;
+
+ if (authCB != NULL)
+ svc->authCB = authCB;
+
+ if (app_data != NULL)
+ svc->app_data = app_data;
+
+ /* If not specified, get a "default" service from the environment */
+ if (service_name == NULL)
+ service_name = default_service_uri(NULL);
+
+ if (service_name != NULL) {
+ result = service_load(svc, service_name);
+ /* if the psm loaded and the svc contains a URI, connect */
+ if ((result == PAPI_OK) && (svc->uri != NULL))
+ result = service_connect(svc, service_name);
+ } else
+ result = PAPI_OK;
+
+ return (result);
+}
+
+void
+papiServiceDestroy(papi_service_t handle)
+{
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ if (svc->so_handle != NULL) {
+ if (svc->svc_handle != NULL) {
+ void (*f)();
+
+ f = (void (*)())psm_sym(svc,
+ "papiServiceDestroy");
+ f(svc->svc_handle);
+ }
+ psm_close(svc->so_handle);
+ }
+ if (svc->attributes != NULL)
+ papiAttributeListFree(svc->attributes);
+ if (svc->name != NULL)
+ free(svc->name);
+ if (svc->user != NULL)
+ free(svc->user);
+ if (svc->password != NULL)
+ free(svc->password);
+ if (svc->uri != NULL)
+ uri_free(svc->uri);
+
+ free(handle);
+ }
+}
+
+papi_status_t
+papiServiceSetPeer(papi_service_t handle, int fd)
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ svc->peer_fd = fd;
+ result = service_send_peer(svc);
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+papi_status_t
+papiServiceSetUserName(papi_service_t handle, char *user_name)
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ if (svc->user != NULL)
+ free(svc->user);
+ if (user_name != NULL)
+ svc->user = strdup(user_name);
+ f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetUserName");
+ if (f != NULL)
+ result = f(svc->svc_handle, user_name);
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+papi_status_t
+papiServiceSetPassword(papi_service_t handle, char *password)
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ if (svc->password != NULL)
+ free(svc->password);
+ if (password != NULL)
+ svc->password = strdup(password);
+ f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPassword");
+ if (f != NULL)
+ result = f(svc->svc_handle, password);
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+papi_status_t
+papiServiceSetEncryption(papi_service_t handle, papi_encryption_t encryption)
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ svc->encryption = encryption;
+ f = (papi_status_t (*)())psm_sym(svc,
+ "papiServiceSetEncryption");
+ if (f != NULL)
+ result = f(svc->svc_handle, encryption);
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+papi_status_t
+papiServiceSetAuthCB(papi_service_t handle,
+ int (*authCB)(papi_service_t svc, void *app_data))
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ svc->authCB = authCB;
+ f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetAuthCB");
+ if (f != NULL)
+ result = f(svc->svc_handle, interposed_auth_callback);
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+
+papi_status_t
+papiServiceSetAppData(papi_service_t handle, void *app_data)
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+ papi_status_t (*f)();
+
+ svc->app_data = (void *)app_data;
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+char *
+papiServiceGetServiceName(papi_service_t handle)
+{
+ char *result = NULL;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+ char *(*f)();
+
+ f = (char *(*)())psm_sym(svc, "papiServiceGetServiceName");
+ if (f != NULL)
+ result = f(svc->svc_handle);
+ if (result == NULL)
+ result = svc->name;
+ }
+
+ return (result);
+}
+
+char *
+papiServiceGetUserName(papi_service_t handle)
+{
+ char *result = NULL;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+ char *(*f)();
+
+ f = (char *(*)())psm_sym(svc, "papiServiceGetUserName");
+ if (f != NULL)
+ result = f(svc->svc_handle);
+ if (result == NULL)
+ result = svc->user;
+ }
+
+ return (result);
+}
+
+char *
+papiServiceGetPassword(papi_service_t handle)
+{
+ char *result = NULL;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+ char *(*f)();
+
+ f = (char *(*)())psm_sym(svc, "papiServiceGetPassword");
+ if (f != NULL)
+ result = f(svc->svc_handle);
+ if (result == NULL)
+ result = svc->password;
+ }
+
+ return (result);
+}
+
+papi_encryption_t
+papiServiceGetEncryption(papi_service_t handle)
+{
+ papi_encryption_t result = PAPI_ENCRYPT_NEVER;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+ papi_encryption_t (*f)();
+
+ f = (papi_encryption_t (*)())psm_sym(svc,
+ "papiServiceGetEncryption");
+ if (f != NULL)
+ result = f(svc->svc_handle);
+ if (result == PAPI_ENCRYPT_NEVER)
+ result = svc->encryption;
+ }
+
+ return (result);
+}
+
+void *
+papiServiceGetAppData(papi_service_t handle)
+{
+ void *result = NULL;
+ service_t *svc = handle;
+
+ if (handle != NULL)
+ result = svc->app_data;
+
+ return (result);
+}
+
+papi_attribute_t **
+papiServiceGetAttributeList(papi_service_t handle)
+{
+ papi_attribute_t **result = NULL;
+ service_t *svc = handle;
+
+ if (handle != NULL) {
+ papi_attribute_t **(*f)();
+
+ if (svc->so_handle == NULL) {
+ char *uri = default_service_uri(DEFAULT_SERVICE_URI);
+
+ if (service_connect(svc, uri) != PAPI_OK)
+ return (NULL);
+ }
+
+ f = (papi_attribute_t **(*)())psm_sym(svc,
+ "papiServiceGetAttributeList");
+ if (f != NULL)
+ result = f(svc->svc_handle);
+ } else
+ result = svc->attributes;
+
+ return (result);
+}
+
+char *
+papiServiceGetStatusMessage(papi_service_t handle)
+{
+ char *result = NULL;
+ service_t *svc = handle;
+
+ if (handle != NULL) {
+ char *(*f)();
+
+ f = (char *(*)())psm_sym(svc, "papiServiceGetStatusMessage");
+ if (f != NULL)
+ result = f(svc->svc_handle);
+ }
+ if (result == NULL) {
+ papiAttributeListGetString(svc->attributes, NULL,
+ "detailed-status-message", &result);
+ }
+
+ return (result);
+}
+
+void
+detailed_error(service_t *svc, char *fmt, ...)
+{
+ if ((svc != NULL) && (fmt != NULL)) {
+ va_list ap;
+ size_t size;
+ char *message = alloca(BUFSIZ);
+
+ va_start(ap, fmt);
+ /*
+ * fill in the message. If the buffer is too small, allocate
+ * one that is large enough and fill it in.
+ */
+ if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ)
+ if ((message = alloca(size)) != NULL)
+ vsnprintf(message, size, fmt, ap);
+ va_end(ap);
+
+ papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
+ "detailed-status-message", message);
+#ifdef DEBUG
+ fprintf(stderr, "detailed_error(%s)\n", message);
+#endif
+ }
+}
diff --git a/usr/src/lib/print/libpapi-dynamic/i386/Makefile b/usr/src/lib/print/libpapi-dynamic/i386/Makefile
new file mode 100644
index 0000000000..3b985583a4
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT)
diff --git a/usr/src/lib/print/libpapi-dynamic/sparc/Makefile b/usr/src/lib/print/libpapi-dynamic/sparc/Makefile
new file mode 100644
index 0000000000..3b985583a4
--- /dev/null
+++ b/usr/src/lib/print/libpapi-dynamic/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT)
diff --git a/usr/src/lib/print/libpapi-ipp/Makefile b/usr/src/lib/print/libpapi-ipp/Makefile
new file mode 100644
index 0000000000..b92d620b10
--- /dev/null
+++ b/usr/src/lib/print/libpapi-ipp/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../../Makefile.lib
+
+#HDRS = papi.h
+#HDRDIR = common
+SUBDIRS = $(MACH)
+#$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all clean clobber install: .WAIT $(SUBDIRS)
+
+lint: # $(SUBDIRS)
+
+install_h: # $(ROOTHDRS)
+
+check: # $(CHECKHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/print/libpapi-ipp/Makefile.com b/usr/src/lib/print/libpapi-ipp/Makefile.com
new file mode 100644
index 0000000000..12c748773d
--- /dev/null
+++ b/usr/src/lib/print/libpapi-ipp/Makefile.com
@@ -0,0 +1,71 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = psm-ipp.a
+VERS = .1
+OBJECTS = ipp-support.o job.o printer.o service.o
+ROOTLIBDIR = $(ROOT)/usr/lib/print
+
+include ../../../Makefile.lib
+include ../../../Makefile.rootfs
+
+ROOTLIBDIR= $(ROOT)/usr/lib/print
+ROOTLIBDIR64= $(ROOT)/usr/lib/print/$(MACH)
+
+EXTRALINKS= $(ROOTLIBDIR)/psm-http.so
+$(EXTRALINKS): $(ROOTLINKS)
+ $(RM) $@; $(SYMLINK) $(LIBLINKS) $@
+
+LIBS = $(DYNLIB)
+
+SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c)
+
+$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+MAPFILE = $(SRCDIR)/mapfile
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -I$(SRCDIR)
+CPPFLAGS += -I../../libpapi-common/common
+CPPFLAGS += -I../../libipp-core/common
+CPPFLAGS += -I../../libhttp-core/common
+DYNFLAGS += $(BDIRECT) -M $(MAPFILE)
+LDLIBS += -L$(ROOTLIBDIR) -R/usr/lib/print -lhttp-core -lmd5
+LDLIBS += -lipp-core -lc
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+$(ROOTLIBDIR):
+ $(INS.dir)
+
+include ../../../Makefile.targ
diff --git a/usr/src/lib/print/libpapi-ipp/common/ipp-support.c b/usr/src/lib/print/libpapi-ipp/common/ipp-support.c
new file mode 100644
index 0000000000..f0f6ced38d
--- /dev/null
+++ b/usr/src/lib/print/libpapi-ipp/common/ipp-support.c
@@ -0,0 +1,612 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: ipp-support.c 148 2006-04-25 16:54:17Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <papi_impl.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <locale.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <md5.h>
+
+#include <config-site.h>
+
+papi_status_t
+http_to_papi_status(http_status_t status)
+{
+ switch (status) {
+ case HTTP_OK:
+ return (PAPI_OK);
+ case HTTP_BAD_REQUEST:
+ return (PAPI_BAD_REQUEST);
+ case HTTP_UNAUTHORIZED:
+ case HTTP_FORBIDDEN:
+ return (PAPI_NOT_AUTHORIZED);
+ case HTTP_NOT_FOUND:
+ return (PAPI_NOT_FOUND);
+ case HTTP_GONE:
+ return (PAPI_GONE);
+ case HTTP_SERVICE_UNAVAILABLE:
+ return (PAPI_SERVICE_UNAVAILABLE);
+ default:
+ return ((papi_status_t)status);
+ }
+}
+
+papi_status_t
+ipp_to_papi_status(uint16_t status)
+{
+ switch (status) {
+ case IPP_OK:
+ return (PAPI_OK);
+ case IPP_OK_IGNORED_ATTRIBUTES:
+ return (PAPI_OK);
+ case IPP_OK_CONFLICTING_ATTRIBUTES:
+ return (PAPI_OK);
+ case IPP_OK_IGNORED_SUBSCRIPTIONS:
+ return (PAPI_OK_IGNORED_SUBSCRIPTIONS);
+ case IPP_OK_IGNORED_NOTIFICATIONS:
+ return (PAPI_OK_IGNORED_NOTIFICATIONS);
+ case IPP_CERR_BAD_REQUEST:
+ return (PAPI_BAD_REQUEST);
+ case IPP_CERR_FORBIDDEN:
+ return (PAPI_FORBIDDEN);
+ case IPP_CERR_NOT_AUTHENTICATED:
+ return (PAPI_NOT_AUTHENTICATED);
+ case IPP_CERR_NOT_AUTHORIZED:
+ return (PAPI_NOT_AUTHORIZED);
+ case IPP_CERR_NOT_POSSIBLE:
+ return (PAPI_NOT_POSSIBLE);
+ case IPP_CERR_TIMEOUT:
+ return (PAPI_TIMEOUT);
+ case IPP_CERR_NOT_FOUND:
+ return (PAPI_NOT_FOUND);
+ case IPP_CERR_GONE:
+ return (PAPI_GONE);
+ case IPP_CERR_REQUEST_ENTITY:
+ return (PAPI_REQUEST_ENTITY);
+ case IPP_CERR_REQUEST_VALUE:
+ return (PAPI_REQUEST_VALUE);
+ case IPP_CERR_DOCUMENT_FORMAT:
+ return (PAPI_DOCUMENT_FORMAT);
+ case IPP_CERR_ATTRIBUTES:
+ return (PAPI_ATTRIBUTES);
+ case IPP_CERR_URI_SCHEME:
+ return (PAPI_URI_SCHEME);
+ case IPP_CERR_CHARSET:
+ return (PAPI_CHARSET);
+ case IPP_CERR_CONFLICT:
+ return (PAPI_CONFLICT);
+ case IPP_CERR_COMPRESSION_NOT_SUPPORTED:
+ return (PAPI_COMPRESSION_NOT_SUPPORTED);
+ case IPP_CERR_COMPRESSION_ERROR:
+ return (PAPI_COMPRESSION_ERROR);
+ case IPP_CERR_DOCUMENT_FORMAT_ERROR:
+ return (PAPI_DOCUMENT_FORMAT_ERROR);
+ case IPP_CERR_DOCUMENT_ACCESS_ERROR:
+ return (PAPI_DOCUMENT_ACCESS_ERROR);
+ case IPP_CERR_ATTRIBUTES_NOT_SETTABLE:
+ return (PAPI_ATTRIBUTES_NOT_SETTABLE);
+ case IPP_CERR_IGNORED_ALL_SUBSCRIPTIONS:
+ return (PAPI_IGNORED_ALL_SUBSCRIPTIONS);
+ case IPP_CERR_TOO_MANY_SUBSCRIPTIONS:
+ return (PAPI_TOO_MANY_SUBSCRIPTIONS);
+ case IPP_CERR_IGNORED_ALL_NOTIFICATIONS:
+ return (PAPI_IGNORED_ALL_NOTIFICATIONS);
+ case IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND:
+ return (PAPI_PRINT_SUPPORT_FILE_NOT_FOUND);
+ case IPP_SERR_INTERNAL:
+ return (PAPI_INTERNAL_ERROR);
+ case IPP_SERR_OPERATION_NOT_SUPPORTED:
+ return (PAPI_OPERATION_NOT_SUPPORTED);
+ case IPP_SERR_SERVICE_UNAVAILABLE:
+ return (PAPI_SERVICE_UNAVAILABLE);
+ case IPP_SERR_VERSION_NOT_SUPPORTED:
+ return (PAPI_VERSION_NOT_SUPPORTED);
+ case IPP_SERR_DEVICE_ERROR:
+ return (PAPI_DEVICE_ERROR);
+ case IPP_SERR_TEMPORARY_ERROR:
+ return (PAPI_TEMPORARY_ERROR);
+ case IPP_SERR_NOT_ACCEPTING:
+ return (PAPI_NOT_ACCEPTING);
+ case IPP_SERR_BUSY:
+ case IPP_SERR_CANCELLED:
+ default:
+ return (PAPI_TEMPORARY_ERROR);
+ }
+}
+
+void
+ipp_initialize_request(service_t *svc, papi_attribute_t ***request,
+ uint16_t operation)
+{
+ papiAttributeListAddInteger(request, PAPI_ATTR_EXCL,
+ "version-major", 1);
+ papiAttributeListAddInteger(request, PAPI_ATTR_EXCL,
+ "version-minor", 1);
+ papiAttributeListAddInteger(request, PAPI_ATTR_EXCL,
+ "request-id", (short)lrand48());
+ papiAttributeListAddInteger(request, PAPI_ATTR_EXCL,
+ "operation-id", operation);
+}
+
+void
+ipp_initialize_operational_attributes(service_t *svc, papi_attribute_t ***op,
+ papi_attribute_t **attributes)
+{
+ char *charset = "utf-8"; /* default to UTF-8 encoding */
+ char *language = setlocale(LC_ALL, "");
+ char *user = "nobody";
+ struct passwd *pw = NULL;
+
+ /*
+ * All IPP requests must contain the following:
+ * attributes-charset (UTF-8)
+ * attributes-natural-language (our current locale)
+ * requesting-user-name (process user)
+ */
+ papiAttributeListGetString(attributes, NULL,
+ "attributes-charset", &charset);
+ papiAttributeListAddString(op, PAPI_ATTR_EXCL,
+ "attributes-charset", charset);
+
+ papiAttributeListGetString(attributes, NULL,
+ "attributes-natural-language", &language);
+ papiAttributeListAddString(op, PAPI_ATTR_EXCL,
+ "attributes-natural-language", language);
+
+ if ((pw = getpwuid(getuid())) != NULL)
+ user = pw->pw_name;
+ /*
+ * if our euid is 0 "super user", we will allow the system supplied
+ * user name to be overridden, if the requestor wants to.
+ */
+ if (geteuid() == 0) {
+ if (svc->user != NULL)
+ user = svc->user;
+ papiAttributeListGetString(attributes, NULL,
+ "requesting-user-name", &user);
+ }
+ papiAttributeListAddString(op, PAPI_ATTR_REPLACE,
+ "requesting-user-name", user);
+}
+
+#ifndef OPID_CUPS_GET_DEFAULT /* for servers that will enumerate */
+#define OPID_CUPS_GET_DEFAULT 0x4001
+#endif /* OPID_CUPS_GET_DEFAULT */
+
+static papi_status_t
+_default_destination(service_t *svc, char **uri)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ printer_t *p = NULL;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+ char *tmp = NULL;
+
+ if ((svc == NULL) || (uri == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* we must be connected to find the default destination */
+ if (svc->connection == NULL)
+ return (PAPI_NOT_POSSIBLE);
+
+ if ((p = calloc(1, sizeof (*p))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ ipp_initialize_request(svc, &request, OPID_CUPS_GET_DEFAULT);
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
+ "requested-attributes", "printer-uri-supported");
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+
+ op = NULL;
+ papiAttributeListGetCollection(response, NULL,
+ "printer-attributes-group", &op);
+
+ if (uri != NULL) {
+ char *tmp = NULL;
+
+ papiAttributeListGetString(op, NULL, "printer-uri", &tmp);
+ papiAttributeListGetString(op, NULL,
+ "printer-uri-supported", &tmp);
+ if (tmp != NULL)
+ *uri = strdup(tmp);
+ }
+
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+void
+ipp_add_printer_uri(service_t *svc, char *name, papi_attribute_t ***op)
+{
+ char *uri = name;
+ char buf[BUFSIZ];
+ uri_t *tmp = NULL;
+
+ if (strstr(name, "://") == NULL) { /* not in URI form */
+ if (strcmp(name, DEFAULT_DEST) != 0) {
+ /* not the "default" */
+ snprintf(buf, sizeof (buf), "%s/%s", svc->name, name);
+ uri = buf;
+ } else
+ _default_destination(svc, &uri);
+ }
+
+ papiAttributeListAddString(op, PAPI_ATTR_EXCL, "printer-uri", uri);
+
+ /* save the printer-uri's path to be used by http POST request */
+ if ((uri_from_string(uri, &tmp) == 0) && (tmp != NULL)) {
+ if (svc->post != NULL)
+ free(svc->post);
+ svc->post = strdup(tmp->path);
+ uri_free(tmp);
+ }
+}
+
+
+/*
+ * don't actually write anything, just add to the total size and return the
+ * size of what would be written, so we can figure out how big the request
+ * is going to be.
+ */
+static ssize_t
+size_calculate(void *fd, void *buffer, size_t length)
+{
+ ssize_t *size = (ssize_t *)fd;
+
+ *size += length;
+ return (length);
+}
+
+
+static ssize_t
+build_chunk(void *fd, void *buffer, size_t length)
+{
+ char **s1 = fd;
+
+ memcpy(*s1, buffer, length);
+ *s1 = *s1 + length;
+
+ return (length);
+}
+
+ssize_t
+ipp_request_write(void *fd, void *buffer, size_t length)
+{
+ service_t *svc = (service_t *)fd;
+
+#ifdef DEBUG
+ printf("ipp_request_write(0x%8.8x, 0x%8.8x, %d)\n", fd, buffer, length);
+ httpDumpData(stdout, "ipp_request_write:", buffer, length);
+#endif
+ return (httpWrite(svc->connection, buffer, length));
+}
+
+ssize_t
+ipp_request_read(void *fd, void *buffer, size_t length)
+{
+ service_t *svc = (service_t *)fd;
+ ssize_t rc, i = length;
+ char *p = buffer;
+
+ while ((rc = httpRead(svc->connection, p, i)) != i) {
+ if (rc == 0)
+ return (rc);
+ if (rc < 0)
+ return (rc);
+ i -= rc;
+ p += rc;
+ }
+#ifdef DEBUG
+ printf("ipp_request_read(0x%8.8x, 0x%8.8x, %d) = %d\n",
+ fd, buffer, length, rc);
+ httpDumpData(stdout, "ipp_request_read:", buffer, length);
+#endif
+
+ return (length);
+}
+
+papi_status_t
+ipp_send_initial_request_block(service_t *svc, papi_attribute_t **request,
+ ssize_t file_size)
+{
+ papi_status_t result = PAPI_OK;
+ ssize_t chunk_size = 0;
+ char length[32];
+ void *chunk, *ptr;
+ http_status_t status;
+
+ /* calculate the request size */
+ (void) ipp_write_message(&size_calculate, &chunk_size, request);
+
+ /* Fill in the HTTP Header information */
+ httpClearFields(svc->connection);
+ if (svc->transfer_encoding == TRANSFER_ENCODING_CHUNKED)
+ httpSetField(svc->connection, HTTP_FIELD_TRANSFER_ENCODING,
+ "chunked");
+ else {
+ sprintf(length, "%lu", (unsigned long)(file_size + chunk_size));
+ httpSetField(svc->connection, HTTP_FIELD_CONTENT_LENGTH,
+ length);
+ }
+ httpSetField(svc->connection, HTTP_FIELD_CONTENT_TYPE,
+ "application/ipp");
+ httpSetField(svc->connection, HTTP_FIELD_AUTHORIZATION,
+ svc->connection->authstring);
+
+ /* flush any state information about this connection */
+ httpFlush(svc->connection);
+
+ /* if we have don't have a POST path, use the service uri path */
+ if (svc->post == NULL)
+ svc->post = strdup(svc->uri->path);
+ /* send the HTTP POST message for the IPP request */
+ /* if the POST fails, return the error */
+ status = httpPost(svc->connection, svc->post);
+ if (status != 0)
+ return (http_to_papi_status(status));
+
+ if (httpCheck(svc->connection) != 0) {
+ status = httpUpdate(svc->connection);
+ if (status != HTTP_OK)
+ return (http_to_papi_status(status));
+ }
+
+ /* build the request chunk */
+ chunk = ptr = calloc(1, chunk_size);
+ result = ipp_write_message(&build_chunk, &ptr, request);
+#ifdef DEBUG
+ printf("request: %d (0x%x) bytes\n", chunk_size, chunk_size);
+ httpDumpData(stdout, "request:", chunk, chunk_size);
+#endif
+
+ /* send the actual IPP request */
+ if (ipp_request_write(svc, chunk, chunk_size) != chunk_size)
+ result = PAPI_TEMPORARY_ERROR;
+ free(chunk);
+
+ if (httpCheck(svc->connection) != 0) {
+ status = httpUpdate(svc->connection);
+ if (status != HTTP_OK)
+ return (http_to_papi_status(status));
+ }
+
+ return (result);
+}
+
+static int
+setAuthString(service_t *svc)
+{
+ http_t *http;
+ char *user, *passphrase;
+ char encoded[BUFSIZ];
+
+ if ((svc == NULL) || (svc->connection == NULL) || (svc->name == NULL))
+ return (-1);
+
+ http = svc->connection;
+
+ if (svc->user == NULL) {
+ struct passwd *p;
+
+ if ((p = getpwuid(getuid())) != NULL) {
+ user = p->pw_name;
+ } else if ((user = getenv("LOGNAME")) == NULL)
+ user = getenv("USER");
+ if (user == NULL)
+ user = "nobody";
+ } else
+ user = svc->user;
+
+ /* if the passphrase is not set, use the Authentication Callback */
+ if (((svc->password == NULL) || (svc->password[0] == '\0')) &&
+ (svc->authCB != NULL))
+ (svc->authCB)(svc, svc->app_data);
+ passphrase = svc->password;
+
+ /* if there is still no passphrase, we have to fail */
+ if ((passphrase == NULL) || (passphrase[0] == '\0'))
+ return (-1);
+
+ if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE],
+ "Basic", 5) == 0) {
+ char plain[BUFSIZ];
+
+ snprintf(plain, sizeof (plain), "%s:%s", user, passphrase);
+ httpEncode64(encoded, plain);
+ snprintf(http->authstring, sizeof (http->authstring),
+ "Basic %s", encoded);
+ } else if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE],
+ "Digest", 6) == 0) {
+ char realm[HTTP_MAX_VALUE];
+ char nonce[HTTP_MAX_VALUE];
+ char line [BUFSIZ];
+ char urp[128];
+ char mr[128];
+ char *uri = svc->post;
+
+ httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE,
+ "realm", realm);
+ httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE,
+ "nonce", nonce);
+
+ snprintf(line, sizeof (line), "%s:%s:%s", user, realm,
+ passphrase);
+ md5_calc(urp, line, strlen(line));
+
+ snprintf(line, sizeof (line), "POST:%s", uri);
+ md5_calc(mr, line, strlen(line));
+
+ snprintf(line, sizeof (line), "%s:%s:%s", urp, mr, nonce);
+ md5_calc(encoded, line, strlen(line));
+
+ snprintf(http->authstring, sizeof (http->authstring),
+ "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", "
+ "uri=\"%s\", response=\"%s\"", user, realm, nonce, uri,
+ encoded);
+ }
+
+ return (0);
+}
+
+papi_status_t
+ipp_status_info(service_t *svc, papi_attribute_t **response)
+{
+ papi_attribute_t **operational = NULL;
+ int32_t status = 0;
+
+ papiAttributeListGetCollection(response, NULL,
+ "operational-attributes-group", &operational);
+ if (operational != NULL) {
+ char *message = NULL;
+
+ papiAttributeListGetString(response, NULL,
+ "status-message", &message);
+ papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE,
+ "detailed-status-message", message);
+ }
+ papiAttributeListGetInteger(response, NULL, "status-code", &status);
+
+ return (ipp_to_papi_status(status));
+}
+
+papi_status_t
+ipp_send_request_with_file(service_t *svc, papi_attribute_t **request,
+ papi_attribute_t ***response, char *file)
+{
+ papi_status_t result = PAPI_OK;
+ ssize_t size = 0;
+ int fd;
+
+#ifdef DEBUG
+ fprintf(stderr, "\nIPP-REQUEST: (%s)", (file ? file : ""));
+ papiAttributeListPrint(stderr, request, " ");
+ putc('\n', stderr);
+ fflush(stderr);
+#endif
+
+ /*
+ * if we are sending a file, open it and include it's size in the
+ * message size.
+ */
+ if (file != NULL) {
+ if ((fd = open(file, O_RDONLY)) < 0) {
+ detailed_error(svc, "%s: %s", file, strerror(errno));
+ return (PAPI_DOCUMENT_ACCESS_ERROR);
+ } else if (svc->transfer_encoding !=
+ TRANSFER_ENCODING_CHUNKED) {
+ struct stat st;
+
+ if (fstat(fd, &st) >= 0)
+ size = st.st_size;
+ }
+ }
+
+ *response = NULL;
+ while (*response == NULL) {
+ http_status_t status = HTTP_CONTINUE;
+
+ result = ipp_send_initial_request_block(svc, request, size);
+
+ if (result == PAPI_OK) {
+ if (file != NULL) {
+ /* send the file contents if we have it */
+ int rc;
+ char buf[BUFSIZ];
+
+ lseek(fd, 0L, SEEK_SET);
+ while ((rc = read(fd, buf, sizeof (buf))) > 0) {
+ if (ipp_request_write(svc, buf, rc)
+ < rc) {
+ break;
+ }
+ }
+ }
+
+ (void) ipp_request_write(svc, "", 0);
+ }
+
+ /* update our connection info */
+ while (status == HTTP_CONTINUE)
+ status = httpUpdate(svc->connection);
+
+ if (status == HTTP_UNAUTHORIZED) {
+ httpFlush(svc->connection);
+ if ((svc->connection->authstring[0] == '\0') &&
+ (setAuthString(svc) == 0)) {
+ httpReconnect(svc->connection);
+ continue;
+ }
+ } else if (status == HTTP_UPGRADE_REQUIRED) {
+ /*
+ * If the transport was built with TLS support, we can
+ * try to use it.
+ */
+ httpFlush(svc->connection);
+ httpReconnect(svc->connection);
+ httpEncryption(svc->connection, HTTP_ENCRYPT_REQUIRED);
+ continue;
+ }
+
+ if (status != HTTP_OK)
+ return (http_to_papi_status(status));
+
+ /* read the IPP response */
+ result = ipp_read_message(&ipp_request_read, svc, response,
+ IPP_TYPE_RESPONSE);
+
+ if (result == PAPI_OK)
+ result = ipp_status_info(svc, *response);
+#ifdef DEBUG
+ fprintf(stderr, "\nIPP-RESPONSE: (%s) (%s)", (file ? file : ""),
+ papiStatusString(result));
+ papiAttributeListPrint(stderr, *response, " ");
+ putc('\n', stderr);
+ fflush(stderr);
+#endif
+ }
+
+ return (result);
+}
+
+papi_status_t
+ipp_send_request(service_t *svc, papi_attribute_t **request,
+ papi_attribute_t ***response)
+{
+ return (ipp_send_request_with_file(svc, request, response, NULL));
+}
diff --git a/usr/src/lib/print/libpapi-ipp/common/job.c b/usr/src/lib/print/libpapi-ipp/common/job.c
new file mode 100644
index 0000000000..3db5e269e2
--- /dev/null
+++ b/usr/src/lib/print/libpapi-ipp/common/job.c
@@ -0,0 +1,627 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: job.c 148 2006-04-25 16:54:17Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <papi_impl.h>
+
+#ifndef OPID_CUPS_MOVE_JOB
+#define OPID_CUPS_MOVE_JOB 0x400D
+#endif
+
+void
+papiJobFree(papi_job_t job)
+{
+ job_t *tmp = (job_t *)job;
+
+ if (tmp != NULL) {
+ if (tmp->attributes != NULL)
+ papiAttributeListFree(tmp->attributes);
+ free(tmp);
+ }
+}
+
+void
+papiJobListFree(papi_job_t *jobs)
+{
+ if (jobs != NULL) {
+ int i;
+
+ for (i = 0; jobs[i] != NULL; i++)
+ papiJobFree(jobs[i]);
+ free(jobs);
+ }
+}
+
+papi_attribute_t **
+papiJobGetAttributeList(papi_job_t job)
+{
+ papi_attribute_t **result = NULL;
+ job_t *j = job;
+
+ if (j != NULL)
+ result = j->attributes;
+
+ return (result);
+}
+
+char *
+papiJobGetPrinterName(papi_job_t job)
+{
+ char *result = NULL;
+ job_t *j = job;
+
+ if (j != NULL)
+ (void) papiAttributeListGetString(j->attributes, NULL,
+ "printer-name", &result);
+
+ return (result);
+}
+
+int32_t
+papiJobGetId(papi_job_t job)
+{
+ int32_t result = -1;
+ job_t *j = job;
+
+ if (j != NULL)
+ (void) papiAttributeListGetInteger(j->attributes, NULL,
+ "job-id", &result);
+
+ return (result);
+}
+
+papi_job_ticket_t *
+papiJobGetJobTicket(papi_job_t job)
+{
+ papi_job_ticket_t *result = NULL;
+
+ return (result);
+}
+
+static void
+populate_job_request(service_t *svc, papi_attribute_t ***request,
+ papi_attribute_t **attributes, char *printer, uint16_t type)
+{
+ papi_attribute_t **operational = NULL, **job = NULL;
+ static char *operational_names[] = {
+ "job-name", "ipp-attribute-fidelity", "document-name",
+ "compression", "document-format", "document-natural-language",
+ "job-k-octets", "job-impressions", "job-media-sheets", NULL
+ };
+
+ /* create the base IPP request */
+ ipp_initialize_request(svc, request, type);
+
+ /* create an operational attributes group */
+ ipp_initialize_operational_attributes(svc, &operational, NULL);
+ ipp_add_printer_uri(svc, printer, &operational);
+
+ /* split up the attributes into operational and job attributes */
+ split_and_copy_attributes(operational_names, attributes,
+ &operational, &job);
+
+ /* add the operational attributes group to the request */
+ papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", operational);
+ papiAttributeListFree(operational);
+
+ /* add the job attributes group to the request */
+ if (job != NULL) {
+ papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE,
+ "job-attributes-group", job);
+ papiAttributeListFree(job);
+ }
+}
+
+static papi_status_t
+send_document_uri(service_t *svc, char *file, papi_attribute_t **attributes,
+ char *printer, int32_t id, char last, uint16_t type)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+
+ /* create the base IPP request */
+ ipp_initialize_request(svc, &request, type);
+
+ /* create an operational attributes group */
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ ipp_add_printer_uri(svc, printer, &op);
+
+ papiAttributeListAddInteger(&op, PAPI_ATTR_REPLACE, "job-id",
+ id);
+ papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, "document-name",
+ file);
+ papiAttributeListAddBoolean(&op, PAPI_ATTR_REPLACE, "last-document",
+ (last ? PAPI_TRUE : PAPI_FALSE));
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+
+ /* send the IPP request to the server */
+ result = ipp_send_request_with_file(svc, request, &response, file);
+ papiAttributeListFree(request);
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+typedef enum {_WITH_DATA, _BY_REFERENCE, _VALIDATE} call_type_t;
+
+papi_status_t
+internal_job_submit(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket,
+ char **files, papi_job_t *job,
+ call_type_t call_type)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ job_t *j = NULL;
+ int i;
+ uint16_t req_type = OPID_PRINT_JOB;
+ uint16_t data_type = OPID_SEND_DOCUMENT;
+ papi_attribute_t **request = NULL, **response = NULL;
+
+ if ((svc == NULL) || (printer == NULL) || (job == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ switch (call_type) {
+ case _BY_REFERENCE:
+#ifdef SOME_DAY_WE_WILL_BE_ABLE_TO_USE_URIS_FOR_JOB_DATA
+ /*
+ * For the time being, this is disabled. There are a number
+ * of issues to be dealt with before we can send a URI
+ * across the network to the server. For example, the file
+ * name(s) passed in are most likely relative to the current
+ * hosts filesystem. They also most likely will require some
+ * form of authentication information to be passed with the
+ * URI.
+ */
+ req_type = OPID_PRINT_URI;
+ req_type = OPID_SEND_URI;
+#endif
+ /* fall-through */
+ case _WITH_DATA:
+ if ((files == NULL) || (files[0] == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if (files[1] != NULL) /* more than 1 file */
+ req_type = OPID_CREATE_JOB;
+
+ break;
+ case _VALIDATE:
+ req_type = OPID_VALIDATE_JOB;
+ /* if we have files, validate access to them */
+ if (files != NULL) {
+ for (i = 0; files[i] != NULL; i++)
+ if (access(files[i], R_OK) < 0) {
+ detailed_error(svc, "%s: %s", files[i],
+ strerror(errno));
+ return (PAPI_DOCUMENT_ACCESS_ERROR);
+ }
+ files = NULL;
+ }
+ break;
+ }
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ if ((*job = j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ /* create IPP request */
+ populate_job_request(svc, &request, job_attributes, printer, req_type);
+
+ switch (req_type) {
+ case OPID_PRINT_JOB:
+ result = ipp_send_request_with_file(svc, request, &response,
+ files[0]);
+ break;
+ case OPID_CREATE_JOB:
+ case OPID_VALIDATE_JOB:
+ case OPID_PRINT_URI:
+ result = ipp_send_request(svc, request, &response);
+ break;
+ }
+ papiAttributeListFree(request);
+
+ if (result == PAPI_OK) {
+ papi_attribute_t **op = NULL;
+
+ /* retrieve the job attributes */
+ papiAttributeListGetCollection(response, NULL,
+ "job-attributes-group", &op);
+ copy_attributes(&j->attributes, op);
+
+ if (req_type == OPID_CREATE_JOB) {
+ int32_t id = 0;
+
+ papiAttributeListGetInteger(j->attributes, NULL,
+ "job-id", &id);
+ /* send each document */
+ for (i = 0; ((result == PAPI_OK) && (files[i] != NULL));
+ i++)
+ result = send_document_uri(svc, files[i],
+ job_attributes,
+ printer, id, (files[i+1]?0:1),
+ data_type);
+ }
+ }
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+papi_status_t
+papiJobSubmit(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
+{
+ return (internal_job_submit(handle, printer, job_attributes,
+ job_ticket, files, job, _WITH_DATA));
+}
+
+papi_status_t
+papiJobSubmitByReference(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
+{
+ return (internal_job_submit(handle, printer, job_attributes,
+ job_ticket, files, job, _BY_REFERENCE));
+}
+
+papi_status_t
+papiJobValidate(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
+{
+ return (internal_job_submit(handle, printer, job_attributes,
+ job_ticket, files, job, _VALIDATE));
+}
+
+papi_status_t
+papiJobStreamOpen(papi_service_t handle, char *printer,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, papi_stream_t *stream)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ papi_attribute_t **request = NULL;
+ service_t *svc = handle;
+
+ if ((svc == NULL) || (printer == NULL) || (stream == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ /* create job request */
+ populate_job_request(svc, &request, job_attributes, printer,
+ OPID_PRINT_JOB);
+
+ *stream = svc->connection;
+
+ result = ipp_send_initial_request_block(svc, request, 0);
+ papiAttributeListFree(request);
+
+ return (result);
+}
+
+papi_status_t
+papiJobStreamWrite(papi_service_t handle,
+ papi_stream_t stream, void *buffer, size_t buflen)
+{
+ papi_status_t result = PAPI_OK;
+ service_t *svc = handle;
+ size_t rc;
+
+#ifdef DEBUG
+ printf("papiJobStreamWrite(0x%8.8x, 0x%8.8x, 0x%8.8x, %d)\n",
+ handle, stream, buffer, buflen);
+ httpDumpData(stdout, "papiJobStreamWrite:", buffer, buflen);
+#endif
+
+ if ((svc == NULL) || (stream == NULL) || (buffer == NULL) ||
+ (buflen == 0))
+ return (PAPI_BAD_ARGUMENT);
+
+ while ((result == PAPI_OK) && (buflen > 0)) {
+ rc = ipp_request_write(svc, buffer, buflen);
+ if (rc < 0)
+ result = PAPI_TEMPORARY_ERROR;
+ else {
+ buffer = (char *)buffer + rc;
+ buflen -= rc;
+ }
+ }
+
+#ifdef DEBUG
+ printf("papiJobStreamWrite(): %s\n", papiStatusString(result));
+#endif
+
+ return (result);
+}
+
+papi_status_t
+papiJobStreamClose(papi_service_t handle,
+ papi_stream_t stream, papi_job_t *job)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ http_status_t status = HTTP_CONTINUE;
+ service_t *svc = handle;
+ papi_attribute_t **response = NULL;
+ job_t *j = NULL;
+
+ if ((svc == NULL) || (stream == NULL) || (job == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((*job = j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ (void) ipp_request_write(svc, "", 0);
+
+ /* update our connection info */
+ while (status == HTTP_CONTINUE)
+ status = httpUpdate(svc->connection);
+
+ if (status != HTTP_OK)
+ return (http_to_papi_status(status));
+ httpWait(svc->connection, 1000);
+
+ /* read the IPP response */
+ result = ipp_read_message(&ipp_request_read, svc, &response,
+ IPP_TYPE_RESPONSE);
+ if (result == PAPI_OK)
+ result = ipp_status_info(svc, response);
+
+ if (result == PAPI_OK) {
+ papi_attribute_t **op = NULL;
+
+ papiAttributeListGetCollection(response, NULL,
+ "job-attributes-group", &op);
+ copy_attributes(&j->attributes, op);
+ }
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+papi_status_t
+papiJobQuery(papi_service_t handle, char *printer, int32_t job_id,
+ char **requested_attrs,
+ papi_job_t *job)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ job_t *j = NULL;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+
+ if ((svc == NULL) || (printer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ if ((*job = j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ ipp_initialize_request(svc, &request, OPID_GET_JOB_ATTRIBUTES);
+
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ ipp_add_printer_uri(svc, printer, &op);
+
+ papiAttributeListAddInteger(&op, PAPI_ATTR_REPLACE, "job-id", job_id);
+ if (requested_attrs != NULL) {
+ int i;
+
+ for (i = 0; requested_attrs[i] != NULL; i++)
+ papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
+ "requested-attributes", requested_attrs[i]);
+ }
+
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+
+ op = NULL;
+ papiAttributeListGetCollection(response, NULL,
+ "job-attributes-group", &op);
+ copy_attributes(&j->attributes, op);
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+/* papiJob{Cancel|Hold|Release|Restart|Promote} are all the same */
+static papi_status_t
+_job_cancel_hold_release_restart_promote(papi_service_t handle,
+ char *printer, int32_t job_id, uint16_t type)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+
+ if ((svc == NULL) || (printer == NULL) || (job_id < 0))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ ipp_initialize_request(svc, &request, type);
+
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ ipp_add_printer_uri(svc, printer, &op);
+
+ papiAttributeListAddInteger(&op, PAPI_ATTR_REPLACE, "job-id", job_id);
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+papi_status_t
+papiJobCancel(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_job_cancel_hold_release_restart_promote(handle, printer,
+ job_id, OPID_CANCEL_JOB));
+}
+
+
+papi_status_t
+papiJobHold(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_job_cancel_hold_release_restart_promote(handle, printer,
+ job_id, OPID_HOLD_JOB));
+}
+
+papi_status_t
+papiJobRelease(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_job_cancel_hold_release_restart_promote(handle, printer,
+ job_id, OPID_RELEASE_JOB));
+}
+
+papi_status_t
+papiJobRestart(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_job_cancel_hold_release_restart_promote(handle, printer,
+ job_id, OPID_RESTART_JOB));
+}
+
+papi_status_t
+papiJobPromote(papi_service_t handle, char *printer, int32_t job_id)
+{
+ return (_job_cancel_hold_release_restart_promote(handle, printer,
+ job_id, OPID_PROMOTE_JOB));
+}
+
+papi_status_t
+papiJobMove(papi_service_t handle, char *printer, int32_t job_id,
+ char *destination)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+
+ if ((svc == NULL) || (printer == NULL) || (job_id < 0) ||
+ (destination == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ ipp_initialize_request(svc, &request, OPID_CUPS_MOVE_JOB);
+
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ ipp_add_printer_uri(svc, printer, &op);
+
+ papiAttributeListAddInteger(&op, PAPI_ATTR_REPLACE, "job-id", job_id);
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+
+ op = NULL;
+ papiAttributeListAddString(&op, PAPI_ATTR_EXCL,
+ "job-printer-uri", destination);
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "job-attributes-group", op);
+ papiAttributeListFree(op);
+
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+papi_status_t
+papiJobModify(papi_service_t handle, char *printer, int32_t job_id,
+ papi_attribute_t **attributes, papi_job_t *job)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+ job_t *j = NULL;
+
+ if ((svc == NULL) || (printer == NULL) || (job_id < 0) ||
+ (attributes == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((*job = j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, printer)) != PAPI_OK)
+ return (result);
+
+ ipp_initialize_request(svc, &request, OPID_SET_JOB_ATTRIBUTES);
+
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ ipp_add_printer_uri(svc, printer, &op);
+
+ papiAttributeListAddInteger(&op, PAPI_ATTR_REPLACE, "job-id", job_id);
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "job-attributes-group", attributes);
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+
+ op = NULL;
+ papiAttributeListGetCollection(response, NULL,
+ "job-attributes-group", &op);
+ copy_attributes(&j->attributes, op);
+ papiAttributeListFree(response);
+
+ return (result);
+}
diff --git a/usr/src/lib/print/libpapi-ipp/common/mapfile b/usr/src/lib/print/libpapi-ipp/common/mapfile
new file mode 100644
index 0000000000..ca9a53f0a4
--- /dev/null
+++ b/usr/src/lib/print/libpapi-ipp/common/mapfile
@@ -0,0 +1,150 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# Common interfaces that are most likely to be shared amongst the various
+# PAPI implementations.
+#
+
+SUNW_1.0 {
+ global:
+ # PAPI Attribute Calls
+ papiAttributeListAddValue = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddBoolean = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddCollection = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddDatetime = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddInteger = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddMetadata = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddRange = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddResolution = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListDelete = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetValue = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetNext = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFind = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetBoolean = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetCollection = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetDatetime = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetInteger = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetMetadata = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetRange = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetResolution = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFromString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListToString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFree = FUNCTION FILTER libpapi-common.so ;
+
+ # PAPI Service Calls
+ papiServiceCreate ;
+ papiServiceDestroy ;
+ papiServiceSetUserName ;
+ papiServiceSetPassword ;
+ papiServiceSetEncryption ;
+ papiServiceSetAuthCB ;
+ papiServiceSetAppData ;
+ papiServiceGetUserName ;
+ papiServiceGetPassword ;
+ papiServiceGetEncryption ;
+ papiServiceGetAppData ;
+ papiServiceGetServiceName ;
+ papiServiceGetAttributeList ;
+ papiServiceGetStatusMessage ;
+
+ # PAPI Printer Calls
+ papiPrintersList ;
+ papiPrinterQuery ;
+ papiPrinterAdd ;
+ papiPrinterModify ;
+ papiPrinterRemove ;
+ papiPrinterDisable ;
+ papiPrinterEnable ;
+ papiPrinterPause ;
+ papiPrinterResume ;
+ papiPrinterPurgeJobs ;
+ papiPrinterListJobs ;
+ papiPrinterGetAttributeList ;
+ papiPrinterFree ;
+ papiPrinterListFree ;
+
+ # PAPI Job Calls
+ papiJobSubmit ;
+ papiJobSubmitByReference ;
+ papiJobValidate ;
+ papiJobStreamOpen ;
+ papiJobStreamWrite ;
+ papiJobStreamClose ;
+ papiJobQuery ;
+ papiJobModify ;
+ papiJobMove ;
+ papiJobCancel ;
+ papiJobHold ;
+ papiJobRelease ;
+ papiJobRestart ;
+ papiJobPromote ;
+ papiJobGetAttributeList ;
+ papiJobGetPrinterName ;
+ papiJobGetId ;
+ papiJobGetJobTicket ;
+ papiJobFree ;
+ papiJobListFree ;
+
+ # Misc. PAPI Calls
+ papiStatusString = FUNCTION FILTER libpapi-common.so ;
+ papiLibrarySupportedCall = FUNCTION FILTER libpapi-common.so ;
+ papiLibrarySupportedCalls = FUNCTION FILTER libpapi-common.so ;
+};
+
+SUNWprivate_1.0 {
+ global:
+ papiServiceSetPeer = FUNCTION FILTER libpapi-common.so ;
+ papiJobCreate = FUNCTION FILTER libpapi-common.so ;
+ papiJobStreamAdd = FUNCTION FILTER libpapi-common.so ;
+ papiJobCommit = FUNCTION FILTER libpapi-common.so ;
+
+ # Misc. supporting calls
+ # URI
+ uri_from_string = FUNCTION FILTER libpapi-common.so ;
+ uri_to_string = FUNCTION FILTER libpapi-common.so ;
+ uri_free = FUNCTION FILTER libpapi-common.so ;
+ # list
+ list_remove = FUNCTION FILTER libpapi-common.so ;
+ list_append = FUNCTION FILTER libpapi-common.so ;
+ list_concatenate = FUNCTION FILTER libpapi-common.so ;
+
+ # extra Attribute Calls
+ copy_attributes = FUNCTION FILTER libpapi-common.so ;
+ split_and_copy_attributes = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListPrint = FUNCTION FILTER libpapi-common.so ;
+
+ local:
+ * ;
+} ;
diff --git a/usr/src/lib/print/libpapi-ipp/common/papi_impl.h b/usr/src/lib/print/libpapi-ipp/common/papi_impl.h
new file mode 100644
index 0000000000..ec298b291e
--- /dev/null
+++ b/usr/src/lib/print/libpapi-ipp/common/papi_impl.h
@@ -0,0 +1,114 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#ifndef _PAPI_IMPL_H
+#define _PAPI_IMPL_H
+
+/* $Id: papi_impl.h 161 2006-05-03 04:32:59Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <papi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <uri.h>
+
+#include <http.h>
+#include <ipp.h>
+
+/*
+ * Implementation specific types/prototypes/definitions follow
+ *
+ *
+ * Ex:
+ */
+typedef enum {
+ TRANSFER_ENCODING_CHUNKED,
+ TRANSFER_ENCODING_LENGTH
+} http_transfer_encoding_t;
+
+typedef struct {
+ papi_attribute_t **attributes;
+ char *name;
+ char *user;
+ char *password;
+ int (*authCB)(papi_service_t svc, void *app_data);
+ papi_encryption_t encryption;
+ void *app_data;
+ uri_t *uri;
+ char *post;
+ http_t *connection;
+ http_transfer_encoding_t transfer_encoding;
+} service_t;
+
+typedef struct job {
+ papi_attribute_t **attributes;
+} job_t;
+
+typedef struct {
+ papi_attribute_t **attributes;
+} printer_t;
+
+/* IPP glue interfaces */
+extern ssize_t ipp_request_read(void *fd, void *buffer, size_t length);
+extern ssize_t ipp_request_write(void *fd, void *buffer, size_t length);
+extern papi_status_t ipp_send_request(service_t *svc,
+ papi_attribute_t **request,
+ papi_attribute_t ***response);
+extern papi_status_t ipp_send_request_with_file(service_t *svc,
+ papi_attribute_t **request,
+ papi_attribute_t ***response, char *file);
+extern papi_status_t ipp_send_initial_request_block(service_t *svc,
+ papi_attribute_t **request, ssize_t file_size);
+extern papi_status_t ipp_status_info(service_t *svc,
+ papi_attribute_t **response);
+extern void ipp_initialize_request(service_t *svc,
+ papi_attribute_t ***request, uint16_t type);
+extern void ipp_initialize_operational_attributes(service_t *svc,
+ papi_attribute_t ***op,
+ papi_attribute_t **attributes);
+extern papi_status_t ipp_to_papi_status(uint16_t status);
+extern papi_status_t http_to_papi_status(http_status_t status);
+
+extern void ipp_add_printer_uri(service_t *svc, char *name,
+ papi_attribute_t ***op);
+
+/* service related interfaces */
+extern void detailed_error(service_t *svc, char *fmt, ...);
+extern papi_status_t service_connect(service_t *svc, char *service_name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAPI_IMPL_H */
diff --git a/usr/src/lib/print/libpapi-ipp/common/printer.c b/usr/src/lib/print/libpapi-ipp/common/printer.c
new file mode 100644
index 0000000000..051088becc
--- /dev/null
+++ b/usr/src/lib/print/libpapi-ipp/common/printer.c
@@ -0,0 +1,435 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: printer.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdlib.h>
+#include <papi_impl.h>
+
+#include <config-site.h>
+
+void
+papiPrinterFree(papi_printer_t printer)
+{
+ printer_t *tmp = printer;
+
+ if (tmp != NULL) {
+ if (tmp->attributes != NULL)
+ papiAttributeListFree(tmp->attributes);
+ free(tmp);
+ }
+}
+
+void
+papiPrinterListFree(papi_printer_t *printers)
+{
+ if (printers != NULL) {
+ int i;
+
+ for (i = 0; printers[i] != NULL; i++)
+ papiPrinterFree(printers[i]);
+ free(printers);
+ }
+}
+
+/*
+ * Enumeration of printers is not part of the IPP specification, so many
+ * servers will probably not respond back with a list of printers, but
+ * CUPS has implemented an extension to IPP to enumerate printers and
+ * classes. the Apache/mod_ipp IPP listener module available in Solaris
+ * implements this IPP extension, so CUPS and Solaris can provide this
+ * to IPP clients.
+ */
+#ifndef OPID_CUPS_GET_PRINTERS /* for servers that will enumerate */
+#define OPID_CUPS_GET_PRINTERS 0x4002
+#endif /* OPID_CUPS_GET_PRINTERS */
+#ifndef OPID_CUPS_DELETE_PRINTER /* for servers that can delete */
+#define OPID_CUPS_DELETE_PRINTER 0x4004
+#endif /* OPID_CUPS_DELETE_PRINTER */
+#ifndef OPID_CUPS_GET_CLASSES /* for servers that will enumerate */
+#define OPID_CUPS_GET_CLASSES 0x4005
+#endif /* OPID_CUPS_GET_CLASSES */
+
+papi_status_t
+papiPrintersList(papi_service_t handle, char **requested_attrs,
+ papi_filter_t *filter, papi_printer_t **printers)
+{
+ papi_status_t status, result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+ void *iter = NULL;
+
+ if ((svc == NULL) || (printers == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, DEFAULT_DEST)) != PAPI_OK)
+ return (result);
+ ipp_initialize_request(svc, &request, OPID_CUPS_GET_PRINTERS);
+
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+
+ if (requested_attrs != NULL) {
+ int i;
+
+ for (i = 0; requested_attrs[i] != NULL; i++)
+ papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
+ "requested-attributes", requested_attrs[i]);
+ }
+
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+
+ op = NULL;
+ for (status = papiAttributeListGetCollection(response, &iter,
+ "printer-attributes-group", &op);
+ status == PAPI_OK;
+ status = papiAttributeListGetCollection(response, &iter,
+ NULL, &op)) {
+ printer_t *p = NULL;
+
+ if ((p = calloc(1, sizeof (*p))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ copy_attributes(&p->attributes, op);
+ op = NULL;
+ list_append(printers, p);
+ }
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterQuery(papi_service_t handle, char *name,
+ char **requested_attrs,
+ papi_attribute_t **job_attributes,
+ papi_printer_t *printer)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ printer_t *p = NULL;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+
+ if ((svc == NULL) || (name == NULL) || (printer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ ipp_initialize_request(svc, &request, OPID_GET_PRINTER_ATTRIBUTES);
+
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ ipp_add_printer_uri(svc, name, &op);
+
+ if (requested_attrs != NULL) {
+ int i;
+
+ for (i = 0; requested_attrs[i] != NULL; i++)
+ papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
+ "requested-attributes", requested_attrs[i]);
+ }
+
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+
+ op = NULL;
+ papiAttributeListGetCollection(response, NULL,
+ "printer-attributes-group", &op);
+ copy_attributes(&p->attributes, op);
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+static papi_status_t
+_printer_enable_disable_pause_resume_delete(papi_service_t handle, char *name,
+ char *message, uint16_t type)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+
+ if ((svc == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ ipp_initialize_request(svc, &request, type);
+
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ ipp_add_printer_uri(svc, name, &op);
+
+ switch (type) {
+ case OPID_DISABLE_PRINTER:
+ papiAttributeListAddString(&op, PAPI_ATTR_REPLACE,
+ "printer-message-from-operator", message);
+ break;
+ case OPID_PAUSE_PRINTER:
+ papiAttributeListAddString(&op, PAPI_ATTR_REPLACE,
+ "printer-state-message", message);
+ break;
+ default: /* a message value is of no use */
+ break;
+ }
+
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterEnable(papi_service_t handle, char *name)
+{
+ return (_printer_enable_disable_pause_resume_delete(handle, name,
+ NULL, OPID_ENABLE_PRINTER));
+}
+
+papi_status_t
+papiPrinterResume(papi_service_t handle, char *name)
+{
+ return (_printer_enable_disable_pause_resume_delete(handle, name,
+ NULL, OPID_RESUME_PRINTER));
+}
+
+papi_status_t
+papiPrinterPause(papi_service_t handle, char *name, char *message)
+{
+ return (_printer_enable_disable_pause_resume_delete(handle, name,
+ message, OPID_PAUSE_PRINTER));
+}
+
+papi_status_t
+papiPrinterDisable(papi_service_t handle, char *name, char *message)
+{
+ return (_printer_enable_disable_pause_resume_delete(handle, name,
+ message, OPID_PAUSE_PRINTER));
+}
+
+/*
+ * there is no IPP create operation, the set-printer-attibutes operation
+ * is the closest we have, so we will assume that the server will create
+ * a printer and set attributes if there is none.
+ */
+papi_status_t
+papiPrinterAdd(papi_service_t handle, char *name,
+ papi_attribute_t **attributes, papi_printer_t *printer)
+{
+ return (papiPrinterModify(handle, name, attributes, printer));
+}
+
+papi_status_t
+papiPrinterModify(papi_service_t handle, char *name,
+ papi_attribute_t **attributes, papi_printer_t *printer)
+{
+ papi_status_t result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ printer_t *p = NULL;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+
+ if ((svc == NULL) || (name == NULL) || (printer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ ipp_initialize_request(svc, &request, OPID_SET_PRINTER_ATTRIBUTES);
+
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ ipp_add_printer_uri(svc, name, &op);
+
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "printer-attributes-group", attributes);
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+
+ op = NULL;
+ papiAttributeListGetCollection(response, NULL,
+ "printer-attributes-group", &op);
+ copy_attributes(&p->attributes, op);
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterRemove(papi_service_t handle, char *name)
+{
+ return (_printer_enable_disable_pause_resume_delete(handle, name,
+ NULL, OPID_CUPS_DELETE_PRINTER));
+}
+
+papi_status_t
+papiPrinterPurgeJobs(papi_service_t handle, char *name,
+ papi_job_t **jobs)
+{
+ papi_status_t status, result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+ void *iter = NULL;
+
+
+ if ((svc == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ ipp_initialize_request(svc, &request, OPID_PURGE_JOBS);
+
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ ipp_add_printer_uri(svc, name, &op);
+
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+
+ op = NULL;
+ for (status = papiAttributeListGetCollection(response, &iter,
+ "job-attributes-group", &op);
+ status == PAPI_OK;
+ status = papiAttributeListGetCollection(response, &iter,
+ NULL, &op)) {
+ job_t *j = NULL;
+
+ if ((j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ copy_attributes(&j->attributes, op);
+ op = NULL;
+ list_append(jobs, j);
+ }
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+papi_status_t
+papiPrinterListJobs(papi_service_t handle, char *name,
+ char **requested_attrs, int type_mask,
+ int max_num_jobs, papi_job_t **jobs)
+{
+ papi_status_t status, result = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
+ void *iter = NULL;
+
+ if ((svc == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ /* if we are already connected, use that connection. */
+ if (svc->connection == NULL)
+ if ((result = service_connect(svc, name)) != PAPI_OK)
+ return (result);
+
+ ipp_initialize_request(svc, &request, OPID_GET_JOBS);
+
+ ipp_initialize_operational_attributes(svc, &op, NULL);
+ ipp_add_printer_uri(svc, name, &op);
+
+ if (requested_attrs != NULL) {
+ int i;
+
+ for (i = 0; requested_attrs[i] != NULL; i++)
+ papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
+ "requested-attributes", requested_attrs[i]);
+ }
+
+ papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
+ "operational-attributes-group", op);
+ papiAttributeListFree(op);
+ result = ipp_send_request(svc, request, &response);
+ papiAttributeListFree(request);
+
+ op = NULL;
+ for (status = papiAttributeListGetCollection(response, &iter,
+ "job-attributes-group", &op);
+ status == PAPI_OK;
+ status = papiAttributeListGetCollection(response, &iter,
+ NULL, &op)) {
+ job_t *j = NULL;
+
+ if ((j = calloc(1, sizeof (*j))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ copy_attributes(&j->attributes, op);
+ op = NULL;
+ list_append(jobs, j);
+ }
+ papiAttributeListFree(response);
+
+ return (result);
+}
+
+papi_attribute_t **
+papiPrinterGetAttributeList(papi_printer_t printer)
+{
+ papi_attribute_t **result = NULL;
+ printer_t *p = printer;
+
+ if (p != NULL)
+ result = p->attributes;
+
+ return (result);
+}
diff --git a/usr/src/lib/print/libpapi-ipp/common/service.c b/usr/src/lib/print/libpapi-ipp/common/service.c
new file mode 100644
index 0000000000..e5531f1422
--- /dev/null
+++ b/usr/src/lib/print/libpapi-ipp/common/service.c
@@ -0,0 +1,394 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: service.c 171 2006-05-20 06:00:32Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*LINTLIBRARY*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <alloca.h>
+#include <libintl.h>
+#include <papi_impl.h>
+
+#include <config-site.h>
+
+http_encryption_t
+http_encryption_type(papi_encryption_t encryption)
+{
+ switch (encryption) {
+ case PAPI_ENCRYPT_IF_REQUESTED:
+ return (HTTP_ENCRYPT_IF_REQUESTED);
+ case PAPI_ENCRYPT_REQUIRED:
+ return (HTTP_ENCRYPT_REQUIRED);
+ case PAPI_ENCRYPT_ALWAYS:
+ return (HTTP_ENCRYPT_ALWAYS);
+ case PAPI_ENCRYPT_NEVER:
+ return (HTTP_ENCRYPT_NEVER);
+ default:
+ ; /* this should log an error */
+ }
+
+ return (HTTP_ENCRYPT_NEVER); /* should never get here */
+}
+
+papi_status_t
+service_connect(service_t *svc, char *service_name)
+{
+ papi_status_t result = PAPI_OK;
+ int port = 631;
+
+ if (svc == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ if (svc->connection != NULL) /* alread connected ? */
+ return (PAPI_OK);
+
+ if (svc->uri == NULL)
+ uri_from_string(service_name, &svc->uri);
+
+ if ((service_name != NULL) && (svc->uri == NULL)) {
+ /*
+ * a name was supplied and it's not in URI form, we will
+ * try to use a "default" IPP service under the assumption
+ * that this is most likely a short-form printer name from
+ * from a papiPrinter*() or papiJob*() call and not from a
+ * papiServiceCreate() call.
+ */
+ if ((service_name = getenv("PAPI_SERVICE_URI")) == NULL) {
+ char *cups;
+
+ if ((cups = getenv("CUPS_SERVER")) != NULL) {
+ char buf[BUFSIZ];
+
+ snprintf(buf, sizeof (buf),
+ "ipp://%s/printers/", cups);
+ service_name = strdup(buf);
+ }
+ }
+ if (service_name == NULL)
+ service_name = DEFAULT_IPP_SERVICE_URI;
+
+ uri_from_string(service_name, &svc->uri);
+ }
+
+ if (svc->uri == NULL)
+ return (PAPI_NOT_POSSIBLE);
+
+ if (svc->uri->port != NULL)
+ port = strtol(svc->uri->port, NULL, 10);
+
+ svc->connection = httpConnectEncrypt(svc->uri->host, port,
+ http_encryption_type(svc->encryption));
+ if (svc->connection == NULL) {
+ if (svc->uri != NULL) {
+ uri_free(svc->uri);
+ svc->uri = NULL;
+ }
+ result = PAPI_SERVICE_UNAVAILABLE;
+ } else if (service_name != NULL)
+ svc->name = strdup(service_name);
+
+ return (result);
+}
+
+papi_status_t
+papiServiceCreate(papi_service_t *handle, char *service_name,
+ char *user_name, char *password,
+ int (*authCB)(papi_service_t svc, void *app_data),
+ papi_encryption_t encryption, void *app_data)
+{
+ papi_status_t result = PAPI_NOT_POSSIBLE;
+ service_t *svc = NULL;
+ char *encoding = getenv("HTTP_TRANSFER_ENCODING");
+
+ if (handle == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ if (user_name != NULL)
+ svc->user = strdup(user_name);
+
+ if (password != NULL)
+ svc->password = strdup(password);
+
+ svc->encryption = encryption;
+
+ if (authCB != NULL)
+ svc->authCB = authCB;
+
+ if (app_data != NULL)
+ svc->app_data = app_data;
+
+ if ((encoding != NULL) && (strcasecmp(encoding, "content-length") == 0))
+ svc->transfer_encoding = TRANSFER_ENCODING_LENGTH;
+ else
+ svc->transfer_encoding = TRANSFER_ENCODING_CHUNKED;
+
+ if (service_name != NULL) {
+ result = service_connect(svc, service_name);
+ } else
+ result = PAPI_OK;
+
+ return (result);
+}
+
+void
+papiServiceDestroy(papi_service_t handle)
+{
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ if (svc->attributes != NULL)
+ papiAttributeListFree(svc->attributes);
+ if (svc->name != NULL)
+ free(svc->name);
+ if (svc->user != NULL)
+ free(svc->user);
+ if (svc->password != NULL)
+ free(svc->password);
+ if (svc->uri != NULL)
+ uri_free(svc->uri);
+ if (svc->post != NULL)
+ free(svc->post);
+ if (svc->connection != NULL)
+ httpClose(svc->connection);
+
+ free(handle);
+ }
+}
+
+papi_status_t
+papiServiceSetUserName(papi_service_t handle, char *user_name)
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ if (svc->user != NULL)
+ free(svc->user);
+ svc->user = NULL;
+ if (user_name != NULL)
+ svc->user = strdup(user_name);
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+papi_status_t
+papiServiceSetPassword(papi_service_t handle, char *password)
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ if (svc->password != NULL)
+ free(svc->password);
+ svc->password = NULL;
+ if (password != NULL)
+ svc->password = strdup(password);
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+papi_status_t
+papiServiceSetEncryption(papi_service_t handle,
+ papi_encryption_t encryption)
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ svc->encryption = encryption;
+ httpEncryption(svc->connection,
+ (http_encryption_t)svc->encryption);
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+papi_status_t
+papiServiceSetAuthCB(papi_service_t handle,
+ int (*authCB)(papi_service_t svc, void *app_data))
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ svc->authCB = authCB;
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+
+papi_status_t
+papiServiceSetAppData(papi_service_t handle, void *app_data)
+{
+ papi_status_t result = PAPI_OK;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ svc->app_data = (void *)app_data;
+ } else
+ result = PAPI_BAD_ARGUMENT;
+
+ return (result);
+}
+
+char *
+papiServiceGetServiceName(papi_service_t handle)
+{
+ char *result = NULL;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ result = svc->name;
+ }
+
+ return (result);
+}
+
+char *
+papiServiceGetUserName(papi_service_t handle)
+{
+ char *result = NULL;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ result = svc->user;
+ }
+
+ return (result);
+}
+
+char *
+papiServiceGetPassword(papi_service_t handle)
+{
+ char *result = NULL;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ result = svc->password;
+ }
+
+ return (result);
+}
+
+papi_encryption_t
+papiServiceGetEncryption(papi_service_t handle)
+{
+ papi_encryption_t result = PAPI_ENCRYPT_NEVER;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ result = svc->encryption;
+ }
+
+ return (result);
+}
+
+void *
+papiServiceGetAppData(papi_service_t handle)
+{
+ void *result = NULL;
+
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+ result = svc->app_data;
+ }
+
+ return (result);
+}
+
+papi_attribute_t **
+papiServiceGetAttributeList(papi_service_t handle)
+{
+ papi_attribute_t **result = NULL;
+ service_t *svc = handle;
+
+ if (handle != NULL)
+ result = svc->attributes;
+
+ return (result);
+}
+
+char *
+papiServiceGetStatusMessage(papi_service_t handle)
+{
+ char *result = NULL;
+ service_t *svc = handle;
+
+ papiAttributeListGetString(svc->attributes, NULL,
+ "detailed-status-message", &result);
+
+ return (result);
+}
+
+void
+detailed_error(service_t *svc, char *fmt, ...)
+{
+ if ((svc != NULL) && (fmt != NULL)) {
+ va_list ap;
+ size_t size;
+ char *message = alloca(BUFSIZ);
+
+ va_start(ap, fmt);
+ /*
+ * fill in the message. If the buffer is too small, allocate
+ * one that is large enough and fill it in.
+ */
+ if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ)
+ if ((message = alloca(size)) != NULL)
+ vsnprintf(message, size, fmt, ap);
+ va_end(ap);
+
+ papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
+ "detailed-status-message", message);
+ }
+}
diff --git a/usr/src/lib/print/libpapi-ipp/i386/Makefile b/usr/src/lib/print/libpapi-ipp/i386/Makefile
new file mode 100644
index 0000000000..39b4a998ec
--- /dev/null
+++ b/usr/src/lib/print/libpapi-ipp/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS)
diff --git a/usr/src/lib/print/libpapi-ipp/sparc/Makefile b/usr/src/lib/print/libpapi-ipp/sparc/Makefile
new file mode 100644
index 0000000000..39b4a998ec
--- /dev/null
+++ b/usr/src/lib/print/libpapi-ipp/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS)
diff --git a/usr/src/lib/print/libpapi-lpd/Makefile b/usr/src/lib/print/libpapi-lpd/Makefile
new file mode 100644
index 0000000000..b92d620b10
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../../Makefile.lib
+
+#HDRS = papi.h
+#HDRDIR = common
+SUBDIRS = $(MACH)
+#$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all clean clobber install: .WAIT $(SUBDIRS)
+
+lint: # $(SUBDIRS)
+
+install_h: # $(ROOTHDRS)
+
+check: # $(CHECKHDRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/print/libpapi-lpd/Makefile.com b/usr/src/lib/print/libpapi-lpd/Makefile.com
new file mode 100644
index 0000000000..eac0eddaac
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/Makefile.com
@@ -0,0 +1,99 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = psm-lpd.a
+VERS = .1
+COMMON_OBJS = lpd-misc.o
+OBJECTS = job.o library.o lpd-cancel.o lpd-job.o lpd-query.o printer.o \
+ service.o $(COMMON_OBJS)
+
+include ../../../Makefile.lib
+include ../../../Makefile.rootfs
+
+ROOTLIBDIR= $(ROOT)/usr/lib/print
+ROOTLIBDIR64= $(ROOT)/usr/lib/print/$(MACH)
+
+EXTRALINKS= $(ROOTLIBDIR)/psm-rfc-1179.so
+$(EXTRALINKS): $(ROOTLINKS)
+ $(RM) $@; $(SYMLINK) $(LIBLINKS) $@
+
+LIBS = $(DYNLIB)
+
+SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c)
+
+$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+MAPFILE = $(SRCDIR)/mapfile
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -I$(SRCDIR)
+CPPFLAGS += -I../../libpapi-common/common
+DYNFLAGS += $(BDIRECT) -M $(MAPFILE)
+LDLIBS += -lc
+
+.KEEP_STATE:
+
+all: $(LIBS) $(PROG)
+
+lint: lintcheck
+
+include ../../../Makefile.targ
+
+#
+# NEEDED to build lpd-port
+#
+PROG = lpd-port
+LPD_PORT_OBJS = lpd-port.o $(COMMON_OBJS)
+
+$(PROG) := LDLIBS += -lsocket -lnsl -lsendfile -lpapi
+
+PROG_OBJS = $(LPD_PORT_OBJS:%=pics/%)
+OBJS += $(PROG_OBJS)
+
+NX_MAP_i386= $(SRC)/cmd/mapfile_noexdata
+NX_MAP_sparc=
+NX_MAP= $(NX_MAP_$(MACH))
+NES_MAPFILE= $(SRC)/cmd/mapfile_noexstk $(NX_MAP)
+
+LDFLAGS.cmd = \
+ $(ENVLDFLAGS1) $(ENVLDFLAGS2) $(ENVLDFLAGS3) \
+ $(NES_MAPFILE:%=-M%) $(PGA_MAPFILE:%=-M%)
+
+$(PROG): $(PROG_OBJS)
+ $(LINK.c) -o $@ $(PROG_OBJS) $(LDFLAGS.cmd) $(LDLIBS)
+ $(POST_PROCESS)
+
+# needed for the 'install' phase
+ROOTLIBPRINTPROG = $(PROG:%=$(ROOTLIBDIR)/%)
+$(ROOTLIBPRINTPROG) := FILEMODE = 04511
+$(ROOTLIBPRINTPROG) := OWNER = root
+
+$(ROOTLIBDIR)/%: $(ROOTLIBDIR) %
+ $(INS.file)
+$(ROOTLIBDIR):
+ $(INS.dir)
diff --git a/usr/src/lib/print/libpapi-lpd/common/job.c b/usr/src/lib/print/libpapi-lpd/common/job.c
new file mode 100644
index 0000000000..900abb7c35
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/job.c
@@ -0,0 +1,298 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: job.c 155 2006-04-26 02:34:54Z ktou $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <limits.h>
+#include <libintl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <papi_impl.h>
+#include <uri.h>
+
+/*
+ * must copy files before leaving routine
+ */
+papi_status_t
+papiJobSubmit(papi_service_t handle, char *name, papi_attribute_t **attributes,
+ papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
+{
+ papi_status_t status = PAPI_OK;
+ service_t *svc = handle;
+ job_t *j = NULL;
+ char *metadata = NULL;
+
+ if ((svc == NULL) || (name == NULL) || (files == NULL) ||
+ (job == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if (job_ticket != NULL) {
+ detailed_error(svc,
+ gettext("papiJobSubmit: job ticket not supported"));
+ return (PAPI_OPERATION_NOT_SUPPORTED);
+ }
+
+ if ((status = service_fill_in(svc, name)) != PAPI_OK)
+ return (status);
+
+ if ((*job = j = (job_t *)calloc(1, sizeof (*j))) == NULL) {
+ detailed_error(svc,
+ gettext("calloc() failed"));
+ return (PAPI_TEMPORARY_ERROR);
+ }
+
+ /* create a control file */
+ status = lpd_job_add_attributes(svc, attributes, &metadata,
+ &j->attributes);
+ status = lpd_job_add_files(svc, attributes, files, &metadata,
+ &j->attributes);
+
+ /* send the job to the server */
+ status = lpd_submit_job(svc, metadata, &j->attributes, NULL);
+ free(metadata);
+
+ return (status);
+
+}
+
+
+papi_status_t
+papiJobSubmitByReference(papi_service_t handle, char *name,
+ papi_attribute_t **job_attributes,
+ papi_job_ticket_t *job_ticket, char **files, papi_job_t *job)
+{
+ return (papiJobSubmit(handle, name, job_attributes,
+ job_ticket, files, job));
+}
+
+papi_status_t
+papiJobStreamOpen(papi_service_t handle, char *name,
+ papi_attribute_t **attributes,
+ papi_job_ticket_t *job_ticket, papi_stream_t *stream)
+{
+ papi_status_t status = PAPI_OK;
+ service_t *svc = handle;
+ char *metadata = NULL;
+ stream_t *s = NULL;
+
+ if ((svc == NULL) || (name == NULL) || (stream == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if (job_ticket != NULL)
+ return (PAPI_OPERATION_NOT_SUPPORTED);
+
+ if ((status = service_fill_in(svc, name)) != PAPI_OK)
+ return (status);
+
+ /* create the stream container */
+ if ((*stream = s = calloc(1, sizeof (*s))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ /* create the job */
+ if ((s->job = calloc(1, sizeof (*(s->job)))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ /* process the attribute list */
+ lpd_job_add_attributes(svc, attributes, &metadata, &s->job->attributes);
+
+ /* if we can stream, do it */
+ if ((svc->uri->fragment != NULL) &&
+ (strcasecmp(svc->uri->fragment, "streaming") == 0)) {
+ char *files[] = { "standard input", NULL };
+
+ lpd_job_add_files(svc, attributes, files, &metadata,
+ &(s->job->attributes));
+ status = lpd_submit_job(svc, metadata, &(s->job->attributes),
+ &s->fd);
+ } else {
+ char dfname[18];
+
+ strcpy(dfname, "/tmp/stdin-XXXXX");
+
+ if ((s->fd = mkstemp(dfname)) >= 0)
+ s->dfname = strdup(dfname);
+ s->job->attributes = attributes;
+ }
+ s->metadata = metadata;
+
+ return (status);
+}
+
+
+papi_status_t
+papiJobStreamWrite(papi_service_t handle, papi_stream_t stream,
+ void *buffer, size_t buflen)
+{
+ service_t *svc = handle;
+ stream_t *s = stream;
+
+ if ((svc == NULL) || (stream == NULL) || (buffer == NULL) ||
+ (buflen == 0))
+ return (PAPI_BAD_ARGUMENT);
+
+ if (write(s->fd, buffer, buflen) != buflen)
+ return (PAPI_DEVICE_ERROR);
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job)
+{
+ papi_status_t status = PAPI_INTERNAL_ERROR;
+ service_t *svc = handle;
+ job_t *j = NULL;
+ stream_t *s = stream;
+ int ret;
+
+ if ((svc == NULL) || (stream == NULL) || (job == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ close(s->fd); /* close the stream */
+
+ if (s->dfname != NULL) { /* if it is a tmpfile, print it */
+ char *files[2];
+
+ files[0] = s->dfname;
+ files[1] = NULL;
+
+ lpd_job_add_files(svc, s->job->attributes, files, &s->metadata,
+ &(s->job->attributes));
+ status = lpd_submit_job(svc, s->metadata,
+ &(s->job->attributes), NULL);
+ unlink(s->dfname);
+ free(s->dfname);
+ } else
+ status = PAPI_OK;
+
+ if (s->metadata != NULL)
+ free(s->metadata);
+
+ *job = s->job;
+
+ return (status);
+}
+
+papi_status_t
+papiJobQuery(papi_service_t handle, char *name, int32_t job_id,
+ char **job_attributes, papi_job_t *job)
+{
+ papi_status_t status = PAPI_OK;
+ service_t *svc = handle;
+
+ if ((svc == NULL) || (name == NULL) || job_id < 0)
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((status = service_fill_in(svc, name)) == PAPI_OK)
+ status = lpd_find_job_info(svc, job_id, (job_t **)job);
+
+ return (status);
+}
+
+papi_status_t
+papiJobCancel(papi_service_t handle, char *name, int32_t job_id)
+{
+ papi_status_t status;
+ service_t *svc = handle;
+
+ if ((svc == NULL) || (name == NULL) || (job_id < 0))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((status = service_fill_in(svc, name)) == PAPI_OK)
+ status = lpd_cancel_job(svc, job_id);
+
+ return (status);
+}
+
+papi_attribute_t **
+papiJobGetAttributeList(papi_job_t job)
+{
+ job_t *j = (job_t *)job;
+
+ if (j != NULL)
+ return ((papi_attribute_t **)j->attributes);
+
+ return (NULL);
+}
+
+char *
+papiJobGetPrinterName(papi_job_t job)
+{
+ char *result = NULL;
+ job_t *j = (job_t *)job;
+
+ if (j != NULL)
+ papiAttributeListGetString(j->attributes, NULL,
+ "printer-name", &result);
+
+ return (result);
+}
+
+int
+papiJobGetId(papi_job_t job)
+{
+ int result = -1;
+ job_t *j = (job_t *)job;
+
+ if (j != NULL)
+ papiAttributeListGetInteger(j->attributes, NULL,
+ "job-id", &result);
+
+ return (result);
+}
+
+void
+papiJobFree(papi_job_t job)
+{
+ job_t *j = (job_t *)job;
+
+
+ if (j != NULL) {
+ papiAttributeListFree(j->attributes);
+ free(j);
+ }
+}
+
+void
+papiJobListFree(papi_job_t *jobs)
+{
+ if (jobs != NULL) {
+ int i;
+
+ for (i = 0; jobs[i] != NULL; i++)
+ papiJobFree(jobs[i]);
+ free(jobs);
+ }
+}
diff --git a/usr/src/lib/print/libpapi-lpd/common/library.c b/usr/src/lib/print/libpapi-lpd/common/library.c
new file mode 100644
index 0000000000..de38c2bbfa
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/library.c
@@ -0,0 +1,90 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: library.c 146 2006-03-24 00:26:54Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <alloca.h>
+#include <libintl.h>
+#include <papi_impl.h>
+
+static char *calls[] = {
+ /* Attribute Calls */
+ "papiAttributeListAdd",
+ "papiAttributeListAddBoolean", "papiAttributeListAddCollection",
+ "papiAttributeListAddDatetime", "papiAttributeListAddInteger",
+ "papiAttributeListAddMetadata", "papiAttributeListAddRange",
+ "papiAttributeListAddResolution", "papiAttributeListAddString",
+ "papiAttributeListDelete",
+ "papiAttributeListGetValue", "papiAttributeListGetNext",
+ "papiAttributeListFind",
+ "papiAttributeListGetBoolean", "papiAttributeListGetCollection",
+ "papiAttributeListGetDatetime", "papiAttributeListGetInteger",
+ "papiAttributeListGetMetadata", "papiAttributeListGetRange",
+ "papiAttributeListGetResolution", "papiAttributeListGetString",
+ "papiAttributeListFromString", "papiAttributeListToString",
+ "papiAttributeListFree",
+ /* Job Calls */
+ "papiJobSubmit", "papiJobSubmitByReference",
+ "papiJobStreamOpen", "papiJobStreamWrite", "papiJobStreamClose",
+ "papiJobQuery", "papiJobCancel",
+ "papiJobGetAttributeList", "papiJobGetId", "papiJobGetPrinterName",
+ "papiJobFree", "papiJobListFree",
+ /* Printer Calls */
+ "papiPrinterQuery", "papiPrinterPurgeJobs", "papiPrinterListJobs",
+ "papiPrinterGetAttributeList", "papiPrinterFree",
+ /* Service Calls */
+ "papiServiceCreate", "papiServiceDestroy",
+ "papiServiceGetStatusMessage",
+ /* Misc Calls */
+ "papiStatusString",
+ "papiLibrarySupportedCall", "papiLibrarySupportedCalls",
+ NULL
+};
+
+char **
+papiLibrarySupportedCalls()
+{
+ return (calls);
+}
+
+char
+papiLibrarySupportedCall(char *name)
+{
+ int i;
+
+ for (i = 0; calls[i] != NULL; i++)
+ if (strcmp(name, calls[i]) == 0)
+ return (PAPI_TRUE);
+
+ return (PAPI_FALSE);
+}
diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-cancel.c b/usr/src/lib/print/libpapi-lpd/common/lpd-cancel.c
new file mode 100644
index 0000000000..3f8cd7320a
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/lpd-cancel.c
@@ -0,0 +1,122 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lpd-cancel.c 155 2006-04-26 02:34:54Z ktou $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#define __EXTENSIONS__ /* for strtok_r() */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <papi_impl.h>
+
+papi_status_t
+lpd_cancel_job(service_t *svc, int id)
+{
+ papi_status_t status = PAPI_INTERNAL_ERROR;
+ int fd;
+ char **list;
+ char buf[128]; /* this should be overkill */
+
+ if (svc == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ snprintf(buf, sizeof (buf), "%d", id);
+ list[0] = buf;
+ list[1] = NULL;
+
+ if ((fd = lpd_open(svc, 'c', list, 3)) < 0)
+ return (PAPI_INTERNAL_ERROR);
+
+ memset(buf, 0, sizeof (buf));
+ if (fdgets(buf, sizeof (buf), fd) != NULL) {
+ if (buf[0] == '\0')
+ status = PAPI_NOT_FOUND;
+ else if (strstr(buf, "permission denied") != NULL)
+ status = PAPI_NOT_AUTHORIZED;
+ else if ((strstr(buf, "cancelled") != NULL) ||
+ (strstr(buf, "removed") != NULL))
+ status = PAPI_OK;
+ } else
+ status = PAPI_NOT_FOUND;
+
+ close(fd);
+
+ return (status);
+}
+
+papi_status_t
+lpd_purge_jobs(service_t *svc, job_t ***jobs)
+{
+ papi_status_t status = PAPI_INTERNAL_ERROR;
+ int fd;
+ char *queue;
+ char buf[256];
+
+ if (svc == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((fd = lpd_open(svc, 'c', NULL, 3)) < 0)
+ return (PAPI_INTERNAL_ERROR);
+
+ queue = queue_name_from_uri(svc->uri);
+
+ status = PAPI_OK;
+ memset(buf, 0, sizeof (buf));
+ while (fdgets(buf, sizeof (buf), fd) != NULL) {
+ /* if we canceled it, add it to the list */
+ if ((strstr(buf, "cancelled") != NULL) ||
+ (strstr(buf, "removed") != NULL)) {
+ job_t *job;
+ papi_attribute_t **attributes = NULL;
+ char *ptr, *iter = NULL;
+ int id;
+
+ ptr = strtok_r(buf, ":", &iter);
+ papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL,
+ "job-name", ptr);
+ id = atoi(ptr);
+ papiAttributeListAddInteger(&attributes, PAPI_ATTR_EXCL,
+ "job-id", id);
+ papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL,
+ "job-printer", queue);
+
+ if ((job = (job_t *)calloc(1, (sizeof (*job))))
+ != NULL) {
+ job->attributes = attributes;
+ list_append(jobs, job);
+ } else
+ papiAttributeListFree(attributes);
+ } else if (strstr(buf, "permission denied") != NULL)
+ status = PAPI_NOT_AUTHORIZED;
+ }
+ close(fd);
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-job.c b/usr/src/lib/print/libpapi-lpd/common/lpd-job.c
new file mode 100644
index 0000000000..3d36fef99d
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/lpd-job.c
@@ -0,0 +1,551 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lpd-job.c 157 2006-04-26 15:07:55Z ktou $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#define __EXTENSIONS__ /* for strtok_r() */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <pwd.h>
+#include <libintl.h>
+#include <papi_impl.h>
+
+enum { LPD_RFC, LPD_SVR4 };
+
+static char
+mime_type_to_rfc1179_type(char *mime)
+{
+ static struct { char *mime; char rfc; } cvt[] = {
+ { "plain/text", 'f' },
+ { "application/octet-stream", 'l' },
+ { "application/postscript", 'f' }, /* rfc incorrectly has 'o' */
+ { "application/x-pr", 'p' },
+ { "application/x-cif", 'c' },
+ { "application/x-dvi", 'd' },
+ { "application/x-fortran", 'r' },
+ { "application/x-plot", 'g' },
+ { "application/x-ditroff", 'n' },
+ { "application/x-troff", 't' },
+ { "application/x-raster", 'v' },
+ { NULL, 0}
+ };
+ char result = '\0';
+
+ if (mime != NULL) {
+ int i;
+
+ for (i = 0; cvt[i].mime != NULL; i++)
+ if (strcasecmp(cvt[i].mime, mime) == 0) {
+ result = cvt[i].rfc;
+ break;
+ }
+ }
+
+ return (result);
+}
+
+static papi_status_t
+add_lpd_control_line(char **metadata, char code, char *value)
+{
+ size_t size = 0;
+ char line[BUFSIZ];
+
+ if ((metadata == NULL) || (value == NULL))
+ return (PAPI_BAD_REQUEST);
+
+ if (*metadata != NULL)
+ size = strlen(*metadata);
+ size += strlen(value) + 3;
+
+ if (*metadata == NULL) {
+ *metadata = (char *)calloc(1, size);
+ } else {
+ void *tmp;
+ tmp = realloc(*metadata, size);
+ if (tmp)
+ *metadata = (char *)tmp;
+ else
+ return (PAPI_TEMPORARY_ERROR);
+ }
+
+ snprintf(line, sizeof (line), "%c%s\n", code, value);
+ strlcat(*metadata, line, size);
+
+ return (PAPI_OK);
+}
+
+static papi_status_t
+add_svr4_control_line(char **metadata, char code, char *value)
+{
+
+ char line[BUFSIZ];
+
+ if ((metadata == NULL) || (value == NULL))
+ return (PAPI_BAD_REQUEST);
+
+ snprintf(line, sizeof (line), "%c%s", code, value);
+
+ return (add_lpd_control_line(metadata, '5', line));
+}
+
+static papi_status_t
+add_hpux_control_line(char **metadata, char *value)
+{
+
+ char line[BUFSIZ];
+
+ if ((metadata == NULL) || (value == NULL))
+ return (PAPI_BAD_REQUEST);
+
+ snprintf(line, sizeof (line), " O%s", value);
+
+ return (add_lpd_control_line(metadata, 'N', line));
+}
+
+static papi_status_t
+add_int_control_line(char **metadata, char code, int value, int flag)
+{
+ char buf[16];
+
+ snprintf(buf, sizeof (buf), "%d", value);
+
+ if (flag == LPD_SVR4)
+ return (add_svr4_control_line(metadata, code, buf));
+ else
+ return (add_lpd_control_line(metadata, code, buf));
+}
+
+static papi_status_t
+lpd_add_rfc1179_attributes(service_t *svc, papi_attribute_t **attributes,
+ char **metadata, papi_attribute_t ***used)
+{
+ papi_status_t status = PAPI_OK;
+ char *s;
+ int integer;
+ char bool;
+ char host[BUFSIZ];
+ char *user = "nobody";
+ uid_t uid = getuid();
+ struct passwd *pw;
+
+ if (svc == NULL)
+ return (PAPI_BAD_REQUEST);
+
+ /* There is nothing to do */
+ if (attributes == NULL)
+ return (PAPI_OK);
+
+ gethostname(host, sizeof (host));
+ add_lpd_control_line(metadata, 'H', host);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "job-originating-host-name", host);
+
+ if ((pw = getpwuid(uid)) != NULL)
+ user = pw->pw_name;
+ if (uid == 0)
+ papiAttributeListGetString(svc->attributes, NULL, "username",
+ &user);
+ add_lpd_control_line(metadata, 'P', user);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "job-originating-user-name", user);
+
+ /* Class for Banner Page */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "rfc-1179-class", &s);
+ if (s != NULL) {
+ add_lpd_control_line(metadata, 'C', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "rfc-1179-class", s);
+ }
+
+ /* Print Banner Page */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "job-sheets", &s);
+ if ((s != NULL) && (strcmp(s, "standard") == 0)) {
+ add_lpd_control_line(metadata, 'L', user);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "job-sheets", s);
+ }
+
+ /* Jobname */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "job-name", &s);
+ if (s != NULL) {
+ add_lpd_control_line(metadata, 'J', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "job-name", s);
+ }
+
+ /* User to mail when job is done - lpr -m */
+ bool = PAPI_FALSE;
+ papiAttributeListGetBoolean(attributes, NULL, "rfc-1179-mail", &bool);
+ if (bool == PAPI_TRUE) {
+ add_lpd_control_line(metadata, 'M', user);
+ papiAttributeListAddBoolean(used, PAPI_ATTR_EXCL,
+ "rfc-1179-mail", bool);
+ }
+
+ /* Title for pr */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "pr-title", &s);
+ if (s != NULL) {
+ add_lpd_control_line(metadata, 'T', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "pr-title", s);
+ }
+
+ /* Indent - used with pr filter */
+ integer = 0;
+ papiAttributeListGetInteger(attributes, NULL, "pr-indent", &integer);
+ if (integer >= 1) {
+ add_int_control_line(metadata, 'I', integer, LPD_RFC);
+ papiAttributeListAddInteger(used, PAPI_ATTR_EXCL,
+ "pr-indent", integer);
+ }
+
+ /* Width - used with pr filter */
+ integer = 0;
+ papiAttributeListGetInteger(attributes, NULL, "pr-width", &integer);
+ if (integer >= 1) {
+ add_int_control_line(metadata, 'W', integer, LPD_RFC);
+ papiAttributeListAddInteger(used, PAPI_ATTR_EXCL,
+ "pr-width", integer);
+ }
+
+ /* file with Times Roman font lpr -1 */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "rfc-1179-font-r", &s);
+ if (s != NULL) {
+ add_lpd_control_line(metadata, '1', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "rfc-1179-font-r", s);
+ }
+
+ /* file with Times Roman font lpr -2 */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "rfc-1179-font-i", &s);
+ if (s != NULL) {
+ add_lpd_control_line(metadata, '2', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "rfc-1179-font-i", s);
+ }
+
+ /* file with Times Roman font lpr -3 */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "rfc-1179-font-b", &s);
+ if (s != NULL) {
+ add_lpd_control_line(metadata, '3', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "rfc-1179-font-b", s);
+ }
+
+ /* file with Times Roman font lpr -4 */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "rfc-1179-font-s", &s);
+ if (s != NULL) {
+ add_lpd_control_line(metadata, '4', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "rfc-1179-font-s", s);
+ }
+
+ return (status);
+}
+
+/*
+ * lpd_add_svr4_attributes
+ * Solaris 2.x LP - BSD protocol extensions
+ */
+static papi_status_t
+lpd_add_svr4_attributes(service_t *svc, papi_attribute_t **attributes,
+ char **metadata, papi_attribute_t ***used)
+{
+ char *s;
+ int integer;
+
+ if (svc == NULL)
+ return (PAPI_BAD_REQUEST);
+
+ /* media */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "media", &s);
+ if (s != NULL) {
+ add_svr4_control_line(metadata, 'f', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "media", s);
+ }
+
+ /* Handling */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "job_hold_until", &s);
+ if ((s != NULL) && (strcmp(s, "indefinite"))) {
+ add_svr4_control_line(metadata, 'H', "hold");
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "media", "hold");
+ } else if ((s != NULL) && (strcmp(s, "no-hold"))) {
+ add_svr4_control_line(metadata, 'H', "release");
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "media", "release");
+ } else if ((s != NULL) && (strcmp(s, "immediate"))) {
+ add_int_control_line(metadata, 'q', 0, LPD_SVR4);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "media", "immediate");
+ }
+
+ /* Pages */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "page-ranges", &s);
+ if (s != NULL) {
+ add_svr4_control_line(metadata, 'P', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "page-ranges", s);
+ }
+
+ /* Priority : lp -q */
+ integer = -1;
+ papiAttributeListGetInteger(attributes, NULL, "priority", &integer);
+ if (integer != -1) {
+ add_int_control_line(metadata, 'q', integer, LPD_SVR4);
+ papiAttributeListAddInteger(used, PAPI_ATTR_EXCL,
+ "priority", integer);
+ }
+
+ /* Charset : lp -S */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "lp-charset", &s);
+ if (s != NULL) {
+ add_svr4_control_line(metadata, 'S', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "lp-charset", s);
+ }
+
+ /* Type : done when adding file */
+
+ /* Mode : lp -y */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "lp-modes", &s);
+ if (s != NULL) {
+ add_svr4_control_line(metadata, 'y', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "lp-modes", s);
+ }
+
+ /* Options lp -o */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "lp-options", &s);
+ if (s != NULL) {
+ add_svr4_control_line(metadata, 'o', s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "lp-options", s);
+ }
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+lpd_add_hpux_attributes(service_t *svc, papi_attribute_t **attributes,
+ char **metadata, papi_attribute_t ***used)
+{
+ char *s = NULL;
+
+ /* Options lp -o */
+ s = NULL;
+ papiAttributeListGetString(attributes, NULL, "lp-options", &s);
+ if (s != NULL) {
+ add_hpux_control_line(metadata, s);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "lp-options", s);
+ }
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+lpd_job_add_attributes(service_t *svc, papi_attribute_t **attributes,
+ char **metadata, papi_attribute_t ***used)
+{
+ if ((svc == NULL) || (metadata == NULL))
+ return (PAPI_BAD_REQUEST);
+
+ lpd_add_rfc1179_attributes(svc, attributes, metadata, used);
+
+ if (svc->uri->fragment != NULL) {
+ if ((strcasecmp(svc->uri->fragment, "solaris") == 0) ||
+ (strcasecmp(svc->uri->fragment, "svr4") == 0))
+ lpd_add_svr4_attributes(svc, attributes, metadata,
+ used);
+ else if (strcasecmp(svc->uri->fragment, "hpux") == 0)
+ lpd_add_hpux_attributes(svc, attributes, metadata,
+ used);
+ /*
+ * others could be added here:
+ * lprng, sco, aix, digital unix, xerox, ...
+ */
+ }
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+lpd_job_add_files(service_t *svc, papi_attribute_t **attributes,
+ char **files, char **metadata, papi_attribute_t ***used)
+{
+ char *format = "plain/text";
+ char rfc_fmt = 'l';
+ int copies = 1;
+ char host[BUFSIZ];
+ int i;
+
+ if ((svc == NULL) || (attributes == NULL) || (files == NULL) ||
+ (metadata == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ papiAttributeListGetString(attributes, NULL, "document-format",
+ &format);
+ papiAttributeListAddString(used, PAPI_ATTR_EXCL,
+ "document-format", format);
+ if ((rfc_fmt = mime_type_to_rfc1179_type(format)) == '\0') {
+ if ((svc->uri->fragment != NULL) &&
+ ((strcasecmp(svc->uri->fragment, "solaris") == 0) ||
+ (strcasecmp(svc->uri->fragment, "svr4") == 0)))
+ add_svr4_control_line(metadata, 'T', format);
+ rfc_fmt = 'l';
+ }
+
+ papiAttributeListGetInteger(attributes, NULL, "copies", &copies);
+ if (copies < 1)
+ copies = 1;
+ papiAttributeListAddInteger(used, PAPI_ATTR_EXCL, "copies", copies);
+
+ gethostname(host, sizeof (host));
+
+ for (i = 0; files[i] != NULL; i++) {
+ char name[BUFSIZ];
+ char key;
+ int j;
+
+ if ((strcmp("standard input", files[i]) != 0) &&
+ (access(files[i], R_OK) < 0)) {
+ detailed_error(svc, gettext("aborting request, %s: %s"),
+ files[i], strerror(errno));
+ return (PAPI_NOT_AUTHORIZED);
+ }
+
+ if (i < 26)
+ key = 'A' + i;
+ else if (i < 52)
+ key = 'a' + (i - 26);
+ else if (i < 62)
+ key = '0' + (i - 52);
+ else {
+ detailed_error(svc,
+ gettext("too many files, truncated at 62"));
+ return (PAPI_OK_SUBST);
+ }
+
+ snprintf(name, sizeof (name), "df%cXXX%s", key, host);
+
+ for (j = 0; j < copies; j++)
+ add_lpd_control_line(metadata, rfc_fmt, name);
+ add_lpd_control_line(metadata, 'U', name);
+ add_lpd_control_line(metadata, 'N', (char *)files[i]);
+ }
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+lpd_submit_job(service_t *svc, char *metadata, papi_attribute_t ***attributes,
+ int *ofd)
+{
+ papi_status_t status = PAPI_INTERNAL_ERROR;
+ int fd;
+ char path[32];
+ char *list[2];
+
+ if ((svc == NULL) || (metadata == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ strcpy(path, "/tmp/lpd-job-XXXXXX");
+ fd = mkstemp(path);
+ write(fd, metadata, strlen(metadata));
+ close(fd);
+
+ list[0] = path;
+ list[1] = NULL;
+
+ if (((fd = lpd_open(svc, 's', list, 3)) < 0) && (errno != EBADMSG)) {
+ switch (errno) {
+ case ENOSPC:
+ status = PAPI_TEMPORARY_ERROR;
+ break;
+ case EIO:
+ status = PAPI_TEMPORARY_ERROR;
+ break;
+ case ECONNREFUSED:
+ status = PAPI_SERVICE_UNAVAILABLE;
+ break;
+ case ENOENT:
+ status = PAPI_NOT_ACCEPTING;
+ break;
+ case EBADMSG:
+ case EBADF:
+ status = PAPI_OK;
+ break;
+ default:
+ status = PAPI_TIMEOUT;
+ break;
+ }
+ } else
+ status = PAPI_OK;
+
+ if (ofd != NULL)
+ *ofd = fd;
+ else
+ close(fd);
+
+ /* read the ID and add it to to the job */
+ if ((fd = open(path, O_RDONLY)) >= 0) {
+ int job_id = 0;
+ read(fd, &job_id, sizeof (job_id));
+ papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE,
+ "job-id", job_id);
+ close(fd);
+ }
+
+ unlink(path);
+
+ return (status);
+}
diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-misc.c b/usr/src/lib/print/libpapi-lpd/common/lpd-misc.c
new file mode 100644
index 0000000000..c41d4fd309
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/lpd-misc.c
@@ -0,0 +1,192 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lpd-misc.c 155 2006-04-26 02:34:54Z ktou $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#define __EXTENSIONS__ /* for strtok_r() */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <wait.h>
+#include <stropts.h>
+#include <papi_impl.h>
+
+#include <config-site.h>
+
+char *
+fdgets(char *buf, size_t len, int fd)
+{
+ char tmp;
+ int count = 0;
+
+ memset(buf, 0, len);
+ while ((count < len) && (read(fd, &tmp, 1) > 0))
+ if ((buf[count++] = tmp) == '\n') break;
+
+ if (count != 0)
+ return (buf);
+ return (NULL);
+}
+
+char *
+queue_name_from_uri(uri_t *uri)
+{
+ char *result = NULL;
+
+ if ((uri != NULL) && (uri->path != NULL)) {
+ char *ptr = strrchr(uri->path, '/');
+
+ if (ptr == NULL)
+ result = uri->path;
+ else
+ result = ++ptr;
+ }
+
+ return (result);
+}
+
+static int
+recvfd(int sockfd)
+{
+ int fd = -1;
+#if defined(sun) && defined(unix) && defined(I_RECVFD)
+ struct strrecvfd recv_fd;
+
+ memset(&recv_fd, NULL, sizeof (recv_fd));
+ if (ioctl(sockfd, I_RECVFD, &recv_fd) == 0)
+ fd = recv_fd.fd;
+#else
+ struct iovec iov[1];
+ struct msghdr msg;
+
+#ifdef CMSG_DATA
+ struct cmsghdr cmp[1];
+ char buf[24]; /* send/recv 2 byte protocol */
+
+ memset(buf, 0, sizeof (buf));
+
+ iov[0].iov_base = buf;
+ iov[0].iov_len = sizeof (buf);
+
+ msg.msg_control = cmp;
+ msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int);
+#else
+ iov[0].iov_base = NULL;
+ iov[0].iov_len = 0;
+ msg.msg_accrights = (caddr_t)&fd;
+ msg.msg_accrights = sizeof (fd);
+#endif
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+
+ if (recvmsg(sockfd, &msg, 0) < 0)
+ fd = -1;
+#ifdef CMSG_DATA
+ else
+ fd = * (int *)CMSG_DATA(cmp);
+#endif
+#endif
+ return (fd);
+}
+
+int
+lpd_open(service_t *svc, char type, char **args, int timeout)
+{
+ int ac, rc = -1, fds[2];
+ pid_t pid;
+ char *av[64], buf[BUFSIZ];
+
+ if ((svc == NULL) || (svc->uri == NULL))
+ return (-1);
+
+#ifndef SUID_LPD_PORT
+#define SUID_LPD_PORT "/usr/lib/print/lpd-port"
+#endif
+
+ av[0] = SUID_LPD_PORT; ac = 1;
+ uri_to_string(svc->uri, buf, sizeof (buf));
+ av[ac++] = "-u";
+ av[ac++] = strdup(buf);
+
+ if (timeout > 0) {
+ snprintf(buf, sizeof (buf), "%d", timeout);
+ av[ac++] = "-t";
+ av[ac++] = strdup(buf);
+ }
+ snprintf(buf, sizeof (buf), "-%c", type);
+ av[ac++] = buf;
+
+ if (args != NULL)
+ while ((*args != NULL) && (ac < 62))
+ av[ac++] = *args++;
+
+ av[ac++] = NULL;
+
+#if defined(sun) && defined(unix) && defined(I_RECVFD)
+ pipe(fds);
+#else
+ socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
+#endif
+
+ switch (pid = fork()) {
+ case -1: /* failed */
+ break;
+ case 0: /* child */
+ dup2(fds[1], 1);
+ execv(av[0], &av[0]);
+ perror("exec");
+ exit(1);
+ break;
+ default: { /* parent */
+ int err, status = 0;
+
+ while ((waitpid(pid, &status, 0) < 0) && (errno == EINTR));
+ errno = WEXITSTATUS(status);
+
+ if (errno == 0)
+ rc = recvfd(fds[0]);
+
+ err = errno;
+ close(fds[0]);
+ close(fds[1]);
+ errno = err;
+ }
+ }
+
+ return (rc);
+}
diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-port.c b/usr/src/lib/print/libpapi-lpd/common/lpd-port.c
new file mode 100644
index 0000000000..2cc106652f
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/lpd-port.c
@@ -0,0 +1,768 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lpd-port.c 155 2006-04-26 02:34:54Z ktou $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <config-site.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <errno.h>
+#include <syslog.h>
+#include <values.h>
+#include <stropts.h> /* for sendfd */
+#include <sys/uio.h> /* for sendmsg stuff */
+#include <pwd.h>
+#include <sys/sendfile.h>
+#include <ctype.h>
+#include <alloca.h>
+#ifdef HAVE_PRIV_H
+#include <priv.h>
+#endif
+#include <papi_impl.h>
+
+#ifndef JOB_ID_FILE
+#define JOB_ID_FILE "/var/run/rfc-1179.seq"
+#endif /* JOB_ID_FILE */
+
+static int
+sendfd(int sockfd, int fd)
+{
+ syslog(LOG_DEBUG, "sendfd(%d, %d)", sockfd, fd);
+
+#if defined(sun) && defined(unix) && defined(I_SENDFD)
+ return (ioctl(sockfd, I_SENDFD, fd));
+#else
+ struct iovec iov[1];
+ struct msghdr msg;
+#ifdef CMSG_DATA
+ struct cmsghdr cmp[1];
+ char buf[2]; /* send/recv 2 byte protocol */
+
+ iov[0].iov_base = buf;
+ iov[0].iov_len = 2;
+
+ cmp[0].cmsg_level = SOL_SOCKET;
+ cmp[0].cmsg_type = SCM_RIGHTS;
+ cmp[0].cmsg_len = sizeof (struct cmsghdr) + sizeof (int);
+ * (int *)CMSG_DATA(cmp) = fd;
+
+ buf[1] = 0;
+ buf[0] = 0;
+ msg.msg_control = cmp;
+ msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int);
+#else
+ iov[0].iov_base = NULL;
+ iov[0].iov_len = 0;
+ msg.msg_accrights = (caddr_t)&fd;
+ msg.msg_accrights = sizeof (fd);
+#endif
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+
+ return (sendmsg(sockfd, &msg, 0));
+#endif
+}
+
+static void
+null(int i)
+{
+}
+
+static int
+sock_connect(int sock, uri_t *uri, int timeout)
+{
+ struct hostent *hp;
+ struct servent *sp;
+#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF)
+ struct sockaddr_in6 sin;
+#else
+ struct sockaddr_in sin;
+#endif
+ static void (*old_handler)();
+ int err,
+ error_num;
+ unsigned timo = 1;
+ int port = -1;
+
+
+ /*
+ * Get the host address and port number to connect to.
+ */
+ if ((uri == NULL) || (uri->host == NULL)) {
+ return (-1);
+ }
+
+ /* linux style NULL usage */
+ (void) memset((char *)&sin, (int)NULL, sizeof (sin));
+
+#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF)
+ if ((hp = getipnodebyname(uri->host, AF_INET6, AI_DEFAULT,
+ &error_num)) == NULL) {
+ errno = ENOENT;
+ return (-1);
+ }
+ (void) memcpy((caddr_t)&sin.sin6_addr, hp->h_addr, hp->h_length);
+ sin.sin6_family = hp->h_addrtype;
+#else
+ if ((hp = gethostbyname(uri->host)) == NULL) {
+ errno = ENOENT;
+ return (-1);
+ }
+
+ (void) memcpy((caddr_t)&sin.sin_addr, hp->h_addr, hp->h_length);
+ sin.sin_family = hp->h_addrtype;
+#endif
+
+ if ((sp = getservbyname("printer", "tcp")) == NULL) {
+ errno = ENOENT;
+ return (-1);
+ }
+
+ if (uri->port != NULL)
+ port = atoi(uri->port);
+ if (port < 0)
+ port = sp->s_port;
+
+#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF)
+ sin.sin6_port = port;
+#else
+ sin.sin_port = port;
+#endif
+
+retry:
+ old_handler = signal(SIGALRM, null);
+ (void) alarm(timeout);
+
+ if (connect(sock, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
+ (void) alarm(0);
+ (void) signal(SIGALRM, old_handler);
+
+ if (errno == ECONNREFUSED && timo <= 16) {
+ (void) sleep(timo);
+ timo *= 2;
+ goto retry;
+ }
+
+ return (-1);
+ }
+
+ (void) alarm(0);
+ (void) signal(SIGALRM, old_handler);
+ return (sock);
+}
+
+static int
+next_job_id()
+{
+ int fd, result = getpid() % 1000;
+
+ /* gain back enough privilege to open the id file */
+#ifdef PRIV_ALLSETS
+ if ((priv_set(PRIV_ON, PRIV_EFFECTIVE,
+ PRIV_FILE_DAC_READ, PRIV_FILE_DAC_WRITE, NULL)) < 0) {
+ syslog(LOG_ERR, "lpd_port:next_job_id:priv_set fails: : %m");
+ return (-1);
+ }
+#else
+ seteuid(0);
+#endif
+
+ /* open the sequence file */
+ if (((fd = open(JOB_ID_FILE, O_RDWR)) < 0) && (errno == ENOENT))
+ fd = open(JOB_ID_FILE, O_CREAT|O_EXCL|O_RDWR, 0644);
+
+ syslog(LOG_DEBUG, "sequence file fd: %d", fd);
+
+ /* drop our privilege again */
+#ifdef PRIV_ALLSETS
+ /* drop file access privilege */
+ priv_set(PRIV_OFF, PRIV_PERMITTED,
+ PRIV_FILE_DAC_READ, PRIV_FILE_DAC_WRITE, NULL);
+#else
+ seteuid(getuid());
+#endif
+
+ if (fd >= 0) {
+ /* wait for a lock on the file */
+ if (lockf(fd, F_LOCK, 0) == 0) {
+ char buf[8];
+ int next;
+
+ /* get the current id */
+ (void) memset(buf, 0, sizeof (buf));
+ if (read(fd, buf, sizeof (buf)) > 0)
+ result = atoi(buf);
+
+ next = ((result < 999) ? (result + 1) : 0);
+
+ /* store the next id in the file */
+ snprintf(buf, sizeof (buf), "%.3d", next);
+ if ((lseek(fd, 0, SEEK_SET) == 0) &&
+ (ftruncate(fd, 0) == 0))
+ write(fd, buf, strlen(buf));
+ }
+ }
+ syslog(LOG_DEBUG, "next_job_id() is %d", result);
+
+ return (result);
+}
+
+static int
+reserved_port()
+{
+ int result = -1;
+ int port;
+
+ /* gain back enough privilege to open a reserved port */
+#ifdef PRIV_ALLSETS
+ if ((priv_set(
+ PRIV_ON, PRIV_EFFECTIVE, PRIV_NET_PRIVADDR, NULL)) != 0) {
+ syslog(LOG_ERR, "priv_set fails for net_privaddr %m");
+ return (-1);
+ }
+#else
+ seteuid(0);
+#endif
+
+#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF)
+ port = 0; /* set to 0, rresvport_af() will find us one. */
+ result = rresvport_af(&port, AF_INET6);
+#else
+ port = IPPORT_RESERVED - 1;
+ while (((result = rresvport(&port)) < 0) && (port >= 0))
+ port--;
+#endif
+
+ /* drop our privilege again */
+#ifdef PRIV_ALLSETS
+ priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_NET_PRIVADDR, NULL);
+#else
+ seteuid(getuid());
+#endif
+
+ return (result);
+}
+
+static char *
+get_user_name()
+{
+ static struct passwd *p = NULL;
+
+ if ((p = getpwuid(getuid())) != NULL)
+ return (p->pw_name);
+ else
+ return ("unknown");
+}
+
+static void
+add_args(int ac, char **av, char *buf, size_t len)
+{
+ while (ac--) {
+ strlcat(buf, " ", len);
+ strlcat(buf, *(av++), len);
+ }
+}
+
+static int
+massage_control_data(char *data, int id)
+{
+ char *line, *iter = NULL;
+ char *ptr;
+ char host[BUFSIZ];
+
+ gethostname(host, sizeof (host));
+
+ for (ptr = strchr(data, '\n'); ptr != NULL; ptr = strchr(ptr, '\n')) {
+ ptr++;
+
+ if (ptr[0] == 'H') {
+ if (strncmp(++ptr, host, strlen(host)) != 0)
+ return (-1);
+ } else if ((ptr[0] == 'P') || (ptr[0] == 'L')) {
+ /* check the user name */
+ uid_t uid = getuid();
+ struct passwd *pw;
+ int len;
+
+ if (uid == 0) /* let root do what they want */
+ continue;
+ if ((pw = getpwuid(uid)) == NULL)
+ return (-1); /* failed */
+ len = strlen(pw->pw_name);
+ if ((strncmp(++ptr, pw->pw_name, len) != 0) ||
+ (ptr[len] != '\n'))
+ return (-1); /* failed */
+ } else if ((islower(ptr[0]) != 0) || (ptr[0] == 'U')) {
+ /* check/fix df?XXXhostname */
+ ptr++;
+
+ if (strlen(ptr) < 6)
+ return (-1);
+ if ((ptr[0] == 'd') && (ptr[1] == 'f') &&
+ (ptr[3] == 'X') && (ptr[4] == 'X') &&
+ (ptr[5] == 'X')) {
+ ptr[3] = '0' + (id / 100) % 10;
+ ptr[4] = '0' + (id / 10) % 10;
+ ptr[5] = '0' + id % 10;
+
+ if (strncmp(&ptr[6], host, strlen(host)) != 0)
+ return (-1);
+ } else
+ return (-1);
+ }
+ }
+ return (1);
+}
+
+static int
+send_lpd_message(int fd, char *fmt, ...)
+{
+ char buf[BUFSIZ];
+ size_t size;
+ va_list ap;
+
+ va_start(ap, fmt);
+ size = vsnprintf(buf, sizeof (buf), fmt, ap);
+ va_end(ap);
+ if (size == 0)
+ size = 1;
+
+ syslog(LOG_DEBUG, "lpd_messsage(%d, %s)", fd, buf);
+
+ if (write(fd, buf, size) != size) {
+ errno = EIO;
+ return (-1);
+ }
+
+ if ((read(fd, buf, 1) != 1) || (buf[0] != 0))
+ return (-1);
+
+ return (0);
+}
+
+static int
+send_data_file(int sock, char *dfname, char *name)
+{
+ size_t len;
+ off_t off = 0;
+ struct stat st;
+ char buf[32];
+ int fd = -1;
+
+ if (strcmp(name, "standard input") != 0) {
+ if ((fd = open(name, O_RDONLY)) < 0)
+ return (-1);
+
+ if (fstat(fd, &st) < 0)
+ return (-1);
+ } else
+ st.st_size = MAXINT; /* should be 0 */
+
+ /* request data file transfer, read ack/nack */
+ errno = ENOSPC;
+ if (send_lpd_message(sock, "\003%d %s\n", st.st_size, dfname) < 0)
+ return (-1);
+
+ if (fd != -1) {
+ /* write the data */
+ if (sendfile(sock, fd, &off, st.st_size) != st.st_size)
+ return (-1);
+ close(fd);
+
+ /* request ack/nack after the data transfer */
+ errno = EIO;
+ if (send_lpd_message(sock, "") < 0)
+ return (-1);
+ }
+
+ return (0);
+}
+
+static int
+send_control_file(int sock, char *data, int id)
+{
+ int len;
+ char buf[BUFSIZ];
+ char *host = "localhost";
+
+ len = strlen(data);
+
+ /* request data file transfer, read ack/nack */
+ errno = ENOSPC;
+ if (send_lpd_message(sock, "\002%d cfA%.3d%s\n", len, id, host) < 0)
+ return (-1);
+
+ /* write the data */
+ if (write(sock, data, len) != len)
+ return (-1);
+
+ /* request ack/nack after the data transfer */
+ errno = EIO;
+ if (send_lpd_message(sock, "") < 0)
+ return (-1);
+
+ return (0);
+}
+
+
+static int
+submit_job(int sock, uri_t *uri, int job_id, char *path)
+{
+ int current = 0;
+ off_t off = 0;
+ char *metadata = NULL;
+ char *ptr, *iter = NULL;
+ int fd, err;
+ int sent_files = 0;
+ char buf[BUFSIZ];
+ size_t len;
+ char *printer = queue_name_from_uri(uri);
+
+ /* read in the control file */
+ if ((fd = open(path, O_RDONLY)) >= 0) {
+ struct stat st;
+
+ if (fstat(fd, &st) < 0) {
+ close(fd);
+ return (-1);
+ }
+
+ metadata = alloca(st.st_size + 1);
+ memset(metadata, 0, st.st_size + 1);
+
+ if (read(fd, metadata, st.st_size) != st.st_size) {
+ close(fd);
+ free(metadata);
+ metadata = NULL;
+ return (-1);
+ }
+
+ } else {
+ syslog(LOG_ERR,
+ "lpd-port:submit_job:open failed : %m path %s", path);
+ return (-1);
+ }
+
+ /* massage the control file */
+ if (massage_control_data(metadata, job_id) < 0) {
+ /* bad control data, dump the job */
+ syslog(LOG_ALERT,
+ "bad control file, possible subversion attempt");
+ }
+
+ /* request to transfer the job */
+ if (send_lpd_message(sock, "\002%s\n", printer) < 0) {
+ /* no such (or disabled) queue, got to love rfc-1179 */
+ errno = ENOENT;
+ return (-1);
+ }
+
+ /* send the control data */
+ if (send_control_file(sock, metadata, job_id) < 0) {
+ err = errno;
+ write(sock, "\001\n", 2); /* abort */
+ errno = err;
+ return (-1);
+ }
+
+ /* walk the control file sending the data files */
+ for (ptr = strtok_r(metadata, "\n", &iter); ptr != NULL;
+ ptr = strtok_r(NULL, "\n", &iter)) {
+ char *name = NULL;
+
+ if (ptr[0] != 'U')
+ continue;
+
+ name = strtok_r(NULL, "\n", &iter);
+ if (name[0] != 'N')
+ continue;
+
+ ptr++;
+ name++;
+
+ if (send_data_file(sock, ptr, name) < 0) {
+ err = errno;
+ write(sock, "\001\n", 2); /* abort */
+ errno = err;
+ return (-1);
+ }
+ if (strcmp(name, "standard input") != 0)
+ sent_files++;
+ }
+
+ /* write back the job-id */
+ err = errno;
+ if ((fd = open(path, O_WRONLY)) >= 0) {
+ ftruncate(fd, 0);
+ write(fd, &job_id, sizeof (job_id));
+ close(fd);
+ }
+ errno = err;
+
+ if (sent_files != 0) {
+ err = errno;
+ close(sock);
+ errno = err;
+ }
+
+ return (0);
+}
+
+static int
+query(int fd, uri_t *uri, int ac, char **av)
+{
+ char buf[BUFSIZ];
+ int rc, len;
+ char *printer = queue_name_from_uri(uri);
+
+ /* build the request */
+ snprintf(buf, sizeof (buf), "\04%s", printer);
+ add_args(ac, av, buf, sizeof (buf));
+ strlcat(buf, "\n", sizeof (buf));
+ len = strlen(buf);
+
+ if (((rc = write(fd, buf, len)) >= 0) && (rc != len)) {
+ errno = EMSGSIZE;
+ rc = -1;
+ } else
+ rc = 0;
+
+ return (rc);
+}
+
+static int
+cancel(int fd, uri_t *uri, int ac, char **av)
+{
+ char buf[BUFSIZ];
+ int rc, len;
+ char *printer = queue_name_from_uri(uri);
+
+ /* build the request */
+ snprintf(buf, sizeof (buf), "\05%s %s", printer, get_user_name());
+ add_args(ac, av, buf, sizeof (buf));
+ strlcat(buf, "\n", sizeof (buf));
+ len = strlen(buf);
+
+ if (((rc = write(fd, buf, len)) >= 0) && (rc != len)) {
+ errno = EMSGSIZE;
+ rc = -1;
+ } else
+ rc = 0;
+
+ return (rc);
+}
+
+static void
+usage(char *program)
+{
+ char *name;
+
+ setreuid(getuid(), getuid());
+
+ if ((name = strrchr(program, '/')) == NULL)
+ name = program;
+ else
+ name++;
+
+ fprintf(stderr, "usage:\t%s -u uri [-t timeout] "
+ "[-s control ]\n", name);
+ fprintf(stderr, "\t%s -u uri [-t timeout] "
+ "[-c user|job ...]\n", name);
+ fprintf(stderr, "\t%s -u uri [-t timeout] "
+ "[-q user|job ...]\n", name);
+ exit(EINVAL);
+}
+
+/*
+ * The main program temporarily loses privilege while searching the command
+ * line arguments. It then allocates any resources it need privilege for
+ * job-id, reserved port. Once it has the resources it needs, it perminently
+ * drops all elevated privilege. It ghen connects to the remote print service
+ * based on destination hostname. Doing it this way reduces the potenential
+ * opportunity for a breakout with elevated privilege, breakout with an
+ * unconnected reserved port, and exploitation of the remote print service
+ * by a calling program.
+ */
+int
+main(int ac, char *av[])
+{
+ enum { OP_NONE, OP_SUBMIT, OP_QUERY, OP_CANCEL } operation = OP_NONE;
+ int fd, c, timeout = 0, exit_code = 0;
+ uri_t *uri = NULL;
+ uid_t uid = getuid();
+#ifdef PRIV_ALLSETS
+ priv_set_t *saveset = NULL;
+#endif
+
+ openlog("lpd-port", LOG_PID, LOG_LPR);
+
+#ifdef PRIV_ALLSETS
+
+ /* lose as much as we can perminently and temporarily drop the rest. */
+
+ if ((saveset = priv_str_to_set("PRIV_NET_PRIVADDR,"
+ "PRIV_FILE_DAC_READ,PRIV_FILE_DAC_WRITE,",
+ ",", (const char **)NULL)) == NULL) {
+ syslog(LOG_ERR,
+ "lpd_port: priv_str_to_set saveset failed: %m\n");
+ return (-1);
+ }
+
+ if ((setppriv(PRIV_SET, PRIV_PERMITTED, saveset)) < 0) {
+ syslog(LOG_ERR, "lpd_port:setppriv:priv_set failed: %m");
+ return (-1);
+ }
+
+ /*
+ * These privileges permanently dropped in next_job_id() and
+ * reserved_port()
+ */
+
+ if ((setppriv(PRIV_OFF, PRIV_EFFECTIVE, saveset)) < 0) {
+ syslog(LOG_ERR, "lpd_port:setppriv:priv_off failed: %m");
+ return (-1);
+ }
+
+ priv_freeset(saveset);
+
+ syslog(LOG_DEBUG, "using privs");
+#else
+
+ syslog(LOG_DEBUG, "no privs");
+ seteuid(uid);
+#endif
+
+
+ while ((c = getopt(ac, av, "cqst:u:")) != EOF) {
+ switch (c) {
+ case 'c':
+ if (operation != OP_NONE)
+ usage(av[0]);
+ operation = OP_CANCEL;
+ break;
+ case 'q':
+ if (operation != OP_NONE)
+ usage(av[0]);
+ operation = OP_QUERY;
+ break;
+ case 's':
+ if (operation != OP_NONE)
+ usage(av[0]);
+ operation = OP_SUBMIT;
+ break;
+ case 't':
+ timeout = atoi(optarg);
+ break;
+ case 'u':
+ if (uri_from_string(optarg, &uri) < 0)
+ usage(av[0]);
+ break;
+ default:
+ usage(av[0]);
+ /* does not return */
+ }
+ }
+
+ if ((uri == NULL) || (timeout < 0) || (operation == OP_NONE))
+ usage(av[0]);
+
+ if ((strcasecmp(uri->scheme, "lpd") != 0) &&
+ (strcasecmp(uri->scheme, "rfc-1179") != 0))
+ usage(av[0]);
+
+ if (operation == OP_SUBMIT) /* get a job-id if we need it */
+ if ((c = next_job_id()) < 0) {
+ syslog(LOG_ERR, "lpd_port:main:next_job_id fails");
+ return (-1);
+ }
+
+ if ((fd = reserved_port()) < 0) {
+ syslog(LOG_ERR, "reserved_port() failed %m");
+ return (errno);
+ }
+
+ /*
+ * we no longer want or need any elevated privilege, lose it all
+ * permanently.
+ */
+
+ setreuid(uid, uid);
+
+
+ /* connect to the print service */
+ if ((fd = sock_connect(fd, uri, timeout)) < 0)
+ return (errno);
+
+ /* perform the requested operation */
+ switch (operation) {
+ case OP_SUBMIT: /* transfer the job, close the fd */
+ if (submit_job(fd, uri, c, av[optind]) < 0)
+ exit_code = errno;
+ break;
+ case OP_QUERY: /* send the query string, return the fd */
+ if (query(fd, uri, ac - optind, &av[optind]) < 0)
+ exit_code = errno;
+ break;
+ case OP_CANCEL: /* send the cancel string, return the fd */
+ if (cancel(fd, uri, ac - optind, &av[optind]) < 0)
+ exit_code = errno;
+ break;
+ default: /* This should never happen */
+ exit_code = EINVAL;
+ }
+
+
+ /* if the operation succeeded, send the fd to our parent */
+ if ((exit_code == 0) && (sendfd(1, fd) < 0)) {
+ char buf[BUFSIZ];
+
+ exit_code = errno;
+
+ /* sendfd() failed, dump the socket data for the heck of it */
+ while ((c = read(fd, buf, sizeof (buf))) > 0)
+ write(1, buf, c);
+ }
+
+ syslog(LOG_DEBUG, "exit code: %d", exit_code);
+ return (exit_code);
+}
diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-query.c b/usr/src/lib/print/libpapi-lpd/common/lpd-query.c
new file mode 100644
index 0000000000..4c1392a1d9
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/lpd-query.c
@@ -0,0 +1,292 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: lpd-query.c 155 2006-04-26 02:34:54Z ktou $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#define __EXTENSIONS__ /* for strtok_r() */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <time.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <papi_impl.h>
+
+static void
+parse_lpd_job_entry(service_t *svc, int fd, job_t **job)
+{
+ char *iter = NULL;
+ char line[128];
+ papi_attribute_t **attributes = NULL;
+ char *p;
+ int octets = 0;
+
+ *job = NULL;
+
+ if (fdgets(line, sizeof (line), fd) == NULL)
+ return;
+ /*
+ * 1st line...
+ * user: rank [job (ID)(host)]\n
+ */
+ if ((p = strtok_r(line, ": ", &iter)) == NULL) /* user: ... */
+ return; /* invalid format */
+ papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE,
+ "job-originating-user-name", p);
+
+ p = strtok_r(NULL, "\t ", &iter); /* ...rank... */
+ papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE,
+ "number-of-intervening-jobs", atoi(p) - 1);
+ p = strtok_r(NULL, " ", &iter); /* ...[job ... */
+ if ((p = strtok_r(NULL, "]\n", &iter)) == NULL) /* ...(id)(hostname)] */
+ return;
+ while (isspace(*p)) p++;
+ papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE,
+ "job-id", atoi(p));
+ while (isdigit(*(++p)));
+ while (isspace(*p)) p++;
+ papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE,
+ "job-originating-host-name", p);
+
+ /*
+ * rest-o-lines
+ * [(num) copies of ]file size bytes\n
+ */
+ while ((fdgets(line, sizeof (line), fd) != NULL) && (line[0] != '\n')) {
+ int copies, size;
+ char *q;
+
+ /* find the number of copies */
+ if ((p = strstr(line, "copies of")) != NULL) {
+ copies = atoi(line);
+ p += 9;
+ } else {
+ copies = 1;
+ p = line;
+ }
+ papiAttributeListAddInteger(&attributes, PAPI_ATTR_EXCL,
+ "copies", copies);
+
+ /* eat the leading whitespace */
+ while (isspace(*p) != 0)
+ p++;
+ if ((q = strstr(p, " bytes\n")) != NULL) {
+ /* back up to the beginning of the size */
+ do { q--; } while (isdigit(*q) != 0);
+
+ /* seperate the name and size */
+ *q = '\0';
+ q++;
+
+ size = atoi(q);
+
+ papiAttributeListAddString(&attributes,
+ PAPI_ATTR_APPEND, "job-name", p);
+ papiAttributeListAddString(&attributes,
+ PAPI_ATTR_APPEND, "job-file-names", p);
+ papiAttributeListAddInteger(&attributes,
+ PAPI_ATTR_APPEND, "job-file-sizes", size);
+
+ octets += (size * copies);
+ }
+ }
+
+ papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND,
+ "job-k-octets", octets/1024);
+ papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND,
+ "job-octets", octets);
+ papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND,
+ "printer-name", queue_name_from_uri(svc->uri));
+
+ if ((*job = (job_t *)calloc(1, sizeof (**job))) != NULL)
+ (*job)->attributes = attributes;
+}
+
+static void
+parse_lpd_job_entries(service_t *svc, int fd)
+{
+ job_t *job = NULL;
+
+ do {
+ parse_lpd_job_entry(svc, fd, &job);
+ list_append(&svc->cache->jobs, job);
+ } while (job != NULL);
+
+}
+
+
+void
+parse_lpd_query(service_t *svc, int fd)
+{
+ papi_attribute_t **attributes = NULL;
+ cache_t *cache = NULL;
+ int state = 0x03; /* idle */
+ char line[128];
+ char buf[1024];
+
+ /* get the status line */
+ if (fdgets(line, sizeof (line), fd) == NULL)
+ return; /* this should not happen. */
+
+ papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND,
+ "printer-name", queue_name_from_uri(svc->uri));
+
+ if (uri_to_string(svc->uri, buf, sizeof (buf)) == 0)
+ papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND,
+ "printer-uri-supported", buf);
+
+ papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE,
+ "printer-state-reasons", line);
+
+ if (strstr(line, "ready and printing") != NULL)
+ state = 0x04; /* processing */
+ else if ((strstr(line, "no entries") != NULL) ||
+ (strstr(line, "is ready") != NULL))
+ state = 0x03; /* idle */
+ else
+ state = 0x05; /* stopped */
+
+ papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE,
+ "printer-state", state);
+
+ if ((cache = (cache_t *)calloc(1, sizeof (*cache))) == NULL)
+ return;
+
+ if ((cache->printer = (printer_t *)calloc(1, sizeof (*cache->printer)))
+ == NULL)
+ return;
+
+ cache->printer->attributes = attributes;
+ svc->cache = cache;
+
+ if (fdgets(line, sizeof (line), fd) != NULL) {
+ /* get the jobs */
+ parse_lpd_job_entries(svc, fd);
+ }
+
+ time(&cache->timestamp);
+}
+
+void
+cache_update(service_t *svc)
+{
+ int fd;
+
+ if (svc->cache != NULL) /* this should be time based */
+ return;
+
+ if (svc == NULL)
+ return;
+
+ if ((fd = lpd_open(svc, 'q', NULL, 3)) < 0)
+ return;
+
+ parse_lpd_query(svc, fd);
+
+ close(fd);
+}
+
+papi_status_t
+lpd_find_printer_info(service_t *svc, printer_t **printer)
+{
+ papi_status_t result = PAPI_BAD_ARGUMENT;
+
+ if ((svc == NULL) || (printer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ cache_update(svc);
+
+ if (svc->cache != NULL) {
+ *printer = svc->cache->printer;
+ result = PAPI_OK;
+ } else
+ result = PAPI_NOT_FOUND;
+
+ return (result);
+}
+
+papi_status_t
+lpd_find_jobs_info(service_t *svc, job_t ***jobs)
+{
+ papi_status_t result = PAPI_BAD_ARGUMENT;
+
+ if (svc != NULL) {
+ cache_update(svc);
+
+ if (svc->cache != NULL) {
+ *jobs = svc->cache->jobs;
+ result = PAPI_OK;
+ }
+ }
+
+ return (result);
+}
+
+papi_status_t
+lpd_find_job_info(service_t *svc, int job_id, job_t **job)
+{
+ papi_status_t result = PAPI_BAD_ARGUMENT;
+ job_t **jobs;
+
+ if (lpd_find_jobs_info(svc, &jobs) != PAPI_OK) {
+ int i;
+
+ *job = NULL;
+ for (i = 0; ((*job == NULL) && (jobs[i] != NULL)); i++) {
+ int id = -1;
+
+ papiAttributeListGetInteger(jobs[i]->attributes, NULL,
+ "job-id", &id);
+ if (id == job_id)
+ *job = jobs[i];
+ }
+
+ if (*job != NULL)
+ result = PAPI_OK;
+ }
+
+ return (result);
+}
+
+void
+cache_free(cache_t *item)
+{
+ if (item != NULL) {
+ if (item->printer != NULL)
+ papiPrinterFree((papi_printer_t *)item->printer);
+ if (item->jobs != NULL)
+ papiJobListFree((papi_job_t *)item->jobs);
+ free(item);
+ }
+}
diff --git a/usr/src/lib/print/libpapi-lpd/common/mapfile b/usr/src/lib/print/libpapi-lpd/common/mapfile
new file mode 100644
index 0000000000..d21b349ff7
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/mapfile
@@ -0,0 +1,150 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+#
+# Common interfaces that are most likely to be shared amongst the various
+# PAPI implementations.
+#
+
+SUNW_1.0 {
+ global:
+ # PAPI Attribute Calls
+ papiAttributeListAddValue = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddBoolean = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddCollection = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddDatetime = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddInteger = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddMetadata = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddRange = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddResolution = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListAddString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListDelete = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetValue = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetNext = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFind = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetBoolean = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetCollection = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetDatetime = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetInteger = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetMetadata = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetRange = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetResolution = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListGetString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFromString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListToString = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListFree = FUNCTION FILTER libpapi-common.so ;
+
+ # PAPI Service Calls
+ papiServiceCreate ;
+ papiServiceDestroy ;
+ papiServiceSetUserName ;
+ papiServiceSetPassword ;
+ papiServiceSetEncryption ;
+ papiServiceSetAuthCB ;
+ papiServiceSetAppData ;
+ papiServiceGetUserName ;
+ papiServiceGetPassword ;
+ papiServiceGetEncryption ;
+ papiServiceGetAppData ;
+ papiServiceGetServiceName ;
+ papiServiceGetAttributeList ;
+ papiServiceGetStatusMessage ;
+
+ # PAPI Printer Calls
+ papiPrintersList = FUNCTION FILTER libpapi-common.so ;
+ papiPrinterQuery ;
+ papiPrinterAdd = FUNCTION FILTER libpapi-common.so ;
+ papiPrinterModify = FUNCTION FILTER libpapi-common.so ;
+ papiPrinterRemove = FUNCTION FILTER libpapi-common.so ;
+ papiPrinterDisable = FUNCTION FILTER libpapi-common.so ;
+ papiPrinterEnable = FUNCTION FILTER libpapi-common.so ;
+ papiPrinterPause = FUNCTION FILTER libpapi-common.so ;
+ papiPrinterResume = FUNCTION FILTER libpapi-common.so ;
+ papiPrinterPurgeJobs ;
+ papiPrinterListJobs ;
+ papiPrinterGetAttributeList ;
+ papiPrinterFree ;
+ papiPrinterListFree ;
+
+ # PAPI Job Calls
+ papiJobSubmit ;
+ papiJobSubmitByReference ;
+ papiJobValidate = FUNCTION FILTER libpapi-common.so ;
+ papiJobStreamOpen ;
+ papiJobStreamWrite ;
+ papiJobStreamClose ;
+ papiJobQuery ;
+ papiJobModify = FUNCTION FILTER libpapi-common.so ;
+ papiJobMove = FUNCTION FILTER libpapi-common.so ;
+ papiJobCancel ;
+ papiJobHold = FUNCTION FILTER libpapi-common.so ;
+ papiJobRelease = FUNCTION FILTER libpapi-common.so ;
+ papiJobRestart = FUNCTION FILTER libpapi-common.so ;
+ papiJobPromote = FUNCTION FILTER libpapi-common.so ;
+ papiJobGetAttributeList ;
+ papiJobGetPrinterName ;
+ papiJobGetId ;
+ papiJobGetJobTicket = FUNCTION FILTER libpapi-common.so ;
+ papiJobFree ;
+ papiJobListFree ;
+
+ # Misc. PAPI Calls
+ papiStatusString = FUNCTION FILTER libpapi-common.so ;
+ papiLibrarySupportedCall ;
+ papiLibrarySupportedCalls ;
+};
+
+SUNWprivate_1.0 {
+ global:
+ papiServiceSetPeer = FUNCTION FILTER libpapi-common.so ;
+ papiJobCreate = FUNCTION FILTER libpapi-common.so ;
+ papiJobStreamAdd = FUNCTION FILTER libpapi-common.so ;
+ papiJobCommit = FUNCTION FILTER libpapi-common.so ;
+
+ # Misc. supporting calls
+ # URI
+ uri_from_string = FUNCTION FILTER libpapi-common.so ;
+ uri_to_string = FUNCTION FILTER libpapi-common.so ;
+ uri_free = FUNCTION FILTER libpapi-common.so ;
+ # list
+ list_remove = FUNCTION FILTER libpapi-common.so ;
+ list_append = FUNCTION FILTER libpapi-common.so ;
+ list_concatenate = FUNCTION FILTER libpapi-common.so ;
+
+ # extra Attribute Calls
+ copy_attributes = FUNCTION FILTER libpapi-common.so ;
+ split_and_copy_attributes = FUNCTION FILTER libpapi-common.so ;
+ papiAttributeListPrint = FUNCTION FILTER libpapi-common.so ;
+
+ local:
+ * ;
+} ;
diff --git a/usr/src/lib/print/libpapi-lpd/common/papi_impl.h b/usr/src/lib/print/libpapi-lpd/common/papi_impl.h
new file mode 100644
index 0000000000..82d955b3cb
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/papi_impl.h
@@ -0,0 +1,111 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+#ifndef _PAPI_IMPL_H
+#define _PAPI_IMPL_H
+
+/* $Id: papi_impl.h 161 2006-05-03 04:32:59Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <papi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <uri.h>
+
+typedef struct {
+ papi_attribute_t **attributes;
+} printer_t;
+
+typedef struct job {
+ papi_attribute_t **attributes;
+} job_t;
+
+typedef struct stream {
+ job_t *job; /* describes current job */
+ int fd; /* the fd to write to */
+ char *metadata; /* the converted metadata */
+ char *dfname; /* the stream data (if we can't stream) */
+
+} stream_t;
+
+typedef struct { /* used for query operations only */
+ time_t timestamp;
+ printer_t *printer;
+ job_t **jobs;
+} cache_t;
+
+typedef struct {
+ papi_attribute_t **attributes; /* extra info */
+ uri_t *uri; /* printer uri */
+ cache_t *cache; /* printer/job cache */
+ int (*authCB)(papi_service_t svc, void *app_data); /* unused */
+ void *app_data; /* unused */
+} service_t;
+
+
+extern papi_status_t service_fill_in(service_t *svc, char *name);
+extern void detailed_error(service_t *svc, char *fmt, ...);
+extern char *queue_name_from_uri(uri_t *uri);
+extern char *fdgets(char *buf, size_t len, int fd);
+
+
+/* lpd operations */
+ /* open a connection to remote print service */
+extern int lpd_open(service_t *svc, char type, char **args,
+ int timeout);
+ /* job cancelation */
+extern papi_status_t lpd_purge_jobs(service_t *svc, job_t ***jobs);
+extern papi_status_t lpd_cancel_job(service_t *svc, int job_id);
+ /* job submission */
+extern papi_status_t lpd_submit_job(service_t *svc, char *metadata,
+ papi_attribute_t ***attributes, int *fd);
+extern papi_status_t lpd_job_add_attributes(service_t *svc,
+ papi_attribute_t **attributes,
+ char **metadata,
+ papi_attribute_t ***used_attributes);
+extern papi_status_t lpd_job_add_files(service_t *svc,
+ papi_attribute_t **attributes, char **files,
+ char **metadata,
+ papi_attribute_t ***used_attributes);
+ /* query cache lookup routines */
+extern papi_status_t lpd_find_printer_info(service_t *svc, printer_t **result);
+extern papi_status_t lpd_find_job_info(service_t *svc, int job_id, job_t **job);
+extern papi_status_t lpd_find_jobs_info(service_t *svc, job_t ***jobs);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PAPI_IMPL_H */
diff --git a/usr/src/lib/print/libpapi-lpd/common/printer.c b/usr/src/lib/print/libpapi-lpd/common/printer.c
new file mode 100644
index 0000000000..af538c62c6
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/printer.c
@@ -0,0 +1,156 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: printer.c 149 2006-04-25 16:55:01Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <strings.h>
+#include <papi_impl.h>
+
+static int
+contains(char *value, char **list)
+{
+ int i;
+
+ if ((value == NULL) || (list == NULL))
+ return (1);
+
+ for (i = 0; list[i] != NULL; i++)
+ if (strcasecmp(value, list[i]) == 0)
+ return (1);
+
+ return (0);
+}
+
+papi_status_t
+papiPrinterQuery(papi_service_t handle, char *name,
+ char **requested_attrs,
+ papi_attribute_t **job_attributes,
+ papi_printer_t *printer)
+{
+ papi_status_t status;
+ service_t *svc = handle;
+ printer_t *p = NULL;
+
+ if ((svc == NULL) || (name == NULL) || (printer == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((status = service_fill_in(svc, name)) == PAPI_OK) {
+ *printer = NULL;
+
+ if ((contains("printer-state", requested_attrs) == 1) ||
+ (contains("printer-state-reasons", requested_attrs) == 1))
+ status = lpd_find_printer_info(svc,
+ (printer_t **)printer);
+
+ if ((status == PAPI_OK) && (*printer == NULL)) {
+ char buf[BUFSIZ];
+
+ *printer = p = calloc(1, sizeof (*p));
+
+ papiAttributeListAddString(&(p->attributes),
+ PAPI_ATTR_APPEND, "printer-name",
+ queue_name_from_uri(svc->uri));
+
+ if (uri_to_string(svc->uri, buf, sizeof (buf)) == 0)
+ papiAttributeListAddString(&(p->attributes),
+ PAPI_ATTR_APPEND,
+ "printer-uri-supported", buf);
+ }
+ }
+
+ return (status);
+}
+
+papi_status_t
+papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs)
+{
+ papi_status_t status;
+ service_t *svc = handle;
+
+ if ((svc == NULL) || (name == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((status = service_fill_in(svc, name)) == PAPI_OK)
+ status = lpd_purge_jobs(svc, (job_t ***)jobs);
+
+ return (status);
+}
+
+papi_status_t
+papiPrinterListJobs(papi_service_t handle, char *name,
+ char **requested_attrs, int type_mask,
+ int max_num_jobs, papi_job_t **jobs)
+{
+ papi_status_t status;
+ service_t *svc = handle;
+
+ if ((svc == NULL) || (name == NULL) || (jobs == NULL))
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((status = service_fill_in(svc, name)) == PAPI_OK)
+ status = lpd_find_jobs_info(svc, (job_t ***)jobs);
+
+ return (status);
+}
+
+papi_attribute_t **
+papiPrinterGetAttributeList(papi_printer_t printer)
+{
+ printer_t *p = printer;
+
+ if (p == NULL)
+ return (NULL);
+
+ return (p->attributes);
+}
+
+void
+papiPrinterFree(papi_printer_t printer)
+{
+ printer_t *p = printer;
+
+ if (p != NULL) {
+ if (p->attributes != NULL)
+ papiAttributeListFree(p->attributes);
+ free(p);
+ }
+}
+
+void
+papiPrinterListFree(papi_printer_t *printers)
+{
+ if (printers != NULL) {
+ int i;
+
+ for (i = 0; printers[i] != NULL; i++)
+ papiPrinterFree(printers[i]);
+ free(printers);
+ }
+}
diff --git a/usr/src/lib/print/libpapi-lpd/common/service.c b/usr/src/lib/print/libpapi-lpd/common/service.c
new file mode 100644
index 0000000000..c39ea0cbb5
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/common/service.c
@@ -0,0 +1,299 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: service.c 163 2006-05-09 15:07:45Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <alloca.h>
+#include <uri.h>
+#include <papi_impl.h>
+
+papi_status_t
+service_fill_in(service_t *svc, char *name)
+{
+ papi_status_t status = PAPI_OK;
+ uri_t *uri = NULL;
+
+ if (svc == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ if (name == NULL)
+ return (PAPI_OK);
+
+ /*
+ * valid URIs are in the form:
+ * lpd://server[:port]/.../queue[#extensions]
+ * rfc-1179://server[:port]/.../queue[#extensions]
+ * any authentication information supplied the URI is ignored.
+ */
+ if (uri_from_string((char *)name, &uri) != -1) {
+ if ((strcasecmp(uri->scheme, "lpd") == 0) ||
+ (strcasecmp(uri->scheme, "rfc-1179") == 0)) {
+ if (svc->uri != NULL)
+ uri_free(svc->uri);
+ svc->uri = uri;
+ } else {
+ uri_free(uri);
+ status = PAPI_URI_SCHEME;
+ }
+ }
+
+ return (status);
+}
+
+papi_status_t
+papiServiceCreate(papi_service_t *handle, char *service_name,
+ char *user_name, char *password,
+ int (*authCB)(papi_service_t svc, void *app_data),
+ papi_encryption_t encryption, void *app_data)
+{
+ papi_status_t status;
+ service_t *svc = NULL;
+
+ if (handle == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ if ((*handle = svc = (service_t *)calloc(1, sizeof (*svc))) == NULL)
+ return (PAPI_TEMPORARY_ERROR);
+
+ if (service_name != NULL)
+ papiAttributeListAddString(&svc->attributes, PAPI_ATTR_EXCL,
+ "service-name", service_name);
+
+ (void) papiServiceSetUserName(svc, user_name);
+ (void) papiServiceSetPassword(svc, password);
+ (void) papiServiceSetAuthCB(svc, authCB);
+ (void) papiServiceSetAppData(svc, app_data);
+ (void) papiServiceSetEncryption(svc, encryption);
+
+ status = service_fill_in(svc, service_name);
+
+ return (status);
+}
+
+void
+papiServiceDestroy(papi_service_t handle)
+{
+ if (handle != NULL) {
+ service_t *svc = handle;
+
+#ifdef DEADBEEF
+ if (svc->cache != NULL)
+ cache_free(svc->cache);
+#endif
+ if (svc->uri != NULL)
+ uri_free(svc->uri);
+ if (svc->attributes != NULL)
+ papiAttributeListFree(svc->attributes);
+ free(svc);
+ }
+}
+
+papi_status_t
+papiServiceSetUserName(papi_service_t handle, char *user_name)
+{
+ service_t *svc = handle;
+
+ if (svc == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ return (papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE,
+ "user-name", user_name));
+}
+
+papi_status_t
+papiServiceSetPassword(papi_service_t handle, char *password)
+{
+ service_t *svc = handle;
+
+ if (svc == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ return (papiAttributeListAddString(&svc->attributes,
+ PAPI_ATTR_REPLACE, "password", password));
+}
+
+papi_status_t
+papiServiceSetEncryption(papi_service_t handle,
+ papi_encryption_t encryption)
+{
+ service_t *svc = handle;
+
+ if (svc == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ return (papiAttributeListAddInteger(&svc->attributes, PAPI_ATTR_REPLACE,
+ "encryption", (int)encryption));
+}
+
+papi_status_t
+papiServiceSetAuthCB(papi_service_t handle,
+ int (*authCB)(papi_service_t svc, void *app_data))
+{
+ service_t *svc = handle;
+
+ if (svc == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ svc->authCB = (int (*)(papi_service_t svc, void *))authCB;
+
+ return (PAPI_OK);
+}
+
+papi_status_t
+papiServiceSetAppData(papi_service_t handle, void *app_data)
+{
+ service_t *svc = handle;
+
+ if (svc == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ svc->app_data = (void *)app_data;
+
+ return (PAPI_OK);
+}
+
+char *
+papiServiceGetServiceName(papi_service_t handle)
+{
+ service_t *svc = handle;
+ char *result = NULL;
+
+ if (svc != NULL)
+ papiAttributeListGetString(svc->attributes, NULL,
+ "service-name", &result);
+
+ return (result);
+}
+
+char *
+papiServiceGetUserName(papi_service_t handle)
+{
+ service_t *svc = handle;
+ char *result = NULL;
+
+ if (svc != NULL)
+ papiAttributeListGetString(svc->attributes, NULL,
+ "user-name", &result);
+
+ return (result);
+
+}
+
+char *
+papiServiceGetPassword(papi_service_t handle)
+{
+ service_t *svc = handle;
+ char *result = NULL;
+
+ if (svc != NULL)
+ papiAttributeListGetString(svc->attributes, NULL,
+ "password", &result);
+
+ return (result);
+}
+
+papi_encryption_t
+papiServiceGetEncryption(papi_service_t handle)
+{
+ service_t *svc = handle;
+ papi_encryption_t result = PAPI_ENCRYPT_NEVER;
+
+ if (svc != NULL)
+ papiAttributeListGetInteger(svc->attributes, NULL,
+ "encryption", (int *)&result);
+
+ return (result);
+}
+
+void *
+papiServiceGetAppData(papi_service_t handle)
+{
+ service_t *svc = handle;
+ void *result = NULL;
+
+ if (svc != NULL) {
+ result = svc->app_data;
+ }
+
+ return (result);
+
+}
+
+papi_attribute_t **
+papiServiceGetAttributeList(papi_service_t handle)
+{
+ service_t *svc = handle;
+ papi_attribute_t **result = NULL;
+
+ if (svc != NULL)
+ result = svc->attributes;
+
+ return (result);
+}
+
+char *
+papiServiceGetStatusMessage(papi_service_t handle)
+{
+ service_t *svc = handle;
+ char *result = NULL;
+
+ if (svc != NULL) {
+ papiAttributeListGetString(svc->attributes, NULL,
+ "detailed-status-message", &result);
+ }
+
+ return (result);
+}
+
+void
+detailed_error(service_t *svc, char *fmt, ...)
+{
+ if ((svc != NULL) && (fmt != NULL)) {
+ va_list ap;
+ size_t size;
+ char *message = alloca(BUFSIZ);
+
+ va_start(ap, fmt);
+ /*
+ * fill in the message. If the buffer is too small, allocate
+ * one that is large enough and fill it in.
+ */
+ if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ)
+ if ((message = alloca(size)) != NULL)
+ vsnprintf(message, size, fmt, ap);
+ va_end(ap);
+
+ papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
+ "detailed-status-message", message);
+ }
+}
diff --git a/usr/src/lib/print/libpapi-lpd/i386/Makefile b/usr/src/lib/print/libpapi-lpd/i386/Makefile
new file mode 100644
index 0000000000..362f811e03
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/i386/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS) \
+ $(ROOTLIBPRINTPROG)
diff --git a/usr/src/lib/print/libpapi-lpd/sparc/Makefile b/usr/src/lib/print/libpapi-lpd/sparc/Makefile
new file mode 100644
index 0000000000..362f811e03
--- /dev/null
+++ b/usr/src/lib/print/libpapi-lpd/sparc/Makefile
@@ -0,0 +1,31 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS) \
+ $(ROOTLIBPRINTPROG)
diff --git a/usr/src/lib/print/libprint/Makefile b/usr/src/lib/print/libprint/Makefile
new file mode 100644
index 0000000000..55847e0be0
--- /dev/null
+++ b/usr/src/lib/print/libprint/Makefile
@@ -0,0 +1,54 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../../Makefile.lib
+
+SUBDIRS = $(MACH)
+#$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all clean clobber install: .WAIT $(SUBDIRS)
+
+lint: # $(SUBDIRS)
+
+install_h:
+
+check:
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/print/libprint/Makefile.com b/usr/src/lib/print/libprint/Makefile.com
new file mode 100644
index 0000000000..6b7e190b11
--- /dev/null
+++ b/usr/src/lib/print/libprint/Makefile.com
@@ -0,0 +1,61 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = libprint.a
+VERS = .2
+OBJECTS = \
+ job.o list.o misc.o network.o ns.o ns_bsd_addr.o ns_cmn_kvp.o \
+ ns_cmn_printer.o nss_convert.o nss_ldap.o nss_printer.o nss_write.o
+
+include ../../../Makefile.lib
+include ../../../Makefile.rootfs
+
+ROOTLIBDIR= $(ROOT)/usr/lib
+
+LIBS = $(DYNLIB)
+
+SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c)
+
+$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ../common
+MAPFILE = $(SRCDIR)/mapfile-vers
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -I$(SRCDIR)
+CPPFLAGS += -I../../head -D_REENTRANT
+DYNFLAGS += -M $(MAPFILE)
+LDLIBS += -lnsl -lsocket -lc -lldap
+
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include ../../../Makefile.targ
diff --git a/usr/src/lib/print/job.c b/usr/src/lib/print/libprint/common/job.c
index c41dcfaf09..b379648d26 100644
--- a/usr/src/lib/print/job.c
+++ b/usr/src/lib/print/libprint/common/job.c
@@ -43,135 +43,15 @@
#include <libintl.h>
#include <grp.h>
-#include <print/job.h>
-#include <print/misc.h>
-#include <print/list.h>
+#include <job.h>
+#include <misc.h>
+#include <list.h>
#define MAX_RETRIES (5)
- /*
- * These specify important strings in the job routines
- */
-
-static char *_sequence_file = SEQUENCE_FILE;
-static char *_data_file_prefix = DATA_FILE_PREFIX;
static char *_control_file_prefix = CONTROL_FILE_PREFIX;
static char *_xfer_file_prefix = XFER_FILE_PREFIX;
-static char *_temp_file_prefix = TEMP_FILE_PREFIX;
-
-
-/*
- * _job_alloc_id() allocates the next request id number from the number space.
- * It does this by looking for it in a sequence number file in the
- * spooling directory, reading the value, incrementing the file value, and
- * returning the previous file value. If the value falls beyond the number
- * space, the new value will be the begining of the space. If the sequence
- * file doesn't exist, the value will be the start of the number space, and
- * a file will be created. If there is some other error opening or reading
- * the sequence file, a -1 will be returned.
- */
-static int
-_job_alloc_id(char *printer, char *spool)
-{
- char buf[BUFSIZ];
- int fd,
- id,
- rc;
-
- if (snprintf(buf, sizeof (buf), "%s/%s", spool, _sequence_file)
- >= sizeof (buf)) {
-
- syslog(LOG_ERR, "_job_alloc_id: buffer overflow");
- return (-1);
- }
-
- fd = open(buf, O_RDWR);
- if ((fd < 0) && (errno == ENOENT))
- fd = open(buf, O_CREAT|O_EXCL|O_RDWR, 0664);
- if (fd < 0) {
- syslog(LOG_ERR, "_job_alloc_id(%s): open :%m", printer);
- return (-1);
- }
-
- if (lockf(fd, F_LOCK, 0) < 0) {
- syslog(LOG_ERR, "_job_alloc_id(%s): lock :%m", printer);
- return (-1);
- }
-
- (void) memset(buf, NULL, sizeof (buf));
- if (read(fd, buf, sizeof (buf)) < 0) {
- syslog(LOG_ERR, "_job_alloc_id(%s): read :%m", printer);
- close(fd);
- return (-1);
- }
-
- rc = atoi(buf);
- id = ((rc < JOB_ID_END) ? (rc + 1) : JOB_ID_START);
-
- snprintf(buf, sizeof (buf), "%.3d\n", id);
- if ((lseek(fd, 0, SEEK_SET) == 0) && (ftruncate(fd, 0) == 0))
- write(fd, buf, strlen(buf));
-
- syslog(LOG_DEBUG, "_job_alloc_id(%s): - id %d", printer, rc);
- close(fd);
- return (rc);
-}
-
-
-
-
-/*
- * _job_alloc_file() finds an unused path name in the format:
- * spool_dir/(prefix)(x)(id)hostname, where x is in [A-Za-z]. If all
- * such paths are in use, the routine returns NULL. If it finds an open
- * name, a newly allocated string is returned containing the path.
- */
-static char *
-_job_alloc_file(char *printer, char *prefix, char *spool, char *key, int id,
- char *host)
-{
- char hostname[128],
- buf[BUFSIZ],
- *path;
- int key_position = 0;
-
- if (host == NULL) {
- (void) sysinfo(SI_HOSTNAME, hostname, sizeof (hostname));
- host = hostname;
- }
-
- if (prefix != NULL)
- key_position = strlen(prefix);
-
- if (*key < 'A')
- *key = 'A';
- else if (*key > 'Z' && *key < 'a')
- *key = 'a';
- else if (*key > 'z')
- return (NULL);
-
- if (snprintf(buf, sizeof (buf),
- "%s/%s%c%.3d%s",
- spool, prefix, *key, id, host) >= sizeof (buf)) {
- syslog(LOG_ERR, "libprint:_job_alloc_file buffer overrun");
- return (NULL);
- }
- path = strrchr(buf, '/') + 1;
-
- while (access(buf, F_OK) == 0) {
- if (++path[key_position] == '[')
- path[key_position] = 'a';
- else if (path[key_position] > 'z')
- return (NULL);
- }
-
- *key = path[key_position] + 1;
-
- syslog(LOG_DEBUG, "_job_alloc_file(%s, %s, %c, %d): %s", printer,
- prefix, *key, id, path);
- return (strdup(path));
-}
/*
@@ -190,263 +70,6 @@ _job_unlink_data_file(jobfile_t *file)
return (-1);
}
-
-/*
- * job_create() creates, initializes and returns a new job structure. Part of
- * the initialization includes generating a job id, and filling in the
- * printer and server information.
- */
-job_t *
-job_create(char *printer, char *server, char *spool)
-{
- job_t *tmp;
- int id;
-
- if ((printer == NULL) || (server == NULL) || (spool == NULL))
- return (NULL);
- if ((id = _job_alloc_id(printer, spool)) == -1)
- return (NULL);
-
- if ((tmp = (job_t *)calloc(1, sizeof (*tmp))) != NULL) {
- tmp->job_id = id;
- tmp->job_printer = printer;
- tmp->job_server = server;
- tmp->job_spool_dir = strdup(spool);
- tmp->job_df_next = 'A';
- }
- syslog(LOG_DEBUG, "job_create(%s, %s): %d", printer, server,
- (tmp != NULL ? tmp->job_id : -1));
- return (tmp);
-}
-
-
-/*
- * job_primative() appends an rfc1179(BSD printing) control message into the
- * job structure's control data. If the message would extend beyond the
- * memory currently allocated for control data, a new buffer is
- * realloc()'d and the message is appended to the new buffer.
- */
-int
-job_primative(job_t *job, char option, char *value)
-{
- char buf[BUFSIZ];
- char key = 'A';
- jobfile_t *cf;
-
- if ((job == NULL) || (value == NULL))
- return (-1);
-
- cf = job->job_cf;
- if (cf == NULL) {
- if ((cf = calloc(1, sizeof (*cf))) == NULL) {
- syslog(LOG_DEBUG, "job_primative(): calloc() failed");
- return (-1);
- }
- cf->jf_spl_path = _job_alloc_file(job->job_printer,
- _control_file_prefix,
- job->job_spool_dir, &key, job->job_id,
- job->job_host);
- job->job_cf = cf;
- }
-
- cf->jf_size += (strlen(value) + 2); /* (opt)(value)\n(NULL) */
- if (cf->jf_data == NULL) {
- cf->jf_data = calloc(1, cf->jf_size + 1);
- } else
- cf->jf_data = realloc(cf->jf_data, cf->jf_size + 1);
-
- if (cf->jf_data == NULL) {
- syslog(LOG_DEBUG, "job_primative(%d, %c, %s): alloc() failed",
- job->job_id, option, value);
- return (-1);
- }
-
- if (snprintf(buf, sizeof (buf), "%c%s\n", option, value)
- >= sizeof (buf)) {
- syslog(LOG_ERR, "libprint:job_primative: buffer overrun");
- return (-1);
- }
- (void) strlcat(cf->jf_data, buf, cf->jf_size + 1);
-
- if (option == CF_USER)
- job->job_user = strdup(value);
- if (option == CF_HOST)
- job->job_host = strdup(value);
-
- syslog(LOG_DEBUG, "job_primative(%d, %c, %s)", job->job_id, option,
- value);
- return (0);
-}
-
-
-/*
- * job_svr4_primative() builds new arguments to call job_primative() with.
- * it is strictly for use with the rfc1179 like options that were added
- * to the protocol to support SVR4 printing features not supported in the
- * protocol.
- */
-int
-job_svr4_primative(job_t *job, char option, char *value)
-{
- char buf[BUFSIZ];
-
- if (value == NULL)
- return (-1);
-
- if (snprintf(buf, sizeof (buf), "%c%s", option, value)
- >= sizeof (buf)) {
- syslog(LOG_ERR, "libprint:job_svr4_primative: buffer overrun");
- return (-1);
- }
- return (job_primative(job, CF_SYSV_FEATURE, buf));
-}
-
-
-/*
- * job_add_data_file() adds a data file into a job structure. It does this
- * by allocating a new temporary spooling file, adding control messages
- * to the control data so the job prints and files unlink on the server.
- * It copies the path passed in to the temporary file, it also adds
- * the temporary file name to the job_df_list.
- */
-int
-job_add_data_file(job_t *job, char *path, char *title, char type, int copies,
- int linked, int delete)
-{
- char full_path[BUFSIZ],
- *dfName;
- jobfile_t *file;
- struct stat st;
-
- errno = EINVAL;
-
- if ((job == NULL) || (path == NULL))
- return (-1);
-
-
- if (access(path, R_OK) < 0) { /* can we read this file */
- int result = -1;
- gid_t gid = getgid(),
- egid = getegid();
-
- if (gid != egid) { /* if it's set-gid, try the egid */
- (void) setgid(egid);
- result = access(path, R_OK);
- (void) setgid(gid);
- (void) setegid(egid);
- }
-
- if (result != 0)
- return (result);
- }
-
- if (stat(path, &st) < 0) /* stat failed */
- return (-1);
-
- if (S_ISREG(st.st_mode) == 0) { /* not a regular file */
- errno = EISDIR;
- return (-1);
- }
-
- if (st.st_size == 0) { /* empty file */
- errno = ESRCH;
- return (-1);
- }
-
- if ((dfName = _job_alloc_file(job->job_printer, _data_file_prefix,
- job->job_spool_dir, &(job->job_df_next),
- job->job_id, job->job_host)) == NULL) {
- errno = ENFILE;
- return (-1);
- }
-
- if ((file = (jobfile_t *)calloc(1, sizeof (*file))) == NULL) {
- job->job_df_next--;
- return (-1);
- }
-
- if (linked == 0) {
- file->jf_size = map_in_file(path, &file->jf_data, 1);
- file->jf_mmapped = 1;
- } else
- file->jf_size = access(path, R_OK);
-
- if (file->jf_size < 0) {
- free(file);
- job->job_df_next--;
- return (-1);
- }
-
- (void) memset(full_path, NULL, sizeof (full_path));
- if (path[0] != '/') {
- int rc = 0;
-
- /*
- * getcwd() makes use of the effective uid/gid.
- * Set them to job owner uid/gid.
- */
- rc = initgroups(job->job_user, getgid());
- if (rc != 0) {
- syslog(LOG_DEBUG, "job_add_data_file(): failed "
- "to initgroups() (errno: %d)", errno);
- }
- rc = seteuid(getuid());
- if (rc != 0) {
- syslog(LOG_DEBUG, "job_add_data_file(): failed "
- "to seteuid() to uid (errno: %d)", errno);
- }
- rc = setegid(getgid());
- if (rc != 0) {
- syslog(LOG_DEBUG, "job_add_data_file(): failed "
- "to setegid() to gid (errno: %d)", errno);
- }
-
- (void) getcwd(full_path, sizeof (full_path));
-
- /* set back euid/egid to previous values */
- rc = seteuid(0);
- if (rc != 0) {
- syslog(LOG_DEBUG, "job_add_data_file(): failed "
- "to reset euid (errno: %d)", errno);
- }
- rc = initgroups("root", 1);
- if (rc != 0) {
- syslog(LOG_DEBUG, "job_add_data_file(): failed "
- "to reset groups (errno: %d)", errno);
- }
-
- (void) strlcat(full_path, "/", sizeof (full_path));
- }
- if (strlcat(full_path, path,
- sizeof (full_path)) >= sizeof (full_path)) {
- syslog(LOG_ERR, "job_add_data_file:buffer overflow");
- return (-1);
- }
-
- file->jf_spl_path = strdup(dfName);
- file->jf_src_path = strdup(full_path);
- file->jf_name = strdup((title?title:path));
-
- job->job_df_list = (jobfile_t **)list_append((void **)
- job->job_df_list,
- (void *)file);
-
- if (type == CF_PRINT_PR)
- (void) job_primative(job, CF_TITLE, (title ? title : path));
- while (copies--)
- (void) job_primative(job, type, dfName);
- (void) job_primative(job, CF_UNLINK, dfName);
- if (delete != 0)
- (void) job_primative(job, CF_UNLINK, full_path);
- (void) job_primative(job, CF_SOURCE_NAME, (title?title:path));
-
- syslog(LOG_DEBUG, "job_add_data_file((%d, %s, %s), %s, %s, %d, %d, %d)",
- job->job_id, job->job_printer, job->job_server, path,
- ((title != NULL) ? title : "NULL"), type, copies, linked);
- return (linked ? st.st_size : file->jf_size);
-}
-
-
/*
*
*/
@@ -565,137 +188,7 @@ job_destroy(job_t *job)
job_free(job);
}
-
-/*
- * _vjob_store_df() moves a data file from memory to disk. Called by
- * list_iterate().
- */
-static int
-_vjob_store_df(jobfile_t *file)
-{
- if ((file->jf_data == NULL) && (file->jf_size == 0) &&
- (symlink(file->jf_src_path, file->jf_spl_path) == 0))
- return (0);
- if (file->jf_data != NULL)
- return (write_buffer(file->jf_spl_path, file->jf_data,
- file->jf_size));
- else
- return (copy_file(file->jf_src_path, file->jf_spl_path));
-}
-
-
-/*
- * job_create_binding_file() finds and opens a temporary binding file locking
- * the file then renaming it to the real name returning the open fd.
- */
static int
-job_create_binding_file(job_t *job, char **xfile)
-{
- int fd;
- char *tmp,
- *src,
- *dst;
- char key = 'A';
- int msize;
-
- /* get a temp file name */
- if ((tmp = _job_alloc_file(job->job_printer, _temp_file_prefix,
- job->job_spool_dir, &key,
- job->job_id, job->job_host)) == NULL)
- return (-1);
- key = 'A';
- /* get a binding file name */
- if ((*xfile = _job_alloc_file(job->job_printer, _xfer_file_prefix,
- job->job_spool_dir, &key,
- job->job_id, job->job_host)) == NULL)
- return (-1);
-
-
- msize = strlen(job->job_spool_dir) + strlen(tmp) + 3;
- if ((src = calloc(1, msize)) == NULL) {
- syslog(LOG_DEBUG, "job_create_binding_file(): calloc(src)");
- return (-1);
- }
- snprintf(src, msize, "%s/%s", job->job_spool_dir, tmp);
-
- msize = strlen(job->job_spool_dir) + strlen(*xfile) + 3;
- if ((dst = calloc(1, msize)) == NULL) {
- syslog(LOG_DEBUG, "job_create_binding_file(): calloc(dst)");
- free(src);
- return (-1);
- }
- snprintf(dst, msize, "%s/%s", job->job_spool_dir, *xfile);
-
- /*
- * open the tmp file, lock it, and rename it so are guaranteed to
- * have it.
- */
- if ((fd = get_lock(src, 0)) < 0) {
- syslog(LOG_ERR, "creating binding file (%s): %m", src);
- } else if (rename(src, dst) < 0) {
- syslog(LOG_DEBUG, "rename binding file(%s,%s): %m", src, dst);
- close(fd);
- fd = -1;
- }
- free(tmp);
- free(src);
- free(dst);
- return (fd);
-}
-
-
-/*
- * job_store() makes a disk copy of a job structure.
- */
-int
-job_store(job_t *job)
-{
- char buf[BUFSIZ];
- int lock;
- jobfile_t *cf;
- syslog(LOG_DEBUG, "job_store(%d, %s, %s)", job->job_id,
- job->job_printer, job->job_server);
-
- cf = job->job_cf;
-
- /* create the control_file */
- if (snprintf(buf, sizeof (buf), "%s/%s", job->job_spool_dir,
- cf->jf_spl_path) >= sizeof (buf)) {
- syslog(LOG_ERR, "job_store: buffer overrun");
- return (-1);
- }
-
- if (write_buffer(buf, cf->jf_data, strlen(cf->jf_data)) < 0) {
- (void) unlink(cf->jf_src_path);
- return (-1);
- }
-
- /*
- * create and lock the binding file, so nobody has access to the job
- * while it is being created.
- */
- if ((lock = job_create_binding_file(job, &cf->jf_src_path)) < 0)
- return (-1);
-
- /* add the binding information */
- if (snprintf(buf, sizeof (buf), "%s:%s\n", job->job_server,
- job->job_printer) >= sizeof (buf)) {
- syslog(LOG_ERR, "job_store: buffer overrun");
- return (-1);
- }
-
- if (write(lock, buf, strlen(buf)) < 0)
- return (-1);
-
-
- /* store the data files */
- (void) list_iterate((void **)job->job_df_list, (VFUNC_T)_vjob_store_df);
-
- close(lock); /* release the lock */
- return (0);
-}
-
-int
get_job_from_cfile(jobfile_t *file, char *cFile, char *xFile, job_t *tmp)
{
jobfile_t *file1;
diff --git a/usr/src/lib/print/libprint/common/job.h b/usr/src/lib/print/libprint/common/job.h
new file mode 100644
index 0000000000..932d993a16
--- /dev/null
+++ b/usr/src/lib/print/libprint/common/job.h
@@ -0,0 +1,138 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _JOB_H
+#define _JOB_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/va_list.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Sequence number space
+ */
+#define JOB_ID_START 0
+#define JOB_ID_END 999
+
+/*
+ * Job related files
+ */
+#define SEQUENCE_FILE ".seq" /* sequence numbers */
+#define TEMP_FILE_PREFIX "tf" /* printer:server */
+#define XFER_FILE_PREFIX "xf" /* printer:server */
+#define CONTROL_FILE_PREFIX "cf" /* job control data */
+#define DATA_FILE_PREFIX "df" /* job data file */
+
+/*
+ * RFC-1179 Control File Primatives
+ */
+#define CF_CLASS 'C' /* C(ClassName)\n - for banner page */
+#define CF_HOST 'H' /* H(Hostname)\n - host submitting job */
+#define CF_INDENT 'I' /* I(indent)\n - # of spaces for 'f' */
+#define CF_JOBNAME 'J' /* J(Jobname)\n - name of job for banner */
+#define CF_PRINT_BANNER 'L' /* L[User]\n - User name on burst page */
+#define CF_MAIL 'M' /* M(user)\n - User to mail when done */
+#define CF_SOURCE_NAME 'N' /* N(name)\n - source of data file */
+#define CF_USER 'P' /* P(name)\n - requesting user */
+#define CF_SYMLINK 'S' /* S(device) (inode)\n - foget it */
+#define CF_TITLE 'T' /* T(title)\n - for pr */
+#define CF_UNLINK 'U' /* U(file)\n - unlink file */
+#define CF_WIDTH 'W' /* W(width)\n - column width */
+#define CF_FONT_TROFF_R '1' /* 1(file)\n - file with Times Roman font */
+#define CF_FONT_TROFF_I '2' /* 2(file)\n - file with Times Italic font */
+#define CF_FONT_TROFF_B '3' /* 3(file)\n - file with Times Bold font */
+#define CF_FONT_TROFF_S '4' /* 4(file)\n - file with Times Special font */
+#define CF_PRINT_CIF 'c' /* c(file)\n - print/plot file as CIF data */
+#define CF_PRINT_DVI 'd' /* d(file)\n - print file as DVI data */
+#define CF_PRINT_ASCII 'f' /* f(file)\n - print file as ASCII */
+#define CF_PRINT_PLOT 'g' /* g(file)\n - print file as plot data */
+#define CF_KERBERIZED 'k' /* k...\n - for Kerberos */
+#define CF_PRINT_RAW 'l' /* l(file)\n - print file dammit */
+#define CF_PRINT_DROFF 'n' /* n(file)\n - print file as ditroff output */
+#define CF_PRINT_PS 'o' /* o(file)\n - print file as PostScript */
+#define CF_PRINT_PR 'p' /* p(file)\n - print file thru "pr" */
+#define CF_PRINT_FORT 'r' /* r(file)\n - print file as fortran */
+#define CF_PRINT_TROFF 't' /* n(file)\n - print file as troff output */
+#define CF_PRINT_RAS 'v' /* v(file)\n - print file as raster image */
+#define CF_PRINT_PLDM 'z' /* z...\n - for Palladium ??? */
+
+/*
+ * Solaris 2.X LP - BSD protocol extensions
+ */
+#define CF_SYSV_OPTION 'O' /* for SVR4 LP '-o' option */
+#define CF_SYSV_FEATURE '5' /* for SVR4 LP features */
+#define CF_SYSV_FORM 'f' /* for SVR4 Forms */
+#define CF_SYSV_HANDLING 'H' /* for SVR4 Handling */
+#define CF_SYSV_NOTIFICATION 'p' /* for SVR4 Notification */
+#define CF_SYSV_PAGES 'P' /* for SVR4 Pages */
+#define CF_SYSV_PRIORITY 'q' /* for SVR4 Priority */
+#define CF_SYSV_CHARSET 'S' /* for SVR4 Charset */
+#define CF_SYSV_TYPE 'T' /* for SVR4 Type */
+#define CF_SYSV_MODE 'y' /* for SVR4 Mode */
+
+
+typedef struct _jobfile jobfile_t;
+typedef struct _job job_t;
+
+struct _jobfile {
+ char *jf_spl_path; /* df file */
+ char *jf_src_path; /* source file */
+ char *jf_name; /* title/name */
+ char *jf_data; /* ptr to mmapped file */
+ long jf_size; /* size of data */
+ char jf_mmapped; /* is this mmapped or malloced */
+};
+
+struct _job {
+ int job_id;
+ char *job_printer;
+ char *job_server;
+ char *job_user;
+ char *job_host;
+ char *job_spool_dir;
+ jobfile_t *job_cf;
+ char job_df_next;
+ jobfile_t **job_df_list;
+};
+
+
+extern int job_store(job_t *job);
+extern void job_free(job_t *job);
+extern void job_destroy(job_t *job);
+extern job_t *job_retrieve(char *xfer_file, char *spool);
+extern job_t **job_list_append(job_t **list, char *printer,
+ char *server, char *spool);
+extern int vjob_match_attribute(char *attribute, __va_list ap);
+extern int vjob_cancel(job_t *job, __va_list ap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_JOB_H */
diff --git a/usr/src/lib/print/list.c b/usr/src/lib/print/libprint/common/list.c
index 1ca4b79f9c..fd90e58130 100644
--- a/usr/src/lib/print/list.c
+++ b/usr/src/lib/print/libprint/common/list.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1994, 1995, 1996, 1998 by Sun Microsystems, Inc.
- * All Rights Reserved
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -37,7 +36,7 @@
#include <stdlib.h>
#include <strings.h>
-#include <print/list.h>
+#include <list.h>
static int _list_increment = 64; /* just so It can be tuned with adb(1) */
diff --git a/usr/src/lib/print/list.h b/usr/src/lib/print/libprint/common/list.h
index d9e83bfa3c..cb9b62df78 100644
--- a/usr/src/lib/print/list.h
+++ b/usr/src/lib/print/libprint/common/list.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,12 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1998 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _LIST_H
-#define _LIST_H
+#define _LIST_H
#pragma ident "%Z%%M% %I% %E% SMI"
diff --git a/usr/src/lib/print/llib-lprint b/usr/src/lib/print/libprint/common/llib-lprint
index 2dc1ad9911..6d89824e36 100644
--- a/usr/src/lib/print/llib-lprint
+++ b/usr/src/lib/print/libprint/common/llib-lprint
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -78,11 +77,6 @@ struct _job {
jobfile_t **job_df_list;
};
-int job_primative(job_t *job, char option, char *value);
-int job_svr4_primative(job_t *job, char option, char *value);
-int job_add_data_file(job_t *job, char *path, char *title,
- char type, int copies, int linked,
- int delete);
int job_store(job_t *job);
void job_free(job_t *job);
void job_destroy(job_t *job);
@@ -102,8 +96,6 @@ void * list_locate(void **, int (*)(void *, void *), void *);
int list_iterate(void **, int (*)(void *, __va_list), ...);
char * get_user_name(void);
-char *long_date(void);
-char *short_date(void);
int check_client_spool(char *printer);
int get_lock(char *name, int write_pid);
uid_t get_user_id(void);
diff --git a/usr/src/lib/print/mapfile-vers b/usr/src/lib/print/libprint/common/mapfile-vers
index 0c1168eaa2..8cf667fb92 100644
--- a/usr/src/lib/print/mapfile-vers
+++ b/usr/src/lib/print/libprint/common/mapfile-vers
@@ -1,15 +1,9 @@
#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -24,6 +18,12 @@
#
# CDDL HEADER END
#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
# Generic interface definition for usr/src/lib/print.
#
# For information regarding the establishment of versioned definitions see:
@@ -72,13 +72,8 @@ SUNWprivate_2.1 {
list_locate;
list_iterate;
- job_primative; # job support
- job_svr4_primative;
- job_add_data_file;
- job_store;
- job_free;
+ job_free; # job support
job_destroy;
- job_create;
job_retrieve;
job_list_append;
vjob_match_attribute;
@@ -94,9 +89,7 @@ SUNWprivate_2.1 {
net_response;
net_send_file;
- long_date; # misc support
- short_date;
- check_client_spool;
+ check_client_spool; # misc support
get_lock;
get_user_id;
get_user_name;
@@ -108,7 +101,6 @@ SUNWprivate_2.1 {
map_in_file;
write_buffer;
start_daemon;
- kill_process;
files_put_printer; # required for ns_put_printer()
nis_put_printer;
diff --git a/usr/src/lib/print/misc.c b/usr/src/lib/print/libprint/common/misc.c
index 5985766203..f9d7e4e966 100644
--- a/usr/src/lib/print/misc.c
+++ b/usr/src/lib/print/libprint/common/misc.c
@@ -41,39 +41,11 @@
#include <syslog.h>
#include <errno.h>
-#include <print/misc.h>
-#include <print/job.h>
-#include <print/list.h>
+#include <misc.h>
+#include <job.h>
+#include <list.h>
-char *
-long_date()
-{
- static char longDate[64];
- time_t curr;
- struct tm *tm;
-
- memset(longDate, 0, sizeof (longDate));
- (void) time(&curr);
- if ((tm = localtime(&curr)) != NULL)
- (void) strftime(longDate, sizeof (longDate), "%b %d %R %Y", tm);
- return (longDate);
-}
-
-char *
-short_date()
-{
- static char shortDate[64];
- time_t curr;
- struct tm *tm;
-
- memset(shortDate, 0, sizeof (shortDate));
- (void) time(&curr);
- if ((tm = localtime(&curr)) != NULL)
- (void) strftime(shortDate, sizeof (shortDate), "%b %d %R", tm);
- return (shortDate);
-}
-
/*
* info about spool directory that we validate and fix
*/
@@ -390,7 +362,7 @@ start_daemon(int do_fork)
if (lock < 0)
return;
if (do_fork == 0) {
- (void) execle("/usr/bin/lp", MASTER_NAME, NULL, NULL);
+ (void) execle("/usr/lib/print/printd", MASTER_NAME, NULL, NULL);
syslog(LOG_ERR, "start_daemon() - execl: %m");
exit(-1);
} else
@@ -402,7 +374,8 @@ start_daemon(int do_fork)
case 0:
break;
default:
- (void) execl("/usr/bin/lp", MASTER_NAME, NULL);
+ (void) execl("/usr/lib/print/printd", MASTER_NAME,
+ NULL);
syslog(LOG_ERR, "start_daemon() - execl: %m");
exit(-1);
/* NOTREACHED */
diff --git a/usr/src/lib/print/misc.h b/usr/src/lib/print/libprint/common/misc.h
index 0e3165e51b..5821794557 100644
--- a/usr/src/lib/print/misc.h
+++ b/usr/src/lib/print/libprint/common/misc.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1998-2002 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,27 +33,25 @@ extern "C" {
#endif
/* Protocol Defined Requests */
-#define PRINT_REQUEST 1 /* \1printer\n */
-#define XFER_REQUEST 2 /* \2printer\n */
-#define XFER_CLEANUP 1 /* \1 */
-#define XFER_CONTROL 2 /* \2size name\n */
-#define XFER_DATA 3 /* \3size name\n */
+#define PRINT_REQUEST 1 /* \1printer\n */
+#define XFER_REQUEST 2 /* \2printer\n */
+#define XFER_CLEANUP 1 /* \1 */
+#define XFER_CONTROL 2 /* \2size name\n */
+#define XFER_DATA 3 /* \3size name\n */
-#define SHOW_QUEUE_SHORT_REQUEST 3 /* \3printer [users|jobs ...]\n */
-#define SHOW_QUEUE_LONG_REQUEST 4 /* \4printer [users|jobs ...]\n */
-#define REMOVE_REQUEST 5 /* \5printer person [users|jobs ...]\n */
+#define SHOW_QUEUE_SHORT_REQUEST 3 /* \3printer [users|jobs ...]\n */
+#define SHOW_QUEUE_LONG_REQUEST 4 /* \4printer [users|jobs ...]\n */
+#define REMOVE_REQUEST 5 /* \5printer person [users|jobs ...]\n */
-#define ACK_BYTE 0
-#define NACK_BYTE 1
+#define ACK_BYTE 0
+#define NACK_BYTE 1
-#define MASTER_NAME "printd"
-#define MASTER_LOCK "/var/spool/print/.printd.lock"
-#define SPOOL_DIR "/var/spool/print"
-#define TBL_NAME "printers.conf"
+#define MASTER_NAME "printd"
+#define MASTER_LOCK "/var/spool/print/.printd.lock"
+#define SPOOL_DIR "/var/spool/print"
+#define TBL_NAME "printers.conf"
-extern char *long_date();
-extern char *short_date();
extern int check_client_spool(char *printer);
extern int get_lock(char *name, int write_pid);
extern uid_t get_user_id();
@@ -73,4 +70,4 @@ extern int kill_process(char *file);
}
#endif
-#endif /* _MISC_H */
+#endif /* _MISC_H */
diff --git a/usr/src/lib/print/network.c b/usr/src/lib/print/libprint/common/network.c
index 6358e0d44f..109b44a7d5 100644
--- a/usr/src/lib/print/network.c
+++ b/usr/src/lib/print/libprint/common/network.c
@@ -45,8 +45,8 @@
#include <syslog.h>
#include <sys/utsname.h>
-#include <print/network.h>
-#include <print/misc.h>
+#include <network.h>
+#include <misc.h>
static int read_wait_time_sec = 60;
static int write_wait_time_sec = 10;
diff --git a/usr/src/lib/print/network.h b/usr/src/lib/print/libprint/common/network.h
index 15a92301c0..ee88e421d0 100644
--- a/usr/src/lib/print/network.h
+++ b/usr/src/lib/print/libprint/common/network.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,12 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1998 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _NETWORK_H
-#define _NETWORK_H
+#define _NETWORK_H
#pragma ident "%Z%%M% %I% %E% SMI"
diff --git a/usr/src/lib/print/ns.c b/usr/src/lib/print/libprint/common/ns.c
index 7b4ec92f8b..fd0a54bd33 100644
--- a/usr/src/lib/print/ns.c
+++ b/usr/src/lib/print/libprint/common/ns.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1994-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,9 +37,9 @@
#include <nss_dbdefs.h>
#include <syslog.h>
-#include <print/ns.h>
-#include <print/list.h>
-#include <print/misc.h>
+#include <ns.h>
+#include <list.h>
+#include <misc.h>
/*
diff --git a/usr/src/lib/print/ns.h b/usr/src/lib/print/libprint/common/ns.h
index 6614e3fad2..6614e3fad2 100644
--- a/usr/src/lib/print/ns.h
+++ b/usr/src/lib/print/libprint/common/ns.h
diff --git a/usr/src/lib/print/ns_bsd_addr.c b/usr/src/lib/print/libprint/common/ns_bsd_addr.c
index 43d1b7d671..c908d4375c 100644
--- a/usr/src/lib/print/ns_bsd_addr.c
+++ b/usr/src/lib/print/libprint/common/ns_bsd_addr.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,9 +35,9 @@
#include <string.h>
#include <syslog.h>
-#include <print/ns.h>
-#include <print/list.h>
-#include <print/misc.h>
+#include <ns.h>
+#include <list.h>
+#include <misc.h>
/*
* Manipulate bsd_addr structures
diff --git a/usr/src/lib/print/ns_cmn_kvp.c b/usr/src/lib/print/libprint/common/ns_cmn_kvp.c
index dd6f30c870..3fdacd7e5d 100644
--- a/usr/src/lib/print/ns_cmn_kvp.c
+++ b/usr/src/lib/print/libprint/common/ns_cmn_kvp.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,8 +34,8 @@
#include <stdarg.h>
#include <string.h>
-#include <print/ns.h>
-#include <print/list.h>
+#include <ns.h>
+#include <list.h>
/*
* Commonly Used routines...
diff --git a/usr/src/lib/print/ns_cmn_printer.c b/usr/src/lib/print/libprint/common/ns_cmn_printer.c
index a6a8a89ae4..25e344b3c4 100644
--- a/usr/src/lib/print/ns_cmn_printer.c
+++ b/usr/src/lib/print/libprint/common/ns_cmn_printer.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,8 +35,8 @@
#include <string.h>
#include <syslog.h>
-#include <print/ns.h>
-#include <print/list.h>
+#include <ns.h>
+#include <list.h>
extern void ns_kvp_destroy(ns_kvp_t *);
diff --git a/usr/src/lib/print/nss_convert.c b/usr/src/lib/print/libprint/common/nss_convert.c
index e7e29294c1..fae5610b98 100644
--- a/usr/src/lib/print/nss_convert.c
+++ b/usr/src/lib/print/libprint/common/nss_convert.c
@@ -38,9 +38,9 @@
#include <stdarg.h>
#include <syslog.h>
-#include <print/ns.h>
-#include <print/list.h>
-#include <print/misc.h>
+#include <ns.h>
+#include <list.h>
+#include <misc.h>
#define ESCAPE_CHARS "\\\n=:" /* \, \n, =, : */
diff --git a/usr/src/lib/print/nss_ldap.c b/usr/src/lib/print/libprint/common/nss_ldap.c
index 661eef9396..887babc740 100644
--- a/usr/src/lib/print/nss_ldap.c
+++ b/usr/src/lib/print/libprint/common/nss_ldap.c
@@ -39,9 +39,9 @@
#include <libintl.h>
#include <netdb.h> /* for rcmd() */
-#include <print/ns.h>
-#include <print/list.h>
-#include <print/misc.h>
+#include <ns.h>
+#include <list.h>
+#include <misc.h>
#define LDAP_REFERRALS
#include <lber.h>
diff --git a/usr/src/lib/print/nss_printer.c b/usr/src/lib/print/libprint/common/nss_printer.c
index 95a774ff2e..326ba9699e 100644
--- a/usr/src/lib/print/nss_printer.c
+++ b/usr/src/lib/print/libprint/common/nss_printer.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (C) 1998 by Sun Microsystems, Inc
- * All Rights Reserved
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
diff --git a/usr/src/lib/print/nss_write.c b/usr/src/lib/print/libprint/common/nss_write.c
index 8637919e9a..77f894be5a 100644
--- a/usr/src/lib/print/nss_write.c
+++ b/usr/src/lib/print/libprint/common/nss_write.c
@@ -39,9 +39,9 @@
#include <libintl.h>
#include <netdb.h> /* for rcmd() */
-#include <print/ns.h>
-#include <print/list.h>
-#include <print/misc.h>
+#include <ns.h>
+#include <list.h>
+#include <misc.h>
/* escaped chars include delimiters and shell meta characters */
#define ESCAPE_CHARS "\\\n=: `&;|>^$()<*?["
diff --git a/usr/src/lib/print/sunPrinter.at.conf.txt b/usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt
index 0cac14ae95..0cac14ae95 100644
--- a/usr/src/lib/print/sunPrinter.at.conf.txt
+++ b/usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt
diff --git a/usr/src/lib/print/sunPrinter.oc.conf.txt b/usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt
index 77f365819d..77f365819d 100644
--- a/usr/src/lib/print/sunPrinter.oc.conf.txt
+++ b/usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt
diff --git a/usr/src/lib/print/libprint/i386/Makefile b/usr/src/lib/print/libprint/i386/Makefile
new file mode 100644
index 0000000000..3b985583a4
--- /dev/null
+++ b/usr/src/lib/print/libprint/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT)
diff --git a/usr/src/lib/print/libprint/sparc/Makefile b/usr/src/lib/print/libprint/sparc/Makefile
new file mode 100644
index 0000000000..3b985583a4
--- /dev/null
+++ b/usr/src/lib/print/libprint/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT)
diff --git a/usr/src/lib/print/mod_ipp/Makefile b/usr/src/lib/print/mod_ipp/Makefile
new file mode 100644
index 0000000000..8531fb213f
--- /dev/null
+++ b/usr/src/lib/print/mod_ipp/Makefile
@@ -0,0 +1,100 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = mod_ipp.a
+VERS =
+OBJECTS = mod_ipp.o
+
+include ../../Makefile.lib
+include ../../Makefile.rootfs
+
+APACHEMODDIR = $(ROOT)/usr/apache/libexec
+APACHECONFDIR = $(ROOT)/etc/apache
+LISTENERDIR = $(ROOT)/var/lp/ipp-listener
+
+ROOTDIRS = $(ROOT)/usr/apache $(APACHEMODDIR) $(APACHECONFDIR) \
+ $(ROOT)/var/lp $(LISTENERDIR)
+
+$(ROOT)/var/lp:= DIRMODE = 775
+$(ROOT)/var/lp:= FILEMODE = 775
+$(ROOT)/var/lp:= OWNER = lp
+$(ROOT)/var/lp:= GROUP = lp
+
+LIBS = $(DYNLIB)
+
+SRCS = $(OBJECTS:%.o = %.c)
+
+MMAPFILE = mapfile
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -I../libipp-listener/common
+CPPFLAGS += -I../libipp-core/common
+CPPFLAGS += -I/usr/apache/include
+CPPFLAGS += -DEAPI
+ZDEFS = $(ZNODEFS)
+DYNFLAGS += -M$(MMAPFILE)
+LDLIBS += -lipp-listener -lipp-core -lpapi -lc
+
+# SMF manifest
+MANIFEST= ipp-listener.xml
+ROOTMANIFESTDIR= $(ROOT)/var/svc/manifest/application/print
+ROOTMANIFEST= $(MANIFEST:%=$(ROOTMANIFESTDIR)/%)
+$(ROOTMANIFEST) := FILEMODE= 444
+
+# Apache module
+$(APACHEMODDIR)/$(LIBLINKS): $(ROOTDIRS)
+
+# Apache config
+APACHECONFFILE= $(APACHECONFDIR)/httpd-standalone-ipp.conf
+$(APACHECONFFILE) := FILEMODE= 644
+LISTENERFILE= $(LISTENERDIR)/index.html
+$(LISTENERFILE) := FILEMODE= 444
+
+$(ROOT)/var/lp:= OWNER = lp
+$(ROOT)/var/lp:= GROUP = lp
+$(ROOT)/var/lp:= FILEMODE = 0775
+
+$(APACHEMODDIR)/$(LIBLINKS):= FILEMODE = 0555
+
+$(ROOTMANIFESTDIR)/% $(APACHEMODDIR)/% $(APACHECONFDIR)/% $(LISTENERDIR)/%: %
+ $(INS.file)
+
+$(ROOTDIRS):
+ $(INS.dir)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+install: all $(APACHEMODDIR)/$(LIBLINKS) $(APACHECONFFILE) \
+ $(LISTENERFILE) $(ROOTMANIFEST)
+
+install_h:
+
+lint:
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf b/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf
new file mode 100644
index 0000000000..07a4b8dc11
--- /dev/null
+++ b/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf
@@ -0,0 +1,341 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# "$Id: httpd-standalone-ipp.conf,v 1.4 2006/03/24 00:26:54 njacobs Exp $"
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+##
+## httpd-standalone-ipp.conf -- Apache HTTP server configuration file for
+## an Internet Print Protocol (IPP) listener
+##
+
+#
+# Based upon the NCSA server configuration files originally by Rob McCool.
+#
+# This is the main Apache server configuration file. It contains the
+# configuration directives that give the server its instructions.
+# See <URL:http://www.apache.org/docs/> for detailed information about
+# the directives. mod_ipp specific directives are described in the
+# mod_ipp(4) man page.
+#
+
+### Section 1: Global Environment
+#
+# The directives in this section affect the overall operation of Apache,
+# such as the number of concurrent requests it can handle or where it
+# can find its configuration files.
+#
+
+#
+# ServerType is either inetd, or standalone. Inetd mode is only supported on
+# Unix platforms.
+#
+ServerType standalone
+
+#
+# ServerRoot: The top of the directory tree under which the server's
+# configuration, error, and log files are kept.
+#
+# NOTE! If you intend to place this on an NFS (or otherwise network)
+# mounted filesystem then please read the LockFile documentation
+# (available at <URL:http://www.apache.org/docs/mod/core.html#lockfile>);
+# you will save yourself a lot of trouble.
+#
+ServerRoot "/usr/apache"
+
+#
+# The LockFile directive sets the path to the lockfile used when Apache
+# is compiled with either USE_FCNTL_SERIALIZED_ACCEPT or
+# USE_FLOCK_SERIALIZED_ACCEPT. This directive should normally be left at
+# its default value. The main reason for changing it is if the logs
+# directory is NFS mounted, since the lockfile MUST BE STORED ON A LOCAL
+# DISK. The PID of the main server process is automatically appended to
+# the filename.
+#
+#LockFile /var/run/httpd.lock
+LockFile /var/run/httpd-standalone-ipp.lock
+
+#
+# PidFile: The file in which the server should record its process
+# identification number when it starts.
+#
+PidFile /var/run/httpd-standalone-ipp.pid
+
+#
+# ScoreBoardFile: File used to store internal server process information.
+# Not all architectures require this. But if yours does (you'll know because
+# this file will be created when you run Apache) then you *must* ensure that
+# no two invocations of Apache share the same scoreboard file.
+#
+ScoreBoardFile /var/run/httpd-standalone-ipp.scoreboard
+
+#
+# In the standard configuration, the server will process httpd.conf (this
+# file, specified by the -f command line option), srm.conf, and access.conf
+# in that order. The latter two files are now distributed empty, as it is
+# recommended that all directives be kept in a single file for simplicity.
+# The commented-out values below are the built-in defaults. You can have the
+# server ignore these files altogether by using "/dev/null" (for Unix) or
+# "nul" (for Win32) for the arguments to the directives.
+#
+#ResourceConfig conf/srm.conf
+#AccessConfig conf/access.conf
+
+#
+# Timeout: The number of seconds before receives and sends time out.
+#
+Timeout 300
+
+#
+# KeepAlive: Whether or not to allow persistent connections (more than
+# one request per connection). Set to "Off" to deactivate.
+#
+KeepAlive On
+
+#
+# MaxKeepAliveRequests: The maximum number of requests to allow
+# during a persistent connection. Set to 0 to allow an unlimited amount.
+# We recommend you leave this number high, for maximum performance.
+#
+MaxKeepAliveRequests 100
+
+#
+# KeepAliveTimeout: Number of seconds to wait for the next request from the
+# same client on the same connection.
+#
+KeepAliveTimeout 15
+
+#
+# Server-pool size regulation. Rather than making you guess how many
+# server processes you need, Apache dynamically adapts to the load it
+# sees --- that is, it tries to maintain enough server processes to
+# handle the current load, plus a few spare servers to handle transient
+# load spikes (e.g., multiple simultaneous requests from a single
+# Netscape browser).
+#
+# It does this by periodically checking how many servers are waiting
+# for a request. If there are fewer than MinSpareServers, it creates
+# a new spare. If there are more than MaxSpareServers, some of the
+# spares die off. The default values are probably OK for most sites.
+#
+MinSpareServers 1
+MaxSpareServers 2
+
+#
+# Number of servers to start initially --- should be a reasonable ballpark
+# figure.
+#
+StartServers 1
+
+#
+# Limit on total number of servers running, i.e., limit on the number
+# of clients who can simultaneously connect --- if this limit is ever
+# reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW.
+# It is intended mainly as a brake to keep a runaway server from taking
+# the system with it as it spirals down...
+#
+MaxClients 150
+
+#
+# MaxRequestsPerChild: the number of requests each child process is
+# allowed to process before the child dies. The child will exit so
+# as to avoid problems after prolonged use when Apache (and maybe the
+# libraries it uses) leak memory or other resources. On most systems, this
+# isn't really needed, but a few (such as Solaris) do have notable leaks
+# in the libraries. For these platforms, set to something like 10000
+# or so; a setting of 0 means unlimited.
+#
+# NOTE: This value does not include keepalive requests after the initial
+# request per connection. For example, if a child process handles
+# an initial request and 10 subsequent "keptalive" requests, it
+# would only count as 1 request towards this limit.
+#
+MaxRequestsPerChild 10
+
+#
+# Dynamic Shared Object (DSO) Support
+#
+# To be able to use the functionality of a module which was built as a DSO you
+# have to place corresponding `LoadModule' lines at this location so the
+# directives contained in it are actually available _before_ they are used.
+# Please read the file http://httpd.apache.org/docs/dso.html for more
+# details about the DSO mechanism and run `httpd -l' for the list of already
+# built-in (statically linked and thus always available) modules in your httpd
+# binary.
+#
+# Note: The order in which modules are loaded is important. Don't change
+# the order below without expert advice.
+#
+LoadModule access_module libexec/mod_access.so
+LoadModule alias_module libexec/mod_alias.so
+LoadModule auth_module libexec/mod_auth.so
+LoadModule mime_module libexec/mod_mime.so
+LoadModule mime_magic_module libexec/mod_mime_magic.so
+LoadModule ipp_module libexec/mod_ipp.so
+
+# Reconstruction of the complete module list from all available modules
+# (static and shared ones) to achieve correct module execution order.
+# [WHENEVER YOU CHANGE THE LOADMODULE SECTION ABOVE UPDATE THIS, TOO]
+ClearModuleList
+AddModule mod_access.c
+AddModule mod_alias.c
+AddModule mod_auth.c
+AddModule mod_mime.c
+AddModule mod_mime_magic.c
+AddModule mod_ipp.c
+AddModule mod_so.c
+
+### Section 2: 'Main' server configuration
+#
+# The directives in this section set up the values used by the 'main'
+# server, which responds to any requests that aren't handled by a
+# <VirtualHost> definition. These values also provide defaults for
+# any <VirtualHost> containers you may define later in the file.
+#
+# All of these directives may appear inside <VirtualHost> containers,
+# in which case these default settings will be overridden for the
+# virtual host being defined.
+#
+
+#
+# If your ServerType directive (set earlier in the 'Global Environment'
+# section) is set to "inetd", the next few directives don't have any
+# effect since their settings are defined by the inetd configuration.
+# Skip ahead to the ServerAdmin directive.
+#
+
+#
+# Port: The port to which the standalone server listens. For
+# ports < 1023, you will need httpd to be run as root initially.
+#
+Port 631
+
+#
+# If you wish httpd to run as a different user or group, you must run
+# httpd as root initially and it will switch.
+#
+# User/Group: The name (or #number) of the user/group to run httpd as.
+# . On SCO (ODT 3) use "User nouser" and "Group nogroup".
+# . On HPUX you may not be able to use shared memory as nobody, and the
+# suggested workaround is to create a user www and use that user.
+# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET)
+# when the value of (unsigned)Group is above 60000;
+# don't use Group nobody on these systems!
+#
+User lp
+Group lp
+
+#
+# ServerAdmin: Your address, where problems with the server should be
+# e-mailed. This address appears on some server-generated pages, such
+# as error documents.
+#
+ServerAdmin lp@localhost
+
+#
+# ServerName allows you to set a host name which is sent back to clients for
+# your server if it's different than the one the program would get (i.e., use
+# "www" instead of the host's real name).
+#
+# Note: You cannot just invent host names and hope they work. The name you
+# define here must be a valid DNS name for your host. If you don't understand
+# this, ask your network administrator.
+# If your host doesn't have a registered DNS name, enter its IP address here.
+# You will have to access it by its address (e.g., http://123.45.67.89/)
+# anyway, and this will make redirections work in a sensible way.
+#
+# 127.0.0.1 is the TCP/IP local loop-back address, often named localhost. Your
+# machine always knows itself by this address. If you use Apache strictly for
+# local testing and development, you may use 127.0.0.1 as the server name.
+#
+#Servername printserver.some_company.com
+
+DefaultType application/ipp
+
+ErrorLog /var/lp/logs/ipp-errors
+LogLevel warn
+
+DocumentRoot /var/lp/ipp-listener
+
+# Allow passing PPD files from this service as well
+Alias /etc/lp/ppd/ /etc/lp/ppd/
+<Directory /etc/lp/ppd>
+ SetHandler send-as-is
+ <LimitExcept GET>
+ Deny from all
+ </LimitExcept>
+</Directory>
+
+# mod_ipp specific configuration
+<IfModule mod_ipp.c>
+
+ <Location />
+ # ipp-conformance automatic # default
+ # ipp-default-user nobody
+ ipp-default-service lpsched
+ #
+ # By default, only turn on operations that are not
+ # likely to cause real problems when the user can't
+ # be trusted.
+ #
+ ipp-operation all off
+ ipp-operation print-job on
+ ipp-operation validate-job on
+ ipp-operation create-job on
+ ipp-operation get-jobs on
+ ipp-operation get-printer-attributes on
+ ipp-operation send-document on
+ ipp-operation cancel-job on
+ ipp-operation get-job-attributes on
+ ipp-operation cups-get-default on
+ ipp-operation cups-get-printers on
+ ipp-operation cups-get-classes on
+ ipp-operation cups-move-job on
+
+ # redirect non-IPP requests
+ ErrorDocument 404 /index.html
+ </Location>
+
+ <Location /admin>
+ # ipp-conformance automatic # default
+ # ipp-default-user nobody
+ ipp-default-service lpsched
+
+ ipp-operation all on
+
+ AuthType Basic
+ AuthName "IPP Server"
+ AuthUserFile /etc/ipp-users
+ Require valid-user
+
+ # redirect non-IPP requests
+ ErrorDocument 404 /index.html
+ </Location>
+</IfModule>
+
diff --git a/usr/src/lib/print/mod_ipp/index.html b/usr/src/lib/print/mod_ipp/index.html
new file mode 100644
index 0000000000..15f680c666
--- /dev/null
+++ b/usr/src/lib/print/mod_ipp/index.html
@@ -0,0 +1,44 @@
+<!--
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+
+ Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ ident "%Z%%M% %I% %E% SMI"
+-->
+<html>
+<body>
+The Internet Print Protocol (IPP) requires that all protocol requests be
+encapsulated in HTTP and that all HTTP protocol requests be POST requests with
+a Content-Type of "application/ipp". Since your request did not meet this
+criteria, it has been ignored by the IPP listener. You will be redirected to
+the
+<a href=http://docs.sun.com/db?q=%22Internet+Print+Protocol%22&p=prod%2Fsolaris>
+<b>Solaris&reg</b> AnswerBook
+</a>
+so that you can learn more about the Internet Print Protocol Listener.
+<p>
+If you would like more information about the Internet Print Protocol itself,
+please visit <a href=http://www.pwg.org/ipp>http://www.pwg.org/ipp/</a>.
+</body>
+</html>
+<meta HTTP-EQUIV=REFRESH CONTENT=10;URL=http://docs.sun.com/db?q=%22Internet+Print+Protocol%22&p=prod%2Fsolaris>
diff --git a/usr/src/lib/print/mod_ipp/ipp-listener.xml b/usr/src/lib/print/mod_ipp/ipp-listener.xml
new file mode 100644
index 0000000000..5f45219775
--- /dev/null
+++ b/usr/src/lib/print/mod_ipp/ipp-listener.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+<!--
+CDDL HEADER START
+
+The contents of this file are subject to the terms of the
+Common Development and Distribution License (the "License").
+You may not use this file except in compliance with the License.
+
+You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+or http://www.opensolaris.org/os/licensing.
+See the License for the specific language governing permissions
+and limitations under the License.
+
+When distributing Covered Code, include this CDDL HEADER in each
+file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+If applicable, add the following below this CDDL HEADER, with the
+fields enclosed by brackets "[]" replaced with your own identifying
+information: Portions Copyright [yyyy] [name of copyright owner]
+
+CDDL HEADER END
+-->
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ pragma ident "%Z%%M% %I% %E% SMI"
+-->
+
+<service_bundle type='manifest' name='SUNWipplr:ipp-listener'>
+
+<service
+ name='application/print/ipp-listener'
+ type='service'
+ version='1'>
+
+ <dependency name='print-service'
+ grouping='require_any'
+ restart_on='refresh'
+ type='service'>
+ <service_fmri value='svc:/application/print/server' />
+ </dependency>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='/usr/apache/bin/httpd -f /etc/apache/httpd-standalone-ipp.conf'
+ timeout_seconds='10' />
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec='/bin/pkill -f httpd-standalone-ipp.conf'
+ timeout_seconds='5' />
+
+ <instance name='default' enabled='true' />
+
+ <stability value='Unstable' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'>
+ Internet Print Protocol Listening Service
+ </loctext>
+ </common_name>
+ <documentation>
+ <manpage title='mod_ipp' section='4'
+ manpath='/usr/share/man' />
+ </documentation>
+ </template>
+</service>
+
+</service_bundle>
diff --git a/usr/src/lib/print/mod_ipp/mapfile b/usr/src/lib/print/mod_ipp/mapfile
new file mode 100644
index 0000000000..d9db50bca9
--- /dev/null
+++ b/usr/src/lib/print/mod_ipp/mapfile
@@ -0,0 +1,39 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# $Id: mapfile 149 2006-04-25 16:55:01Z njacobs $
+#
+
+# ident "%Z%%M% %I% %E% SMI"
+
+SUNWprivate_1.0 {
+ global:
+ ipp_module;
+
+ local:
+ *;
+};
diff --git a/usr/src/lib/print/mod_ipp/mod_ipp.c b/usr/src/lib/print/mod_ipp/mod_ipp.c
new file mode 100644
index 0000000000..2d9ece2287
--- /dev/null
+++ b/usr/src/lib/print/mod_ipp/mod_ipp.c
@@ -0,0 +1,552 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: mod_ipp.c 149 2006-04-25 16:55:01Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Internet Printing Protocol (IPP) module for Apache.
+ */
+
+#include "ap_config.h"
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include <values.h>
+#include <libintl.h>
+#include <alloca.h>
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_protocol.h"
+#include "http_log.h"
+#include "http_main.h"
+#include "papi.h"
+#ifndef APACHE_RELEASE /* appears to only exist in Apache 1.X */
+#define APACHE2
+#include "apr_compat.h"
+#endif
+
+#include <papi.h>
+#include <ipp-listener.h>
+
+#ifndef APACHE2
+module MODULE_VAR_EXPORT ipp_module;
+#else
+module AP_MODULE_DECLARE_DATA ipp_module;
+#endif
+
+#ifndef AP_INIT_TAKE1 /* Apache 2.X has this, but 1.3.X does not */
+#define AP_INIT_NO_ARGS(directive, action, arg, where, mesg) \
+ { directive, action, arg, where, NO_ARGS, mesg }
+#define AP_INIT_TAKE1(directive, action, arg, where, mesg) \
+ { directive, action, arg, where, TAKE1, mesg }
+#define AP_INIT_TAKE2(directive, action, arg, where, mesg) \
+ { directive, action, arg, where, TAKE2, mesg }
+#endif
+
+typedef struct {
+ int conformance;
+ char *default_user;
+ char *default_svc;
+ papi_attribute_t **operations;
+} IPPListenerConfig;
+
+#ifdef DEBUG
+void
+dump_buffer(FILE *fp, char *tag, char *buffer, int bytes)
+{
+ int i, j, ch;
+
+ fprintf(fp, "%s %d(0x%x) bytes\n", (tag ? tag : ""), bytes, bytes);
+ for (i = 0; i < bytes; i += 16) {
+ fprintf(fp, "%s ", (tag ? tag : ""));
+
+ for (j = 0; j < 16 && (i + j) < bytes; j ++)
+ fprintf(fp, " %02X", buffer[i + j] & 255);
+
+ while (j < 16) {
+ fprintf(fp, " ");
+ j++;
+ }
+
+ fprintf(fp, " ");
+ for (j = 0; j < 16 && (i + j) < bytes; j ++) {
+ ch = buffer[i + j] & 255;
+ if (ch < ' ' || ch == 127)
+ ch = '.';
+ putc(ch, fp);
+ }
+ putc('\n', fp);
+ }
+ fflush(fp);
+}
+#endif
+
+static ssize_t
+read_data(void *fd, void *buf, size_t siz)
+{
+ ssize_t len_read;
+ request_rec *ap_r = (request_rec *)fd;
+
+ len_read = ap_get_client_block(ap_r, buf, siz);
+#ifndef APACHE2
+ ap_reset_timeout(ap_r);
+#endif
+
+#ifdef DEBUG
+ fprintf(stderr, "read_data(0x%8.8x, 0x%8.8x, %d): %d",
+ fd, buf, siz, len_read);
+ if (len_read < 0)
+ fprintf(stderr, ": %s", strerror(errno));
+ putc('\n', stderr);
+ dump_buffer(stderr, "read_data:", buf, len_read);
+#endif
+
+ return (len_read);
+}
+
+static ssize_t
+write_data(void *fd, void *buf, size_t siz)
+{
+ ssize_t len_written;
+ request_rec *ap_r = (request_rec *)fd;
+
+#ifndef APACHE2
+ ap_reset_timeout(ap_r);
+#endif
+#ifdef DEBUG
+ dump_buffer(stderr, "write_data:", buf, siz);
+#endif
+ len_written = ap_rwrite(buf, siz, ap_r);
+
+ return (len_written);
+}
+
+static void
+discard_data(request_rec *r)
+{
+#ifdef APACHE2
+ (void) ap_discard_request_body(r);
+#else
+ /*
+ * This is taken from ap_discard_request_body(). The reason we can't
+ * just use it in Apache 1.3 is that it does various timeout things we
+ * don't want it to do. Apache 2.0 doesn't do that, so we can safely
+ * use the normal function.
+ */
+ if (r->read_chunked || r->remaining > 0) {
+ char dumpbuf[HUGE_STRING_LEN];
+ int i;
+
+ do {
+ i = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN);
+#ifdef DEBUG
+ dump_buffer(stderr, "discarded", dumpbuf, i);
+#endif
+ } while (i > 0);
+ }
+#endif
+}
+
+void _log_rerror(const char *file, int line, int level, request_rec *r,
+ const char *fmt, ...)
+{
+ va_list args;
+ size_t size;
+ char *message = alloca(BUFSIZ);
+
+ va_start(args, fmt);
+ /*
+ * fill in the message. If the buffer is too small, allocate
+ * one that is large enough and fill it in.
+ */
+ if ((size = vsnprintf(message, BUFSIZ, fmt, args)) >= BUFSIZ)
+ if ((message = alloca(size)) != NULL)
+ vsnprintf(message, size, fmt, args);
+ va_end(args);
+
+#ifdef APACHE2
+ ap_log_rerror(file, line, level, NULL, r, message);
+#else
+ ap_log_rerror(file, line, level, r, message);
+#endif
+}
+
+static int
+ipp_handler(request_rec *r)
+{
+ papi_attribute_t **request = NULL, **response = NULL;
+ IPPListenerConfig *config;
+ papi_status_t status;
+ int ret;
+
+ /* Really, IPP is all POST requests */
+ if (r->method_number != M_POST)
+ return (DECLINED);
+
+#ifndef APACHE2
+ /*
+ * An IPP request must have a MIME type of "application/ipp"
+ * (RFC-2910, Section 4, page 19). If it doesn't match this
+ * MIME type, we should decline the request and let someone else
+ * try and handle it.
+ */
+ if (r->headers_in != NULL) {
+ char *mime_type = (char *)ap_table_get(r->headers_in,
+ "Content-Type");
+
+ if ((mime_type == NULL) ||
+ (strcasecmp(mime_type, "application/ipp") != 0))
+ return (DECLINED);
+ }
+#endif
+ /* CHUNKED_DECHUNK might not work right for IPP? */
+ if ((ret = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK)
+ return (ret);
+
+ if (!ap_should_client_block(r))
+ return (HTTP_INTERNAL_SERVER_ERROR);
+
+#ifndef APACHE2
+ ap_soft_timeout("ipp_module: read/reply request ", r);
+#endif
+ /* read the IPP request off the network */
+ status = ipp_read_message(read_data, r, &request, IPP_TYPE_REQUEST);
+
+ if (status != PAPI_OK)
+ _log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "read failed: %s\n", papiStatusString(status));
+#ifdef DEBUG
+ papiAttributeListPrint(stderr, request, "request (%d) ", getpid());
+#endif
+
+ (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
+ "originating-host", (char *)
+#ifdef APACHE2
+ ap_get_remote_host
+ (r->connection, r->per_dir_config, REMOTE_NAME, NULL));
+#else
+ ap_get_remote_host
+ (r->connection, r->per_dir_config, REMOTE_NAME));
+#endif
+
+ (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
+ "uri-port", ap_get_server_port(r));
+ if (r->headers_in != NULL) {
+ char *host = (char *)ap_table_get(r->headers_in, "Host");
+
+ if ((host == NULL) || (host[0] == '\0'))
+ host = (char *)ap_get_server_name(r);
+
+ (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
+ "uri-host", host);
+ }
+ (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
+ "uri-path", r->uri);
+
+ config = ap_get_module_config(r->per_dir_config, &ipp_module);
+ if (config != NULL) {
+ (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
+ "conformance", config->conformance);
+ (void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL,
+ "operations", config->operations);
+ if (config->default_user != NULL)
+ (void) papiAttributeListAddString(&request,
+ PAPI_ATTR_EXCL, "default-user",
+ config->default_user);
+ if (config->default_svc != NULL)
+ (void) papiAttributeListAddString(&request,
+ PAPI_ATTR_EXCL, "default-service",
+ config->default_svc);
+ }
+
+ /*
+ * For Trusted Solaris, pass the fd number of the socket connection
+ * to the backend so the it can be forwarded to the backend print
+ * service to retrieve the sensativity label off of a multi-level
+ * port.
+ */
+ (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
+ "peer-socket", ap_bfileno(r->connection->client, B_RD));
+
+ /* process the request */
+ status = ipp_process_request(request, &response, read_data, r);
+ if (status != PAPI_OK) {
+ errno = 0;
+ _log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "request failed: %s\n", papiStatusString(status));
+ discard_data(r);
+ }
+#ifdef DEBUG
+ fprintf(stderr, "processing result: %s\n", papiStatusString(status));
+ papiAttributeListPrint(stderr, response, "response (%d) ", getpid());
+#endif
+
+ /*
+ * If the client is using chunking and we have not yet received the
+ * final "0" sized chunk, we need to discard any data that may
+ * remain in the post request.
+ */
+ if ((r->read_chunked != 0) &&
+ (ap_table_get(r->headers_in, "Content-Length") == NULL))
+ discard_data(r);
+
+ /* write an IPP response back to the network */
+ r->content_type = "application/ipp";
+
+#ifndef APACHE2
+ ap_send_http_header(r);
+#endif
+
+ status = ipp_write_message(write_data, r, response);
+ if (status != PAPI_OK)
+ _log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "write failed: %s\n", papiStatusString(status));
+#ifdef DEBUG
+ fprintf(stderr, "write result: %s\n", papiStatusString(status));
+ fflush(stderr);
+#endif
+
+ papiAttributeListFree(request);
+ papiAttributeListFree(response);
+
+#ifndef APACHE2
+ ap_kill_timeout(r);
+ if (ap_rflush(r) < 0)
+ _log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "flush failed, response may not have been sent");
+#endif
+
+ return (OK);
+}
+
+
+/*ARGSUSED1*/
+static void *
+create_ipp_dir_config(
+#ifndef APACHE2
+ pool *p,
+#else
+ apr_pool_t *p,
+#endif
+ char *dirspec)
+{
+ IPPListenerConfig *config =
+#ifndef APACHE2
+ ap_pcalloc(p, sizeof (*config));
+#else
+ apr_pcalloc(p, sizeof (*config));
+#endif
+
+ if (config != NULL) {
+ (void) memset(config, 0, sizeof (*config));
+ config->conformance = IPP_PARSE_CONFORMANCE_RASH;
+ config->default_user = NULL;
+ config->default_svc = NULL;
+ (void) ipp_configure_operation(&config->operations, "required",
+ "enable");
+ }
+
+ return (config);
+}
+
+/*ARGSUSED0*/
+static const char *
+ipp_conformance(cmd_parms *cmd, void *cfg, const char *arg)
+{
+ IPPListenerConfig *config = (IPPListenerConfig *)cfg;
+
+ if (strncasecmp(arg, "automatic", 4) == 0) {
+ config->conformance = IPP_PARSE_CONFORMANCE_RASH;
+ } else if (strcasecmp(arg, "1.0") == 0) {
+ config->conformance = IPP_PARSE_CONFORMANCE_LOOSE;
+ } else if (strcasecmp(arg, "1.1") == 0) {
+ config->conformance = IPP_PARSE_CONFORMANCE_STRICT;
+ } else {
+ return ("unknown conformance, try (automatic/1.0/1.1)");
+ }
+
+ return (NULL);
+}
+
+/*ARGSUSED0*/
+static const char *
+ipp_operation(cmd_parms *cmd, void *cfg, char *op, char *toggle)
+{
+ IPPListenerConfig *config = (IPPListenerConfig *)cfg;
+ papi_status_t status;
+
+ status = ipp_configure_operation(&config->operations, op, toggle);
+ switch (status) {
+ case PAPI_OK:
+ return (NULL);
+ case PAPI_BAD_ARGUMENT:
+ return (gettext("internal error (invalid argument)"));
+ default:
+ return (papiStatusString(status));
+ }
+
+ /* NOTREACHED */
+ /* return (gettext("contact your software vendor")); */
+}
+
+static const char *
+ipp_default_user(cmd_parms *cmd, void *cfg, const char *arg)
+{
+ IPPListenerConfig *config = (IPPListenerConfig *)cfg;
+
+ config->default_user = (char *)arg;
+
+ return (NULL);
+}
+
+static const char *
+ipp_default_svc(cmd_parms *cmd, void *cfg, const char *arg)
+{
+ IPPListenerConfig *config = (IPPListenerConfig *)cfg;
+
+ config->default_svc = (char *)arg;
+
+ return (NULL);
+}
+
+#ifdef DEBUG
+/*ARGSUSED0*/
+static const char *
+ipp_module_hang(cmd_parms *cmd, void *cfg)
+{
+ static int i = 1;
+
+ /* wait so we can attach a debugger, assign i = 0, and step through */
+ while (i);
+
+ return (NULL);
+}
+#endif /* DEBUG */
+
+static const command_rec ipp_cmds[] =
+{
+ AP_INIT_TAKE1("ipp-conformance", ipp_conformance, NULL, ACCESS_CONF,
+ "IPP protocol conformance (loose/strict)"),
+ AP_INIT_TAKE2("ipp-operation", ipp_operation, NULL, ACCESS_CONF,
+ "IPP protocol operations to enable/disable)"),
+ AP_INIT_TAKE1("ipp-default-user", ipp_default_user, NULL, ACCESS_CONF,
+ "default user for various operations"),
+ AP_INIT_TAKE1("ipp-default-service", ipp_default_svc, NULL, ACCESS_CONF,
+ "default service for various operations"),
+#ifdef DEBUG
+ AP_INIT_NO_ARGS("ipp-module-hang", ipp_module_hang, NULL, ACCESS_CONF,
+ "hang the module until we can attach a debugger (no args)"),
+#endif
+ { NULL }
+};
+
+#ifdef APACHE2
+/*ARGSUSED0*/
+static const char *
+ipp_method(const request_rec *r)
+{
+ return ("ipp");
+}
+
+/*ARGSUSED0*/
+static unsigned short
+ipp_port(const request_rec *r)
+{
+ return (631);
+}
+
+/* Dispatch list for API hooks */
+/*ARGSUSED0*/
+static void
+ipp_register_hooks(apr_pool_t *p)
+{
+ static const char * const modules[] = { "mod_dir.c", NULL };
+
+ /* Need to make sure we don't get directory listings by accident */
+ ap_hook_handler(ipp_handler, NULL, modules, APR_HOOK_MIDDLE);
+ ap_hook_default_port(ipp_port, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_http_method(ipp_method, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+module AP_MODULE_DECLARE_DATA ipp_module = {
+ STANDARD20_MODULE_STUFF,
+ create_ipp_dir_config, /* create per-dir config */
+ NULL, /* merge per-dir config */
+ NULL, /* create per-server config */
+ NULL, /* merge per-server config */
+ ipp_cmds, /* table of config commands */
+ ipp_register_hooks /* register hooks */
+};
+
+#else /* Apache 1.X */
+
+/* Dispatch list of content handlers */
+static const handler_rec ipp_handlers[] = {
+ /*
+ * This handler association causes all IPP request with the
+ * correct MIME type to call the protocol handler.
+ */
+ { "application/ipp", ipp_handler },
+ /*
+ * This hander association is causes everything to go through the IPP
+ * protocol request handler. This is necessary because client POST
+ * request may be for something outside of the normal printer-uri
+ * space.
+ */
+ { "*/*", ipp_handler },
+
+ { NULL, NULL }
+};
+
+
+module MODULE_VAR_EXPORT ipp_module = {
+ STANDARD_MODULE_STUFF,
+ NULL, /* module initializer */
+ create_ipp_dir_config, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ NULL, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ ipp_cmds, /* table of config file commands */
+ ipp_handlers, /* [#8] MIME-typed-dispatched handlers */
+ NULL, /* [#1] URI to filename translation */
+ NULL, /* [#4] validate user id from request */
+ NULL, /* [#5] check if the user is ok _here_ */
+ NULL, /* [#3] check access by host address */
+ NULL, /* [#6] determine MIME type */
+ NULL, /* [#7] pre-run fixups */
+ NULL, /* [#9] log a transaction */
+ NULL, /* [#2] header parser */
+ NULL, /* child_init */
+ NULL, /* child_exit */
+ NULL /* [#0] post read-request */
+};
+#endif
diff --git a/usr/src/pkgdefs/Makefile b/usr/src/pkgdefs/Makefile
index 2458e078d9..e1c007168e 100644
--- a/usr/src/pkgdefs/Makefile
+++ b/usr/src/pkgdefs/Makefile
@@ -203,6 +203,9 @@ COMMON_SUBDIRS= \
SUNWipfr \
SUNWipfu \
SUNWipoib \
+ SUNWippcore \
+ SUNWipplr \
+ SUNWipplu \
SUNWixgb \
SUNWkrbr \
SUNWkrbu \
@@ -210,6 +213,8 @@ COMMON_SUBDIRS= \
SUNWllc \
SUNWllcr\
SUNWlldap \
+ SUNWlp-cmds \
+ SUNWlpr-cmds \
SUNWkey \
SUNWloc \
SUNWmdar \
@@ -245,6 +250,7 @@ COMMON_SUBDIRS= \
SUNWypr \
SUNWypu \
SUNWpamsc \
+ SUNWpapi \
SUNWpcelx \
SUNWpcmci \
SUNWpcmcu \
@@ -275,6 +281,8 @@ COMMON_SUBDIRS= \
SUNWpppgS \
SUNWpsdpr \
SUNWpsf \
+ SUNWpsm-ipp \
+ SUNWpsm-lpd \
SUNWpmu \
SUNWpsr \
SUNWpsu \
diff --git a/usr/src/pkgdefs/SUNWippcore/Makefile b/usr/src/pkgdefs/SUNWippcore/Makefile
new file mode 100644
index 0000000000..830ffbdf70
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWippcore/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES=depend copyright
+CLEANFILES += action
+
+ACTION=grep SUNWpapi depend > /dev/null || \
+ ( chmod 666 depend; \
+ echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \
+ chmod 444 depend );
+
+.KEEP_STATE:
+
+all: $(FILES) action
+install: all pkg
+
+# action is a pseudotarget denoting completed work on the depend file
+action: depend
+ $(ACTION)
+ touch $@
+
+include ../Makefile.targ
+include ../Makefile.prtarg
diff --git a/usr/src/pkgdefs/SUNWippcore/pkginfo.tmpl b/usr/src/pkgdefs/SUNWippcore/pkginfo.tmpl
new file mode 100644
index 0000000000..80f135c1cf
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWippcore/pkginfo.tmpl
@@ -0,0 +1,57 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWippcore"
+NAME="Internet Printing Protocol(IPP) core libraries, (usr)"
+ARCH="ISA"
+# this should be changed to ONVERS when ON catches up to the version number
+VERSION="13.1,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Internet Print Protocol (IPP) encoding/decoding/operation support"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWippcore/prototype_com b/usr/src/pkgdefs/SUNWippcore/prototype_com
new file mode 100644
index 0000000000..c170f87963
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWippcore/prototype_com
@@ -0,0 +1,52 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# SUNWippcore - Sun Open Printing - IPP libraries
+#
+d none usr 0755 root sys
+d none usr/lib 0755 root bin
+# IPP read/write/marshal/unmarshal
+f none usr/lib/libipp-core.so.0 0755 root bin
+s none usr/lib/libipp-core.so=./libipp-core.so.0
+# IPP operations
+f none usr/lib/libipp-listener.so.0 0755 root bin
+s none usr/lib/libipp-listener.so=./libipp-listener.so.0
+
diff --git a/usr/src/pkgdefs/SUNWippcore/prototype_i386 b/usr/src/pkgdefs/SUNWippcore/prototype_i386
new file mode 100644
index 0000000000..ec7308930a
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWippcore/prototype_i386
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWippcore
+#
diff --git a/usr/src/pkgdefs/SUNWippcore/prototype_sparc b/usr/src/pkgdefs/SUNWippcore/prototype_sparc
new file mode 100644
index 0000000000..d63ead3dda
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWippcore/prototype_sparc
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWippcore
+#
diff --git a/usr/src/pkgdefs/SUNWipplr/Makefile b/usr/src/pkgdefs/SUNWipplr/Makefile
new file mode 100644
index 0000000000..eafb15d98a
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplr/Makefile
@@ -0,0 +1,51 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES=depend copyright i.manifest r.manifest i.preserve
+
+TMPLFILES += preremove
+CLEANFILES += action
+
+ACTION=grep SUNWapchr depend > /dev/null || \
+ ( chmod 666 depend; \
+ echo "P SUNWapchr Apache (root) files" >> depend; \
+ chmod 444 depend );
+
+.KEEP_STATE:
+
+all: $(FILES) action
+install: all pkg
+
+# action is a pseudotarget denoting completed work on the depend file
+action: depend
+ $(ACTION)
+ touch $@
+
+include ../Makefile.targ
+include ../Makefile.prtarg
diff --git a/usr/src/pkgdefs/SUNWipplr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWipplr/pkginfo.tmpl
new file mode 100644
index 0000000000..b0fe1ca73c
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplr/pkginfo.tmpl
@@ -0,0 +1,57 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWipplr"
+NAME="Internet Printing Protocol(IPP) listener, (root)"
+ARCH="ISA"
+# this should be changed to ONVERS when ON catches up to the version number
+VERSION="13.1,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="root"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Internet Printing Protocol(IPP) Apache configuration for service module"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none preserve manifest"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWipplr/preremove.tmpl b/usr/src/pkgdefs/SUNWipplr/preremove.tmpl
new file mode 100644
index 0000000000..fafd44d99e
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplr/preremove.tmpl
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+# If we are removing a "local" version of the package, disable the listener.
+
+[ "${PKG_INSTALL_ROOT:-/}" = "/" ] || exit 0
+
+svcprop -q svc:/application/print/ipp-listener:default || exit 0
+
+/usr/sbin/svcadm disable svc:/application/print/ipp-listener
+
+if [ $? -ne 0 ]; then
+ exit 1
+fi
+
+exit 0
diff --git a/usr/src/pkgdefs/SUNWipplr/prototype_com b/usr/src/pkgdefs/SUNWipplr/prototype_com
new file mode 100644
index 0000000000..0bd888421b
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplr/prototype_com
@@ -0,0 +1,60 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+i preremove
+i i.preserve
+i i.manifest
+i r.manifest
+#
+# SUNWipplr - Sun Open Print Apache IPP Listener root files
+#
+d none etc 0755 root sys
+d none etc/apache 0755 root bin
+e preserve etc/apache/httpd-standalone-ipp.conf 0644 root bin
+# smf(5) manifest for IPP Listener
+d none var 755 root sys
+d none var/lp 775 lp lp
+d none var/lp/ipp-listener 755 root bin
+f none var/lp/ipp-listener/index.html 444 root bin
+d none var/svc 755 root sys
+d none var/svc/manifest 755 root sys
+d none var/svc/manifest/application 755 root sys
+d none var/svc/manifest/application/print 755 root sys
+f manifest var/svc/manifest/application/print/ipp-listener.xml 0444 root sys
diff --git a/usr/src/pkgdefs/SUNWipplr/prototype_i386 b/usr/src/pkgdefs/SUNWipplr/prototype_i386
new file mode 100644
index 0000000000..91f70a1724
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplr/prototype_i386
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWipplr
+#
diff --git a/usr/src/pkgdefs/SUNWipplr/prototype_sparc b/usr/src/pkgdefs/SUNWipplr/prototype_sparc
new file mode 100644
index 0000000000..40316b4cd5
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplr/prototype_sparc
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWipplr
+#
diff --git a/usr/src/pkgdefs/SUNWipplu/Makefile b/usr/src/pkgdefs/SUNWipplu/Makefile
new file mode 100644
index 0000000000..2300581ce5
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplu/Makefile
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES=depend copyright
+CLEANFILES += action
+
+ACTION=grep SUNWpapi depend > /dev/null || \
+ ( chmod 666 depend; \
+ echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \
+ echo "P SUNWippcore Sun Open Print IPP Core libraries" >> depend; \
+ chmod 444 depend );
+
+.KEEP_STATE:
+
+all: $(FILES) action
+install: all pkg
+
+# action is a pseudotarget denoting completed work on the depend file
+action: depend
+ $(ACTION)
+ touch $@
+
+include ../Makefile.targ
+include ../Makefile.prtarg
diff --git a/usr/src/pkgdefs/SUNWipplu/pkginfo.tmpl b/usr/src/pkgdefs/SUNWipplu/pkginfo.tmpl
new file mode 100644
index 0000000000..a07f6c449e
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplu/pkginfo.tmpl
@@ -0,0 +1,57 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWipplu"
+NAME="Internet Printing Protocol(IPP) listener module (/usr)"
+ARCH="ISA"
+# this should be changed to ONVERS when ON catches up to the version number
+VERSION="13.1,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Internet Printing Protocol(IPP) Apache module for listening service"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWipplu/prototype_com b/usr/src/pkgdefs/SUNWipplu/prototype_com
new file mode 100644
index 0000000000..5d313b7b05
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplu/prototype_com
@@ -0,0 +1,48 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# SUNWipplu - Sun Open Print Apache IPP Listener /usr files
+#
+d none usr 0755 root sys
+d none usr/apache 0755 root bin
+d none usr/apache/libexec 0755 root bin
+# Apache/IPP Listener glue code
+f none usr/apache/libexec/mod_ipp.so 0555 root bin
diff --git a/usr/src/pkgdefs/SUNWipplu/prototype_i386 b/usr/src/pkgdefs/SUNWipplu/prototype_i386
new file mode 100644
index 0000000000..629330616b
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplu/prototype_i386
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWipplu
+#
diff --git a/usr/src/pkgdefs/SUNWipplu/prototype_sparc b/usr/src/pkgdefs/SUNWipplu/prototype_sparc
new file mode 100644
index 0000000000..b0e58c0feb
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWipplu/prototype_sparc
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWipplu
+#
diff --git a/usr/src/pkgdefs/SUNWlp-cmds/Makefile b/usr/src/pkgdefs/SUNWlp-cmds/Makefile
new file mode 100644
index 0000000000..830ffbdf70
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWlp-cmds/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES=depend copyright
+CLEANFILES += action
+
+ACTION=grep SUNWpapi depend > /dev/null || \
+ ( chmod 666 depend; \
+ echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \
+ chmod 444 depend );
+
+.KEEP_STATE:
+
+all: $(FILES) action
+install: all pkg
+
+# action is a pseudotarget denoting completed work on the depend file
+action: depend
+ $(ACTION)
+ touch $@
+
+include ../Makefile.targ
+include ../Makefile.prtarg
diff --git a/usr/src/pkgdefs/SUNWlp-cmds/pkginfo.tmpl b/usr/src/pkgdefs/SUNWlp-cmds/pkginfo.tmpl
new file mode 100644
index 0000000000..1eec27a3fc
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWlp-cmds/pkginfo.tmpl
@@ -0,0 +1,59 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWlp-cmds"
+NAME="System V LP commands"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="System V LP commands using the FSG OpenPrinting API (PAPI)"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWlp-cmds/prototype_com b/usr/src/pkgdefs/SUNWlp-cmds/prototype_com
new file mode 100644
index 0000000000..08613b5ab5
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWlp-cmds/prototype_com
@@ -0,0 +1,64 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWpapi-lp-cmds
+#
+d none usr 755 root sys
+d none usr/bin 755 root bin
+f none usr/bin/cancel 0555 root bin
+f none usr/bin/disable 0555 root bin
+f none usr/bin/enable 0555 root bin
+f none usr/bin/lp 0555 root bin
+f none usr/bin/lpstat 0555 root bin
+d none usr/lib 755 root bin
+s none usr/lib/accept=../sbin/accept
+s none usr/lib/lpmove=../sbin/lpmove
+s none usr/lib/reject=../sbin/reject
+d none usr/sbin 755 root bin
+f none usr/sbin/accept 0555 root bin
+f none usr/sbin/lpmove 0555 root bin
+f none usr/sbin/reject 0555 root bin
diff --git a/usr/src/pkgdefs/SUNWlp-cmds/prototype_i386 b/usr/src/pkgdefs/SUNWlp-cmds/prototype_i386
new file mode 100644
index 0000000000..fc0351d75f
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWlp-cmds/prototype_i386
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpapi-lp-cmds
+#
diff --git a/usr/src/pkgdefs/SUNWlp-cmds/prototype_sparc b/usr/src/pkgdefs/SUNWlp-cmds/prototype_sparc
new file mode 100644
index 0000000000..a520804be7
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWlp-cmds/prototype_sparc
@@ -0,0 +1,53 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpapi-lp-cmds
+#
diff --git a/usr/src/pkgdefs/SUNWlpr-cmds/Makefile b/usr/src/pkgdefs/SUNWlpr-cmds/Makefile
new file mode 100644
index 0000000000..830ffbdf70
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWlpr-cmds/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES=depend copyright
+CLEANFILES += action
+
+ACTION=grep SUNWpapi depend > /dev/null || \
+ ( chmod 666 depend; \
+ echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \
+ chmod 444 depend );
+
+.KEEP_STATE:
+
+all: $(FILES) action
+install: all pkg
+
+# action is a pseudotarget denoting completed work on the depend file
+action: depend
+ $(ACTION)
+ touch $@
+
+include ../Makefile.targ
+include ../Makefile.prtarg
diff --git a/usr/src/pkgdefs/SUNWlpr-cmds/pkginfo.tmpl b/usr/src/pkgdefs/SUNWlpr-cmds/pkginfo.tmpl
new file mode 100644
index 0000000000..38f6ab861e
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWlpr-cmds/pkginfo.tmpl
@@ -0,0 +1,58 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWlpr-cmds"
+NAME="Berkeley LPR commands"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Berkeley LPR commands using the FSG OpenPrinting API (PAPI)"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWlpr-cmds/prototype_com b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_com
new file mode 100644
index 0000000000..124d7c7480
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_com
@@ -0,0 +1,53 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWpapi-lpr-cmds
+#
+d none usr 755 root sys
+d none usr/bin 755 root bin
+f none usr/bin/lpc 0555 root bin
+f none usr/bin/lpq 0555 root bin
+f none usr/bin/lpr 0555 root bin
+f none usr/bin/lprm 0555 root bin
diff --git a/usr/src/pkgdefs/SUNWlpr-cmds/prototype_i386 b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_i386
new file mode 100644
index 0000000000..e033491157
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_i386
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpapi-lpr-cmds
+#
diff --git a/usr/src/pkgdefs/SUNWlpr-cmds/prototype_sparc b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_sparc
new file mode 100644
index 0000000000..39517853b2
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_sparc
@@ -0,0 +1,52 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpapi-lpr-cmds
+#
diff --git a/usr/src/pkgdefs/SUNWpapi/Makefile b/usr/src/pkgdefs/SUNWpapi/Makefile
new file mode 100644
index 0000000000..d4b6746b7a
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpapi/Makefile
@@ -0,0 +1,39 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES=depend copyright
+CLEANFILES += action
+
+.KEEP_STATE:
+
+all: $(FILES)
+install: all pkg
+
+include ../Makefile.targ
+include ../Makefile.prtarg
diff --git a/usr/src/pkgdefs/SUNWpapi/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpapi/pkginfo.tmpl
new file mode 100644
index 0000000000..fe0a3fd84b
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpapi/pkginfo.tmpl
@@ -0,0 +1,56 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWpapi"
+NAME="Free Standards Group Open Printing API"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Free Standards Group Open Printing API, Draft v0.9"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWpapi/prototype_com b/usr/src/pkgdefs/SUNWpapi/prototype_com
new file mode 100644
index 0000000000..0949f900fd
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpapi/prototype_com
@@ -0,0 +1,53 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWpapi
+#
+d none usr 755 root sys
+d none usr/lib 755 root bin
+s none usr/lib/libpapi.so=./libpapi.so.0
+f none usr/lib/libpapi.so.0 0755 root bin
+s none usr/lib/libpapi-common.so=./libpapi-common.so.0
+f none usr/lib/libpapi-common.so.0 0755 root bin
+d none usr/include 755 root bin
+f none usr/include/papi.h 644 root bin
diff --git a/usr/src/pkgdefs/SUNWpapi/prototype_i386 b/usr/src/pkgdefs/SUNWpapi/prototype_i386
new file mode 100644
index 0000000000..0b1ae232f0
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpapi/prototype_i386
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpapi
+#
diff --git a/usr/src/pkgdefs/SUNWpapi/prototype_sparc b/usr/src/pkgdefs/SUNWpapi/prototype_sparc
new file mode 100644
index 0000000000..631fb3e1f7
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpapi/prototype_sparc
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpapi
+#
diff --git a/usr/src/pkgdefs/SUNWpcr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpcr/pkginfo.tmpl
index 0930e92e86..3ccaf669cb 100644
--- a/usr/src/pkgdefs/SUNWpcr/pkginfo.tmpl
+++ b/usr/src/pkgdefs/SUNWpcr/pkginfo.tmpl
@@ -34,6 +34,7 @@
PKG="SUNWpcr"
NAME="Solaris Print - Client, (root)"
ARCH="ISA"
+# this should be changed to ONVERS when ON catches up to the version number
VERSION="13.1,REV=0.0.0"
SUNW_PRODNAME="SunOS"
SUNW_PRODVERS="RELEASE/VERSION"
diff --git a/usr/src/pkgdefs/SUNWpcu/Makefile b/usr/src/pkgdefs/SUNWpcu/Makefile
index 89e50717d1..e19a81f92d 100644
--- a/usr/src/pkgdefs/SUNWpcu/Makefile
+++ b/usr/src/pkgdefs/SUNWpcu/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,11 +19,11 @@
# CDDL HEADER END
#
#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
+#ident "%Z%%M% %I% %E% SMI"
+#
include ../Makefile.com
diff --git a/usr/src/pkgdefs/SUNWpcu/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpcu/pkginfo.tmpl
index ea875d4e90..2165dc8f2e 100644
--- a/usr/src/pkgdefs/SUNWpcu/pkginfo.tmpl
+++ b/usr/src/pkgdefs/SUNWpcu/pkginfo.tmpl
@@ -34,6 +34,7 @@
PKG="SUNWpcu"
NAME="Solaris Print - Client, (usr)"
ARCH="ISA"
+# this should be changed to ONVERS when ON catches up to the version number
VERSION="13.1,REV=0.0.0"
SUNW_PRODNAME="SunOS"
SUNW_PRODVERS="RELEASE/VERSION"
diff --git a/usr/src/pkgdefs/SUNWpcu/prototype_com b/usr/src/pkgdefs/SUNWpcu/prototype_com
index ca766ef935..7819733540 100644
--- a/usr/src/pkgdefs/SUNWpcu/prototype_com
+++ b/usr/src/pkgdefs/SUNWpcu/prototype_com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -45,24 +44,13 @@ i preremove
#
d none usr 0755 root sys
d none usr/bin 0755 root bin
-f none usr/bin/cancel 4511 root lp
-s none usr/bin/disable=../sbin/accept
-s none usr/bin/enable=../sbin/accept
-f none usr/bin/lp 4511 root lp
-f none usr/bin/lpc 555 root lp
f none usr/bin/lpget 0511 root lp
-s none usr/bin/lpq=lpstat
-s none usr/bin/lpr=lp
-s none usr/bin/lprm=cancel
f none usr/bin/lpset 4511 root lp
-f none usr/bin/lpstat 4511 root lp
f none usr/bin/lptest 555 root lp
d none usr/lib 0755 root bin
-s none usr/lib/accept=../sbin/accept
f none usr/lib/libprint.so.2 0755 root bin
s none usr/lib/libprint.so=./libprint.so.2
s none usr/lib/lpadmin=../sbin/lpadmin
-s none usr/lib/lpmove=../sbin/lpmove
s none usr/lib/lpsystem=../sbin/lpsystem
d none usr/lib/print 0755 root lp
d none usr/lib/print/bsd-adaptor 0755 root lp
@@ -75,11 +63,7 @@ f none usr/lib/print/in.lpd 0555 root bin
f none usr/lib/print/conv_fix 0555 root lp
f none usr/lib/print/conv_lp 0555 root lp
f none usr/lib/print/conv_lpd 0555 root lp
-s none usr/lib/print/printd=../../bin/lp
-s none usr/lib/reject=../sbin/accept
+f none usr/lib/print/printd 0555 root bin
d none usr/sbin 0755 root bin
-f none usr/sbin/accept 0555 root lp
f none usr/sbin/lpadmin 0555 root lp
-f none usr/sbin/lpmove 4511 root lp
f none usr/sbin/lpsystem 0555 root lp
-s none usr/sbin/reject=../sbin/accept
diff --git a/usr/src/pkgdefs/SUNWpsf/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpsf/pkginfo.tmpl
index 7f88714e47..26edac2f7e 100644
--- a/usr/src/pkgdefs/SUNWpsf/pkginfo.tmpl
+++ b/usr/src/pkgdefs/SUNWpsf/pkginfo.tmpl
@@ -34,6 +34,7 @@
PKG="SUNWpsf"
NAME="PostScript filters - (Usr)"
ARCH="ISA"
+# this should be changed to ONVERS when ON catches up to the version number
VERSION="13.1,REV=0.0.0"
SUNW_PRODNAME="SunOS"
SUNW_PRODVERS="RELEASE/VERSION"
diff --git a/usr/src/pkgdefs/SUNWpsm-ipp/Makefile b/usr/src/pkgdefs/SUNWpsm-ipp/Makefile
new file mode 100644
index 0000000000..2300581ce5
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpsm-ipp/Makefile
@@ -0,0 +1,50 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES=depend copyright
+CLEANFILES += action
+
+ACTION=grep SUNWpapi depend > /dev/null || \
+ ( chmod 666 depend; \
+ echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \
+ echo "P SUNWippcore Sun Open Print IPP Core libraries" >> depend; \
+ chmod 444 depend );
+
+.KEEP_STATE:
+
+all: $(FILES) action
+install: all pkg
+
+# action is a pseudotarget denoting completed work on the depend file
+action: depend
+ $(ACTION)
+ touch $@
+
+include ../Makefile.targ
+include ../Makefile.prtarg
diff --git a/usr/src/pkgdefs/SUNWpsm-ipp/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpsm-ipp/pkginfo.tmpl
new file mode 100644
index 0000000000..142ec31882
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpsm-ipp/pkginfo.tmpl
@@ -0,0 +1,56 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWpsm-ipp"
+NAME="Free Standards Group Open Printing API IPP Print Service Module"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Client side support for communicating with IPP based print servers"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWpsm-ipp/prototype_com b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_com
new file mode 100644
index 0000000000..7ba7ad8f6b
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_com
@@ -0,0 +1,53 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWpsm-ipp
+#
+d none usr 755 root sys
+d none usr/lib 755 root bin
+d none usr/lib/print 755 root lp
+s none usr/lib/print/psm-http.so=./psm-ipp.so
+s none usr/lib/print/psm-ipp.so=./psm-ipp.so.1
+f none usr/lib/print/psm-ipp.so.1 0755 root bin
+s none usr/lib/print/libhttp-core.so=./libhttp-core.so.1
+f none usr/lib/print/libhttp-core.so.1 0755 root bin
diff --git a/usr/src/pkgdefs/SUNWpsm-ipp/prototype_i386 b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_i386
new file mode 100644
index 0000000000..ab88f4de24
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_i386
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpsm-ipp
+#
diff --git a/usr/src/pkgdefs/SUNWpsm-ipp/prototype_sparc b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_sparc
new file mode 100644
index 0000000000..e71982c894
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_sparc
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpsm-ipp
+#
diff --git a/usr/src/pkgdefs/SUNWpsm-lpd/Makefile b/usr/src/pkgdefs/SUNWpsm-lpd/Makefile
new file mode 100644
index 0000000000..830ffbdf70
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpsm-lpd/Makefile
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES=depend copyright
+CLEANFILES += action
+
+ACTION=grep SUNWpapi depend > /dev/null || \
+ ( chmod 666 depend; \
+ echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \
+ chmod 444 depend );
+
+.KEEP_STATE:
+
+all: $(FILES) action
+install: all pkg
+
+# action is a pseudotarget denoting completed work on the depend file
+action: depend
+ $(ACTION)
+ touch $@
+
+include ../Makefile.targ
+include ../Makefile.prtarg
diff --git a/usr/src/pkgdefs/SUNWpsm-lpd/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpsm-lpd/pkginfo.tmpl
new file mode 100644
index 0000000000..8040882278
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpsm-lpd/pkginfo.tmpl
@@ -0,0 +1,56 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWpsm-lpd"
+NAME="Free Standards Group Open Printing API RFC-1179 Print Service Module"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Client side support for communicating with RFC-1179 based print servers"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+SUNW_PKG_THISZONE="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWpsm-lpd/prototype_com b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_com
new file mode 100644
index 0000000000..c64d0aafc4
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_com
@@ -0,0 +1,52 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWpsm-lpd
+#
+d none usr 755 root sys
+d none usr/lib 755 root bin
+d none usr/lib/print 755 root lp
+f none usr/lib/print/lpd-port 4511 root bin
+s none usr/lib/print/psm-rfc-1179.so=./psm-lpd.so
+s none usr/lib/print/psm-lpd.so=./psm-lpd.so.1
+f none usr/lib/print/psm-lpd.so.1 0755 root bin
diff --git a/usr/src/pkgdefs/SUNWpsm-lpd/prototype_i386 b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_i386
new file mode 100644
index 0000000000..0b1ae232f0
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_i386
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpapi
+#
diff --git a/usr/src/pkgdefs/SUNWpsm-lpd/prototype_sparc b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_sparc
new file mode 100644
index 0000000000..631fb3e1f7
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_sparc
@@ -0,0 +1,50 @@
+#
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpapi
+#
diff --git a/usr/src/pkgdefs/SUNWpsr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpsr/pkginfo.tmpl
index e6210c9877..f27008d5d6 100644
--- a/usr/src/pkgdefs/SUNWpsr/pkginfo.tmpl
+++ b/usr/src/pkgdefs/SUNWpsr/pkginfo.tmpl
@@ -34,6 +34,7 @@
PKG="SUNWpsr"
NAME="Solaris Print - LP Server, (root)"
ARCH="ISA"
+# this should be changed to ONVERS when ON catches up to the version number
VERSION="13.1,REV=0.0.0"
SUNW_PRODNAME="SunOS"
SUNW_PRODVERS="RELEASE/VERSION"
diff --git a/usr/src/pkgdefs/SUNWpsu/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpsu/pkginfo.tmpl
index bb547bec40..100f32127a 100644
--- a/usr/src/pkgdefs/SUNWpsu/pkginfo.tmpl
+++ b/usr/src/pkgdefs/SUNWpsu/pkginfo.tmpl
@@ -34,6 +34,7 @@
PKG="SUNWpsu"
NAME="Solaris Print - LP Server, (usr)"
ARCH="ISA"
+# this should be changed to ONVERS when ON catches up to the version number
VERSION="13.1,REV=0.0.0"
SUNW_PRODNAME="SunOS"
SUNW_PRODVERS="RELEASE/VERSION"
diff --git a/usr/src/pkgdefs/SUNWpsu/prototype_com b/usr/src/pkgdefs/SUNWpsu/prototype_com
index 514a48c435..bfa9bb7d81 100644
--- a/usr/src/pkgdefs/SUNWpsu/prototype_com
+++ b/usr/src/pkgdefs/SUNWpsu/prototype_com
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -63,14 +62,7 @@ f none usr/lib/lp/model/uri 555 root lp
# commands that only talk to lpsched
d none usr/lib/lp/local 755 root lp
f none usr/lib/lp/local/lpsched 555 root lp
-f none usr/lib/lp/local/lp 555 root lp
-f none usr/lib/lp/local/lpstat 555 root lp
-f none usr/lib/lp/local/accept 555 root lp
-s none usr/lib/lp/local/disable=./accept
-s none usr/lib/lp/local/enable=./accept
-s none usr/lib/lp/local/reject=./accept
f none usr/lib/lp/local/lpadmin 555 root lp
-f none usr/lib/lp/local/lpmove 555 root lp
f none usr/lib/lp/local/lpsystem 555 root lp
f none usr/lib/lp/local/lpshut 555 root lp
# links maintianed for convenience
diff --git a/usr/src/pkgdefs/SUNWscplp/pkginfo.tmpl b/usr/src/pkgdefs/SUNWscplp/pkginfo.tmpl
index 1cfbc29f3b..c4d6b839df 100644
--- a/usr/src/pkgdefs/SUNWscplp/pkginfo.tmpl
+++ b/usr/src/pkgdefs/SUNWscplp/pkginfo.tmpl
@@ -34,6 +34,7 @@
PKG="SUNWscplp"
NAME="Solaris Print - Source Compatibility, (Usr)"
ARCH="ISA"
+# this should be changed to ONVERS when ON catches up to the version number
VERSION="13.1,REV=0.0.0"
SUNW_PRODNAME="SunOS"
SUNW_PRODVERS="RELEASE/VERSION"