4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 /* $Id: printer.c 146 2006-03-24 00:26:54Z njacobs $ */
30 #pragma ident "%Z%%M% %I% %E% SMI"
35 #include <papi_impl.h>
37 #include <config-site.h>
40 papiPrinterFree(papi_printer_t printer
)
42 printer_t
*tmp
= printer
;
45 if (tmp
->attributes
!= NULL
)
46 papiAttributeListFree(tmp
->attributes
);
52 papiPrinterListFree(papi_printer_t
*printers
)
54 if (printers
!= NULL
) {
57 for (i
= 0; printers
[i
] != NULL
; i
++)
58 papiPrinterFree(printers
[i
]);
64 * Enumeration of printers is not part of the IPP specification, so many
65 * servers will probably not respond back with a list of printers, but
66 * CUPS has implemented an extension to IPP to enumerate printers and
67 * classes. the Apache/mod_ipp IPP listener module available in Solaris
68 * implements this IPP extension, so CUPS and Solaris can provide this
71 #ifndef OPID_CUPS_GET_PRINTERS /* for servers that will enumerate */
72 #define OPID_CUPS_GET_PRINTERS 0x4002
73 #endif /* OPID_CUPS_GET_PRINTERS */
74 #ifndef OPID_CUPS_DELETE_PRINTER /* for servers that can delete */
75 #define OPID_CUPS_DELETE_PRINTER 0x4004
76 #endif /* OPID_CUPS_DELETE_PRINTER */
77 #ifndef OPID_CUPS_GET_CLASSES /* for servers that will enumerate */
78 #define OPID_CUPS_GET_CLASSES 0x4005
79 #endif /* OPID_CUPS_GET_CLASSES */
82 papiPrintersList(papi_service_t handle
, char **requested_attrs
,
83 papi_filter_t
*filter
, papi_printer_t
**printers
)
85 papi_status_t status
, result
= PAPI_INTERNAL_ERROR
;
86 service_t
*svc
= handle
;
87 papi_attribute_t
**request
= NULL
, **op
= NULL
, **response
= NULL
;
90 if ((svc
== NULL
) || (printers
== NULL
))
91 return (PAPI_BAD_ARGUMENT
);
93 /* if we are already connected, use that connection. */
94 if (svc
->connection
== NULL
)
95 if ((result
= service_connect(svc
, DEFAULT_DEST
)) != PAPI_OK
)
97 ipp_initialize_request(svc
, &request
, OPID_CUPS_GET_PRINTERS
);
99 ipp_initialize_operational_attributes(svc
, &op
, NULL
, -1);
101 if (requested_attrs
!= NULL
) {
104 for (i
= 0; requested_attrs
[i
] != NULL
; i
++)
105 papiAttributeListAddString(&op
, PAPI_ATTR_APPEND
,
106 "requested-attributes", requested_attrs
[i
]);
109 papiAttributeListAddCollection(&request
, PAPI_ATTR_REPLACE
,
110 "operational-attributes-group", op
);
111 papiAttributeListFree(op
);
112 result
= ipp_send_request(svc
, request
, &response
);
113 papiAttributeListFree(request
);
116 for (status
= papiAttributeListGetCollection(response
, &iter
,
117 "printer-attributes-group", &op
);
119 status
= papiAttributeListGetCollection(response
, &iter
,
123 if ((p
= calloc(1, sizeof (*p
))) == NULL
)
124 return (PAPI_TEMPORARY_ERROR
);
126 copy_attributes(&p
->attributes
, op
);
128 list_append(printers
, p
);
130 papiAttributeListFree(response
);
136 papiPrinterQuery(papi_service_t handle
, char *name
,
137 char **requested_attrs
,
138 papi_attribute_t
**job_attributes
,
139 papi_printer_t
*printer
)
141 papi_status_t result
= PAPI_INTERNAL_ERROR
;
142 service_t
*svc
= handle
;
144 papi_attribute_t
**request
= NULL
, **op
= NULL
, **response
= NULL
;
146 if ((svc
== NULL
) || (name
== NULL
) || (printer
== NULL
))
147 return (PAPI_BAD_ARGUMENT
);
149 /* if we are already connected, use that connection. */
150 if (svc
->connection
== NULL
)
151 if ((result
= service_connect(svc
, name
)) != PAPI_OK
)
154 if ((*printer
= p
= calloc(1, sizeof (*p
))) == NULL
)
155 return (PAPI_TEMPORARY_ERROR
);
157 ipp_initialize_request(svc
, &request
, OPID_GET_PRINTER_ATTRIBUTES
);
159 ipp_initialize_operational_attributes(svc
, &op
, name
, -1);
161 if (requested_attrs
!= NULL
) {
164 for (i
= 0; requested_attrs
[i
] != NULL
; i
++)
165 papiAttributeListAddString(&op
, PAPI_ATTR_APPEND
,
166 "requested-attributes", requested_attrs
[i
]);
169 papiAttributeListAddCollection(&request
, PAPI_ATTR_REPLACE
,
170 "operational-attributes-group", op
);
171 papiAttributeListFree(op
);
172 result
= ipp_send_request(svc
, request
, &response
);
173 papiAttributeListFree(request
);
176 papiAttributeListGetCollection(response
, NULL
,
177 "printer-attributes-group", &op
);
178 copy_attributes(&p
->attributes
, op
);
179 papiAttributeListFree(response
);
185 _printer_enable_disable_pause_resume_delete(papi_service_t handle
, char *name
,
186 char *message
, uint16_t type
)
188 papi_status_t result
= PAPI_INTERNAL_ERROR
;
189 service_t
*svc
= handle
;
190 papi_attribute_t
**request
= NULL
, **op
= NULL
, **response
= NULL
;
192 if ((svc
== NULL
) || (name
== NULL
))
193 return (PAPI_BAD_ARGUMENT
);
195 /* if we are already connected, use that connection. */
196 if (svc
->connection
== NULL
)
197 if ((result
= service_connect(svc
, name
)) != PAPI_OK
)
200 ipp_initialize_request(svc
, &request
, type
);
202 ipp_initialize_operational_attributes(svc
, &op
, name
, -1);
205 case OPID_DISABLE_PRINTER
:
206 papiAttributeListAddString(&op
, PAPI_ATTR_REPLACE
,
207 "printer-message-from-operator", message
);
209 case OPID_PAUSE_PRINTER
:
210 papiAttributeListAddString(&op
, PAPI_ATTR_REPLACE
,
211 "printer-state-message", message
);
213 default: /* a message value is of no use */
217 papiAttributeListAddCollection(&request
, PAPI_ATTR_REPLACE
,
218 "operational-attributes-group", op
);
219 papiAttributeListFree(op
);
220 result
= ipp_send_request(svc
, request
, &response
);
221 papiAttributeListFree(request
);
222 papiAttributeListFree(response
);
228 papiPrinterEnable(papi_service_t handle
, char *name
)
230 return (_printer_enable_disable_pause_resume_delete(handle
, name
,
231 NULL
, OPID_ENABLE_PRINTER
));
235 papiPrinterResume(papi_service_t handle
, char *name
)
237 return (_printer_enable_disable_pause_resume_delete(handle
, name
,
238 NULL
, OPID_RESUME_PRINTER
));
242 papiPrinterPause(papi_service_t handle
, char *name
, char *message
)
244 return (_printer_enable_disable_pause_resume_delete(handle
, name
,
245 message
, OPID_PAUSE_PRINTER
));
249 papiPrinterDisable(papi_service_t handle
, char *name
, char *message
)
251 return (_printer_enable_disable_pause_resume_delete(handle
, name
,
252 message
, OPID_PAUSE_PRINTER
));
256 * there is no IPP create operation, the set-printer-attibutes operation
257 * is the closest we have, so we will assume that the server will create
258 * a printer and set attributes if there is none.
261 papiPrinterAdd(papi_service_t handle
, char *name
,
262 papi_attribute_t
**attributes
, papi_printer_t
*printer
)
264 return (papiPrinterModify(handle
, name
, attributes
, printer
));
268 papiPrinterModify(papi_service_t handle
, char *name
,
269 papi_attribute_t
**attributes
, papi_printer_t
*printer
)
271 papi_status_t result
= PAPI_INTERNAL_ERROR
;
272 service_t
*svc
= handle
;
274 papi_attribute_t
**request
= NULL
, **op
= NULL
, **response
= NULL
;
276 if ((svc
== NULL
) || (name
== NULL
) || (printer
== NULL
))
277 return (PAPI_BAD_ARGUMENT
);
279 /* if we are already connected, use that connection. */
280 if (svc
->connection
== NULL
)
281 if ((result
= service_connect(svc
, name
)) != PAPI_OK
)
284 if ((*printer
= p
= calloc(1, sizeof (*p
))) == NULL
)
285 return (PAPI_TEMPORARY_ERROR
);
287 ipp_initialize_request(svc
, &request
, OPID_SET_PRINTER_ATTRIBUTES
);
289 ipp_initialize_operational_attributes(svc
, &op
, name
, -1);
291 papiAttributeListAddCollection(&request
, PAPI_ATTR_REPLACE
,
292 "operational-attributes-group", op
);
293 papiAttributeListFree(op
);
295 papiAttributeListAddCollection(&request
, PAPI_ATTR_REPLACE
,
296 "printer-attributes-group", attributes
);
297 result
= ipp_send_request(svc
, request
, &response
);
298 papiAttributeListFree(request
);
301 papiAttributeListGetCollection(response
, NULL
,
302 "printer-attributes-group", &op
);
303 copy_attributes(&p
->attributes
, op
);
304 papiAttributeListFree(response
);
310 papiPrinterRemove(papi_service_t handle
, char *name
)
312 return (_printer_enable_disable_pause_resume_delete(handle
, name
,
313 NULL
, OPID_CUPS_DELETE_PRINTER
));
317 papiPrinterPurgeJobs(papi_service_t handle
, char *name
,
320 papi_status_t status
, result
= PAPI_INTERNAL_ERROR
;
321 service_t
*svc
= handle
;
322 papi_attribute_t
**request
= NULL
, **op
= NULL
, **response
= NULL
;
326 if ((svc
== NULL
) || (name
== NULL
))
327 return (PAPI_BAD_ARGUMENT
);
329 /* if we are already connected, use that connection. */
330 if (svc
->connection
== NULL
)
331 if ((result
= service_connect(svc
, name
)) != PAPI_OK
)
334 ipp_initialize_request(svc
, &request
, OPID_PURGE_JOBS
);
336 ipp_initialize_operational_attributes(svc
, &op
, name
, -1);
338 papiAttributeListAddCollection(&request
, PAPI_ATTR_REPLACE
,
339 "operational-attributes-group", op
);
340 papiAttributeListFree(op
);
341 result
= ipp_send_request(svc
, request
, &response
);
342 papiAttributeListFree(request
);
345 for (status
= papiAttributeListGetCollection(response
, &iter
,
346 "job-attributes-group", &op
);
348 status
= papiAttributeListGetCollection(response
, &iter
,
352 if ((j
= calloc(1, sizeof (*j
))) == NULL
)
353 return (PAPI_TEMPORARY_ERROR
);
355 copy_attributes(&j
->attributes
, op
);
357 list_append(jobs
, j
);
359 papiAttributeListFree(response
);
365 papiPrinterListJobs(papi_service_t handle
, char *name
,
366 char **requested_attrs
, int type_mask
,
367 int max_num_jobs
, papi_job_t
**jobs
)
369 papi_status_t status
, result
= PAPI_INTERNAL_ERROR
;
370 service_t
*svc
= handle
;
371 papi_attribute_t
**request
= NULL
, **op
= NULL
, **response
= NULL
;
374 if ((svc
== NULL
) || (name
== NULL
))
375 return (PAPI_BAD_ARGUMENT
);
377 /* if we are already connected, use that connection. */
378 if (svc
->connection
== NULL
)
379 if ((result
= service_connect(svc
, name
)) != PAPI_OK
)
382 ipp_initialize_request(svc
, &request
, OPID_GET_JOBS
);
384 ipp_initialize_operational_attributes(svc
, &op
, name
, -1);
386 if (requested_attrs
!= NULL
) {
389 for (i
= 0; requested_attrs
[i
] != NULL
; i
++)
390 papiAttributeListAddString(&op
, PAPI_ATTR_APPEND
,
391 "requested-attributes", requested_attrs
[i
]);
394 papiAttributeListAddCollection(&request
, PAPI_ATTR_REPLACE
,
395 "operational-attributes-group", op
);
396 papiAttributeListFree(op
);
397 result
= ipp_send_request(svc
, request
, &response
);
398 papiAttributeListFree(request
);
401 for (status
= papiAttributeListGetCollection(response
, &iter
,
402 "job-attributes-group", &op
);
404 status
= papiAttributeListGetCollection(response
, &iter
,
408 if ((j
= calloc(1, sizeof (*j
))) == NULL
)
409 return (PAPI_TEMPORARY_ERROR
);
411 copy_attributes(&j
->attributes
, op
);
413 list_append(jobs
, j
);
415 papiAttributeListFree(response
);
421 papiPrinterGetAttributeList(papi_printer_t printer
)
423 papi_attribute_t
**result
= NULL
;
424 printer_t
*p
= printer
;
427 result
= p
->attributes
;