/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: 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 */
setprinterentry(0, NULL);
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);
}