xref: /onnv-gate/usr/src/lib/print/libpapi-dynamic/common/printer.c (revision 2792:8027421b19ae)
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 /*
232264Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
242264Sjacobs  * Use is subject to license terms.
252264Sjacobs  *
262264Sjacobs  */
272264Sjacobs 
282264Sjacobs /* $Id: printer.c 151 2006-04-25 16:55:34Z 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 void
papiPrinterFree(papi_printer_t printer)382264Sjacobs papiPrinterFree(papi_printer_t printer)
392264Sjacobs {
402264Sjacobs 	printer_t *tmp = printer;
412264Sjacobs 
422264Sjacobs 	if (tmp != NULL) {
432264Sjacobs 		void (*f)();
442264Sjacobs 
452264Sjacobs 		f = (void (*)())psm_sym(tmp->svc, "papiPrinterFree");
462264Sjacobs 		if (f != NULL)
472264Sjacobs 			f(tmp->printer);
482264Sjacobs 		if (tmp->attributes != NULL)
492264Sjacobs 			papiAttributeListFree(tmp->attributes);
502264Sjacobs 		if (tmp->svc_is_internal != 0)
512264Sjacobs 			papiServiceDestroy(tmp->svc);
522264Sjacobs 		free(tmp);
532264Sjacobs 	}
542264Sjacobs }
552264Sjacobs 
562264Sjacobs void
papiPrinterListFree(papi_printer_t * printers)572264Sjacobs papiPrinterListFree(papi_printer_t *printers)
582264Sjacobs {
592264Sjacobs 	if (printers != NULL) {
602264Sjacobs 		int i;
612264Sjacobs 
622264Sjacobs 		for (i = 0; printers[i] != NULL; i++)
632264Sjacobs 			papiPrinterFree(printers[i]);
642264Sjacobs 		free(printers);
652264Sjacobs 	}
662264Sjacobs }
672264Sjacobs 
682264Sjacobs /* Enumerate a list of printers from the loaded print service. */
692264Sjacobs static papi_status_t
printers_from_service(service_t * svc,char ** requested_attrs,papi_filter_t * filter,papi_printer_t ** printers)702264Sjacobs printers_from_service(service_t *svc, char **requested_attrs,
712264Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
722264Sjacobs {
732264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
742264Sjacobs 	papi_printer_t *svc_printers = NULL;
752264Sjacobs 	papi_status_t (*f)();
762264Sjacobs 
772264Sjacobs 	if ((svc == NULL) || (printers == NULL))
782264Sjacobs 		return (PAPI_BAD_ARGUMENT);
792264Sjacobs 
802264Sjacobs 	/* connect to the service if we are not connected */
812264Sjacobs 	if ((result = service_connect(svc, svc->name)) != PAPI_OK)
822264Sjacobs 		return (result);
832264Sjacobs 
842264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrintersList");
852264Sjacobs 	if (f != NULL)
862264Sjacobs 		result = f(svc->svc_handle, requested_attrs, filter,
872264Sjacobs 				&svc_printers);
882264Sjacobs 
892264Sjacobs 	/*
902264Sjacobs 	 * copy the resulting printer object pointers into our own
912264Sjacobs 	 * representation of a printer object because we need the
922264Sjacobs 	 * service context to operate against the individual printer
932264Sjacobs 	 * objects.  We free the list now because we no longer need
942264Sjacobs 	 * it and would have no way of freeing it later.
952264Sjacobs 	 */
962264Sjacobs 	if ((result == PAPI_OK) && (svc_printers != NULL)) {
972264Sjacobs 		int i;
982264Sjacobs 
992264Sjacobs 		*printers = NULL;
1002264Sjacobs 		for (i = 0; svc_printers[i] != NULL; i++) {
1012264Sjacobs 			printer_t *p = NULL;
1022264Sjacobs 
1032264Sjacobs 			if ((p = calloc(1, sizeof (*p))) == NULL)
1042264Sjacobs 				return (PAPI_TEMPORARY_ERROR);
1052264Sjacobs 
1062264Sjacobs 			p->svc = svc;
1072264Sjacobs 			p->printer = svc_printers[i];
1082264Sjacobs 			list_append(printers, p);
1092264Sjacobs 		}
1102264Sjacobs 		free(svc_printers);
1112264Sjacobs 	}
1122264Sjacobs 
1132264Sjacobs 	return (result);
1142264Sjacobs }
1152264Sjacobs 
1162264Sjacobs /* Get printer attributes from it's print service */
1172264Sjacobs static papi_status_t
printer_from_service(service_t * svc,printer_t * p,char ** requested_attrs)1182264Sjacobs printer_from_service(service_t *svc, printer_t *p, char **requested_attrs)
1192264Sjacobs {
1202264Sjacobs 	papi_status_t result;
1212264Sjacobs 	papi_service_t p_svc = NULL;
1222264Sjacobs 	papi_printer_t printer = NULL;
1232264Sjacobs 	char *psm = NULL;
1242264Sjacobs 	char *uri = NULL;
1252264Sjacobs 
1262264Sjacobs 	/* get the psm and uri from the attributes */
1272264Sjacobs 	papiAttributeListGetString(p->attributes, NULL,
1282264Sjacobs 			"print-service-module", &psm);
1292264Sjacobs 	papiAttributeListGetString(p->attributes, NULL, "printer-name", &uri);
1302264Sjacobs 	papiAttributeListGetString(p->attributes, NULL, "printer-uri-supported",
1312264Sjacobs 			&uri);
1322264Sjacobs 
1332264Sjacobs 	/* contact the service for the printer */
1342264Sjacobs 	result = papiServiceCreate((papi_service_t *)&p_svc, psm, svc->user,
1352264Sjacobs 				svc->password, svc->authCB, svc->encryption,
1362264Sjacobs 				svc->app_data);
1372264Sjacobs 	if (result != PAPI_OK)
1382264Sjacobs 		return (result);
1392264Sjacobs 
1402264Sjacobs 	/* get the printer from the service */
1412264Sjacobs 	result = papiPrinterQuery(p_svc, uri, requested_attrs, NULL, &printer);
1422264Sjacobs 	if (result == PAPI_OK) {
1432264Sjacobs 		papi_attribute_t **attributes;
1442264Sjacobs 
1452264Sjacobs 		attributes = papiPrinterGetAttributeList(printer);
1462264Sjacobs 		copy_attributes(&p->attributes, attributes);
1472264Sjacobs 	}
1482264Sjacobs 	papiPrinterFree(printer);
1492264Sjacobs 	papiServiceDestroy(p_svc);
1502264Sjacobs 
1512264Sjacobs 	return (result);
1522264Sjacobs }
1532264Sjacobs 
1542264Sjacobs /* are the requested attributes contained in the list */
1552264Sjacobs static int
contained(char ** requested,papi_attribute_t ** list)1562264Sjacobs contained(char **requested, papi_attribute_t **list)
1572264Sjacobs {
1582264Sjacobs 	int i;
1592264Sjacobs 
1602264Sjacobs 	if (requested == NULL)	/* we want every possible attribute */
1612264Sjacobs 		return (0);
1622264Sjacobs 
1632264Sjacobs 	for (i = 0; requested[i] != NULL; i++)
1642264Sjacobs 		if (papiAttributeListFind(list, requested[i]) == NULL)
1652264Sjacobs 			return (0);
1662264Sjacobs 
1672264Sjacobs 	return (1);
1682264Sjacobs }
1692264Sjacobs 
1702264Sjacobs /* Enumerate a list of printers from the Name Service */
1712264Sjacobs static papi_status_t
printers_from_name_service(service_t * svc,char ** requested_attrs,papi_filter_t * filter,papi_printer_t ** printers)1722264Sjacobs printers_from_name_service(service_t *svc, char **requested_attrs,
1732264Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
1742264Sjacobs {
1752264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
1762264Sjacobs 	papi_attribute_t **attrs;
1772264Sjacobs 
1782264Sjacobs 	if ((svc == NULL) || (printers == NULL))
1792264Sjacobs 		return (PAPI_BAD_ARGUMENT);
1802264Sjacobs 
1812264Sjacobs 	/* retrieve printers from the nameservice */
182*2792Sjacobs 	setprinterentry(0, NULL);
1832264Sjacobs 	while ((attrs = getprinterentry(NULL)) != NULL) {
1842264Sjacobs 		printer_t *p = NULL;
1852264Sjacobs 
1862264Sjacobs 		if ((p = calloc(1, sizeof (*p))) == NULL)
1872264Sjacobs 			return (PAPI_TEMPORARY_ERROR);
1882264Sjacobs 
1892264Sjacobs 		p->attributes = attrs;
1902264Sjacobs 		list_append(printers, p);
1912264Sjacobs 	}
1922264Sjacobs 
1932264Sjacobs 	/* if we have printers, check if our request has been satisfied */
1942264Sjacobs 	if ((printers != NULL) && (*printers != NULL)) {
1952264Sjacobs 		int i;
1962264Sjacobs 
1972264Sjacobs 		/* walk through the list */
1982264Sjacobs 		for (i = 0; (*printers)[i] != NULL; i++) {
1992264Sjacobs 			printer_t *p = (*printers)[i];
2002264Sjacobs 
2012264Sjacobs 			/* see if the name service satisfied the request */
2022264Sjacobs 			if (contained(requested_attrs, p->attributes) == 0)
2032264Sjacobs 				printer_from_service(svc, p, requested_attrs);
2042264Sjacobs 		}
2052264Sjacobs 	}
2062264Sjacobs 
2072264Sjacobs 	return (PAPI_OK);
2082264Sjacobs }
2092264Sjacobs 
2102264Sjacobs papi_status_t
papiPrintersList(papi_service_t handle,char ** requested_attrs,papi_filter_t * filter,papi_printer_t ** printers)2112264Sjacobs papiPrintersList(papi_service_t handle, char **requested_attrs,
2122264Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
2132264Sjacobs {
2142264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
2152264Sjacobs 	service_t *svc = handle;
2162264Sjacobs 	papi_printer_t *svc_printers = NULL;
2172264Sjacobs 	papi_status_t (*f)();
2182264Sjacobs 
2192264Sjacobs 	if ((svc == NULL) || (printers == NULL))
2202264Sjacobs 		return (PAPI_BAD_ARGUMENT);
2212264Sjacobs 
2222264Sjacobs 	if (svc->so_handle != NULL)	/* connected, use the print svc */
2232264Sjacobs 		result = printers_from_service(svc, requested_attrs,
2242264Sjacobs 					filter, printers);
2252264Sjacobs 	else				/* not connected, use the name svc */
2262264Sjacobs 		result = printers_from_name_service(svc, requested_attrs,
2272264Sjacobs 					filter, printers);
2282264Sjacobs 
2292264Sjacobs 	return (result);
2302264Sjacobs }
2312264Sjacobs 
2322264Sjacobs papi_status_t
papiPrinterQuery(papi_service_t handle,char * name,char ** requested_attrs,papi_attribute_t ** job_attributes,papi_printer_t * printer)2332264Sjacobs papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs,
2342264Sjacobs 		papi_attribute_t **job_attributes, papi_printer_t *printer)
2352264Sjacobs {
2362264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
2372264Sjacobs 	service_t *svc = handle;
2382264Sjacobs 	printer_t *p = NULL;
2392264Sjacobs 	papi_status_t (*f)();
2402264Sjacobs 
2412264Sjacobs 	if ((svc == NULL) || (name == NULL) || (printer == NULL))
2422264Sjacobs 		return (PAPI_BAD_ARGUMENT);
2432264Sjacobs 
2442264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
2452264Sjacobs 		return (result);
2462264Sjacobs 
2472264Sjacobs 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
2482264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
2492264Sjacobs 
2502264Sjacobs 	if ((svc->name != NULL) && (svc->svc_handle != NULL) &&
2512264Sjacobs 	    (svc->uri != NULL)) {
2522264Sjacobs 		p->svc = svc;
2532264Sjacobs 		f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery");
2542264Sjacobs 		if (f != NULL)
2552264Sjacobs 			result = f(svc->svc_handle, svc->name, requested_attrs,
2562264Sjacobs 					job_attributes, &p->printer);
2572264Sjacobs 	} else {
2582264Sjacobs 		setprinterentry(0, NULL);
2592264Sjacobs 		p->attributes = getprinterbyname(name, NULL);
2602264Sjacobs 		if (p->attributes == NULL)
2612264Sjacobs 			result = PAPI_NOT_FOUND;
2622264Sjacobs 		else
2632264Sjacobs 			result = PAPI_OK;
2642264Sjacobs 	}
2652264Sjacobs 
2662264Sjacobs 	return (result);
2672264Sjacobs }
2682264Sjacobs 
2692264Sjacobs static papi_status_t
_papi_printer_disable_or_pause(papi_service_t handle,char * name,char * message,char * function)2702264Sjacobs _papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message,
2712264Sjacobs 		char *function)
2722264Sjacobs {
2732264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
2742264Sjacobs 	service_t *svc = handle;
2752264Sjacobs 	papi_status_t (*f)();
2762264Sjacobs 
2772264Sjacobs 	if ((svc == NULL) || (name == NULL))
2782264Sjacobs 		return (PAPI_BAD_ARGUMENT);
2792264Sjacobs 
2802264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
2812264Sjacobs 		return (result);
2822264Sjacobs 
2832264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, function);
2842264Sjacobs 	if (f != NULL)
2852264Sjacobs 		result = f(svc->svc_handle, svc->name, message);
2862264Sjacobs 
2872264Sjacobs 	return (result);
2882264Sjacobs }
2892264Sjacobs 
2902264Sjacobs static papi_status_t
_papi_printer_enable_or_resume(papi_service_t handle,char * name,char * function)2912264Sjacobs _papi_printer_enable_or_resume(papi_service_t handle, char *name,
2922264Sjacobs 		char *function)
2932264Sjacobs {
2942264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
2952264Sjacobs 	service_t *svc = handle;
2962264Sjacobs 	papi_status_t (*f)();
2972264Sjacobs 
2982264Sjacobs 	if ((svc == NULL) || (name == NULL))
2992264Sjacobs 		return (PAPI_BAD_ARGUMENT);
3002264Sjacobs 
3012264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
3022264Sjacobs 		return (result);
3032264Sjacobs 
3042264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, function);
3052264Sjacobs 	if (f != NULL)
3062264Sjacobs 		result = f(svc->svc_handle, svc->name);
3072264Sjacobs 
3082264Sjacobs 	return (result);
3092264Sjacobs }
3102264Sjacobs 
3112264Sjacobs papi_status_t
papiPrinterDisable(papi_service_t handle,char * name,char * message)3122264Sjacobs papiPrinterDisable(papi_service_t handle, char *name, char *message)
3132264Sjacobs {
3142264Sjacobs 	return (_papi_printer_disable_or_pause(handle, name, message,
3152264Sjacobs 						"papiPrinterDisable"));
3162264Sjacobs }
3172264Sjacobs 
3182264Sjacobs papi_status_t
papiPrinterPause(papi_service_t handle,char * name,char * message)3192264Sjacobs papiPrinterPause(papi_service_t handle, char *name, char *message)
3202264Sjacobs {
3212264Sjacobs 	return (_papi_printer_disable_or_pause(handle, name, message,
3222264Sjacobs 						"papiPrinterPause"));
3232264Sjacobs }
3242264Sjacobs 
3252264Sjacobs papi_status_t
papiPrinterEnable(papi_service_t handle,char * name)3262264Sjacobs papiPrinterEnable(papi_service_t handle, char *name)
3272264Sjacobs {
3282264Sjacobs 	return (_papi_printer_enable_or_resume(handle, name,
3292264Sjacobs 						"papiPrinterEnable"));
3302264Sjacobs }
3312264Sjacobs 
3322264Sjacobs papi_status_t
papiPrinterResume(papi_service_t handle,char * name)3332264Sjacobs papiPrinterResume(papi_service_t handle, char *name)
3342264Sjacobs {
3352264Sjacobs 	return (_papi_printer_enable_or_resume(handle, name,
3362264Sjacobs 						"papiPrinterResume"));
3372264Sjacobs }
3382264Sjacobs 
3392264Sjacobs 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)3402264Sjacobs _papi_printer_add_or_modify(papi_service_t handle, char *name,
3412264Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer,
3422264Sjacobs 		char *function)
3432264Sjacobs {
3442264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
3452264Sjacobs 	service_t *svc = handle;
3462264Sjacobs 	printer_t *p = NULL;
3472264Sjacobs 	papi_status_t (*f)();
3482264Sjacobs 
3492264Sjacobs 	if ((svc == NULL) || (name == NULL) || (attributes == NULL))
3502264Sjacobs 		return (PAPI_BAD_ARGUMENT);
3512264Sjacobs 
3522264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
3532264Sjacobs 		return (result);
3542264Sjacobs 
3552264Sjacobs 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
3562264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
3572264Sjacobs 
3582264Sjacobs 	p->svc = svc;
3592264Sjacobs 	f = (papi_status_t (*)())psm_sym(p->svc, function);
3602264Sjacobs 	if (f != NULL)
3612264Sjacobs 		result = f(svc->svc_handle, svc->name, attributes,
3622264Sjacobs 				&p->printer);
3632264Sjacobs 
3642264Sjacobs 	return (result);
3652264Sjacobs }
3662264Sjacobs 
3672264Sjacobs papi_status_t
papiPrinterAdd(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_printer_t * printer)3682264Sjacobs papiPrinterAdd(papi_service_t handle, char *name,
3692264Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer)
3702264Sjacobs {
3712264Sjacobs 	return (_papi_printer_add_or_modify(handle, name, attributes, printer,
3722264Sjacobs 						"papiPrinterAdd"));
3732264Sjacobs }
3742264Sjacobs 
3752264Sjacobs papi_status_t
papiPrinterModify(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_printer_t * printer)3762264Sjacobs papiPrinterModify(papi_service_t handle, char *name,
3772264Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer)
3782264Sjacobs {
3792264Sjacobs 	return (_papi_printer_add_or_modify(handle, name, attributes, printer,
3802264Sjacobs 						"papiPrinterModify"));
3812264Sjacobs }
3822264Sjacobs 
3832264Sjacobs 
3842264Sjacobs papi_status_t
papiPrinterRemove(papi_service_t handle,char * name)3852264Sjacobs papiPrinterRemove(papi_service_t handle, char *name)
3862264Sjacobs {
3872264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
3882264Sjacobs 	service_t *svc = handle;
3892264Sjacobs 	papi_status_t (*f)();
3902264Sjacobs 
3912264Sjacobs 	if ((svc == NULL) || (name == NULL))
3922264Sjacobs 		return (PAPI_BAD_ARGUMENT);
3932264Sjacobs 
3942264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
3952264Sjacobs 		return (result);
3962264Sjacobs 
3972264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove");
3982264Sjacobs 	if (f != NULL)
3992264Sjacobs 		result = f(svc->svc_handle, svc->name);
4002264Sjacobs 
4012264Sjacobs 	return (result);
4022264Sjacobs }
4032264Sjacobs 
4042264Sjacobs papi_status_t
papiPrinterPurgeJobs(papi_service_t handle,char * name,papi_job_t ** jobs)4052264Sjacobs papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs)
4062264Sjacobs {
4072264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
4082264Sjacobs 	service_t *svc = handle;
4092264Sjacobs 	papi_job_t *svc_jobs = NULL;
4102264Sjacobs 	papi_status_t (*f)();
4112264Sjacobs 
4122264Sjacobs 	if ((svc == NULL) || (name == NULL))
4132264Sjacobs 		return (PAPI_BAD_ARGUMENT);
4142264Sjacobs 
4152264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
4162264Sjacobs 		return (result);
4172264Sjacobs 
4182264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs");
4192264Sjacobs 	if (f != NULL)
4202264Sjacobs 		result = f(svc->svc_handle, svc->name, &svc_jobs);
4212264Sjacobs 
4222264Sjacobs 	/*
4232264Sjacobs 	 * copy the resulting job object pointers into our own
4242264Sjacobs 	 * representation of a job object because we need the
4252264Sjacobs 	 * service context to operate against the individual job
4262264Sjacobs 	 * objects.  We free the list now because we no longer need
4272264Sjacobs 	 * it and would have no way of freeing it later.
4282264Sjacobs 	 */
4292264Sjacobs 	if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) {
4302264Sjacobs 		int i;
4312264Sjacobs 
4322264Sjacobs 		*jobs = NULL;
4332264Sjacobs 		for (i = 0; svc_jobs[i] != NULL; i++) {
4342264Sjacobs 			job_t *j = NULL;
4352264Sjacobs 
4362264Sjacobs 			if ((j = calloc(1, sizeof (*j))) == NULL)
4372264Sjacobs 				return (PAPI_TEMPORARY_ERROR);
4382264Sjacobs 
4392264Sjacobs 			j->svc = svc;
4402264Sjacobs 			j->job = svc_jobs[i];
4412264Sjacobs 			list_append(jobs, j);
4422264Sjacobs 		}
4432264Sjacobs 		free(svc_jobs);
4442264Sjacobs 	}
4452264Sjacobs 
4462264Sjacobs 	return (result);
4472264Sjacobs }
4482264Sjacobs 
4492264Sjacobs papi_status_t
papiPrinterListJobs(papi_service_t handle,char * name,char ** requested_attrs,int type_mask,int max_num_jobs,papi_job_t ** jobs)4502264Sjacobs papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs,
4512264Sjacobs 		int type_mask, int max_num_jobs, papi_job_t **jobs)
4522264Sjacobs {
4532264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
4542264Sjacobs 	service_t *svc = handle;
4552264Sjacobs 	papi_job_t *svc_jobs = NULL;
4562264Sjacobs 	papi_status_t (*f)();
4572264Sjacobs 
4582264Sjacobs 	if ((svc == NULL) || (name == NULL) || (jobs == NULL))
4592264Sjacobs 		return (PAPI_BAD_ARGUMENT);
4602264Sjacobs 
4612264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
4622264Sjacobs 		return (result);
4632264Sjacobs 
4642264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs");
4652264Sjacobs 	if (f != NULL)
4662264Sjacobs 		result = f(svc->svc_handle, svc->name, requested_attrs,
4672264Sjacobs 				type_mask, max_num_jobs, &svc_jobs);
4682264Sjacobs 
4692264Sjacobs 	/*
4702264Sjacobs 	 * copy the resulting job object pointers into our own
4712264Sjacobs 	 * representation of a job object because we need the
4722264Sjacobs 	 * service context to operate against the individual job
4732264Sjacobs 	 * objects.  We free the list now because we no longer need
4742264Sjacobs 	 * it and would have no way of freeing it later.
4752264Sjacobs 	 */
4762264Sjacobs 	if ((result == PAPI_OK) && (svc_jobs != NULL)) {
4772264Sjacobs 		int i;
4782264Sjacobs 
4792264Sjacobs 		*jobs = NULL;
4802264Sjacobs 		for (i = 0; svc_jobs[i] != NULL; i++) {
4812264Sjacobs 			job_t *j = NULL;
4822264Sjacobs 
4832264Sjacobs 			if ((j = calloc(1, sizeof (*j))) == NULL)
4842264Sjacobs 				return (PAPI_TEMPORARY_ERROR);
4852264Sjacobs 
4862264Sjacobs 			j->svc = svc;
4872264Sjacobs 			j->job = svc_jobs[i];
4882264Sjacobs 			list_append(jobs, j);
4892264Sjacobs 		}
4902264Sjacobs 		free(svc_jobs);
4912264Sjacobs 	}
4922264Sjacobs 
4932264Sjacobs 	return (result);
4942264Sjacobs }
4952264Sjacobs 
4962264Sjacobs papi_attribute_t **
papiPrinterGetAttributeList(papi_printer_t printer)4972264Sjacobs papiPrinterGetAttributeList(papi_printer_t printer)
4982264Sjacobs {
4992264Sjacobs 	papi_attribute_t **result = NULL;
5002264Sjacobs 	printer_t *p = printer;
5012264Sjacobs 
5022264Sjacobs 	if ((p != NULL) && (p->printer != NULL)) {
5032264Sjacobs 		papi_attribute_t **(*f)();
5042264Sjacobs 
5052264Sjacobs 		f = (papi_attribute_t **(*)())psm_sym(p->svc,
5062264Sjacobs 					"papiPrinterGetAttributeList");
5072264Sjacobs 		if (f != NULL)
5082264Sjacobs 			result = f(p->printer);
5092264Sjacobs 	} else
5102264Sjacobs 		result = p->attributes;
5112264Sjacobs 
5122264Sjacobs 	return (result);
5132264Sjacobs }
514