1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 */
27
28 /* $Id: printer.c 146 2006-03-24 00:26:54Z njacobs $ */
29
30 /*LINTLIBRARY*/
31
32 #include <stdlib.h>
33 #include <papi_impl.h>
34
35 #include <config-site.h>
36
37 void
papiPrinterFree(papi_printer_t printer)38 papiPrinterFree(papi_printer_t printer)
39 {
40 printer_t *tmp = printer;
41
42 if (tmp != NULL) {
43 if (tmp->attributes != NULL)
44 papiAttributeListFree(tmp->attributes);
45 free(tmp);
46 }
47 }
48
49 void
papiPrinterListFree(papi_printer_t * printers)50 papiPrinterListFree(papi_printer_t *printers)
51 {
52 if (printers != NULL) {
53 int i;
54
55 for (i = 0; printers[i] != NULL; i++)
56 papiPrinterFree(printers[i]);
57 free(printers);
58 }
59 }
60
61 /*
62 * Enumeration of printers is not part of the IPP specification, so many
63 * servers will probably not respond back with a list of printers, but
64 * CUPS has implemented an extension to IPP to enumerate printers and
65 * classes. the Apache/mod_ipp IPP listener module available in Solaris
66 * implements this IPP extension, so CUPS and Solaris can provide this
67 * to IPP clients.
68 */
69 #ifndef OPID_CUPS_GET_PRINTERS /* for servers that will enumerate */
70 #define OPID_CUPS_GET_PRINTERS 0x4002
71 #endif /* OPID_CUPS_GET_PRINTERS */
72 #ifndef OPID_CUPS_DELETE_PRINTER /* for servers that can delete */
73 #define OPID_CUPS_DELETE_PRINTER 0x4004
74 #endif /* OPID_CUPS_DELETE_PRINTER */
75 #ifndef OPID_CUPS_GET_CLASSES /* for servers that will enumerate */
76 #define OPID_CUPS_GET_CLASSES 0x4005
77 #endif /* OPID_CUPS_GET_CLASSES */
78
79 papi_status_t
papiPrintersList(papi_service_t handle,char ** requested_attrs,papi_filter_t * filter,papi_printer_t ** printers)80 papiPrintersList(papi_service_t handle, char **requested_attrs,
81 papi_filter_t *filter, papi_printer_t **printers)
82 {
83 papi_status_t status, result = PAPI_INTERNAL_ERROR;
84 service_t *svc = handle;
85 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
86 void *iter = NULL;
87
88 if ((svc == NULL) || (printers == NULL))
89 return (PAPI_BAD_ARGUMENT);
90
91 /* if we are already connected, use that connection. */
92 if (svc->connection == NULL)
93 if ((result = service_connect(svc, DEFAULT_DEST)) != PAPI_OK)
94 return (result);
95 ipp_initialize_request(svc, &request, OPID_CUPS_GET_PRINTERS);
96
97 ipp_initialize_operational_attributes(svc, &op, NULL, -1);
98
99 if (requested_attrs != NULL) {
100 int i;
101
102 for (i = 0; requested_attrs[i] != NULL; i++)
103 papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
104 "requested-attributes", requested_attrs[i]);
105 }
106
107 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
108 "operational-attributes-group", op);
109 papiAttributeListFree(op);
110 result = ipp_send_request(svc, request, &response);
111 papiAttributeListFree(request);
112
113 op = NULL;
114 for (status = papiAttributeListGetCollection(response, &iter,
115 "printer-attributes-group", &op);
116 status == PAPI_OK;
117 status = papiAttributeListGetCollection(response, &iter,
118 NULL, &op)) {
119 printer_t *p = NULL;
120
121 if ((p = calloc(1, sizeof (*p))) == NULL)
122 return (PAPI_TEMPORARY_ERROR);
123
124 copy_attributes(&p->attributes, op);
125 op = NULL;
126 list_append(printers, p);
127 }
128 papiAttributeListFree(response);
129
130 return (result);
131 }
132
133 papi_status_t
papiPrinterQuery(papi_service_t handle,char * name,char ** requested_attrs,papi_attribute_t ** job_attributes,papi_printer_t * printer)134 papiPrinterQuery(papi_service_t handle, char *name,
135 char **requested_attrs,
136 papi_attribute_t **job_attributes,
137 papi_printer_t *printer)
138 {
139 papi_status_t result = PAPI_INTERNAL_ERROR;
140 service_t *svc = handle;
141 printer_t *p = NULL;
142 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
143
144 if ((svc == NULL) || (name == NULL) || (printer == NULL))
145 return (PAPI_BAD_ARGUMENT);
146
147 /* if we are already connected, use that connection. */
148 if (svc->connection == NULL)
149 if ((result = service_connect(svc, name)) != PAPI_OK)
150 return (result);
151
152 if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
153 return (PAPI_TEMPORARY_ERROR);
154
155 ipp_initialize_request(svc, &request, OPID_GET_PRINTER_ATTRIBUTES);
156
157 ipp_initialize_operational_attributes(svc, &op, name, -1);
158
159 if (requested_attrs != NULL) {
160 int i;
161
162 for (i = 0; requested_attrs[i] != NULL; i++)
163 papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
164 "requested-attributes", requested_attrs[i]);
165 }
166
167 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
168 "operational-attributes-group", op);
169 papiAttributeListFree(op);
170 result = ipp_send_request(svc, request, &response);
171 papiAttributeListFree(request);
172
173 op = NULL;
174 papiAttributeListGetCollection(response, NULL,
175 "printer-attributes-group", &op);
176 copy_attributes(&p->attributes, op);
177 papiAttributeListFree(response);
178
179 return (result);
180 }
181
182 static papi_status_t
_printer_enable_disable_pause_resume_delete(papi_service_t handle,char * name,char * message,uint16_t type)183 _printer_enable_disable_pause_resume_delete(papi_service_t handle, char *name,
184 char *message, uint16_t type)
185 {
186 papi_status_t result = PAPI_INTERNAL_ERROR;
187 service_t *svc = handle;
188 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
189
190 if ((svc == NULL) || (name == NULL))
191 return (PAPI_BAD_ARGUMENT);
192
193 /* if we are already connected, use that connection. */
194 if (svc->connection == NULL)
195 if ((result = service_connect(svc, name)) != PAPI_OK)
196 return (result);
197
198 ipp_initialize_request(svc, &request, type);
199
200 ipp_initialize_operational_attributes(svc, &op, name, -1);
201
202 switch (type) {
203 case OPID_DISABLE_PRINTER:
204 papiAttributeListAddString(&op, PAPI_ATTR_REPLACE,
205 "printer-message-from-operator", message);
206 break;
207 case OPID_PAUSE_PRINTER:
208 papiAttributeListAddString(&op, PAPI_ATTR_REPLACE,
209 "printer-state-message", message);
210 break;
211 default: /* a message value is of no use */
212 break;
213 }
214
215 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
216 "operational-attributes-group", op);
217 papiAttributeListFree(op);
218 result = ipp_send_request(svc, request, &response);
219 papiAttributeListFree(request);
220 papiAttributeListFree(response);
221
222 return (result);
223 }
224
225 papi_status_t
papiPrinterEnable(papi_service_t handle,char * name)226 papiPrinterEnable(papi_service_t handle, char *name)
227 {
228 return (_printer_enable_disable_pause_resume_delete(handle, name,
229 NULL, OPID_ENABLE_PRINTER));
230 }
231
232 papi_status_t
papiPrinterResume(papi_service_t handle,char * name)233 papiPrinterResume(papi_service_t handle, char *name)
234 {
235 return (_printer_enable_disable_pause_resume_delete(handle, name,
236 NULL, OPID_RESUME_PRINTER));
237 }
238
239 papi_status_t
papiPrinterPause(papi_service_t handle,char * name,char * message)240 papiPrinterPause(papi_service_t handle, char *name, char *message)
241 {
242 return (_printer_enable_disable_pause_resume_delete(handle, name,
243 message, OPID_PAUSE_PRINTER));
244 }
245
246 papi_status_t
papiPrinterDisable(papi_service_t handle,char * name,char * message)247 papiPrinterDisable(papi_service_t handle, char *name, char *message)
248 {
249 return (_printer_enable_disable_pause_resume_delete(handle, name,
250 message, OPID_PAUSE_PRINTER));
251 }
252
253 /*
254 * there is no IPP create operation, the set-printer-attibutes operation
255 * is the closest we have, so we will assume that the server will create
256 * a printer and set attributes if there is none.
257 */
258 papi_status_t
papiPrinterAdd(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_printer_t * printer)259 papiPrinterAdd(papi_service_t handle, char *name,
260 papi_attribute_t **attributes, papi_printer_t *printer)
261 {
262 return (papiPrinterModify(handle, name, attributes, printer));
263 }
264
265 papi_status_t
papiPrinterModify(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_printer_t * printer)266 papiPrinterModify(papi_service_t handle, char *name,
267 papi_attribute_t **attributes, papi_printer_t *printer)
268 {
269 papi_status_t result = PAPI_INTERNAL_ERROR;
270 service_t *svc = handle;
271 printer_t *p = NULL;
272 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
273
274 if ((svc == NULL) || (name == NULL) || (printer == NULL))
275 return (PAPI_BAD_ARGUMENT);
276
277 /* if we are already connected, use that connection. */
278 if (svc->connection == NULL)
279 if ((result = service_connect(svc, name)) != PAPI_OK)
280 return (result);
281
282 if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
283 return (PAPI_TEMPORARY_ERROR);
284
285 ipp_initialize_request(svc, &request, OPID_SET_PRINTER_ATTRIBUTES);
286
287 ipp_initialize_operational_attributes(svc, &op, name, -1);
288
289 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
290 "operational-attributes-group", op);
291 papiAttributeListFree(op);
292
293 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
294 "printer-attributes-group", attributes);
295 result = ipp_send_request(svc, request, &response);
296 papiAttributeListFree(request);
297
298 op = NULL;
299 papiAttributeListGetCollection(response, NULL,
300 "printer-attributes-group", &op);
301 copy_attributes(&p->attributes, op);
302 papiAttributeListFree(response);
303
304 return (result);
305 }
306
307 papi_status_t
papiPrinterRemove(papi_service_t handle,char * name)308 papiPrinterRemove(papi_service_t handle, char *name)
309 {
310 return (_printer_enable_disable_pause_resume_delete(handle, name,
311 NULL, OPID_CUPS_DELETE_PRINTER));
312 }
313
314 papi_status_t
papiPrinterPurgeJobs(papi_service_t handle,char * name,papi_job_t ** jobs)315 papiPrinterPurgeJobs(papi_service_t handle, char *name,
316 papi_job_t **jobs)
317 {
318 papi_status_t status, result = PAPI_INTERNAL_ERROR;
319 service_t *svc = handle;
320 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
321 void *iter = NULL;
322
323
324 if ((svc == NULL) || (name == NULL))
325 return (PAPI_BAD_ARGUMENT);
326
327 /* if we are already connected, use that connection. */
328 if (svc->connection == NULL)
329 if ((result = service_connect(svc, name)) != PAPI_OK)
330 return (result);
331
332 ipp_initialize_request(svc, &request, OPID_PURGE_JOBS);
333
334 ipp_initialize_operational_attributes(svc, &op, name, -1);
335
336 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
337 "operational-attributes-group", op);
338 papiAttributeListFree(op);
339 result = ipp_send_request(svc, request, &response);
340 papiAttributeListFree(request);
341
342 op = NULL;
343 for (status = papiAttributeListGetCollection(response, &iter,
344 "job-attributes-group", &op);
345 status == PAPI_OK;
346 status = papiAttributeListGetCollection(response, &iter,
347 NULL, &op)) {
348 job_t *j = NULL;
349
350 if ((j = calloc(1, sizeof (*j))) == NULL)
351 return (PAPI_TEMPORARY_ERROR);
352
353 copy_attributes(&j->attributes, op);
354 op = NULL;
355 list_append(jobs, j);
356 }
357 papiAttributeListFree(response);
358
359 return (result);
360 }
361
362 papi_status_t
papiPrinterListJobs(papi_service_t handle,char * name,char ** requested_attrs,int type_mask,int max_num_jobs,papi_job_t ** jobs)363 papiPrinterListJobs(papi_service_t handle, char *name,
364 char **requested_attrs, int type_mask,
365 int max_num_jobs, papi_job_t **jobs)
366 {
367 papi_status_t status, result = PAPI_INTERNAL_ERROR;
368 service_t *svc = handle;
369 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
370 void *iter = NULL;
371
372 if ((svc == NULL) || (name == NULL))
373 return (PAPI_BAD_ARGUMENT);
374
375 /* if we are already connected, use that connection. */
376 if (svc->connection == NULL)
377 if ((result = service_connect(svc, name)) != PAPI_OK)
378 return (result);
379
380 ipp_initialize_request(svc, &request, OPID_GET_JOBS);
381
382 ipp_initialize_operational_attributes(svc, &op, name, -1);
383
384 if (requested_attrs != NULL) {
385 int i;
386
387 for (i = 0; requested_attrs[i] != NULL; i++)
388 papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
389 "requested-attributes", requested_attrs[i]);
390 }
391
392 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
393 "operational-attributes-group", op);
394 papiAttributeListFree(op);
395 result = ipp_send_request(svc, request, &response);
396 papiAttributeListFree(request);
397
398 op = NULL;
399 for (status = papiAttributeListGetCollection(response, &iter,
400 "job-attributes-group", &op);
401 status == PAPI_OK;
402 status = papiAttributeListGetCollection(response, &iter,
403 NULL, &op)) {
404 job_t *j = NULL;
405
406 if ((j = calloc(1, sizeof (*j))) == NULL)
407 return (PAPI_TEMPORARY_ERROR);
408
409 copy_attributes(&j->attributes, op);
410 op = NULL;
411 list_append(jobs, j);
412 }
413 papiAttributeListFree(response);
414
415 return (result);
416 }
417
418 papi_attribute_t **
papiPrinterGetAttributeList(papi_printer_t printer)419 papiPrinterGetAttributeList(papi_printer_t printer)
420 {
421 papi_attribute_t **result = NULL;
422 printer_t *p = printer;
423
424 if (p != NULL)
425 result = p->attributes;
426
427 return (result);
428 }
429