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