xref: /illumos-gate/usr/src/lib/print/libpapi-dynamic/common/printer.c (revision 60425338a8e9a5ded7e559e227eedd42d30c8967)
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
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
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
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
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
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
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 	while ((attrs = getprinterentry(NULL)) != NULL) {
183 		printer_t *p = NULL;
184 
185 		if ((p = calloc(1, sizeof (*p))) == NULL)
186 			return (PAPI_TEMPORARY_ERROR);
187 
188 		p->attributes = attrs;
189 		list_append(printers, p);
190 	}
191 
192 	/* if we have printers, check if our request has been satisfied */
193 	if ((printers != NULL) && (*printers != NULL)) {
194 		int i;
195 
196 		/* walk through the list */
197 		for (i = 0; (*printers)[i] != NULL; i++) {
198 			printer_t *p = (*printers)[i];
199 
200 			/* see if the name service satisfied the request */
201 			if (contained(requested_attrs, p->attributes) == 0)
202 				printer_from_service(svc, p, requested_attrs);
203 		}
204 	}
205 
206 	return (PAPI_OK);
207 }
208 
209 papi_status_t
210 papiPrintersList(papi_service_t handle, char **requested_attrs,
211 		papi_filter_t *filter, papi_printer_t **printers)
212 {
213 	papi_status_t result = PAPI_INTERNAL_ERROR;
214 	service_t *svc = handle;
215 	papi_printer_t *svc_printers = NULL;
216 	papi_status_t (*f)();
217 
218 	if ((svc == NULL) || (printers == NULL))
219 		return (PAPI_BAD_ARGUMENT);
220 
221 	if (svc->so_handle != NULL)	/* connected, use the print svc */
222 		result = printers_from_service(svc, requested_attrs,
223 					filter, printers);
224 	else				/* not connected, use the name svc */
225 		result = printers_from_name_service(svc, requested_attrs,
226 					filter, printers);
227 
228 	return (result);
229 }
230 
231 papi_status_t
232 papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs,
233 		papi_attribute_t **job_attributes, papi_printer_t *printer)
234 {
235 	papi_status_t result = PAPI_INTERNAL_ERROR;
236 	service_t *svc = handle;
237 	printer_t *p = NULL;
238 	papi_status_t (*f)();
239 
240 	if ((svc == NULL) || (name == NULL) || (printer == NULL))
241 		return (PAPI_BAD_ARGUMENT);
242 
243 	if ((result = service_connect(svc, name)) != PAPI_OK)
244 		return (result);
245 
246 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
247 		return (PAPI_TEMPORARY_ERROR);
248 
249 	if ((svc->name != NULL) && (svc->svc_handle != NULL) &&
250 	    (svc->uri != NULL)) {
251 		p->svc = svc;
252 		f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery");
253 		if (f != NULL)
254 			result = f(svc->svc_handle, svc->name, requested_attrs,
255 					job_attributes, &p->printer);
256 	} else {
257 		setprinterentry(0, NULL);
258 		p->attributes = getprinterbyname(name, NULL);
259 		if (p->attributes == NULL)
260 			result = PAPI_NOT_FOUND;
261 		else
262 			result = PAPI_OK;
263 	}
264 
265 	return (result);
266 }
267 
268 static papi_status_t
269 _papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message,
270 		char *function)
271 {
272 	papi_status_t result = PAPI_INTERNAL_ERROR;
273 	service_t *svc = handle;
274 	papi_status_t (*f)();
275 
276 	if ((svc == NULL) || (name == NULL))
277 		return (PAPI_BAD_ARGUMENT);
278 
279 	if ((result = service_connect(svc, name)) != PAPI_OK)
280 		return (result);
281 
282 	f = (papi_status_t (*)())psm_sym(svc, function);
283 	if (f != NULL)
284 		result = f(svc->svc_handle, svc->name, message);
285 
286 	return (result);
287 }
288 
289 static papi_status_t
290 _papi_printer_enable_or_resume(papi_service_t handle, char *name,
291 		char *function)
292 {
293 	papi_status_t result = PAPI_INTERNAL_ERROR;
294 	service_t *svc = handle;
295 	papi_status_t (*f)();
296 
297 	if ((svc == NULL) || (name == NULL))
298 		return (PAPI_BAD_ARGUMENT);
299 
300 	if ((result = service_connect(svc, name)) != PAPI_OK)
301 		return (result);
302 
303 	f = (papi_status_t (*)())psm_sym(svc, function);
304 	if (f != NULL)
305 		result = f(svc->svc_handle, svc->name);
306 
307 	return (result);
308 }
309 
310 papi_status_t
311 papiPrinterDisable(papi_service_t handle, char *name, char *message)
312 {
313 	return (_papi_printer_disable_or_pause(handle, name, message,
314 						"papiPrinterDisable"));
315 }
316 
317 papi_status_t
318 papiPrinterPause(papi_service_t handle, char *name, char *message)
319 {
320 	return (_papi_printer_disable_or_pause(handle, name, message,
321 						"papiPrinterPause"));
322 }
323 
324 papi_status_t
325 papiPrinterEnable(papi_service_t handle, char *name)
326 {
327 	return (_papi_printer_enable_or_resume(handle, name,
328 						"papiPrinterEnable"));
329 }
330 
331 papi_status_t
332 papiPrinterResume(papi_service_t handle, char *name)
333 {
334 	return (_papi_printer_enable_or_resume(handle, name,
335 						"papiPrinterResume"));
336 }
337 
338 static papi_status_t
339 _papi_printer_add_or_modify(papi_service_t handle, char *name,
340 		papi_attribute_t **attributes, papi_printer_t *printer,
341 		char *function)
342 {
343 	papi_status_t result = PAPI_INTERNAL_ERROR;
344 	service_t *svc = handle;
345 	printer_t *p = NULL;
346 	papi_status_t (*f)();
347 
348 	if ((svc == NULL) || (name == NULL) || (attributes == NULL))
349 		return (PAPI_BAD_ARGUMENT);
350 
351 	if ((result = service_connect(svc, name)) != PAPI_OK)
352 		return (result);
353 
354 	if ((*printer = p = calloc(1, sizeof (*p))) == NULL)
355 		return (PAPI_TEMPORARY_ERROR);
356 
357 	p->svc = svc;
358 	f = (papi_status_t (*)())psm_sym(p->svc, function);
359 	if (f != NULL)
360 		result = f(svc->svc_handle, svc->name, attributes,
361 				&p->printer);
362 
363 	return (result);
364 }
365 
366 papi_status_t
367 papiPrinterAdd(papi_service_t handle, char *name,
368 		papi_attribute_t **attributes, papi_printer_t *printer)
369 {
370 	return (_papi_printer_add_or_modify(handle, name, attributes, printer,
371 						"papiPrinterAdd"));
372 }
373 
374 papi_status_t
375 papiPrinterModify(papi_service_t handle, char *name,
376 		papi_attribute_t **attributes, papi_printer_t *printer)
377 {
378 	return (_papi_printer_add_or_modify(handle, name, attributes, printer,
379 						"papiPrinterModify"));
380 }
381 
382 
383 papi_status_t
384 papiPrinterRemove(papi_service_t handle, char *name)
385 {
386 	papi_status_t result = PAPI_INTERNAL_ERROR;
387 	service_t *svc = handle;
388 	papi_status_t (*f)();
389 
390 	if ((svc == NULL) || (name == NULL))
391 		return (PAPI_BAD_ARGUMENT);
392 
393 	if ((result = service_connect(svc, name)) != PAPI_OK)
394 		return (result);
395 
396 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove");
397 	if (f != NULL)
398 		result = f(svc->svc_handle, svc->name);
399 
400 	return (result);
401 }
402 
403 papi_status_t
404 papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs)
405 {
406 	papi_status_t result = PAPI_INTERNAL_ERROR;
407 	service_t *svc = handle;
408 	papi_job_t *svc_jobs = NULL;
409 	papi_status_t (*f)();
410 
411 	if ((svc == NULL) || (name == NULL))
412 		return (PAPI_BAD_ARGUMENT);
413 
414 	if ((result = service_connect(svc, name)) != PAPI_OK)
415 		return (result);
416 
417 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs");
418 	if (f != NULL)
419 		result = f(svc->svc_handle, svc->name, &svc_jobs);
420 
421 	/*
422 	 * copy the resulting job object pointers into our own
423 	 * representation of a job object because we need the
424 	 * service context to operate against the individual job
425 	 * objects.  We free the list now because we no longer need
426 	 * it and would have no way of freeing it later.
427 	 */
428 	if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) {
429 		int i;
430 
431 		*jobs = NULL;
432 		for (i = 0; svc_jobs[i] != NULL; i++) {
433 			job_t *j = NULL;
434 
435 			if ((j = calloc(1, sizeof (*j))) == NULL)
436 				return (PAPI_TEMPORARY_ERROR);
437 
438 			j->svc = svc;
439 			j->job = svc_jobs[i];
440 			list_append(jobs, j);
441 		}
442 		free(svc_jobs);
443 	}
444 
445 	return (result);
446 }
447 
448 papi_status_t
449 papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs,
450 		int type_mask, int max_num_jobs, papi_job_t **jobs)
451 {
452 	papi_status_t result = PAPI_INTERNAL_ERROR;
453 	service_t *svc = handle;
454 	papi_job_t *svc_jobs = NULL;
455 	papi_status_t (*f)();
456 
457 	if ((svc == NULL) || (name == NULL) || (jobs == NULL))
458 		return (PAPI_BAD_ARGUMENT);
459 
460 	if ((result = service_connect(svc, name)) != PAPI_OK)
461 		return (result);
462 
463 	f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs");
464 	if (f != NULL)
465 		result = f(svc->svc_handle, svc->name, requested_attrs,
466 				type_mask, max_num_jobs, &svc_jobs);
467 
468 	/*
469 	 * copy the resulting job object pointers into our own
470 	 * representation of a job object because we need the
471 	 * service context to operate against the individual job
472 	 * objects.  We free the list now because we no longer need
473 	 * it and would have no way of freeing it later.
474 	 */
475 	if ((result == PAPI_OK) && (svc_jobs != NULL)) {
476 		int i;
477 
478 		*jobs = NULL;
479 		for (i = 0; svc_jobs[i] != NULL; i++) {
480 			job_t *j = NULL;
481 
482 			if ((j = calloc(1, sizeof (*j))) == NULL)
483 				return (PAPI_TEMPORARY_ERROR);
484 
485 			j->svc = svc;
486 			j->job = svc_jobs[i];
487 			list_append(jobs, j);
488 		}
489 		free(svc_jobs);
490 	}
491 
492 	return (result);
493 }
494 
495 papi_attribute_t **
496 papiPrinterGetAttributeList(papi_printer_t printer)
497 {
498 	papi_attribute_t **result = NULL;
499 	printer_t *p = printer;
500 
501 	if ((p != NULL) && (p->printer != NULL)) {
502 		papi_attribute_t **(*f)();
503 
504 		f = (papi_attribute_t **(*)())psm_sym(p->svc,
505 					"papiPrinterGetAttributeList");
506 		if (f != NULL)
507 			result = f(p->printer);
508 	} else
509 		result = p->attributes;
510 
511 	return (result);
512 }
513