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 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 /*LINTLIBRARY*/
33
34 #include <stdlib.h>
35 #include <papi_impl.h>
36
37 #include <config-site.h>
38
39 void
papiPrinterFree(papi_printer_t printer)40 papiPrinterFree(papi_printer_t printer)
41 {
42 printer_t *tmp = printer;
43
44 if (tmp != NULL) {
45 if (tmp->attributes != NULL)
46 papiAttributeListFree(tmp->attributes);
47 free(tmp);
48 }
49 }
50
51 void
papiPrinterListFree(papi_printer_t * printers)52 papiPrinterListFree(papi_printer_t *printers)
53 {
54 if (printers != NULL) {
55 int i;
56
57 for (i = 0; printers[i] != NULL; i++)
58 papiPrinterFree(printers[i]);
59 free(printers);
60 }
61 }
62
63 /*
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
69 * to IPP clients.
70 */
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 */
80
81 papi_status_t
papiPrintersList(papi_service_t handle,char ** requested_attrs,papi_filter_t * filter,papi_printer_t ** printers)82 papiPrintersList(papi_service_t handle, char **requested_attrs,
83 papi_filter_t *filter, papi_printer_t **printers)
84 {
85 papi_status_t status, result = PAPI_INTERNAL_ERROR;
86 service_t *svc = handle;
87 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
88 void *iter = NULL;
89
90 if ((svc == NULL) || (printers == NULL))
91 return (PAPI_BAD_ARGUMENT);
92
93 /* if we are already connected, use that connection. */
94 if (svc->connection == NULL)
95 if ((result = service_connect(svc, DEFAULT_DEST)) != PAPI_OK)
96 return (result);
97 ipp_initialize_request(svc, &request, OPID_CUPS_GET_PRINTERS);
98
99 ipp_initialize_operational_attributes(svc, &op, NULL, -1);
100
101 if (requested_attrs != NULL) {
102 int i;
103
104 for (i = 0; requested_attrs[i] != NULL; i++)
105 papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
106 "requested-attributes", requested_attrs[i]);
107 }
108
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);
114
115 op = NULL;
116 for (status = papiAttributeListGetCollection(response, &iter,
117 "printer-attributes-group", &op);
118 status == PAPI_OK;
119 status = papiAttributeListGetCollection(response, &iter,
120 NULL, &op)) {
121 printer_t *p = NULL;
122
123 if ((p = calloc(1, sizeof (*p))) == NULL)
124 return (PAPI_TEMPORARY_ERROR);
125
126 copy_attributes(&p->attributes, op);
127 op = NULL;
128 list_append(printers, p);
129 }
130 papiAttributeListFree(response);
131
132 return (result);
133 }
134
135 papi_status_t
papiPrinterQuery(papi_service_t handle,char * name,char ** requested_attrs,papi_attribute_t ** job_attributes,papi_printer_t * printer)136 papiPrinterQuery(papi_service_t handle, char *name,
137 char **requested_attrs,
138 papi_attribute_t **job_attributes,
139 papi_printer_t *printer)
140 {
141 papi_status_t result = PAPI_INTERNAL_ERROR;
142 service_t *svc = handle;
143 printer_t *p = NULL;
144 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
145
146 if ((svc == NULL) || (name == NULL) || (printer == NULL))
147 return (PAPI_BAD_ARGUMENT);
148
149 /* if we are already connected, use that connection. */
150 if (svc->connection == NULL)
151 if ((result = service_connect(svc, name)) != PAPI_OK)
152 return (result);
153
154 if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
155 return (PAPI_TEMPORARY_ERROR);
156
157 ipp_initialize_request(svc, &request, OPID_GET_PRINTER_ATTRIBUTES);
158
159 ipp_initialize_operational_attributes(svc, &op, name, -1);
160
161 if (requested_attrs != NULL) {
162 int i;
163
164 for (i = 0; requested_attrs[i] != NULL; i++)
165 papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
166 "requested-attributes", requested_attrs[i]);
167 }
168
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);
174
175 op = NULL;
176 papiAttributeListGetCollection(response, NULL,
177 "printer-attributes-group", &op);
178 copy_attributes(&p->attributes, op);
179 papiAttributeListFree(response);
180
181 return (result);
182 }
183
184 static papi_status_t
_printer_enable_disable_pause_resume_delete(papi_service_t handle,char * name,char * message,uint16_t type)185 _printer_enable_disable_pause_resume_delete(papi_service_t handle, char *name,
186 char *message, uint16_t type)
187 {
188 papi_status_t result = PAPI_INTERNAL_ERROR;
189 service_t *svc = handle;
190 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
191
192 if ((svc == NULL) || (name == NULL))
193 return (PAPI_BAD_ARGUMENT);
194
195 /* if we are already connected, use that connection. */
196 if (svc->connection == NULL)
197 if ((result = service_connect(svc, name)) != PAPI_OK)
198 return (result);
199
200 ipp_initialize_request(svc, &request, type);
201
202 ipp_initialize_operational_attributes(svc, &op, name, -1);
203
204 switch (type) {
205 case OPID_DISABLE_PRINTER:
206 papiAttributeListAddString(&op, PAPI_ATTR_REPLACE,
207 "printer-message-from-operator", message);
208 break;
209 case OPID_PAUSE_PRINTER:
210 papiAttributeListAddString(&op, PAPI_ATTR_REPLACE,
211 "printer-state-message", message);
212 break;
213 default: /* a message value is of no use */
214 break;
215 }
216
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);
223
224 return (result);
225 }
226
227 papi_status_t
papiPrinterEnable(papi_service_t handle,char * name)228 papiPrinterEnable(papi_service_t handle, char *name)
229 {
230 return (_printer_enable_disable_pause_resume_delete(handle, name,
231 NULL, OPID_ENABLE_PRINTER));
232 }
233
234 papi_status_t
papiPrinterResume(papi_service_t handle,char * name)235 papiPrinterResume(papi_service_t handle, char *name)
236 {
237 return (_printer_enable_disable_pause_resume_delete(handle, name,
238 NULL, OPID_RESUME_PRINTER));
239 }
240
241 papi_status_t
papiPrinterPause(papi_service_t handle,char * name,char * message)242 papiPrinterPause(papi_service_t handle, char *name, char *message)
243 {
244 return (_printer_enable_disable_pause_resume_delete(handle, name,
245 message, OPID_PAUSE_PRINTER));
246 }
247
248 papi_status_t
papiPrinterDisable(papi_service_t handle,char * name,char * message)249 papiPrinterDisable(papi_service_t handle, char *name, char *message)
250 {
251 return (_printer_enable_disable_pause_resume_delete(handle, name,
252 message, OPID_PAUSE_PRINTER));
253 }
254
255 /*
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.
259 */
260 papi_status_t
papiPrinterAdd(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_printer_t * printer)261 papiPrinterAdd(papi_service_t handle, char *name,
262 papi_attribute_t **attributes, papi_printer_t *printer)
263 {
264 return (papiPrinterModify(handle, name, attributes, printer));
265 }
266
267 papi_status_t
papiPrinterModify(papi_service_t handle,char * name,papi_attribute_t ** attributes,papi_printer_t * printer)268 papiPrinterModify(papi_service_t handle, char *name,
269 papi_attribute_t **attributes, papi_printer_t *printer)
270 {
271 papi_status_t result = PAPI_INTERNAL_ERROR;
272 service_t *svc = handle;
273 printer_t *p = NULL;
274 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
275
276 if ((svc == NULL) || (name == NULL) || (printer == NULL))
277 return (PAPI_BAD_ARGUMENT);
278
279 /* if we are already connected, use that connection. */
280 if (svc->connection == NULL)
281 if ((result = service_connect(svc, name)) != PAPI_OK)
282 return (result);
283
284 if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
285 return (PAPI_TEMPORARY_ERROR);
286
287 ipp_initialize_request(svc, &request, OPID_SET_PRINTER_ATTRIBUTES);
288
289 ipp_initialize_operational_attributes(svc, &op, name, -1);
290
291 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
292 "operational-attributes-group", op);
293 papiAttributeListFree(op);
294
295 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE,
296 "printer-attributes-group", attributes);
297 result = ipp_send_request(svc, request, &response);
298 papiAttributeListFree(request);
299
300 op = NULL;
301 papiAttributeListGetCollection(response, NULL,
302 "printer-attributes-group", &op);
303 copy_attributes(&p->attributes, op);
304 papiAttributeListFree(response);
305
306 return (result);
307 }
308
309 papi_status_t
papiPrinterRemove(papi_service_t handle,char * name)310 papiPrinterRemove(papi_service_t handle, char *name)
311 {
312 return (_printer_enable_disable_pause_resume_delete(handle, name,
313 NULL, OPID_CUPS_DELETE_PRINTER));
314 }
315
316 papi_status_t
papiPrinterPurgeJobs(papi_service_t handle,char * name,papi_job_t ** jobs)317 papiPrinterPurgeJobs(papi_service_t handle, char *name,
318 papi_job_t **jobs)
319 {
320 papi_status_t status, result = PAPI_INTERNAL_ERROR;
321 service_t *svc = handle;
322 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
323 void *iter = NULL;
324
325
326 if ((svc == NULL) || (name == NULL))
327 return (PAPI_BAD_ARGUMENT);
328
329 /* if we are already connected, use that connection. */
330 if (svc->connection == NULL)
331 if ((result = service_connect(svc, name)) != PAPI_OK)
332 return (result);
333
334 ipp_initialize_request(svc, &request, OPID_PURGE_JOBS);
335
336 ipp_initialize_operational_attributes(svc, &op, name, -1);
337
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);
343
344 op = NULL;
345 for (status = papiAttributeListGetCollection(response, &iter,
346 "job-attributes-group", &op);
347 status == PAPI_OK;
348 status = papiAttributeListGetCollection(response, &iter,
349 NULL, &op)) {
350 job_t *j = NULL;
351
352 if ((j = calloc(1, sizeof (*j))) == NULL)
353 return (PAPI_TEMPORARY_ERROR);
354
355 copy_attributes(&j->attributes, op);
356 op = NULL;
357 list_append(jobs, j);
358 }
359 papiAttributeListFree(response);
360
361 return (result);
362 }
363
364 papi_status_t
papiPrinterListJobs(papi_service_t handle,char * name,char ** requested_attrs,int type_mask,int max_num_jobs,papi_job_t ** jobs)365 papiPrinterListJobs(papi_service_t handle, char *name,
366 char **requested_attrs, int type_mask,
367 int max_num_jobs, papi_job_t **jobs)
368 {
369 papi_status_t status, result = PAPI_INTERNAL_ERROR;
370 service_t *svc = handle;
371 papi_attribute_t **request = NULL, **op = NULL, **response = NULL;
372 void *iter = NULL;
373
374 if ((svc == NULL) || (name == NULL))
375 return (PAPI_BAD_ARGUMENT);
376
377 /* if we are already connected, use that connection. */
378 if (svc->connection == NULL)
379 if ((result = service_connect(svc, name)) != PAPI_OK)
380 return (result);
381
382 ipp_initialize_request(svc, &request, OPID_GET_JOBS);
383
384 ipp_initialize_operational_attributes(svc, &op, name, -1);
385
386 if (requested_attrs != NULL) {
387 int i;
388
389 for (i = 0; requested_attrs[i] != NULL; i++)
390 papiAttributeListAddString(&op, PAPI_ATTR_APPEND,
391 "requested-attributes", requested_attrs[i]);
392 }
393
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);
399
400 op = NULL;
401 for (status = papiAttributeListGetCollection(response, &iter,
402 "job-attributes-group", &op);
403 status == PAPI_OK;
404 status = papiAttributeListGetCollection(response, &iter,
405 NULL, &op)) {
406 job_t *j = NULL;
407
408 if ((j = calloc(1, sizeof (*j))) == NULL)
409 return (PAPI_TEMPORARY_ERROR);
410
411 copy_attributes(&j->attributes, op);
412 op = NULL;
413 list_append(jobs, j);
414 }
415 papiAttributeListFree(response);
416
417 return (result);
418 }
419
420 papi_attribute_t **
papiPrinterGetAttributeList(papi_printer_t printer)421 papiPrinterGetAttributeList(papi_printer_t printer)
422 {
423 papi_attribute_t **result = NULL;
424 printer_t *p = printer;
425
426 if (p != NULL)
427 result = p->attributes;
428
429 return (result);
430 }
431