xref: /illumos-gate/usr/src/lib/print/libpapi-dynamic/common/printer.c (revision b51e021de072d76292addb44467f777617c6a8c1)
1355b4669Sjacobs /*
2355b4669Sjacobs  * CDDL HEADER START
3355b4669Sjacobs  *
4355b4669Sjacobs  * The contents of this file are subject to the terms of the
5355b4669Sjacobs  * Common Development and Distribution License (the "License").
6355b4669Sjacobs  * You may not use this file except in compliance with the License.
7355b4669Sjacobs  *
8355b4669Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9355b4669Sjacobs  * or http://www.opensolaris.org/os/licensing.
10355b4669Sjacobs  * See the License for the specific language governing permissions
11355b4669Sjacobs  * and limitations under the License.
12355b4669Sjacobs  *
13355b4669Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14355b4669Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15355b4669Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16355b4669Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17355b4669Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18355b4669Sjacobs  *
19355b4669Sjacobs  * CDDL HEADER END
20355b4669Sjacobs  */
21355b4669Sjacobs 
22355b4669Sjacobs /*
23355b4669Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24355b4669Sjacobs  * Use is subject to license terms.
25355b4669Sjacobs  *
26355b4669Sjacobs  */
27355b4669Sjacobs 
28355b4669Sjacobs /* $Id: printer.c 151 2006-04-25 16:55:34Z njacobs $ */
29355b4669Sjacobs 
30355b4669Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
31355b4669Sjacobs 
32355b4669Sjacobs /*LINTLIBRARY*/
33355b4669Sjacobs 
34355b4669Sjacobs #include <stdlib.h>
35355b4669Sjacobs #include <papi_impl.h>
36355b4669Sjacobs 
37355b4669Sjacobs void
38355b4669Sjacobs papiPrinterFree(papi_printer_t printer)
39355b4669Sjacobs {
40355b4669Sjacobs 	printer_t *tmp = printer;
41355b4669Sjacobs 
42355b4669Sjacobs 	if (tmp != NULL) {
43355b4669Sjacobs 		void (*f)();
44355b4669Sjacobs 
45355b4669Sjacobs 		f = (void (*)())psm_sym(tmp->svc, "papiPrinterFree");
46355b4669Sjacobs 		if (f != NULL)
47355b4669Sjacobs 			f(tmp->printer);
48355b4669Sjacobs 		if (tmp->attributes != NULL)
49355b4669Sjacobs 			papiAttributeListFree(tmp->attributes);
50355b4669Sjacobs 		if (tmp->svc_is_internal != 0)
51355b4669Sjacobs 			papiServiceDestroy(tmp->svc);
52355b4669Sjacobs 		free(tmp);
53355b4669Sjacobs 	}
54355b4669Sjacobs }
55355b4669Sjacobs 
56355b4669Sjacobs void
57355b4669Sjacobs papiPrinterListFree(papi_printer_t *printers)
58355b4669Sjacobs {
59355b4669Sjacobs 	if (printers != NULL) {
60355b4669Sjacobs 		int i;
61355b4669Sjacobs 
62355b4669Sjacobs 		for (i = 0; printers[i] != NULL; i++)
63355b4669Sjacobs 			papiPrinterFree(printers[i]);
64355b4669Sjacobs 		free(printers);
65355b4669Sjacobs 	}
66355b4669Sjacobs }
67355b4669Sjacobs 
68355b4669Sjacobs /* Enumerate a list of printers from the loaded print service. */
69355b4669Sjacobs static papi_status_t
70355b4669Sjacobs printers_from_service(service_t *svc, char **requested_attrs,
71355b4669Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
72355b4669Sjacobs {
73355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
74355b4669Sjacobs 	papi_printer_t *svc_printers = NULL;
75355b4669Sjacobs 	papi_status_t (*f)();
76355b4669Sjacobs 
77355b4669Sjacobs 	if ((svc == NULL) || (printers == NULL))
78355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
79355b4669Sjacobs 
80355b4669Sjacobs 	/* connect to the service if we are not connected */
81355b4669Sjacobs 	if ((result = service_connect(svc, svc->name)) != PAPI_OK)
82355b4669Sjacobs 		return (result);
83355b4669Sjacobs 
84355b4669Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrintersList");
85355b4669Sjacobs 	if (f != NULL)
86355b4669Sjacobs 		result = f(svc->svc_handle, requested_attrs, filter,
87355b4669Sjacobs 				&svc_printers);
88355b4669Sjacobs 
89355b4669Sjacobs 	/*
90355b4669Sjacobs 	 * copy the resulting printer object pointers into our own
91355b4669Sjacobs 	 * representation of a printer object because we need the
92355b4669Sjacobs 	 * service context to operate against the individual printer
93355b4669Sjacobs 	 * objects.  We free the list now because we no longer need
94355b4669Sjacobs 	 * it and would have no way of freeing it later.
95355b4669Sjacobs 	 */
96355b4669Sjacobs 	if ((result == PAPI_OK) && (svc_printers != NULL)) {
97355b4669Sjacobs 		int i;
98355b4669Sjacobs 
99355b4669Sjacobs 		*printers = NULL;
100355b4669Sjacobs 		for (i = 0; svc_printers[i] != NULL; i++) {
101355b4669Sjacobs 			printer_t *p = NULL;
102355b4669Sjacobs 
103355b4669Sjacobs 			if ((p = calloc(1, sizeof (*p))) == NULL)
104355b4669Sjacobs 				return (PAPI_TEMPORARY_ERROR);
105355b4669Sjacobs 
106355b4669Sjacobs 			p->svc = svc;
107355b4669Sjacobs 			p->printer = svc_printers[i];
108355b4669Sjacobs 			list_append(printers, p);
109355b4669Sjacobs 		}
110355b4669Sjacobs 		free(svc_printers);
111355b4669Sjacobs 	}
112355b4669Sjacobs 
113355b4669Sjacobs 	return (result);
114355b4669Sjacobs }
115355b4669Sjacobs 
116355b4669Sjacobs /* Get printer attributes from it's print service */
117355b4669Sjacobs static papi_status_t
118355b4669Sjacobs printer_from_service(service_t *svc, printer_t *p, char **requested_attrs)
119355b4669Sjacobs {
120355b4669Sjacobs 	papi_status_t result;
121355b4669Sjacobs 	papi_service_t p_svc = NULL;
122355b4669Sjacobs 	papi_printer_t printer = NULL;
123355b4669Sjacobs 	char *psm = NULL;
124355b4669Sjacobs 	char *uri = NULL;
125355b4669Sjacobs 
126355b4669Sjacobs 	/* get the psm and uri from the attributes */
127355b4669Sjacobs 	papiAttributeListGetString(p->attributes, NULL,
128355b4669Sjacobs 			"print-service-module", &psm);
129355b4669Sjacobs 	papiAttributeListGetString(p->attributes, NULL, "printer-name", &uri);
130355b4669Sjacobs 	papiAttributeListGetString(p->attributes, NULL, "printer-uri-supported",
131355b4669Sjacobs 			&uri);
132355b4669Sjacobs 
133355b4669Sjacobs 	/* contact the service for the printer */
134355b4669Sjacobs 	result = papiServiceCreate((papi_service_t *)&p_svc, psm, svc->user,
135355b4669Sjacobs 				svc->password, svc->authCB, svc->encryption,
136355b4669Sjacobs 				svc->app_data);
137355b4669Sjacobs 	if (result != PAPI_OK)
138355b4669Sjacobs 		return (result);
139355b4669Sjacobs 
140355b4669Sjacobs 	/* get the printer from the service */
141355b4669Sjacobs 	result = papiPrinterQuery(p_svc, uri, requested_attrs, NULL, &printer);
142355b4669Sjacobs 	if (result == PAPI_OK) {
143355b4669Sjacobs 		papi_attribute_t **attributes;
144355b4669Sjacobs 
145355b4669Sjacobs 		attributes = papiPrinterGetAttributeList(printer);
146355b4669Sjacobs 		copy_attributes(&p->attributes, attributes);
147355b4669Sjacobs 	}
148355b4669Sjacobs 	papiPrinterFree(printer);
149355b4669Sjacobs 	papiServiceDestroy(p_svc);
150355b4669Sjacobs 
151355b4669Sjacobs 	return (result);
152355b4669Sjacobs }
153355b4669Sjacobs 
154355b4669Sjacobs /* are the requested attributes contained in the list */
155355b4669Sjacobs static int
156355b4669Sjacobs contained(char **requested, papi_attribute_t **list)
157355b4669Sjacobs {
158355b4669Sjacobs 	int i;
159355b4669Sjacobs 
160355b4669Sjacobs 	if (requested == NULL)	/* we want every possible attribute */
161355b4669Sjacobs 		return (0);
162355b4669Sjacobs 
163355b4669Sjacobs 	for (i = 0; requested[i] != NULL; i++)
164355b4669Sjacobs 		if (papiAttributeListFind(list, requested[i]) == NULL)
165355b4669Sjacobs 			return (0);
166355b4669Sjacobs 
167355b4669Sjacobs 	return (1);
168355b4669Sjacobs }
169355b4669Sjacobs 
170355b4669Sjacobs /* Enumerate a list of printers from the Name Service */
171355b4669Sjacobs static papi_status_t
172355b4669Sjacobs printers_from_name_service(service_t *svc, char **requested_attrs,
173355b4669Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
174355b4669Sjacobs {
175355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
176355b4669Sjacobs 	papi_attribute_t **attrs;
177355b4669Sjacobs 
178355b4669Sjacobs 	if ((svc == NULL) || (printers == NULL))
179355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
180355b4669Sjacobs 
181355b4669Sjacobs 	/* retrieve printers from the nameservice */
182*b51e021dSjacobs 	setprinterentry(0, NULL);
183355b4669Sjacobs 	while ((attrs = getprinterentry(NULL)) != NULL) {
184355b4669Sjacobs 		printer_t *p = NULL;
185355b4669Sjacobs 
186355b4669Sjacobs 		if ((p = calloc(1, sizeof (*p))) == NULL)
187355b4669Sjacobs 			return (PAPI_TEMPORARY_ERROR);
188355b4669Sjacobs 
189355b4669Sjacobs 		p->attributes = attrs;
190355b4669Sjacobs 		list_append(printers, p);
191355b4669Sjacobs 	}
192355b4669Sjacobs 
193355b4669Sjacobs 	/* if we have printers, check if our request has been satisfied */
194355b4669Sjacobs 	if ((printers != NULL) && (*printers != NULL)) {
195355b4669Sjacobs 		int i;
196355b4669Sjacobs 
197355b4669Sjacobs 		/* walk through the list */
198355b4669Sjacobs 		for (i = 0; (*printers)[i] != NULL; i++) {
199355b4669Sjacobs 			printer_t *p = (*printers)[i];
200355b4669Sjacobs 
201355b4669Sjacobs 			/* see if the name service satisfied the request */
202355b4669Sjacobs 			if (contained(requested_attrs, p->attributes) == 0)
203355b4669Sjacobs 				printer_from_service(svc, p, requested_attrs);
204355b4669Sjacobs 		}
205355b4669Sjacobs 	}
206355b4669Sjacobs 
207355b4669Sjacobs 	return (PAPI_OK);
208355b4669Sjacobs }
209355b4669Sjacobs 
210355b4669Sjacobs papi_status_t
211355b4669Sjacobs papiPrintersList(papi_service_t handle, char **requested_attrs,
212355b4669Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
213355b4669Sjacobs {
214355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
215355b4669Sjacobs 	service_t *svc = handle;
216355b4669Sjacobs 	papi_printer_t *svc_printers = NULL;
217355b4669Sjacobs 	papi_status_t (*f)();
218355b4669Sjacobs 
219355b4669Sjacobs 	if ((svc == NULL) || (printers == NULL))
220355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
221355b4669Sjacobs 
222355b4669Sjacobs 	if (svc->so_handle != NULL)	/* connected, use the print svc */
223355b4669Sjacobs 		result = printers_from_service(svc, requested_attrs,
224355b4669Sjacobs 					filter, printers);
225355b4669Sjacobs 	else				/* not connected, use the name svc */
226355b4669Sjacobs 		result = printers_from_name_service(svc, requested_attrs,
227355b4669Sjacobs 					filter, printers);
228355b4669Sjacobs 
229355b4669Sjacobs 	return (result);
230355b4669Sjacobs }
231355b4669Sjacobs 
232355b4669Sjacobs papi_status_t
233355b4669Sjacobs papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs,
234355b4669Sjacobs 		papi_attribute_t **job_attributes, papi_printer_t *printer)
235355b4669Sjacobs {
236355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
237355b4669Sjacobs 	service_t *svc = handle;
238355b4669Sjacobs 	printer_t *p = NULL;
239355b4669Sjacobs 	papi_status_t (*f)();
240355b4669Sjacobs 
241355b4669Sjacobs 	if ((svc == NULL) || (name == NULL) || (printer == NULL))
242355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
243355b4669Sjacobs 
244355b4669Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
245355b4669Sjacobs 		return (result);
246355b4669Sjacobs 
247355b4669Sjacobs 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
248355b4669Sjacobs 		return (PAPI_TEMPORARY_ERROR);
249355b4669Sjacobs 
250355b4669Sjacobs 	if ((svc->name != NULL) && (svc->svc_handle != NULL) &&
251355b4669Sjacobs 	    (svc->uri != NULL)) {
252355b4669Sjacobs 		p->svc = svc;
253355b4669Sjacobs 		f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery");
254355b4669Sjacobs 		if (f != NULL)
255355b4669Sjacobs 			result = f(svc->svc_handle, svc->name, requested_attrs,
256355b4669Sjacobs 					job_attributes, &p->printer);
257355b4669Sjacobs 	} else {
258355b4669Sjacobs 		setprinterentry(0, NULL);
259355b4669Sjacobs 		p->attributes = getprinterbyname(name, NULL);
260355b4669Sjacobs 		if (p->attributes == NULL)
261355b4669Sjacobs 			result = PAPI_NOT_FOUND;
262355b4669Sjacobs 		else
263355b4669Sjacobs 			result = PAPI_OK;
264355b4669Sjacobs 	}
265355b4669Sjacobs 
266355b4669Sjacobs 	return (result);
267355b4669Sjacobs }
268355b4669Sjacobs 
269355b4669Sjacobs static papi_status_t
270355b4669Sjacobs _papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message,
271355b4669Sjacobs 		char *function)
272355b4669Sjacobs {
273355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
274355b4669Sjacobs 	service_t *svc = handle;
275355b4669Sjacobs 	papi_status_t (*f)();
276355b4669Sjacobs 
277355b4669Sjacobs 	if ((svc == NULL) || (name == NULL))
278355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
279355b4669Sjacobs 
280355b4669Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
281355b4669Sjacobs 		return (result);
282355b4669Sjacobs 
283355b4669Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, function);
284355b4669Sjacobs 	if (f != NULL)
285355b4669Sjacobs 		result = f(svc->svc_handle, svc->name, message);
286355b4669Sjacobs 
287355b4669Sjacobs 	return (result);
288355b4669Sjacobs }
289355b4669Sjacobs 
290355b4669Sjacobs static papi_status_t
291355b4669Sjacobs _papi_printer_enable_or_resume(papi_service_t handle, char *name,
292355b4669Sjacobs 		char *function)
293355b4669Sjacobs {
294355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
295355b4669Sjacobs 	service_t *svc = handle;
296355b4669Sjacobs 	papi_status_t (*f)();
297355b4669Sjacobs 
298355b4669Sjacobs 	if ((svc == NULL) || (name == NULL))
299355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
300355b4669Sjacobs 
301355b4669Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
302355b4669Sjacobs 		return (result);
303355b4669Sjacobs 
304355b4669Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, function);
305355b4669Sjacobs 	if (f != NULL)
306355b4669Sjacobs 		result = f(svc->svc_handle, svc->name);
307355b4669Sjacobs 
308355b4669Sjacobs 	return (result);
309355b4669Sjacobs }
310355b4669Sjacobs 
311355b4669Sjacobs papi_status_t
312355b4669Sjacobs papiPrinterDisable(papi_service_t handle, char *name, char *message)
313355b4669Sjacobs {
314355b4669Sjacobs 	return (_papi_printer_disable_or_pause(handle, name, message,
315355b4669Sjacobs 						"papiPrinterDisable"));
316355b4669Sjacobs }
317355b4669Sjacobs 
318355b4669Sjacobs papi_status_t
319355b4669Sjacobs papiPrinterPause(papi_service_t handle, char *name, char *message)
320355b4669Sjacobs {
321355b4669Sjacobs 	return (_papi_printer_disable_or_pause(handle, name, message,
322355b4669Sjacobs 						"papiPrinterPause"));
323355b4669Sjacobs }
324355b4669Sjacobs 
325355b4669Sjacobs papi_status_t
326355b4669Sjacobs papiPrinterEnable(papi_service_t handle, char *name)
327355b4669Sjacobs {
328355b4669Sjacobs 	return (_papi_printer_enable_or_resume(handle, name,
329355b4669Sjacobs 						"papiPrinterEnable"));
330355b4669Sjacobs }
331355b4669Sjacobs 
332355b4669Sjacobs papi_status_t
333355b4669Sjacobs papiPrinterResume(papi_service_t handle, char *name)
334355b4669Sjacobs {
335355b4669Sjacobs 	return (_papi_printer_enable_or_resume(handle, name,
336355b4669Sjacobs 						"papiPrinterResume"));
337355b4669Sjacobs }
338355b4669Sjacobs 
339355b4669Sjacobs static papi_status_t
340355b4669Sjacobs _papi_printer_add_or_modify(papi_service_t handle, char *name,
341355b4669Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer,
342355b4669Sjacobs 		char *function)
343355b4669Sjacobs {
344355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
345355b4669Sjacobs 	service_t *svc = handle;
346355b4669Sjacobs 	printer_t *p = NULL;
347355b4669Sjacobs 	papi_status_t (*f)();
348355b4669Sjacobs 
349355b4669Sjacobs 	if ((svc == NULL) || (name == NULL) || (attributes == NULL))
350355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
351355b4669Sjacobs 
352355b4669Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
353355b4669Sjacobs 		return (result);
354355b4669Sjacobs 
355355b4669Sjacobs 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
356355b4669Sjacobs 		return (PAPI_TEMPORARY_ERROR);
357355b4669Sjacobs 
358355b4669Sjacobs 	p->svc = svc;
359355b4669Sjacobs 	f = (papi_status_t (*)())psm_sym(p->svc, function);
360355b4669Sjacobs 	if (f != NULL)
361355b4669Sjacobs 		result = f(svc->svc_handle, svc->name, attributes,
362355b4669Sjacobs 				&p->printer);
363355b4669Sjacobs 
364355b4669Sjacobs 	return (result);
365355b4669Sjacobs }
366355b4669Sjacobs 
367355b4669Sjacobs papi_status_t
368355b4669Sjacobs papiPrinterAdd(papi_service_t handle, char *name,
369355b4669Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer)
370355b4669Sjacobs {
371355b4669Sjacobs 	return (_papi_printer_add_or_modify(handle, name, attributes, printer,
372355b4669Sjacobs 						"papiPrinterAdd"));
373355b4669Sjacobs }
374355b4669Sjacobs 
375355b4669Sjacobs papi_status_t
376355b4669Sjacobs papiPrinterModify(papi_service_t handle, char *name,
377355b4669Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer)
378355b4669Sjacobs {
379355b4669Sjacobs 	return (_papi_printer_add_or_modify(handle, name, attributes, printer,
380355b4669Sjacobs 						"papiPrinterModify"));
381355b4669Sjacobs }
382355b4669Sjacobs 
383355b4669Sjacobs 
384355b4669Sjacobs papi_status_t
385355b4669Sjacobs papiPrinterRemove(papi_service_t handle, char *name)
386355b4669Sjacobs {
387355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
388355b4669Sjacobs 	service_t *svc = handle;
389355b4669Sjacobs 	papi_status_t (*f)();
390355b4669Sjacobs 
391355b4669Sjacobs 	if ((svc == NULL) || (name == NULL))
392355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
393355b4669Sjacobs 
394355b4669Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
395355b4669Sjacobs 		return (result);
396355b4669Sjacobs 
397355b4669Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove");
398355b4669Sjacobs 	if (f != NULL)
399355b4669Sjacobs 		result = f(svc->svc_handle, svc->name);
400355b4669Sjacobs 
401355b4669Sjacobs 	return (result);
402355b4669Sjacobs }
403355b4669Sjacobs 
404355b4669Sjacobs papi_status_t
405355b4669Sjacobs papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs)
406355b4669Sjacobs {
407355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
408355b4669Sjacobs 	service_t *svc = handle;
409355b4669Sjacobs 	papi_job_t *svc_jobs = NULL;
410355b4669Sjacobs 	papi_status_t (*f)();
411355b4669Sjacobs 
412355b4669Sjacobs 	if ((svc == NULL) || (name == NULL))
413355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
414355b4669Sjacobs 
415355b4669Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
416355b4669Sjacobs 		return (result);
417355b4669Sjacobs 
418355b4669Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs");
419355b4669Sjacobs 	if (f != NULL)
420355b4669Sjacobs 		result = f(svc->svc_handle, svc->name, &svc_jobs);
421355b4669Sjacobs 
422355b4669Sjacobs 	/*
423355b4669Sjacobs 	 * copy the resulting job object pointers into our own
424355b4669Sjacobs 	 * representation of a job object because we need the
425355b4669Sjacobs 	 * service context to operate against the individual job
426355b4669Sjacobs 	 * objects.  We free the list now because we no longer need
427355b4669Sjacobs 	 * it and would have no way of freeing it later.
428355b4669Sjacobs 	 */
429355b4669Sjacobs 	if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) {
430355b4669Sjacobs 		int i;
431355b4669Sjacobs 
432355b4669Sjacobs 		*jobs = NULL;
433355b4669Sjacobs 		for (i = 0; svc_jobs[i] != NULL; i++) {
434355b4669Sjacobs 			job_t *j = NULL;
435355b4669Sjacobs 
436355b4669Sjacobs 			if ((j = calloc(1, sizeof (*j))) == NULL)
437355b4669Sjacobs 				return (PAPI_TEMPORARY_ERROR);
438355b4669Sjacobs 
439355b4669Sjacobs 			j->svc = svc;
440355b4669Sjacobs 			j->job = svc_jobs[i];
441355b4669Sjacobs 			list_append(jobs, j);
442355b4669Sjacobs 		}
443355b4669Sjacobs 		free(svc_jobs);
444355b4669Sjacobs 	}
445355b4669Sjacobs 
446355b4669Sjacobs 	return (result);
447355b4669Sjacobs }
448355b4669Sjacobs 
449355b4669Sjacobs papi_status_t
450355b4669Sjacobs papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs,
451355b4669Sjacobs 		int type_mask, int max_num_jobs, papi_job_t **jobs)
452355b4669Sjacobs {
453355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
454355b4669Sjacobs 	service_t *svc = handle;
455355b4669Sjacobs 	papi_job_t *svc_jobs = NULL;
456355b4669Sjacobs 	papi_status_t (*f)();
457355b4669Sjacobs 
458355b4669Sjacobs 	if ((svc == NULL) || (name == NULL) || (jobs == NULL))
459355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
460355b4669Sjacobs 
461355b4669Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
462355b4669Sjacobs 		return (result);
463355b4669Sjacobs 
464355b4669Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs");
465355b4669Sjacobs 	if (f != NULL)
466355b4669Sjacobs 		result = f(svc->svc_handle, svc->name, requested_attrs,
467355b4669Sjacobs 				type_mask, max_num_jobs, &svc_jobs);
468355b4669Sjacobs 
469355b4669Sjacobs 	/*
470355b4669Sjacobs 	 * copy the resulting job object pointers into our own
471355b4669Sjacobs 	 * representation of a job object because we need the
472355b4669Sjacobs 	 * service context to operate against the individual job
473355b4669Sjacobs 	 * objects.  We free the list now because we no longer need
474355b4669Sjacobs 	 * it and would have no way of freeing it later.
475355b4669Sjacobs 	 */
476355b4669Sjacobs 	if ((result == PAPI_OK) && (svc_jobs != NULL)) {
477355b4669Sjacobs 		int i;
478355b4669Sjacobs 
479355b4669Sjacobs 		*jobs = NULL;
480355b4669Sjacobs 		for (i = 0; svc_jobs[i] != NULL; i++) {
481355b4669Sjacobs 			job_t *j = NULL;
482355b4669Sjacobs 
483355b4669Sjacobs 			if ((j = calloc(1, sizeof (*j))) == NULL)
484355b4669Sjacobs 				return (PAPI_TEMPORARY_ERROR);
485355b4669Sjacobs 
486355b4669Sjacobs 			j->svc = svc;
487355b4669Sjacobs 			j->job = svc_jobs[i];
488355b4669Sjacobs 			list_append(jobs, j);
489355b4669Sjacobs 		}
490355b4669Sjacobs 		free(svc_jobs);
491355b4669Sjacobs 	}
492355b4669Sjacobs 
493355b4669Sjacobs 	return (result);
494355b4669Sjacobs }
495355b4669Sjacobs 
496355b4669Sjacobs papi_attribute_t **
497355b4669Sjacobs papiPrinterGetAttributeList(papi_printer_t printer)
498355b4669Sjacobs {
499355b4669Sjacobs 	papi_attribute_t **result = NULL;
500355b4669Sjacobs 	printer_t *p = printer;
501355b4669Sjacobs 
502355b4669Sjacobs 	if ((p != NULL) && (p->printer != NULL)) {
503355b4669Sjacobs 		papi_attribute_t **(*f)();
504355b4669Sjacobs 
505355b4669Sjacobs 		f = (papi_attribute_t **(*)())psm_sym(p->svc,
506355b4669Sjacobs 					"papiPrinterGetAttributeList");
507355b4669Sjacobs 		if (f != NULL)
508355b4669Sjacobs 			result = f(p->printer);
509355b4669Sjacobs 	} else
510355b4669Sjacobs 		result = p->attributes;
511355b4669Sjacobs 
512355b4669Sjacobs 	return (result);
513355b4669Sjacobs }
514