1*2264Sjacobs /*
2*2264Sjacobs  * CDDL HEADER START
3*2264Sjacobs  *
4*2264Sjacobs  * The contents of this file are subject to the terms of the
5*2264Sjacobs  * Common Development and Distribution License (the "License").
6*2264Sjacobs  * You may not use this file except in compliance with the License.
7*2264Sjacobs  *
8*2264Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2264Sjacobs  * or http://www.opensolaris.org/os/licensing.
10*2264Sjacobs  * See the License for the specific language governing permissions
11*2264Sjacobs  * and limitations under the License.
12*2264Sjacobs  *
13*2264Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14*2264Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2264Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16*2264Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17*2264Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18*2264Sjacobs  *
19*2264Sjacobs  * CDDL HEADER END
20*2264Sjacobs  */
21*2264Sjacobs 
22*2264Sjacobs /*
23*2264Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24*2264Sjacobs  * Use is subject to license terms.
25*2264Sjacobs  *
26*2264Sjacobs  */
27*2264Sjacobs 
28*2264Sjacobs /* $Id: printer.c 151 2006-04-25 16:55:34Z njacobs $ */
29*2264Sjacobs 
30*2264Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*2264Sjacobs 
32*2264Sjacobs /*LINTLIBRARY*/
33*2264Sjacobs 
34*2264Sjacobs #include <stdlib.h>
35*2264Sjacobs #include <papi_impl.h>
36*2264Sjacobs 
37*2264Sjacobs void
38*2264Sjacobs papiPrinterFree(papi_printer_t printer)
39*2264Sjacobs {
40*2264Sjacobs 	printer_t *tmp = printer;
41*2264Sjacobs 
42*2264Sjacobs 	if (tmp != NULL) {
43*2264Sjacobs 		void (*f)();
44*2264Sjacobs 
45*2264Sjacobs 		f = (void (*)())psm_sym(tmp->svc, "papiPrinterFree");
46*2264Sjacobs 		if (f != NULL)
47*2264Sjacobs 			f(tmp->printer);
48*2264Sjacobs 		if (tmp->attributes != NULL)
49*2264Sjacobs 			papiAttributeListFree(tmp->attributes);
50*2264Sjacobs 		if (tmp->svc_is_internal != 0)
51*2264Sjacobs 			papiServiceDestroy(tmp->svc);
52*2264Sjacobs 		free(tmp);
53*2264Sjacobs 	}
54*2264Sjacobs }
55*2264Sjacobs 
56*2264Sjacobs void
57*2264Sjacobs papiPrinterListFree(papi_printer_t *printers)
58*2264Sjacobs {
59*2264Sjacobs 	if (printers != NULL) {
60*2264Sjacobs 		int i;
61*2264Sjacobs 
62*2264Sjacobs 		for (i = 0; printers[i] != NULL; i++)
63*2264Sjacobs 			papiPrinterFree(printers[i]);
64*2264Sjacobs 		free(printers);
65*2264Sjacobs 	}
66*2264Sjacobs }
67*2264Sjacobs 
68*2264Sjacobs /* Enumerate a list of printers from the loaded print service. */
69*2264Sjacobs static papi_status_t
70*2264Sjacobs printers_from_service(service_t *svc, char **requested_attrs,
71*2264Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
72*2264Sjacobs {
73*2264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
74*2264Sjacobs 	papi_printer_t *svc_printers = NULL;
75*2264Sjacobs 	papi_status_t (*f)();
76*2264Sjacobs 
77*2264Sjacobs 	if ((svc == NULL) || (printers == NULL))
78*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
79*2264Sjacobs 
80*2264Sjacobs 	/* connect to the service if we are not connected */
81*2264Sjacobs 	if ((result = service_connect(svc, svc->name)) != PAPI_OK)
82*2264Sjacobs 		return (result);
83*2264Sjacobs 
84*2264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrintersList");
85*2264Sjacobs 	if (f != NULL)
86*2264Sjacobs 		result = f(svc->svc_handle, requested_attrs, filter,
87*2264Sjacobs 				&svc_printers);
88*2264Sjacobs 
89*2264Sjacobs 	/*
90*2264Sjacobs 	 * copy the resulting printer object pointers into our own
91*2264Sjacobs 	 * representation of a printer object because we need the
92*2264Sjacobs 	 * service context to operate against the individual printer
93*2264Sjacobs 	 * objects.  We free the list now because we no longer need
94*2264Sjacobs 	 * it and would have no way of freeing it later.
95*2264Sjacobs 	 */
96*2264Sjacobs 	if ((result == PAPI_OK) && (svc_printers != NULL)) {
97*2264Sjacobs 		int i;
98*2264Sjacobs 
99*2264Sjacobs 		*printers = NULL;
100*2264Sjacobs 		for (i = 0; svc_printers[i] != NULL; i++) {
101*2264Sjacobs 			printer_t *p = NULL;
102*2264Sjacobs 
103*2264Sjacobs 			if ((p = calloc(1, sizeof (*p))) == NULL)
104*2264Sjacobs 				return (PAPI_TEMPORARY_ERROR);
105*2264Sjacobs 
106*2264Sjacobs 			p->svc = svc;
107*2264Sjacobs 			p->printer = svc_printers[i];
108*2264Sjacobs 			list_append(printers, p);
109*2264Sjacobs 		}
110*2264Sjacobs 		free(svc_printers);
111*2264Sjacobs 	}
112*2264Sjacobs 
113*2264Sjacobs 	return (result);
114*2264Sjacobs }
115*2264Sjacobs 
116*2264Sjacobs /* Get printer attributes from it's print service */
117*2264Sjacobs static papi_status_t
118*2264Sjacobs printer_from_service(service_t *svc, printer_t *p, char **requested_attrs)
119*2264Sjacobs {
120*2264Sjacobs 	papi_status_t result;
121*2264Sjacobs 	papi_service_t p_svc = NULL;
122*2264Sjacobs 	papi_printer_t printer = NULL;
123*2264Sjacobs 	char *psm = NULL;
124*2264Sjacobs 	char *uri = NULL;
125*2264Sjacobs 
126*2264Sjacobs 	/* get the psm and uri from the attributes */
127*2264Sjacobs 	papiAttributeListGetString(p->attributes, NULL,
128*2264Sjacobs 			"print-service-module", &psm);
129*2264Sjacobs 	papiAttributeListGetString(p->attributes, NULL, "printer-name", &uri);
130*2264Sjacobs 	papiAttributeListGetString(p->attributes, NULL, "printer-uri-supported",
131*2264Sjacobs 			&uri);
132*2264Sjacobs 
133*2264Sjacobs 	/* contact the service for the printer */
134*2264Sjacobs 	result = papiServiceCreate((papi_service_t *)&p_svc, psm, svc->user,
135*2264Sjacobs 				svc->password, svc->authCB, svc->encryption,
136*2264Sjacobs 				svc->app_data);
137*2264Sjacobs 	if (result != PAPI_OK)
138*2264Sjacobs 		return (result);
139*2264Sjacobs 
140*2264Sjacobs 	/* get the printer from the service */
141*2264Sjacobs 	result = papiPrinterQuery(p_svc, uri, requested_attrs, NULL, &printer);
142*2264Sjacobs 	if (result == PAPI_OK) {
143*2264Sjacobs 		papi_attribute_t **attributes;
144*2264Sjacobs 
145*2264Sjacobs 		attributes = papiPrinterGetAttributeList(printer);
146*2264Sjacobs 		copy_attributes(&p->attributes, attributes);
147*2264Sjacobs 	}
148*2264Sjacobs 	papiPrinterFree(printer);
149*2264Sjacobs 	papiServiceDestroy(p_svc);
150*2264Sjacobs 
151*2264Sjacobs 	return (result);
152*2264Sjacobs }
153*2264Sjacobs 
154*2264Sjacobs /* are the requested attributes contained in the list */
155*2264Sjacobs static int
156*2264Sjacobs contained(char **requested, papi_attribute_t **list)
157*2264Sjacobs {
158*2264Sjacobs 	int i;
159*2264Sjacobs 
160*2264Sjacobs 	if (requested == NULL)	/* we want every possible attribute */
161*2264Sjacobs 		return (0);
162*2264Sjacobs 
163*2264Sjacobs 	for (i = 0; requested[i] != NULL; i++)
164*2264Sjacobs 		if (papiAttributeListFind(list, requested[i]) == NULL)
165*2264Sjacobs 			return (0);
166*2264Sjacobs 
167*2264Sjacobs 	return (1);
168*2264Sjacobs }
169*2264Sjacobs 
170*2264Sjacobs /* Enumerate a list of printers from the Name Service */
171*2264Sjacobs static papi_status_t
172*2264Sjacobs printers_from_name_service(service_t *svc, char **requested_attrs,
173*2264Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
174*2264Sjacobs {
175*2264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
176*2264Sjacobs 	papi_attribute_t **attrs;
177*2264Sjacobs 
178*2264Sjacobs 	if ((svc == NULL) || (printers == NULL))
179*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
180*2264Sjacobs 
181*2264Sjacobs 	/* retrieve printers from the nameservice */
182*2264Sjacobs 	while ((attrs = getprinterentry(NULL)) != NULL) {
183*2264Sjacobs 		printer_t *p = NULL;
184*2264Sjacobs 
185*2264Sjacobs 		if ((p = calloc(1, sizeof (*p))) == NULL)
186*2264Sjacobs 			return (PAPI_TEMPORARY_ERROR);
187*2264Sjacobs 
188*2264Sjacobs 		p->attributes = attrs;
189*2264Sjacobs 		list_append(printers, p);
190*2264Sjacobs 	}
191*2264Sjacobs 
192*2264Sjacobs 	/* if we have printers, check if our request has been satisfied */
193*2264Sjacobs 	if ((printers != NULL) && (*printers != NULL)) {
194*2264Sjacobs 		int i;
195*2264Sjacobs 
196*2264Sjacobs 		/* walk through the list */
197*2264Sjacobs 		for (i = 0; (*printers)[i] != NULL; i++) {
198*2264Sjacobs 			printer_t *p = (*printers)[i];
199*2264Sjacobs 
200*2264Sjacobs 			/* see if the name service satisfied the request */
201*2264Sjacobs 			if (contained(requested_attrs, p->attributes) == 0)
202*2264Sjacobs 				printer_from_service(svc, p, requested_attrs);
203*2264Sjacobs 		}
204*2264Sjacobs 	}
205*2264Sjacobs 
206*2264Sjacobs 	return (PAPI_OK);
207*2264Sjacobs }
208*2264Sjacobs 
209*2264Sjacobs papi_status_t
210*2264Sjacobs papiPrintersList(papi_service_t handle, char **requested_attrs,
211*2264Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
212*2264Sjacobs {
213*2264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
214*2264Sjacobs 	service_t *svc = handle;
215*2264Sjacobs 	papi_printer_t *svc_printers = NULL;
216*2264Sjacobs 	papi_status_t (*f)();
217*2264Sjacobs 
218*2264Sjacobs 	if ((svc == NULL) || (printers == NULL))
219*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
220*2264Sjacobs 
221*2264Sjacobs 	if (svc->so_handle != NULL)	/* connected, use the print svc */
222*2264Sjacobs 		result = printers_from_service(svc, requested_attrs,
223*2264Sjacobs 					filter, printers);
224*2264Sjacobs 	else				/* not connected, use the name svc */
225*2264Sjacobs 		result = printers_from_name_service(svc, requested_attrs,
226*2264Sjacobs 					filter, printers);
227*2264Sjacobs 
228*2264Sjacobs 	return (result);
229*2264Sjacobs }
230*2264Sjacobs 
231*2264Sjacobs papi_status_t
232*2264Sjacobs papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs,
233*2264Sjacobs 		papi_attribute_t **job_attributes, papi_printer_t *printer)
234*2264Sjacobs {
235*2264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
236*2264Sjacobs 	service_t *svc = handle;
237*2264Sjacobs 	printer_t *p = NULL;
238*2264Sjacobs 	papi_status_t (*f)();
239*2264Sjacobs 
240*2264Sjacobs 	if ((svc == NULL) || (name == NULL) || (printer == NULL))
241*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
242*2264Sjacobs 
243*2264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
244*2264Sjacobs 		return (result);
245*2264Sjacobs 
246*2264Sjacobs 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
247*2264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
248*2264Sjacobs 
249*2264Sjacobs 	if ((svc->name != NULL) && (svc->svc_handle != NULL) &&
250*2264Sjacobs 	    (svc->uri != NULL)) {
251*2264Sjacobs 		p->svc = svc;
252*2264Sjacobs 		f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery");
253*2264Sjacobs 		if (f != NULL)
254*2264Sjacobs 			result = f(svc->svc_handle, svc->name, requested_attrs,
255*2264Sjacobs 					job_attributes, &p->printer);
256*2264Sjacobs 	} else {
257*2264Sjacobs 		setprinterentry(0, NULL);
258*2264Sjacobs 		p->attributes = getprinterbyname(name, NULL);
259*2264Sjacobs 		if (p->attributes == NULL)
260*2264Sjacobs 			result = PAPI_NOT_FOUND;
261*2264Sjacobs 		else
262*2264Sjacobs 			result = PAPI_OK;
263*2264Sjacobs 	}
264*2264Sjacobs 
265*2264Sjacobs 	return (result);
266*2264Sjacobs }
267*2264Sjacobs 
268*2264Sjacobs static papi_status_t
269*2264Sjacobs _papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message,
270*2264Sjacobs 		char *function)
271*2264Sjacobs {
272*2264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
273*2264Sjacobs 	service_t *svc = handle;
274*2264Sjacobs 	papi_status_t (*f)();
275*2264Sjacobs 
276*2264Sjacobs 	if ((svc == NULL) || (name == NULL))
277*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
278*2264Sjacobs 
279*2264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
280*2264Sjacobs 		return (result);
281*2264Sjacobs 
282*2264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, function);
283*2264Sjacobs 	if (f != NULL)
284*2264Sjacobs 		result = f(svc->svc_handle, svc->name, message);
285*2264Sjacobs 
286*2264Sjacobs 	return (result);
287*2264Sjacobs }
288*2264Sjacobs 
289*2264Sjacobs static papi_status_t
290*2264Sjacobs _papi_printer_enable_or_resume(papi_service_t handle, char *name,
291*2264Sjacobs 		char *function)
292*2264Sjacobs {
293*2264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
294*2264Sjacobs 	service_t *svc = handle;
295*2264Sjacobs 	papi_status_t (*f)();
296*2264Sjacobs 
297*2264Sjacobs 	if ((svc == NULL) || (name == NULL))
298*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
299*2264Sjacobs 
300*2264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
301*2264Sjacobs 		return (result);
302*2264Sjacobs 
303*2264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, function);
304*2264Sjacobs 	if (f != NULL)
305*2264Sjacobs 		result = f(svc->svc_handle, svc->name);
306*2264Sjacobs 
307*2264Sjacobs 	return (result);
308*2264Sjacobs }
309*2264Sjacobs 
310*2264Sjacobs papi_status_t
311*2264Sjacobs papiPrinterDisable(papi_service_t handle, char *name, char *message)
312*2264Sjacobs {
313*2264Sjacobs 	return (_papi_printer_disable_or_pause(handle, name, message,
314*2264Sjacobs 						"papiPrinterDisable"));
315*2264Sjacobs }
316*2264Sjacobs 
317*2264Sjacobs papi_status_t
318*2264Sjacobs papiPrinterPause(papi_service_t handle, char *name, char *message)
319*2264Sjacobs {
320*2264Sjacobs 	return (_papi_printer_disable_or_pause(handle, name, message,
321*2264Sjacobs 						"papiPrinterPause"));
322*2264Sjacobs }
323*2264Sjacobs 
324*2264Sjacobs papi_status_t
325*2264Sjacobs papiPrinterEnable(papi_service_t handle, char *name)
326*2264Sjacobs {
327*2264Sjacobs 	return (_papi_printer_enable_or_resume(handle, name,
328*2264Sjacobs 						"papiPrinterEnable"));
329*2264Sjacobs }
330*2264Sjacobs 
331*2264Sjacobs papi_status_t
332*2264Sjacobs papiPrinterResume(papi_service_t handle, char *name)
333*2264Sjacobs {
334*2264Sjacobs 	return (_papi_printer_enable_or_resume(handle, name,
335*2264Sjacobs 						"papiPrinterResume"));
336*2264Sjacobs }
337*2264Sjacobs 
338*2264Sjacobs static papi_status_t
339*2264Sjacobs _papi_printer_add_or_modify(papi_service_t handle, char *name,
340*2264Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer,
341*2264Sjacobs 		char *function)
342*2264Sjacobs {
343*2264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
344*2264Sjacobs 	service_t *svc = handle;
345*2264Sjacobs 	printer_t *p = NULL;
346*2264Sjacobs 	papi_status_t (*f)();
347*2264Sjacobs 
348*2264Sjacobs 	if ((svc == NULL) || (name == NULL) || (attributes == NULL))
349*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
350*2264Sjacobs 
351*2264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
352*2264Sjacobs 		return (result);
353*2264Sjacobs 
354*2264Sjacobs 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
355*2264Sjacobs 		return (PAPI_TEMPORARY_ERROR);
356*2264Sjacobs 
357*2264Sjacobs 	p->svc = svc;
358*2264Sjacobs 	f = (papi_status_t (*)())psm_sym(p->svc, function);
359*2264Sjacobs 	if (f != NULL)
360*2264Sjacobs 		result = f(svc->svc_handle, svc->name, attributes,
361*2264Sjacobs 				&p->printer);
362*2264Sjacobs 
363*2264Sjacobs 	return (result);
364*2264Sjacobs }
365*2264Sjacobs 
366*2264Sjacobs papi_status_t
367*2264Sjacobs papiPrinterAdd(papi_service_t handle, char *name,
368*2264Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer)
369*2264Sjacobs {
370*2264Sjacobs 	return (_papi_printer_add_or_modify(handle, name, attributes, printer,
371*2264Sjacobs 						"papiPrinterAdd"));
372*2264Sjacobs }
373*2264Sjacobs 
374*2264Sjacobs papi_status_t
375*2264Sjacobs papiPrinterModify(papi_service_t handle, char *name,
376*2264Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer)
377*2264Sjacobs {
378*2264Sjacobs 	return (_papi_printer_add_or_modify(handle, name, attributes, printer,
379*2264Sjacobs 						"papiPrinterModify"));
380*2264Sjacobs }
381*2264Sjacobs 
382*2264Sjacobs 
383*2264Sjacobs papi_status_t
384*2264Sjacobs papiPrinterRemove(papi_service_t handle, char *name)
385*2264Sjacobs {
386*2264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
387*2264Sjacobs 	service_t *svc = handle;
388*2264Sjacobs 	papi_status_t (*f)();
389*2264Sjacobs 
390*2264Sjacobs 	if ((svc == NULL) || (name == NULL))
391*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
392*2264Sjacobs 
393*2264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
394*2264Sjacobs 		return (result);
395*2264Sjacobs 
396*2264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove");
397*2264Sjacobs 	if (f != NULL)
398*2264Sjacobs 		result = f(svc->svc_handle, svc->name);
399*2264Sjacobs 
400*2264Sjacobs 	return (result);
401*2264Sjacobs }
402*2264Sjacobs 
403*2264Sjacobs papi_status_t
404*2264Sjacobs papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs)
405*2264Sjacobs {
406*2264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
407*2264Sjacobs 	service_t *svc = handle;
408*2264Sjacobs 	papi_job_t *svc_jobs = NULL;
409*2264Sjacobs 	papi_status_t (*f)();
410*2264Sjacobs 
411*2264Sjacobs 	if ((svc == NULL) || (name == NULL))
412*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
413*2264Sjacobs 
414*2264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
415*2264Sjacobs 		return (result);
416*2264Sjacobs 
417*2264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs");
418*2264Sjacobs 	if (f != NULL)
419*2264Sjacobs 		result = f(svc->svc_handle, svc->name, &svc_jobs);
420*2264Sjacobs 
421*2264Sjacobs 	/*
422*2264Sjacobs 	 * copy the resulting job object pointers into our own
423*2264Sjacobs 	 * representation of a job object because we need the
424*2264Sjacobs 	 * service context to operate against the individual job
425*2264Sjacobs 	 * objects.  We free the list now because we no longer need
426*2264Sjacobs 	 * it and would have no way of freeing it later.
427*2264Sjacobs 	 */
428*2264Sjacobs 	if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) {
429*2264Sjacobs 		int i;
430*2264Sjacobs 
431*2264Sjacobs 		*jobs = NULL;
432*2264Sjacobs 		for (i = 0; svc_jobs[i] != NULL; i++) {
433*2264Sjacobs 			job_t *j = NULL;
434*2264Sjacobs 
435*2264Sjacobs 			if ((j = calloc(1, sizeof (*j))) == NULL)
436*2264Sjacobs 				return (PAPI_TEMPORARY_ERROR);
437*2264Sjacobs 
438*2264Sjacobs 			j->svc = svc;
439*2264Sjacobs 			j->job = svc_jobs[i];
440*2264Sjacobs 			list_append(jobs, j);
441*2264Sjacobs 		}
442*2264Sjacobs 		free(svc_jobs);
443*2264Sjacobs 	}
444*2264Sjacobs 
445*2264Sjacobs 	return (result);
446*2264Sjacobs }
447*2264Sjacobs 
448*2264Sjacobs papi_status_t
449*2264Sjacobs papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs,
450*2264Sjacobs 		int type_mask, int max_num_jobs, papi_job_t **jobs)
451*2264Sjacobs {
452*2264Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
453*2264Sjacobs 	service_t *svc = handle;
454*2264Sjacobs 	papi_job_t *svc_jobs = NULL;
455*2264Sjacobs 	papi_status_t (*f)();
456*2264Sjacobs 
457*2264Sjacobs 	if ((svc == NULL) || (name == NULL) || (jobs == NULL))
458*2264Sjacobs 		return (PAPI_BAD_ARGUMENT);
459*2264Sjacobs 
460*2264Sjacobs 	if ((result = service_connect(svc, name)) != PAPI_OK)
461*2264Sjacobs 		return (result);
462*2264Sjacobs 
463*2264Sjacobs 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs");
464*2264Sjacobs 	if (f != NULL)
465*2264Sjacobs 		result = f(svc->svc_handle, svc->name, requested_attrs,
466*2264Sjacobs 				type_mask, max_num_jobs, &svc_jobs);
467*2264Sjacobs 
468*2264Sjacobs 	/*
469*2264Sjacobs 	 * copy the resulting job object pointers into our own
470*2264Sjacobs 	 * representation of a job object because we need the
471*2264Sjacobs 	 * service context to operate against the individual job
472*2264Sjacobs 	 * objects.  We free the list now because we no longer need
473*2264Sjacobs 	 * it and would have no way of freeing it later.
474*2264Sjacobs 	 */
475*2264Sjacobs 	if ((result == PAPI_OK) && (svc_jobs != NULL)) {
476*2264Sjacobs 		int i;
477*2264Sjacobs 
478*2264Sjacobs 		*jobs = NULL;
479*2264Sjacobs 		for (i = 0; svc_jobs[i] != NULL; i++) {
480*2264Sjacobs 			job_t *j = NULL;
481*2264Sjacobs 
482*2264Sjacobs 			if ((j = calloc(1, sizeof (*j))) == NULL)
483*2264Sjacobs 				return (PAPI_TEMPORARY_ERROR);
484*2264Sjacobs 
485*2264Sjacobs 			j->svc = svc;
486*2264Sjacobs 			j->job = svc_jobs[i];
487*2264Sjacobs 			list_append(jobs, j);
488*2264Sjacobs 		}
489*2264Sjacobs 		free(svc_jobs);
490*2264Sjacobs 	}
491*2264Sjacobs 
492*2264Sjacobs 	return (result);
493*2264Sjacobs }
494*2264Sjacobs 
495*2264Sjacobs papi_attribute_t **
496*2264Sjacobs papiPrinterGetAttributeList(papi_printer_t printer)
497*2264Sjacobs {
498*2264Sjacobs 	papi_attribute_t **result = NULL;
499*2264Sjacobs 	printer_t *p = printer;
500*2264Sjacobs 
501*2264Sjacobs 	if ((p != NULL) && (p->printer != NULL)) {
502*2264Sjacobs 		papi_attribute_t **(*f)();
503*2264Sjacobs 
504*2264Sjacobs 		f = (papi_attribute_t **(*)())psm_sym(p->svc,
505*2264Sjacobs 					"papiPrinterGetAttributeList");
506*2264Sjacobs 		if (f != NULL)
507*2264Sjacobs 			result = f(p->printer);
508*2264Sjacobs 	} else
509*2264Sjacobs 		result = p->attributes;
510*2264Sjacobs 
511*2264Sjacobs 	return (result);
512*2264Sjacobs }
513