summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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"