summaryrefslogtreecommitdiff
path: root/usr/src/lib/print/libpapi-dynamic
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/print/libpapi-dynamic')
-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
11 files changed, 2552 insertions, 0 deletions
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)