summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-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/cmd/cancel.c501
-rw-r--r--usr/src/cmd/lp/cmd/comb.c488
-rw-r--r--usr/src/cmd/lp/cmd/lp.c1082
-rw-r--r--usr/src/cmd/lp/cmd/lpc/Makefile77
-rw-r--r--usr/src/cmd/lp/cmd/lpc/cmds.c432
-rw-r--r--usr/src/cmd/lp/cmd/lpc/cmdtab.c52
-rw-r--r--usr/src/cmd/lp/cmd/lpc/fatalmsg.c158
-rw-r--r--usr/src/cmd/lp/cmd/lpc/global.c44
-rw-r--r--usr/src/cmd/lp/cmd/lpc/lpc.c353
-rw-r--r--usr/src/cmd/lp/cmd/lpc/lpc.h78
-rw-r--r--usr/src/cmd/lp/cmd/lpc/process.c534
-rw-r--r--usr/src/cmd/lp/cmd/lpc/sndrcv.c112
-rw-r--r--usr/src/cmd/lp/cmd/lpc/topq.c210
-rw-r--r--usr/src/cmd/lp/cmd/lpmove.c376
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/accept.c106
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/add_mounted.c267
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/charset.c230
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/class.c103
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/device.c145
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/done.c50
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/form.c188
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/lpstat.c244
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/lpstat.h100
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/output.c289
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/parse.c379
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/printer.c555
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/request.c346
-rw-r--r--usr/src/cmd/lp/cmd/lpstat/send_message.c87
-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/cancel/Makefile86
-rw-r--r--usr/src/cmd/print/cancel/cancel.c378
-rw-r--r--usr/src/cmd/print/cancel/cancel_list.c185
-rw-r--r--usr/src/cmd/print/cancel/cancel_list.h54
-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/Makefile97
-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/lpmove/Makefile77
-rw-r--r--usr/src/cmd/print/lpmove/lpmove.c243
-rw-r--r--usr/src/cmd/print/lpset/lpset.c13
-rw-r--r--usr/src/cmd/print/lpstat/Makefile85
-rw-r--r--usr/src/cmd/print/lpstat/bsd-functions.c256
-rw-r--r--usr/src/cmd/print/lpstat/bsd-functions.h44
-rw-r--r--usr/src/cmd/print/lpstat/lpstat.c806
-rw-r--r--usr/src/cmd/print/lpstat/parse.h49
-rw-r--r--usr/src/cmd/print/lpstat/parse_bsd.c171
-rw-r--r--usr/src/cmd/print/lpstat/sysv-functions.c619
-rw-r--r--usr/src/cmd/print/lpstat/sysv-functions.h50
-rw-r--r--usr/src/cmd/print/scripts/Makefile24
-rw-r--r--usr/src/cmd/print/scripts/accept141
-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.com (renamed from usr/src/cmd/lp/cmd/lpstat/Makefile)75
-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.c (renamed from usr/src/cmd/lp/lib/papi/attribute.c)720
-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.c (renamed from usr/src/cmd/lp/lib/papi/list.c)11
-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.h (renamed from usr/src/cmd/lp/lib/papi/papi.h)265
-rw-r--r--usr/src/lib/print/libpapi-common/common/status.c (renamed from usr/src/cmd/lp/lib/papi/status.c)16
-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
282 files changed, 29605 insertions, 14307 deletions
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/cmd/cancel.c b/usr/src/cmd/lp/cmd/cancel.c
deleted file mode 100644
index 9acdbe805b..0000000000
--- a/usr/src/cmd/lp/cmd/cancel.c
+++ /dev/null
@@ -1,501 +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 1996 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.14 */
-
-#include "stdio.h"
-#include "stdlib.h"
-#include "signal.h"
-#include "string.h"
-#include "errno.h"
-#if defined(__STDC__)
-#include "stdarg.h"
-#else
-#include "varargs.h"
-#endif
-#include "sys/types.h"
-
-#include "lp.h"
-#include "requests.h"
-#include "msgs.h"
-
-#define WHO_AM_I I_AM_CANCEL
-#include "oam.h"
-#include <locale.h>
-
-#define OPT_LIST "u:"
-
-/*
- * There are no sections of code in this progam that have to be
- * protected from interrupts. We do want to catch them, however,
- * so we can clean up properly.
- */
-
-char *users = NULL;
-
-void startup(),
- cleanup(),
- cancel(),
- restart(), /* a misnomer */
- ucancel();
-
-#if defined(__STDC__)
-void send_message ( int , ... );
-void recv_message ( int , ... );
-#else
-void send_message(),
- recv_message();
-#endif
-
-/**
- ** usage()
- **/
-
-void usage ()
-{
- (void) printf("%s\n", gettext("usage: cancel id ... printer ..."));
- (void) printf("%s\n", gettext(" or cancel -u id-list printer ..."));
-
- return;
-}
-
-/**
- ** main()
- **/
-
-int main (argc, argv)
- int argc;
- char *argv[];
-{
- extern int optind,
- opterr,
- optopt,
- getopt();
-
- extern char *optarg;
-
- int c;
-
- char *arg,
- *p,
- **users = 0,
- **pu;
-
- setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- opterr = 0;
-
- while ((c = getopt(argc, argv, OPT_LIST)) != -1) switch (c) {
-
- case 'u':
- if (users)
- LP_ERRMSG1 (WARNING, E_LP_2MANY, 'u');
- users = getlist(optarg, LP_WS, LP_SEP);
- break;
-
- default:
- if (optopt == '?') {
- usage ();
- exit (0);
- }
- (p = "-X")[1] = optopt;
- if (strchr(OPT_LIST, optopt))
- LP_ERRMSG1 (ERROR, E_LP_OPTARG, p);
- else
- LP_ERRMSG1 (ERROR, E_LP_OPTION, p);
- exit (1);
-
- }
-
- if (optind == argc && !users) {
- LP_ERRMSG (ERROR, E_CAN_NOACT);
- exit (1);
- }
-
- startup ();
-
- if (optind == argc)
- for (pu = users; *pu; pu++)
- ucancel (*pu, NAME_ALL);
-
- else while (optind < argc) {
-
- arg = argv[optind++];
-
- if (users) {
- if (isprinter(arg) || STREQU(NAME_ALL, arg))
- for (pu = users; *pu; pu++)
- ucancel (*pu, arg);
- else
- LP_ERRMSG1 (WARNING, E_CAN_BADARG, arg);
- } else
- if (isrequest(arg))
- cancel (arg);
- else if (isprinter(arg))
- restart (arg);
- else
- LP_ERRMSG1 (WARNING, E_CAN_BADARG, arg);
-
- }
-
- cleanup ();
- return (0);
-}
-
-/**
- ** cancel() - CANCEL ONE REQUEST
- **/
-
-void cancel (req)
- char *req;
-{
- short status;
-
- /*
- * Now try to cancel the request.
- */
-
- send_message (S_CANCEL_REQUEST, req);
- recv_message (R_CANCEL_REQUEST, &status);
-
- switch (status) {
-
- case MOK:
- printf(gettext("request \"%s\" cancelled\n"), req);
- break;
-
- case MUNKNOWN:
- case MNOINFO:
- LP_ERRMSG1 (WARNING, E_LP_UNKREQID, req);
- break;
-
- case M2LATE:
- LP_ERRMSG1 (WARNING, E_LP_2LATE, req);
- break;
-
- case MNOPERM:
- LP_ERRMSG1 (WARNING, E_CAN_CANT, req);
- break;
-
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- cleanup ();
- exit (1);
- }
- return;
-}
-
-/**
- ** restart() - CANCEL REQUEST CURRENTLY PRINTING ON GIVEN PRINTER
- **/
-
-void restart (printer)
- char *printer;
-{
- char *req_id,
- *s_ignore;
-
- short status,
- h_ignore;
-
- long l_ignore;
-
-
- /*
- * Get the list of requests queued for this printer.
- */
-
- send_message (S_INQUIRE_PRINTER_STATUS, printer);
- recv_message (
- R_INQUIRE_PRINTER_STATUS,
- &status,
- &s_ignore, /* printer */
- &s_ignore, /* form */
- &s_ignore, /* print_wheel */
- &s_ignore, /* dis_reason */
- &s_ignore, /* rej_reason */
- &h_ignore, /* p_status */
- &req_id,
- &l_ignore, /* dis_date */
- &l_ignore /* rej_date */
- );
-
- switch (status) {
-
- case MOK:
- if (!req_id || !*req_id)
- LP_ERRMSG1 (WARNING, E_LP_PNBUSY, printer);
- else
- cancel (req_id);
- break;
-
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- cleanup ();
- exit (1);
-
- }
-
- return;
-}
-
-/**
- ** ucancel()
- **/
-
-void ucancel (user, printer)
- char * user;
- char * printer;
-{
- int i;
-
- short more;
-
- long status;
-
- char * req_id;
-
-
- send_message (S_CANCEL, printer, user, "");
-
- do {
- recv_message (R_CANCEL, &more, &status, &req_id);
-
- switch (status) {
-
- case MOK:
- printf(gettext("request \"%s\" cancelled\n"), req_id);
- break;
-
- case M2LATE:
- LP_ERRMSG1 (WARNING, E_LP_2LATE, req_id);
- break;
-
- case MNOPERM:
- LP_ERRMSG1 (WARNING, E_CAN_CANT, req_id);
- break;
-
- case MUNKNOWN:
- case MNOINFO:
- if (STREQU(user, NAME_ALL) && STREQU(printer, NAME_ALL))
- LP_ERRMSG (WARNING, E_CAN_ANYUSERANYP);
- else if (STREQU(user, NAME_ALL))
- LP_ERRMSG1 (WARNING, E_CAN_ANYUSERP, printer);
- else if (STREQU(printer, NAME_ALL))
- LP_ERRMSG1 (WARNING, E_CAN_NOUSERANYP, user);
- else
- LP_ERRMSG2 (WARNING, E_CAN_NOUSERP, printer, user);
- break;
-
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- cleanup ();
- exit (1);
- }
-
- } while (more == MOKMORE);
-
- return;
-}
-
-/**
- ** startup() - OPEN MESSAGE QUEUE TO SPOOLER
- **/
-
-void startup ()
-{
- void catch();
-
- /*
- * Open a private queue for messages to the Spooler.
- * An error is deadly.
- */
- if (mopen() == -1) {
-
- switch (errno) {
- case ENOMEM:
- case ENOSPC:
- LP_ERRMSG (ERROR, E_LP_MLATER);
- break;
- default:
- LP_ERRMSG (ERROR, E_LP_NEEDSCHED);
- break;
- }
-
- exit (1);
- }
-
- /*
- * Now that the queue is open, quickly trap signals
- * that we might get so we'll be able to close the
- * queue again, regardless of what happens.
- */
- if(signal(SIGHUP, SIG_IGN) != SIG_IGN)
- signal(SIGHUP, catch);
- if(signal(SIGINT, SIG_IGN) != SIG_IGN)
- signal(SIGINT, catch);
- if(signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- signal(SIGQUIT, catch);
- if(signal(SIGTERM, SIG_IGN) != SIG_IGN)
- signal(SIGTERM, catch);
-}
-
-/**
- ** catch() - CATCH INTERRUPT, HANGUP, ETC.
- **/
-
-void catch (sig)
- int sig;
-{
- signal (sig, SIG_IGN);
- cleanup ();
- exit (1);
-}
-
-/**
- ** cleanup() - CLOSE THE MESSAGE QUEUE TO THE SPOOLER
- **/
-
-void cleanup ()
-{
- (void)mclose ();
- return;
-}
-
-/**
- ** send_message() - HANDLE MESSAGE SENDING TO SPOOLER
- **/
-
-/*VARARGS1*/
-
-void
-#if defined(__STDC__)
-send_message (
- int type,
- ...
-)
-#else
-send_message (type, va_alist)
- int type;
- va_dcl
-#endif
-{
- va_list ap;
-
- char buffer[MSGMAX];
-
-
-#if defined(__STDC__)
- va_start (ap, type);
-#else
- va_start (ap);
-#endif
-
- switch (type) {
-
- case S_INQUIRE_PRINTER_STATUS:
- case S_CANCEL_REQUEST:
- case S_CANCEL:
- (void)_putmessage (buffer, type, ap);
- break;
-
- }
-
- va_end (ap);
-
- if (msend(buffer) == -1) {
- LP_ERRMSG (ERROR, E_LP_MSEND);
- cleanup ();
- exit (1);
- }
-
- return;
-}
-
-/**
- ** recv_message() - HANDLE MESSAGES BACK FROM SPOOLER
- **/
-
-/*VARARGS1*/
-
-void
-#if defined(__STDC__)
-recv_message (
- int type,
- ...
-)
-#else
-recv_message (type, va_alist)
- int type;
- va_dcl
-#endif
-{
- va_list ap;
-
- static char buffer[MSGMAX];
-
- int rc;
-
-
-#if defined(__STDC__)
- va_start (ap, type);
-#else
- va_start (ap);
-#endif
-
- if (mrecv(buffer, MSGMAX) != type) {
- LP_ERRMSG (ERROR, E_LP_MRECV);
- cleanup ();
- exit (1);
- }
-
- switch(type) {
-
- case R_INQUIRE_PRINTER_STATUS:
- case R_CANCEL_REQUEST:
- case R_CANCEL:
- rc = _getmessage(buffer, type, ap);
- if (rc != type) {
- LP_ERRMSG1 (ERROR, E_LP_BADREPLY, rc);
- cleanup ();
- exit (1);
- }
- break;
-
- }
-
- va_end (ap);
-
- return;
-}
diff --git a/usr/src/cmd/lp/cmd/comb.c b/usr/src/cmd/lp/cmd/comb.c
deleted file mode 100644
index 595fed9651..0000000000
--- a/usr/src/cmd/lp/cmd/comb.c
+++ /dev/null
@@ -1,488 +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.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <assert.h>
-#include <signal.h>
-#include <string.h>
-#include <locale.h>
-
-#include "lp.h"
-#include "msgs.h"
-
-#define WHO_AM_I I_AM_COMB
-#include "oam.h"
-
-#define NULL 0
-
-char message[MSGMAX],
- reply[MSGMAX];
-
-void reject(), accept(), enable(), disable();
-
-int
-main(int argc, char *argv[])
-{
- char *p;
-
- (void) setlocale(LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- if (p = strrchr(argv[0], '/'))
- p++;
- else
- p = argv[0];
-
- strncpy(who_am_i+3, p, 14);
-
- if (STREQU(p, "reject")) reject(argc, argv);
- if (STREQU(p, "accept")) accept(argc, argv);
- if (STREQU(p, "enable")) enable(argc, argv);
- if (STREQU(p, "disable")) disable(argc, argv);
-
- return (0);
-}
-
-void startup(), cleanup(), err_exit();
-
-#if defined(__STDC__)
-void catch();
-#else
-int catch();
-#endif
-
-void
-reject(argc, argv)
-int argc;
-char *argv[];
-{
- int i, c, dests = 0, rc = 0;
- char *dest, *reason = "unknown reason";
- int type, size;
- short status;
- extern char *optarg;
- extern int optind, opterr, optopt;
-
- if(argc == 1 || STREQU(argv[1], "-?")) {
-usage:
- printf(gettext("usage: reject [-r [reason]] dest ...\n"));
- cleanup();
- exit(argc == 1);
- }
-
- startup();
-
- opterr = 0; /* disable printing of errors by getopt */
- for(i = 1; i < argc; i++) {
- dest = argv[i];
- if(*(dest) == '-' && strcmp (dest,"-") != 0) {
- optind = i;
- c = getopt(argc, argv, "r:");
- switch (c) {
- case 'r':
- if (isprinter(optarg) || isclass(optarg))
- optind--;
- else
- {
- reason = optarg;
- if (strlen(reason) > (size_t) 1024)
- reason[1024] = '\0';
- }
- break;
-
- case '?':
- if (optopt == '?')
- goto usage;
- LP_ERRMSG1 (ERROR, E_LP_OPTION, argv[optind-1]);
- err_exit();
- }
- i = optind-1;
- } else {
- dests++;
- /* reject(dest, reason) */
- size = putmessage(message, S_REJECT_DEST, dest, reason);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- err_exit();
- }
- if ((type = mrecv(reply, sizeof(reply))) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- err_exit();
- }
- if (type != R_REJECT_DEST
- || getmessage(reply, type, &status) == -1) {
- LP_ERRMSG1(ERROR, E_LP_BADREPLY, type);
- err_exit();
- }
- switch (status) {
- case MOK:
- printf(gettext("destination \"%s\" will no longer accept requests\n"), dest);
- continue;
- case MERRDEST:
- LP_ERRMSG1(WARNING, E_REJ_2TIME, dest);
- break;
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest);
- rc = 1;
- break;
- case MNOPERM:
- LP_ERRMSG (ERROR, E_LP_NOTADM);
- rc = 1;
- break;
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- rc = 1;
- }
- }
- }
-
- cleanup();
-
- if(dests == 0) {
- LP_ERRMSG(ERROR, E_LP_NODEST);
- exit(1);
- }
- exit(rc);
-}
-
-void
-accept(argc, argv)
-int argc;
-char *argv[];
-{
- int size, type, i, rc = 0;
- short status;
- char *dest, *strcpy();
-
- if(argc == 1 || STREQU(argv[1], "-?")) {
-usage:
- printf(gettext("usage: accept dest ...\n"));
- cleanup();
- exit(argc == 1);
- }
-
- startup();
-
- for(i = 1; i < argc; i++) {
- dest = argv[i];
- if (STREQU(dest, "-?"))
- goto usage;
- size = putmessage(message, S_ACCEPT_DEST, dest);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- err_exit();
- }
- if ((type = mrecv(reply, sizeof(reply))) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- err_exit();
- }
- if (type != R_ACCEPT_DEST || getmessage(reply, type, &status) == -1) {
- LP_ERRMSG1 (ERROR, E_LP_BADREPLY, type);
- err_exit();
- }
-
- switch (status) {
- case MOK:
- printf(gettext("destination \"%s\" now accepting requests\n"), dest);
- continue;
- case MERRDEST:
- LP_ERRMSG1(WARNING, E_ACC_2TIME, dest);
- rc = 1;
- break;
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest);
- rc = 1;
- break;
- case MNOPERM:
- LP_ERRMSG (ERROR, E_LP_NOTADM);
- rc = 1;
- break;
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- rc = 1;
- }
- }
-
- cleanup();
- exit(rc);
-}
-
-void
-enable(argc, argv)
-int argc;
-char *argv[];
-{
- int i, type, size, rc = 0;
- short status;
- char *dest, *strcpy();
-
- if(argc == 1 || STREQU(argv[1], "-?")) {
-usage:
- printf(gettext("usage: enable printer ...\n"));
- cleanup();
- exit(argc == 1);
- }
-
- startup();
-
- for(i = 1; i < argc; i++) {
- dest = argv[i];
- if (STREQU(dest, "-?"))
- goto usage;
- if (isclass(dest)) {
- LP_ERRMSG1 (ERROR, E_ENA_CLASS, dest);
- continue; /* MR bl88-02715 */
- }
- size = putmessage(message, S_ENABLE_DEST, dest);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- err_exit();
- }
- if ((type = mrecv(reply, sizeof(reply))) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- err_exit();
- }
- if (type != R_ENABLE_DEST || getmessage(reply, type, &status) == -1) {
- LP_ERRMSG1 (ERROR, E_LP_BADREPLY, type);
- err_exit();
- }
-
- switch (status) {
- case MOK:
- printf(gettext("printer \"%s\" now enabled\n"), dest);
- continue;
- case MERRDEST:
- LP_ERRMSG1(WARNING, E_ENA_2TIME, dest);
- rc = 1;
- break;
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest);
- rc = 1;
- break;
- case MNOPERM:
- LP_ERRMSG (ERROR, E_LP_NOTADM);
- rc = 1;
- break;
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- }
- }
-
- cleanup();
-
- exit(rc);
-}
-
-#define TRUE 1
-#define FALSE 0
-
-void
-disable(argc, argv)
-int argc;
-char **argv;
-{
- int rc = 0, cancel = FALSE, Wait = FALSE,
- dests = 0, type, size, c;
- short status, when;
- char *reason = "unknown reason", *dest, *req_id;
- extern char *optarg;
- extern int optind, opterr, optopt;
-
- if(argc == 1 || STREQU(argv[1], "-?")) {
-usage:
- printf(gettext("usage: disable [-c|-W] [-r [reason]] printer ...\n"));
- cleanup();
- exit(argc == 1);
- }
-
- opterr = 0; /* disable printing of errors by getopt */
- while ((c = getopt(argc, argv, "cWr:")) != -1)
- switch(c) {
- case 'c':
- if (cancel)
- LP_ERRMSG1 (WARNING, E_LP_2MANY, 'c');
- cancel = TRUE;
- break;
- case 'W':
- if (Wait)
- LP_ERRMSG1 (WARNING, E_LP_2MANY, 'W');
- Wait = TRUE;
- break;
- case 'r':
- if (isprinter(optarg) || isclass(optarg))
- optind--;
- else
- {
- reason = optarg;
- if (strlen(reason) > (size_t) 1024)
- reason[1024] = '\0';
- }
- break;
-
- case '?':
- if (optopt == '?')
- goto usage;
- LP_ERRMSG1 (ERROR, E_LP_OPTION, argv[optind-1]);
- exit(1);
- }
-
- if (Wait && cancel) {
- LP_ERRMSG(ERROR, E_LP_OPTCOMB);
- exit(1);
- }
-
- startup();
-
- for ( ;optind < argc; optind++) {
- dest = argv[optind];
- if(*(dest) == '-' && strcmp (dest,"-") != 0) {
- c = getopt(argc, argv, "r:");
- switch (c) {
- case 'r':
- if (isprinter(optarg) || isclass(optarg))
- optind--;
- else
- reason = optarg;
- break;
- case '?':
- LP_ERRMSG1 (ERROR, E_LP_OPTION, argv[optind-1]);
- err_exit();
- }
- optind--;
- } else {
- if (isclass(dest)) {
- LP_ERRMSG1 (ERROR, E_DIS_CLASS, dest);
- continue; /* MR bl88-02715 */
- }
- dests++;
- /* disable(dest, reason, cancel, Wait); */
- when = (Wait) ? 1 : ((cancel) ? 2 : 0);
- size = putmessage(message, S_DISABLE_DEST, dest, reason, when);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- err_exit();
- }
- if ((type = mrecv(reply, sizeof(reply))) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- err_exit();
- }
- if (type != R_DISABLE_DEST
- || getmessage(reply, type, &status, &req_id) == -1) {
- LP_ERRMSG1 (ERROR, E_LP_BADREPLY, type);
- err_exit();
- }
- switch (status) {
- case MOK:
- if (req_id && *req_id)
- printf(gettext("request \"%s\" cancelled\n"), req_id);
- printf(gettext("printer \"%s\" now disabled\n"), dest);
- break;
- case MERRDEST:
- LP_ERRMSG1(WARNING, E_DIS_2TIME, dest);
- break;
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest);
- rc = 1;
- break;
- case MNOPERM:
- LP_ERRMSG (ERROR, E_LP_NOTADM);
- rc = 1;
- break;
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- rc = 1;
- }
- }
- }
-
- cleanup();
-
- if(dests == 0) {
- LP_ERRMSG(ERROR, E_LP_NODEST);
- exit(1);
- }
-
- exit(rc);
-}
-
-void
-startup()
-{
-#if defined(__STDC__)
- void catch();
-#endif
-
- if (mopen()) {LP_ERRMSG(ERROR, E_LP_MOPEN); exit(1);}
-
- if(signal(SIGHUP, SIG_IGN) != SIG_IGN)
- signal(SIGHUP, catch);
- if(signal(SIGINT, SIG_IGN) != SIG_IGN)
- signal(SIGINT, catch);
- if(signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- signal(SIGQUIT, catch);
- if(signal(SIGTERM, SIG_IGN) != SIG_IGN)
- signal(SIGTERM, catch);
-}
-
-/* catch -- catch signals */
-
-#if defined(__STDC__)
-void catch()
-#else
-int catch()
-#endif
-{
-
- signal(SIGHUP, SIG_IGN);
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- err_exit();
-}
-
-void
-cleanup()
-{
- (void)mclose ();
-}
-
-void
-err_exit()
-{
- cleanup();
- exit(1);
-}
diff --git a/usr/src/cmd/lp/cmd/lp.c b/usr/src/cmd/lp/cmd/lp.c
deleted file mode 100644
index d24d6791a8..0000000000
--- a/usr/src/cmd/lp/cmd/lp.c
+++ /dev/null
@@ -1,1082 +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.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/* lp -- print files on a line printer */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include <assert.h>
-#include <locale.h>
-#include <string.h>
-#include "requests.h"
-#include "lp.h"
-#include "msgs.h"
-#include "printers.h"
-
-#define WHO_AM_I I_AM_LP
-#include "oam.h"
-
-#define TRUE 1
-#define FALSE 0
-#define ALERT_CMD "/etc/lp/alerts/jobdone"
- /* file to run when job is done if -p option is selected */
-short alertMsg = FALSE; /* TRUE => user wants notification via
- running /etc/lp/alerts/jobdone
- FALSE => don't do it */
-#define HOLD 1
-#define RESUME 2
-#define IMMEDIATE 3
-#define POSTSCRIPT "postscript"
-
-static struct stat stbuf; /* Global stat buffer */
-static char *dest = NULL; /* destination class or printer */
-static char *title = NULL; /* User-supplied title for output */
-static int specialh = 0; /* -H flag indicates special handling */
-static char *formname = NULL; /* form to use */
-static char *char_set = NULL; /* print wheel or character set to use */
-static char *cont_type = NULL; /* content type of input files */
-static char *curdir; /* working directory at time of request */
-static char reqfile[20]; /* name of request file */
-static char *stdinfile;
-static char *rfilebase;
-static short priority = -1; /* priority of print request */
-static short copies = 0; /* number of copies of output */
-static char **opts = NULL; /* options for interface program */
-static char **yopts = NULL; /* options for filter program */
-static char *pages = NULL; /* pages to be printed */
-static short silent = FALSE; /* don't run off at the mouth */
-static short mail = FALSE; /* TRUE => user wants mail, FALSE ==> no mail */
-static short wrt = FALSE; /* TRUE => user wants notification on tty
- * via write, FALSE => don't write
- */
-static short raw = FALSE; /* set option xx"stty=raw"xx and raw flag if
- * true
- */
-static short copy = FALSE; /* TRUE => copy files, FALSE ==> don't */
-static char *pre_rqid = NULL; /* previos request id (-i option) */
-static char *reqid = NULL; /* request id for this job */
-
-static char **files = NULL; /* list of file to be printed */
-static int nfiles = 0; /* # of files on cmd line (excluding "-") */
-static int stdinp = 0; /* indicates how many times to print std input
- *-1 ==> standard input empty
- */
-static int Tflag = 0; /* 0, -T not specified, 1, -T specified
- * this flag used for autorecognizing
- * postscript
- * if == 1, autorec. ps. is off!
- */
-
-static int exit_code = 0; /* exit with this value */
-
-extern char *sprintlist();
-extern int appendlist();
-
-static void startup(), clean_up(), err_exit(), savestd(), arps(REQUEST *rqp),
- ack_job(), catch(), allocfiles(), end_change(char *, REQUEST *);
-static int psfile(char *);
-static char *start_ch(char *), *getfiles(int), *que_job(REQUEST *);
-static REQUEST *makereq();
-
-#define OPTSTRING "q:H:f:d:T:S:o:y:P:i:cmwpn:st:r"
-
-static void
-chk_cont_type(str)
-char *str;
-{
- if (STREQU(str, NAME_ANY) || STREQU(str, NAME_TERMINFO)) {
- LP_ERRMSG2(ERROR, E_LP_BADOARG, 'T', str);
- exit(1);
- }
-}
-
-char *
-mkAlertCmd(char *reqfile)
-{
- char *str,*ptr;
- int len;
-
- str = (char *) malloc(strlen(ALERT_CMD) + strlen(dest) +
- strlen(reqfile) + 3);
- ptr = strchr(reqfile,'-');
- len = (ptr ? ptr-reqfile : strlen(reqfile));
- sprintf(str,"%s %s %.*s", ALERT_CMD, dest, len, reqfile);
-
- return(str);
-}
-
-int
-main(int argc, char *argv[])
-{
- int letter;
- char *p, **templist, **stemp;
- char *file;
- REQUEST *reqp, *makereq();
- int fileargs = 0;
- extern char *optarg;
- extern int optind, opterr, optopt;
-
- (void) setlocale (LC_ALL, "");
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- opterr = 0; /* disable printing of errors by getopt */
- while ((letter = getopt(argc, argv, OPTSTRING)) != -1)
- switch(letter) {
- case 'c': /* copy files */
- if (copy) LP_ERRMSG1(WARNING, E_LP_2MANY, 'c');
- copy = TRUE;
- break;
- case 'd': /* destination */
- if (dest) LP_ERRMSG1(WARNING, E_LP_2MANY, 'd');
- dest = optarg;
- if (!isprinter(dest) && !isclass(dest) && !STREQU(dest, NAME_ANY)) {
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest);
- exit (1);
- }
- break;
- case 'f':
- if (formname) LP_ERRMSG1(WARNING, E_LP_2MANY, 'f');
- formname = optarg;
- break;
- case 'H':
- if (specialh) LP_ERRMSG1(WARNING, E_LP_2MANY, 'H');
- if (STREQU(optarg, "hold")) specialh = HOLD;
- else if (STREQU(optarg, "resume")) specialh = RESUME;
- else if (STREQU(optarg, "immediate")) specialh = IMMEDIATE;
- else {
- LP_ERRMSG2(ERROR, E_LP_BADOARG, 'H', optarg);
- exit(1);
- }
- break;
- case 'i':
- if (pre_rqid) LP_ERRMSG1(WARNING, E_LP_2MANY, 'i');
- pre_rqid = optarg;
- break;
- case 'm': /* mail */
- if (mail) LP_ERRMSG1(WARNING, E_LP_2MANY, 'm');
- mail = TRUE;
- break;
- case 'n': /* # of copies */
- if (copies) LP_ERRMSG1(WARNING, E_LP_2MANY, 'n');
- if (
- *optarg == 0
- || (copies=(int)strtol(optarg, &p, 10)) <= 0
- || *p
- ) {
- LP_ERRMSG2(ERROR, E_LP_BADOARG, 'n', optarg);
- exit(1);
- }
- break;
- case 'o': /* option for interface program */
- stemp = templist = getlist(optarg, " \t", ""); /* MR bl88-13915 */
- if (!stemp)
- break; /* MR bl88-14720 */
- while (*templist)
- appendlist(&opts, *templist++);
- freelist(stemp);
- break;
- case 'y':
- stemp = templist = getlist(optarg, " \t", ",");
- if (!stemp)
- break; /* MR bl88-14720 */
- while (*templist)
- appendlist(&yopts, *templist++);
- freelist(stemp);
- break;
- case 'P':
- if (pages) LP_ERRMSG1(WARNING, E_LP_2MANY, 'P');
- pages = optarg;
- break;
- case 'q':
- if (priority != -1) LP_ERRMSG1(WARNING, E_LP_2MANY, 'q');
- priority = (int)strtol(optarg, &p, 10);
- if (*p || priority<0 || priority>39) {
- LP_ERRMSG1(ERROR, E_LP_BADPRI, optarg);
- exit(1);
- }
- break;
- case 'r':
- if (raw) LP_ERRMSG1(WARNING, E_LP_2MANY, 'r');
- raw = TRUE;
- break;
- case 's': /* silent */
- if (silent) LP_ERRMSG1(WARNING, E_LP_2MANY, 's');
- silent = 1;
- break;
- case 'S':
- if (char_set) LP_ERRMSG1(WARNING, E_LP_2MANY, 'S');
- char_set = optarg;
- break;
- case 't': /* title */
- if (title) LP_ERRMSG1(WARNING, E_LP_2MANY, 't');
- title = optarg;
- break;
- case 'T':
- if (cont_type) LP_ERRMSG1(WARNING, E_LP_2MANY, 'T');
- chk_cont_type(optarg);
- cont_type = optarg;
- Tflag++;
- break;
- case 'p':
- if (alertMsg) LP_ERRMSG1(WARNING, E_LP_2MANY, 'p');
- alertMsg = TRUE;
- break;
- case 'w': /* write */
- if (wrt) LP_ERRMSG1(WARNING, E_LP_2MANY, 'w');
- wrt = TRUE;
- break;
- default:
- if (optopt == '?') {
-
- (void)printf(
- gettext("usage:\n\n(submit file(s) for printing)\n"));
-
- (void) printf (gettext(\
-"lp [options] { file-name ... | - }\n"));
-
- (void) printf (gettext(
-" [-c] (make copies first)\n"
-" [-d destination] (printer/class to use)\n"
-" [-f form [-d any]] (print on this form)\n"
-" [-H hold] (don't print yet)\n"
-" [-H immediate] (print first--reserved)\n"
-" [-m | -w] (mail/write when done)\n"
-" [-p] (notify when done via ToolTalk)\n"
-" [-n copies] (print this many copies)\n"
-" [-o nobanner] (no banner page)\n"));
-
- (void) printf (gettext(
-" [-o nofilebreak] (no inter-file formfeed)\n"
-" [-o length=scaled-number] (page length)\n"
-" [-o width=scaled-number] (page width)\n"));
-
- (void) printf (gettext(
-" [-o lpi=scaled-number] (line pitch)\n"
-" [-o cpi=scaled-number] (character pitch)\n"));
-
- (void) printf (gettext(
-" [-o stty='stty-options'] (port characteristics)\n"
-" [-o other-local-options] (as defined locally)\n"));
-
- (void) printf (gettext(
-" [-P page-list] (locally defined)\n"
-" [-q priority] (priority level)\n"
-" [-r] (use no filter)\n"));
-
- (void) printf (gettext(
-" [-s] (no request-id message)\n"
-" [-S char-set | print-wheel [-d any]] (font to start with)\n"
-" [-t title] (title for banner page)\n"
-" [-T file-type] (type of input files)\n"
-" [-y local-modes] (locally defined)\n"
-"\n"));
-
- (void) printf(gettext(
-" (change previous request)\n"
-" lp -i request-id {options}\n"
-" [-H resume] (resume held request)\n"
-" [other options listed above]\n"));
-
- exit(0);
- }
- (p = "-X")[1] = optopt;
- if (strchr(OPTSTRING, optopt))
- LP_ERRMSG1(ERROR, E_LP_OPTARG, p);
- else
- LP_ERRMSG1(ERROR, E_LP_OPTION, p);
- exit(1);
- }
-
- if ((mail && wrt) || (mail && alertMsg) || (wrt && alertMsg))
- LP_ERRMSG(WARNING, E_LPP_COMBMW);
-
- while (optind < argc) {
- fileargs++;
- file = argv[optind++];
- if(strcmp(file, "-") == 0) {
- stdinp++;
- appendlist(&files, file);
- } else {
- if(Access(file, 4/*read*/) || Stat(file, &stbuf)) {
- if (errno == EOVERFLOW)
- LP_ERRMSG2(WARNING, E_LP_LARGEFILE, file, errno);
- else
- LP_ERRMSG2(WARNING, E_LP_BADFILE, file, errno);
- exit_code = 1;
- } else if((stbuf.st_mode & S_IFMT) == S_IFDIR) {
- LP_ERRMSG1(WARNING, E_LP_ISDIR, file);
- exit_code = 1;
- } else if(stbuf.st_size == 0) {
- LP_ERRMSG1(WARNING, E_LP_EMPTY, file);
- exit_code = 1;
- } else {
- nfiles++;
- appendlist(&files, file);
- continue;
- }
- }
- }
-
- if(fileargs == 0) {
- if (!pre_rqid) stdinp = 1;
- } else if (pre_rqid) {
- LP_ERRMSG(ERROR, E_LPP_ILLARG);
- exit(1);
- } else if(nfiles == 0 && stdinp == 0) {
- LP_ERRMSG(ERROR, E_LP_NOFILES);
- exit(1);
- }
-
-/* args parsed, now let's do it */
-
- startup(); /* open message queue
- and catch interupts so it gets closed too */
-
- if (!(reqp = makereq())) { /* establish defaults & sanity check args */
- LP_ERRMSG1(ERROR, E_LPP_FGETREQ, pre_rqid);
- err_exit();
- }
-
- /* allocate files for request, standard input and files if copy */
- if (pre_rqid) {
- if (putrequest(reqfile, reqp) == -1) { /* write request file */
-puterr:
- switch(errno) {
- default:
- LP_ERRMSG(ERROR, E_LPP_FPUTREQ);
- err_exit();
- }
- }
- end_change(pre_rqid, reqp);
- reqid = pre_rqid;
- } else {
- allocfiles();
- if(stdinp > 0) {
- savestd(); /* save standard input */
- }
- reqp->file_list = files;
- arps(reqp); /* autorecognize postscript */
- if (alertMsg) reqp->alert = mkAlertCmd(reqfile);
- if (putrequest(reqfile, reqp) == -1) goto puterr;
- reqid = que_job(reqp);
- }
-
- signal(SIGHUP, SIG_IGN);
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
-
- clean_up();
- ack_job(); /* issue request id message */
-
- return (exit_code);
-}
- /* startup -- initialization routine */
-
-static void
-startup()
-{
- void catch();
- int try = 0;
-
- for (;;)
- if (mopen() == 0) break;
- else {
- if (errno == ENOSPC && try++ < 5) {
- (void) sleep(3);
- continue;
- }
- LP_ERRMSG(ERROR, E_LP_MOPEN);
- exit(1);
- }
-
- if(signal(SIGHUP, SIG_IGN) != SIG_IGN)
- signal(SIGHUP, catch);
- if(signal(SIGINT, SIG_IGN) != SIG_IGN)
- signal(SIGINT, catch);
- if(signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- signal(SIGQUIT, catch);
- if(signal(SIGTERM, SIG_IGN) != SIG_IGN)
- signal(SIGTERM, catch);
-
- (void) umask(0000);
- curdir = getcwd(NULL, 512);
-}
-
-/* catch -- catch signals */
-
-static void
-catch()
-{
- signal(SIGHUP, SIG_IGN);
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- err_exit();
-}
-
-/* clean_up -- called by catch() after interrupts
- or by err_exit() after errors */
-
-static void
-clean_up()
-{
- (void)mclose ();
-}
-
-static void
-err_exit()
-{
- clean_up();
- exit(1);
-}
-
- /*
- * copyfile(stream, name) -- copy stream to file "name"
- */
-
-static void
-copyfile(stream, name)
-FILE *stream;
-char *name;
-{
- FILE *ostream;
- int i;
- char buf[BUFSIZ];
-
- if ((ostream = fopen(name, "w")) == NULL) {
- LP_ERRMSG2(ERROR, E_LP_BADFILE, name, errno);
- return;
- }
-
- Chmod(name, 0600);
- errno = 0;
- while ((i = fread(buf, sizeof(char), BUFSIZ, stream)) > 0) {
- (void) fwrite(buf, sizeof(char), i, ostream);
- if (feof(stream)) break;
- }
- if (errno != 0) {
- if (errno == ENOSPC) {
- LP_ERRMSG(ERROR, E_LP_NOSPACE);
- } else {
- LP_ERRMSG2(ERROR, E_LP_BADFILE, name, errno);
- }
- err_exit();
- }
-
- (void) fclose(ostream);
-}
- /* makereq -- sanity check args, establish defaults */
-
-static REQUEST *
-makereq()
-{
- static REQUEST rq;
- REQUEST *oldrqp;
- char *preqfile;
- char **optp, *pdest = dest;
-
- /*
- * begin changes for 1112940
- * The test used to look like: if (!dest && !pre_rqid && !cont_type)
- * Now, if either LPDEST or a default is set, use those instead of "any".
- * This is probably more like what the user expects and the SVID isn't
- * real clear about the interaction of LPDEST, the default and -T.
- * If the printer can't handle this content, we'll get an error later.
- */
- if (!dest && !pre_rqid) {
- if ((dest = getenv("LPDEST")) && *dest)
- ;
- else {
- if (!(dest = getdefault())) {
- if (cont_type)
- dest = "any";
- else {
- LP_ERRMSG(ERROR, E_LPP_NODEST);
- err_exit();
- }
- }
- }
- }
- /* end changes for 1112940 */
-
- if (!dest) dest = "any";
-
- if (!pre_rqid && !cont_type) {
- cont_type = getenv("LPTYPE");
- if (cont_type != (char *) NULL) {
- Tflag++;/* for autorecognizing postscript, LPTYPE is */
- /* equivalent to specifying "-T" */
- }
- }
- if (!pre_rqid && !cont_type)
- cont_type = NAME_SIMPLE;
-
- if (formname && opts)
- for (optp = opts; *optp; optp++)
- if (STRNEQU("lpi=", *optp, 4)
- || STRNEQU("cpi=", *optp, 4)
- || STRNEQU("length=", *optp, 7)
- || STRNEQU("width=", *optp, 6)) {
- LP_ERRMSG(ERROR, E_LP_OPTCOMB);
- err_exit();
- }
-
- if (raw && (yopts || pages)) {
- LP_ERRMSG(ERROR, E_LP_OPTCOMB);
- err_exit();
- }
-
- /* now to build the request */
- if (pre_rqid) {
- preqfile = start_ch(pre_rqid);
- (void) strlcpy(reqfile, preqfile, sizeof (reqfile));
- if (!(oldrqp = getrequest(preqfile))) return (NULL);
- rq.copies = (copies) ? copies : oldrqp->copies;
- rq.destination = (pdest) ? dest : oldrqp->destination;
- rq.file_list = oldrqp->file_list;
- rq.form = (formname) ? formname : oldrqp->form;
- rq.actions = (specialh) ? ((specialh == HOLD) ? ACT_HOLD :
- ((specialh == RESUME) ? ACT_RESUME : ACT_IMMEDIATE)) :
- oldrqp->actions;
- if (wrt) rq.actions |= ACT_WRITE;
- if (mail) rq.actions |= ACT_MAIL;
- if (raw) {
- rq.actions |= ACT_RAW;
- /*appendlist(&opts, "stty=raw");*/
- }
- rq.options = (opts) ? sprintlist(opts) : oldrqp->options;
- rq.priority = (priority == -1) ? oldrqp->priority : priority;
- rq.pages = (pages) ? pages : oldrqp->pages;
- rq.charset = (char_set) ? char_set : oldrqp->charset;
- rq.modes = (yopts) ? sprintlist(yopts) : oldrqp->modes;
- rq.title = (title) ? title : oldrqp->title;
- rq.input_type = (cont_type) ? cont_type : oldrqp->input_type;
- rq.alert = (alertMsg) ? mkAlertCmd(reqfile) : oldrqp->alert;
- rq.user = oldrqp->user;
- rq.outcome = 0;
- rq.version = VERSION_NEW_LP;
- return(&rq);
- }
- rq.copies = (copies) ? copies : 1;
- rq.destination = dest;
- rq.form = formname;
- rq.actions = (specialh) ? ((specialh == HOLD) ? ACT_HOLD :
- ((specialh == RESUME) ? ACT_RESUME : ACT_IMMEDIATE)) : 0;
- if (wrt) rq.actions |= ACT_WRITE;
- if (mail) rq.actions |= ACT_MAIL;
- if (raw) {
- rq.actions |= ACT_RAW;
- /*appendlist(&opts, "stty=raw");*/
- }
- rq.alert = NULL;
- rq.options = sprintlist(opts);
- rq.priority = priority;
- rq.pages = pages;
- rq.charset = char_set;
- rq.modes = sprintlist(yopts);
- rq.title = title;
- rq.input_type = cont_type;
- rq.file_list = 0;
- rq.user = getname();
- rq.version = VERSION_NEW_LP;
- return(&rq);
-}
-
-/* files -- process command line file arguments */
-static void
-allocfiles()
-{
- char **reqfiles = 0, **filep, *p, *prefix;
- FILE *f;
- int numfiles, filenum = 1;
-
- numfiles = 1 + ((stdinp > 0) ? 1 : 0) + ((copy) ? nfiles : 0);
-
- if ((prefix = getfiles(numfiles)) == NULL)
- {
- numfiles += nfiles;
- prefix = getfiles(numfiles);
- copy = 1;
- }
-
- (void) strlcpy(reqfile, prefix, sizeof (reqfile));
- (void) strlcat(reqfile, "-0000", sizeof (reqfile));
- rfilebase = makepath(Lp_Temp, reqfile, NULL);
- if (stdinp > 0) {
- stdinfile = strdup(rfilebase);
- p = strchr(stdinfile, 0) - 4;
- *p++ = '1';
- *p = 0;
- filenum++;
- }
- p = strchr(reqfile, 0) - 4; *p++ = '0'; *p = 0;
- p = strchr(rfilebase, 0) - 4;
-
- if (!files) appendlist(&files, "-");
-
- for (filep = files; *filep; filep++) {
- if(STREQU(*filep, "-")) {
- if(stdinp > 0)
- appendlist(&reqfiles, stdinfile);
- } else {
- if(copy) {
- if (f = fopen(*filep, "r")) {
- (void) snprintf(p, sizeof ("0000"), "%d", filenum++);
- copyfile(f, rfilebase);
- appendlist(&reqfiles, rfilebase);
- (void) fclose(f);
- } else
- LP_ERRMSG2(WARNING, E_LP_BADFILE, *filep, errno);
- } else {
- if (**filep == '/' || (curdir && *curdir))
- appendlist(&reqfiles,
- (**filep == '/') ? *filep
- : makepath(curdir, *filep, (char *)0));
- else {
- LP_ERRMSG (ERROR, E_LPP_CURDIR);
- err_exit ();
- }
- }
- }
- }
- freelist(files);
- files = reqfiles;
-}
-
- /* start_ch -- start change request */
-static char *
-start_ch(char *rqid)
-{
- int size, type;
- short status;
- char message[100],
- reply[100],
- *rqfile;
-
- size = putmessage(message, S_START_CHANGE_REQUEST, rqid);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- err_exit();
- }
- if ((type = mrecv(reply, 100)) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- err_exit();
- }
- if (type != R_START_CHANGE_REQUEST
- || getmessage(reply, type, &status, &rqfile) == -1) {
- LP_ERRMSG1(ERROR, E_LP_BADREPLY, type);
- err_exit();
- }
-
- switch (status) {
- case MOK:
- return(strdup(rqfile));
- case MNOPERM:
- LP_ERRMSG(ERROR, E_LP_NOTADM);
- break;
- case MUNKNOWN:
- LP_ERRMSG1(ERROR, E_LP_UNKREQID, rqid);
- break;
- case MBUSY:
- LP_ERRMSG1(ERROR, E_LP_BUSY, rqid);
- break;
- case M2LATE:
- LP_ERRMSG1(ERROR, E_LP_2LATE, rqid);
- break;
- case MGONEREMOTE:
- LP_ERRMSG1(ERROR, E_LP_GONEREMOTE, rqid);
- break;
- default:
- LP_ERRMSG1(ERROR, E_LP_BADSTATUS, status);
- }
- err_exit();
- /*NOTREACHED*/
- return (NULL);
-}
-
-static void
-end_change(char *rqid, REQUEST *rqp)
-{
- int size, type;
- long chkbits;
- short status;
- char message[255],
- reply[100],
- *chkp;
-
- size = putmessage(message, S_END_CHANGE_REQUEST, rqid);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- err_exit();
- }
- if ((type = mrecv(reply, 100)) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- err_exit();
- }
- if (type != R_END_CHANGE_REQUEST
- || getmessage(reply, type, &status, &chkbits) == -1) {
- LP_ERRMSG1(ERROR, E_LP_BADREPLY, type);
- err_exit();
- }
-
- switch (status) {
- case MOK:
- return;
- case MNOPERM:
- LP_ERRMSG(ERROR, E_LP_NOTADM);
- break;
- case MNOSTART:
- LP_ERRMSG(ERROR, E_LPP_NOSTART);
- break;
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, rqp->destination);
- break;
- case MDENYDEST:
- if (chkbits) {
- chkp = message;
- /* PCK_TYPE indicates a Terminfo error, and should */
- /* be handled as a ``get help'' problem. */
- if (chkbits & PCK_TYPE) chkp += sprintf(chkp, "");
- if (chkbits & PCK_CHARSET)
- chkp += sprintf(chkp, "-S character-set, ");
- if (chkbits & PCK_CPI) chkp += sprintf(chkp, "-o cpi=, ");
- if (chkbits & PCK_LPI) chkp += sprintf(chkp, "-o lpi=, ");
- if (chkbits & PCK_WIDTH) chkp += sprintf(chkp, "-o width=, ");
- if (chkbits & PCK_LENGTH) chkp += sprintf(chkp, "-o length=, ");
- if (chkbits & PCK_BANNER) chkp += sprintf(chkp, "-o nobanner, ");
- if (chkbits & PCK_PAPER)
- chkp += snprintf(chkp, sizeof (message) - (chkp - message),
- gettext("does not print on specified type of paper, "));
-
- if (chkp - 2 >= message + sizeof (message))
- message[sizeof(message) - 1] = 0;
- else
- chkp[-2] = 0;
- LP_ERRMSG1(ERROR, E_LP_PTRCHK, message);
- }
- else LP_ERRMSG1(ERROR, E_LP_DENYDEST, rqp->destination);
- break;
- case MNOMEDIA:
- LP_ERRMSG(ERROR, E_LPP_NOMEDIA);
- break;
- case MDENYMEDIA:
- if (chkbits & PCK_CHARSET) LP_ERRMSG(ERROR, E_LPP_FORMCHARSET);
- else LP_ERRMSG1(ERROR, E_LPP_DENYMEDIA, rqp->form);
- break;
- case MNOMOUNT:
- LP_ERRMSG(ERROR, E_LPP_NOMOUNT);
- break;
- case MNOFILTER:
- LP_ERRMSG(ERROR, E_LP_NOFILTER);
- break;
- case MERRDEST:
- LP_ERRMSG1(ERROR, E_LP_REQDENY, rqp->destination);
- break;
- case MNOOPEN:
- LP_ERRMSG(ERROR, E_LPP_NOOPEN);
- break;
- default:
- LP_ERRMSG1(ERROR, E_LP_BADSTATUS, status);
- }
- err_exit();
-}
-
-/* getfile -- allocate the requested number of temp files */
-static char *
-getfiles(int number)
-{
- int size, type;
- short status;
- char message[100],
- reply[100],
- *pfix;
-
- size = putmessage(message, S_ALLOC_FILES, number);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- err_exit();
- }
- if ((type = mrecv(reply, 100)) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- err_exit();
- }
- if (type != R_ALLOC_FILES
- || getmessage(reply, type, &status, &pfix) == -1) {
- LP_ERRMSG1(ERROR, E_LP_BADREPLY, type);
- err_exit();
- }
-
- switch (status) {
- case MOK:
- return(strdup(pfix));
- case MOKREMOTE:
- clean_up();
- startup();
- return(NULL);
- case MNOMEM:
- LP_ERRMSG(ERROR, E_LP_NOSPACE);
- break;
- case MERRDEST:
- LP_ERRMSG(ERROR, E_LP_NOREQ);
- break;
- default:
- LP_ERRMSG1(ERROR, E_LP_BADSTATUS, status);
- }
- err_exit();
- /*NOTREACHED*/
- return (NULL);
-}
-
-static char *
-que_job(REQUEST *rqp)
-{
- int size, type;
- long chkbits;
- short status;
- char message[255],
- reply[100],
- *chkp,
- *req_id;
-
- size = putmessage(message, S_PRINT_REQUEST, reqfile);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- err_exit();
- }
- if ((type = mrecv(reply, 100)) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- err_exit();
- }
- if (type != R_PRINT_REQUEST
- || getmessage(reply, type, &status, &req_id, &chkbits) == -1) {
- LP_ERRMSG1(ERROR, E_LP_BADREPLY, type);
- err_exit();
- }
-
- switch (status) {
- case MOK:
- return(strdup(req_id));
- case MNOPERM:
- LP_ERRMSG(ERROR, E_LP_NOTADM);
- break;
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, rqp->destination);
- break;
- case MDENYDEST:
- if (chkbits) {
- chkp = message;
- /* PCK_TYPE indicates a Terminfo error, and should */
- /* be handled as a ``get help'' problem. */
- if (chkbits & PCK_TYPE) chkp += sprintf(chkp, "");
- if (chkbits & PCK_CHARSET) chkp += sprintf(chkp, "-S character-set, ");
- if (chkbits & PCK_CPI) chkp += sprintf(chkp, "-o cpi=, ");
- if (chkbits & PCK_LPI) chkp += sprintf(chkp, "-o lpi=, ");
- if (chkbits & PCK_WIDTH) chkp += sprintf(chkp, "-o width=, ");
- if (chkbits & PCK_LENGTH) chkp += sprintf(chkp, "-o length=, ");
- if (chkbits & PCK_BANNER) chkp += sprintf(chkp, "-o nobanner, ");
- if (chkbits & PCK_PAPER)
- chkp += snprintf(chkp, sizeof (message) - (chkp - message),
- gettext("does not print on specified type of paper, "));
-
- if (chkp - 2 >= message + sizeof (message))
- message[sizeof(message) - 1] = 0;
- else
- chkp[-2] = 0;
- LP_ERRMSG1(ERROR, E_LP_PTRCHK, message);
- }
- else LP_ERRMSG1(ERROR, E_LP_DENYDEST, rqp->destination);
- break;
- case MNOMEDIA:
- LP_ERRMSG(ERROR, E_LPP_NOMEDIA);
- break;
- case MDENYMEDIA:
- if (chkbits & PCK_CHARSET) LP_ERRMSG(ERROR, E_LPP_FORMCHARSET);
- else LP_ERRMSG1(ERROR, E_LPP_DENYMEDIA, rqp->form);
- break;
- case MNOMOUNT:
- LP_ERRMSG(ERROR, E_LPP_NOMOUNT);
- break;
- case MNOFILTER:
- LP_ERRMSG(ERROR, E_LP_NOFILTER);
- break;
- case MERRDEST:
- LP_ERRMSG1(ERROR, E_LP_REQDENY, rqp->destination);
- break;
- case MNOOPEN:
- LP_ERRMSG(ERROR, E_LPP_NOOPEN);
- break;
- case MUNKNOWN:
- LP_ERRMSG(ERROR, E_LPP_ODDFILE);
- break;
- default:
- LP_ERRMSG1(ERROR, E_LP_BADSTATUS, status);
- }
- err_exit();
- /*NOTREACHED*/
- return (NULL);
-}
-
-/* ack_job -- issue request id message */
-static void
-ack_job()
-{
- if(silent || pre_rqid) return;
- printf(gettext("request id is %s "), reqid);
- if (nfiles > 0) {
- if (stdinp > 0) {
- printf(gettext(
- "(%d file(s) and standard input)\n"), nfiles);
- } else {
- printf(gettext("(%d file(s))\n"), nfiles);
- }
- } else if (stdinp > 0) {
- printf(gettext("(standard input)\n"));
- } else
- printf("\n");
-}
-
-/* savestd -- save standard input */
-static void
-savestd()
-{
- copyfile(stdin, stdinfile);
- Stat(stdinfile, &stbuf);
- if(stbuf.st_size == 0) {
- if(nfiles == 0) {
- LP_ERRMSG(ERROR, E_LP_NOFILES);
- err_exit();
- } else {/* inhibit printing of std input */
- LP_ERRMSG1(WARNING, E_LP_EMPTY, "(standard input)");
- stdinp = -1;
- }
- }
- else { /* see if our non-zero size file is postscript */
- if (!Tflag && psfile(stdinfile)) {
- cont_type = POSTSCRIPT;
- }
- }
-}
-
-/* psfile(): Determine whether a file is postscript or not
- * input: char string of the filename
- * ouput: 0 if the file isn't postscript,
- * non-zero if it is.
- * Description:
- * This routine looks to see if the "%!" characters are the first
- * parts of the document (See PostScript Language Reference Manual,
- * Second Edition - Adobe Systems Inc.; Appendix G - D.S.C. 3.0, p. 621).
- *
- * This code has been blatently (and legally) ripped off from lpr,
- * with only one apology: USL should've done this in the first place!!
- */
-
-#define PSCOM "%!"
-#define PC_PSCOM "\004%!"
-
-static int
-psfile(char *fname)
-{
- int fd;
- register int ret = 0;
- char buf[sizeof(PC_PSCOM)-1];
-
- if ((fd = open(fname, O_RDONLY)) >= 0 &&
- read(fd, buf, sizeof(buf)) == sizeof(buf) &&
- ((strncmp(buf, PSCOM, sizeof(PSCOM)-1) == 0) ||
- (strncmp(buf, PC_PSCOM, sizeof(PC_PSCOM)-1) == 0)))
- ret++;
- (void)close(fd);
- return(ret);
-}
-
-/* arps(): autorecognize postscript files
- * input: REQUEST pointer.
- * ouput: none directly; the REQUEST pointer may be modified.
- * description:
- * this routine is called before the REQUEST structure
- * is written to disk. the list of files to be printed is
- * examined to see if all of the files are postscript. if
- * they are, then the input_type field is changed to
- * "postscript".
- *
- * NOTE WELL - autorecognition is not done under the following
- * conditions:
- * 1) The -T flag has been used.
- * 2) *Any* file in the file_list is *not* postscript. Right now,
- * this is actually an ugly design decision. The request
- * file specifies only one input_type for all of the files
- * in the request. If any type isn't postscript, then
- * input_type is unmodified, and the request will be
- * treated as "simple". The reason for this is due
- * to the design of the lp subsystem. What's need is
- * to change the request handling to allow for multiple
- * file types per request. However, this current
- * implementation will fit in 100% with the original
- * design of the lp subsystem.
- */
-static void
-arps(REQUEST * rqp)
-{
- char **lfiles;
- int start = 0;
- int current;
-
- if (Tflag != 0) {
- return;
- }
-
- lfiles = rqp->file_list;
- start = psfile(*lfiles);
-
- for (lfiles++; (lfiles != NULL) && (*lfiles != NULL); lfiles++) {
- current = psfile(*lfiles);
- if (current != start) {
- return;
- }
- }
-
- if (start != 0) { /* all the files are postscript */
- rqp->input_type = POSTSCRIPT;
- }
-}
diff --git a/usr/src/cmd/lp/cmd/lpc/Makefile b/usr/src/cmd/lp/cmd/lpc/Makefile
deleted file mode 100644
index d4704db6ba..0000000000
--- a/usr/src/cmd/lp/cmd/lpc/Makefile
+++ /dev/null
@@ -1,77 +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
-#
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# cmd/lp/cmd/lpc/Makefile
-#
-
-include ../../Makefile.lp
-
-PROG= lpc
-
-ROOTUSRUCBSYMLINK= $(ROOTUSRUCB)/$(PROG)
-ROOTUSRBINPROG= $(PROG:%=$(ROOTBIN)/%)
-
-SRCS= cmds.c cmdtab.c lpc.c process.c topq.c fatalmsg.c sndrcv.c \
- global.c
-
-OBJS= $(SRCS:.c=.o)
-
-
-CPPFLAGS = -I. -I$(LPINC) $(CPPFLAGS.master)
-LDLIBS += $(LIBREQ) $(LIBMSG) $(LIBOAM) \
- $(LIBPRT) $(LIBSEC) $(LIBLP)
-
-POFILE = lp_cmd_lpc.po
-
-.KEEP_STATE:
-
-.PARALLEL: $(OBJS)
-
-all: $(PROG)
-
-$(PROG): $(OBJS)
- $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-install: all .WAIT $(ROOTUSRBINPROG) $(ROOTUSRUCBSYMLINK)
-
-$(ROOTUSRUCBSYMLINK):
- $(RM) $@; $(SYMLINK) ../bin/$(PROG) $@
-
-clean:
- $(RM) $(OBJS)
-
-clobber: clean
- -$(RM) $(PROG) $(CLOBBERFILES)
-
-strip:
- $(STRIP) $(PROG)
-
-lint:
- $(LINT.c) $(SRCS) $(LDLIBS)
-
-include ../Makefile.msg
diff --git a/usr/src/cmd/lp/cmd/lpc/cmds.c b/usr/src/cmd/lp/cmd/lpc/cmds.c
deleted file mode 100644
index e877fb71e4..0000000000
--- a/usr/src/cmd/lp/cmd/lpc/cmds.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
-** lpc -- line printer control program -- commands:
-**
-*/
-#include <locale.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include "msgs.h"
-#include "lpc.h"
-
-#define REQUEUE_CURR 0 /* Stop immediately and requeue current job */
-#define WAIT_CURR 1 /* Finish current job before stopping */
-#define ABORT_CURR 2 /* Abort current job */
-
-int When;
-char *Reason;
-
-extern char *Printer;
-extern char *Lhost;
-
-#if defined(__STDC__)
-static int doarg(char *);
-#else
-static int doarg();
-#endif
-
-/*
- * kill an existing daemon and disable printing.
- */
-void
-#if defined(__STDC__)
-_abort(int argc, char **argv)
-#else
-_abort(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- When = REQUEUE_CURR;
- Reason = NULL;
- if (argc == 1)
- printf(gettext("Usage: abort {all | printer ...}\n"));
- else if (argc == 2 && !strcmp(argv[1], "all"))
- do_all(disablepr);
- else
- while (--argc)
- disablepr(*++argv);
-}
-
-
-/*
- * Kill and restart the daemon.
- */
-void
-#if defined(__STDC__)
-restart(int argc, char **argv)
-#else
-restart(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- When = REQUEUE_CURR;
- Reason = NULL;
- if (argc == 1)
- printf(gettext("Usage: restart {all | printer ...}\n"));
- else if (argc == 2 && !strcmp(argv[1], "all"))
- do_all(restartpr);
- else
- while (--argc)
- restartpr(*++argv);
-}
-
-
-/*
- * Enable printing on the specified printer and startup the daemon.
- */
-void
-#if defined(__STDC__)
-start(int argc, char **argv)
-#else
-start(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- if (argc == 1)
- printf(gettext("Usage: start {all | printer ...}\n"));
- else if (argc == 2 && !strcmp(argv[1], "all"))
- do_all(enablepr);
- else
- while (--argc)
- enablepr(*++argv);
-}
-/*
- * Stop the specified daemon after completing the current job and disable
- * printing. (Disable only the printer not the queue )
- */
-void
-#if defined(__STDC__)
-stop(int argc, char **argv)
-#else
-stop(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- When = WAIT_CURR;
- Reason = NULL;
- if (argc == 1)
- printf(gettext("Usage: stop {all | printer ...}\n"));
- else if (argc == 2 && !strcmp(argv[1], "all"))
- do_all(disablepr);
- else
- while (--argc)
- disablepr(*++argv);
-}
-
-/*
- * Enable everything and start printer (undo `down').
- */
-void
-#if defined(__STDC__)
-up(int argc, char **argv)
-#else
-up(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- if (argc == 1)
- printf(gettext("Usage: up {all | printer ...}\n"));
- else if (argc == 2 && !strcmp(argv[1], "all"))
- do_all(uppr);
- else
- while (--argc)
- uppr(*++argv);
-}
-
-/*
- * Disable queuing and printing and put a message into the status file
- * (reason for being down).
- */
-void
-#if defined(__STDC__)
-down(int argc, char **argv)
-#else
-down(argc, argv)
-int argc;
-char **argv[];
-#endif
-{
- if (argc == 1) {
- printf(gettext("Usage: down {all | printer} [message ...]\n"));
- return;
- }
- When = WAIT_CURR;
- Reason = get_reason(argc-2, &argv[2]);
- if (!strcmp(argv[1], "all"))
- do_all(downpr);
- else
- downpr(argv[1]);
-}
-
-/*
-**
-** Queue Control commands (enable, disable)
-**
-*/
-
-/*
- * Enable queuing to the printer (allow lpr's).
- */
-void
-#if defined(__STDC__)
-enable(int argc, char **argv)
-#else
-enable(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- if (argc == 1)
- printf(gettext("Usage: enable {all | printer ...}\n"));
- else if (argc == 2 && !strcmp(argv[1], "all"))
- do_all(enableq);
- else
- while (--argc)
- enableq(*++argv);
-}
-
-
-/*
- * Disable queuing.
- */
-void
-#if defined(__STDC__)
-disable(int argc, char **argv)
-#else
-disable(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- Reason = NULL;
- if (argc == 1)
- printf(gettext("Usage: disable {all | printer ...}\n"));
- else if (argc == 2 && !strcmp(argv[1], "all"))
- do_all(disableq);
- else
- while (--argc)
- disableq(*++argv);
-}
-
-/*
-** Status of printers and queues
-**/
-
-/*
- * Print the status of each queue listed or all the queues.
- */
-void
-#if defined(__STDC__)
-status(int argc, char **argv)
-#else
-status(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- if( (argc == 1) || (argc == 2 && !strcmp(argv[1], "all")))
- do_all(statuspr);
- else
- while (--argc)
- statuspr(*++argv);
-}
-
-
-/*
- * Put the specified jobs at the top of printer queue.
- */
-void
-#if defined(__STDC__)
-topq(int argc, char **argv)
-#else
-topq(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- register int i;
- int changed;
-
- if (argc < 3) {
- printf(gettext("Usage: topq printer [jobnum ...] [user ...]\n"));
- return;
- }
-
- --argc;
- Printer = *++argv;
-
- /*
- * Check if it is a known printer
- */
- if(isprinter(Printer))
- printf("%s:\n", Printer);
- else{
- printf(gettext("%s: unknown printer\n"), Printer);
- return;
- }
-
- /*
- * Find if a requestid or a user name is specified
- * Also accept job# (LPD style )
- */
- changed = 0;
- for (i = argc; --i; ) {
- if (doarg(argv[i]) == 0) {
- printf(gettext("\tjob %s is not in the queue\n"), argv[i]);
- continue;
- } else
- changed++;
-
- }
- if (!changed)
- printf(gettext("\tqueue order unchanged\n"));
- return;
-
-}
-
-static int
-#if defined(__STDC__)
-doarg(char *job)
-#else
-doarg(job)
-char *job;
-#endif
-{
-
- char *cp;
- int jobnum, n;
- char *machine = NULL;
-
- /*
- ** Look for a job item consisting of system name, colon, number
- ** (example: ucbarpa:114)
- */
- if ((cp = strpbrk(job, "!:")) != NULL) {
- *cp++ = NULL;
- if (strcmp(Lhost, job))
- machine = job;
- job = cp;
- }
-
- /*
- ** Check for job specified by number (example: 112 or 235ucbarpa).
- */
- if (isdigit(*job) ) {
- /*
- ** Find machine name if it is of the type "job#machine"
- **/
- jobnum = strtol(job, &cp, 10);
- /* rest of the string ought to be a machine name */
- if (*cp && strcmp(Lhost, cp))
- machine = cp;
- job = (char *)malloc(strlen(Printer) + cp - job + 2);
- sprintf(job, "%s-%d", Printer, jobnum);
- n = topq_reqid(job, machine);
- free(job);
- return(n);
- }
- /*
- ** If it is a request-id, process it.
- */
- if (isrequest(job))
- return(topq_reqid(job, machine));
-
- /*
- ** Process item consisting of owner's name (example: henry).
- ** job is user name.
- **/
- return(topq_user(job, machine));
-
-}
-
-char *
-#if defined(__STDC__)
-get_reason(int argc, char **argv)
-#else
-get_reason(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- char *cpto, *cpfrom;
- static char buf[1024];
-
- /*
- * Obtain the reason
- */
-
- if (!argc)
- return(NULL);
- cpto = buf;
- while (--argc >= 0) {
- cpfrom = *argv++;
- while (*cpto++ = *cpfrom++)
- ;
- cpto[-1] = ' ';
- }
- cpto[-1] = '\n';
- *cpto = NULL;
-
- return(buf);
-}
-
-/*
- * Remove all spool files and temporaries from the spooling area.
- */
-void
-#if defined(__STDC__)
-clean(int argc, char **argv)
-#else
-clean(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- if (argc == 1)
- printf(gettext("Usage: clean {all | printer ...}\n"));
- else if (argc == 2 && !strcmp(argv[1], "all"))
- do_all(cleanpr);
- else
- while (--argc)
- cleanpr(*++argv);
-}
-
-/*
- * Exit lpc
- */
-/*ARGSUSED*/
-void
-#if defined(__STDC__)
-quit(int argc, char **argv)
-#else
-quit(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- void done();
-
- done(0);
-}
-
diff --git a/usr/src/cmd/lp/cmd/lpc/cmdtab.c b/usr/src/cmd/lp/cmd/lpc/cmdtab.c
deleted file mode 100644
index 602f06d3df..0000000000
--- a/usr/src/cmd/lp/cmd/lpc/cmdtab.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1 */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-/*
- * lpc -- command tables
- */
-
-#include "lpc.h"
-
-char aborthelp[] = "terminate a spooling daemon immediately and disable printing";
-char cleanhelp[] = "remove cruft files from a queue";
-char enablehelp[] = "turn a spooling queue on";
-char disablehelp[] = "turn a spooling queue off";
-char downhelp[] = "do a 'stop' followed by 'disable' and put a message in status";
-char helphelp[] = "get help on commands";
-char quithelp[] = "exit lpc";
-char restarthelp[] = "kill (if possible) and restart a spooling daemon";
-char starthelp[] = "enable printing and start a spooling daemon";
-char statushelp[] = "show status of daemon and queue";
-char stophelp[] = "stop a spooling daemon after current job completes and disable printing";
-char topqhelp[] = "put job at top of printer queue";
-char uphelp[] = "enable everything and restart spooling daemon";
-
-struct cmd cmdtab[] = {
- { "abort", aborthelp, _abort, 1 },
- { "clean", cleanhelp, clean, 1 },
- { "enable", enablehelp, enable, 1 },
- { "exit", quithelp, quit, 0 },
- { "disable", disablehelp, disable, 1 },
- { "down", downhelp, down, 1 },
- { "help", helphelp, help, 0 },
- { "quit", quithelp, quit, 0 },
- { "restart", restarthelp, restart, 0 },
- { "start", starthelp, start, 1 },
- { "status", statushelp, status, 0 },
- { "stop", stophelp, stop, 1 },
- { "topq", topqhelp, topq, 1 },
- { "up", uphelp, up, 1 },
- { "?", helphelp, help, 0 },
- { 0 },
-};
-
-int NCMDS = sizeof (cmdtab) / sizeof (cmdtab[0]) - 1;
diff --git a/usr/src/cmd/lp/cmd/lpc/fatalmsg.c b/usr/src/cmd/lp/cmd/lpc/fatalmsg.c
deleted file mode 100644
index 521061e152..0000000000
--- a/usr/src/cmd/lp/cmd/lpc/fatalmsg.c
+++ /dev/null
@@ -1,158 +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 2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-/*
- * University Copyright- Copyright (c) 1982, 1986, 1988
- * The Regents of the University of California
- * All Rights Reserved
- *
- * University Acknowledgment- Portions of this document are derived from
- * software developed by the University of California, Berkeley, and its
- * contributors.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <string.h>
-#if defined(__STDC__)
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#define WHO_AM_I I_AM_OZ /* to get oam.h to unfold */
-#include "oam.h"
-#include "lpd.h"
-
-/*
- * Report fatal error and exit
- */
-/*VARARGS1*/
-void
-#if defined (__STDC__)
-fatal(char *fmt, ...)
-#else
-fatal(fmt, va_alist)
-char *fmt;
-va_dcl
-#endif
-{
- va_list argp;
-
- if (Rhost)
- (void)printf("%s: ", Lhost);
- printf("%s: ", Name);
- if (Printer)
- (void)printf("%s: ", Printer);
-#if defined (__STDC__)
- va_start(argp, fmt);
-#else
- va_start(argp);
-#endif
- (void)vprintf(fmt, argp);
- va_end(argp);
- putchar('\n');
- fflush(stdout);
- done(1); /* defined by invoker */
- /*NOTREACHED*/
-}
-
-/*
- * Format lp error message to stderr
- * (this will probably change to remain compatible with LP)
- */
-/*VARARGS1*/
-void
-#if defined (__STDC__)
-_lp_msg(long msgid, va_list argp)
-#else
-_lp_msg(msgid, argp)
-long msgid;
-va_list argp;
-#endif
-{
- char label[20];
-
- (void)vsprintf(_m_, agettxt(msgid, _a_, MSGSIZ), argp);
- strcpy(label, "UX:");
- (void)strlcat(label, basename(Name), sizeof (label));
- fmtmsg(label, ERROR, _m_, agettxt(msgid+1, _a_, MSGSIZ));
-}
-
-/*
- * Format lp error message to stderr
- */
-/*VARARGS1*/
-void
-#if defined (__STDC__)
-lp_msg(long msgid, ...)
-#else
-lp_msg(msgid, va_alist)
-long msgid;
-va_dcl
-#endif
-{
- va_list argp;
-
-#if defined (__STDC__)
- va_start(argp, msgid);
-#else
- va_start(argp);
-#endif
- _lp_msg(msgid, argp);
- va_end(argp);
-}
-
-/*
- * Report lp error message to stderr and exit
- */
-/*VARARGS1*/
-void
-#if defined (__STDC__)
-lp_fatal(long msgid, ...)
-#else
-lp_fatal(msgid, va_alist)
-long msgid;
-va_dcl
-#endif
-{
- va_list argp;
-
-#if defined (__STDC__)
- va_start(argp, msgid);
-#else
- va_start(argp);
-#endif
- _lp_msg(msgid, argp);
- va_end(argp);
-
- done(1); /* Supplied by caller */
- /*NOTREACHED*/
-}
diff --git a/usr/src/cmd/lp/cmd/lpc/global.c b/usr/src/cmd/lp/cmd/lpc/global.c
deleted file mode 100644
index 83fa12c222..0000000000
--- a/usr/src/cmd/lp/cmd/lpc/global.c
+++ /dev/null
@@ -1,44 +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) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-/*
- * University Copyright- Copyright (c) 1982, 1986, 1988
- * The Regents of the University of California
- * All Rights Reserved
- *
- * University Acknowledgment- Portions of this document are derived from
- * software developed by the University of California, Berkeley, and its
- * contributors.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */
-
-#include "msgs.h"
-
-char *Lhost; /* Local host name */
-char *Rhost; /* Remote host name */
-char *Name; /* Program name */
-char *Printer; /* Printer name */
-char Msg[MSGMAX]; /* Message buffer */
diff --git a/usr/src/cmd/lp/cmd/lpc/lpc.c b/usr/src/cmd/lp/cmd/lpc/lpc.c
deleted file mode 100644
index 09c4641f96..0000000000
--- a/usr/src/cmd/lp/cmd/lpc/lpc.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * lpc -- line printer control program
- */
-#include <locale.h>
-#include <stdio.h>
-#include <signal.h>
-#include <ctype.h>
-#include <setjmp.h>
-#include <pwd.h>
-#include <assert.h>
-#include <sys/systeminfo.h>
-
-#include "lpc.h"
-
-#include "lp.h"
-#include "msgs.h"
-#include "oam_def.h"
-
-
-int fromatty;
-
-char cmdline[200];
-int margc;
-char *margv[20];
-int top;
-int isadmin; /* set if root or lp */
-
-jmp_buf toplevel;
-
-extern struct cmd cmdtab[];
-extern int NCMDS;
-
-extern char *Lhost;
-extern char *Printer;
-extern char *Name;
-
-#if defined (__STDC__)
- void done(int);
-static struct cmd * getcmd(char *);
-static void cmdscanner(int);
-static void intr(int);
-static void makeargv(void);
-static void startup(void);
-#else
- void done();
-static struct cmd * getcmd();
-static void cmdscanner();
-static void intr();
-static void makeargv();
-static void startup();
-#endif
-
-int
-main(int argc, char *argv[])
-{
- register struct cmd *c;
- struct passwd *p;
- char my_name[MAXNAMELEN];
-
- (void) setlocale (LC_ALL, "");
-
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- Name = argv[0];
- if (sysinfo(SI_HOSTNAME, my_name, sizeof (my_name)) < 0) {
- perror(Name);
- exit(1);
- }
- Lhost = my_name;
-
- isadmin = getuid() == 0 ||
- (p = getpwnam(LPUSER)) && p->pw_uid == getuid();
- endpwent();
-
- if (--argc > 0) {
- c = getcmd(*++argv);
- if (c == (struct cmd *)-1) {
- printf(gettext("?Ambiguous command\n"));
- exit(1);
- }
- if (c == 0) {
- printf(gettext("?Invalid command\n"));
- exit(1);
- }
- if (c->c_priv && !isadmin) {
- printf(gettext("?Privileged command\n"));
- exit(1);
- }
- startup();
- (*c->c_handler)(argc, argv);
- done(0);
- }
-
- startup();
-
- fromatty = isatty(fileno(stdin));
- top = setjmp(toplevel) == 0;
- if (top)
- sigset(SIGINT, intr);
- for (;;) {
- cmdscanner(top);
- top = 1;
- }
-}
-
-/*ARGSUSED*/
-static void
-#if defined(__STDC__)
-intr(int s)
-#else
-intr(s)
-int s;
-#endif
-{
- if (!fromatty)
- done(0);
- longjmp(toplevel, 1);
-}
-
-/*
- * Command parser.
- */
-static void
-#if defined(__STDC__)
-cmdscanner(int top)
-#else
-cmdscanner(top)
-int top;
-#endif
-{
- register struct cmd *c;
-
- if (!top)
- putchar('\n');
- for (;;) {
- if (fromatty) {
- printf("lpc> ");
- fflush(stdout);
- }
- if (fgets(cmdline, sizeof (cmdline), stdin) == 0)
- done(0);
- if (cmdline[0] == 0)
- break;
- makeargv();
- if (!margv[0])
- break;
- c = getcmd(margv[0]);
- if (c == (struct cmd *)-1) {
- printf(gettext("?Ambiguous command\n"));
- continue;
- }
- if (c == 0) {
- printf(gettext("?Invalid command\n"));
- continue;
- }
- if (c->c_priv && !isadmin) {
- printf(gettext("?Privileged command\n"));
- continue;
- }
- (*c->c_handler)(margc, margv);
- }
- longjmp(toplevel, 0);
-}
-
-static struct cmd *
-#if defined(__STDC__)
-getcmd(register char *name)
-#else
-getcmd(name)
-register char *name;
-#endif
-{
- register char *p, *q;
- register struct cmd *c, *found;
- register int nmatches, longest;
-
- longest = 0;
- nmatches = 0;
- found = 0;
- if (!name) return(0);
- for (c = cmdtab; p = c->c_name; c++) {
- for (q = name; *q == *p++; q++)
- if (*q == 0) /* exact match? */
- return(c);
- if (!*q) { /* the name was a prefix */
- if (q - name > longest) {
- longest = q - name;
- nmatches = 1;
- found = c;
- } else if (q - name == longest)
- nmatches++;
- }
- }
- if (nmatches > 1)
- return((struct cmd *)-1);
- return(found);
-}
-
-/*
- * Slice a string up into argc/argv.
- */
-static void
-#if defined(__STDC__)
-makeargv(void)
-#else
-makeargv()
-#endif
-{
- register char *cp;
- register char **argp = margv;
-
- margc = 0;
- for (cp = cmdline; *cp;) {
- while (isspace(*cp))
- cp++;
- if (*cp == '\0')
- break;
- *argp++ = cp;
- margc += 1;
- while (*cp != '\0' && !isspace(*cp))
- cp++;
- if (*cp == '\0')
- break;
- *cp++ = '\0';
- }
- *argp++ = 0;
-}
-
-#define HELPINDENT (sizeof ("directory"))
-
-/*
- * Help command.
- */
-void
-#if defined(__STDC__)
-help(int argc, char **argv)
-#else
-help(argc, argv)
-int argc;
-char **argv;
-#endif
-{
- register struct cmd *c;
-
- if (argc == 1) {
- register int i, j, w;
- int columns, width = 0, lines;
-
- printf(gettext("Commands may be abbreviated. Commands are:\n\n"));
- for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
- int len = strlen(c->c_name);
-
- if (len > width)
- width = len;
- }
- width = (width + 8) &~ 7;
- columns = 80 / width;
- if (columns == 0)
- columns = 1;
- lines = (NCMDS + columns - 1) / columns;
- for (i = 0; i < lines; i++) {
- for (j = 0; j < columns; j++) {
- c = cmdtab + j * lines + i;
- printf("%s", c->c_name);
- if (c + lines >= &cmdtab[NCMDS]) {
- printf("\n");
- break;
- }
- w = strlen(c->c_name);
- while (w < width) {
- w = (w + 8) &~ 7;
- putchar('\t');
- }
- }
- }
- return;
- }
- while (--argc > 0) {
- register char *arg;
- arg = *++argv;
- c = getcmd(arg);
- if (c == (struct cmd *)-1)
- printf(gettext("?Ambiguous help command %s\n"), arg);
- else if (c == (struct cmd *)0)
- printf(gettext("?Invalid help command %s\n"), arg);
- else
- printf("%-*s\t%s\n", HELPINDENT,
- c->c_name, c->c_help);
- }
-}
-
-static void
-#if defined(__STDC__)
-catch(int s)
-#else
-catch(s)
-int s;
-#endif
-{
- done(2);
-}
-
-static void
-#if defined(__STDC__)
-startup(void)
-#else
-startup()
-#endif
-{
- register int try = 0;
-
- if (sigset(SIGHUP, SIG_IGN) != SIG_IGN)
- (void)sigset(SIGHUP, catch);
- if (sigset(SIGINT, SIG_IGN) != SIG_IGN)
- (void)sigset(SIGINT, catch);
- if (sigset(SIGQUIT, SIG_IGN) != SIG_IGN)
- (void)sigset(SIGQUIT, catch);
- if (sigset(SIGTERM, SIG_IGN) != SIG_IGN)
- (void)sigset(SIGTERM, catch);
-
- (void)mopen();
-}
-
-void
-#if defined(__STDC__)
-done(int rc)
-#else
-done(rc)
-int rc;
-#endif
-{
- (void)mclose();
- exit(rc);
-}
diff --git a/usr/src/cmd/lp/cmd/lpc/lpc.h b/usr/src/cmd/lp/cmd/lpc/lpc.h
deleted file mode 100644
index a9af649549..0000000000
--- a/usr/src/cmd/lp/cmd/lpc/lpc.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1 */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- *
- */
-
-/*
- * Line printer control program.
- */
-struct cmd {
- char *c_name; /* command name */
- char *c_help; /* help message */
- void (*c_handler)(); /* routine to do the work */
- int c_priv; /* privileged command */
-};
-
-#if defined(__STDC__)
-char * get_reason(int, char **);
-int topq_reqid(char *, char *);
-int topq_user(char *, char *);
-void _abort(int, char **);
-void clean(int, char **);
-void cleanpr(char *);
-void disable(int, char **);
-void disablepr(char *);
-void disableq(char *);
-void do_all(void (*)(char *));
-void down(int, char **);
-void downpr(char *);
-void enable(int, char **);
-void enablepr(char *);
-void enableq(char *);
-void help(int, char **);
-void quit(int, char **);
-void restart(int, char **);
-void restartpr(char *);
-void start(int, char **);
-void status(int, char **);
-void statuspr(char *);
-void stop(int, char **);
-void topq(int, char **);
-void up(int, char **);
-void uppr(char *);
-#else
-char * get_reason();
-int topq_reqid();
-int topq_user();
-void _abort();
-void clean();
-void cleanpr();
-void disable();
-void disablepr();
-void disableq();
-void do_all();
-void down();
-void downpr();
-void enable();
-void enablepr();
-void enableq();
-void help();
-void quit();
-void restart();
-void restartpr();
-void start();
-void status();
-void statuspr();
-void stop();
-void topq();
-void up();
-void uppr();
-#endif
diff --git a/usr/src/cmd/lp/cmd/lpc/process.c b/usr/src/cmd/lp/cmd/lpc/process.c
deleted file mode 100644
index ddeda2c430..0000000000
--- a/usr/src/cmd/lp/cmd/lpc/process.c
+++ /dev/null
@@ -1,534 +0,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
- */
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-/*
- * University Copyright- Copyright (c) 1982, 1986, 1988
- * The Regents of the University of California
- * All Rights Reserved
- *
- * University Acknowledgment- Portions of this document are derived from
- * software developed by the University of California, Berkeley, and its
- * contributors.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <assert.h>
-#include <locale.h>
-
-#include "lp.h"
-#include "printers.h"
-#include "class.h"
-#include "msgs.h"
-#include "requests.h"
-#include "oam.h"
-#include "oam_def.h"
-#include "lpc.h"
-
-struct prnames {
- char *printer;
- struct prnames *next;
-};
-
-struct prnames *prhead;
-
-int got_all_prnames;
-
-extern int When;
-extern char *Reason;
-
-#if defined (__STDC__)
-static void unlinkf(char *);
-#else
-static void unlinkf();
-#endif
-
-/**
- ** Obtain all printer names from LPSCHED and save them in
- ** a linked list of printer names.
- **/
-static void
-#if defined(__STDC__)
-get_all_prnames(void)
-#else
-get_all_prnames()
-#endif
-{
-
-
-
- char *printer,
- *reject_reason,
- *request_id,
- *form,
- *char_set,
- *disable_reason;
-
- short printer_status,
- status;
-
- long enable_date,
- reject_date;
-
- int rc;
- register struct prnames *ptr, *prcur;
-
-
- if (got_all_prnames)
- return;
-
-
- /*
- * Send a message to LPSCHED to retrive all printer names
- * This is done by sending a: S_INQUIRE_PRINTER_STATUS to LPSCHED.
- * This will return the current status of the job underway on
- * all the printers on the system.
- */
- prhead = NULL;
- snd_msg(S_INQUIRE_PRINTER_STATUS, "");
- do {
- rcv_msg(R_INQUIRE_PRINTER_STATUS, &status,
- &printer,
- &form,
- &char_set,
- &disable_reason,
- &reject_reason,
- &printer_status,
- &request_id,
- &enable_date,
- &reject_date);
- if(!(ptr = (struct prnames *)malloc(sizeof(struct prnames)))) {
- lp_fatal(E_LP_MALLOC);
- /*NOTREACHED*/
- }
- if(prhead == NULL)
- prhead = ptr;
- else
- prcur->next = ptr;
- prcur = ptr;
- /* Copy : printer name
- * Increment the entry count.
- */
- ptr->printer = (char *)malloc(strlen(printer) + 1);
- strcpy(ptr->printer, printer);
- ptr->next = NULL;
- } while(status== MOKMORE);
- got_all_prnames = 1;
- return;
-}
-
-
-
-/*
-** The actual work in passing the commands to LPCSHED is done here
-** i.e: Enable/disable the queues
-** Enable/disable the printers
-** canceling jobs and the temporary files etc
-**/
-
-/*
-** Disable the queue to a printer.
-**/
-void
-#if defined(__STDC__)
-disableq(char *dest)
-#else
-disableq(dest)
-char *dest;
-#endif
-{
- short status;
- char *reason = Reason;
-
- if (!reason)
- reason = "unknown reason";
-
- snd_msg(S_REJECT_DEST, dest, reason);
- rcv_msg(R_REJECT_DEST, &status);
- switch (status) {
- case MOK:
- case MERRDEST:
- printf(gettext("%s:\n\tqueuing disabled\n"), dest);
- break;
- case MNODEST:
- printf(gettext("unknown printer %s\n"), dest);
- break;
- case MNOPERM:
- printf(gettext("%s:\n\tcannot disable queuing\n"), dest);
- break;
- default:
- lp_fatal(E_LP_BADSTATUS, status);
- /*NOTREACHED*/
- }
-}
-/*
-** Enable the queue to a printer.
-**/
-
-void
-#if defined(__STDC__)
-enableq(char *dest)
-#else
-enableq(dest)
-char *dest;
-#endif
-{
- short status;
-
- snd_msg(S_ACCEPT_DEST, dest);
- rcv_msg(R_ACCEPT_DEST, &status);
- switch (status) {
- case MOK:
- case MERRDEST:
- printf("%s:\n", dest);
- printf(gettext("\tqueueing enabled\n"));
- break;
- case MNODEST:
- printf(gettext("unknown printer %s\n"), dest);
- break;
- case MNOPERM:
- printf("%s:\n", dest);
- printf(gettext("\tcannot enable queueing\n"));
- break;
- default:
- lp_fatal(E_LP_BADSTATUS, status);
- /*NOTREACHED*/
- }
-
-}
-
-/*
-** Enable printing on the given printer.
-**/
-void
-#if defined(__STDC__)
-enablepr(char *dest)
-#else
-enablepr(dest)
-char *dest;
-#endif
-{
- short status;
-
- snd_msg(S_ENABLE_DEST, dest);
- rcv_msg(R_ENABLE_DEST, &status);
- switch (status) {
- case MOK:
- case MERRDEST:
- printf("%s:\n", dest);
- printf(gettext("\tprinting enabled\n"));
- break;
- case MNODEST:
- printf(gettext("unknown printer %s\n"), dest);
- break;
- case MNOPERM:
- printf("%s:\n", dest);
- printf(gettext("\tcannot enable printing\n"));
- break;
- default:
- lp_fatal(E_LP_BADSTATUS, status);
- /*NOTREACHED*/
- }
-}
-
-/*
-** Disable printing on the named printer.
-**/
-void
-#if defined(__STDC__)
-disablepr(char *dest)
-#else
-disablepr(dest)
-char *dest;
-#endif
-{
- short status;
- char *req_id;
- char *reason = Reason;
-
- if (!reason)
- reason = "stopped by user";
-
- snd_msg(S_DISABLE_DEST, dest, reason, When);
- rcv_msg(R_DISABLE_DEST, &status, &req_id);
- switch (status) {
- case MOK:
- case MERRDEST:
- printf("%s:\n", dest);
- printf(gettext("\tprinting disabled\n"));
- break;
- case MNODEST:
- printf(gettext("unknown printer %s\n"), dest);
- break;
- case MNOPERM:
- printf("%s:\n", dest);
- printf(gettext("\tcannot disable printing\n"));
- break;
- default:
- lp_fatal(E_LP_BADSTATUS, status);
- /*NOTREACHED*/
- }
- return;
-}
-
-void
-#if defined(__STDC__)
-statuspr(char *printer)
-#else
-statuspr(printer)
-char *printer;
-#endif
-{
- char *tprinter;
-
- int rc, entry_count;
-
- char *user,
- *reject_reason,
- *request_id,
- *form,
- *slabel,
- *file,
- *char_set,
- *disable_reason;
-
- short printer_status,
- status, rank,
- state;
-
- long size,
- enable_date,
- reject_date,
- date;
- char buff[100];
-
- entry_count = 0;
- snd_msg(S_INQUIRE_PRINTER_STATUS, printer);
- rcv_msg(R_INQUIRE_PRINTER_STATUS, &status,
- &tprinter,
- &form,
- &char_set,
- &disable_reason,
- &reject_reason,
- &printer_status,
- &request_id,
- &enable_date,
- &reject_date);
- switch (status) {
- case MOK:
- case MOKMORE:
- break;
- case MNODEST:
- printf(gettext("unknown printer %s\n"), printer);
- return;
- default:
- lp_fatal(E_LP_BADSTATUS, status);
- /*NOTREACHED*/
- }
- printf("%s:\n", printer);
- printf(gettext("\tqueueing is %s\n"), printer_status & PS_REJECTED ? gettext("disabled") :
- gettext("enabled"));
- printf(gettext("\tprinting is %s\n"), printer_status & PS_DISABLED ? gettext("disabled") :
- gettext("enabled"));
- snd_msg(S_INQUIRE_REQUEST_RANK, "", "", printer, "", "");
- do {
- rcv_msg(R_INQUIRE_REQUEST_RANK, &status,
- &request_id,
- &user,
- &slabel,
- &size,
- &date,
- &state,
- &tprinter,
- &form,
- &char_set,
- &rank,
- &file);
- switch (status) {
- case MOK:
- case MOKMORE:
- if (!(state & RS_DONE))
- entry_count++;
- break;
- case MNOINFO:
- break;
- default:
- lp_fatal(E_LP_BADSTATUS, status);
- /*NOTREACHED*/
- }
- } while (status == MOKMORE);
- if (entry_count == 0 )
- printf(gettext("\tno entries\n"));
- else if (entry_count == 1)
- printf(gettext("\t1 entry in spool area\n"));
- else
- printf(gettext("\t%d entries in spool area\n"), entry_count);
- if (entry_count) {
- if (!(printer_status & (PS_FAULTED|PS_DISABLED)))
- printf(gettext("\t%s is ready and printing\n"), printer);
- else if (printer_status & PS_FAULTED)
- printf(gettext("\twaiting for %s to become ready (offline?)\n"), printer);
- }
-
- /*??? what to do for remote printers:
- possible status:
- "waiting for RM to come up"
- "waiting for queue to be enabled on RM"
- "sending to RM"
- "no space on remote; waiting for queue to drain"
- */
-}
-
-void
-#if defined(__STDC__)
-restartpr(char *dest)
-#else
-restartpr(dest)
-char *dest;
-#endif
-{
- disablepr(dest);
- enablepr(dest);
-}
-
-void
-#if defined(__STDC__)
-uppr(char *dest)
-#else
-uppr(dest)
-char *dest;
-#endif
-{
- enableq(dest);
- enablepr(dest);
-}
-
-void
-#if defined(__STDC__)
-downpr(char *dest)
-#else
-downpr(dest)
-char *dest;
-#endif
-{
- disableq(dest);
- disablepr(dest);
-}
-
-/* avoids compiler type checking problem */
-static int
-#if defined(__STDC__)
-_strcmp(const void *s1, const void *s2)
-#else
-_strcmp(s1, s2)
-void *s1;
-void *s2;
-#endif
-{
- return(strcmp(s1, s2));
-}
-
-void
-#if defined(__STDC__)
-cleanpr(char *dest)
-#else
-cleanpr(dest)
-char *dest;
-#endif
-{
- int i;
- short more;
- long status;
- char * req_id;
-
- snd_msg(S_CANCEL, dest, "", "");
-
- do {
- rcv_msg(R_CANCEL, &more, &status, &req_id);
-
- switch (status) {
- case MOK:
- printf(gettext("\tremoved %s\n"), req_id);
- break;
- case M2LATE:
- printf(gettext("\tbusy %s failed\n"), req_id);
- break;
- case MUNKNOWN:
- case MNOINFO:
- case MNOPERM:
- printf(gettext("\t%s failed\n"), req_id);
- break;
- default:
- printf(gettext("Unknown status from scheduler (%d)\n"),
- status);
- exit (1);
- }
-
- } while (more == MOKMORE);
-
- return;
-
-
-
-}
-
-static void
-#if defined(__STDC__)
-unlinkf(char *name)
-#else
-unlinkf(name)
-char *name;
-#endif
-{
- if (unlink(name) < 0)
- printf(gettext("\tcannot remove %s\n"), name);
- else
- printf(gettext("\tremoved %s\n"), name);
-}
-
-void
-#if defined(__STDC__)
-do_all(void (*func)(char *))
-#else
-do_all(func)
-void (*func)();
-#endif
-{
- register struct prnames *ptr;
-
- get_all_prnames();
-
- for (ptr = prhead; ptr; ptr = ptr->next)
- (*func)(ptr->printer);
-}
diff --git a/usr/src/cmd/lp/cmd/lpc/sndrcv.c b/usr/src/cmd/lp/cmd/lpc/sndrcv.c
deleted file mode 100644
index b989ba5a86..0000000000
--- a/usr/src/cmd/lp/cmd/lpc/sndrcv.c
+++ /dev/null
@@ -1,112 +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) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-/*
- * University Copyright- Copyright (c) 1982, 1986, 1988
- * The Regents of the University of California
- * All Rights Reserved
- *
- * University Acknowledgment- Portions of this document are derived from
- * software developed by the University of California, Berkeley, and its
- * contributors.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */
-
-#if defined(__STDC__)
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include "lp.h"
-#include "msgs.h"
-#define WHO_AM_I I_AM_OZ /* to get oam.h to unfold */
-#include "oam.h"
-#include "lpd.h"
-
-/*
- * Format and send message to lpsched
- * (die if any errors occur)
- */
-/*VARARGS1*/
-void
-#if defined (__STDC__)
-snd_msg(int type, ...)
-#else
-snd_msg(type, va_alist)
-int type;
-va_dcl
-#endif
-{
- va_list ap;
-
-#if defined (__STDC__)
- va_start(ap, type);
-#else
- va_start(ap);
-#endif
- (void)_putmessage (Msg, type, ap);
- va_end(ap);
- if (msend(Msg) == -1) {
- lp_fatal(E_LP_MSEND);
- /*NOTREACHED*/
- }
-}
-
-/*
- * Recieve message from lpsched
- * (die if any errors occur)
- */
-void
-#if defined (__STDC__)
-rcv_msg(int type, ...)
-#else
-rcv_msg(type, va_alist)
-int type;
-va_dcl
-#endif
-{
- va_list ap;
- int rc;
-
- if ((rc = mrecv(Msg, MSGMAX)) != type) {
- if (rc == -1)
- lp_fatal(E_LP_MRECV);
- else
- lp_fatal(E_LP_BADREPLY, rc);
- /*NOTREACHED*/
- }
-#if defined (__STDC__)
- va_start(ap, type);
-#else
- va_start(ap);
-#endif
- rc = _getmessage(Msg, type, ap);
- va_end(ap);
- if (rc < 0) {
- lp_fatal(E_LP_GETMSG, PERROR);
- /*NOTREACHED*/
- }
-}
diff --git a/usr/src/cmd/lp/cmd/lpc/topq.c b/usr/src/cmd/lp/cmd/lpc/topq.c
deleted file mode 100644
index 4a5b0fccff..0000000000
--- a/usr/src/cmd/lp/cmd/lpc/topq.c
+++ /dev/null
@@ -1,210 +0,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
- */
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-/*
- * University Copyright- Copyright (c) 1982, 1986, 1988
- * The Regents of the University of California
- * All Rights Reserved
- *
- * University Acknowledgment- Portions of this document are derived from
- * software developed by the University of California, Berkeley, and its
- * contributors.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <locale.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <assert.h>
-
-#include "lp.h"
-#include "printers.h"
-#include "class.h"
-#include "msgs.h"
-#include "requests.h"
-#define WHO_AM_I I_AM_OZ
-#include "oam_def.h"
-
-extern char *Printer;
-
-#if defined(__STDC__)
-static char * start_change(char *);
-static int end_change(char *);
-#else
-static char * start_change();
-static int end_change();
-#endif
-
-int
-#if defined(__STDC__)
-topq_reqid(char *reqid, char *machine)
-#else
-topq_reqid(reqid, machine)
-char *reqid;
-char *machine;
-#endif
-{
-
- /*
- ** This is similar to: lp -i request-id -H IMMEDIATE
- */
-
- char *reqfile; /* Name of request file */
- REQUEST *oldrqp;
- char buf[50];
-
- if (machine) {
- (void) snprintf(buf, sizeof (buf), "%s!%s", machine, reqid);
- reqid = buf;
- }
- if (!(reqfile = start_change(reqid)))
- return(0);
-
- if (!(oldrqp = getrequest(reqfile)))
- return (0);
-
- oldrqp->actions |= ACT_IMMEDIATE;
-
- if (putrequest(reqfile, oldrqp) == -1) { /* write request file */
- switch(errno) {
- default:
- lp_fatal(E_LPP_FPUTREQ);
- /*NOTREACHED*/
- }
- }
- free(reqfile);
- (void)end_change(reqid);
-
- printf(gettext("\tmoved %s\n"), reqid);
- return(1);
-}
-
-
-/* start_change -- start change request */
-static char *
-#if defined(__STDC__)
-start_change(char *rqid)
-#else
-start_change(rqid)
-char *rqid;
-#endif
-{
- short status;
- char *rqfile;
-
- snd_msg(S_START_CHANGE_REQUEST, rqid);
- rcv_msg(R_START_CHANGE_REQUEST, &status, &rqfile);
-
- switch (status) {
- case MOK:
- return((char *)strdup(rqfile));
- default:
- return(NULL);
- }
-}
-
-static int
-#if defined(__STDC__)
-end_change(char *rqid)
-#else
-end_change(rqid)
-char *rqid;
-#endif
-{
- long chkbits;
- short status;
-
- snd_msg(S_END_CHANGE_REQUEST, rqid);
- rcv_msg(R_END_CHANGE_REQUEST, &status, &chkbits);
-
- switch (status) {
- case MOK:
- return(1);
- default:
- return(0);
- }
-}
-
-/*
-** topq command handler if user name is specified
-** Find request-ids of all jobs submitted by the user.
-** Save the request-ids
-** Follow the same method as in topq_reqid for each if the ids.
-*/
-int
-#if defined(__STDC__)
-topq_user(char *user, char *machine)
-#else
-topq_user(user, machine)
-char *user;
-char *machine;
-#endif
-{
- char *request_id, *form, *slabel, *character_set;
- char buf[50];
- char **rqlist = NULL, **pp;
- short state, status;
- long size, date;
- int count = 0;
-
-
- if (machine) {
- (void) snprintf(buf, sizeof (buf), "%s!%s", machine, user);
- user = buf;
- }
- snd_msg(S_INQUIRE_REQUEST, "", Printer, "", user, "");
- do {
- rcv_msg(R_INQUIRE_REQUEST, &status,
- &request_id,
- &user,
- &slabel,
- &size,
- &date,
- &state,
- &Printer,
- &form,
- &character_set);
- switch (status) {
- case MOK:
- case MOKMORE:
- appendlist(&rqlist, request_id);
- break;
- default:
- return(0);
- }
- } while (status == MOKMORE);
- for (pp = rqlist; *pp; pp++)
- count += topq_reqid(*pp, machine);
- freelist(rqlist);
- return(count); /* Number of jobs moved to topq */
-}
diff --git a/usr/src/cmd/lp/cmd/lpmove.c b/usr/src/cmd/lp/cmd/lpmove.c
deleted file mode 100644
index 56d52e38b1..0000000000
--- a/usr/src/cmd/lp/cmd/lpmove.c
+++ /dev/null
@@ -1,376 +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.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/* lpmove dest1 dest2 - move all requests from dest1 to dest2
- * lpmove request ... dest - move requests to destination dest
- *
- * This command may be used only by an LP Administrator
- */
-
-#include <assert.h>
-#include <signal.h>
-#include <locale.h>
-#include <sys/types.h>
-
-#include "lp.h"
-#include "msgs.h"
-#include "printers.h"
-
-#define WHO_AM_I I_AM_LPMOVE
-#include "oam.h"
-
-char message[100],
- reply[100];
-
-#define TRUE 1
-#define FALSE 0
-
-void startup(), cleanup(), err_exit();
-static int accept(char *);
-static int reject(char *, char *);
-
-#if defined(__STDC__)
-void catch();
-#else
-int catch();
-#endif
-
-void
-usage()
-{
- (void) printf (gettext(
-"usage:\n"
-"\n"
-" (move all requests, reject any new requests)\n"
-" lpmove from-destination to-destination\n"
-"\n"
-" (move individual requests)\n"
-" lpmove requests ... to-destination\n"));
-
- return;
-}
-
-char *strncpy();
-
-int
-main(int argc, char *argv[])
-{
- int i, type, size, rc = 0, wasrej;
- short status;
- char *strchr(), *rq_id, *chkp;
- long chkbits;
- short nmove = 0;
-
- (void) setlocale(LC_ALL, "");
-
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- if (argc == 2 && STREQU(argv[1], "-?")) {
- usage();
- exit(0);
- }
- if(argc < 3) {
- usage();
- exit(1);
- }
-
- startup();
-
- if (!isrequest(argv[1])) { /* if first arg is a dest */
- if(argc != 3) {
- usage();
- exit(1);
- }
-
- if ((wasrej = reject(argv[1],argv[2])) == 1) err_exit();
-
- printf(gettext("move in progress ...\n"));
- size = putmessage(message, S_MOVE_DEST, argv[1], argv[2]);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- goto Errexit;
- }
- while (1) {
- if ((type = mrecv(reply, sizeof(reply))) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- goto Errexit;
- }
- if (type != R_MOVE_DEST
- || getmessage(reply, type, &status, &rq_id, &nmove) == -1) {
- LP_ERRMSG1 (ERROR, E_LP_BADREPLY, type);
- goto Errexit;
- }
- switch (status) {
- case MOK:
- break;
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, rq_id);
-Errexit: if (!wasrej) accept(argv[1]);
- err_exit();
- case MERRDEST:
- LP_ERRMSG1(WARNING, E_MOV_BADDEST, rq_id);
- rc = 1;
- break;
- case MMORERR:
- LP_ERRMSG1(WARNING, E_MOV_BADDEST, rq_id);
- rc = 1;
- continue;
- case MNOPERM:
- LP_ERRMSG(ERROR, E_LP_NOTADM);
- err_exit();
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- rc = 1;
- }
- break;
- }
- printf(gettext("total of %d requests moved from %s to %s\n"),
- nmove, argv[1], argv[2]);
- } else {
- for(i = 1; i < argc - 1; i++) {
- size = putmessage(message,
- S_MOVE_REQUEST, argv[i], argv[argc-1]);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- err_exit();
- }
- if ((type = mrecv(reply, sizeof(reply))) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- err_exit();
- }
- if (type != R_MOVE_REQUEST
- || getmessage(reply, type, &status, &chkbits) == -1) {
- LP_ERRMSG1 (ERROR, E_LP_BADREPLY, type);
- err_exit();
- }
- switch (status) {
- case MOK:
- nmove++;
- break;
- case MDENYDEST:
- if (chkbits) {
- chkp = message;
- if (chkbits & PCK_TYPE) chkp += sprintf(chkp, "printer type, ");
- if (chkbits & PCK_CHARSET) chkp += sprintf(chkp, "character set, ");
- if (chkbits & PCK_CPI) chkp += sprintf(chkp, "cpi, ");
- if (chkbits & PCK_LPI) chkp += sprintf(chkp, "lpi, ");
- if (chkbits & PCK_WIDTH) chkp += sprintf(chkp, "width, ");
- if (chkbits & PCK_LENGTH) chkp += sprintf(chkp, "length, ");
- if (chkbits & PCK_BANNER) chkp += sprintf(chkp, "banner req., ");
- chkp[-2] = 0;
- LP_ERRMSG2(ERROR, E_MOV_PTRCHK, argv[i], message);
- }
- else LP_ERRMSG1(ERROR, E_MOV_DENYDEST, argv[i]);
- rc = 1;
- break;
- case MNOMEDIA:
- LP_ERRMSG1(ERROR, E_MOV_NOMEDIA, argv[i]);
- rc = 1;
- break;
- case MDENYMEDIA:
- LP_ERRMSG1(ERROR, E_MOV_DENYMEDIA, argv[i]);
- rc = 1;
- break;
- case MNOMOUNT:
- LP_ERRMSG1(ERROR, E_MOV_NOMOUNT, argv[i]);
- rc = 1;
- break;
- case MNOFILTER:
- LP_ERRMSG1(ERROR, E_MOV_NOFILTER, argv[i]);
- rc = 1;
- break;
- case MERRDEST:
- LP_ERRMSG1(ERROR, E_LP_REQDENY, argv[argc-1]);
- rc = 1;
- break;
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, argv[argc-1]);
- err_exit();
- case MUNKNOWN:
- LP_ERRMSG1(ERROR, E_LP_UNKREQID, argv[i]);
- rc = 1;
- break;
- case MBUSY:
- LP_ERRMSG1(ERROR, E_LP_BUSY, argv[i]);
- rc = 1;
- break;
- case M2LATE:
- LP_ERRMSG1(ERROR, E_LP_2LATE, argv[i]);
- rc = 1;
- break;
- case MNOPERM:
- LP_ERRMSG (ERROR, E_LP_NOTADM);
- err_exit();
- case MGONEREMOTE:
- LP_ERRMSG1(ERROR, E_LP_GONEREMOTE, argv[i]);
- break;
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- rc = 1;
- }
- }
- printf(gettext("total of %d requests moved to %s\n"), nmove, argv[argc-1]);
- }
-
- cleanup();
- return (rc);
-}
-
-static int
-accept(char *dest)
-{
- int type, size;
- short status;
-
- size = putmessage(message, S_ACCEPT_DEST, dest);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- return(1);
- }
- if ((type = mrecv(reply, size)) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- return(1);
- }
- if (type != R_ACCEPT_DEST
- || getmessage(reply, type, &status) == -1) {
- LP_ERRMSG(ERROR, E_LP_BADREPLY);
- return(1);
- }
- switch (status) {
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest);
- return(1);
- case MNOPERM:
- LP_ERRMSG (ERROR, E_LP_NOTADM);
- return(1);
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- return(1);
- case MOK:
- case MERRDEST:
- ;
- }
-
- return (0);
-}
-
-static int
-reject(char *d1, char *d2)
-{
- int type, size;
- short status;
- char reason[128];
-
- /* reject(dest, reason) */
- snprintf(reason, sizeof (reason), "requests moved to %s", d2);
- size = putmessage(message, S_REJECT_DEST, d1, reason);
- assert(size != -1);
- if (msend(message)) {
- LP_ERRMSG(ERROR, E_LP_MSEND);
- return(1);
- }
- if ((type = mrecv(reply, size)) == -1) {
- LP_ERRMSG(ERROR, E_LP_MRECV);
- return(1);
- }
- if (type != R_REJECT_DEST
- || getmessage(reply, type, &status) == -1) {
- LP_ERRMSG(ERROR, E_LP_BADREPLY);
- return(1);
- }
- switch (status) {
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_DSTUNK, d1);
- return(1);
- case MNOPERM:
- LP_ERRMSG (ERROR, E_LP_NOTADM);
- return(1);
- default:
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- return(1);
- case MERRDEST:
- return(-1); /* was rejecting */
- case MOK:
- printf(gettext("destination %s is not accepting requests\n"), d1);
- break;
- }
-
- return (0);
-}
-
-void
-startup()
-{
- if (mopen()) {LP_ERRMSG(ERROR, E_LP_MOPEN); exit(1);}
-
- if(signal(SIGHUP, SIG_IGN) != SIG_IGN)
- signal(SIGHUP, catch);
- if(signal(SIGINT, SIG_IGN) != SIG_IGN)
- signal(SIGINT, catch);
- if(signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- signal(SIGQUIT, catch);
- if(signal(SIGTERM, SIG_IGN) != SIG_IGN)
- signal(SIGTERM, catch);
-}
-
-/* catch -- catch signals */
-
-#if defined(__STDC__)
-void
-#endif
-catch()
-{
-
- signal(SIGHUP, SIG_IGN);
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- err_exit();
-}
-
-void
-cleanup()
-{
- (void)mclose ();
-}
-
-void
-err_exit()
-{
- cleanup();
- exit(1);
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/accept.c b/usr/src/cmd/lp/cmd/lpstat/accept.c
deleted file mode 100644
index 987682cde8..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/accept.c
+++ /dev/null
@@ -1,106 +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) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <locale.h>
-#include "stdio.h"
-
-#include "lp.h"
-#include "class.h"
-#include "msgs.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-
-/**
- ** do_accept()
- **/
-
-void
-#if defined(__STDC__)
-do_accept (
- char ** list
-)
-#else
-do_accept (list)
- char **list;
-#endif
-{
- while (*list) {
- if (STREQU(*list, NAME_ALL)) {
- send_message (S_INQUIRE_CLASS, "");
- (void)output (R_INQUIRE_CLASS);
- send_message (S_INQUIRE_PRINTER_STATUS, "");
- (void)output (R_INQUIRE_PRINTER_STATUS);
-
- } else if (isclass(*list)) {
- send_message (S_INQUIRE_CLASS, *list);
- (void)output (R_INQUIRE_CLASS);
-
- } else {
- send_message (S_INQUIRE_PRINTER_STATUS, *list);
- switch (output(R_INQUIRE_PRINTER_STATUS)) {
- case MNODEST:
- LP_ERRMSG1 (ERROR, E_LP_BADDEST, *list);
- exit_rc = 1;
- break;
- }
-
- }
- list++;
- }
- return;
-}
-
-/**
- ** putqline()
- **/
-
-void
-putqline(char *dest, int rejecting, time_t date, char *reject_reason)
-{
- char reject_date[SZ_DATE_BUFF];
-
- (void) strftime(reject_date, sizeof (reject_date), NULL,
- localtime(&date));
-
-
- if (!rejecting)
- (void) printf(gettext("%s accepting requests since %s\n"),
- dest, reject_date);
- else
- (void) printf(
- gettext("%s not accepting requests since %s -\n\t%s\n"),
- dest, reject_date, reject_reason);
- return;
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/add_mounted.c b/usr/src/cmd/lp/cmd/lpstat/add_mounted.c
deleted file mode 100644
index f89f633caf..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/add_mounted.c
+++ /dev/null
@@ -1,267 +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 1993 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.8 */
-
-#include "string.h"
-#include "errno.h"
-#include "sys/types.h"
-#include "stdlib.h"
-
-#include "lp.h"
-#include "printers.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-
-
-#define nuther_mount() (MOUNTED *)Malloc(sizeof(MOUNTED))
-
-static MOUNTED mounted_forms_head = { 0, 0, 0 },
- mounted_pwheels_head = { 0, 0, 0 };
-
-MOUNTED *mounted_forms = &mounted_forms_head,
- *mounted_pwheels = &mounted_pwheels_head;
-
-static void insert_mounted ( MOUNTED * , char * , char * , char * );
-static int cs_addlist ( char *** , char * );
-
-/**
- ** add_mounted() - ADD A FORM, PRINTWHEEL TO LIST
- **/
-
-void
-add_mounted(char *printer, char *form, char *pwheel)
-{
- register PRINTER *pp;
-
- register char **pcs;
- char *ptrForm,*ptrEndForm;
-
-
- /*
- * Add this form to the list of mounted forms.
- */
- if (form && *form)
- if (ptrEndForm = strchr(form,*LP_SEP) ) {
- ptrForm = form;
- while (ptrEndForm) {
- *ptrEndForm = 0;
- insert_mounted(mounted_forms, ptrForm, printer,
- (char *)0);
- ptrForm = ptrEndForm+1;
- ptrEndForm = strchr(ptrForm,*LP_SEP);
- }
- } else
- insert_mounted(mounted_forms, form, printer, (char *)0);
-
- /*
- * Add this print wheel to the list of mounted print
- * wheels.
- */
- if (pwheel && *pwheel)
- insert_mounted (
- mounted_pwheels,
- pwheel,
- printer,
- "!"
- );
-
- if (!(pp = getprinter(printer))) {
- LP_ERRMSG2 (ERROR, E_LP_GETPRINTER, printer, PERROR);
- done(1);
- }
-
- /*
- * Add the list of administrator supplied character-set
- * or print wheel aliases to the list.
- */
- if (pp->char_sets)
- for (pcs = pp->char_sets; *pcs; pcs++)
- if (pp->daisy)
- insert_mounted (
- mounted_pwheels,
- *pcs,
- printer,
- (char *)0
- );
-
- else {
- register char *terminfo_name,
- *alias;
-
- if (
- (terminfo_name = strtok(*pcs, "="))
- && (alias = strtok((char *)0, "="))
- )
- insert_mounted (
- mounted_pwheels,
- alias,
- printer,
- terminfo_name
- );
- }
-
- /*
- * Do the aliases built into the Terminfo database for
- * this printer's type. This applies only to printers
- * that have defined character sets.
- */
- if ((pcs = get_charsets(pp, 1)))
- for ( ; *pcs; pcs++) {
- register char *terminfo_name,
- *alias;
-
- if (
- (terminfo_name = strtok(*pcs, "="))
- && (alias = strtok((char *)0, "="))
- )
- insert_mounted (
- mounted_pwheels,
- alias,
- printer,
- terminfo_name
- );
- }
-
-
- return;
-}
-
-/**
- ** insert_mounted()
- **/
-
-static void
-insert_mounted(MOUNTED *ml, char *name, char *printer, char *tag)
-{
- register MOUNTED *pm;
-
- register char *nm,
- *pnm;
-
-
- /*
- * For forms: Each printer that has the form mounted is
- * marked with a leading '!'.
- * For print wheels and character sets: Each character
- * set name is marked with a leading '!'; each printer
- * that has a print wheel mounted is marked with a leading '!'.
- */
-
- if (tag && tag[0] != '!') {
- nm = Malloc(1 + strlen(name) + 1);
- nm[0] = '!';
- (void)strcpy (nm + 1, name);
- } else
- nm = name;
-
- for (
- pm = ml;
- pm->name && !STREQU(pm->name, nm);
- pm = pm->forward
- )
- ;
-
- if (tag && tag[0] == '!') {
- pnm = Malloc(1 + strlen(printer) + 1);
- pnm[0] = '!';
- (void)strcpy (pnm + 1, printer);
-
- } else if (tag) {
- pnm = Malloc(strlen(printer) + 1 + strlen(tag) + 1);
- (void)sprintf (pnm, "%s=%s", printer, tag);
-
- } else
- pnm = printer;
-
-
- if (cs_addlist(&(pm->printers), pnm) == -1) {
- LP_ERRMSG (ERROR, E_LP_MALLOC);
- done (1);
- }
-
- if (!pm->name) {
- pm->name = strdup(nm);
- pm = (pm->forward = nuther_mount());
- pm->name = 0;
- pm->printers = 0;
- pm->forward = 0;
- }
-
- return;
-}
-
-/**
- ** cs_addlist()
- **/
-
-static int
-cs_addlist(char ***plist, char *item)
-{
- register char **pl;
-
- register int n;
-
- if (*plist) {
-
- n = lenlist(*plist);
-
- for (pl = *plist; *pl; pl++)
- if (
- (*pl)[0] == '!' && STREQU((*pl)+1, item)
- || STREQU(*pl, item)
- )
- break;
-
- if (!*pl) {
-
- n++;
- *plist = (char **)Realloc(
- (char *)*plist,
- (n + 1) * sizeof(char *)
- );
- (*plist)[n - 1] = strdup(item);
- (*plist)[n] = 0;
-
- }
-
- } else {
-
- *plist = (char **)Malloc(2 * sizeof(char *));
- (*plist)[0] = strdup(item);
- (*plist)[1] = 0;
-
- }
-
- return (0);
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/charset.c b/usr/src/cmd/lp/cmd/lpstat/charset.c
deleted file mode 100644
index 6d6f504e9c..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/charset.c
+++ /dev/null
@@ -1,230 +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 1991 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.6 */
-
-#include "string.h"
-#include "sys/types.h"
-#include "stdlib.h"
-
-#include "lp.h"
-#include "form.h"
-#include "access.h"
-#include "printers.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-#include <locale.h>
-
-extern char *tparm();
-
-#if defined(__STDC__)
-static void putsline ( MOUNTED * );
-#else
-static void putsline();
-#endif
-
-/**
- ** do_charset()
- **/
-
-void
-#if defined(__STDC__)
-do_charset (
- char ** list
-)
-#else
-do_charset (list)
- char ** list;
-#endif
-{
- register MOUNTED * pm;
-
- register int found;
-
-
- while (*list) {
- if (STREQU(NAME_ALL, *list))
- for (pm = mounted_pwheels; pm->name; pm = pm->forward)
- putsline (pm);
-
- else {
- found = 0;
- for (pm = mounted_pwheels; pm->name; pm = pm->forward)
- if (
- pm->name[0] == '!'
- && STREQU(pm->name + 1, *list)
- || STREQU(pm->name, *list)
- ) {
- putsline (pm);
- found = 1;
- }
- if (!found) {
- LP_ERRMSG1 (ERROR, E_STAT_BADSET, *list);
- exit_rc = 1;
- }
- }
- list++;
- }
- return;
-}
-
-/**
- ** putsline()
- **/
-
-static void
-#if defined(__STDC__)
-putsline (
- MOUNTED * pm
-)
-#else
-putsline (pm)
- register MOUNTED *pm;
-#endif
-{
- register char ** pp;
- register char * sep;
-
-
- if (pm->name[0] != '!') {
-
- if ((pp = pm->printers))
- if (verbosity & V_LONG) {
- (void)printf (gettext("print wheel %s\n\tavailable on:"), pm->name);
- while (*pp) {
- if ((*pp)[0] == '!')
- (void)printf (
- gettext("\n\t\t%s (mounted)"),
- *pp + 1
- );
- else
- (void)printf ("\n\t\t%s", *pp);
- pp++;
- }
- } else {
- sep = ", mounted on ";
- while (*pp) {
- if ((verbosity & V_LONG) || (*pp)[0] == '!') {
- (void)printf (
- "%s%s",
- sep,
- ((*pp)[0] == '!'? *pp + 1 : *pp)
- );
- sep = ",";
- }
- pp++;
- }
- }
-
- (void)printf ("\n");
-
- } else {
-
- (void)printf (gettext("character set %s\n"), pm->name + 1);
-
- if ((verbosity & V_LONG) && (pp = pm->printers)) {
- (void)printf (gettext("\tavailable on:\n"));
- while (*pp) {
- (void)printf (
- "\t\t%s (as %s)\n",
- strtok(*pp, "="),
- strtok((char *)0, "=")
- );
- pp++;
- }
- }
-
- }
- return;
-}
-
-/**
- ** get_charsets() - CONSTRUCT (char **) LIST OF CHARSETS FROM csnm
- **/
-
-char **
-#if defined(__STDC__)
-get_charsets (
- PRINTER * prbufp,
- int addcs
-)
-#else
-get_charsets (prbufp, addcs)
- PRINTER *prbufp;
- register int addcs;
-#endif
-{
- register int cs = 0;
-
- register char * name;
-
- register char ** pt;
-
- char * csnm;
- char ** list = 0;
-
-
- if (
- prbufp->printer_types
- && !STREQU(*(prbufp->printer_types), NAME_UNKNOWN)
- && !prbufp->daisy
- )
- for (pt = prbufp->printer_types; *pt; pt++)
- if (tidbit(*pt, "csnm", &csnm) != -1 && csnm && *csnm) {
- for (cs = 0; cs <= 63; cs++)
- if ((name = tparm(csnm, cs)) && *name) {
-
- if (addcs) {
- register char *nm = Malloc(
- 2+2+1 + strlen(name) + 1
- );
-
- sprintf (nm, "cs%d=%s", cs, name);
- name = nm;
- }
-
- if (addlist(&list, name) == -1) {
- LP_ERRMSG (ERROR, E_LP_MALLOC);
- done (1);
- }
-
- } else
- /*
- * Assume that a break in the
- * numbers means we're done.
- */
- break;
- }
-
- return (list);
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/class.c b/usr/src/cmd/lp/cmd/lpstat/class.c
deleted file mode 100644
index c567d86971..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/class.c
+++ /dev/null
@@ -1,103 +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 1991 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.5 */
-
-#include <locale.h>
-#include "stdio.h"
-
-#include "lp.h"
-#include "class.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-
-
-#if defined(__STDC__)
-static void putcline ( CLASS * );
-#else
-static void putcline();
-#endif
-
-/**
- ** do_class()
- **/
-
-void
-#if defined(__STDC__)
-do_class (
- char ** list
-)
-#else
-do_class (list)
- char **list;
-#endif
-{
- register CLASS *pc;
-
- printlist_setup ("\t", 0, 0, 0);
- while (*list) {
- if (STREQU(NAME_ALL, *list))
- while ((pc = getclass(NAME_ALL)))
- putcline (pc);
-
- else if ((pc = getclass(*list)))
- putcline (pc);
-
- else {
- LP_ERRMSG1 (ERROR, E_LP_NOCLASS, *list);
- exit_rc = 1;
- }
- list++;
- }
- printlist_unsetup ();
- return;
-}
-
-/**
- ** putcline()
- **/
-
-static void
-#if defined(__STDC__)
-putcline (
- CLASS * pc
-)
-#else
-putcline (pc)
- register CLASS *pc;
-#endif
-{
- (void) printf(gettext("members of class %s:\n"), pc->name);
- printlist (stdout, pc->members);
- return;
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/device.c b/usr/src/cmd/lp/cmd/lpstat/device.c
deleted file mode 100644
index afc21c56a8..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/device.c
+++ /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 1991 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */
-
-#include <locale.h>
-#include "sys/types.h"
-#include "string.h"
-
-#include "lp.h"
-#include "printers.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-
-
-#if defined(__STDC__)
-static void putdline ( PRINTER * );
-#else
-static void putdline();
-#endif
-
-/**
- ** do_device()
- **/
-
-void
-#if defined(__STDC__)
-do_device (
- char ** list
-)
-#else
-do_device (list)
- char **list;
-#endif
-{
- register PRINTER *pp;
-
-
- while (*list) {
- if (STREQU(NAME_ALL, *list))
- while ((pp = getprinter(NAME_ALL)))
- putdline (pp);
-
- else if ((pp = getprinter(*list)))
- putdline (pp);
-
- else {
- LP_ERRMSG1 (ERROR, E_LP_NOPRINTER, *list);
- exit_rc = 1;
- }
-
- list++;
- }
- return;
-}
-
-/**
- ** putdline()
- **/
-
-static void
-#if defined(__STDC__)
-putdline (
- PRINTER * pp
-)
-#else
-putdline (pp)
- register PRINTER *pp;
-#endif
-{
- if (!pp->device && !pp->dial_info && !pp->remote) {
- LP_ERRMSG1 (ERROR, E_LP_PGONE, pp->name);
-
- } else if (pp->remote) {
- char * cp = strchr(pp->remote, BANG_C);
-
-
- if (cp)
- *cp++ = 0;
- (void)printf (gettext("system for %s: %s"), pp->name, pp->remote);
- if (cp)
- (void)printf (gettext(" (as printer %s)"), cp);
- (void)printf ("\n");
-
- } else if (pp->dial_info) {
- (void)printf (gettext("dial token for %s: %s"), pp->name, pp->dial_info);
- if (pp->device)
- (void)printf (gettext(" (on port %s)"), pp->device);
- (void)printf ("\n");
-
- } else {
- (void)printf (gettext("device for %s: %s"), pp->name, pp->device);
-#if defined(CAN_DO_MODULES)
- if (verbosity & V_MODULES)
- if (
- emptylist(pp->modules)
- || STREQU(NAME_NONE, pp->modules[0])
- )
- (void)printf (gettext(" (no modules)"));
- else if (STREQU(NAME_KEEP, pp->modules[0]))
- (void)printf (gettext(" (keep startup modules)"));
- else if (STREQU(NAME_DEFAULT, pp->modules[0]))
- (void)printf (gettext(" %s (default)"), DEFMODULES);
- else {
- (void)printf (" ");
- printlist_setup ("", 0, ",", "");
- printlist (stdout, pp->modules);
- printlist_unsetup ();
- }
-#endif
- (void)printf ("\n");
- }
-
- return;
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/done.c b/usr/src/cmd/lp/cmd/lpstat/done.c
deleted file mode 100644
index edbaffc42d..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/done.c
+++ /dev/null
@@ -1,50 +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) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.4 */
-
-#include "lpstat.h"
-
-/**
- ** done() - CLEAN UP AND EXIT
- **/
-
-void
-#if defined(__STDC__)
-done (
- int rc
-)
-#else
-done (rc)
- int rc;
-#endif
-{
- (void)mclose ();
-
- if (!rc && exit_rc)
- exit (exit_rc);
- else
- exit (rc);
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/form.c b/usr/src/cmd/lp/cmd/lpstat/form.c
deleted file mode 100644
index 60feda5eb5..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/form.c
+++ /dev/null
@@ -1,188 +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 1993 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */
-
-#include <locale.h>
-#include "stdio.h"
-
-#include "string.h"
-
-#include "lp.h"
-#include "form.h"
-#include "access.h"
-#include "msgs.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-
-static void putfline ( FORM * );
-
-/**
- ** do_form()
- **/
-
-void
-do_form(char **list)
-{
- FORM form;
-
- while (*list) {
- if (STREQU(NAME_ALL, *list))
- while (getform(NAME_ALL, &form, (FALERT *)0, (FILE **)0) != -1)
- putfline (&form);
-
- else if (getform(*list, &form, (FALERT *)0, (FILE **)0) != -1) {
- putfline (&form);
-
- } else {
- LP_ERRMSG1 (ERROR, E_LP_NOFORM, *list);
- exit_rc = 1;
- }
-
- list++;
- }
- printsdn_unsetup ();
- return;
-}
-
-/**
- ** putfline()
- **/
-
-static void
-putfline(FORM *pf)
-{
- register MOUNTED *pm;
-
-
- (void) printf(gettext("form %s"), pf->name);
-
- (void) printf(gettext(" is %s to you"),
- is_user_allowed_form(getname(), pf->name) ?
- gettext( "available") :
- gettext("not available"));
-
- for (pm = mounted_forms; pm->forward; pm = pm->forward)
- if (STREQU(pm->name, pf->name)) {
- if (pm->printers) {
- (void) printf(gettext(", mounted on "));
- printlist_setup (0, 0, ",", "");
- printlist (stdout, pm->printers);
- printlist_unsetup();
- }
- break;
- }
-
- (void) printf("\n");
-
- if (verbosity & V_LONG) {
-
- printsdn_setup (gettext("\tPage length: "), 0, 0);
- printsdn (stdout, pf->plen);
-
- printsdn_setup (gettext("\tPage width: "), 0, 0);
- printsdn (stdout, pf->pwid);
-
- (void) printf(gettext("\tNumber of pages: %d\n"), pf->np);
-
- printsdn_setup (gettext("\tLine pitch: "), 0, 0);
- printsdn (stdout, pf->lpi);
-
- (void) printf(gettext("\tCharacter pitch:"));
- if (pf->cpi.val == N_COMPRESSED)
- (void) printf(" %s\n", NAME_COMPRESSED);
- else {
- printsdn_setup (" ", 0, 0);
- printsdn (stdout, pf->cpi);
- }
-
- (void) printf(gettext("\tCharacter set choice: %s%s\n"),
- (pf->chset? pf->chset : NAME_ANY),
- (pf->mandatory ? ", mandatory" : ""));
-
- (void) printf(gettext("\tRibbon color: %s\n"),
- (pf->rcolor? pf->rcolor : NAME_ANY));
-
- if (pf->paper)
- (void) printf(gettext("\tpaper: %s\n"), pf->paper);
-
- if (pf->comment)
- (void) printf(gettext("\tComment:\n\t%s\n"),
- pf->comment);
- }
- return;
-}
-
-/**
- ** do_paper()
- **/
-
-void
-do_paper(char **list)
-{
- while (*list) {
- if (STREQU(NAME_ALL, *list)) {
- send_message (S_PAPER_ALLOWED, "");
- (void)output(R_PAPER_ALLOWED);
- } else {
- send_message (S_PAPER_ALLOWED, *list);
- switch (output(R_PAPER_ALLOWED)) {
- case MNODEST:
- LP_ERRMSG1 (ERROR, E_LP_NOPRINTER, *list);
- exit_rc = 1;
- break;
- }
- }
-
- list++;
- }
- printsdn_unsetup ();
-}
-
-/**
- ** putppline()
- **/
-
-void
-putppline(char *printer, char *paperAllowed)
-{
- char *ptr;
-
- ptr = paperAllowed;
- while (ptr = strchr(ptr,' ')) {
- *ptr = ',';
- ptr++;
- }
- (void) printf(gettext("paper allowed for printer %s: %s\n"), printer,
- paperAllowed);
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/lpstat.c b/usr/src/cmd/lp/cmd/lpstat/lpstat.c
deleted file mode 100644
index 5a264904cb..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/lpstat.c
+++ /dev/null
@@ -1,244 +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.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include "stdio.h"
-#include "errno.h"
-#include "sys/types.h"
-#include "signal.h"
-#include "stdlib.h"
-
-#include "lp.h"
-#include "msgs.h"
-#include "printers.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-#include <locale.h>
-
-
-#ifdef SIGPOLL
-static void
-#else
-static int
-#endif
-#if defined(__STDC__)
- catch ( int );
-#else
- catch();
-#endif
-
-#if defined(__STDC__)
-static void mallocfail ( void );
-#else
-static void mallocfail ();
-#endif
-
-int exit_rc = 0,
- inquire_type = INQ_UNKNOWN,
- scheduler_active = 0,
- r; /* Says -r was specified */
-
-char *alllist[] = {
- NAME_ALL,
- 0
-};
-
-/**
- ** main()
- **/
-
-int
-#if defined(__STDC__)
-main (
- int argc,
- char * argv[]
-)
-#else
-main (argc, argv)
- int argc;
- char *argv[];
-#endif
-{
- (void) setlocale (LC_ALL, "");
-
-#if !defined(TEXT_DOMAIN)
-#define TEXT_DOMAIN "SYS_TEST"
-#endif
- (void) textdomain(TEXT_DOMAIN);
-
- lp_alloc_fail_handler = mallocfail;
- parse (argc, argv);
- done (0);
- /*NOTREACHED*/
- return (0);
-}
-
-/**
- ** def()
- **/
-
-void
-#if defined(__STDC__)
-def (
- void
-)
-#else
-def ()
-#endif
-{
- char *name;
-
- if ((name = getdefault()))
- (void) printf(gettext("system default destination: %s\n"), name);
- else
- (void) printf(gettext("no system default destination\n"));
-
- return;
-}
-
-/**
- ** running()
- **/
-
-void
-#if defined(__STDC__)
-running (
- void
-)
-#else
-running ()
-#endif
-{
- (void) printf((scheduler_active ? gettext("scheduler is running\n") :
- gettext("scheduler is not running\n")));
- return;
-}
-
-/**
- ** printer_configured()
- **/
-int
-printer_configured(void)
-{
- long lastdir = -1;
- char *name;
- int nameisprinter;
-
- while ((name = next_dir(Lp_A_Printers, &lastdir)) != NULL) {
- nameisprinter = isprinter(name);
- Free(name);
- if (nameisprinter)
- return (1);
- }
- return (0);
-}
-
-/**
- ** startup()
- **/
-
-void
-#if defined(__STDC__)
-startup (
- void
-)
-#else
-startup ()
-#endif
-{
- int try;
-
-
- if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
- (void)signal (SIGHUP, catch);
-
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- (void)signal (SIGINT, catch);
-
- if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- (void)signal (SIGQUIT, catch);
-
- if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
- (void)signal (SIGTERM, catch);
-
- for (try = 1; try <= 5; try++) {
- scheduler_active = (mopen() == 0);
- if (scheduler_active || errno != ENOSPC)
- break;
- sleep (3);
- }
-
- return;
-}
-
-/**
- ** catch()
- **/
-
-#ifdef SIGPOLL
-static void
-#else
-static int
-#endif
-#if defined(__STDC__)
-catch (
- int ignore
-)
-#else
-catch (ignore)
- int ignore;
-#endif
-{
- (void)signal (SIGHUP, SIG_IGN);
- (void)signal (SIGINT, SIG_IGN);
- (void)signal (SIGQUIT, SIG_IGN);
- (void)signal (SIGTERM, SIG_IGN);
- done (2);
-}
-
-/**
- ** mallocfail()
- **/
-
-static void
-#if defined(__STDC__)
-mallocfail (
- void
-)
-#else
-mallocfail ()
-#endif
-{
- LP_ERRMSG (ERROR, E_LP_MALLOC);
- done (1);
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/lpstat.h b/usr/src/cmd/lp/cmd/lpstat/lpstat.h
deleted file mode 100644
index b1d9a6d76f..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/lpstat.h
+++ /dev/null
@@ -1,100 +0,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
- */
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-
-
-#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.7 */
-
-#include <sys/types.h>
-#include <time.h>
-
-#define DESTMAX 14 /* max length of destination name */
-#define SEQLEN 8 /* max length of sequence number */
-#define IDSIZE DESTMAX+SEQLEN+1 /* maximum length of request id */
-#define LOGMAX 15 /* maximum length of logname */
-#define OSIZE 7
-#define SZ_DATE_BUFF 100 /* size of conversion buff for dates */
-
-#define INQ_UNKNOWN -1
-#define INQ_ACCEPT 0
-#define INQ_PRINTER 1
-#define INQ_STORE 2
-#define INQ_USER 3
-
-#define V_LONG 0x0001
-#define V_BITS 0x0002
-#define V_RANK 0x0004
-#define V_MODULES 0x0008
-
-#define BITPRINT(S,B) \
- if ((S)&(B)) { (void)printf("%s%s",sep,#B); sep = "|"; }
-
-typedef struct mounted {
- char *name,
- **printers;
- struct mounted *forward;
-} MOUNTED;
-
-void add_mounted ( char * , char * , char * );
-void def ( void );
-void do_accept ( char ** );
-void do_charset ( char ** );
-void do_class ( char ** );
-void do_device ( char ** );
-void do_form ( char ** );
-void do_paper ( char ** );
-void do_printer ( char ** );
-void do_request ( char ** );
-void do_user ( char ** );
-void done ( int );
-void parse ( int , char ** );
-void putoline(char *, char *, char *, long, time_t, int, char *,
- char *, char *, int);
-void putpline(char *, int, char *, time_t, char *, char *, char *);
-void putqline(char *, int, time_t, char *);
-void putppline ( char * , char *);
-void running ( void );
-void send_message ( int , ... );
-void startup ( void );
-
-int output ( int );
-int printer_configured ( void );
-
-#if defined(_LP_PRINTERS_H)
-char ** get_charsets ( PRINTER * , int );
-#endif
-
-extern int exit_rc;
-extern int inquire_type;
-extern int D;
-extern int remote_cmd;
-extern int scheduler_active;
-
-extern char *alllist[];
-
-extern unsigned int verbosity;
-
-extern MOUNTED *mounted_forms;
-extern MOUNTED *mounted_pwheels;
diff --git a/usr/src/cmd/lp/cmd/lpstat/output.c b/usr/src/cmd/lp/cmd/lpstat/output.c
deleted file mode 100644
index 1cf20519a3..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/output.c
+++ /dev/null
@@ -1,289 +0,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
- */
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include "stdio.h"
-#include "errno.h"
-#include "sys/types.h"
-
-#include "lp.h"
-#include "printers.h"
-#include "class.h"
-#include "msgs.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-
-/*
- * output() - RECEIVE MESSAGE BACK FROM SPOOLER, PRODUCE OUTPUT
- */
-
-int
-output(int type)
-{
- char buffer[MSGMAX];
-
- int rc;
-
- char *class,
- *user,
- *slabel,
- *reject_reason,
- *request_id,
- *printer,
- *paperAllowed,
- *form,
- *file,
- *character_set,
- *disable_reason;
-
- short printer_status,
- class_status,
- state,
- status,
- rank = 0;
-
- long size,
- enable_date,
- reject_date,
- date;
-
-
- if (!scheduler_active) {
- static int complained = 0;
-
- if (!complained) {
- if (printer_configured()) {
- LP_ERRMSG (ERROR, E_LP_NEEDSCHED);
- exit_rc = 1;
- }
- complained = 1;
- }
- return (MOK);
- }
-
- status = MOKMORE;
- while (status == MOKMORE) {
-
- if ((rc = mrecv(buffer, MSGMAX)) != type) {
- if (rc == -1 && errno == EIDRM)
- LP_ERRMSG (ERROR, E_LP_MRECV);
- else
- LP_ERRMSG1 (ERROR, E_LP_BADREPLY, rc);
- done (1);
- }
-
- switch (type) {
-
- case R_PAPER_ALLOWED:
- if (getmessage(
- buffer,
- R_PAPER_ALLOWED,
- &status,
- &printer,
- &paperAllowed
- ) == -1) {
- LP_ERRMSG1 (ERROR, E_LP_GETMSG, PERROR);
- done (1);
- }
-
- switch (status) {
- case MOK:
- case MOKMORE:
- putppline(printer, paperAllowed);
- break;
-
- }
- break;
-
- case R_INQUIRE_REQUEST:
- if (getmessage(
- buffer,
- R_INQUIRE_REQUEST,
- &status,
- &request_id,
- &user,
- &slabel,
- &size,
- &date,
- &state,
- &printer,
- &form,
- &character_set,
- &file) == -1)
- {
- LP_ERRMSG1 (ERROR, E_LP_GETMSG, PERROR);
- done (1);
- }
-
- switch (status) {
-
- case MOK:
- case MOKMORE:
- putoline(request_id, user, slabel, size, date,
- state, printer, form, character_set,
- ++rank);
- break;
-
- }
- break;
-
- case R_INQUIRE_REQUEST_RANK:
- if (getmessage(
- buffer,
- R_INQUIRE_REQUEST_RANK,
- &status,
- &request_id,
- &user,
- &slabel,
- &size,
- &date,
- &state,
- &printer,
- &form,
- &character_set,
- &rank,
- &file) == -1)
- {
- LP_ERRMSG1 (ERROR, E_LP_GETMSG, PERROR);
- done (1);
- }
-
- switch (status) {
-
- case MOK:
- case MOKMORE:
- putoline(request_id, user, slabel, size, date,
- state, printer, form, character_set,
- rank);
- break;
-
- }
- break;
-
- case R_INQUIRE_PRINTER_STATUS:
- if (getmessage(
- buffer,
- R_INQUIRE_PRINTER_STATUS,
- &status,
- &printer,
- &form,
- &character_set,
- &disable_reason,
- &reject_reason,
- &printer_status,
- &request_id,
- &enable_date,
- &reject_date) == -1)
- {
- LP_ERRMSG1 (ERROR, E_LP_GETMSG, PERROR);
- done (1);
- }
-
- switch (status) {
-
- case MOK:
- case MOKMORE:
- switch (inquire_type) {
- case INQ_ACCEPT:
- putqline(printer,
- (printer_status & PS_REJECTED),
- reject_date, reject_reason);
- break;
-
- case INQ_PRINTER:
- putpline(printer, printer_status,
- request_id, enable_date,
- disable_reason, form,
- character_set);
- break;
-
- case INQ_STORE:
- add_mounted (
- printer,
- form,
- character_set);
- break;
-
- }
- break;
-
- }
- break;
-
- case R_INQUIRE_CLASS:
- if (getmessage(
- buffer,
- R_INQUIRE_CLASS,
- &status,
- &class,
- &class_status,
- &reject_reason,
- &reject_date) == -1)
- {
- LP_ERRMSG1 (ERROR, E_LP_GETMSG, PERROR);
- done (1);
- }
-
- switch (status) {
-
- case MOK:
- case MOKMORE:
- switch (inquire_type) {
- case INQ_ACCEPT:
- putqline(class,
- (class_status & CS_REJECTED),
- reject_date, reject_reason);
- break;
- }
- break;
-
- }
- break;
- }
- }
-
- switch (status) {
-
- case MOK:
- case MNOINFO:
- case MNODEST:
- case MUNKNOWN:
- return (status);
-
- default: /* we are lost */
- LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status);
- done(1);
-
- }
- /*NOTREACHED*/
- return (0);
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/parse.c b/usr/src/cmd/lp/cmd/lpstat/parse.c
deleted file mode 100644
index c408d844a9..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/parse.c
+++ /dev/null
@@ -1,379 +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.
- */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include "string.h"
-#include "sys/types.h"
-#include "stdlib.h"
-
-#include "lp.h"
-#include "printers.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-#include <locale.h>
-
-typedef struct execute {
- char *list;
- void (*func)();
- int inquire_type;
- struct execute *forward;
-} EXECUTE;
-
-static int r = 0;
-int D = 0,
- remote_cmd = 0;
-
-unsigned int verbosity = 0;
-
-extern char *optarg;
-
-extern int getopt(),
- optind,
- opterr,
- optopt;
-
-
-static void usage ( void );
-
-#if defined(CAN_DO_MODULES)
-#define OPT_LIST "a:c:do:p:rstu:v:f:TDS:lLRHP:"
-#else
-#define OPT_LIST "a:c:do:p:rstu:v:f:TDS:lLRP:"
-#endif
-
-#define QUEUE(LIST, FUNC, TYPE) \
- { \
- next->list = LIST; \
- next->func = FUNC; \
- next->inquire_type = TYPE; \
- next->forward = (EXECUTE *)Malloc(sizeof(EXECUTE)); \
- (next = next->forward)->forward = 0; \
- }
-
-/**
- ** parse() - PARSE COMMAND LINE OPTIONS
- **/
-
-/*
- * This routine parses the command line, builds a linked list of
- * function calls desired, then executes them in the order they
- * were received. This is necessary as we must apply -l to all
- * options. So, we could either stash the calls away, or go
- * through parsing twice. I chose to build the linked list.
- */
-
-void
-parse(int argc, char **argv)
-{
- int optsw;
- int ac;
- int need_mount = 0;
-
- char ** av;
- char * p;
- char ** list;
-
- EXECUTE linked_list;
-
- register EXECUTE * next = &linked_list;
-
-
- next->forward = 0;
-
- /*
- * Add a fake value to the end of the "argv" list, to
- * catch the case that a valued-option comes last.
- */
- av = (char **)Malloc((argc + 2) * sizeof(char *));
- for (ac = 0; ac < argc; ac++)
- av[ac] = argv[ac];
- av[ac++] = "--";
-
- opterr = 0;
-
- while ((optsw = getopt(ac, (char * const *)av, OPT_LIST)) != -1) {
-
- switch(optsw) {
-
- /*
- * These option letters MAY take a value. Check the value;
- * if it begins with a '-', assume it's really the next
- * argument.
- */
- case 'a':
- case 'c':
- case 'o':
- case 'p':
- case 'u':
- case 'v':
- case 'f':
- case 'P':
- case 'S':
- if (*optarg == '-') {
- /*
- * This will work if we were given
- *
- * -x -foo
- *
- * but would fail if we were given
- *
- * -x-foo
- */
- optind--;
- optarg = NAME_ALL;
- }
- break;
- }
-
- switch(optsw) {
- case 'a': /* acceptance status */
- QUEUE (optarg, do_accept, INQ_ACCEPT);
- break;
-
- case 'c': /* class to printer mapping */
- QUEUE (optarg, do_class, 0);
- break;
-
- case 'd': /* default destination */
- QUEUE (0, def, 0);
- break;
-
- case 'D': /* Description of printers */
- D = 1;
- break;
-
- case 'f': /* do forms */
- QUEUE (optarg, do_form, 0);
- need_mount = 1;
- break;
-
- case 'P': /* do forms */
- QUEUE (optarg, do_paper, 0);
- break;
-
-#if defined(CAN_DO_MODULES)
- case 'H': /* show modules pushed for printer */
- verbosity |= V_MODULES;
- break;
-#endif
-
- case 'l': /* verbose output */
- verbosity |= V_LONG;
- verbosity &= ~V_BITS;
- break;
-
- case 'L': /* Local only */
- remote_cmd = 0;
- break;
-
- case 'o': /* output for destinations */
- QUEUE (optarg, do_request, 0);
- break;
-
- case 'p': /* printer status */
- QUEUE (optarg, do_printer, INQ_PRINTER);
- break;
-
- case 'R': /* show rank in queue */
- verbosity |= V_RANK;
- break;
-
- case 'r': /* is scheduler running? */
- QUEUE (0, running, 0);
- r = 1;
- break;
-
- case 's': /* configuration summary */
- QUEUE (0, running, 0);
- QUEUE (0, def, 0);
- QUEUE (NAME_ALL, do_class, 0);
- QUEUE (NAME_ALL, do_device, 0);
- QUEUE (NAME_ALL, do_form, 0);
- QUEUE (NAME_ALL, do_charset, 0);
- r = 1;
- need_mount = 1;
- break;
-
- case 'S': /* character set info */
- QUEUE (optarg, do_charset, 0);
- need_mount = 1;
- break;
-
- case 't': /* print all info */
- QUEUE (0, running, 0);
- QUEUE (0, def, 0);
- QUEUE (NAME_ALL, do_class, 0);
- QUEUE (NAME_ALL, do_device, 0);
- QUEUE (NAME_ALL, do_accept, INQ_ACCEPT);
- QUEUE (NAME_ALL, do_printer, INQ_PRINTER);
- QUEUE (NAME_ALL, do_form, 0);
- QUEUE (NAME_ALL, do_charset, 0);
- QUEUE (NAME_ALL, do_request, 0);
- r = 1;
- need_mount = 1;
- break;
-
- case 'T': /* (trace) special debugging output */
- verbosity |= V_BITS;
- verbosity &= ~V_LONG;
- break;
-
- case 'u': /* output by user */
- QUEUE (optarg, do_user, INQ_USER);
- break;
-
- case 'v': /* printers to devices mapping */
- QUEUE (optarg, do_device, 0);
- break;
-
- default:
- if (optopt == '?') {
- usage ();
- done (0);
- }
-
- (p = "-X")[1] = optopt;
-
- if (strchr(OPT_LIST, optopt))
- LP_ERRMSG1 (ERROR, E_LP_OPTARG, p);
- else
- LP_ERRMSG1 (ERROR, E_LP_USAGE, p);
- done(1);
- break;
- }
-
- }
-
-#ifdef NEVER
- if (getenv("LPSTAT_NO_REMOTE"))
- remote_cmd = 0;
-#endif /* NEVER */
-
- /*
- * Note: "argc" here, not "ac", to skip our fake option.
- * We could use either "argv" or "av", since for the range
- * of interest they're the same.
- */
-
- list = 0;
- while (optind < argc)
- if (addlist(&list, av[optind++]) == -1) {
- LP_ERRMSG (ERROR, E_LP_MALLOC);
- done(1);
- }
- if (list)
- QUEUE (sprintlist(list), do_request, 0);
-
- if (argc == 1 || (verbosity & V_RANK) && argc == 2)
- QUEUE (getname(), do_user, INQ_USER);
-
- startup ();
-
- /*
- Linked list is completed, load up mount info if
- needed then do the requests
- */
-
- if (need_mount) {
- inquire_type = INQ_STORE;
- do_printer (alllist);
- }
-
- for (next = &linked_list; next->forward; next = next->forward) {
- inquire_type = next->inquire_type;
- if (!next->list)
- (*next->func) ();
- else if (!*next->list)
- (*next->func) (alllist);
- else
- (*next->func) (getlist(next->list, LP_WS, LP_SEP));
- }
-
- return;
-}
-
-/**
- ** usage() - PRINT USAGE MESSAGE
- **/
-
-static void
-usage(void)
-{
-
-#if defined(CAN_DO_MODULES)
-
- (void) printf (gettext(
-"usage:\n"
-" lpstat [options] [request-ids]\n"
-" [-a printers,classes] (show acceptance status)\n"
-" [-c classes] (show available classes)\n"
-" [-d] (show default destination)\n"
-" [-D] (-p only: describe printers)\n"
-" [-f forms] (show available forms)\n"
-" [-l] (be verbose)\n"
-" [-o printers,classes,req-ids] (show status of requests)\n"
-" [-p printers] (show available printers)\n"
-" [-P] (show paper types)\n"
-" [-R] (show rank in queue)\n"
-" [-r] (show status of Spooler)\n"
-" [-s] (show summary status)\n"
-" [-S char-sets,print-wheels] (show available \"fonts\")\n"
-" [-t] (show status of everything)\n"
-" [-u users] (show status of user requests)\n"
-" [-v printers [-H]] (show devices used by printers)\n"
-" (\"all\" allowed with -a,-c,-f,-o,-p,-S,-u,-v options)\n"));
-#else
-
- (void) printf (gettext(
-"usage:\n"
-" lpstat [options] [request-ids]\n"
-" [-a printers,classes] (show acceptance status)\n"
-" [-c classes] (show available classes)\n"
-" [-d] (show default destination)\n"
-" [-D] (-p only: describe printers)\n"
-" [-f forms] (show available forms)\n"
-" [-l] (be verbose)\n"
-" [-o printers,classes,req-ids] (show status of requests)\n"
-" [-p printers] (show available printers)\n"
-" [-P] (show paper types)\n"
-" [-R] (show rank in queue)\n"
-" [-r] (show status of Spooler)\n"
-" [-s] (show summary status)\n"
-" [-S char-sets,print-wheels] (show available \"fonts\")\n"
-" [-t] (show status of everything)\n"
-" [-u users] (show status of user requests)\n"
-" [-v printers] (show devices used by printers)\n"
-" (\"all\" allowed with -a,-c,-f,-o,-p,-S,-u,-v options)\n"));
-#endif
- return;
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/printer.c b/usr/src/cmd/lp/cmd/lpstat/printer.c
deleted file mode 100644
index 5e83017193..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/printer.c
+++ /dev/null
@@ -1,555 +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) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <locale.h>
-#include "stdio.h"
-#include "string.h"
-#include "errno.h"
-#include "sys/types.h"
-#include "stdlib.h"
-
-#include "lp.h"
-#include "printers.h"
-#include "msgs.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-
-static void figure_pitch_size(char *, SCALED *, SCALED *, SCALED *,
- SCALED *);
-static void printallowdeny(FILE *, int, char **, char **);
-static void printpwheels(PRINTER *, char *);
-static void printsets(PRINTER *);
-static int put_flt(char *printer, char *flt);
-
-#define USERS_AD 0
-#define FORMS_AD 1
-
-/*
- * do_printer()
- */
-
-void
-do_printer(char **list)
-{
- while (*list) {
- if (STREQU(*list, NAME_ALL)) {
- send_message(S_INQUIRE_PRINTER_STATUS, "");
- (void) output(R_INQUIRE_PRINTER_STATUS);
-
- } else {
- send_message(S_INQUIRE_PRINTER_STATUS, *list);
- switch (output(R_INQUIRE_PRINTER_STATUS)) {
- case MNODEST:
- LP_ERRMSG1(ERROR, E_LP_NOPRINTER, *list);
- exit_rc = 1;
- break;
- }
- }
- list++;
- }
-}
-
-/*
- * putpline() - DISPLAY STATUS OF PRINTER
- */
-
-void
-putpline(char *printer, int printer_status, char *request_id,
- time_t date, char *disable_reason, char *form,
- char *character_set)
-{
- register PRINTER *prbufp;
- char **u_allow = 0,
- **u_deny = 0,
- **f_allow = 0,
- **f_deny = 0,
- **pt;
- char enable_date[SZ_DATE_BUFF];
- int multi_type;
-
- if (!(prbufp = getprinter(printer))) {
- LP_ERRMSG2(ERROR, E_LP_GETPRINTER, printer, PERROR);
- done(1);
- }
-
- (void) strftime(enable_date, sizeof (enable_date), NULL,
- localtime(&date));
-
- /*
- * if (prbufp->login)
- * printf(gettext(" (login terminal)"));
- */
-
- if (!(printer_status & (PS_DISABLED|PS_LATER))) {
- if (printer_status & PS_FAULTED) {
- if (printer_status & PS_BUSY)
- printf(gettext(
- "printer %s faulted printing %s."),
- printer, request_id);
- else
- printf(gettext("printer %s faulted."),
- printer);
- } else if (printer_status & PS_BUSY)
- printf(gettext("printer %s now printing %s."),
- printer, request_id);
- else
- printf(gettext("printer %s is idle."), printer);
-
- printf(gettext(" enabled since %s."), enable_date);
-
- } else if (printer_status & PS_DISABLED)
- printf(gettext("printer %s disabled since %s."),
- printer, enable_date);
-
- else if (printer_status & PS_LATER)
- printf(gettext("printer %s waiting for auto-retry."), printer);
-
- (void) load_userprinter_access(printer, &u_allow, &u_deny);
- printf(is_user_allowed(getname(), u_allow, u_deny) ?
- gettext(" available.\n") : gettext(" not available.\n"));
-
- if (printer_status & (PS_FAULTED | PS_DISABLED|PS_LATER)) {
- if (strncmp("Warning: ", disable_reason, 9) == 0) {
- if (! put_flt(printer, disable_reason))
- printf("\t%s\n", gettext(disable_reason));
- }
- else
- printf("\t%s\n", gettext(disable_reason));
- }
-
- if (D && !(verbosity & (V_LONG|V_BITS)))
- printf(gettext("\tDescription: %s\n"),
- NB(prbufp->description));
-
- else if (verbosity & V_BITS) {
- register char *sep = " ";
-
- BITPRINT(printer_status, PS_REJECTED);
- BITPRINT(printer_status, PS_DISABLED);
- BITPRINT(printer_status, PS_FAULTED);
- BITPRINT(printer_status, PS_BUSY);
- BITPRINT(printer_status, PS_LATER);
- BITPRINT(printer_status, PS_REMOTE);
- if (sep[0] == '|')
- printf("\n");
-
- } else if (verbosity & V_LONG) {
- char *ptrForm, *ptrEndForm;
- int trayNum;
-
- if (form && (ptrEndForm = strchr(form, *LP_SEP))) {
- if (*(ptrEndForm+1)) {
- printf(gettext("\tForms mounted:\n"));
- ptrForm = form;
- trayNum = 1;
- while (ptrEndForm) {
- *ptrEndForm = 0;
- printf(gettext("\ttray %d: %s\n"),
- trayNum++, ptrForm);
- ptrForm = ptrEndForm+1;
- ptrEndForm = strchr(ptrForm, *LP_SEP);
- }
- } else {
- *ptrEndForm = 0;
- printf(gettext("\tForm mounted: %s\n"),
- NB(form));
- }
- } else if (!prbufp->remote)
- printf(gettext("\tForm mounted: %s\n"), NB(form));
-
- printf(gettext("\tContent types:"));
- if (prbufp->input_types) {
- printlist_setup(" ", 0, ",", "");
- printlist(stdout, prbufp->input_types);
- printlist_unsetup();
- }
- printf("\n");
-
- printf(gettext("\tPrinter types:"));
- if (prbufp->printer_types) {
- printlist_setup(" ", 0, ",", "");
- printlist(stdout, prbufp->printer_types);
- printlist_unsetup();
- } else
- printf(gettext(" (unknown)"));
- printf("\n");
-
- printf(gettext("\tDescription: %s\n"), NB(prbufp->description));
-
- if (!prbufp->remote)
- printf(gettext("\tConnection: %s\n"),
- (prbufp->dial_info ? prbufp->dial_info :
- gettext(NAME_DIRECT)));
-
- if (!prbufp->remote)
- printf(gettext("\tInterface: %s\n"),
- NB(prbufp->interface));
-
- if (!prbufp->remote) {
- if (prbufp->ppd != NULL) {
- printf(gettext("\tPPD: %s\n"), NB(prbufp->ppd));
- } else {
- printf(gettext("\tPPD: %s\n"), "none");
- }
- }
-
- if (!prbufp->remote) {
- if (is_user_admin()) {
- printf("\t");
- printalert(stdout, &(prbufp->fault_alert), 1);
- }
- printf(gettext("\tAfter fault: %s\n"),
- (prbufp->fault_rec ? prbufp->fault_rec :
- gettext(NAME_CONTINUE)));
- }
-
- (void) load_formprinter_access(printer, &f_allow, &f_deny);
- printallowdeny(stdout, USERS_AD, u_allow, u_deny);
- printallowdeny(stdout, FORMS_AD, f_allow, f_deny);
-
- switch (prbufp->banner) {
- case BAN_ALWAYS:
- printf(gettext("\tBanner required\n"));
- break;
- case BAN_OPTIONAL:
- printf(gettext("\tBanner not required\n"));
- break;
- case BAN_NEVER:
- printf(gettext("\tBanner page never printed\n"));
- break;
- }
-
- if (prbufp->daisy) {
- printf(gettext("\tPrint wheels:\n"));
- printpwheels(prbufp, character_set);
- } else {
- printf(gettext("\tCharacter sets:\n"));
- printsets(prbufp);
- }
-
- multi_type = (lenlist(prbufp->printer_types) > 1);
- for (pt = prbufp->printer_types; *pt; pt++) {
-
- SCALED cpi;
- SCALED lpi;
- SCALED pwid;
- SCALED plen;
-
- cpi = prbufp->cpi;
- lpi = prbufp->lpi;
- pwid = prbufp->pwid;
- plen = prbufp->plen;
-
- figure_pitch_size (*pt, &cpi, &lpi, &pwid, &plen);
-
- if (multi_type)
- printf(gettext("\tDefault pitch(%s):"), *pt);
- else
- printf(gettext("\tDefault pitch:"));
-
- if (cpi.val == N_COMPRESSED)
- printf(" %s CPI", NAME_COMPRESSED);
- else {
- printsdn_setup(" ", gettext(" CPI"), "");
- printsdn(stdout, cpi);
- }
- printsdn_setup(" ", gettext(" LPI"), "");
- printsdn(stdout, lpi);
- printf("\n");
-
- if (multi_type)
- printf(gettext("\tDefault page size(%s):"),
- *pt);
- else
- printf(gettext("\tDefault page size:"));
-
- printsdn_setup(" ", gettext(" wide"), "");
- printsdn(stdout, pwid);
- printsdn_setup(" ", gettext(" long"), "");
- printsdn(stdout, plen);
- printf("\n");
-
- printsdn_unsetup();
- }
-
- if (!prbufp->remote)
- printf(gettext("\tDefault port settings: %s "),
- NB(prbufp->stty));
- if (!prbufp->remote) {
- if (prbufp->speed && prbufp->dial_info)
- if (!STREQU(prbufp->dial_info, NAME_DIRECT))
- printf("%s", NB(prbufp->speed));
- printf("\n");
- }
-
- if (!prbufp->remote) {
- if (prbufp->options) {
- printf(gettext("\tOptions:"));
- printlist_setup(" ", 0, ",", "");
- printlist(stdout, prbufp->options);
- printlist_unsetup();
- printf("\n");
- }
- }
-
- printf("\n");
- }
-}
-
-/*
- * figure_pitch_size() - CALCULATE *REAL* DEFAULT PITCH, PAGE SIZE
- */
-
-static void
-figure_pitch_size(char *type, SCALED *cpi, SCALED *lpi, SCALED *pwid,
- SCALED *plen)
-{
- short orc,
- orhi,
- orl,
- orvi,
- cols,
- lines;
-
- /*
- * The user want's to know how the page will look if
- * he or she uses this printer. Thus, if the administrator
- * hasn't set any defaults, figure out what they are from
- * the Terminfo entry.
- */
- if (!type || STREQU(type, NAME_UNKNOWN))
- return;
-
- /*
- * NOTE: We should never get a failure return unless
- * someone has trashed the printer configuration file.
- * Also, if we don't fail the first time, we can't fail
- * subsequently.
- */
- if (tidbit(type, "orc", &orc) == -1)
- return;
- (void) tidbit(type, "orhi", &orhi);
- (void) tidbit(type, "orl", &orl);
- (void) tidbit(type, "orvi", &orvi);
- (void) tidbit(type, "cols", &cols);
- (void) tidbit(type, "lines", &lines);
-
-#define COMPUTE(ORI, OR) \
- (ORI != -1 && OR != -1? (int)((ORI / (double)OR) + .5) : 0)
-
- if (cpi->val <= 0) {
- cpi->val = (float)COMPUTE(orhi, orc);
- cpi->sc = 0;
- }
- if (lpi->val <= 0) {
- lpi->val = (float)COMPUTE(orvi, orl);
- lpi->sc = 0;
- }
- if (pwid->val <= 0) {
- pwid->val = (float)cols;
- pwid->sc = 0;
- }
- if (plen->val <= 0) {
- plen->val = (float)lines;
- plen->sc = 0;
- }
-
-}
-
-/*
- * printallowdeny() - PRINT ALLOW/DENY LIST NICELY
- */
-
-static void
-printallowdeny(FILE *fp, int type, char **allow, char **deny)
-{
-
- printlist_setup("\t\t", 0, 0, 0);
-
- if (allow || deny && !*deny || !deny) {
- if (type == USERS_AD)
- (void) fprintf(fp, gettext("\tUsers allowed:\n"));
- else
- (void) fprintf(fp, gettext("\tForms allowed:\n"));
- if (allow && *allow)
- printlist(fp, allow);
- else if (allow && !*allow || !deny)
- (void) fprintf(fp, gettext("\t\t(none)\n"));
- else
- (void) fprintf(fp, gettext("\t\t(all)\n"));
-
- } else {
- if (type == USERS_AD)
- (void) fprintf(fp, gettext("\tUsers denied:\n"));
- else
- (void) fprintf(fp, gettext("\tForms denied:\n"));
- printlist(fp, deny);
-
- }
-
- printlist_unsetup();
-}
-
-/*
- * printpwheels() - PRINT LIST OF PRINT WHEELS
- */
-
-static void
-printpwheels(PRINTER *prbufp, char *pwheel)
-{
- register char **list;
-
- register int mount_in_list = 0,
- something_shown = 0;
-
-
- if ((list = prbufp->char_sets))
- while (*list) {
- printf("\t\t%s", *list);
- if (pwheel && STREQU(*list, pwheel)) {
- printf(gettext(" (mounted)"));
- mount_in_list = 1;
- }
- printf("\n");
- list++;
- something_shown = 1;
- }
-
- if (!mount_in_list && pwheel && *pwheel) {
- printf(gettext("\t\t%s (mounted)\n"), pwheel);
- something_shown = 1;
- }
-
- if (!something_shown)
- printf(gettext("\t\t(none)\n"));
-}
-
-/*
- * printsets() - PRINT LIST OF CHARACTER SETS, WITH MAPPING
- */
-
-static void
-printsets(PRINTER *prbufp)
-{
- register char **alist = prbufp->char_sets,
- *cp;
-
- char **tlist = 0;
-
-
- /*
- * We'll report the administrator defined character set aliases
- * and any OTHER character sets we find in the Terminfo database.
- */
- tlist = get_charsets(prbufp, 0);
-
- if ((!alist || !*alist) && (!tlist || !*tlist)) {
- printf(gettext("\t\t(none)\n"));
- return;
- }
-
- if (alist)
- while (*alist) {
- cp = strchr(*alist, '=');
- if (cp)
- *cp++ = 0;
-
- /*
- * Remove the alias from the Terminfo list so
- * we don't report it twice.
- */
- if (dellist(&tlist, *alist) == -1) {
- LP_ERRMSG(ERROR, E_LP_MALLOC);
- done(1);
- }
-
- if (cp)
- printf("\t\t%s (as %s)\n", cp, *alist);
- else
- printf("\t\t%s\n", *alist);
-
- alist++;
- }
-
- if (tlist)
- while (*tlist)
- printf("\t\t%s\n", *tlist++);
-
-}
-
-/*
- * if the msg is in the format:
- * Warning: <printer> is down: <reason>\n
- * break it up and reprint it out so we can do it in the users language.
- */
-static int
-put_flt(char *printer, char *flt)
-{
- char *dup, *p;
-
- if ((dup = strdup(flt)) == NULL)
- return (0);
-
- if (strtok(dup + 9, " ") == NULL) { /* start after "Warning: " */
- free(dup);
- return (0);
- }
-
- p = strtok(NULL, " ");
- if (p == NULL || strcmp(p, "is") != 0) {
- free(dup);
- return (0);
- }
-
- p = strtok(NULL, " ");
- if (p == NULL || strcmp(p, "down:") != 0) {
- free(dup);
- return (0);
- }
-
- p += 6;
- if (*p == NULL) {
- free(dup);
- return (0);
- }
-
- if (*(p + (strlen(p) - 1)) == '\n')
- *(p + (strlen(p) - 1)) = 0;
- putchar('\t');
- printf(gettext("Warning: %s is down: %s\n"), printer, gettext(p));
-
- free(dup);
- return (1);
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/request.c b/usr/src/cmd/lp/cmd/lpstat/request.c
deleted file mode 100644
index 6ced71d4e1..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/request.c
+++ /dev/null
@@ -1,346 +0,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
- */
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <locale.h>
-#include "stdio.h"
-#include "pwd.h"
-#include "sys/types.h"
-
-#include "lp.h"
-#include "strings.h"
-#include "msgs.h"
-#include "requests.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-
-
-/*
- * do_request()
- */
-
-void
-do_request(char **list)
-{
- while (*list) {
- if (STREQU(NAME_ALL, *list)) {
- if (remote_cmd || verbosity & V_RANK) {
- send_message(S_INQUIRE_REQUEST_RANK,
- (remote_cmd ? 2 : 1),
- "", "", "", "", "");
- (void) output (R_INQUIRE_REQUEST_RANK);
- } else {
- send_message (S_INQUIRE_REQUEST,
- "", "", "", "", "");
- (void) output (R_INQUIRE_REQUEST);
- }
-
- } else if (isrequest(*list)) {
- if (remote_cmd || verbosity & V_RANK) {
- send_message (S_INQUIRE_REQUEST_RANK,
- (remote_cmd ? 2 : 1),
- "", "", *list, "", "");
- switch (output(R_INQUIRE_REQUEST_RANK)) {
- case MNOINFO:
- LP_ERRMSG1 (ERROR,
- E_STAT_DONE, *list);
- exit_rc = 1;
- break;
- }
- } else {
- send_message (S_INQUIRE_REQUEST,
- "", "", *list, "", "");
- switch (output(R_INQUIRE_REQUEST)) {
- case MNOINFO:
- LP_ERRMSG1 (ERROR,
- E_STAT_DONE, *list);
- exit_rc = 1;
- break;
- }
- }
-
- } else {
- if (remote_cmd || verbosity & V_RANK) {
- send_message(S_INQUIRE_REQUEST_RANK,
- (remote_cmd ? 2 : 1),
- "", *list, "", "", "");
- switch (output(R_INQUIRE_REQUEST_RANK)) {
- case MNOINFO:
- if (!isprinter(*list) &&
- !isclass(*list)) {
- LP_ERRMSG1 (ERROR,
- E_STAT_BADSTAT, *list);
- exit_rc = 1;
- }
- break;
- }
- } else {
- send_message (S_INQUIRE_REQUEST,
- "", *list, "", "", "");
- switch (output(R_INQUIRE_REQUEST)) {
- case MNOINFO:
- if (!isprinter(*list) &&
- !isclass(*list)) {
- LP_ERRMSG1 (ERROR,
- E_STAT_BADSTAT, *list);
- exit_rc = 1;
- }
- break;
- }
- }
-
- }
- list++;
- }
- return;
-}
-
-/*
- * do_user()
- */
-
-static char *user_name = NULL;
-
-void
-do_user(char **list)
-{
- user_name = NULL;
-
- while (*list) {
- if (STREQU(NAME_ALL, *list)) {
- if (remote_cmd || verbosity & V_RANK) {
- send_message (S_INQUIRE_REQUEST_RANK,
- (remote_cmd ? 2 : 1),
- "", "", "", "", "");
- (void) output (R_INQUIRE_REQUEST_RANK);
- } else {
- send_message (S_INQUIRE_REQUEST,
- "", "", "", "", "");
- (void) output (R_INQUIRE_REQUEST);
- }
- } else {
- user_name = *list;
- if (remote_cmd || verbosity & V_RANK) {
- send_message (S_INQUIRE_REQUEST_RANK,
- (remote_cmd ? 2 : 1),
- "", "", "", *list, "");
- switch (output(R_INQUIRE_REQUEST_RANK)) {
- case MNOINFO:
- if (!getpwnam(*list))
- LP_ERRMSG1 (WARNING,
- E_STAT_USER, *list);
- break;
- }
- } else {
- send_message (S_INQUIRE_REQUEST,
- "", "", "", *list, "");
- switch (output(R_INQUIRE_REQUEST)) {
- case MNOINFO:
- if (!getpwnam(*list))
- LP_ERRMSG1 (WARNING,
- E_STAT_USER, *list);
- break;
- }
- }
- }
- list++;
- }
- user_name = NULL;
-}
-
-
-/*
- * putoline()
- */
-
-void
-putoline(char *request_id, char *user, char *slabel, long size, time_t clock,
- int state, char *printer, char *form, char *character_set, int rank)
-{
- int showRank;
- char user_buf[LOGMAX];
- char date[SZ_DATE_BUFF];
-
- if ((slabel != NULL) && (slabel[0] != '\0'))
- snprintf(user_buf, sizeof (user_buf), "%s:%s", user, slabel);
- else
- snprintf(user_buf, sizeof (user_buf), "%s", user);
-
- /*
- * This is the basic time format used in the output. It represents
- * all times of the form "Dec 11 11:04" seen in the output.
- */
- (void) strftime(date, sizeof (date), "%b %d %R", localtime(&clock));
- if (user_name)
- if (!strchr(user_name, '!')) {
- char buf[512];
-
- snprintf(buf, sizeof (buf), "all!%s", user_name);
- if (!bangequ(buf, user))
- return;
- }
- else if (!bangequ(user_name, user))
- return;
-
-
- showRank = (verbosity & V_RANK);
- if (showRank)
- (void) printf("%3d ", rank);
-
- (void) printf(
- "%-*s %-*s %*ld %s%s",
- ((showRank) ? IDSIZE - 2 : IDSIZE),
- request_id,
- LOGMAX-1,
- user_buf,
- OSIZE,
- size,
- ((showRank) ? "" : " "),
- date);
-
- if (!(verbosity & (V_LONG|V_BITS))) {
-
- /*
- * Unless the -l option is given, we show the CURRENT
- * status. Check the status bits in reverse order of
- * chronology, i.e. go with the bit that would have been
- * set last. Old bits don't get cleared by the Spooler.
- * We only have space for 21 characters!
- */
-
- if (state & RS_NOTIFYING)
- (void) printf(gettext(" notifying user"));
-
- else if (state & RS_CANCELLED)
- (void) printf(gettext(" canceled"));
-
- else if (state & RS_PRINTED)
- (void) printf(gettext(" finished printing"));
-
- else if (state & RS_PRINTING)
- (void) printf(gettext(" on %s"), printer);
-
- else if (state & RS_ADMINHELD)
- (void) printf(gettext(" held by admin"));
-
- else if (state & RS_HELD)
- (void) printf(gettext(" being held"));
-
- else if (state & RS_FILTERED)
- (void) printf(gettext(" filtered"));
-
- else if (state & RS_FILTERING)
- (void) printf(gettext(" being filtered"));
-
- else if (state & RS_CHANGING)
- (void) printf(gettext(" held for change"));
-
- } else if (verbosity & V_BITS) {
- register char *sep = "\n ";
-
- BITPRINT (state, RS_HELD);
- BITPRINT (state, RS_FILTERING);
- BITPRINT (state, RS_FILTERED);
- BITPRINT (state, RS_PRINTING);
- BITPRINT (state, RS_PRINTED);
- BITPRINT (state, RS_CHANGING);
- BITPRINT (state, RS_CANCELLED);
- BITPRINT (state, RS_IMMEDIATE);
- BITPRINT (state, RS_FAILED);
- BITPRINT (state, RS_SENDING);
- BITPRINT (state, RS_NOTIFY);
- BITPRINT (state, RS_NOTIFYING);
- BITPRINT (state, RS_SENT);
- BITPRINT (state, RS_ADMINHELD);
- BITPRINT (state, RS_REFILTER);
- BITPRINT (state, RS_STOPPED);
-
- } else if (verbosity & V_LONG) {
- /*
- * Here we show all the interesting states the job
- * has gone through. Left to right they are in
- * chronological order.
- */
-
- if (state & RS_PRINTING) {
- (void) printf(gettext("\n\ton %s"), printer);
- } else if (state & RS_CANCELLED) {
- (void) printf(gettext("\n\tcanceled"));
- } else if (state & RS_FAILED) {
- (void) printf(gettext("\n\tfailed"));
- } else if (state & RS_PRINTED) {
- (void) printf(gettext("\n\tfinished on %s"), printer);
- /*
- * WATCH IT! We make the request ID unusable after
- * the next line.
- */
- } else if (!STREQU(strtok(request_id, "-"), printer)) {
- (void) printf(gettext("\n\tassigned %s"), printer);
- } else {
- if (state & RS_SENT)
- (void)printf (
- gettext("\n\tqueued remotely for %s"),
- printer);
- else
- (void)printf (gettext("\n\tqueued for %s"),
- printer);
- }
-
- if (!(state & RS_DONE)) {
- if (form && *form) {
- (void) printf(gettext(", form %s"), form);
- }
- if (character_set && *character_set) {
- (void) printf(gettext(", charset %s"),
- character_set);
- }
- }
-
- if (state & RS_NOTIFYING) {
- (void) printf(gettext(", notifying user"));
- } else if (state & RS_CHANGING) {
- (void) printf(gettext(", held for change"));
- } else if (state & RS_ADMINHELD) {
- (void) printf(gettext(", held by admin"));
- } else if (state & RS_HELD) {
- (void) printf(gettext(", being held"));
- }
-
- if (state & RS_FILTERED) {
- (void) printf(gettext(", filtered"));
- } else if (state & RS_FILTERING) {
- (void) printf(gettext(", being filtered"));
- }
- }
- (void) printf("\n");
- return;
-}
diff --git a/usr/src/cmd/lp/cmd/lpstat/send_message.c b/usr/src/cmd/lp/cmd/lpstat/send_message.c
deleted file mode 100644
index e241825717..0000000000
--- a/usr/src/cmd/lp/cmd/lpstat/send_message.c
+++ /dev/null
@@ -1,87 +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) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-
-#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.5 */
-
-#include "stdio.h"
-
-#if defined(__STDC__)
-#include "stdarg.h"
-#else
-#include "varargs.h"
-#endif
-
-#include "msgs.h"
-
-#define WHO_AM_I I_AM_LPSTAT
-#include "oam.h"
-
-#include "lpstat.h"
-
-
-/**
- ** send_message() - HANDLE MESSAGE SENDING TO SPOOLER
- **/
-
-/*VARARGS1*/
-void
-#if defined(__STDC__)
-send_message (
- int type,
- ...
-)
-#else
-send_message (type, va_alist)
- int type;
- va_dcl
-#endif
-{
- va_list ap;
-
- int n;
-
- char msgbuf[MSGMAX];
-
-
- if (!scheduler_active)
- return;
-
-#if defined(__STDC__)
- va_start (ap, type);
-#else
- va_start (ap);
-#endif
-
- (void)_putmessage (msgbuf, type, ap);
-
- va_end (ap);
-
- if (msend(msgbuf) == -1) {
- LP_ERRMSG (ERROR, E_LP_MSEND);
- done(1);
- }
-
- return;
-}
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/cancel/Makefile b/usr/src/cmd/print/cancel/Makefile
deleted file mode 100644
index f7d257fd90..0000000000
--- a/usr/src/cmd/print/cancel/Makefile
+++ /dev/null
@@ -1,86 +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
-#
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
-# cmd/lp/client/cancel/Makefile
-#
-
-include ../Makefile.sp
-
-PROG= cancel
-
-SRCS= cancel.c cancel_list.c
-
-OBJS= $(SRCS:.c=.o)
-
-ROOTBINPROG= $(PROG:%=$(ROOTBIN)/%)
-ROOTUSRBINSYMLINK= $(ROOTBIN)/lprm
-ROOTUSRUCBSYMLINK= $(ROOTUSRUCB)/lprm
-
-FILEMODE= 04511
-OWNER= root
-
-CPPFLAGS += -I. -I$(NPRTINC) #$(CPPFLAGS.master)
-LDLIBS += $(LIBNPRT)
-
-.KEEP_STATE:
-
-all: $(PROG)
-
-$(PROG): $(OBJS)
- $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-install: all $(ROOTBIN) $(ROOTBINPROG) $(ROOTUSRBINSYMLINK) \
- $(ROOTUSRUCBSYMLINK)
-
-$(ROOTBIN):
- $(INS.dir)
-
-$(ROOTUSRBINSYMLINK):
- $(RM) $@; $(SYMLINK) $(PROG) $@
-
-$(ROOTUSRUCBSYMLINK):
- $(RM) $@; $(SYMLINK) ../bin/lprm $@
-
-strip:
- $(STRIP) $(PROG)
-
-lint:
- $(LINT.c) $(SRCS) $(LDLIBS)
-
-cstyle:
- cstyle $(SRCS)
-
-_msg:
- @echo "Messages are made in usr/src/cmd/print"
-
-clean:
- $(RM) $(OBJS)
-
-clobber: clean
- -$(RM) $(PROG) $(CLOBBERFILES)
-
diff --git a/usr/src/cmd/print/cancel/cancel.c b/usr/src/cmd/print/cancel/cancel.c
deleted file mode 100644
index acfc529344..0000000000
--- a/usr/src/cmd/print/cancel/cancel.c
+++ /dev/null
@@ -1,378 +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 <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <syslog.h>
-#include <ctype.h>
-#include <locale.h>
-#ifndef SUNOS_4
-#include <libintl.h>
-#endif
-
-#include <print/ns.h>
-#include <print/network.h>
-#include <print/misc.h>
-#include <print/list.h>
-#include <print/job.h>
-
-#include <cancel_list.h>
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-int exit_code = 0;
-extern char *getenv(const char *);
-
-static int all = 0; /* global for canceling everything */
-
-
-
-static char *
-vappend_list(void **list)
-{
- int current = 0;
- char *string;
- int stringlen;
- int listlen;
- int strsize = BUFSIZ;
-
-
- string = malloc(strsize);
- (void) memset(string, NULL, sizeof (string));
-
- if (list != NULL) {
- while (list[current] != NULL) {
- stringlen = strlen(string);
- listlen = strlen(list[current]);
- if (strsize < (stringlen + listlen + 2)) {
- strsize = stringlen + listlen + 2;
- string = realloc(string, strsize);
- }
-
- (void) strcat(string, " ");
- (void) strcat(string, list[current]);
- current++;
- }
- }
-
- return (string);
-}
-
-
-/*
- * vcancel_local() attempts to cancel all locally spooled jobs that are
- * are associated with a cancel_req_t structure. This function is
- * intended to be called by list_iterate().
- */
-static int
-vcancel_local(cancel_req_t *entry, va_list ap)
-{
- char *user = va_arg(ap, char *);
- job_t **list = NULL;
-
- list = job_list_append(list, entry->binding->printer,
- entry->binding->server, SPOOL_DIR);
- return (list_iterate((void **)list, (VFUNC_T)vjob_cancel, user,
- entry->binding->printer, entry->binding->server,
- entry->list));
-}
-
-
-/*
- * vcancel_remote() attempts to send a cancel request to a print server
- * for any jobs that might be associated with the cancel_req_t structure
- * passed in. This function is intended to be called by list_iterate().
- */
-static int
-vcancel_remote(cancel_req_t *entry, va_list ap)
-{
- char buf[BUFSIZ],
- *user = va_arg(ap, char *),
- *printer = entry->binding->printer,
- *server = entry->binding->server;
- int nd,
- rc;
- char *string;
-
- if ((nd = net_open(server, 15)) < 0) {
- (void) fprintf(stderr,
- gettext("could not talk to print service at %s\n"),
- server);
- return (-1);
- }
-
- (void) memset(buf, NULL, sizeof (buf));
-
- if (strcmp(user, "-all") != 0)
- string = vappend_list((void *)entry->list);
-
- syslog(LOG_DEBUG, "vcancel_remote(): %s %s%s", printer, user, string);
- rc = net_printf(nd, "%c%s %s%s\n", REMOVE_REQUEST, printer, user,
- string);
- if (rc < 0)
- syslog(LOG_ERR, "net_printf() failed: %m");
-
- while (memset(buf, NULL, sizeof (buf)) &&
- (net_read(nd, buf, sizeof (buf)) > 0))
- (void) printf("%s", buf);
-
- (void) net_close(nd);
- return (0);
-}
-
-
-/*
- * vsysv_printer() adds an entry to the cancel list with the items supplied.
- */
-static void
-vsysv_printer(char *printer, va_list ap)
-{
- cancel_req_t ***list = va_arg(ap, cancel_req_t ***);
- char **items = va_arg(ap, char **);
-
- *list = cancel_list_add_list(*list, printer, items);
-}
-
-/*
- * vsysv_binding() adds an entry to the cancel list with the items supplied.
- */
-static void
-vsysv_binding(ns_bsd_addr_t *binding, va_list ap)
-{
- cancel_req_t ***list = va_arg(ap, cancel_req_t ***);
- char **items = va_arg(ap, char **);
-
- *list = cancel_list_add_binding_list(*list, binding, items);
-}
-
-/*
- * sysv_remove() parses the command line arguments as defined for cancel
- * and builds a list of cancel_req_t structures to return
- */
-static cancel_req_t **
-sysv_remove(int ac, char **av)
-{
- char *printer,
- **printers = NULL,
- **items = NULL;
- int c;
- int user = 0;
- cancel_req_t **list = NULL;
-
- if (ac == 1) {
- (void) fprintf(stderr,
- gettext("printer, request-id, and/or user required\n"));
- exit(-1);
- }
-
- if ((printer = getenv((const char *)"LPDEST")) == NULL)
- printer = getenv((const char *)"PRINTER");
- if (printer == NULL)
- printer = NS_NAME_DEFAULT;
-
- while ((c = getopt(ac, av, "u")) != EOF)
- switch (c) {
- case 'u':
- user++;
- break;
- default:
- (void) fprintf(stderr,
- "Usage:\t%s [-u user-list] [printer-list]\n", av[0]);
- (void) fprintf(stderr,
- "\t%s [request-list] [printer-list]\n", av[0]);
- exit(-1);
- }
-
- ac--;
- while (optind <= ac) { /* pull printers off */
- char *p,
- *q;
-
- if (((p = strrchr(av[ac], ':')) != NULL) &&
- ((q = strrchr(p, '-')) != NULL)) {
- int req = 0;
- while (*++q != NULL)
- if (isdigit(*q) == 0)
- req++;
- if (req == 0)
- break;
- }
- if ((ns_bsd_addr_get_name(av[ac])) != NULL) {
- printers = (char **)list_append((void **)printers,
- (void *)av[ac]);
- } else
- break;
- ac--;
- }
-
- while (optind <= ac) { /* get reqs or users */
- if (user != 0) { /* list o users */
- items = (char **)list_append((void **)items,
- (void *)av[ac]);
- } else { /* list o jobs */
- char *p;
-
- if ((p = strrchr(av[ac], '-')) != NULL) { /* job-id */
- *(p++) = NULL;
- if (*p == NULL) {
- (void) fprintf(stderr,
- gettext("invalid job id: %s-\n"),
- av[ac]);
- exit(-1);
- }
- list = cancel_list_add_item(list, av[ac], p);
- } else { /* just a number */
- list = cancel_list_add_item(list, av[ac], NULL);
- }
- }
- ac--;
- }
-
- if ((printers == NULL) && (items != NULL)) { /* handle "all" printers */
- ns_bsd_addr_t **addrs = NULL;
-
- if ((addrs = ns_bsd_addr_get_all(UNIQUE)) != NULL)
- (void) list_iterate((void **)addrs,
- (VFUNC_T)vsysv_binding, &list, items);
- }
-
- if ((list == NULL) && (items == NULL))
- items = (char **)list_append((void **)items, NULL);
-
- (void) list_iterate((void **)printers, (VFUNC_T)vsysv_printer,
- &list, items);
-
- return (list);
-}
-
-
-/*
- * bsd_remove() parses the command line arguments as defined for lprm
- * and builds a list of cancel_req_t structures to return
- */
-static cancel_req_t **
-bsd_remove(int ac, char **av)
-{
- char *printer;
- int c;
- cancel_req_t **list = NULL;
-
- if ((printer = getenv((const char *)"PRINTER")) == NULL)
- printer = getenv((const char *)"LPDEST");
- if (printer == NULL)
- printer = NS_NAME_DEFAULT;
-
- while ((c = getopt(ac, av, "P:-")) != EOF)
- switch (c) {
- case 'P':
- printer = optarg;
- break;
- default:
- (void) fprintf(stderr, gettext(
- "Usage: %s [-P printer] [-] [job # ...] [username ...]\n"),
- av[0]);
- exit(-1);
- }
-
- while (optind < ac)
- if (strcmp(av[optind++], "-") == 0) {
- if (getuid() == 0) {
- all = 1;
- list = cancel_list_add_item(list, printer,
- "-all");
- } else {
- list = cancel_list_add_item(list, printer,
- get_user_name());
- }
- } else {
- list = cancel_list_add_item(list, printer,
- av[optind-1]);
- }
-
- if (list == NULL)
- list = cancel_list_add_item(list, printer, NULL);
-
- return (list);
-}
-
-
-/*
- * main() calls the appropriate routine to parse the command line arguments
- * and then calls the local remove routine, followed by the remote remove
- * routine to remove jobs.
- */
-int
-main(int ac, char *av[])
-{
- int rc = 0;
- char *program;
- cancel_req_t **list = NULL;
-
- (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);
-
- 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, "lprm") == 0)
- list = bsd_remove(ac, av);
- else
- list = sysv_remove(ac, av);
-
- (void) chdir(SPOOL_DIR);
- if (list_iterate((void **)list, (VFUNC_T)vcancel_local,
- get_user_name()) != 0)
- start_daemon(1);
-
- rc = list_iterate((void **)list, (VFUNC_T)vcancel_remote,
- ((all == 0) ? get_user_name() : "-all"));
-
- if (exit_code == 0)
- exit_code = rc;
-
- return (exit_code);
-}
diff --git a/usr/src/cmd/print/cancel/cancel_list.c b/usr/src/cmd/print/cancel/cancel_list.c
deleted file mode 100644
index d9ad68ebab..0000000000
--- a/usr/src/cmd/print/cancel/cancel_list.c
+++ /dev/null
@@ -1,185 +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 1998-2002 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 <stdarg.h>
-#include <string.h>
-#include <syslog.h>
-#ifndef SUNOS_4
-#include <libintl.h>
-#endif
-
-#include <print/ns.h>
-#include <print/network.h>
-#include <print/misc.h>
-#include <print/list.h>
-#include <print/job.h>
-
-#include <cancel_list.h>
-
-
-/*
- * printer_compair() compares the printer name in the cancel request and the
- * printer name passed in. If they match, 0 is returned.
- */
-static int
-printer_compair(cancel_req_t *cancel, char *printer)
-{
- return (strcmp(cancel->printer, printer));
-}
-
-/*
- * binding_compair() compares the binding in the cancel request and the
- * binding passed in. If they match, 0 is returned.
- */
-static int
-binding_compair(cancel_req_t *cancel, ns_bsd_addr_t *binding)
-{
- return (strcmp(cancel->binding->printer, binding->printer) ||
- strcmp(cancel->binding->server, binding->server));
-}
-
-
-/*
- * cancel_list_element() adds information to the cancel list. It either adds
- * information to an existing cancel entry if the printers match, or
- * adds a new entry to the cancel list. It returns the new list in either
- * case.
- */
-static cancel_req_t *
-cancel_list_element(cancel_req_t ***list, char *printer)
-{
- cancel_req_t *element = NULL;
-
- if ((element = (cancel_req_t *)list_locate((void **)*list,
- (COMP_T)printer_compair, (void *)printer)) == NULL) {
- if ((element = calloc(1, sizeof (*element))) != NULL) {
- if ((element->binding = ns_bsd_addr_get_name(printer))
- == NULL) {
- extern int exit_code;
-
- free(element);
- if (strcmp(printer, NS_NAME_DEFAULT) == 0)
- (void) fprintf(stderr, gettext(
- "No default destination\n"));
- else
- (void) fprintf(stderr, gettext(
- "%s: unknown printer\n"),
- printer);
- exit_code = -1;
- return (NULL);
- }
- element->printer = strdup(printer);
- *list = (cancel_req_t **)list_append((void **)*list,
- (void *)element);
- }
- }
-
- return (element);
-}
-
-
-/*
- * cancel_list_element_by_binding() returns an element in the cancel list
- * passed in that matches the binding passed in. If none exists, then
- * one is created, inserted and returned.
- */
-static cancel_req_t *
-cancel_list_element_by_binding(cancel_req_t ***list, ns_bsd_addr_t *binding)
-{
- cancel_req_t *element = NULL;
-
- if ((element = (cancel_req_t *)list_locate((void **)*list,
- (COMP_T)binding_compair, (void *)binding)) == NULL) {
- if ((element = calloc(1, sizeof (*element))) != NULL) {
- element->printer = strdup(binding->printer);
- element->binding = binding;
- *list = (cancel_req_t **)list_append((void **)*list,
- (void *)element);
- }
- }
-
- return (element);
-}
-
-
-/*
- * cancel_list_add_item() adds information to the cancel list. It either adds
- * information to an existing cancel entry if the printers match, or
- * adds a new entry to the cancel list. It returns the new list in either
- * case.
- */
-cancel_req_t **
-cancel_list_add_item(cancel_req_t **list, char *printer, char *item)
-{
- cancel_req_t *element = NULL;
-
- if ((element = cancel_list_element(&list, printer)) != NULL)
- element->list = (char **)list_append((void **)element->list,
- (void *)item);
- return (list);
-}
-
-
-/*
- * cancel_list_add_list() adds information to the cancel list. It either adds
- * information to an existing cancel entry if the printers match, or
- * adds a new entry to the cancel list. It returns the new list in either
- * case.
- */
-cancel_req_t **
-cancel_list_add_list(cancel_req_t **list, char *printer, char **items)
-{
- cancel_req_t *element = NULL;
-
- if ((element = cancel_list_element(&list, printer)) != NULL)
- element->list = (char **)list_concatenate(
- (void **)element->list, (void **)items);
- return (list);
-}
-
-
-/*
- * cancel_list_add_binding_list() adds information to the cancel list. It
- * either adds information to an existing cancel entry if the bindings
- * match, or adds a new entry to the cancel list. It returns the new
- * list in either case.
- */
-cancel_req_t **
-cancel_list_add_binding_list(cancel_req_t **list, ns_bsd_addr_t *binding,
- char **items)
-{
- cancel_req_t *element = NULL;
-
- if ((element = cancel_list_element_by_binding(&list, binding)) != NULL)
- element->list = (char **)list_concatenate(
- (void **)element->list, (void **)items);
- return (list);
-}
diff --git a/usr/src/cmd/print/cancel/cancel_list.h b/usr/src/cmd/print/cancel/cancel_list.h
deleted file mode 100644
index d535e0f3ff..0000000000
--- a/usr/src/cmd/print/cancel/cancel_list.h
+++ /dev/null
@@ -1,54 +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 _CANCEL_LIST_H
-#define _CANCEL_LIST_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _cancel_req cancel_req_t;
-struct _cancel_req {
- char *printer;
- ns_bsd_addr_t *binding;
- char **list;
-};
-
-extern cancel_req_t ** cancel_list_add_item(cancel_req_t **list, char *printer,
- char *item);
-extern cancel_req_t ** cancel_list_add_list(cancel_req_t **list, char *printer,
- char **items);
-extern cancel_req_t ** cancel_list_add_binding_list(cancel_req_t **list,
- ns_bsd_addr_t *binding, char **items);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CANCEL_LIST_H */
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/Makefile b/usr/src/cmd/print/lp/Makefile
deleted file mode 100644
index 3e813bb0a2..0000000000
--- a/usr/src/cmd/print/lp/Makefile
+++ /dev/null
@@ -1,97 +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.
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# cmd/lp/client/lp/Makefile
-#
-
-include ../Makefile.sp
-
-PROG= lp
-
-MANIFEST= cleanup.xml
-
-SRCS= $(PROG).c
-
-ROOTMANIFESTDIR= $(ROOTSVCAPPLICATIONPRINT)
-ROOTMETHOD= $(ROOTLIBSVCMETHOD)/print-cleanup
-$(ROOTMANIFEST) := FILEMODE= 444
-
-OBJS= $(SRCS:.c=.o)
-
-ROOTBINPROG= $(PROG:%=$(ROOTBIN)/%)
-ROOTUSRBINSYMLINK= $(ROOTBIN)/lpr
-ROOTUSRUCBSYMLINK= $(ROOTUSRUCB)/lpr
-PRINTSYMLINK= $(ROOTLIB)/print/printd
-$(ROOTLIB)/print := OWNER=root
-$(ROOTLIB)/print := GROUP=lp
-$(ROOTLIBSVCMETHOD)/print-cleanup := FILEMODE=555
-
-FILEMODE= 04511
-OWNER= root
-
-CPPFLAGS += -I$(NPRTINC)
-LDLIBS += $(LIBNPRT)
-
-.KEEP_STATE:
-
-all: $(PROG)
-
-install: all $(ROOTBIN) $(ROOTLIB)/print $(ROOTBINPROG) \
- $(ROOTUSRBINSYMLINK) $(ROOTUSRUCBSYMLINK) $(PRINTSYMLINK) \
- $(ROOTMANIFEST) $(ROOTMETHOD)
-
-check: $(CHKMANIFEST)
-
-$(ROOTBIN) $(ROOTLIB)/print:
- $(INS.dir)
-
-$(ROOTUSRBINSYMLINK):
- $(RM) $@; $(SYMLINK) $(PROG) $@
-
-$(ROOTUSRUCBSYMLINK):
- $(RM) $@; $(SYMLINK) ../bin/lpr $@
-
-$(PRINTSYMLINK):
- $(RM) $@; $(SYMLINK) ../../bin/$(PROG) $@
-
-strip:
- $(STRIP) $(PROG)
-
-lint:
- $(LINT.c) $(PROG).c $(LDLIBS)
-
-cstyle:
- cstyle $(SRCS)
-
-_msg:
- @echo "Messages are made in usr/src/cmd/print"
-
-clean:
- $(RM) $(OBJS)
-
-clobber: clean
- -$(RM) $(PROG) $(CLOBBERFILES)
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/lpmove/Makefile b/usr/src/cmd/print/lpmove/Makefile
deleted file mode 100644
index 7892c91c36..0000000000
--- a/usr/src/cmd/print/lpmove/Makefile
+++ /dev/null
@@ -1,77 +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) 1994, 1995, 1996 by Sun Microsystems, Inc.
-# All Rights Reserved
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# cmd/lp/client/lpmove/Makefile
-#
-
-include ../Makefile.sp
-
-PROG= lpmove
-
-SRCS= $(PROG).c
-
-OBJS= $(SRCS:.c=.o)
-
-ROOTUSRSBINPROG= $(PROG:%=$(ROOTUSRSBIN)/%)
-ROOTUSRLIBSYMLINK= $(PROG:%=$(ROOTLIB)/%)
-
-FILEMODE= 04511
-OWNER= root
-
-CPPFLAGS += -I$(NPRTINC)
-LDLIBS += $(LIBNPRT)
-
-.KEEP_STATE:
-
-all: $(PROG)
-
-install: all $(ROOTUSRSBIN) $(ROOTUSRSBINPROG) $(ROOTUSRLIBSYMLINK)
-
-
-$(ROOTUSRSBIN):
- $(INS.dir)
-
-$(ROOTUSRLIBSYMLINK):
- $(RM) $@; $(SYMLINK) ../sbin/$(PROG) $@
-
-strip:
- $(STRIP) $(PROG)
-
-lint:
- $(LINT.c) $(PROG).c $(LDLIBS)
-
-cstyle:
- cstyle $(SRCS)
-
-_msg:
- @echo "Messages are made in usr/src/cmd/print"
-
-clean:
- $(RM) $(OBJS)
-
-clobber: clean
- -$(RM) $(PROG) $(CLOBBERFILES)
diff --git a/usr/src/cmd/print/lpmove/lpmove.c b/usr/src/cmd/print/lpmove/lpmove.c
deleted file mode 100644
index e3d32afee2..0000000000
--- a/usr/src/cmd/print/lpmove/lpmove.c
+++ /dev/null
@@ -1,243 +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 <fcntl.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <syslog.h>
-#include <locale.h>
-#ifndef SUNOS_4
-#include <libintl.h>
-#endif
-
-#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 *);
-
-
-/*
- * creates a new job moves/modifies control data and data files.
- * If a job is moved, we should return 1 regardless of whether we
- * killed the daemon or not. This will allow us to attempt to start
- * the transfer agent for any jobs in /var/spool/print.
- */
-static int
-vjob_reset_destination(job_t *job, va_list ap)
-{
- char *user = va_arg(ap, char *),
- buf[BUFSIZ];
- int id = va_arg(ap, int),
- lock;
- ns_bsd_addr_t *src = va_arg(ap, ns_bsd_addr_t *),
- *dst = va_arg(ap, ns_bsd_addr_t *);
-
-
- if ((id != -1) && (job->job_id != id))
- return (0);
- if (strcmp(job->job_server, src->server) != 0)
- return (0);
- if ((strcmp(user, "root") != 0) &&
- (strcmp(user, job->job_user) != 0))
- return (0);
-
- while ((lock = get_lock(job->job_cf->jf_src_path, 0)) < 0)
- (void) kill_process(job->job_cf->jf_src_path);
-
- /* just do it */
- (void) snprintf(buf, sizeof (buf), "%s:%s\n", dst->server,
- dst->printer);
- (void) ftruncate(lock, 0);
- (void) write(lock, buf, strlen(buf));
- (void) close(lock);
- (void) printf(gettext("moved: %s-%d to %s-%d\n"), src->printer,
- job->job_id, dst->printer, job->job_id);
- return (1);
-}
-
-
-static int
-job_move(char *user, int id, ns_bsd_addr_t *src_binding,
- ns_bsd_addr_t *dst_binding)
-{
- job_t **list = NULL;
- int rc = 0;
-
- if ((list = job_list_append(NULL, src_binding->printer,
- src_binding->server, SPOOL_DIR)) != NULL)
- rc = list_iterate((void **)list,
- (VFUNC_T)vjob_reset_destination, user, id,
- src_binding, dst_binding);
- return (rc);
-
-}
-
-/*
- * move print jobs from one queue to another. This gets the lock
- * file (killing the locking process if necessary), Moves the jobs, and
- * restarts the transfer daemon.
- */
-
-#define OLD_LPMOVE "/usr/lib/lp/local/lpmove"
-
-int
-main(int ac, char *av[])
-{
- char *program = NULL,
- *dst = NULL,
- *user = get_user_name();
- char **argv = NULL;
- int remote_moved = 0,
- i, argc = 0;
- ns_bsd_addr_t *dst_binding;
-
- (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);
-
- if (access(OLD_LPMOVE, F_OK) == 0) { /* copy args for local move */
- if ((argv = (char **)calloc(ac + 1, sizeof (char *))) == NULL) {
- fprintf(stderr, gettext("lpmove: out of memory\n"));
- exit(1);
- }
-
- if (av[0] != NULL)
- argv[argc++] = strdup(av[0]);
- }
-
- (void) chdir(SPOOL_DIR);
-
- /*
- * Get the destination; use binding to set it; the input may
- * be an alias, not a printer name
- */
- dst = av[--ac];
- if ((dst_binding = ns_bsd_addr_get_name(dst)) == NULL) {
- (void) fprintf(stderr, gettext("%s: unknown printer\n"), dst);
- return (-1);
- }
-
- /*
- * Decrement orig arg count so the following for() loop iterates for
- * each source request or destination. Also, when we later check if
- * there are local jobs to move, we will be comparing number of remote
- * requests moved with the total number supplied.
- */
- ac--;
-
- for (i = 1; i <= ac; i++) {
- ns_bsd_addr_t *src_binding = NULL;
- char *src = av[i], *s, *str;
- int id = -1;
-
- /*
- * if the argument contains a '-', see if it is a request
- * or a printer.
- */
- if ((s = strrchr(src, '-')) != NULL) {
- *(s++) = NULL;
-
- errno = 0;
- id = strtol(s, &str, 10);
- if (((id <= 0) && (errno != 0)) || (*str != NULL)) {
- id = -1;
- *(--s) = '-';
- }
- }
-
- /*
- * get the binding for the printer, so we can use the printer
- * name from the binding to move the job(s)
- */
- if ((src_binding = ns_bsd_addr_get_name(src)) == NULL) {
- (void) fprintf(stderr,
- gettext("%s: unknown printer\n"), src);
- return (-1);
- }
-
- if (job_move(user, id, src_binding, dst_binding) == 0) {
- /*
- * There was nothing "remote" to move, so add it to the
- * list of "local" items to move. Use the printer name
- * from the binding, because that is the one that
- * lpsched is most likely to understand.
- */
- char buf[BUFSIZ];
-
- (void) snprintf(buf, sizeof (buf), "%s%s%s",
- src_binding->printer,
- (id == -1 ? "" : "-"),
- (id == -1 ? "" : s));
- argv[argc++] = strdup(buf);
- } else
- remote_moved++;
- }
-
- /* if we moved a "remote" job(s), try to (re)start the transfer agent */
- if (remote_moved != 0)
- start_daemon(1);
-
- /* if there is something "local" to move, try it */
- if ((argv != NULL) && (remote_moved != ac)) {
- argv[argc++] = strdup(dst_binding->printer);
-
- /* limit ourselves to real user's perms before exec'ing */
- (void) setuid(getuid());
- (void) execv(OLD_LPMOVE, argv);
- }
-
- return (0);
-}
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/lpstat/Makefile b/usr/src/cmd/print/lpstat/Makefile
deleted file mode 100644
index 0e77ee879b..0000000000
--- a/usr/src/cmd/print/lpstat/Makefile
+++ /dev/null
@@ -1,85 +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.
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-# cmd/lp/client/lpstat/Makefile
-#
-
-include ../Makefile.sp
-
-PROG= lpstat
-
-SRCS= lpstat.c sysv-functions.c bsd-functions.c parse_bsd.c
-
-OBJS= $(SRCS:.c=.o)
-
-ROOTBINPROG= $(PROG:%=$(ROOTBIN)/%)
-ROOTUSRBINSYMLINK= $(ROOTBIN)/lpq
-ROOTUSRUCBSYMLINK= $(ROOTUSRUCB)/lpq
-
-FILEMODE= 04511
-OWNER= root
-
-CPPFLAGS += -I. -I$(NPRTINC)
-LDLIBS += $(LIBNPRT)
-
-.KEEP_STATE:
-
-all: $(PROG)
-
-$(PROG): $(OBJS)
- $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-install: all $(ROOTBIN) $(ROOTBINPROG) $(ROOTUSRBINSYMLINK) \
- $(ROOTUSRUCBSYMLINK)
-
-$(ROOTBIN):
- $(INS.dir)
-
-$(ROOTUSRBINSYMLINK):
- $(RM) $@; $(SYMLINK) $(PROG) $@
-
-$(ROOTUSRUCBSYMLINK):
- $(RM) $@; $(SYMLINK) ../bin/lpq $@
-
-strip:
- $(STRIP) $(PROG)
-
-lint:
- $(LINT.c) $(SRCS) $(LDLIBS)
-
-cstyle:
- cstyle $(SRCS)
-
-_msg:
- @echo "Messages are made in usr/src/cmd/print"
-
-clean:
- $(RM) $(OBJS)
-
-clobber: clean
- -$(RM) $(PROG) $(CLOBBERFILES)
diff --git a/usr/src/cmd/print/lpstat/bsd-functions.c b/usr/src/cmd/print/lpstat/bsd-functions.c
deleted file mode 100644
index 8b5b42fe46..0000000000
--- a/usr/src/cmd/print/lpstat/bsd-functions.c
+++ /dev/null
@@ -1,256 +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.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <ctype.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <syslog.h>
-#ifndef SUNOS_4
-#include <libintl.h>
-#endif
-extern char *getenv(const char *);
-
-#include <print/ns.h>
-#include <print/network.h>
-#include <print/misc.h>
-#include <print/list.h>
-#include <print/job.h>
-
-#include "bsd-functions.h"
-
-
-static char *order[] = {
- "", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th" };
-
-static char *
-show_rank(int i)
-{
- static char rank[12];
- if ((i%100)/10 == 1)
- (void) sprintf(rank, "%dth", i);
- else
- (void) sprintf(rank, "%d%s", i, order[i%10]);
- return (rank);
-}
-
-
-static int
-vadd_file(jobfile_t *file, va_list ap)
-{
- char *mesg = va_arg(ap, char *);
-
- if (file != NULL) {
- (void) strlcat(mesg, file->jf_name, BUFSIZ);
- (void) strlcat(mesg, " ", BUFSIZ);
- return (file->jf_size);
- }
- return (0);
-}
-
-/*ARGSUSED*/
-static int
-vprint_file(jobfile_t *file, va_list ap)
-{
- if (file != NULL)
- (void) printf("\t%-33.33s%ld bytes\n", file->jf_name,
- file->jf_size);
- return (0);
-}
-
-static int
-vprint_job(job_t *job, va_list ap)
-{
- int jobSize = 0,
- *rank,
- format,
- curr,
- printIt = 0,
- ac;
- char fileList[BUFSIZ],
- *printer,
- **av;
-
- printer = va_arg(ap, char *);
- format = va_arg(ap, int);
- rank = va_arg(ap, int *);
- ac = va_arg(ap, int);
- av = va_arg(ap, char **);
-
- if (strcmp(job->job_printer, printer) != 0)
- return (0);
-
- if (ac > 0) {
- for (curr = 0; curr < ac; curr++)
- if ((av[curr][0] >= '0') && (av[curr][0] <= '9') &&
- (job->job_id == atoi(av[curr])) ||
- (strcmp(job->job_user, av[curr]) == 0)) {
- printIt++;
- break;
- }
- } else
- printIt++;
-
- if (printIt != 0) {
- if (format == SHOW_QUEUE_SHORT_REQUEST) {
- (void) memset(fileList, 0, sizeof (fileList));
- jobSize = list_iterate((void **)job->job_df_list,
- (VFUNC_T)vadd_file, fileList);
- (void) printf(
- "%-7.7s%-8.8s %3.3d %-38.38s%d bytes\n",
- show_rank((*rank)++), job->job_user,
- job->job_id, fileList, jobSize);
- } else {
- (void) printf("%s: %-7.7s \t\t\t\t [job %.3d%s]\n",
- job->job_user, show_rank((*rank)++),
- job->job_id, job->job_host);
- (void) list_iterate((void **)job->job_df_list,
- (VFUNC_T)vprint_file);
- (void) printf("\n");
- }
- }
- return (0);
-}
-
-static int
-vjob_count(job_t *job, va_list ap)
-{
- int curr,
- ac;
- char *printer,
- **av;
-
- printer = va_arg(ap, char *);
- ac = va_arg(ap, int);
- av = va_arg(ap, char **);
-
- if (strcmp(job->job_printer, printer) != 0)
- return (0);
-
- if (ac == 0)
- return (1);
-
- for (curr = 0; curr < ac; curr++)
- if ((av[curr][0] >= '0') && (av[curr][0] <= '9') &&
- (job->job_id == atoi(av[curr])) ||
- (strcmp(job->job_user, av[curr]) == 0))
- return (1);
-
- return (0);
-}
-
-
-void
-clear_screen() /* for now use tput rather than link in UCB stuff */
-{
- (void) system("/bin/tput clear");
-}
-
-
-int
-bsd_queue(ns_bsd_addr_t *binding, int format, int ac, char *av[])
-{
- char *server = NULL,
- *printer = NULL;
- job_t **list = NULL;
- int nd = -1,
- idle = 0,
- rc;
-
- server = binding->server;
- printer = binding->printer;
-
- if ((nd = net_open(server, 15)) >= 0) {
- char buf[BUFSIZ];
-
- (void) memset(buf, 0, sizeof (buf));
- while (ac--) { /* potential SEGV if av's are more than BUFSIZ */
- (void) strlcat(buf, av[ac], sizeof (buf));
- if (strlcat(buf, " ", sizeof (buf)) >= sizeof (buf)) {
- syslog(LOG_ERR, "bsd_queue: buffer overflow");
- }
- }
-
- rc = net_printf(nd, "%c%s %s\n", format, printer, buf);
- if (rc < 0)
- syslog(LOG_ERR, "net_printf() failed: %m");
-#ifdef SUNOS_4
- do {
- (void) memset(buf, 0, sizeof (buf));
- if ((ac = net_read(nd, buf, sizeof (buf))) > 0)
- (void) printf("%s", buf);
- } while (ac > 0);
-#else
- while (memset(buf, 0, sizeof (buf)) &&
- (net_read(nd, buf, sizeof (buf)) > 0)) {
- (void) printf("%s", buf);
- if (strstr(buf, "no entries") != 0)
- idle = 1;
- }
-#endif
-
- (void) net_close(nd);
- }
-
- if (nd < 0) {
- if (server != NULL)
- (void) fprintf(stderr, gettext(
- "could not talk to print service at %s\n"),
- server);
- else
- (void) fprintf(stderr, gettext(
- "could not locate server for printer: %s\n"),
- printer);
- }
-
- if (((list = job_list_append(NULL, printer,
- server, SPOOL_DIR)) != NULL) &&
- (list_iterate((void **)list, (VFUNC_T)vjob_count, printer,
- ac, av) != 0)) {
- if ((nd < 0) && (format == SHOW_QUEUE_SHORT_REQUEST))
- (void) printf(gettext(
- "Rank\tOwner Job\tFiles\t\t\t\t\tTotal Size\n"));
- }
-
- if (format == SHOW_QUEUE_LONG_REQUEST)
- (void) printf("\n");
-
- nd = 1;
- (void) list_iterate((void **)list, (VFUNC_T)vprint_job, printer, format,
- &nd, ac, av);
-
- if ((idle == 1) && (list == NULL))
- return (1);
- else
- return (0);
-}
diff --git a/usr/src/cmd/print/lpstat/bsd-functions.h b/usr/src/cmd/print/lpstat/bsd-functions.h
deleted file mode 100644
index b12adedc84..0000000000
--- a/usr/src/cmd/print/lpstat/bsd-functions.h
+++ /dev/null
@@ -1,44 +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 _BSD_FUNCTIONS_H
-#define _BSD_FUNCTIONS_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int bsd_queue(ns_bsd_addr_t *binding, int format, int ac, char *av[]);
-extern void clear_screen();
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* _BSD_FUNCTIONS_H */
diff --git a/usr/src/cmd/print/lpstat/lpstat.c b/usr/src/cmd/print/lpstat/lpstat.c
deleted file mode 100644
index 0902aa51fa..0000000000
--- a/usr/src/cmd/print/lpstat/lpstat.c
+++ /dev/null
@@ -1,806 +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 <sys/fcntl.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <syslog.h>
-#include <locale.h>
-#ifndef SUNOS_4
-#include <libintl.h>
-#endif
-#include <sys/systeminfo.h>
-#include <sys/param.h>
-#include <errno.h>
-#include <netdb.h>
-
-#include <print/ns.h>
-#include <print/network.h>
-#include <print/misc.h>
-#include <print/list.h>
-#include <print/job.h>
-
-#include "parse.h"
-#include "sysv-functions.h"
-#include "bsd-functions.h"
-
-extern char *optarg;
-extern int optind, opterr, optopt;
-extern char *getenv(const char *);
-extern char *getname(void);
-
-static int exit_code = 0;
-static int _processing_all = 0;
-
-
-static ns_bsd_addr_t **_printer_bindings = NULL;
-static ns_bsd_addr_t **_printer_bindings_unique = NULL;
-
-
-static int sysvVerbose = 0;
-static int sysvDesc = 0;
-static int sysvLocal = 0;
-
-static int bsdFormat = SHOW_QUEUE_SHORT_REQUEST;
-static int bsdInterval = 0;
-static char **bsdv;
-static int bsdc;
-
-typedef enum _work_type work_type_t;
-typedef struct _work_entry work_entry_t;
-
-enum _work_type { ACCEPTING, DEFAULT, ENTRIES, STATUS, RUNNING, RANK, SUMMARY,
- FULL, USER, DEVICE, FORMS, CLASSES, CHAR_SETS, BSD_QUEUE };
-struct _work_entry {
- ns_bsd_addr_t *binding;
- char *printer;
- char *user;
- int id;
- work_type_t type;
-};
-
-static work_entry_t **workList = NULL;
-
-
-static void
-work_list_append(char *printer, char *user, int id, work_type_t type)
-{
- work_entry_t *tmp = (work_entry_t *)calloc(1, sizeof (work_entry_t));
-
- if (tmp == NULL)
- return;
- if (user != NULL)
- tmp->user = strdup(user);
- tmp->id = id;
- tmp->type = type;
- if (printer != NULL) {
- tmp->printer = strdup(printer);
- if ((tmp->binding = ns_bsd_addr_get_name(printer)) != NULL)
- workList = (work_entry_t **)list_append(
- (void **)workList,
- (void *)tmp);
- else if (strcmp(printer, NS_NAME_DEFAULT) == 0) {
- (void) fprintf(stderr,
- gettext("No default destination\n"));
- exit_code = 1;
- } else {
- (void) fprintf(stderr, gettext("%s: unknown printer\n"),
- printer);
- exit_code = 1;
- }
- } else
- workList = (work_entry_t **)list_append((void **)workList,
- (void *)tmp);
-}
-
-
-static char *
-check_for_req_id(char *name)
-{
- char *p;
- char *p1;
-
- /* request id has the form <name>-<number> */
- p1 = name + strlen(name);
- if (p1 == name)
- return (NULL);
- p = p1 - 1;
- while (p > name && isdigit(*p))
- p--;
- if (*p != '-' || p == name)
- return (NULL);
- else
- return (p);
-}
-
-static void
-work_list_append_list(char *list, work_type_t type)
-{
- char *p;
- char *elem;
-
- if (list == NULL) {
- work_list_append(NULL, NULL, -1, type);
- return;
- }
-
- for (elem = strtok(list, "\t ,"); elem != NULL;
- elem = strtok(NULL, "\t ,")) {
- switch (type) {
- case RANK:
- case ACCEPTING:
- case STATUS:
- case DEVICE:
- work_list_append(elem, NULL, -1, type);
- break;
- case CHAR_SETS:
- case CLASSES:
- case FORMS:
- case USER:
- work_list_append(NULL, elem, -1, type);
- break;
- case ENTRIES:
- if ((p = check_for_req_id(elem)) == NULL)
- work_list_append(elem, NULL, -1, ENTRIES);
- else if (ns_bsd_addr_get_name(elem) != NULL)
- work_list_append(elem, NULL, -1, ENTRIES);
- else {
- *p++ = '\0';
- work_list_append(elem, NULL, atoi(p), ENTRIES);
- }
- break;
- }
- }
-}
-
-static char *
-lpstat_opt(work_type_t type)
-{
- switch (type) {
- case STATUS:
- return ("-p");
- case RANK:
- return ("-R");
- case USER:
- return ("-u");
- case ENTRIES:
- return ("-o");
- default:
- return (NULL);
- }
-}
-
-/*
- * This function is for a performance improvement.
- */
-
-static int
-is_local_printer(char *server, char *printer)
-{
- static char *hostname, hbuf[MAXHOSTNAMELEN];
- char buf[MAXPATHLEN];
-
- if ((server == NULL) || (printer == NULL)) {
- errno = EINVAL;
- return (-1);
- }
-
- if (hostname == NULL) {
- sysinfo(SI_HOSTNAME, hbuf, sizeof (hbuf));
- hostname = hbuf;
- }
-
- if ((strcasecmp(server, hostname) != 0) &&
- (strcasecmp(server, "localhost") != 0))
- return (1);
-
- snprintf(buf, sizeof (buf), "/etc/lp/printers/%s/configuration",
- printer);
- if (access(buf, F_OK) != 0) {
- /* OK its not a local printer but may be a local class */
- snprintf(buf, sizeof (buf), "/etc/lp/classes/%s", printer);
- if (access(buf, F_OK) != 0)
- return (1);
- }
- return (0);
-}
-
-/*
- * Determine if there are any local printers in the list
- */
-static int
-local_printers(ns_bsd_addr_t **printers)
-{
- static int local_printer_found = 0;
- static int already_looked = 0;
-
- if (already_looked == 0) {
- already_looked = 1;
- if ((printers == NULL) || (*printers == NULL)) {
- return (0);
- }
-
- /* Step through list and break out if we find a local printer */
- while (*printers != NULL) {
- if (((*printers)->server == NULL) ||
- ((*printers)->printer == NULL))
- continue;
- if (is_local_printer((*printers)->server,
- (*printers)->printer) == 0)
- break;
- printers++;
- }
-
- if ((printers != NULL) && (*printers != NULL))
- local_printer_found = 1;
- }
-
- return (local_printer_found);
-}
-
-
-/*
- * Determine if local status needs to be run. This is true
- * if there are any local printers in the list with a local
- * printer definition.
- */
-static int
-need_local_status(ns_bsd_addr_t **printers, ns_bsd_addr_t *binding)
-{
-
- return ((local_printers(_printer_bindings) == 1) ||
- ((binding != NULL) &&
- (is_local_printer(binding->server,
- binding->printer) == 0)));
-}
-
-
-static int
-work_execute(work_entry_t *work, int verb)
-{
- char *printer = NULL;
- char *server = NULL;
- print_queue_t *qp;
- int rank = 0;
- int rc = 0;
-
- switch (work->type) {
- case RUNNING:
- sysv_running();
- return (0);
- case DEFAULT:
- sysv_default();
- return (0);
- case FORMS:
- return (sysv_local_status("-f", work->user, verb, 0,
- gettext("form listing not supported on client\n")));
- case CLASSES:
- return (sysv_local_status("-c", work->user, 0, 0,
- gettext("class listing not supported on client\n")));
- case CHAR_SETS:
- return (sysv_local_status("-S", work->user, verb, 0,
- gettext("char set listing not supported on client\n")));
- }
-
- if ((work->binding->printer == NULL) &&
- (work->binding->server == NULL))
- return (0);
-
- /*
- * If the printer is a local LP printer, we can use the local lpstat
- * and it should be faster than going via the network.
- */
- if ((is_local_printer(work->binding->server,
- work->binding->printer) == 0) &&
- ((work->binding->pname == NULL) ||
- (strcmp(work->binding->printer, work->binding->pname) == 0) ||
- (strcmp(work->binding->pname, NS_NAME_DEFAULT) == 0))) {
- char *option = lpstat_opt(work->type);
-
- if (option != NULL) {
- /*
- * If we are processing all printers
- * (ie. -p, -o, -r,
- * -u, -t), simply return, because the local lpstat
- * was already run and all local printers were reported
- * against.
- */
- if (_processing_all != 0)
- return (0);
-
- if (work->printer)
- return (sysv_local_status(option,
- work->printer, verb, sysvDesc,
- gettext("can't execute \n")));
- else if (work->user)
- return (sysv_local_status(option,
- work->user, verb, sysvDesc,
- gettext("can't execute \n")));
- else
- return (sysv_local_status(option,
- "", verb, sysvDesc,
- gettext("can't execute \n")));
- }
- }
-
- if ((printer = strchr(work->binding->printer, '|')) != NULL)
- *printer = NULL;
- printer = work->binding->printer;
- server = work->binding->server;
-
- switch (work->type) {
- case STATUS:
- case RANK:
- case USER:
- case ENTRIES:
- if ((qp = sysv_get_queue(work->binding, sysvLocal)) != NULL) {
- qp->jobs = job_list_append(qp->jobs, printer,
- server, SPOOL_DIR);
- switch (work->type) {
- case STATUS:
- if (work->binding->pname)
- rc += sysv_queue_state(qp,
- work->binding->pname, verb,
- sysvDesc);
- else
- rc += sysv_queue_state(qp, printer,
- verb, sysvDesc);
- break;
- case ENTRIES:
- case USER:
- rank = -1;
- /*FALLTHRU*/
- case RANK:
- if ((work->binding->pname != NULL) &&
- (strcmp(work->binding->pname,
- NS_NAME_DEFAULT) != 0))
- (void) list_iterate((void **)qp->jobs,
- (VFUNC_T)vsysv_queue_entry,
- work->binding->pname, work->user,
- work->id, verb, &rank);
- else
- (void) list_iterate((void **)qp->jobs,
- (VFUNC_T)vsysv_queue_entry, printer,
- work->user, work->id, verb, &rank);
- break;
- }
- if ((qp->state == RAW) && (qp->status != NULL)) {
- (void) printf("%s", qp->status);
- qp->status = NULL;
- }
- }
- break;
- default:
- switch (work->type) {
- case DEVICE:
- rc += sysv_system(work->binding);
- break;
- case ACCEPTING:
- rc += sysv_accept(work->binding);
- break;
- case BSD_QUEUE:
- do {
- int i;
-
- if (bsdInterval != 0)
- clear_screen();
- if (bsd_queue(work->binding, bsdFormat,
- bsdc, bsdv) != 0)
- break;
- if (bsdInterval != 0)
- (void) sleep(bsdInterval);
- } while (bsdInterval != 0);
- break;
- }
- }
-
- return (rc);
-}
-
-
-static int
-vbinding_execute(ns_bsd_addr_t *binding, va_list ap)
-{
- work_entry_t *work = va_arg(ap, work_entry_t *);
- int verbose = va_arg(ap, int);
-
- work->binding = binding;
- return (work_execute(work, verbose));
-}
-
-
-
-
-
-static int
-vwork_list_execute(work_entry_t *work, va_list ap)
-{
- int verbose = va_arg(ap, int);
- work_entry_t tmp;
- int rc = 0;
-
- if ((work->binding == NULL) || ((work->binding->printer == NULL) &&
- (work->binding->server == NULL))) {
- switch (work->type) {
- case RUNNING:
- case DEFAULT:
- case CLASSES:
- case FORMS:
- case CHAR_SETS:
- rc += work_execute(work, verbose);
- break;
- case STATUS:
- case RANK:
- case ENTRIES:
- case ACCEPTING:
- case DEVICE:
- case SUMMARY:
- case USER:
- case FULL:
-
- if (_printer_bindings == NULL) {
- if (sysvLocal == 0) {
- _printer_bindings =
- ns_bsd_addr_get_all(LOCAL_UNIQUE);
- _printer_bindings_unique =
- ns_bsd_addr_get_all(UNIQUE);
- } else {
- _printer_bindings =
- ns_bsd_addr_get_list(LOCAL_UNIQUE);
- _printer_bindings_unique =
- ns_bsd_addr_get_list(UNIQUE);
- }
- }
-
- (void) memcpy(&tmp, work, sizeof (tmp));
-
- if (work->type == FULL || work->type == SUMMARY) {
- tmp.type = RUNNING;
- rc += work_execute(&tmp, verbose);
-
- tmp.type = DEFAULT;
- rc += work_execute(&tmp, verbose);
-
- tmp.type = CLASSES;
- rc += work_execute(&tmp, verbose);
-
- tmp.type = DEVICE;
- rc += list_iterate(
- (void **)_printer_bindings,
- (VFUNC_T)vbinding_execute,
- &tmp, verbose);
-
- tmp.type = CHAR_SETS;
- rc += work_execute(&tmp, verbose);
-
-
- if (work->type == FULL) {
- _processing_all = 1;
- tmp.type = ACCEPTING;
- rc += list_iterate(
- (void **)_printer_bindings,
- (VFUNC_T)vbinding_execute,
- &tmp, verbose);
- if (need_local_status(_printer_bindings,
- work->binding) == 1)
- sysv_local_status("-p", "",
- verbose, sysvDesc,
- gettext(
- "can't execute \n"));
-
- tmp.type = STATUS;
- rc += list_iterate(
- (void **)_printer_bindings,
- (VFUNC_T)vbinding_execute,
- &tmp, verbose);
- if (need_local_status(_printer_bindings,
- work->binding) == 1)
- sysv_local_status("-o", "",
- verbose, sysvDesc,
- gettext(
- "can't execute \n"));
-
- tmp.type = ENTRIES;
- rc += list_iterate(
- (void **)_printer_bindings_unique,
- (VFUNC_T)vbinding_execute,
- &tmp, verbose);
- _processing_all = 0;
- }
-
- /*
- * Put this here to preserve same ordering
- * as found in previous releases.
- */
- if (work->type == FULL ||
- work->type == SUMMARY) {
-
- tmp.type = FORMS;
- rc += work_execute(&tmp, verbose);
- }
-
- } else if ((work->type == ACCEPTING) ||
- (work->type == DEVICE)) {
- tmp.type = work->type;
- rc += list_iterate(
- (void **)_printer_bindings,
- (VFUNC_T)vbinding_execute,
- &tmp, verbose);
-
- } else if (work->type == USER ||
- work->type == STATUS ||
- work->type == ENTRIES ||
- work->type == RANK) {
-
- if (need_local_status(_printer_bindings,
- work->binding) == 1) {
- char *option = lpstat_opt(work->type);
- if ((work->type == USER) &&
- (work->user != NULL)) {
- sysv_local_status(option,
- work->user, verbose,
- sysvDesc,
- gettext(
- "can't execute \n"));
- } else {
- sysv_local_status(option, "",
- verbose, sysvDesc,
- gettext(
- "can't execute \n"));
- }
- }
-
- _processing_all = 1;
- tmp.type = work->type;
- if (work->type == STATUS) {
- rc += list_iterate(
- (void **)_printer_bindings,
- (VFUNC_T)vbinding_execute,
- &tmp, verbose);
- } else {
- rc += list_iterate(
- (void **)_printer_bindings_unique,
- (VFUNC_T)vbinding_execute,
- &tmp, verbose);
- }
- _processing_all = 0;
- } else
- rc += list_iterate(
- (void **)_printer_bindings,
- (VFUNC_T)vbinding_execute, &tmp,
- verbose);
- return (rc);
- default:
- return (rc);
- }
- } else {
- rc += work_execute(work, verbose);
- }
- return (rc);
-}
-
-static void
-sysv_options(int ac, char *av[])
-{
- char **argv,
- *program;
- int c;
- int argc = 0;
- char *user;
-
- if ((program = strrchr(av[0], '/')) == NULL)
- program = av[0];
- else
- program++;
-
- argv = (char **)calloc((ac + 1), sizeof (char *));
-
- if (argv == NULL) {
- fprintf(stderr, gettext("memory allocation failed\n"));
- exit(1);
- }
- for (argc = 0; argc < ac; argc++)
- argv[argc] = av[argc];
- argv[argc++] = "--";
-
- while ((c = getopt(argc, argv, "R:a:c:f:o:p:u:v:DLSdlrst")) != EOF) {
- switch (c) { /* these may or may not have an option */
- case 'R':
- case 'a':
- case 'c':
- case 'f':
- case 'o':
- case 'p':
- case 'u':
- case 'v':
- 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 'D':
- sysvDesc++;
- break;
- case 'L':
- sysvLocal++;
- /* undocumented option that keeps it long and local */
- break;
- case 'R':
- work_list_append_list(optarg, RANK);
- break;
- case 'S':
- work_list_append_list(optarg, CHAR_SETS);
- break;
- case 'a':
- work_list_append_list(optarg, ACCEPTING);
- break;
- case 'c':
- work_list_append_list(optarg, CLASSES);
- break;
- case 'd':
- work_list_append(NULL, NULL, -1, DEFAULT);
- break;
- case 'f':
- work_list_append_list(optarg, FORMS);
- break;
- case 'l':
- sysvVerbose++;
- break;
- case 'o':
- work_list_append_list(optarg, ENTRIES);
- break;
- case 'p':
- work_list_append_list(optarg, STATUS);
- break;
- case 'r':
- work_list_append(NULL, NULL, -1, RUNNING);
- break;
- case 's':
- work_list_append(NULL, NULL, -1, SUMMARY);
- break;
- case 't':
- work_list_append(NULL, NULL, -1, FULL);
- break;
- case 'u':
- work_list_append_list(optarg, USER);
- break;
- case 'v':
- work_list_append_list(optarg, DEVICE);
- break;
- default:
- (void) fprintf(stderr,
- gettext(
- "Usage: %s [-drtslDL] [-R [list]] [-S [list]] "
- "[-a [list]] [-c [list]] [-f [list]] "
- "[-o [list]] [-p [printer]] [-u [list]] "
- "[-v [list]] [list]\n"),
- av[0]);
- exit(1);
- }
- }
- for (argc = optind; argc < ac; argc++) /* add requests */
- work_list_append_list(av[argc], ENTRIES);
-
- if ((workList == NULL) && (ac == 1)) {
- user = get_user_name();
- work_list_append(NULL, user, -1, USER);
- }
-}
-
-
-static void
-bsd_options(int ac, char **av)
-{
- char *printer;
- int c;
-
- if ((bsdv = (char **)calloc(ac, sizeof (char *))) == NULL)
- return;
-
- if ((printer = getenv((const char *)"PRINTER")) == NULL)
- printer = getenv((const char *)"LPDEST");
- if (printer == NULL)
- printer = NS_NAME_DEFAULT;
-
- while ((c = getopt(ac, av, "lP:+:")) != EOF)
- switch (c) {
- case 'l':
- bsdFormat = SHOW_QUEUE_LONG_REQUEST;
- break;
- case 'P':
- printer = optarg;
- break;
- default:
- (void) fprintf(stderr,
- gettext("Usage: %s [-P printer] [-l] [+ interval] [list]\n"),
- av[0]);
- exit(1);
- }
-
- work_list_append(printer, NULL, -1, BSD_QUEUE);
-
- while (optind < ac)
- if (av[optind][0] == '+')
- bsdInterval = atoi(&av[optind++][1]);
- else
- bsdv[bsdc++] = av[optind++];
-}
-
-
-int
-main(int ac, char *av[])
-{
- char *program;
- int rc = 0;
-
- (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);
-
- if (check_client_spool(NULL) < 0) {
- (void) fprintf(stderr, gettext("couldn't validate local spool "
- "area (%s)\n"), SPOOL_DIR);
- return (1);
- }
- (void) chdir(SPOOL_DIR);
-
- if (strcmp(program, "lpq") == 0)
- bsd_options(ac, av);
- else {
- sysv_options(ac, av);
- }
-
- rc = list_iterate((void **)workList, (VFUNC_T)vwork_list_execute,
- sysvVerbose, sysvDesc);
-
- if (exit_code == 0)
- exit_code = rc;
-
- return (exit_code);
-}
diff --git a/usr/src/cmd/print/lpstat/parse.h b/usr/src/cmd/print/lpstat/parse.h
deleted file mode 100644
index fb4abd3d9f..0000000000
--- a/usr/src/cmd/print/lpstat/parse.h
+++ /dev/null
@@ -1,49 +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 _PARSE_H
-#define _PARSE_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _print_queue {
- ns_bsd_addr_t *binding;
- char *status;
- enum { RAW, IDLE, PRINTING, FAULTED, DISABLED } state;
- job_t **jobs;
-} print_queue_t;
-
-extern print_queue_t *parse_bsd_queue(ns_bsd_addr_t *binding, char *data,
- int len);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PARSE_H */
diff --git a/usr/src/cmd/print/lpstat/parse_bsd.c b/usr/src/cmd/print/lpstat/parse_bsd.c
deleted file mode 100644
index 963ea8f048..0000000000
--- a/usr/src/cmd/print/lpstat/parse_bsd.c
+++ /dev/null
@@ -1,171 +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-2001 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdarg.h>
-#include <libintl.h>
-
-#include <print/ns.h>
-#include <print/network.h>
-#include <print/misc.h>
-#include <print/job.h>
-#include <print/list.h>
-
-#include "parse.h"
-
-
-#define MERR_NOMEM "ERROR: no memory\n"
-#define STRNCASECMP(a, b) strncasecmp(a, b, strlen(b))
-
-static job_t *
-parse_bsd_entry(char *data)
-{
- job_t *tmp;
- char *p;
-
- tmp = (job_t *)malloc(sizeof (*tmp));
- if (tmp == NULL) {
- (void) fprintf(stderr, gettext(MERR_NOMEM));
- return (NULL);
- }
- (void) memset(tmp, 0, sizeof (*tmp));
-
- /*
- * 1st line...
- * user: rank [job (ID)(host)]\n
- */
- if ((p = strtok(data, ": ")) == NULL) /* user: ... */
- return (NULL);
- tmp->job_user = strdup(p);
- p = strtok(NULL, "\t "); /* ...rank... */
- p = strtok(NULL, " "); /* ...[job ... */
- if ((p = strtok(NULL, "]\n")) == NULL) /* ... (id)(hostname)] */
- return (NULL);
- while (isspace(*p)) p++;
- tmp->job_id = atoi(p);
- while (isdigit(*(++p)));
- while (isspace(*p)) p++;
- tmp->job_host = strdup(p);
-
- /*
- * rest o lines
- * file size bytes\n
- */
- do {
- jobfile_t *file;
-
- p = strtok(NULL, "\t ");
- p = strtok(NULL, "\t "); /* file Name */
- if (p != NULL) {
- file = (jobfile_t *)malloc(sizeof (*file));
- if (file == NULL) {
- (void) fprintf(stderr, gettext(MERR_NOMEM));
- return (NULL);
- }
- file->jf_name = strdup(p);
- if ((p = strtok(NULL, "\t ")) != NULL)
- if ((file->jf_size = atoi(p)) == 0)
- while ((p = strtok(NULL, "\t "))
- != NULL)
- if (isdigit(p[0])) {
- file->jf_size = atoi(p);
- break;
- }
- tmp->job_df_list = (jobfile_t **)list_append((void **)
- tmp->job_df_list,
- (void *)file);
- }
- } while (p != NULL);
- return (tmp);
-}
-
-
-/*ARGSUSED*/
-print_queue_t *
-parse_bsd_queue(ns_bsd_addr_t *binding, char *data, int len)
-{
- char *p;
- print_queue_t *tmp;
-
- tmp = (print_queue_t *)malloc(sizeof (*tmp));
- if (tmp == NULL) {
- (void) fprintf(stderr, gettext(MERR_NOMEM));
- return (NULL);
- }
- (void) memset(tmp, 0, sizeof (*tmp));
- tmp->state = RAW;
- tmp->status = data;
- tmp->binding = binding;
-
- if (data == NULL)
- return (tmp);
-
- if ((p = strstr(data, "\n\n")) == NULL) {
- if (strstr(data, "no entries") != NULL)
- tmp->state = IDLE;
- return (tmp);
- }
-
- *(p++) = NULL;
- tmp->status = strdup(data);
- data = ++p;
-
- tmp->state = FAULTED; /* Error */
- if (STRNCASECMP(tmp->status, "no entries") == 0)
- tmp->state = IDLE;
- else if (STRNCASECMP((tmp->status + strlen(tmp->status)
- - strlen("ready and printing")),
- "ready and printing") == 0)
- tmp->state = PRINTING;
-
- do { /* parse jobs */
- job_t *job;
- char *q = data;
-
- if ((p = strstr(data, "\n\n")) != NULL) {
- *(++p) = NULL;
- data = ++p;
- }
- if ((job = parse_bsd_entry(q)) == NULL)
- break;
-
- job->job_server = strdup(binding->server);
- job->job_printer = strdup(binding->printer);
- tmp->jobs = (job_t **)list_append((void **)tmp->jobs,
- (void *)job);
- } while (p != NULL);
-
- return (tmp);
-}
diff --git a/usr/src/cmd/print/lpstat/sysv-functions.c b/usr/src/cmd/print/lpstat/sysv-functions.c
deleted file mode 100644
index 35520fddd3..0000000000
--- a/usr/src/cmd/print/lpstat/sysv-functions.c
+++ /dev/null
@@ -1,619 +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-2001 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/fcntl.h>
-#include <sys/wait.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <errno.h>
-#include <unistd.h>
-#include <syslog.h>
-#ifndef SUNOS_4
-#include <libintl.h>
-#endif
-
-#include <print/ns.h>
-#include <print/list.h>
-#include <print/misc.h>
-#include <print/job.h>
-#include <print/network.h>
-
-#include "parse.h"
-#include "sysv-functions.h"
-
-extern char *getenv(const char *);
-
-static print_queue_t **_queue_list = NULL;
-
-static int sysv_displayLocalLPSTAT(char *pname, char *aname);
-
-#define ALL "all"
-static int
-compair_user(char *full, char *user, char *host)
-{
- char *u1,
- *h1;
-
- if (full == NULL)
- return (0);
-
- if ((strcmp(full, ALL) == 0) || strcmp(full, user) == 0)
- return (0);
- if ((u1 = strchr(full, '!')) == NULL)
- return (-1);
- h1 = strcdup(full, '!');
- u1++;
- if (((strcmp(u1, ALL) == 0) || (strcmp(u1, user) == 0)) &&
- (strcmp(h1, host) == 0)) {
- free(h1);
- return (0);
- }
- if (((strcmp(h1, ALL) == 0) || (strcmp(h1, host) == 0)) &&
- (strcmp(u1, user) == 0)) {
- free(h1);
- return (0);
- }
- free(h1);
- return (-1);
-}
-
-
-static int
-compair_queue_binding(print_queue_t *queue, ns_bsd_addr_t *binding)
-{
- if ((queue == NULL) || (binding == NULL))
- return (-1);
- if ((strcmp(queue->binding->printer, binding->printer) == 0) &&
- (strcmp(queue->binding->server, binding->server) == 0))
- return (0);
- return (-1);
-}
-
-
-
-static char *
-get_queue_buffer(ns_bsd_addr_t *binding)
-{
- char *q = NULL,
- *p = NULL,
- *server,
- *printer;
- int nd,
- rc,
- count = 0,
- q_size = 0,
- p_left = 0;
-
- server = binding->server;
- printer = binding->printer;
-
- if ((nd = net_open(server, 15)) < 0) {
- char err[128];
-
- (void) snprintf(err, sizeof (err),
- gettext("server %s not responding\n\n"),
- server);
- return (strdup(err));
- }
-
- rc = net_printf(nd, "%c%s \n", SHOW_QUEUE_LONG_REQUEST, printer);
- if (rc < 0)
- syslog(LOG_ERR, "net_printf() failed: %m");
-
- do {
- p += count;
- if ((p_left -= count) < 10) {
- char *t;
-
-#ifdef SUNOS_4
- if (q == NULL) {
- p = q = malloc(BUFSIZ);
- (void) memset(p, NULL, BUFSIZ);
- q_size = BUFSIZ;
- } else {
- q_size += BUFSIZ;
- t = malloc(q_size);
- (void) memset(t, NULL, q_size);
- strcpy(t, q);
- free(q);
- p = t + (p - q);
- q = t;
- }
-#else
- if ((t = (char *)realloc(q, q_size += BUFSIZ)) != q) {
- p = t + (p - q);
- q = t;
- }
-#endif
- p_left += BUFSIZ;
- (void) memset(p, NULL, p_left);
- }
- } while ((count = net_read(nd, p, p_left)) > 0);
-
- (void) net_close(nd);
-
- return (q);
-}
-
-
-
-print_queue_t *
-sysv_get_queue(ns_bsd_addr_t *binding, int local)
-{
- print_queue_t *qp = NULL;
- char *buf;
-
- if (_queue_list != NULL) /* did we already get it ? */
- if ((qp = (print_queue_t *)list_locate((void **)_queue_list,
- (COMP_T)compair_queue_binding, binding)) != NULL)
- return (qp);
-
- if (local == 0)
- buf = (char *)get_queue_buffer(binding);
- else
- buf = strdup("no entries\n");
-
- if (buf != NULL) {
- qp = parse_bsd_queue(binding, buf, strlen(buf));
- _queue_list = (print_queue_t **)list_append((void **)
- _queue_list, (void *)qp);
- }
- return (qp);
-}
-
-
-
-
-
-
- /*
- * SYSV (lpstat) specific routines
- */
-
-static int
-vJobfile_size(jobfile_t *file)
-{
- if (file != NULL)
- return (file->jf_size);
- return (0);
-}
-
-
-void
-vsysv_queue_entry(job_t *job, va_list ap)
-{
- char id[128],
- user[128],
- *printer = va_arg(ap, char *),
- *in_user = va_arg(ap, char *);
- int in_id = va_arg(ap, int),
- verbose = va_arg(ap, int),
- *rank = va_arg(ap, int *),
- size = 0;
-
- if ((in_id != -1) && (in_id != job->job_id))
- return;
- if (compair_user(in_user, job->job_user, job->job_host) != 0)
- return;
-
- (void) sprintf(id, "%.16s-%-5d", printer, job->job_id);
- (void) snprintf(user, sizeof (user), "%s@%s", job->job_user,
- job->job_host);
- size = list_iterate((void **)job->job_df_list, (VFUNC_T)vJobfile_size);
- if (*rank >= 0)
- (void) printf("%d ", (*rank)++);
- (void) printf("%-*s %-*s %*d %s%s", (*rank >= 0 ? 20 : 22), id, 15,
- user, 7, size, (*rank >= 0 ? "" : " "), short_date());
- if (verbose == 0) {
- if (*rank == 1)
- (void) printf(" on %s", printer);
- (void) printf("\n");
- } else
- (void) printf("\n\t%s %s\n",
- ((*rank > 1) ? "on" : "assigned"), printer);
-}
-
-
-#define OLD_LPSTAT "/usr/lib/lp/local/lpstat" /* for -c -f -S */
-#ifdef OLD_LPSTAT
-static int
-local_printer(char *name)
-{
- char buf[128];
-
- (void) snprintf(buf, sizeof (buf),
- "/etc/lp/printers/%s/configuration", name);
- return (access(buf, F_OK));
-}
-
-static int
-local_class(char *name)
-{
- char buf[128];
-
- (void) snprintf(buf, sizeof (buf),
- "/etc/lp/classes/%s", name);
- return (access(buf, F_OK));
-}
-
-int
-sysv_local_status(char *option, char *arg, int verbose,
- int description, char *invalid)
-{
- pid_t stat;
-
- if (access(OLD_LPSTAT, F_OK) == 0) {
- char buf[BUFSIZ];
-
- /*
- * Need the fflush to preserve output order when
- * output re-directed to a file. Close of old lpstat
- * flushes buffers causing old lpstat output to preceed
- * all other output to the file.
- */
- (void) fflush(stdout);
- (void) fflush(stderr);
- (void) snprintf(buf, sizeof (buf),
- "%s %s %s%s%s", OLD_LPSTAT, option,
- (arg ? arg : ""), (verbose ? " -l" : ""),
- (description ? " -D" : ""));
- stat = system(buf);
- if (WIFEXITED(stat)) {
- return (WEXITSTATUS(stat));
- } else {
- if (stat == -1)
- return (errno);
- else
- return (ENOMSG);
- }
- } else
- (void) printf("%s", invalid);
-
- return (0);
-}
-#endif
-
-
-int
-sysv_queue_state(print_queue_t *qp, char *printer, int verbose, int description)
-{
-#ifdef OLD_LPSTAT
- pid_t stat;
-
- if ((local_printer(printer) == 0) && (access(OLD_LPSTAT, F_OK) == 0)) {
- char buf[BUFSIZ];
-
- /* see sysv_local_status for reason for fflush */
- (void) fflush(stdout);
- (void) fflush(stderr);
- (void) snprintf(buf, sizeof (buf),
- "%s -p %s%s%s", OLD_LPSTAT, printer,
- (verbose ? " -l" : ""), (description ? " -D" : ""));
- stat = system(buf);
- if (WIFEXITED(stat)) {
- return (WEXITSTATUS(stat));
- } else {
- if (stat == -1)
- return (errno);
- else
- return (ENOMSG);
- }
-
-
- }
-#endif
-
- (void) printf(gettext("printer %s "), printer);
- switch (qp->state) {
- case IDLE:
- (void) printf(gettext("is idle. "));
- break;
- case PRINTING:
- (void) printf(gettext("now printing %s-%d. "), printer,
- qp->jobs[0]->job_id);
- break;
- case FAULTED:
- (void) printf(gettext("faulted printing %s-%d. "), printer,
- (qp->jobs != NULL ? qp->jobs[0]->job_id : 0));
- break;
- case RAW:
- (void) printf(gettext("unknown state. "));
- break;
- default:
- (void) printf(gettext("disabled. "));
- }
- (void) printf(gettext("enabled since %s. available.\n"), long_date());
- if (qp->state == FAULTED)
- (void) printf("\t%s\n", qp->status);
- if (description != 0) {
- ns_printer_t *pobj;
- char *desc;
-
- if (((pobj = ns_printer_get_name(qp->binding->printer, NULL))
- != NULL) &&
- ((desc = ns_get_value(NS_KEY_DESCRIPTION, pobj)) != NULL))
- (void) printf(gettext("\tDescription: %s\n"), desc);
- else
- (void) printf(gettext("\tDescription: %s@%s\n"),
- qp->binding->printer, qp->binding->server);
- }
- if (verbose != 0)
- (void) printf(
- gettext("\tRemote Name: %s\n\tRemote Server: %s\n"),
- qp->binding->printer, qp->binding->server);
-
- return (0);
-}
-
-
-int
-sysv_accept(ns_bsd_addr_t *binding)
-{
-#ifdef OLD_LPSTAT
- int result = 0;
-
- if (((local_printer(binding->printer) == 0) ||
- (local_class(binding->printer) == 0)) &&
- (access(OLD_LPSTAT, F_OK) == 0)) {
- /*
- * Locally attached printer, so display its accept state using
- * the old lpstat utility.
- */
- result = sysv_displayLocalLPSTAT(binding->printer,
- binding->pname);
- return (result);
- }
-#endif
-
-
- if (binding->pname != NULL)
- (void) printf(gettext("%s accepting requests since %s\n"),
- binding->pname, long_date());
- else
- (void) printf(gettext("%s accepting requests since %s\n"),
- binding->printer, long_date());
-
- return (0);
-}
-
-
-
-#ifdef OLD_LPSTAT
-/*
- * FUNCTION: sysv_displayLocalLPSTAT()
- *
- * DESCRIPTION: This function uses the old lpstat (/usr/lib/lp/local/lpstat)
- * utility to display the accepting state (-a option) for locally
- * attached printers.
- * If an alias name is given then the output from lpstat is
- * captured and modified to show the alias name instead of the
- * printer's real name. Note: this is done because the old lpstat
- * can not handle alias names.
- *
- * PARAMETERS:
- * Input: char *pname - printers real name
- * char *aname - printers alias name
- *
- * RETURNS: 0 = completed okay, otherwise error
- *
- */
-
-static int
-sysv_displayLocalLPSTAT(char *pname, char *aname)
-
-{
- int result = ENOMSG;
- char buf[BUFSIZ];
- FILE *fd = NULL;
- char *tmp = NULL;
-
- /* see sysv_local_status for reason for fflush */
- (void) fflush(stdout);
- (void) fflush(stderr);
-
- if (((pname != NULL) && (aname != NULL)) &&
- (strcmp(pname, aname) != 0))
- {
- /*
- * This is a request to display status of an aliased local
- * printer, so capture the output from the local lpstat for the
- * real printer and then display that output with the alias
- * name instead of the real name.
- */
-
- (void) snprintf(buf, sizeof (buf), "%s -a %s",
- OLD_LPSTAT, pname);
-
- /* execute the local lpstat utility and display output */
-
- fd = popen(buf, "r");
- if (fd != NULL)
- {
- tmp = fgets(buf, sizeof (buf), fd);
- if (tmp != NULL)
- {
- result = 0;
-
- if (strncmp(buf, pname, strlen(pname)) == 0)
- {
- printf("%s", aname);
- printf("%s", &(buf[strlen(pname)]));
-
- tmp = fgets(buf, sizeof (buf), fd);
- }
-
- /*
- * finish reading and displaying the
- * output from the lpstat utility
- */
-
- while (tmp != NULL)
- {
- printf("%s", buf);
- tmp = fgets(buf, sizeof (buf), fd);
- }
- }
-
- (void) pclose(fd);
- }
- }
-
- else
- if (pname != NULL)
- {
- /*
- * Not an alias so directly display output from the
- * local lpstat utility
- */
- (void) snprintf(buf, sizeof (buf), "%s -a %s",
- OLD_LPSTAT, pname);
- result = system(buf);
-
- if (WIFEXITED(result))
- {
- result = WEXITSTATUS(result);
- }
- else
- if (result == -1)
- {
- result = errno;
- }
- else
- {
- result = ENOMSG;
- }
- }
-
- return (result);
-} /* sysv_displayLocalLPSTAT */
-#endif
-
-
-
-int
-sysv_system(ns_bsd_addr_t *binding)
-{
- char *host;
- char *printer;
- pid_t stat;
-
- if (binding->pname)
- printer = binding->pname;
- else
- printer = binding->printer;
- host = binding->server;
-#ifdef OLD_LPSTAT
-
- if ((local_printer(printer) == 0) && (access(OLD_LPSTAT, F_OK) == 0)) {
- char buf[BUFSIZ];
-
- /* see sysv_local_status for reason for fflush */
- (void) fflush(stdout);
- (void) fflush(stderr);
- (void) snprintf(buf, sizeof (buf),
- "%s -v %s", OLD_LPSTAT, printer);
- stat = system(buf);
-
- if (WIFEXITED(stat)) {
- return (WEXITSTATUS(stat));
- } else {
- if (stat == -1)
- return (errno);
- else
- return (ENOMSG);
- }
- } else
-#endif
- if (printer && host) {
- if (strcmp(printer, binding->printer) == 0)
- (void) printf(gettext("system for %s: %s\n"), printer,
- host);
- else
- (void) printf(
- gettext("system for %s: %s (as printer %s)\n"),
- printer, host, binding->printer);
- }
-
- return (0);
-}
-
-
-void
-sysv_running()
-{
- int lock;
- struct stat st;
-
- lock = stat("/usr/spool/lp/SCHEDLOCK", &st);
- if (lock < 0)
- (void) printf(gettext("scheduler is not running\n"));
- else
- (void) printf(gettext("scheduler is running\n"));
-}
-
-
-void
-sysv_default()
-{
- char *printer;
-
- if ((printer = getenv((const char *)"LPDEST")) == NULL)
- printer = getenv((const char *)"PRINTER");
- if (printer == NULL) {
- ns_printer_t *p;
-
- if ((p = ns_printer_get_name(NS_NAME_DEFAULT, NULL)) != NULL) {
- printer = ns_get_value(NS_KEY_USE, p);
- /*
- * Fall back to the printer name out of
- * the "bsdaddr" attribute
- */
- if (printer == NULL) {
- ns_bsd_addr_t *a =
- ns_get_value(NS_KEY_BSDADDR, p);
- if ((a != NULL) && (a->printer != NULL)) {
- static char buf[64];
- (void) snprintf(buf, sizeof (buf), "%s",
- a->printer);
- printer = buf;
- }
- }
- }
- }
- if (printer != NULL)
- (void) printf(gettext("system default destination: %s\n"),
- printer);
- else
- (void) printf(gettext("no system default destination\n"));
-}
diff --git a/usr/src/cmd/print/lpstat/sysv-functions.h b/usr/src/cmd/print/lpstat/sysv-functions.h
deleted file mode 100644
index eea04ecc4b..0000000000
--- a/usr/src/cmd/print/lpstat/sysv-functions.h
+++ /dev/null
@@ -1,50 +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 _SYSV_FUNCTIONS_H
-#define _SYSV_FUNCTIONS_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern void vsysv_queue_entry(job_t *job, va_list ap);
-extern int sysv_queue_state(print_queue_t *qp, char *printer, int verbose,
- int description);
-extern int sysv_accept(ns_bsd_addr_t *binding);
-extern int sysv_system(ns_bsd_addr_t *binding);
-extern void sysv_running();
-extern void sysv_default();
-extern int sysv_local_status(char *, char *, int, int, char *);
-extern print_queue_t *sysv_get_queue(ns_bsd_addr_t *binding, int local);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYSV_FUNCTIONS_H */
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/accept b/usr/src/cmd/print/scripts/accept
deleted file mode 100644
index 8d2fb4a995..0000000000
--- a/usr/src/cmd/print/scripts/accept
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/bin/sh
-#
-# 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) 1994, 1995, 1996 by Sun Microsystems, Inc.
-# All Rights Reserved
-#
-# ident "%Z%%M% %I% %E% SMI"
-#
-PATH=/usr/ucb:/bin:/usr/bin:/usr/sbin export PATH
-cmd_name=`basename $0`
-args=""
-reason=""
-destinations=""
-exit_code=0
-local_exit=0
-
-TEXTDOMAIN="SUNW_OST_OSCMD"
-export TEXTDOMAIN
-
-#
-# check for some options
-#
-if [ $# -lt 1 ] ; then
- gettext "Usage: "
- echo -n $cmd_name $valid_opts
- gettext " printer ..."
- echo
- exit 1
-fi
-
-# set variables for command
-case $cmd_name in
- accept)
- valid_opts=""
- options="\?"
- ;;
- enable)
- valid_opts=""
- options="\?"
- ;;
- reject)
- valid_opts="[ -r reason ]"
- options="r:"
- ;;
- disable)
- valid_opts="[ -c | -W ] [ -r reason ]"
- options="Wcr:"
- ;;
- *)
- gettext "Error: "
- echo -n $cmd_name
- gettext " - invalid name"
- echo
- exit 1
- ;;
-esac
-
-# Strip off legal options
-while getopts $options arg
-do
- case $arg in
- c|W)
- args="${args} -$arg"
- ;;
- r)
- reason=${OPTARG}
- ;;
- \?)
- gettext "Usage: "
- echo -n $cmd_name $valid_opts
- gettext " printer ..."
- echo
- exit 1
- ;;
- esac
-done
-shift `expr $OPTIND - 1`
-
-
-if [ "$*" = "" ] ; then
- gettext "No destination specified"
- echo
- exit 1
-fi
-
-# Each destination
-for printer in $*
-do
- if [ -f /etc/lp/classes/$printer -o -d /etc/lp/printers/$printer -a \
- -f /usr/lib/lp/local/$cmd_name ]
- then
- destinations="${destinations} ${printer}"
- else
- check=`lpstat -v $printer -L`
- if [ -n "$check" ]
- then
- gettext "Warning: "
- echo -n $printer
- gettext " is remote, $cmd_name has no meaning."
- echo
- else
- exit_code=1
- fi
- fi
-done
-
-if [ -n "$destinations" ]
-then
- if [ -n "$reason" ] ; then
- /usr/lib/lp/local/$cmd_name -r "$reason" $args $destinations
- else
- /usr/lib/lp/local/$cmd_name $args $destinations
- fi
- local_exit=$?
-fi
-
-if [ ${local_exit} -ne 0 ] ; then
- exit ${local_exit}
-else
- exit ${exit_code}
-fi
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/cmd/lp/cmd/lpstat/Makefile b/usr/src/lib/print/libhttp-core/Makefile.com
index 9e9b661703..c027f93270 100644
--- a/usr/src/cmd/lp/cmd/lpstat/Makefile
+++ b/usr/src/lib/print/libhttp-core/Makefile.com
@@ -17,75 +17,48 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
-
-
#
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# cmd/lp/cmd/lpstat/Makefile
+# ident "%Z%%M% %I% %E% SMI"
#
-include ../../Makefile.lp
+LIBRARY = libhttp-core.a
+VERS = .1
+OBJECTS = http-addr.o http-support.o http.o
-PROG= lpstat
+ROOTLIBDIR = $(ROOT)/usr/lib/print
-SRCS = accept.c \
- add_mounted.c \
- charset.c \
- class.c \
- device.c \
- done.c \
- form.c \
- lpstat.c \
- output.c \
- parse.c \
- printer.c \
- request.c \
- send_message.c
+include ../../../Makefile.lib
+include ../../../Makefile.rootfs
-OBJS= $(SRCS:.c=.o)
+ROOTLIBDIR= $(ROOT)/usr/lib/print
+ROOTLIBDIR64= $(ROOT)/usr/lib/print/$(MACH)
+LIBS = $(DYNLIB)
-CPPFLAGS = -I$(LPINC) $(CPPFLAGS.master)
+SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c)
-LPLIBS = $(LIBACC) \
- $(LIBCLS) \
- $(LIBMSG) \
- $(LIBPRT) \
- $(LIBFRM) \
- $(LIBOAM) \
- $(LIBLP)
+$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
-SYSLIBS= -lcurses
+SRCDIR = ../common
+MAPFILE = $(SRCDIR)/mapfile
-LDLIBS += $(LPLIBS) $(SYSLIBS) $(I18N) -z lazyload -lsecdb -z nolazyload
-
-POFILE= lp_cmd_lpstat.po
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -I$(SRCDIR)
+CPPFLAGS += -I../../libpapi-common/common
+DYNFLAGS += -M $(MAPFILE)
+LDLIBS += -lsocket -lnsl -lc
.KEEP_STATE:
-all: $(PROG)
-
-$(PROG): $(OBJS)
- $(LINK.c) $(OBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
-
-install: all $(ROOTLIBLPLOCLPROG)
-
-clean:
- $(RM) $(OBJS)
-
-clobber: clean
- -$(RM) $(PROG) $(CLOBBERFILES)
+all: $(LIBS)
-strip:
- $(STRIP) $(PROG)
+lint: lintcheck
-lint:
- $(LINT.c) $(SRCS) $(LDLIBS)
+$(ROOTLIBDIR):
+ $(INS.dir)
-include ../Makefile.msg
+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/cmd/lp/lib/papi/attribute.c b/usr/src/lib/print/libpapi-common/common/attribute.c
index 02f5db2fc4..2b2e035cfe 100644
--- a/usr/src/cmd/lp/lib/papi/attribute.c
+++ b/usr/src/lib/print/libpapi-common/common/attribute.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.
@@ -19,19 +18,25 @@
*
* 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.
+ *
*/
+/* $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 <papi_impl.h>
+#include <alloca.h>
+#include <papi.h>
static void papiAttributeFree(papi_attribute_t *attribute);
@@ -110,31 +115,40 @@ collection_dup(papi_attribute_t **collection)
/* 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; i++) {
+ for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK));
+ i++) {
papi_attribute_t *a = collection[i];
- papiAttributeListAdd(&result, PAPI_ATTR_APPEND, a->name,
- a->type, NULL);
- if (a->values != NULL) {
+ 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; j++)
- papiAttributeListAdd(&result,
+ 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(const papi_attribute_value_type_t type,
- const papi_attribute_value_t *v)
+papiAttributeValueDup(papi_attribute_value_type_t type,
+ papi_attribute_value_t *v)
{
papi_attribute_value_t *result = NULL;
@@ -168,6 +182,9 @@ papiAttributeValueDup(const papi_attribute_value_type_t type,
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;
@@ -178,7 +195,7 @@ papiAttributeValueDup(const papi_attribute_value_type_t type,
}
static papi_attribute_t *
-papiAttributeAlloc(const char *name, papi_attribute_value_type_t type)
+papiAttributeAlloc(char *name, papi_attribute_value_type_t type)
{
papi_attribute_t *result = NULL;
@@ -191,9 +208,9 @@ papiAttributeAlloc(const char *name, papi_attribute_value_type_t type)
}
static papi_status_t
-papiAttributeListAddValue(papi_attribute_value_t ***values,
- const papi_attribute_value_type_t type,
- const papi_attribute_value_t *value)
+papiAttributeListAppendValue(papi_attribute_value_t ***values,
+ papi_attribute_value_type_t type,
+ papi_attribute_value_t *value)
{
if (values == NULL)
@@ -212,9 +229,9 @@ papiAttributeListAddValue(papi_attribute_value_t ***values,
}
papi_status_t
-papiAttributeListAdd(papi_attribute_t ***list, const int flgs,
- const char *name, const papi_attribute_value_type_t type,
- const papi_attribute_value_t *value)
+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;
@@ -262,7 +279,7 @@ papiAttributeListAdd(papi_attribute_t ***list, const int flgs,
attribute->type = type;
- result = papiAttributeListAddValue(&attribute->values, type, value);
+ result = papiAttributeListAppendValue(&attribute->values, type, value);
/* free old values if we replaced them */
if (values != NULL)
@@ -272,81 +289,95 @@ papiAttributeListAdd(papi_attribute_t ***list, const int flgs,
}
papi_status_t
-papiAttributeListAddString(papi_attribute_t ***list, const int flags,
- const char *name, const char *string)
+papiAttributeListAddString(papi_attribute_t ***list, int flags,
+ char *name, char *string)
{
papi_attribute_value_t v;
v.string = (char *)string;
- return (papiAttributeListAdd(list, flags, name, PAPI_STRING, &v));
+ return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v));
}
papi_status_t
-papiAttributeListAddInteger(papi_attribute_t ***list, const int flags,
- const char *name, const int integer)
+papiAttributeListAddInteger(papi_attribute_t ***list, int flags,
+ char *name, int integer)
{
papi_attribute_value_t v;
v.integer = integer;
- return (papiAttributeListAdd(list, flags, name, PAPI_INTEGER, &v));
+ return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v));
}
papi_status_t
-papiAttributeListAddBoolean(papi_attribute_t ***list, const int flags,
- const char *name, const char boolean)
+papiAttributeListAddBoolean(papi_attribute_t ***list, int flags,
+ char *name, char boolean)
{
papi_attribute_value_t v;
v.boolean = boolean;
- return (papiAttributeListAdd(list, flags, name, PAPI_BOOLEAN, &v));
+ return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v));
}
papi_status_t
-papiAttributeListAddRange(papi_attribute_t ***list, const int flags,
- const char *name, const int lower, const int upper)
+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 (papiAttributeListAdd(list, flags, name, PAPI_RANGE, &v));
+ return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v));
}
papi_status_t
-papiAttributeListAddResolution(papi_attribute_t ***list, const int flags,
- const char *name, const int xres, const int yres,
- const papi_resolution_unit_t units)
+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 (papiAttributeListAdd(list, flags, name, PAPI_RESOLUTION, &v));
+ return (papiAttributeListAddValue(list, flags, name,
+ PAPI_RESOLUTION, &v));
}
papi_status_t
-papiAttributeListAddDatetime(papi_attribute_t ***list, const int flags,
- const char *name, const time_t datetime)
+papiAttributeListAddDatetime(papi_attribute_t ***list, int flags,
+ char *name, time_t datetime)
{
papi_attribute_value_t v;
v.datetime = datetime;
- return (papiAttributeListAdd(list, flags, name, PAPI_DATETIME, &v));
+ return (papiAttributeListAddValue(list, flags, name,
+ PAPI_DATETIME, &v));
}
papi_status_t
-papiAttributeListAddCollection(papi_attribute_t ***list, const int flags,
- const char *name, const papi_attribute_t **collection)
+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 (papiAttributeListAdd(list, flags, name, PAPI_COLLECTION, &v));
+ 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, const char *name)
+papiAttributeListDelete(papi_attribute_t ***list, char *name)
{
papi_attribute_t *attribute;
@@ -363,15 +394,15 @@ papiAttributeListDelete(papi_attribute_t ***list, const char *name)
}
papi_attribute_t *
-papiAttributeListFind(papi_attribute_t **list, const char *name)
+papiAttributeListFind(papi_attribute_t **list, char *name)
{
- if (list != NULL) {
- int i;
+ 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]);
- }
+ for (i = 0; list[i] != NULL; i++)
+ if (strcasecmp(list[i]->name, name) == 0)
+ return ((papi_attribute_t *)list[i]);
return (NULL);
}
@@ -396,7 +427,7 @@ papiAttributeListGetNext(papi_attribute_t **list, void **iter)
papi_status_t
papiAttributeListGetValue(papi_attribute_t **list, void **iter,
- const char *name, papi_attribute_value_type_t type,
+ char *name, papi_attribute_value_type_t type,
papi_attribute_value_t **value)
{
papi_attribute_value_t **tmp;
@@ -436,7 +467,7 @@ papiAttributeListGetValue(papi_attribute_t **list, void **iter,
papi_status_t
papiAttributeListGetString(papi_attribute_t **list, void **iter,
- const char *name, char **vptr)
+ char *name, char **vptr)
{
papi_status_t status;
papi_attribute_value_t *value = NULL;
@@ -454,7 +485,7 @@ papiAttributeListGetString(papi_attribute_t **list, void **iter,
papi_status_t
papiAttributeListGetInteger(papi_attribute_t **list, void **iter,
- const char *name, int *vptr)
+ char *name, int *vptr)
{
papi_status_t status;
papi_attribute_value_t *value = NULL;
@@ -472,7 +503,7 @@ papiAttributeListGetInteger(papi_attribute_t **list, void **iter,
papi_status_t
papiAttributeListGetBoolean(papi_attribute_t **list, void **iter,
- const char *name, char *vptr)
+ char *name, char *vptr)
{
papi_status_t status;
papi_attribute_value_t *value = NULL;
@@ -490,7 +521,7 @@ papiAttributeListGetBoolean(papi_attribute_t **list, void **iter,
papi_status_t
papiAttributeListGetRange(papi_attribute_t **list, void **iter,
- const char *name, int *min, int *max)
+ char *name, int *min, int *max)
{
papi_status_t status;
papi_attribute_value_t *value = NULL;
@@ -510,7 +541,7 @@ papiAttributeListGetRange(papi_attribute_t **list, void **iter,
papi_status_t
papiAttributeListGetResolution(papi_attribute_t **list, void **iter,
- const char *name, int *x, int *y,
+ char *name, int *x, int *y,
papi_resolution_unit_t *units)
{
papi_status_t status;
@@ -532,7 +563,7 @@ papiAttributeListGetResolution(papi_attribute_t **list, void **iter,
papi_status_t
papiAttributeListGetDatetime(papi_attribute_t **list, void **iter,
- const char *name, time_t *dt)
+ char *name, time_t *dt)
{
papi_status_t status;
papi_attribute_value_t *value = NULL;
@@ -551,7 +582,7 @@ papiAttributeListGetDatetime(papi_attribute_t **list, void **iter,
papi_status_t
papiAttributeListGetCollection(papi_attribute_t **list, void **iter,
- const char *name, papi_attribute_t ***collection)
+ char *name, papi_attribute_t ***collection)
{
papi_status_t status;
papi_attribute_value_t *value = NULL;
@@ -568,22 +599,36 @@ papiAttributeListGetCollection(papi_attribute_t **list, void **iter,
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.
+ * 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(const char *string, int *next)
+_getNextAttr(char *string, int *next)
{
char *result = NULL;
@@ -594,8 +639,7 @@ _getNextAttr(const char *string, int *next)
char *val = NULL;
int len = 0;
- if ((string != NULL) && (*start != '\0'))
- {
+ if ((string != NULL) && (*start != '\0')) {
while ((*start == ' ') || (*start == '\t') || (*start == '\n'))
{
start++;
@@ -606,11 +650,9 @@ _getNextAttr(const char *string, int *next)
val = strchr(start, '=');
- if ((val != NULL) && ((val[1] == '"') || (val[1] == '\'')))
- {
+ if ((val != NULL) && ((val[1] == '"') || (val[1] == '\''))) {
val = strchr(&val[2], val[1]);
- if (val != NULL)
- {
+ if (val != NULL) {
nl = strchr(&val[1], '\n');
sp = strchr(&val[1], ' ');
tab = strchr(&val[1], '\t');
@@ -619,36 +661,23 @@ _getNextAttr(const char *string, int *next)
if ((nl != NULL) &&
((sp == NULL) || ((sp != NULL) && (nl < sp))) &&
- ((tab == NULL) || ((tab != NULL) && (nl < tab))))
- {
+ ((tab == NULL) || ((tab != NULL) && (nl < tab)))) {
len = nl-start;
- }
- else
- if ((sp != NULL) && (tab != NULL) && (sp > tab))
- {
+ } else if ((sp != NULL) && (tab != NULL) && (sp > tab)) {
len = tab-start;
- }
- else
- if ((sp != NULL) && (sp != NULL))
- {
+ } else if ((sp != NULL) && (sp != NULL)) {
len = sp-start;
- }
- else
- if ((tab != NULL) && (tab != NULL))
- {
+ } else if ((tab != NULL) && (tab != NULL)) {
len = tab-start;
}
- if (len == 0)
- {
+ if (len == 0) {
len = strlen(start);
}
- if (len > 0)
- {
+ if (len > 0) {
result = (char *)malloc(len+1);
- if (result != NULL)
- {
+ if (result != NULL) {
strncpy(result, start, len);
result[len] = '\0';
*next = (start-string)+len;
@@ -661,12 +690,9 @@ _getNextAttr(const char *string, int *next)
/*
- * *****************************************************************************
- *
* Description: Parse the given attribute string value and transform it into
- * the papi_attribute_value_t in the papi_attribute_t structure.
+ * the papi_attribute_value_t in the papi_attribute_t structure.
*
- * *****************************************************************************
*/
static papi_status_t
@@ -683,15 +709,13 @@ _parseAttrValue(char *value, papi_attribute_t *attr)
papi_attribute_value_t **avalues = NULL;
avalues = malloc(sizeof (papi_attribute_value_t *) * 2);
- if (avalues == NULL)
- {
+ if (avalues == NULL) {
result = PAPI_TEMPORARY_ERROR;
return (result);
}
avalues[0] = malloc(sizeof (papi_attribute_value_t));
avalues[1] = NULL;
- if (avalues[0] == NULL)
- {
+ if (avalues[0] == NULL) {
free(avalues);
result = PAPI_TEMPORARY_ERROR;
return (result);
@@ -701,59 +725,41 @@ _parseAttrValue(char *value, papi_attribute_t *attr)
/*
* TODO - need to sort out 'resolution', 'dateandtime' & 'collection' values
*/
- if ((value != NULL) && (strlen(value) > 0) && (attr != NULL))
- {
+ if ((value != NULL) && (strlen(value) > 0) && (attr != NULL)) {
len = strlen(value);
- if ((len >= 2) &&
- (((value[0] == '"') && (value[len-1] == '"')) ||
- ((value[0] == '\'') && (value[len-1] == '\''))))
- {
+ 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)
- {
+ if (papiString != NULL) {
papiString[strlen(papiString)-1] = '\0';
avalues[0]->string = papiString;
- }
- else
- {
+ } else {
result = PAPI_TEMPORARY_ERROR;
}
- }
-
- else
- if ((strcasecmp(value, "true") == 0) ||
- (strcasecmp(value, "YES") == 0))
- {
+ } 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))
- {
+ } 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? */
+ } 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] == '-')
- {
+ (value[i] == '-')) {
+ if (value[i] == '-') {
tmp1[i] = '\0';
tmp2 = &tmp1[i+1];
attr->type = PAPI_RANGE;
@@ -762,40 +768,29 @@ _parseAttrValue(char *value, papi_attribute_t *attr)
i++;
}
- if (strlen(value) == i)
- {
- if (attr->type == PAPI_RANGE)
- {
+ if (strlen(value) == i) {
+ if (attr->type == PAPI_RANGE) {
avalues[0]->range.lower = atoi(tmp1);
avalues[0]->range.upper = atoi(tmp2);
- }
- else
- {
+ } else {
avalues[0]->integer = atoi(value);
}
- }
- else
- {
- /* is value a resolution? */
-
+ } 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')
- {
+ (value[i] == 'x')) {
+ if (value[i] == 'x') {
tmp1[i] = '\0';
if (attr->type == PAPI_INTEGER)
{
tmp2 = &tmp1[i+1];
attr->type =
PAPI_RESOLUTION;
- }
- else
- {
+ } else {
tmp3 = &tmp1[i+1];
}
}
@@ -803,35 +798,27 @@ _parseAttrValue(char *value, papi_attribute_t *attr)
i++;
}
- if (strlen(value) == i)
- {
- if (attr->type == PAPI_RESOLUTION)
- {
+ if (strlen(value) == i) {
+ if (attr->type == PAPI_RESOLUTION) {
avalues[0]->resolution.xres =
atoi(tmp1);
avalues[0]->resolution.yres =
atoi(tmp2);
- if (tmp3 != NULL)
- {
+ if (tmp3 != NULL) {
avalues[0]->
- resolution.units =
+ resolution.units =
atoi(tmp3);
- }
- else
- {
+ } else {
avalues[0]->
- resolution.units =
- 0;
+ resolution.units = 0;
}
}
}
- if (attr->type != PAPI_RESOLUTION)
- {
+ if (attr->type != PAPI_RESOLUTION) {
attr->type = PAPI_STRING;
avalues[0]->string = strdup(value);
- if (avalues[0]->string == NULL)
- {
+ if (avalues[0]->string == NULL) {
result = PAPI_TEMPORARY_ERROR;
}
}
@@ -839,24 +826,18 @@ _parseAttrValue(char *value, papi_attribute_t *attr)
free(tmp1);
}
- }
- else
- {
+ } else {
result = PAPI_BAD_ARGUMENT;
}
- if (result != PAPI_OK)
- {
+ if (result != PAPI_OK) {
i = 0;
- while (avalues[i] != NULL)
- {
+ while (avalues[i] != NULL) {
free(avalues[i]);
i++;
}
free(avalues);
- }
- else
- {
+ } else {
attr->values = avalues;
}
@@ -865,12 +846,9 @@ _parseAttrValue(char *value, papi_attribute_t *attr)
/*
- * *****************************************************************************
- *
* Description: Parse the given attribute string and transform it into the
- * papi_attribute_t structure.
+ * papi_attribute_t structure.
*
- * *****************************************************************************
*/
static papi_status_t
@@ -882,57 +860,49 @@ _parseAttributeString(char *attrString, papi_attribute_t *attr)
char *p = NULL;
papi_attribute_value_t **avalues = NULL;
- if ((attrString != NULL) && (strlen(attrString) >= 3) && (attr != NULL))
- {
+ if ((attrString != NULL) && (strlen(attrString) >= 3) &&
+ (attr != NULL)) {
attr->name = NULL;
string = strdup(attrString);
- if (string != NULL)
- {
+ if (string != NULL) {
p = strchr(string, '=');
- if (p != NULL)
- {
+ if (p != NULL) {
*p = '\0';
attr->name = string;
p++; /* pointer to value */
result = _parseAttrValue(p, attr);
- }
- else
- {
+ } 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(
+ avalues = malloc(
sizeof (papi_attribute_value_t *) * 2);
- if (avalues == NULL)
- {
+ if (avalues == NULL) {
result = PAPI_TEMPORARY_ERROR;
- }
- else
- {
- avalues[0] =
- malloc(
- sizeof (papi_attribute_value_t));
+ } else {
+ avalues[0] = malloc(
+ sizeof (papi_attribute_value_t));
avalues[1] = NULL;
- if (avalues[0] == NULL)
- {
+ if (avalues[0] == NULL) {
free(avalues);
result = PAPI_TEMPORARY_ERROR;
- }
- else
- {
- avalues[0]->boolean =
- PAPI_TRUE;
+ } else {
+ avalues[0]->boolean = value;
attr->values = avalues;
}
}
}
}
- }
- else
- {
+ } else {
result = PAPI_BAD_ARGUMENT;
}
@@ -942,25 +912,24 @@ _parseAttributeString(char *attrString, papi_attribute_t *attr)
papi_status_t
papiAttributeListFromString(papi_attribute_t ***attrs,
- const int flags, const char *string)
+ int flags, char *string)
{
papi_status_t result = PAPI_OK;
- int next = 0;
- char *attrString = NULL;
+ 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)) {
+ ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL))
+ == 0)) {
attrString = _getNextAttr(string, &next);
while ((result == PAPI_OK) && (attrString != NULL)) {
-printf("papiAttributeListFromString() attr='%s'\n", attrString);
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 = papiAttributeListAdd(
+ result = papiAttributeListAddValue(
attrs, PAPI_ATTR_APPEND,
attr.name, attr.type,
attr.values[0]);
@@ -983,131 +952,230 @@ printf("papiAttributeListFromString() attr='%s'\n", attrString);
return (result);
}
-papi_status_t
-papiAttributeListToString(const papi_attribute_t **attrs,
- const char *delim, char *buffer, const size_t buflen)
+static papi_status_t
+papiAttributeToString(papi_attribute_t *attribute, char *delim,
+ char *buffer, size_t buflen)
{
- return (PAPI_OPERATION_NOT_SUPPORTED);
+ 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);
}
-/* for debugging, not part of the public API */
-static char *
-typeString(papi_attribute_value_type_t type)
+papi_status_t
+papiAttributeListToString(papi_attribute_t **attrs,
+ char *delim, char *buffer, size_t buflen)
{
- switch (type) {
- case PAPI_STRING:
- return ("string");
- case PAPI_INTEGER:
- return ("integer");
- case PAPI_BOOLEAN:
- return ("boolean");
- case PAPI_RANGE:
- return ("range");
- case PAPI_RESOLUTION:
- return ("resolution");
- case PAPI_DATETIME:
- return ("datetime");
- case PAPI_COLLECTION:
- return ("collection");
+ 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 ("unknown");
+ return (status);
}
-void papiAttributeListPrint(FILE *fp, char *prefix, papi_attribute_t **list);
+static int
+is_in_list(char *value, char **list)
+{
+ if ((list != NULL) && (value != NULL)) {
+ int i;
-void
-papiAttributePrint(FILE *fp, char *prefix, papi_attribute_t *attribute)
+ 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)
{
- if (attribute != NULL) {
- char *name = attribute->name;
+ papi_status_t status;
+ int i = 0;
- if (prefix == NULL)
- prefix = "";
+ if ((list == NULL) || (attribute == NULL) ||
+ (attribute->values == NULL))
+ return (PAPI_BAD_ARGUMENT);
-/*
- * fprintf(fp, "%s'%s' (%s) =\n", prefix, (name ? name : "(NULL)"),
- * typeString(attribute->type));
- */
- if (attribute->values != NULL) {
- papi_attribute_value_t **values = attribute->values;
- int i;
+ 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++;
- for (i = 0; values[i] != NULL; i++) {
- fprintf(fp, "%s=", (name ? name : "(NULL)"));
-/*
- * if (attribute->type != PAPI_COLLECTION)
- * fprintf(fp, "%s\t", prefix);
- */
- switch (attribute->type) {
- case PAPI_STRING:
- if ((strchr(values[i]->string, ' ')
- != NULL) ||
- (strchr(values[i]->string, '\t')
- != NULL)) {
- /* quote the string */
- fprintf(fp, "\"%s\"",
- values[i]->string);
- } else {
- fprintf(fp, "%s",
- values[i]->string);
- }
- break;
- case PAPI_INTEGER:
- fprintf(fp, "%d", values[i]->integer);
- break;
- case PAPI_BOOLEAN:
- fprintf(fp, "%s", (values[i]->boolean ?
- "true" : "false"));
- break;
- case PAPI_RANGE:
- fprintf(fp, "%d-%d",
- values[i]->range.lower,
- values[i]->range.upper);
- break;
- case PAPI_RESOLUTION:
- fprintf(fp, "%dx%d",
- values[i]->resolution.xres,
- values[i]->resolution.yres);
- break;
- case PAPI_DATETIME: {
- struct tm *tm;
-
- tm = localtime(&values[i]->datetime);
- if (tm != NULL) {
- char buf[64];
-
- strftime(buf, sizeof (buf),
- "%C", tm);
- fprintf(fp, "%s", buf);
- }}
- break;
- case PAPI_COLLECTION: {
- char s[64];
-
- snprintf(s, sizeof (s), "%s\t", prefix);
- papiAttributeListPrint(fp, s,
- values[i]->collection);
- }
- break;
- default:
- fprintf(fp, "unknown");
- }
- if (attribute->type != PAPI_COLLECTION)
- fprintf(fp, "\n");
- }
- }
- }
+ 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
-papiAttributeListPrint(FILE *fp, char *prefix, papi_attribute_t **list)
+split_and_copy_attributes(char **list, papi_attribute_t **attributes,
+ papi_attribute_t ***in, papi_attribute_t ***out)
{
- if (list != NULL) {
- int i;
+ int i;
- for (i = 0; list[i] != NULL; i++)
- papiAttributePrint(fp, prefix, list[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/cmd/lp/lib/papi/list.c b/usr/src/lib/print/libpapi-common/common/list.c
index fb5451232f..9ed0d2ded2 100644
--- a/usr/src/cmd/lp/lib/papi/list.c
+++ b/usr/src/lib/print/libpapi-common/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.
@@ -19,11 +18,15 @@
*
* 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.
+ *
*/
+/* $Id: list.c 146 2006-03-24 00:26:54Z njacobs $ */
+
#pragma ident "%Z%%M% %I% %E% SMI"
/*LINTLIBRARY*/
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/cmd/lp/lib/papi/papi.h b/usr/src/lib/print/libpapi-common/common/papi.h
index 1ba622aa2a..7c1d891eb2 100644
--- a/usr/src/cmd/lp/lib/papi/papi.h
+++ b/usr/src/lib/print/libpapi-common/common/papi.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.
@@ -19,14 +18,18 @@
*
* 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.
+ *
*/
#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>
@@ -62,7 +65,8 @@ typedef enum {
PAPI_RANGE,
PAPI_RESOLUTION,
PAPI_DATETIME,
- PAPI_COLLECTION
+ PAPI_COLLECTION,
+ PAPI_METADATA
} papi_attribute_value_type_t;
typedef enum {
@@ -75,6 +79,15 @@ enum { /* for boolean values */
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
@@ -97,6 +110,7 @@ typedef union {
} 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 {
@@ -214,195 +228,218 @@ enum {
/* Service related */
extern 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,
+ 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,
- const char *user_name);
+ char *user_name);
extern papi_status_t papiServiceSetPassword(papi_service_t handle,
- const char *password);
+ char *password);
extern papi_status_t papiServiceSetEncryption(papi_service_t handle,
- const papi_encryption_t encryption);
+ papi_encryption_t encryption);
extern papi_status_t papiServiceSetAuthCB(papi_service_t handle,
- const int (*authCB)(papi_service_t s));
+ int (*authCB)(papi_service_t s,
+ void *app_data));
extern papi_status_t papiServiceSetAppData(papi_service_t handle,
- const void *app_data);
+ 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 papiAttributeListAdd(papi_attribute_t ***attrs,
- const int flags,
- const char *name,
- const papi_attribute_value_type_t type,
- const papi_attribute_value_t *value);
+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,
- const int flags, const char *name,
- const char *string);
+ int flags, char *name, char *string);
extern papi_status_t papiAttributeListAddInteger(papi_attribute_t ***attrs,
- const int flags, const char *name,
- const int integer);
+ int flags, char *name, int integer);
extern papi_status_t papiAttributeListAddBoolean(papi_attribute_t ***attrs,
- const int flags, const char *name,
- const char boolean);
+ int flags, char *name, char boolean);
extern papi_status_t papiAttributeListAddRange(papi_attribute_t ***attrs,
- const int flags, const char *name,
- const int lower, const int upper);
+ int flags, char *name,
+ int lower, int upper);
extern papi_status_t papiAttributeListAddResolution(papi_attribute_t ***attrs,
- const int flags, const char *name,
- const int xres, const int yres,
+ int flags, char *name,
+ int xres, int yres,
papi_resolution_unit_t units);
extern papi_status_t papiAttributeListAddDatetime(papi_attribute_t ***attrs,
- const int flags, const char *name,
- const time_t datetime);
+ int flags, char *name, time_t datetime);
extern papi_status_t papiAttributeListAddCollection(papi_attribute_t ***attrs,
- const int flags, const char *name,
- const papi_attribute_t **collection);
+ 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,
- const char *name);
+ char *name);
extern papi_status_t papiAttributeListGetValue(papi_attribute_t **list,
- void **iterator, const char *name,
+ 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, const char *name,
+ void **iterator, char *name,
char **vptr);
extern papi_status_t papiAttributeListGetInteger(papi_attribute_t **list,
- void **iterator, const char *name,
- int *vptr);
+ void **iterator, char *name, int *vptr);
extern papi_status_t papiAttributeListGetBoolean(papi_attribute_t **list,
- void **iterator, const char *name,
+ void **iterator, char *name,
char *vptr);
extern papi_status_t papiAttributeListGetRange(papi_attribute_t **list,
- void **iterator, const char *name,
+ void **iterator, char *name,
int *min, int *max);
extern papi_status_t papiAttributeListGetResolution(papi_attribute_t **list,
- void **iterator, const char *name,
+ void **iterator, char *name,
int *x, int *y,
papi_resolution_unit_t *units);
extern papi_status_t papiAttributeListGetDatetime(papi_attribute_t **list,
- void **iterator, const char *name,
+ void **iterator, char *name,
time_t *dt);
extern papi_status_t papiAttributeListGetCollection(papi_attribute_t **list,
- void **iterator, const char *name,
+ 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,
- const char *name);
+ 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,
- const int flags, const char *string);
-extern papi_status_t papiAttributeListToString(const papi_attribute_t **attrs,
- const char *delim,
- char *buffer, const size_t buflen);
-extern void papiAttributeListPrint
- (FILE *fp, char *prefix, papi_attribute_t **list);
+ 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,
- const char **requested_attrs,
- const papi_filter_t *filter,
+ char **requested_attrs,
+ papi_filter_t *filter,
papi_printer_t **printers);
-extern papi_status_t papiPrinterQuery(papi_service_t handle, const char *name,
- const char **requested_attrs,
- const papi_attribute_t **job_attributes,
+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, const char *name,
- const papi_attribute_t **attributes,
+extern papi_status_t papiPrinterModify(papi_service_t handle, char *name,
+ papi_attribute_t **attributes,
papi_printer_t *printer);
-extern papi_status_t papiPrinterPause(papi_service_t handle, const char *name,
- const char *message);
-extern papi_status_t papiPrinterResume(papi_service_t handle, const char *name);
+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,
- const char *name, papi_job_t **jobs);
+ char *name, papi_job_t **jobs);
extern papi_status_t papiPrinterListJobs(papi_service_t handle,
- const char *name,
- const char **requested_attrs,
- const int type_mask,
- const int max_num_jobs,
+ 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, const char *printer,
- const papi_attribute_t **job_attributes,
- const papi_job_ticket_t *job_ticket,
- const char **files, papi_job_t *job);
+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,
- const char *printer,
- const papi_attribute_t **job_attributes,
- const papi_job_ticket_t *job_ticket,
- const char **files, papi_job_t *job);
-extern 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);
+ 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,
- const char *printer,
- const papi_attribute_t **job_attributes,
- const papi_job_ticket_t *job_ticket,
+ 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,
- const void *buffer,
- const size_t buflen);
+ 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, const char *printer,
- const int32_t job_id,
- const char **requested_attrs,
+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, const char *printer,
- const int32_t job_id,
- const papi_attribute_t **attributes,
+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 papiJobCancel(papi_service_t handle, const char *printer,
- const int32_t job_id);
-extern 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);
-extern papi_status_t papiJobRelease(papi_service_t handle, const char *printer,
- const int32_t job_id);
-extern papi_status_t papiJobRestart(papi_service_t handle, const char *printer,
- const int32_t job_id);
-extern papi_attribute_t **papiJobGetAttributeList(papi_printer_t printer);
-extern char *papiJobGetPrinterName(papi_printer_t printer);
-extern int32_t papiJobGetId(papi_printer_t printer);
-extern papi_job_ticket_t *papiJobGetJobTicket(papi_printer_t printer);
+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_1_0
+#ifdef SOLARIS_PRIVATE_POST_0_9
/*
- * These have been added to support IPP create-job/send-document with PAPI v1.0
+ * 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, const char *printer,
- const papi_attribute_t **job_attributes,
- const papi_job_ticket_t *job_ticket,
+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, papi_job_t job,
- papi_attribute_t **document_attributes,
- papi_stream_t *stream);
-extern papi_status_t papiJobCommit(papi_service_t handle, papi_job_t job);
-#endif /* SOLARIS_PRIVATE_POST_1_0 */
+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(const papi_status_t status);
+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
}
diff --git a/usr/src/cmd/lp/lib/papi/status.c b/usr/src/lib/print/libpapi-common/common/status.c
index 61f6d20739..897aa1322d 100644
--- a/usr/src/cmd/lp/lib/papi/status.c
+++ b/usr/src/lib/print/libpapi-common/common/status.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.
@@ -19,18 +18,19 @@
*
* 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.
+ *
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*LINTLIBRARY*/
+/* $Id: status.c 146 2006-03-24 00:26:54Z njacobs $ */
+#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdlib.h>
-#include <papi_impl.h>
+#include <papi.h>
#include <libintl.h>
char *
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"