xref: /onnv-gate/usr/src/lib/print/libpapi-ipp/common/printer.c (revision 3917:9e19a8d4a355)
12264Sjacobs /*
22264Sjacobs  * CDDL HEADER START
32264Sjacobs  *
42264Sjacobs  * The contents of this file are subject to the terms of the
52264Sjacobs  * Common Development and Distribution License (the "License").
62264Sjacobs  * You may not use this file except in compliance with the License.
72264Sjacobs  *
82264Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92264Sjacobs  * or http://www.opensolaris.org/os/licensing.
102264Sjacobs  * See the License for the specific language governing permissions
112264Sjacobs  * and limitations under the License.
122264Sjacobs  *
132264Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
142264Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152264Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
162264Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
172264Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
182264Sjacobs  *
192264Sjacobs  * CDDL HEADER END
202264Sjacobs  */
212264Sjacobs 
222264Sjacobs /*
23*3917Sjacobs  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
242264Sjacobs  * Use is subject to license terms.
252264Sjacobs  *
262264Sjacobs  */
272264Sjacobs 
282264Sjacobs /* $Id: printer.c 146 2006-03-24 00:26:54Z njacobs $ */
292264Sjacobs 
302264Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
312264Sjacobs 
322264Sjacobs /*LINTLIBRARY*/
332264Sjacobs 
342264Sjacobs #include <stdlib.h>
352264Sjacobs #include <papi_impl.h>
362264Sjacobs 
372264Sjacobs #include <config-site.h>
382264Sjacobs 
392264Sjacobs void
papiPrinterFree(papi_printer_t printer)402264Sjacobs papiPrinterFree(papi_printer_t printer)
412264Sjacobs {
422264Sjacobs 	printer_t *tmp = printer;
432264Sjacobs 
442264Sjacobs 	if (tmp != NULL) {
452264Sjacobs 		if (tmp->attributes != NULL)
462264Sjacobs 			papiAttributeListFree(tmp->attributes);
472264Sjacobs 		free(tmp);
482264Sjacobs 	}
492264Sjacobs }
502264Sjacobs 
512264Sjacobs void
papiPrinterListFree(papi_printer_t * printers)522264Sjacobs papiPrinterListFree(papi_printer_t *printers)
532264Sjacobs {
542264Sjacobs 	if (printers != NULL) {
552264Sjacobs 		int i;
562264Sjacobs 
572264Sjacobs 		for (i = 0; printers[i] != NULL; i++)
582264Sjacobs 			papiPrinterFree(printers[i]);
592264Sjacobs 		free(printers);
602264Sjacobs 	}
612264Sjacobs }
622264Sjacobs 
632264Sjacobs /*
642264Sjacobs  * Enumeration of printers is not part of the IPP specification, so many
652264Sjacobs  * servers will probably not respond back with a list of printers, but
662264Sjacobs  * CUPS has implemented an extension to IPP to enumerate printers and
672264Sjacobs  * classes. the Apache/mod_ipp IPP listener module available in Solaris
682264Sjacobs  * implements this IPP extension, so CUPS and Solaris can provide this
692264Sjacobs  * to IPP clients.
702264Sjacobs  */
712264Sjacobs #ifndef	OPID_CUPS_GET_PRINTERS		/* for servers that will enumerate */
722264Sjacobs #define	OPID_CUPS_GET_PRINTERS		0x4002
732264Sjacobs #endif	/* OPID_CUPS_GET_PRINTERS */
742264Sjacobs #ifndef	OPID_CUPS_DELETE_PRINTER	/* for servers that can delete */
752264Sjacobs #define	OPID_CUPS_DELETE_PRINTER	0x4004
762264Sjacobs #endif	/* OPID_CUPS_DELETE_PRINTER */
772264Sjacobs #ifndef	OPID_CUPS_GET_CLASSES		/* for servers that will enumerate */
782264Sjacobs #define	OPID_CUPS_GET_CLASSES		0x4005
792264Sjacobs #endif	/* OPID_CUPS_GET_CLASSES */
802264Sjacobs 
812264Sjacobs papi_status_t
papiPrintersList(papi_service_t handle,char ** requested_attrs,papi_filter_t * filter,papi_printer_t ** printers)822264Sjacobs papiPrintersList(papi_service_t handle, char **requested_attrs,
832264Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
842264Sjacobs {
852264Sjacobs 	papi_status_t status, result = PAPI_INTERNAL_ERROR;
862264Sjacobs 	service_t *svc = handle;
872264Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
882264Sjacobs 	void *iter = NULL;
892264Sjacobs 
902264Sjacobs 	if ((svc == NULL) || (printers == NULL))
912264Sjacobs 		return (PAPI_BAD_ARGUMENT);
922264Sjacobs 
932264Sjacobs 	/* if we are already connected, use that connection. */
942264Sjacobs 	if (svc->connection == NULL)
952264Sjacobs 		if ((result = service_connect(svc, DEFAULT_DEST)) != PAPI_OK)
962264Sjacobs 			return (result);
972264Sjacobs 	ipp_initialize_request(svc, &request, OPID_CUPS_GET_PRINTERS);
982264Sjacobs 
99*3917Sjacobs 	ipp_initialize_operational_attributes(svc, &op, NULL, -1);
1002264Sjacobs 
1012264Sjacobs 	if (requested_attrs != NULL) {
1022264Sjacobs 		int i;
1032264Sjacobs 
1042264Sjacobs 		for (i = 0; requested_attrs[i] != NULL; i++)
1052264Sjacobs 			papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
1062264Sjacobs 				"requested-attributes", requested_attrs[i]);
1072264Sjacobs 	}
1082264Sjacobs 
1092264Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
1102264Sjacobs 			"operational-attributes-group", op);
1112264Sjacobs 	papiAttributeListFree(op);
1122264Sjacobs 	result = ipp_send_request(svc, request, &response);
1132264Sjacobs 	papiAttributeListFree(request);
1142264Sjacobs 
1152264Sjacobs 	op = NULL;
1162264Sjacobs 	for (status = papiAttributeListGetCollection(response, &iter,
1172264Sjacobs 				"printer-attributes-group", &op);
1182264Sjacobs 	     status == PAPI_OK;
1192264Sjacobs 	     status = papiAttributeListGetCollection(response, &iter,
1202264Sjacobs 				NULL, &op)) {
1212264Sjacobs 		printer_t *p = NULL;
1222264Sjacobs 
1232264Sjacobs 		if ((p = calloc(1, sizeof (*p))) == NULL)
1242264Sjacobs 			return (PAPI_TEMPORARY_ERROR);
1252264Sjacobs 
1262264Sjacobs 		copy_attributes(&p->attributes, op);
1272264Sjacobs 		op = NULL;
1282264Sjacobs 		list_append(printers, p);
1292264Sjacobs 	}
1302264Sjacobs 	papiAttributeListFree(response);
1312264Sjacobs 
1322264Sjacobs 	return (result);
1332264Sjacobs }
1342264Sjacobs 
1352264Sjacobs papi_status_t
papiPrinterQuery(papi_service_t handle,char * name,char ** requested_attrs,papi_attribute_t ** job_attributes,papi_printer_t * printer)1362264Sjacobs papiPrinterQuery(papi_service_t handle, char *name,
1372264Sjacobs 		char **requested_attrs,
1382264Sjacobs 		papi_attribute_t **job_attributes,
1392264Sjacobs 		papi_printer_t *printer)
1402264Sjacobs {
1412264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
1422264Sjacobs 	service_t *svc = handle;
1432264Sjacobs 	printer_t *p = NULL;
1442264Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
1452264Sjacobs 
1462264Sjacobs 	if ((svc == NULL) || (name == NULL) || (printer == NULL))
1472264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1482264Sjacobs 
1492264Sjacobs 	/* if we are already connected, use that connection. */
1502264Sjacobs 	if (svc->connection == NULL)
1512264Sjacobs 		if ((result = service_connect(svc, name)) != PAPI_OK)
1522264Sjacobs 			return (result);
1532264Sjacobs 
1542264Sjacobs 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
1552264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
1562264Sjacobs 
1572264Sjacobs 	ipp_initialize_request(svc, &request, OPID_GET_PRINTER_ATTRIBUTES);
1582264Sjacobs 
159*3917Sjacobs 	ipp_initialize_operational_attributes(svc, &op, name, -1);
1602264Sjacobs 
1612264Sjacobs 	if (requested_attrs != NULL) {
1622264Sjacobs 		int i;
1632264Sjacobs 
1642264Sjacobs 		for (i = 0; requested_attrs[i] != NULL; i++)
1652264Sjacobs 			papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
1662264Sjacobs 				"requested-attributes", requested_attrs[i]);
1672264Sjacobs 	}
1682264Sjacobs 
1692264Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
1702264Sjacobs 			"operational-attributes-group", op);
1712264Sjacobs 	papiAttributeListFree(op);
1722264Sjacobs 	result = ipp_send_request(svc, request, &response);
1732264Sjacobs 	papiAttributeListFree(request);
1742264Sjacobs 
1752264Sjacobs 	op = NULL;
1762264Sjacobs 	papiAttributeListGetCollection(response, NULL,
1772264Sjacobs 			"printer-attributes-group", &op);
1782264Sjacobs 	copy_attributes(&p->attributes, op);
1792264Sjacobs 	papiAttributeListFree(response);
1802264Sjacobs 
1812264Sjacobs 	return (result);
1822264Sjacobs }
1832264Sjacobs 
1842264Sjacobs static papi_status_t
_printer_enable_disable_pause_resume_delete(papi_service_t handle,char * name,char * message,uint16_t type)1852264Sjacobs _printer_enable_disable_pause_resume_delete(papi_service_t handle, char *name,
1862264Sjacobs 		char *message, uint16_t type)
1872264Sjacobs {
1882264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
1892264Sjacobs 	service_t *svc = handle;
1902264Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
1912264Sjacobs 
1922264Sjacobs 	if ((svc == NULL) || (name == NULL))
1932264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1942264Sjacobs 
1952264Sjacobs 	/* if we are already connected, use that connection. */
1962264Sjacobs 	if (svc->connection == NULL)
1972264Sjacobs 		if ((result = service_connect(svc, name)) != PAPI_OK)
1982264Sjacobs 			return (result);
1992264Sjacobs 
2002264Sjacobs 	ipp_initialize_request(svc, &request, type);
2012264Sjacobs 
202*3917Sjacobs 	ipp_initialize_operational_attributes(svc, &op, name, -1);
2032264Sjacobs 
2042264Sjacobs 	switch (type) {
2052264Sjacobs 	case OPID_DISABLE_PRINTER:
2062264Sjacobs 		papiAttributeListAddString(&op, PAPI_ATTR_REPLACE,
2072264Sjacobs 				"printer-message-from-operator", message);
2082264Sjacobs 		break;
2092264Sjacobs 	case OPID_PAUSE_PRINTER:
2102264Sjacobs 		papiAttributeListAddString(&op, PAPI_ATTR_REPLACE,
2112264Sjacobs 				"printer-state-message", message);
2122264Sjacobs 		break;
2132264Sjacobs 	default: /* a message value is of no use */
2142264Sjacobs 		break;
2152264Sjacobs 	}
2162264Sjacobs 
2172264Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
2182264Sjacobs 			"operational-attributes-group", op);
2192264Sjacobs 	papiAttributeListFree(op);
2202264Sjacobs 	result = ipp_send_request(svc, request, &response);
2212264Sjacobs 	papiAttributeListFree(request);
2222264Sjacobs 	papiAttributeListFree(response);
2232264Sjacobs 
2242264Sjacobs 	return (result);
2252264Sjacobs }
2262264Sjacobs 
2272264Sjacobs papi_status_t
papiPrinterEnable(papi_service_t handle,char * name)2282264Sjacobs papiPrinterEnable(papi_service_t handle, char *name)
2292264Sjacobs {
2302264Sjacobs 	return (_printer_enable_disable_pause_resume_delete(handle, name,
2312264Sjacobs 				NULL, OPID_ENABLE_PRINTER));
2322264Sjacobs }
2332264Sjacobs 
2342264Sjacobs papi_status_t
papiPrinterResume(papi_service_t handle,char * name)2352264Sjacobs papiPrinterResume(papi_service_t handle, char *name)
2362264Sjacobs {
2372264Sjacobs 	return (_printer_enable_disable_pause_resume_delete(handle, name,
2382264Sjacobs 				NULL, OPID_RESUME_PRINTER));
2392264Sjacobs }
2402264Sjacobs 
2412264Sjacobs papi_status_t
papiPrinterPause(papi_service_t handle,char * name,char * message)2422264Sjacobs papiPrinterPause(papi_service_t handle, char *name, char *message)
2432264Sjacobs {
2442264Sjacobs 	return (_printer_enable_disable_pause_resume_delete(handle, name,
2452264Sjacobs 				message, OPID_PAUSE_PRINTER));
2462264Sjacobs }
2472264Sjacobs 
2482264Sjacobs papi_status_t
papiPrinterDisable(papi_service_t handle,char * name,char * message)2492264Sjacobs papiPrinterDisable(papi_service_t handle, char *name, char *message)
2502264Sjacobs {
2512264Sjacobs 	return (_printer_enable_disable_pause_resume_delete(handle, name,
2522264Sjacobs 				message, OPID_PAUSE_PRINTER));
2532264Sjacobs }
2542264Sjacobs 
2552264Sjacobs /*
2562264Sjacobs  * there is no IPP create operation, the set-printer-attibutes operation
2572264Sjacobs  * is the closest we have, so we will assume that the server will create
2582264Sjacobs  * a printer and set attributes if there is none.
2592264Sjacobs  */
2602264Sjacobs papi_status_t
papiPrinterAdd(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_printer_t * printer)2612264Sjacobs papiPrinterAdd(papi_service_t handle, char *name,
2622264Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer)
2632264Sjacobs {
2642264Sjacobs 	return (papiPrinterModify(handle, name, attributes, printer));
2652264Sjacobs }
2662264Sjacobs 
2672264Sjacobs papi_status_t
papiPrinterModify(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_printer_t * printer)2682264Sjacobs papiPrinterModify(papi_service_t handle, char *name,
2692264Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer)
2702264Sjacobs {
2712264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
2722264Sjacobs 	service_t *svc = handle;
2732264Sjacobs 	printer_t *p = NULL;
2742264Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
2752264Sjacobs 
2762264Sjacobs 	if ((svc == NULL) || (name == NULL) || (printer == NULL))
2772264Sjacobs 		return (PAPI_BAD_ARGUMENT);
2782264Sjacobs 
2792264Sjacobs 	/* if we are already connected, use that connection. */
2802264Sjacobs 	if (svc->connection == NULL)
2812264Sjacobs 		if ((result = service_connect(svc, name)) != PAPI_OK)
2822264Sjacobs 			return (result);
2832264Sjacobs 
2842264Sjacobs 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
2852264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
2862264Sjacobs 
2872264Sjacobs 	ipp_initialize_request(svc, &request, OPID_SET_PRINTER_ATTRIBUTES);
2882264Sjacobs 
289*3917Sjacobs 	ipp_initialize_operational_attributes(svc, &op, name, -1);
2902264Sjacobs 
2912264Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
2922264Sjacobs 			"operational-attributes-group", op);
2932264Sjacobs 	papiAttributeListFree(op);
2942264Sjacobs 
2952264Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
2962264Sjacobs 			"printer-attributes-group", attributes);
2972264Sjacobs 	result = ipp_send_request(svc, request, &response);
2982264Sjacobs 	papiAttributeListFree(request);
2992264Sjacobs 
3002264Sjacobs 	op = NULL;
3012264Sjacobs 	papiAttributeListGetCollection(response, NULL,
3022264Sjacobs 			"printer-attributes-group", &op);
3032264Sjacobs 	copy_attributes(&p->attributes, op);
3042264Sjacobs 	papiAttributeListFree(response);
3052264Sjacobs 
3062264Sjacobs 	return (result);
3072264Sjacobs }
3082264Sjacobs 
3092264Sjacobs papi_status_t
papiPrinterRemove(papi_service_t handle,char * name)3102264Sjacobs papiPrinterRemove(papi_service_t handle, char *name)
3112264Sjacobs {
3122264Sjacobs 	return (_printer_enable_disable_pause_resume_delete(handle, name,
3132264Sjacobs 				NULL, OPID_CUPS_DELETE_PRINTER));
3142264Sjacobs }
3152264Sjacobs 
3162264Sjacobs papi_status_t
papiPrinterPurgeJobs(papi_service_t handle,char * name,papi_job_t ** jobs)3172264Sjacobs papiPrinterPurgeJobs(papi_service_t handle, char *name,
3182264Sjacobs 		papi_job_t **jobs)
3192264Sjacobs {
3202264Sjacobs 	papi_status_t status, result = PAPI_INTERNAL_ERROR;
3212264Sjacobs 	service_t *svc = handle;
3222264Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
3232264Sjacobs 	void *iter = NULL;
3242264Sjacobs 
3252264Sjacobs 
3262264Sjacobs 	if ((svc == NULL) || (name == NULL))
3272264Sjacobs 		return (PAPI_BAD_ARGUMENT);
3282264Sjacobs 
3292264Sjacobs 	/* if we are already connected, use that connection. */
3302264Sjacobs 	if (svc->connection == NULL)
3312264Sjacobs 		if ((result = service_connect(svc, name)) != PAPI_OK)
3322264Sjacobs 			return (result);
3332264Sjacobs 
3342264Sjacobs 	ipp_initialize_request(svc, &request, OPID_PURGE_JOBS);
3352264Sjacobs 
336*3917Sjacobs 	ipp_initialize_operational_attributes(svc, &op, name, -1);
3372264Sjacobs 
3382264Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
3392264Sjacobs 			"operational-attributes-group", op);
3402264Sjacobs 	papiAttributeListFree(op);
3412264Sjacobs 	result = ipp_send_request(svc, request, &response);
3422264Sjacobs 	papiAttributeListFree(request);
3432264Sjacobs 
3442264Sjacobs 	op = NULL;
3452264Sjacobs 	for (status = papiAttributeListGetCollection(response, &iter,
3462264Sjacobs 				"job-attributes-group", &op);
3472264Sjacobs 	     status == PAPI_OK;
3482264Sjacobs 	     status = papiAttributeListGetCollection(response, &iter,
3492264Sjacobs 				NULL, &op)) {
3502264Sjacobs 		job_t *j = NULL;
3512264Sjacobs 
3522264Sjacobs 		if ((j = calloc(1, sizeof (*j))) == NULL)
3532264Sjacobs 			return (PAPI_TEMPORARY_ERROR);
3542264Sjacobs 
3552264Sjacobs 		copy_attributes(&j->attributes, op);
3562264Sjacobs 		op = NULL;
3572264Sjacobs 		list_append(jobs, j);
3582264Sjacobs 	}
3592264Sjacobs 	papiAttributeListFree(response);
3602264Sjacobs 
3612264Sjacobs 	return (result);
3622264Sjacobs }
3632264Sjacobs 
3642264Sjacobs papi_status_t
papiPrinterListJobs(papi_service_t handle,char * name,char ** requested_attrs,int type_mask,int max_num_jobs,papi_job_t ** jobs)3652264Sjacobs papiPrinterListJobs(papi_service_t handle, char *name,
3662264Sjacobs 		char **requested_attrs, int type_mask,
3672264Sjacobs 		int max_num_jobs, papi_job_t **jobs)
3682264Sjacobs {
3692264Sjacobs 	papi_status_t status, result = PAPI_INTERNAL_ERROR;
3702264Sjacobs 	service_t *svc = handle;
3712264Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
3722264Sjacobs 	void *iter = NULL;
3732264Sjacobs 
3742264Sjacobs 	if ((svc == NULL) || (name == NULL))
3752264Sjacobs 		return (PAPI_BAD_ARGUMENT);
3762264Sjacobs 
3772264Sjacobs 	/* if we are already connected, use that connection. */
3782264Sjacobs 	if (svc->connection == NULL)
3792264Sjacobs 		if ((result = service_connect(svc, name)) != PAPI_OK)
3802264Sjacobs 			return (result);
3812264Sjacobs 
3822264Sjacobs 	ipp_initialize_request(svc, &request, OPID_GET_JOBS);
3832264Sjacobs 
384*3917Sjacobs 	ipp_initialize_operational_attributes(svc, &op, name, -1);
3852264Sjacobs 
3862264Sjacobs 	if (requested_attrs != NULL) {
3872264Sjacobs 		int i;
3882264Sjacobs 
3892264Sjacobs 		for (i = 0; requested_attrs[i] != NULL; i++)
3902264Sjacobs 			papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
3912264Sjacobs 				"requested-attributes", requested_attrs[i]);
3922264Sjacobs 	}
3932264Sjacobs 
3942264Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
3952264Sjacobs 			"operational-attributes-group", op);
3962264Sjacobs 	papiAttributeListFree(op);
3972264Sjacobs 	result = ipp_send_request(svc, request, &response);
3982264Sjacobs 	papiAttributeListFree(request);
3992264Sjacobs 
4002264Sjacobs 	op = NULL;
4012264Sjacobs 	for (status = papiAttributeListGetCollection(response, &iter,
4022264Sjacobs 				"job-attributes-group", &op);
4032264Sjacobs 	     status == PAPI_OK;
4042264Sjacobs 	     status = papiAttributeListGetCollection(response, &iter,
4052264Sjacobs 				NULL, &op)) {
4062264Sjacobs 		job_t *j = NULL;
4072264Sjacobs 
4082264Sjacobs 		if ((j = calloc(1, sizeof (*j))) == NULL)
4092264Sjacobs 			return (PAPI_TEMPORARY_ERROR);
4102264Sjacobs 
4112264Sjacobs 		copy_attributes(&j->attributes, op);
4122264Sjacobs 		op = NULL;
4132264Sjacobs 		list_append(jobs, j);
4142264Sjacobs 	}
4152264Sjacobs 	papiAttributeListFree(response);
4162264Sjacobs 
4172264Sjacobs 	return (result);
4182264Sjacobs }
4192264Sjacobs 
4202264Sjacobs papi_attribute_t **
papiPrinterGetAttributeList(papi_printer_t printer)4212264Sjacobs papiPrinterGetAttributeList(papi_printer_t printer)
4222264Sjacobs {
4232264Sjacobs 	papi_attribute_t **result = NULL;
4242264Sjacobs 	printer_t *p = printer;
4252264Sjacobs 
4262264Sjacobs 	if (p != NULL)
4272264Sjacobs 		result = p->attributes;
4282264Sjacobs 
4292264Sjacobs 	return (result);
4302264Sjacobs }
431