xref: /titanic_50/usr/src/lib/print/libpapi-ipp/common/printer.c (revision 223f6c28404c8d330c123e98936160b8da9a26b2)
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 /*
23*223f6c28Sjacobs  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24355b4669Sjacobs  * Use is subject to license terms.
25355b4669Sjacobs  *
26355b4669Sjacobs  */
27355b4669Sjacobs 
28355b4669Sjacobs /* $Id: printer.c 146 2006-03-24 00:26:54Z 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 #include <config-site.h>
38355b4669Sjacobs 
39355b4669Sjacobs void
papiPrinterFree(papi_printer_t printer)40355b4669Sjacobs papiPrinterFree(papi_printer_t printer)
41355b4669Sjacobs {
42355b4669Sjacobs 	printer_t *tmp = printer;
43355b4669Sjacobs 
44355b4669Sjacobs 	if (tmp != NULL) {
45355b4669Sjacobs 		if (tmp->attributes != NULL)
46355b4669Sjacobs 			papiAttributeListFree(tmp->attributes);
47355b4669Sjacobs 		free(tmp);
48355b4669Sjacobs 	}
49355b4669Sjacobs }
50355b4669Sjacobs 
51355b4669Sjacobs void
papiPrinterListFree(papi_printer_t * printers)52355b4669Sjacobs papiPrinterListFree(papi_printer_t *printers)
53355b4669Sjacobs {
54355b4669Sjacobs 	if (printers != NULL) {
55355b4669Sjacobs 		int i;
56355b4669Sjacobs 
57355b4669Sjacobs 		for (i = 0; printers[i] != NULL; i++)
58355b4669Sjacobs 			papiPrinterFree(printers[i]);
59355b4669Sjacobs 		free(printers);
60355b4669Sjacobs 	}
61355b4669Sjacobs }
62355b4669Sjacobs 
63355b4669Sjacobs /*
64355b4669Sjacobs  * Enumeration of printers is not part of the IPP specification, so many
65355b4669Sjacobs  * servers will probably not respond back with a list of printers, but
66355b4669Sjacobs  * CUPS has implemented an extension to IPP to enumerate printers and
67355b4669Sjacobs  * classes. the Apache/mod_ipp IPP listener module available in Solaris
68355b4669Sjacobs  * implements this IPP extension, so CUPS and Solaris can provide this
69355b4669Sjacobs  * to IPP clients.
70355b4669Sjacobs  */
71355b4669Sjacobs #ifndef	OPID_CUPS_GET_PRINTERS		/* for servers that will enumerate */
72355b4669Sjacobs #define	OPID_CUPS_GET_PRINTERS		0x4002
73355b4669Sjacobs #endif	/* OPID_CUPS_GET_PRINTERS */
74355b4669Sjacobs #ifndef	OPID_CUPS_DELETE_PRINTER	/* for servers that can delete */
75355b4669Sjacobs #define	OPID_CUPS_DELETE_PRINTER	0x4004
76355b4669Sjacobs #endif	/* OPID_CUPS_DELETE_PRINTER */
77355b4669Sjacobs #ifndef	OPID_CUPS_GET_CLASSES		/* for servers that will enumerate */
78355b4669Sjacobs #define	OPID_CUPS_GET_CLASSES		0x4005
79355b4669Sjacobs #endif	/* OPID_CUPS_GET_CLASSES */
80355b4669Sjacobs 
81355b4669Sjacobs papi_status_t
papiPrintersList(papi_service_t handle,char ** requested_attrs,papi_filter_t * filter,papi_printer_t ** printers)82355b4669Sjacobs papiPrintersList(papi_service_t handle, char **requested_attrs,
83355b4669Sjacobs 		papi_filter_t *filter, papi_printer_t **printers)
84355b4669Sjacobs {
85355b4669Sjacobs 	papi_status_t status, result = PAPI_INTERNAL_ERROR;
86355b4669Sjacobs 	service_t *svc = handle;
87355b4669Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
88355b4669Sjacobs 	void *iter = NULL;
89355b4669Sjacobs 
90355b4669Sjacobs 	if ((svc == NULL) || (printers == NULL))
91355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
92355b4669Sjacobs 
93355b4669Sjacobs 	/* if we are already connected, use that connection. */
94355b4669Sjacobs 	if (svc->connection == NULL)
95355b4669Sjacobs 		if ((result = service_connect(svc, DEFAULT_DEST)) != PAPI_OK)
96355b4669Sjacobs 			return (result);
97355b4669Sjacobs 	ipp_initialize_request(svc, &request, OPID_CUPS_GET_PRINTERS);
98355b4669Sjacobs 
99*223f6c28Sjacobs 	ipp_initialize_operational_attributes(svc, &op, NULL, -1);
100355b4669Sjacobs 
101355b4669Sjacobs 	if (requested_attrs != NULL) {
102355b4669Sjacobs 		int i;
103355b4669Sjacobs 
104355b4669Sjacobs 		for (i = 0; requested_attrs[i] != NULL; i++)
105355b4669Sjacobs 			papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
106355b4669Sjacobs 				"requested-attributes", requested_attrs[i]);
107355b4669Sjacobs 	}
108355b4669Sjacobs 
109355b4669Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
110355b4669Sjacobs 			"operational-attributes-group", op);
111355b4669Sjacobs 	papiAttributeListFree(op);
112355b4669Sjacobs 	result = ipp_send_request(svc, request, &response);
113355b4669Sjacobs 	papiAttributeListFree(request);
114355b4669Sjacobs 
115355b4669Sjacobs 	op = NULL;
116355b4669Sjacobs 	for (status = papiAttributeListGetCollection(response, &iter,
117355b4669Sjacobs 				"printer-attributes-group", &op);
118355b4669Sjacobs 	     status == PAPI_OK;
119355b4669Sjacobs 	     status = papiAttributeListGetCollection(response, &iter,
120355b4669Sjacobs 				NULL, &op)) {
121355b4669Sjacobs 		printer_t *p = NULL;
122355b4669Sjacobs 
123355b4669Sjacobs 		if ((p = calloc(1, sizeof (*p))) == NULL)
124355b4669Sjacobs 			return (PAPI_TEMPORARY_ERROR);
125355b4669Sjacobs 
126355b4669Sjacobs 		copy_attributes(&p->attributes, op);
127355b4669Sjacobs 		op = NULL;
128355b4669Sjacobs 		list_append(printers, p);
129355b4669Sjacobs 	}
130355b4669Sjacobs 	papiAttributeListFree(response);
131355b4669Sjacobs 
132355b4669Sjacobs 	return (result);
133355b4669Sjacobs }
134355b4669Sjacobs 
135355b4669Sjacobs papi_status_t
papiPrinterQuery(papi_service_t handle,char * name,char ** requested_attrs,papi_attribute_t ** job_attributes,papi_printer_t * printer)136355b4669Sjacobs papiPrinterQuery(papi_service_t handle, char *name,
137355b4669Sjacobs 		char **requested_attrs,
138355b4669Sjacobs 		papi_attribute_t **job_attributes,
139355b4669Sjacobs 		papi_printer_t *printer)
140355b4669Sjacobs {
141355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
142355b4669Sjacobs 	service_t *svc = handle;
143355b4669Sjacobs 	printer_t *p = NULL;
144355b4669Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
145355b4669Sjacobs 
146355b4669Sjacobs 	if ((svc == NULL) || (name == NULL) || (printer == NULL))
147355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
148355b4669Sjacobs 
149355b4669Sjacobs 	/* if we are already connected, use that connection. */
150355b4669Sjacobs 	if (svc->connection == NULL)
151355b4669Sjacobs 		if ((result = service_connect(svc, name)) != PAPI_OK)
152355b4669Sjacobs 			return (result);
153355b4669Sjacobs 
154355b4669Sjacobs 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
155355b4669Sjacobs 		return (PAPI_TEMPORARY_ERROR);
156355b4669Sjacobs 
157355b4669Sjacobs 	ipp_initialize_request(svc, &request, OPID_GET_PRINTER_ATTRIBUTES);
158355b4669Sjacobs 
159*223f6c28Sjacobs 	ipp_initialize_operational_attributes(svc, &op, name, -1);
160355b4669Sjacobs 
161355b4669Sjacobs 	if (requested_attrs != NULL) {
162355b4669Sjacobs 		int i;
163355b4669Sjacobs 
164355b4669Sjacobs 		for (i = 0; requested_attrs[i] != NULL; i++)
165355b4669Sjacobs 			papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
166355b4669Sjacobs 				"requested-attributes", requested_attrs[i]);
167355b4669Sjacobs 	}
168355b4669Sjacobs 
169355b4669Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
170355b4669Sjacobs 			"operational-attributes-group", op);
171355b4669Sjacobs 	papiAttributeListFree(op);
172355b4669Sjacobs 	result = ipp_send_request(svc, request, &response);
173355b4669Sjacobs 	papiAttributeListFree(request);
174355b4669Sjacobs 
175355b4669Sjacobs 	op = NULL;
176355b4669Sjacobs 	papiAttributeListGetCollection(response, NULL,
177355b4669Sjacobs 			"printer-attributes-group", &op);
178355b4669Sjacobs 	copy_attributes(&p->attributes, op);
179355b4669Sjacobs 	papiAttributeListFree(response);
180355b4669Sjacobs 
181355b4669Sjacobs 	return (result);
182355b4669Sjacobs }
183355b4669Sjacobs 
184355b4669Sjacobs static papi_status_t
_printer_enable_disable_pause_resume_delete(papi_service_t handle,char * name,char * message,uint16_t type)185355b4669Sjacobs _printer_enable_disable_pause_resume_delete(papi_service_t handle, char *name,
186355b4669Sjacobs 		char *message, uint16_t type)
187355b4669Sjacobs {
188355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
189355b4669Sjacobs 	service_t *svc = handle;
190355b4669Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
191355b4669Sjacobs 
192355b4669Sjacobs 	if ((svc == NULL) || (name == NULL))
193355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
194355b4669Sjacobs 
195355b4669Sjacobs 	/* if we are already connected, use that connection. */
196355b4669Sjacobs 	if (svc->connection == NULL)
197355b4669Sjacobs 		if ((result = service_connect(svc, name)) != PAPI_OK)
198355b4669Sjacobs 			return (result);
199355b4669Sjacobs 
200355b4669Sjacobs 	ipp_initialize_request(svc, &request, type);
201355b4669Sjacobs 
202*223f6c28Sjacobs 	ipp_initialize_operational_attributes(svc, &op, name, -1);
203355b4669Sjacobs 
204355b4669Sjacobs 	switch (type) {
205355b4669Sjacobs 	case OPID_DISABLE_PRINTER:
206355b4669Sjacobs 		papiAttributeListAddString(&op, PAPI_ATTR_REPLACE,
207355b4669Sjacobs 				"printer-message-from-operator", message);
208355b4669Sjacobs 		break;
209355b4669Sjacobs 	case OPID_PAUSE_PRINTER:
210355b4669Sjacobs 		papiAttributeListAddString(&op, PAPI_ATTR_REPLACE,
211355b4669Sjacobs 				"printer-state-message", message);
212355b4669Sjacobs 		break;
213355b4669Sjacobs 	default: /* a message value is of no use */
214355b4669Sjacobs 		break;
215355b4669Sjacobs 	}
216355b4669Sjacobs 
217355b4669Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
218355b4669Sjacobs 			"operational-attributes-group", op);
219355b4669Sjacobs 	papiAttributeListFree(op);
220355b4669Sjacobs 	result = ipp_send_request(svc, request, &response);
221355b4669Sjacobs 	papiAttributeListFree(request);
222355b4669Sjacobs 	papiAttributeListFree(response);
223355b4669Sjacobs 
224355b4669Sjacobs 	return (result);
225355b4669Sjacobs }
226355b4669Sjacobs 
227355b4669Sjacobs papi_status_t
papiPrinterEnable(papi_service_t handle,char * name)228355b4669Sjacobs papiPrinterEnable(papi_service_t handle, char *name)
229355b4669Sjacobs {
230355b4669Sjacobs 	return (_printer_enable_disable_pause_resume_delete(handle, name,
231355b4669Sjacobs 				NULL, OPID_ENABLE_PRINTER));
232355b4669Sjacobs }
233355b4669Sjacobs 
234355b4669Sjacobs papi_status_t
papiPrinterResume(papi_service_t handle,char * name)235355b4669Sjacobs papiPrinterResume(papi_service_t handle, char *name)
236355b4669Sjacobs {
237355b4669Sjacobs 	return (_printer_enable_disable_pause_resume_delete(handle, name,
238355b4669Sjacobs 				NULL, OPID_RESUME_PRINTER));
239355b4669Sjacobs }
240355b4669Sjacobs 
241355b4669Sjacobs papi_status_t
papiPrinterPause(papi_service_t handle,char * name,char * message)242355b4669Sjacobs papiPrinterPause(papi_service_t handle, char *name, char *message)
243355b4669Sjacobs {
244355b4669Sjacobs 	return (_printer_enable_disable_pause_resume_delete(handle, name,
245355b4669Sjacobs 				message, OPID_PAUSE_PRINTER));
246355b4669Sjacobs }
247355b4669Sjacobs 
248355b4669Sjacobs papi_status_t
papiPrinterDisable(papi_service_t handle,char * name,char * message)249355b4669Sjacobs papiPrinterDisable(papi_service_t handle, char *name, char *message)
250355b4669Sjacobs {
251355b4669Sjacobs 	return (_printer_enable_disable_pause_resume_delete(handle, name,
252355b4669Sjacobs 				message, OPID_PAUSE_PRINTER));
253355b4669Sjacobs }
254355b4669Sjacobs 
255355b4669Sjacobs /*
256355b4669Sjacobs  * there is no IPP create operation, the set-printer-attibutes operation
257355b4669Sjacobs  * is the closest we have, so we will assume that the server will create
258355b4669Sjacobs  * a printer and set attributes if there is none.
259355b4669Sjacobs  */
260355b4669Sjacobs papi_status_t
papiPrinterAdd(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_printer_t * printer)261355b4669Sjacobs papiPrinterAdd(papi_service_t handle, char *name,
262355b4669Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer)
263355b4669Sjacobs {
264355b4669Sjacobs 	return (papiPrinterModify(handle, name, attributes, printer));
265355b4669Sjacobs }
266355b4669Sjacobs 
267355b4669Sjacobs papi_status_t
papiPrinterModify(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_printer_t * printer)268355b4669Sjacobs papiPrinterModify(papi_service_t handle, char *name,
269355b4669Sjacobs 		papi_attribute_t **attributes, papi_printer_t *printer)
270355b4669Sjacobs {
271355b4669Sjacobs 	papi_status_t result = PAPI_INTERNAL_ERROR;
272355b4669Sjacobs 	service_t *svc = handle;
273355b4669Sjacobs 	printer_t *p = NULL;
274355b4669Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
275355b4669Sjacobs 
276355b4669Sjacobs 	if ((svc == NULL) || (name == NULL) || (printer == NULL))
277355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
278355b4669Sjacobs 
279355b4669Sjacobs 	/* if we are already connected, use that connection. */
280355b4669Sjacobs 	if (svc->connection == NULL)
281355b4669Sjacobs 		if ((result = service_connect(svc, name)) != PAPI_OK)
282355b4669Sjacobs 			return (result);
283355b4669Sjacobs 
284355b4669Sjacobs 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
285355b4669Sjacobs 		return (PAPI_TEMPORARY_ERROR);
286355b4669Sjacobs 
287355b4669Sjacobs 	ipp_initialize_request(svc, &request, OPID_SET_PRINTER_ATTRIBUTES);
288355b4669Sjacobs 
289*223f6c28Sjacobs 	ipp_initialize_operational_attributes(svc, &op, name, -1);
290355b4669Sjacobs 
291355b4669Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
292355b4669Sjacobs 			"operational-attributes-group", op);
293355b4669Sjacobs 	papiAttributeListFree(op);
294355b4669Sjacobs 
295355b4669Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
296355b4669Sjacobs 			"printer-attributes-group", attributes);
297355b4669Sjacobs 	result = ipp_send_request(svc, request, &response);
298355b4669Sjacobs 	papiAttributeListFree(request);
299355b4669Sjacobs 
300355b4669Sjacobs 	op = NULL;
301355b4669Sjacobs 	papiAttributeListGetCollection(response, NULL,
302355b4669Sjacobs 			"printer-attributes-group", &op);
303355b4669Sjacobs 	copy_attributes(&p->attributes, op);
304355b4669Sjacobs 	papiAttributeListFree(response);
305355b4669Sjacobs 
306355b4669Sjacobs 	return (result);
307355b4669Sjacobs }
308355b4669Sjacobs 
309355b4669Sjacobs papi_status_t
papiPrinterRemove(papi_service_t handle,char * name)310355b4669Sjacobs papiPrinterRemove(papi_service_t handle, char *name)
311355b4669Sjacobs {
312355b4669Sjacobs 	return (_printer_enable_disable_pause_resume_delete(handle, name,
313355b4669Sjacobs 				NULL, OPID_CUPS_DELETE_PRINTER));
314355b4669Sjacobs }
315355b4669Sjacobs 
316355b4669Sjacobs papi_status_t
papiPrinterPurgeJobs(papi_service_t handle,char * name,papi_job_t ** jobs)317355b4669Sjacobs papiPrinterPurgeJobs(papi_service_t handle, char *name,
318355b4669Sjacobs 		papi_job_t **jobs)
319355b4669Sjacobs {
320355b4669Sjacobs 	papi_status_t status, result = PAPI_INTERNAL_ERROR;
321355b4669Sjacobs 	service_t *svc = handle;
322355b4669Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
323355b4669Sjacobs 	void *iter = NULL;
324355b4669Sjacobs 
325355b4669Sjacobs 
326355b4669Sjacobs 	if ((svc == NULL) || (name == NULL))
327355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
328355b4669Sjacobs 
329355b4669Sjacobs 	/* if we are already connected, use that connection. */
330355b4669Sjacobs 	if (svc->connection == NULL)
331355b4669Sjacobs 		if ((result = service_connect(svc, name)) != PAPI_OK)
332355b4669Sjacobs 			return (result);
333355b4669Sjacobs 
334355b4669Sjacobs 	ipp_initialize_request(svc, &request, OPID_PURGE_JOBS);
335355b4669Sjacobs 
336*223f6c28Sjacobs 	ipp_initialize_operational_attributes(svc, &op, name, -1);
337355b4669Sjacobs 
338355b4669Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
339355b4669Sjacobs 			"operational-attributes-group", op);
340355b4669Sjacobs 	papiAttributeListFree(op);
341355b4669Sjacobs 	result = ipp_send_request(svc, request, &response);
342355b4669Sjacobs 	papiAttributeListFree(request);
343355b4669Sjacobs 
344355b4669Sjacobs 	op = NULL;
345355b4669Sjacobs 	for (status = papiAttributeListGetCollection(response, &iter,
346355b4669Sjacobs 				"job-attributes-group", &op);
347355b4669Sjacobs 	     status == PAPI_OK;
348355b4669Sjacobs 	     status = papiAttributeListGetCollection(response, &iter,
349355b4669Sjacobs 				NULL, &op)) {
350355b4669Sjacobs 		job_t *j = NULL;
351355b4669Sjacobs 
352355b4669Sjacobs 		if ((j = calloc(1, sizeof (*j))) == NULL)
353355b4669Sjacobs 			return (PAPI_TEMPORARY_ERROR);
354355b4669Sjacobs 
355355b4669Sjacobs 		copy_attributes(&j->attributes, op);
356355b4669Sjacobs 		op = NULL;
357355b4669Sjacobs 		list_append(jobs, j);
358355b4669Sjacobs 	}
359355b4669Sjacobs 	papiAttributeListFree(response);
360355b4669Sjacobs 
361355b4669Sjacobs 	return (result);
362355b4669Sjacobs }
363355b4669Sjacobs 
364355b4669Sjacobs papi_status_t
papiPrinterListJobs(papi_service_t handle,char * name,char ** requested_attrs,int type_mask,int max_num_jobs,papi_job_t ** jobs)365355b4669Sjacobs papiPrinterListJobs(papi_service_t handle, char *name,
366355b4669Sjacobs 		char **requested_attrs, int type_mask,
367355b4669Sjacobs 		int max_num_jobs, papi_job_t **jobs)
368355b4669Sjacobs {
369355b4669Sjacobs 	papi_status_t status, result = PAPI_INTERNAL_ERROR;
370355b4669Sjacobs 	service_t *svc = handle;
371355b4669Sjacobs 	papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
372355b4669Sjacobs 	void *iter = NULL;
373355b4669Sjacobs 
374355b4669Sjacobs 	if ((svc == NULL) || (name == NULL))
375355b4669Sjacobs 		return (PAPI_BAD_ARGUMENT);
376355b4669Sjacobs 
377355b4669Sjacobs 	/* if we are already connected, use that connection. */
378355b4669Sjacobs 	if (svc->connection == NULL)
379355b4669Sjacobs 		if ((result = service_connect(svc, name)) != PAPI_OK)
380355b4669Sjacobs 			return (result);
381355b4669Sjacobs 
382355b4669Sjacobs 	ipp_initialize_request(svc, &request, OPID_GET_JOBS);
383355b4669Sjacobs 
384*223f6c28Sjacobs 	ipp_initialize_operational_attributes(svc, &op, name, -1);
385355b4669Sjacobs 
386355b4669Sjacobs 	if (requested_attrs != NULL) {
387355b4669Sjacobs 		int i;
388355b4669Sjacobs 
389355b4669Sjacobs 		for (i = 0; requested_attrs[i] != NULL; i++)
390355b4669Sjacobs 			papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
391355b4669Sjacobs 				"requested-attributes", requested_attrs[i]);
392355b4669Sjacobs 	}
393355b4669Sjacobs 
394355b4669Sjacobs 	papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
395355b4669Sjacobs 			"operational-attributes-group", op);
396355b4669Sjacobs 	papiAttributeListFree(op);
397355b4669Sjacobs 	result = ipp_send_request(svc, request, &response);
398355b4669Sjacobs 	papiAttributeListFree(request);
399355b4669Sjacobs 
400355b4669Sjacobs 	op = NULL;
401355b4669Sjacobs 	for (status = papiAttributeListGetCollection(response, &iter,
402355b4669Sjacobs 				"job-attributes-group", &op);
403355b4669Sjacobs 	     status == PAPI_OK;
404355b4669Sjacobs 	     status = papiAttributeListGetCollection(response, &iter,
405355b4669Sjacobs 				NULL, &op)) {
406355b4669Sjacobs 		job_t *j = NULL;
407355b4669Sjacobs 
408355b4669Sjacobs 		if ((j = calloc(1, sizeof (*j))) == NULL)
409355b4669Sjacobs 			return (PAPI_TEMPORARY_ERROR);
410355b4669Sjacobs 
411355b4669Sjacobs 		copy_attributes(&j->attributes, op);
412355b4669Sjacobs 		op = NULL;
413355b4669Sjacobs 		list_append(jobs, j);
414355b4669Sjacobs 	}
415355b4669Sjacobs 	papiAttributeListFree(response);
416355b4669Sjacobs 
417355b4669Sjacobs 	return (result);
418355b4669Sjacobs }
419355b4669Sjacobs 
420355b4669Sjacobs papi_attribute_t **
papiPrinterGetAttributeList(papi_printer_t printer)421355b4669Sjacobs papiPrinterGetAttributeList(papi_printer_t printer)
422355b4669Sjacobs {
423355b4669Sjacobs 	papi_attribute_t **result = NULL;
424355b4669Sjacobs 	printer_t *p = printer;
425355b4669Sjacobs 
426355b4669Sjacobs 	if (p != NULL)
427355b4669Sjacobs 		result = p->attributes;
428355b4669Sjacobs 
429355b4669Sjacobs 	return (result);
430355b4669Sjacobs }
431